引用:http://zhouruijun163.blog.163.com/blog/static/1077156200810744257672/
看过《windows程序设计》的童鞋都知道,这本书在第九章介绍了一些常用的控件,但是这些控件的功能比较简单。如果,我们想要实现比较复杂的功能,我们不得采用MFC框架中一些更高级的控件。又没有一种方法:既不用创建MFC工程,又能使用MFC中的一些控件呢?
经过,一般百度,我发现使用Windows下面的公共控件库是比较靠谱的解决方案。
Win32公共控件库是由COMCTL32.DLL支持的窗口控件库,这个库中包含了一些全新的32位控件(相比于16位Wndows环境下的控件,确实是全新的)。
这个库里控件的使用基本上,和《windows程序设计》中介绍的相似,我们可以在资源视图中直接拖动控件到窗口,当然也可以用CreateWindow函数手工创建(创建这些控件好像需要用CreateWindowEX)。
在消息响应方面,除了原先的WM——COMMAND的消息,这个库中似乎还大量使用WM_NOTIFY消息。
基本上,这个库为我们扩充了这几个控件
由于,这些控件的功能比较强大,使用WM_COMMAND已经不足以传递消息。这些,新的控件使用WM_NOTIFY进行消息传送。一个WM_NOTIFY消息的lParam参数包含了一个
NMHDR结构
typedef struct tagNMHDR {
HWND hwndFrom; // 发送消息的窗口句柄
UINT idFrom;// 控件的ID
UINT code; // 消息码
} NMHDR;
<span style="white-space:pre"> </span>NM_CLICK //左键单击
NM_DBLCLK //左键双击
NM_KILLFOCUS //控件失去焦点
NM_OUTOFMEMORY //控件的内存空间不足
NM_RCLICK //右键单击
NM_RDBLCLK //右键双击
NM_RETURN //控件拥有输入焦点,并且用户按下了回车键
NM_SETFOCUS //控件获得焦点
使用公共控件要添加头文件#include <commctrl.h>
下面,介绍一个比较有用的控件ListView,这个控件在MFC中叫CListCtrl,指定他的类名为SysListView32,我们可以在资源编辑器直接拖动一个到我们的对话框,也可以使用下面的CreateWindowEX函数创建一个
向控件中添加列,这里我们要用到一个结构成员LVCOLUMN,这个结构msdn中是怎么说的自己去看
我们可以向控件发送 LVM_INSERTCOLUMN消息来添加列,当然我们还可使用一个叫ListView_InsertColumn的宏
下面的代码生成了一个简单列表
VOID InitList()
{
//IDC_Process_LIST是ListView的ID
HWND hList=GetDlgItem(theAppHandle,IDC_Process_LIST);
//初始化表格
TCHAR rgtsz[4][10] = {_T("名称"), _T("进程ID"),_T("线程数"),_T("父进程ID")};
LV_COLUMN lvcolumn;
RECT rect;
GetWindowRect(hList,&rect);
for(int i=0;i<4;i++)
{
//列属性声明:对齐方式|子项的起始索引值|列标题使用文本|允许定义列的宽度|允许排序
lvcolumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH | LVCF_ORDER;
lvcolumn.fmt = LVCFMT_LEFT;//文本左对齐
lvcolumn.pszText = rgtsz[i];//列的名字
lvcolumn.iSubItem = i;//列的索引
lvcolumn.iOrder = i;//列顺序从0开始
if(i==0)
lvcolumn.cx = (rect.right-rect.left)*2.0/5.0;
else
lvcolumn.cx = (rect.right-rect.left)*1.0/5.0;
SendMessage(hList,LVM_INSERTCOLUMN,i,(LPARAM)&lvcolumn);
}
}
向列表中插入一项,这里要又要用一个新的结构表示列表中新的一项: LVITEM
向列表中添加一项相当的麻烦,由于列表中的项有几个不同元素构成,因此我们每次写入项中的一个部分都要调用一个相应的宏
首先,我们先调用listview_insterItem在表中新建一项,然后还剩下多少子项,就调用多少次,listview_setItem宏,
下面的例子在表格最末端添加一个一列。
typedef struct
{
<span style="white-space:pre"> </span>//定义一个数据结构表示基本进程信息
<span style="white-space:pre"> </span>DWORD PID;
<span style="white-space:pre"> </span>DWORD threadCount;
<span style="white-space:pre"> </span>DWORD parentPID;
<span style="white-space:pre"> </span>TCHAR Name[MAXLENGTH_NAME];
}ProcessINFO;
VOID AddItem(ProcessINFO * pInfo)
{
TCHAR NUM[10];
HWND hList=GetDlgItem(theAppHandle,IDC_Process_LIST);
//由于是添加在末尾一行,我们需要计算出列表中已经有了几行
int nIndex =ListView_GetItemCount(hList);//获取表格中有多少行
//这里我们要先在列表中创建一行,然后在修改其中的参数
LV_ITEM lvitemAdd ;//添加一行
lvitemAdd.mask = LVIF_TEXT;
lvitemAdd.iItem = nIndex ;//添加到最后一列
lvitemAdd.iSubItem = 0;//添加的列
lvitemAdd.pszText=pInfo->Name;
ListView_InsertItem(hList,&lvitemAdd);
//修改子项中的内容
lvitemAdd.iSubItem = 1;
_itot_s(pInfo->PID,NUM,10,10);
lvitemAdd.pszText=NUM;
ListView_SetItem(hList,&lvitemAdd);
lvitemAdd.iSubItem = 2;
_itot_s(pInfo->threadCount,NUM,10,10);
lvitemAdd.pszText=NUM;
ListView_SetItem(hList,&lvitemAdd);
lvitemAdd.iSubItem = 3;
_itot_s(pInfo->parentPID,NUM,10,10);
lvitemAdd.pszText=NUM;
ListView_SetItem(hList,&lvitemAdd);
}
关于ListView的其他功能,我在学习的过程中发现,其实在MSDN中输入关键字ListView能获得大量关于他的定义,比如上面用到的几个!
这是运行的结果,关于进程的枚举,是用toolhelp这dll实现的