积累的VC编程小技巧之列表框
1.列表框中标题栏(Column)的添加
创建一个List Control,其ID为IDC_LIST,在其Styles属性项下的View项里选择Report、Align项里选择Top、Sort项里选择None.
然后在该List所在对话框的类(头文件)里创建ClistCtrl的一个对象m_list然后在.cpp文件的OnInitDialog()之类的函数里实现如下代码:
CString strname[3];
strname[0]="Screen Name";
strname[1]="Form ID";
strname[2]="Category Path";
for(int i=0;i<3;i++)
{
m_List.InsertColumn(i,strname[i],LVCFMT_LEFT,130);
}
在这之前也要将List Control的ID与ClistCtrl的对象m_list在DoDataExchange(CDataExchange* pDX)函数里绑定,如下:
DDX_Control(pDX, IDC_LIST, m_List);
2.如何防止在列表框中添加很多数据出现不停的刷新?
[问题提出]
在listbox添加很多数据的时候,由于控件不停的刷新,导致出现闪烁,如何解决?
[解决方法]
再添加数据以前,禁止控件刷新,数据添加完毕以后,再刷新一次。
[程序实现](其中:m_ListBox是CListBox的控件类型的变量)
m_ListBox.LockWindowUpdate();//禁止本listbox刷新。
for(int i=0;i<9999;i++)
{
m_ListBox.AddString("test");
}//添加数据。
this->RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
3.列表框中选择变化时如何获得通知?
我在Report View中使用了一个CListCtrl(自绘制类型),我想知道什么时候选择项发生了改变.
在选择项变化时,可以使用按钮有效或失效,按如下操作:
加入LVN_ITEMCHANGED消息处理.
void CYourClassNameHere::OnItemchangedEventList(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
*pResult = 0;
if (pNMListView->uChanged == LVIF_STATE)
{
if (pNMListView->uNewState)
{
GetDlgItem(IDC_DELETE)->EnableWindow(TRUE);
}
else
{
GetDlgItem(IDC_DELETE)->EnableWindow(FALSE);
}
}
}
4.列表框控件中整栏选择?
我在处理List控件时碰到了麻烦,我想创建一个ListView,来依据Tree控件的选择同时在ListView和ReportView中显示列表的信息.以下是相关的代码:
// Set full line select
ListView_SetExtendedListViewStyle(m_plstCustomers->GetSafeHwnd(),
LVS_EX_FULLROWSELECT);
按如下方法处理:
// -------------------- begin of snippet --------------------------------
bool CCommCtrlUtil32::ListCtrl_ModifyExtendedStyle(CListCtrl& p_rListCtrl,
const DWORD p_dwStyleEx,
const bool p_bAdd)
{
HWND t_hWnd = p_rListCtrl.GetSafeHwnd();
DWORD t_dwStyleEx = ListView_GetExtendedListViewStyle(t_hWnd);
if(p_bAdd)
{
if(0 == (p_dwStyleEx & t_dwStyleEx))
{
// add style
t_dwStyleEx |= p_dwStyleEx;
}
}
else
{
if(0 != (p_dwStyleEx & t_dwStyleEx))
{
// remove style
t_dwStyleEx &= ~p_dwStyleEx;
}
}
ListView_SetExtendedListViewStyle(t_hWnd, t_dwStyleEx);
return true;
}
5.如何双击列表框项启动一个与文件关联的程序?
有人问我如何双击列表框项启动一个程序?其实这个问题很简单,Windows中有一个API函数可以打开任何类型的文件:
ShellExecute(NULL,"open",lpFileName,NULL,NULL,SW_SHOWNORMAL);
参数 lpFileName 是文件的全路径名。用这个变量你可以传递象“C:\\MyExcelFile.xls”或者“http://www.vckbase.com”启动Excel程序或者浏览器程序。如果你只是想获取与文件关联的程序名,而不是要运行程序,那么调用::FindExecutable就可以了。
6.如何得到列表框中所选择项的String?
[问题提出]
如何得到CListBox所选择项的String
[解决方法]
用到:CListBox::GetText()
[程序实现]
CString scInfo;
pList->GetText( GetCurSel(),scInfo);
7.锁定ListView的栏目头宽度
编译:NorthTibet
世界之大,真是无其不有。Windows 应用程序的GUI标准明确规定了 ListView 栏目头(Column Header)的宽度必须是可调整的,这本来是专门为用户考虑而设计的控制特性,可是偏偏就有用户拒绝这样的特性。作为技术人员,用户的需求是很难拒绝的。尽管这明显是一种“非典型性需求”。本文将通过一个实例来示范如何实现 ListView Column Header 宽度的锁定。
ListView 及其 Column Header 实际上都是 Windows 通用控件(Comctl32.dll) 的一部分。所以查一查 MSDN 中与“Header Control”相关的控件资料不难发现,栏目头的锁定与否与几个 Windows 的通知消息密切相关,这几个消息分别是 HDN_TRACK、HDN_BEGINTRACK 和 HDN_ENDTRACKA。其中 HDN_BEGINTRACK 是本文要特别关照的一个。当用户在栏目头上拖拽鼠标时,如果位置正好在改变宽度的分割条上,则栏目头控件会向其父窗口发送一个 HDN_BEGINTRACK 通知消息。为了实现栏目头宽度的锁定,就必须搞掂这个通知消息。不能将它传递到父窗口,但是,这个消息与 Windows 中形形色色的其它通知消息一样,有两个版本:一个版本是 HDN_BEGINTRACKW,专门用于宽字符和 Unicode 字符集;另一个版本是 HDN_BEGINTRACKA,专门用于 ANSI 字符集。这两个版本的使用方法可以从公共控件的头文件 commctrl.h 中获取:
// From commctrl.h
#ifdef UNICODE
#define HDN_BEGINTRACK HDN_BEGINTRACKW
#else
#define HDN_BEGINTRACK HDN_BEGINTRACKA
#endif
所以在实现对消息的 HDN_BEGINTRACK 处理时,实际上是根据 UNICODE 的取值实现对 HDN_BEGINTRACKA 或 HDN_BEGINTRACKW 的处理。那么 Header Control 到底是发送的哪一个消息呢?在这里必须明白:Header Control 是 Windows 通用控件的一部分,它的实现都在 comctl32.dll 动态链接库中。由于这个 DLL 已经被编译成可执行代码,因此在工程中修改 UNICODE 的设置将无济于事。如何知道栏目头控件发送哪一个版本的通知消息呢?是 A 版本还是 W 版本?
为了找到答案,我们必须求助一个经常被遗忘的消息 WM_NOTIFYFORMAT。一般控件第一次被创建时,都要向父窗口一个消息询问父窗口需要哪个版本的通知消息。然后父窗口返回 NFR_ANSI 或 NFR_UNICODE。如果父窗口不处理 WM_NOTIFYFORMAT,那么这个消息将根据父窗口或对话框本身的首选项被传递到 Windows 的 DefWindowProc 消息处理例程进行默认处理。默认为 UNICODE。因此,要知道通知消息的版本,必须处理 ListCtrl 的 WM_NOTIFYFORMAT。为了确认父窗口的返回值,你可以做一个试验便明白了。
如果你不想处理 WM_NOTIFYFORMAT 消息,那么完全可以通过双双实现 HDN_BEGINTRACKA 和 HDN_BEGINTRACKW 通知消息的处理来简化问题的解决方案,同时这种方法也更可靠和通用。此时代码将同时支持 ANSI 和 Unicode。本文附带的例子程序示范了这种方法的实现。如图一所示:
图一 锁定栏目头宽度
实现代码很简单,Header 控件发送 HDN_XXX 到父窗口(ListCtrl),在 MFC 中可以利用消息反射来处理 Header 控件的通知消息。因为“可锁定栏目头”特性本身更趋向于 Header 控件的属性,而不是 ListCtrl 的属性。如果你不用 MFC ,那么就得处理 ListCtrl 中的通知消息。例子程序使用了消息反射机制,在 Header 控件的消息映射使用 ON_NOTIFY_REFLECT,也就是该写虚拟成员函数 OnChildNotify:
BOOL CLockableHeader::OnChildNotify(UINT msg, WPARAM wp, LPARAM lp, LRESULT* pRes)
{
NMHDR& nmh = *(NMHDR*)lp;
if (nmh.code==HDN_BEGINTRACKW || nmg.code==HDN_BEGINTRACKA)
return *pRes=TRUE;
......
}
因为 OnChildNotify 是虚函数,所以没有必要具备消息映射入口。只要实现此函数即可。在任何应用中,Header 发送的消息非此即彼,不会两者都发送。不管怎样,所发送的通知消息在到达父窗口之前都会被吃掉。也就是说,消息处理总是返回 TRUE,是否锁定栏目头的宽度通过一个标志来控制:应用程序通过 Lock 来修改标志的值。
如果锁定了头宽度,那么同时也必须禁用改变宽度的光标,这样用户界面才会有一致性,要实现这一点也很简单:
BOOL CLockableHeader::OnSetCursor( CWnd* pWnd, UINT nHit, UINT msg)
{
return m_bLocked ? TRUE : CHeaderCtrl::OnSetCursor(pWnd, nHit, msg);
}
如果栏目头被锁定,则 OnSetCursor 返回 TRUE,此时光标不会被重新设置,否则由 Header 控件的进行默认处理。锁定宽度后,当鼠标移到栏目头上时,Windows 显示标准的箭头光标,而不是带左右箭头光标。
从 CHeaderCtrl 派生类出来的类的使用方法与处理对话框控制一样,通过在父窗口的 OnCreate 的处理例程中进行子类化。实现细节请参考例子源代码:
// CMyView is derived from CListView
int CMyView::OnCreate(LPCREATESTRUCT lpcs)
{
VERIFY(CListView::OnCreate(lpcs)==0);
return m_header.SubclassDlgItem(0,this) ? 0 : -1;
}
由于 Header 控制的资源 ID = 0,所以上面的代码是行得通的。为了有一个友好的用户界面,例子程序创建了一个命令菜单和界面更新处理例程。如图一所示。
积累的VC编程小技巧之列表框的更多相关文章
- 积累的VC编程小技巧之组合框
1.如何正确的得到ComBox的指针 CComboBox *mComb = (CComboBox*)GetDlgItem(IDC_DuanCB); CComboBox *mComb = (CCombo ...
- 积累的VC编程小技巧之编辑框
1.如何让对话框中的编辑框接收对话框的消息 ////////////////////////////////////////////////// 如何让对话框中的CEdit控件类接收对话框的消息/// ...
- 积累的VC编程小技巧之文件操作
1.删除文件夹 // 删除文件夹及其所有内容void CBaseDoc::RemoveFolder(const CString &strPathName){ CString path = ...
- 积累的VC编程小技巧之按钮
1.资源种创建的控件,对其属性的动态控制: 在对话框类的头文件里创建所要改变属性的控件的对象,如要改变一个Button(其ID为IDC_MyButton)的属性,则需创建Cbutton的对象m_but ...
- 积累的VC编程小技巧之框架窗口及其他
1.修改主窗口风格 AppWizard生成的应用程序框架的主窗口具有缺省的窗口风格,比如在窗口标题条中自动添加文档名.窗口是叠加型的.可改变窗口大小等.要修改窗口的缺省风格,需要重载CWnd::Pre ...
- 积累的VC编程小技巧之打印相关
1.修改打印预览的ToolBar 为AFX_IDD_PREVIEW_TOOLBAR这个ID创建一个DialogBar.则系统就会用新创建的DialogBar代替系统默认的那个 2.关于打印 1.要打印 ...
- 积累的VC编程小技巧之对话框
1.用鼠标移动基于对话框的无标题栏程序的简单方法 void CVCTestDlg::OnLButtonDown(UINT nFlags, CPoint point) { //一句话解决问题 ...
- 积累的VC编程小技巧之工具提示
1.用鼠标移动基于对话框的无标题栏程序的简单方法 void CVCTestDlg::OnLButtonDown(UINT nFlags, CPoint point) { //一句话解决问题 ...
- 积累的VC编程小技巧之树操作
1.如何在TreeList中加图标? [问题提出] 请问treeview控件和treectrl控件的用法有何不同呢?向如何imagelist控件中加图象呀? [解决方法] 1) HICON ...
随机推荐
- hdu1540之线段树单点更新+区间合并
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- 解决Android Activity切换时出现白屏问题
有些性能低的机器,在切换activity时候出现白屏一段时候后才显示正确的视图 高性能的机器可能太快看不到,但是事实是存在的, 特别是当你新开一个进程的时候,A进程的activity跳转到B进程的Ac ...
- Ubuntu: 搭建tftp,nfs服务器
Ubuntu12.04搭建tftp&nfs服务器 http://blog.163.com/thinki_cao/blog/static/83944875201411610467306/ 硬件环 ...
- Windows VS下搭建cocos2d-x环境搭建
VS2010以上版本(eg:VS2012/VS2013,这里本人用VS2013) 1.环境.安装包准备 2.python安装 3.cocos2d-x安装包解压安装 4.环境变量配置 5.执行setup ...
- Android调整TimePicker和DatePicker大小
最近写了个app,里面要将DatePicker和TimePicker并列显示.但是,Android内部把DatePicker和 TimePicker大小固定了,导致4.5寸手机屏幕一行只能显示出一个, ...
- 基于visual Studio2013解决算法导论之007优先队列(堆实现)
题目 优先队列 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #in ...
- servlet 与缓存(4)
1.设置缓存的两种情况: 第一种:对于不常常变化的数据,在servlet中能够为其设置合理的缓存时间值,以避免浏览器频繁向server发送请求,提升server的性能. 另外一种:假设要实现一种高级功 ...
- PCB设计资料:看到最后才知道是福利
參考资料 通过以下的关键词直接从网络上Google或Baidu就能非常easy的找到以下的资料,这里仅仅是以參考文献的方式做一个整理以及简单的说明. 刘雅芳,张俊辉. 抗干扰角度分析六层板的布线技巧. ...
- mac下和windows下清空DNS缓存
在WIN下: > ipconfig /flushdns 在mac下: 对于低版本系统,在命令行窗口(terminal)输入 lookupd -flushcache 即可: $ sudo look ...
- 网盘大全, 邮箱大全 good
网盘推荐 115网盘 注册 百度网盘 注册 微云 注册 360云盘 注册 金山快盘 注册 新浪微盘 注册 和彩云 注册 酷盘 注册 OneDrive 外链 BOX 注册 Dropbox 注册 国内网盘 ...