ListCtrl使用详述及进程列表示例

ListCtrl使用详述及进程列表示例
作者:阿珊境界
近日同事问起ListCtrl的使用示例,我竟有一种无从下手的感觉。查了查资料,觉得有必要把常用的东西都整理出来,以备后用,也方便大家。
创建ListCtrl我们可以通过在界面上直接绘制和动态生成两种方式,得到其指针后就可以进行操作了。
ListCtrl有三种显示模式,即图标,小图标和报表形式。下面以报表为例阐述。同时,还设置了其整行选取和显示表格线的样式:

   CListCtrl* pmyListCtrl=(CListCtrl*)GetDlgItem(IDC_LIST1);   //获取ListCtrl指针
   DWORD dwstyle=GetWindowLong(pmyListCtrl->m_hWnd,GWL_STYLE);
   //获取窗口样式
   SetWindowLong(pmyListCtrl->m_hWnd,GWL_STYLE,dwstyle | LVS_REPORT  );    //设置报表样式
   DWORD styles=pmyListCtrl->GetExStyle();    //获取扩展样式
   styles &=~LVS_EX_CHECKBOXES;    //去掉每行前端复选框   pmyListCtrl->SetExtendedStyle(styles | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);  //设置其整行选取和显示表格线样式

给ListCtrl加上列头,需要用到LVCOLUMN结构体,代码如下:

   TCHAR szHeader[3][10]={_T("col1"),_T("col2"),_T("col3")};
   LVCOLUMN lvcolumn;  //定义一个结构体
   CRect rect;
   pmyListCtrl->GetWindowRect(&rect);  //获取窗口矩形
   int i=0;
   for(i=0;i<3;i++)  //加入3列
   {
          lvcolumn.mask=LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT
                 | LVCF_WIDTH | LVCF_ORDER;  //设定哪些项有效
          lvcolumn.fmt=LVCFMT_LEFT;  //左对齐
          lvcolumn.pszText=szHeader;  //字符串数组的数组
          lvcolumn.iSubItem=i;
          lvcolumn.iOrder = i;
          lvcolumn.cx=(rect.Width())/4-1;    //宽度
          pmyListCtrl->InsertColumn(i,&lvcolumn);   //插入列

}

也可以通过发送LVM_INSERTCOLUMN消息来插入列,如下:

pmyListCtrl->SendMessage(LVM_INSERTCOLUMN,i,(LPARAM)&lvcolumn);

   增加10条记录
   CString strText;
   for (i=0;i<=10;i++)
   {
          strText.Format(TEXT("item %d"), i);
          pmyListCtrl->InsertItem(i, strText);
          for (int j=1;j<3;j++)
          {
                 strText.Format(TEXT("sub-item %d-%d"), i, j);
                 pmyListCtrl->SetItemText(i, j, strText);
          }
   }

与插入列其似,插行也可以通过发送LVM_INSERTITEM和LVM_SETITEMTEXT来实现。先定义一个LVITEM结构体,如下:
LVITEM item;
item.iItem=I;
item.mask=LVIF_TEXT;
item.pszText=(LPSTSTR)str;
pmyListCtrl->SendMessage(I,(LPARAM)L&item);
LVITEM lvi;
lvi.SubItem=1;
lvi.pszText=(LPTSTR)str;
pmyListCtrl->SendMessage(LVM_INSERTITEM,I,(LPARAM)&lvi);
下面说一下ListCtrl的消息处理。当事件发生时,通用控件向父窗口发送WM_NOTIFY消息,该消息的wParam参数指定了控件的ID号,lParam则是一个指向NMHDR结构体的指针。该结构体定义如下:
typedef struct tagNMHDR { HWND hwndFrom; //控件句柄 UINT idFrom; //控件ID号 UINT code; //通知代码,如NM_CLICK} NMHDR; ListCtrl通知消息的lParam指向了一个更大的结构体NMLISTVIEW,它的第一个成员是NMHDR结构体。下面代码是双击一个列表项时,弹出此项的index。
if(wParam == IDC_LIST)
{

   NMHDR* pHeader = (NMHDR*)lParam;
   HWND hWndList = pHeader->hwndFrom;
   if(pHeader->code == NM_DBLCLK)  
   {
          NMLISTVIEW* pNMListView = (NMLISTVIEW*)pHeader;
          // 用户双击的项号
          int nIndex = pNMListView->iItem;
          char  str[20]="/0" ;
          sprintf(str,"%d",nIndex);
          MessageBox(0,str,"Index",0);
   }

}
下面代码是用Toolhelp API实现的进程列表。注意在工程文件中包含tlhelp32.h头文件。
LVCOLUMN column;
column.mask = LVCF_TEXT|LVCF_FMT|LVCF_WIDTH;
column.fmt = LVCFMT_CENTER; //居中显示
column.cx = 100; //宽度
column.pszText = "进程";
pmyListCtrl->SendMessage(LVM_INSERTCOLUMN, 0, (LPARAM)&column);
column.pszText = "PID";
column.cx = 50;
pmyListCtrl->SendMessage(LVM_INSERTCOLUMN, 1, (LPARAM)&column);
int nItem = 0;
PROCESSENTRY32 pe32 = {sizeof(PROCESSENTRY32)};
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)

   return;

if(Process32First(hProcessSnap, &pe32))
{

   do
   {
          char szID[20]="/0";
          wsprintf(szID, "%u", pe32.th32ProcessID);
          LVITEM item = {0};
          item.iItem = nItem;
          item.mask = LVIF_TEXT;                    //设定有效项
          item.pszText = (LPTSTR)pe32.szExeFile;   
          pmyListCtrl->SendMessageLVM_INSERTITEM, 0, (LPARAM)&item);
          LVITEM lvi;
          lvi.iSubItem = 1;        
          lvi.pszText = (LPTSTR)szID;  
          pmyListCtrl->SendMessage(LVM_SETITEMTEXT, nItem, (LPARAM)&lvi);
          nItem++;
   }
   while(Process32Next(hProcessSnap, &pe32));

}
::CloseHandle(hProcessSnap);

赞(0) 打赏
取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

    暂无评论...