1.新建對話框MFC,在對話框上放一個ListCtrl
ID:IDC_PATH
View:Report
2.為ListCtrl添加變量
右擊->添加變量m_wndPath
3.找到OnInitDialog()函數添加如下代碼:
// TODO: 在此添加額外的初始化代碼 m_wndPath.DeleteAllItems();//清空 m_wndPath.InsertColumn(0,_T("項目"));//添加列 m_wndPath.InsertColumn(1,_T("所在路徑")); m_wndPath.SetColumnWidth(0, 150);//設置列寬 m_wndPath.SetColumnWidth(1, 350); m_wndPath.SetRedraw(FALSE);//防止重繪 int nIndex; //char|TCHAR項目屬性->字符集:使用多字節字符集 TCHAR Path[MAX_PATH+1];//TCHAR取代char MAX_PATH最長路徑 nIndex=m_wndPath.InsertItem( 0,_T("Windows目錄") ); if( nIndex < 0 ) return TRUE; GetWindowsDirectory(Path,MAX_PATH);//取得windows目錄 m_wndPath.SetItemText( nIndex, 1, Path ); LPITEMIDLIST pidl;//桌面CSIDL_DESKTOPDIRECTORY //用來得到系統的某些特定文件夾的位置信息 if(SUCCEEDED(SHGetSpecialFolderLocation(NULL,CSIDL_DESKTOPDIRECTORY,&pidl))) { if(SHGetPathFromIDList(pidl, Path))//功能是把項目標志符列表轉換為文檔系統路徑 { nIndex=m_wndPath.InsertItem( 0,_T("桌面"));//成功則返回0 if( nIndex < 0 ) { return TRUE; } m_wndPath.SetItemText( nIndex, 1, Path ); } } m_wndPath.SetRedraw(TRUE);//顯示 return TRUE; // 除非將焦點設置到控件,否則返回 TRUE
// TODO: 在此添加額外的初始化代碼m_wndPath.DeleteAllItems();//清空 m_wndPath.InsertColumn(0,_T("項目"));//添加列 m_wndPath.InsertColumn(1,_T("所在路徑")); m_wndPath.SetColumnWidth(0, 150);//設置列寬 m_wndPath.SetColumnWidth(1, 350); m_wndPath.SetRedraw(FALSE);//防止重繪 int nIndex; //char|TCHAR項目屬性->字符集:使用多字節字符集 TCHAR Path[MAX_PATH+1];//TCHAR取代char MAX_PATH最長路徑 nIndex=m_wndPath.InsertItem( 0,_T("Windows目錄") ); if( nIndex < 0 ) return TRUE; GetWindowsDirectory(Path,MAX_PATH);//取得windows目錄 m_wndPath.SetItemText( nIndex, 1, Path ); LPITEMIDLIST pidl;//桌面CSIDL_DESKTOPDIRECTORY //用來得到系統的某些特定文件夾的位置信息 if(SUCCEEDED(SHGetSpecialFolderLocation(NULL,CSIDL_DESKTOPDIRECTORY,&pidl))) { if(SHGetPathFromIDList(pidl, Path))//功能是把項目標志符列表轉換為文檔系統路徑 { nIndex=m_wndPath.InsertItem( 0,_T("桌面"));//成功則返回0 if( nIndex < 0 ) { return TRUE; } m_wndPath.SetItemText( nIndex, 1, Path ); } } m_wndPath.SetRedraw(TRUE);//顯示 return TRUE; // 除非將焦點設置到控件,否則返回 TRUE
4.char被TCHAR取代,若要用則:
項目屬性->字符集:使用多字節字符集
參考代碼:
m_wndPath.DeleteAllItems(); m_wndPath.InsertColumn(0,"項目"); m_wndPath.InsertColumn(1,"所在路徑"); m_wndPath.SetColumnWidth(0, 150); m_wndPath.SetColumnWidth(1, 350); m_wndPath.SetRedraw(FALSE); int nIndex; const int nFolder[]={ CSIDL_ALTSTARTUP,CSIDL_APPDATA,CSIDL_BITBUCKET,CSIDL_COMMON_ALTSTARTUP, CSIDL_COMMON_DESKTOPDIRECTORY,CSIDL_COMMON_FAVORITES,CSIDL_COMMON_PROGRAMS, CSIDL_COMMON_STARTMENU,CSIDL_COMMON_STARTUP,CSIDL_CONTROLS,CSIDL_COOKIES, CSIDL_DESKTOP,CSIDL_DESKTOPDIRECTORY,CSIDL_DRIVES,CSIDL_FAVORITES,CSIDL_FONTS, CSIDL_HISTORY,CSIDL_INTERNET,CSIDL_INTERNET_CACHE,CSIDL_NETHOOD,CSIDL_NETWORK, CSIDL_PERSONAL,CSIDL_PRINTERS,CSIDL_PRINTHOOD,CSIDL_PROGRAMS,CSIDL_RECENT, CSIDL_SENDTO,CSIDL_STARTMENU,CSIDL_STARTUP,CSIDL_TEMPLATES }; const CString strFolderName[]={ "CSIDL_ALTSTARTUP","CSIDL_APPDATA","回收站","CSIDL_COMMON_ALTSTARTUP", "CSIDL_COMMON_DESKTOPDIRECTORY","CSIDL_COMMON_FAVORITES","CSIDL_COMMON_PROGRAMS", "CSIDL_COMMON_STARTMENU","CSIDL_COMMON_STARTUP","控制面板","CSIDL_COOKIES", "CSIDL_DESKTOP","桌面","我的電腦","收藏夾","字體", "歷史紀錄","CSIDL_INTERNET","CSIDL_INTERNET_CACHE","網上鄰居","CSIDL_NETWORK", "我的文檔","打印機","CSIDL_PRINTHOOD","程序組","最近打開的文檔", "發送","任務條啟動菜單目錄","啟動目錄","臨時文檔" }; char Path[MAX_PATH+1]; nIndex=m_wndPath.InsertItem( 0,"Windows目錄" ); if( nIndex < 0 ) return TRUE; GetWindowsDirectory(Path,MAX_PATH); m_wndPath.SetItemText( nIndex, 1, Path ); nIndex=m_wndPath.InsertItem( 0,"System目錄" ); if( nIndex < 0 ) return TRUE; GetSystemDirectory(Path,MAX_PATH); m_wndPath.SetItemText( nIndex, 1, Path ); int i,count=sizeof(nFolder)/sizeof(int); for(i=0;i<count;i++) { LPITEMIDLIST pidl; LPMALLOC pShellMalloc; if(SUCCEEDED(SHGetMalloc(&pShellMalloc))) { if(SUCCEEDED(SHGetSpecialFolderLocation(NULL, nFolder[i],&pidl))) { if(SHGetPathFromIDList(pidl, Path)) { nIndex=m_wndPath.InsertItem( 0,strFolderName[i] ); if( nIndex < 0 ) { pShellMalloc->Free(pidl); pShellMalloc->Release(); return TRUE; } m_wndPath.SetItemText( nIndex, 1, Path ); } pShellMalloc->Free(pidl); } pShellMalloc->Release(); } } m_wndPath.SetRedraw(TRUE); m_wndPath.DeleteAllItems(); m_wndPath.InsertColumn(0,"項目"); m_wndPath.InsertColumn(1,"所在路徑"); m_wndPath.SetColumnWidth(0, 150); m_wndPath.SetColumnWidth(1, 350); m_wndPath.SetRedraw(FALSE); int nIndex; const int nFolder[]={ CSIDL_ALTSTARTUP,CSIDL_APPDATA,CSIDL_BITBUCKET,CSIDL_COMMON_ALTSTARTUP, CSIDL_COMMON_DESKTOPDIRECTORY,CSIDL_COMMON_FAVORITES,CSIDL_COMMON_PROGRAMS, CSIDL_COMMON_STARTMENU,CSIDL_COMMON_STARTUP,CSIDL_CONTROLS,CSIDL_COOKIES, CSIDL_DESKTOP,CSIDL_DESKTOPDIRECTORY,CSIDL_DRIVES,CSIDL_FAVORITES,CSIDL_FONTS, CSIDL_HISTORY,CSIDL_INTERNET,CSIDL_INTERNET_CACHE,CSIDL_NETHOOD,CSIDL_NETWORK, CSIDL_PERSONAL,CSIDL_PRINTERS,CSIDL_PRINTHOOD,CSIDL_PROGRAMS,CSIDL_RECENT, CSIDL_SENDTO,CSIDL_STARTMENU,CSIDL_STARTUP,CSIDL_TEMPLATES }; const CString strFolderName[]={ "CSIDL_ALTSTARTUP","CSIDL_APPDATA","回收站","CSIDL_COMMON_ALTSTARTUP", "CSIDL_COMMON_DESKTOPDIRECTORY","CSIDL_COMMON_FAVORITES","CSIDL_COMMON_PROGRAMS", "CSIDL_COMMON_STARTMENU","CSIDL_COMMON_STARTUP","控制面板","CSIDL_COOKIES", "CSIDL_DESKTOP","桌面","我的電腦","收藏夾","字體", "歷史紀錄","CSIDL_INTERNET","CSIDL_INTERNET_CACHE","網上鄰居","CSIDL_NETWORK", "我的文檔","打印機","CSIDL_PRINTHOOD","程序組","最近打開的文檔", "發送","任務條啟動菜單目錄","啟動目錄","臨時文檔" }; char Path[MAX_PATH+1]; nIndex=m_wndPath.InsertItem( 0,"Windows目錄" ); if( nIndex < 0 ) return TRUE; GetWindowsDirectory(Path,MAX_PATH); m_wndPath.SetItemText( nIndex, 1, Path ); nIndex=m_wndPath.InsertItem( 0,"System目錄" ); if( nIndex < 0 ) return TRUE; GetSystemDirectory(Path,MAX_PATH); m_wndPath.SetItemText( nIndex, 1, Path ); int i,count=sizeof(nFolder)/sizeof(int); for(i=0;i<count;i++) { LPITEMIDLIST pidl; LPMALLOC pShellMalloc; if(SUCCEEDED(SHGetMalloc(&pShellMalloc))) { if(SUCCEEDED(SHGetSpecialFolderLocation(NULL, nFolder[i],&pidl))) { if(SHGetPathFromIDList(pidl, Path)) { nIndex=m_wndPath.InsertItem( 0,strFolderName[i] ); if( nIndex < 0 ) { pShellMalloc->Free(pidl); pShellMalloc->Release(); return TRUE; } m_wndPath.SetItemText( nIndex, 1, Path ); } pShellMalloc->Free(pidl); } pShellMalloc->Release(); } } m_wndPath.SetRedraw(TRUE);
VC中ListCtrl經驗總結
先注明一下,這裡,我們用m_listctrl來表示一個CListCtrl的類對象,然後這裡我們的ListCtrl都是report形式,至於其他的如什麼大圖標,小圖標的暫時不講,畢竟report是大眾話的使用。其次,我們這裡用條款一,條款二來描述第一點,第二點,這個是參照《Effective C++》的叫法,俺覺得這麼叫比較COOL :)
條款一:設置ListCtrl的風格
在CSDN上常常看到有人問怎麼設置風格的,他們ListCtrl的樣子是一個列表,有橫條和豎條分界線,然後選中一行,要整一行都選中,而不是只有某一列被選中,等等,這裡給一個比較全面的設置方法。
//獲得原有風格
DWORD dwStyle = ::GetWindowLong(m_listctrl.m_hWnd, GWL_STYLE); dwStyle &= ~(LVS_TYPEMASK); dwStyle &= ~(LVS_EDITLABELS);
SetWindowLong(m_listctrl.m_hWnd, GWL_STYLE,dwStyle, |LVS_REPORT | LVS_NOLABELWRAP | LVS_SHOWSELALWAYS);//設置擴展風格
DWORD styles = LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_CHECKBOXES; ListView_SetExtendedListViewStyleEx(m_listctrl.m_hWnd, styles, styles );其中LVS_EX_FULLROWSELECT 就是前面說得整行選中
TCHAR rgtsz[2][10] = {_T("列頭1"), _T("列頭2")}; LV_COLUMN lvcolumn; CRect rect; m_listctrl.GetWindowRect(&rect); for(int i=0;i<2;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; if(i==0) { lvcolumn.cx = rect.Width()*3/5 ; } else lvcolumn.cx = rect.Width()*2/5; m_listctrl.InsertColumn(i, &lvcolumn); } TCHAR rgtsz[2][10] = {_T("列頭1"), _T("列頭2")}; LV_COLUMN lvcolumn; CRect rect; m_listctrl.GetWindowRect(&rect); for(int i=0;i<2;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; if(i==0) { lvcolumn.cx = rect.Width()*3/5 ; } else lvcolumn.cx = rect.Width()*2/5; m_listctrl.InsertColumn(i, &lvcolumn); }
int nIndex = m_listctrl.GetItemCount(); LV_ITEM lvitemAdd = {0}; lvitemAdd.mask = LVIF_TEXT; lvitemAdd.iItem = nIndex ; lvitemAdd.iSubItem = 0; lvitemAdd.pszText =_T("毛毛1");; if (m_listctrl.InsertItem(&lvitemAdd) != -1) { LV_ITEM lvitem = {0}; lvitem.mask = LVIF_TEXT; lvitem.iItem = nIndex ; lvitem.iSubItem = 1; lvitem.pszText =_T("毛毛2"); m_listctrl.SetItem(&lvitem); } int nIndex = m_listctrl.GetItemCount(); LV_ITEM lvitemAdd = {0}; lvitemAdd.mask = LVIF_TEXT; lvitemAdd.iItem = nIndex ; lvitemAdd.iSubItem = 0; lvitemAdd.pszText =_T("毛毛1");; if (m_listctrl.InsertItem(&lvitemAdd) != -1) { LV_ITEM lvitem = {0}; lvitem.mask = LVIF_TEXT; lvitem.iItem = nIndex ; lvitem.iSubItem = 1; lvitem.pszText =_T("毛毛2"); m_listctrl.SetItem(&lvitem); }
int nIndex = m_listctrl.GetItemCount(); LV_ITEM lvitemAdd = {0}; lvitemAdd.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; lvitemAdd.iItem = nIndex ; lvitemAdd.iSubItem = 0; lvitemAdd.pszText =_T("毛毛1");; lvitemAdd.iImage = n; lvitemAdd.lParam = (LPARAM)hwnd;(某個窗口的窗口句柄) if (m_listctrl.InsertItem(&lvitemAdd) != -1) { LV_ITEM lvitem = {0}; lvitem.mask = LVIF_TEXT; lvitem.iItem = nIndex ; lvitem.iSubItem = 1; lvitem.pszText =_T("毛毛2"); m_listctrl.SetItem(&lvitem); } int nIndex = m_listctrl.GetItemCount(); LV_ITEM lvitemAdd = {0}; lvitemAdd.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; lvitemAdd.iItem = nIndex ; lvitemAdd.iSubItem = 0; lvitemAdd.pszText =_T("毛毛1");; lvitemAdd.iImage = n; lvitemAdd.lParam = (LPARAM)hwnd;(某個窗口的窗口句柄) if (m_listctrl.InsertItem(&lvitemAdd) != -1) { LV_ITEM lvitem = {0}; lvitem.mask = LVIF_TEXT; lvitem.iItem = nIndex ; lvitem.iSubItem = 1; lvitem.pszText =_T("毛毛2"); m_listctrl.SetItem(&lvitem); }
[cpp] view plaincopyprint?
void CMyDlg::OnItemClick(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here int nItem = -1; LPNMITEMACTIVATE lpNMItemActivate = (LPNMITEMACTIVATE)pNMHDR; if(lpNMItemActivate != NULL) { nItem = lpNMItemActivate->iItem; } } void CMyDlg::OnItemClick(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here int nItem = -1; LPNMITEMACTIVATE lpNMItemActivate = (LPNMITEMACTIVATE)pNMHDR; if(lpNMItemActivate != NULL) { nItem = lpNMItemActivate->iItem; } }
LV_ITEM lvitem = {0}; lvitem.iItem = nIndex; lvitem.iSubItem = 0; lvitem.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; m_listctrl.GetItem(&lvitem) LV_ITEM lvitem = {0}; lvitem.iItem = nIndex; lvitem.iSubItem = 0; lvitem.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; m_listctrl.GetItem(&lvitem)
[cpp] view plaincopyprint?
// CListCtrl* pListCtrl = (CListCtrl*) GetDlgItem (IDC_YOURLISTCONTROL); ASSERT(pListCtrl != NULL); POSITION pos = pList->GetFirstSelectedItemPosition(); if (pos == NULL) TRACE0("No items were selected!\n"); else { while (pos) { int nItem = pList->GetNextSelectedItem(pos); TRACE1("Item %d was selected!\n", nItem); // you could do your own processing on nItem here } }條款十:刪除條款九中選中的行
POSITION pos = m_listctrl.GetFirstSelectedItemPosition(); if (pos == NULL) TRACE0("No items were selected!\n"); else { while (pos) { int nItem = m_listctrl.GetNextSelectedItem(pos); m_listctrl.DeleteItem(nItem ); // CListCtrl* pListCtrl = (CListCtrl*) GetDlgItem (IDC_YOURLISTCONTROL); ASSERT(pListCtrl != NULL); POSITION pos = pList->GetFirstSelectedItemPosition(); if (pos == NULL) TRACE0("No items were selected!\n"); else { while (pos) { int nItem = pList->GetNextSelectedItem(pos); TRACE1("Item %d was selected!\n", nItem); // you could do your own processing on nItem here } }
POSITION pos = m_listctrl.GetFirstSelectedItemPosition(); if (pos == NULL) TRACE0("No items were selected!\n"); else { while (pos) { int nItem = m_listctrl.GetNextSelectedItem(pos); m_listctrl.DeleteItem(nItem ); } }你就等著收屍吧
POSITION sSelPos = NULL; while(sSelPos = m_listctrl.GetFirstSelectedItemPosition()) { int nSelItem = -1; nSelItem = m_listctrl.GetNextSelectedItem(sSelPos); if(nSelItem >= 0 && nSelItem<m_listctrl.GetItemCount()) { //好了,這個nSelItem 就是我們要的DD } }GetNextSelectedItem這個函數,看msdn的用法,其實是返回第一個的index,然後走到下一個選中的行去,所以這麼做也是安全的,在實際中,俺也是這麼做的,測試也通過,沒問題的