//////////////////////////////////////////////////////////////////////////////////////////?
這樣可以選中呀
int nItem = -1;
?nItem = m_listApp.GetNextItem(nItem, LVNI_SELECTED);
?m_listApp.DeleteItem(nItem);
////////////////////////////////////////////////////////////////////////////////////////////
1。彈出方式菜單
// The code fragment shows how to get the File menu from the
// application window and displays it as a floating popup menu
// when the right mouse button is clicked in view.
// CMyView is a CView-derived class.
void CMyView::OnRButtonDown(UINT nFlags, CPoint point)
{
??CView::OnRButtonDown(nFlags, point);
??CMenu* menu_bar = AfxGetMainWnd()->GetMenu();
??CMenu* file_menu = menu_bar->GetSubMenu(0);
??ASSERT(file_menu);
??file_menu->TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, point.x,
????point.y, this);
}
2。圖標設置
BOOL CListCtrlDemoDlg::InitImageList()
{
?// Create 256 color image lists
?HIMAGELIST hList = ImageList_Create(32,32, ILC_COLOR8 |ILC_MASK , 8, 1);
?m_cImageListNormal.Attach(hList);
?hList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 8, 1);
?m_cImageListSmall.Attach(hList);
?
?// Load the large icons
?CBitmap cBmp;
?
?cBmp.LoadBitmap(IDB_IMAGES_NORMAL);
?m_cImageListNormal.Add(&cBmp, RGB(255,0, 255));
?cBmp.DeleteObject();
?
?// Load the small icons
?cBmp.LoadBitmap(IDB_IMAGES_SMALL);
?m_cImageListSmall.Add(&cBmp, RGB(255,0, 255));
?
?// Attach them
?m_cListCtrl.SetImageList(&m_cImageListNormal, LVSIL_NORMAL);
?m_cListCtrl.SetImageList(&m_cImageListSmall, LVSIL_SMALL);
?
?return TRUE;
}
3。插入圖標
/////////////////////////////////////////////////////////////////////////////
void CListCtrlDemoDlg::InsertItems()
{
?//刪除所有的當前條目內容
?m_cListCtrl.DeleteAllItems();
?
?//用LV_ITEM結構指向要插入的條目
?LVITEM lvi;
?CString strItem;
?for (int i = 0; i < m_nItems; i++)
?{
??// Insert the first item
??lvi.mask =? LVIF_IMAGE | LVIF_TEXT;
??strItem.Format(_T("Item %d"), i);
?
??lvi.iItem = i;
?
??lvi.iSubItem = 0;
??lvi.pszText = (LPTSTR)(LPCTSTR)(strItem);
??lvi.iImage = i%8;??// There are 8 images in the image list
??m_cListCtrl.InsertItem(&lvi);
?
??// Set subitem 1
??strItem.Format(_T("%d"), 10*i);
??lvi.iSubItem =1;
??lvi.pszText = (LPTSTR)(LPCTSTR)(strItem);
??m_cListCtrl.SetItem(&lvi);
?
??// Set subitem 2
??strItem.Format(_T("%s"), COleDateTime::GetCurrentTime().Format(_T("Created: %I:%M:%S %p, %m/%d/%Y")));
??lvi.iSubItem =4;
??lvi.pszText = (LPTSTR)(LPCTSTR)(strItem);
??m_cListCtrl.SetItem(&lvi);
?
?}
}
4。刪除條目
void CMmDlg::OnDelete()
{
?int i,iState;
?int nItemSelected=m_mm_host_ListCtrl.GetSelectedCount();//得到所選表項數
?int nItemCount=m_mm_host_ListCtrl.GetItemCount();//得到表項總數
?if(nItemSelected<1)//如果沒有選中行,退出
??return;
?for(i=nItemCount-1;i>=0;i--)
?{
??iState=m_mm_host_ListCtrl.GetItemState(i,LVIS_SELECTED);
??if(iState!=0)
???m_mm_host_ListCtrl.DeleteItem(i);
?}
}
5。擊活條目
void CMmDlg::OnClickList(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;
?}
?//CString str;
?//str.Format("%d",nItem);
?//MessageBox(str);
?*pResult = 0;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
排序算發
// SortTextItems - Sort the list based on column text// Returns - Returns truefor success// nCol - column that contains the text to be sorted// bAscending - indicate sort order// low - row to start scanning from - default row is 0// high - row to end scan. -1 indicates last row
字符串
///////////////////////////
BOOL CMyListCtrl::SortTextItems( int nCol, BOOL bAscending,?
int low
//////////////////////////////////////////////////////////
數值:
bool CMyListCtrl::SortNumericItems( int nCol, BOOL bAscending,int low
//////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// int i = 0;
CString str;
str.Format("%d",i*10);// 序號for(i=0;i<10;i++)
?{? ??
??????str.Format("%d",i*10);
?? m_mm_host_ListCtrl.InsertItem(i, str, 0);
??????m_mm_host_ListCtrl.SetItemText(i, 1, str);??????m_mm_host_ListCtrl.SetItemText(i, 2, str);??????m_mm_host_ListCtrl.SetItemText(i, 3, str);}
/////////////////////////////////
void CMmDlg::OnDelete()
{
?int i,iState;
?int nItemSelected=m_mm_host_ListCtrl.GetSelectedCount();//所選表項數
?int nItemCount=m_mm_host_ListCtrl.GetItemCount();//表項總數
?if(nItemSelected<1)
??return;
?for(i=nItemCount-1;i>=0;i--)
?{
??iState=m_mm_host_ListCtrl.GetItemState(i,LVIS_SELECTED);
??if(iState!=0)
???m_mm_host_ListCtrl.DeleteItem(i);
?}
}
////////////////////////////////////////////////////////////////
CListCtrl使用技巧[轉]
/////////////////////////////////////////////////////////////////
?
1. CListCtrl 風格
????? LVS_ICON: 為每個item顯示大圖標
????? LVS_SMALLICON: 為每個item顯示小圖標
????? LVS_LIST: 顯示一列帶有小圖標的item
????? LVS_REPORT: 顯示item詳細資料
????? 直觀的理解:windows資源管理器,“查看”標簽下的“大圖標,小圖標,列表,詳細資料”
?
2. 設置listctrl 風格及擴展風格
????? LONG lStyle;
????? lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//獲取當前窗口style
????? lStyle &= ~LVS_TYPEMASK; //清除顯示方式位
????? lStyle |= LVS_REPORT; //設置style
????? SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//設置style
?
????? DWORD dwStyle = m_list.GetExtendedStyle();
????? dwStyle |= LVS_EX_FULLROWSELECT;//選中某行使整行高亮(只適用與report風格的listctrl)
????? dwStyle |= LVS_EX_GRIDLINES;//網格線(只適用與report風格的listctrl)
????? dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
????? m_list.SetExtendedStyle(dwStyle); //設置擴展風格
?
????? 注:listview的style請查閱msdn
????? http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrflistviewstyles.asp
?
3. 插入數據
????? m_list.InsertColumn( 0, "ID", LVCFMT_LEFT, 40 );//插入列
????? m_list.InsertColumn( 1, "NAME", LVCFMT_LEFT, 50 );
????? int nRow = m_list.InsertItem(0, “11”);//插入行
????? m_list.SetItemText(nRow, 1, “jacky”);//設置數據
?
4. 一直選中item
??? 選中style中的Show selection always,或者在上面第2點中設置LVS_SHOWSELALWAYS
5. 選中和取消選中一行
??? int nIndex = 0;
??? //選中
??? m_list.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
??? //取消選中
??? m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);
?
6. 得到listctrl中所有行的checkbox的狀態
????? m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);
????? CString str;
????? for(int i=0; i????? {
?????????? if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i))
?????????? {
??????????????? str.Format(_T("第%d行的checkbox為選中狀態"), i);
??????????????? AfxMessageBox(str);
?????????? }
????? }
?
7. 得到listctrl中所有選中行的序號
????? 方法一:
????? CString str;
????? for(int i=0; i????? {
?????????? if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
?????????? {
??????????????? str.Format(_T("選中了第%d行"), i);
??????????????? AfxMessageBox(str);
?????????? }
????? }
????? 方法二:
????? POSITION pos = m_list.GetFirstSelectedItemPosition();
????? if (pos == NULL)
?????????? TRACE0("No items were selected!\n");
????? else
????? {
?????????? while (pos)
?????????? {
??????????????? int nItem = m_list.GetNextSelectedItem(pos);
??????????????? TRACE1("Item %d was selected!\n", nItem);
??????????????? // you could do your own processing on nItem here
?????????? }
????? }
?
8. 得到item的信息
????? TCHAR szBuf[1024];
????? LVITEM lvi;
????? lvi.iItem = nItemIndex;
????? lvi.iSubItem = 0;
????? lvi.mask = LVIF_TEXT;
????? lvi.pszText = szBuf;
????? lvi.cchTextMax = 1024;
????? m_list.GetItem(&lvi);
????? 關于得到設置item的狀態,還可以參考msdn文章
????? Q173242: Use Masks to Set/Get Item States in CListCtrl
?????????????? http://support.microsoft.com/kb/173242/en-us
?
9. 得到listctrl的所有列的header字符串內容
????? LVCOLUMN lvcol;
????? char? str[256];
????? int?? nColNum;
????? CString? strColumnName[4];//假如有4列
????? nColNum = 0;
????? lvcol.mask = LVCF_TEXT;
????? lvcol.pszText = str;
????? lvcol.cchTextMax = 256;
????? while(m_list.GetColumn(nColNum, &lvcol))
????? {
?????????? strColumnName[nColNum] = lvcol.pszText;
?????????? nColNum++;
????? }
?
10. 使listctrl中一項可見,即滾動滾動條
??? m_list.EnsureVisible(i, FALSE);
11. 得到listctrl列數
??? int nHeadNum = m_list.GetHeaderCtrl()->GetItemCount();
12. 刪除所有列
??? ? 方法一:
???? ??? while ( m_list.DeleteColumn (0))
??? ?? 因為你刪除了第一列后,后面的列會依次向上移動。
??? ? 方法二:
????? int nColumns = 4;
????? for (int i=nColumns-1; i>=0; i--)
????? ??? m_list.DeleteColumn (i);
?
13. 得到單擊的listctrl的行列號
????? 添加listctrl控件的NM_CLICK消息相應函數
????? void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
????? {
?????????? // 方法一:
?????????? /*
?????????? DWORD dwPos = GetMessagePos();
?????????? CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
??
?????????? m_list.ScreenToClient(&point);
??
?????????? LVHITTESTINFO lvinfo;
?????????? lvinfo.pt = point;
?????????? lvinfo.flags = LVHT_ABOVE;
????
?????????? int nItem = m_list.SubItemHitTest(&lvinfo);
?????????? if(nItem != -1)
?????????? {
??????????????? CString strtemp;
??????????????? strtemp.Format("單擊的是第%d行第%d列", lvinfo.iItem, lvinfo.iSubItem);
??????????????? AfxMessageBox(strtemp);
?????????? }
????????? */
??
????????? // 方法二:
????????? /*
?????????? NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
?????????? if(pNMListView->iItem != -1)
?????????? {
??????????????? CString strtemp;
??????????????? strtemp.Format("單擊的是第%d行第%d列",
??????????????????????????????? pNMListView->iItem, pNMListView->iSubItem);
??????????????? AfxMessageBox(strtemp);
?????????? }
????????? */
?????????? *pResult = 0;
????? }
?
14. 判斷是否點擊在listctrl的checkbox上
????? 添加listctrl控件的NM_CLICK消息相應函數
????? void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
????? {
?????????? DWORD dwPos = GetMessagePos();
?????????? CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
??
?????????? m_list.ScreenToClient(&point);
??
?????????? LVHITTESTINFO lvinfo;
?????????? lvinfo.pt = point;
?????????? lvinfo.flags = LVHT_ABOVE;
????
?????????? UINT nFlag;
?????????? int nItem = m_list.HitTest(point, &nFlag);
?????????? //判斷是否點在checkbox上
?????????? if(nFlag == LVHT_ONITEMSTATEICON)
?????????? {
??????????????? AfxMessageBox("點在listctrl的checkbox上");
?????????? }
?????????? *pResult = 0;
????? }
?
15. 右鍵點擊listctrl的item彈出菜單
????? 添加listctrl控件的NM_RCLICK消息相應函數
????? void CTest6Dlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
????? {
?????????? NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
?????????? if(pNMListView->iItem != -1)
?????????? {
??????????????? DWORD dwPos = GetMessagePos();
??????????????? CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
???
??????????????? CMenu menu;
??????????????? VERIFY( menu.LoadMenu( IDR_MENU1 ) );
??????????????? CMenu* popup = menu.GetSubMenu(0);
??????????????? ASSERT( popup != NULL );
??????????????? popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this );
?????????? }
?????????? *pResult = 0;
? }
?
?
16. item切換焦點時(包括用鍵盤和鼠標切換item時),狀態的一些變化順序
????? 添加listctrl控件的LVN_ITEMCHANGED消息相應函數
????? void CTest6Dlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
????? {
?????????? NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
?????????? // TODO: Add your control notification handler code here
???
?????????? CString sTemp;
?
?????????? if((pNMListView->uOldState & LVIS_FOCUSED) == LVIS_FOCUSED &&
??????????? (pNMListView->uNewState & LVIS_FOCUSED) == 0)
?????????? {
??????????????? sTemp.Format("%d losted focus",pNMListView->iItem);
?????????? }
?????????? else if((pNMListView->uOldState & LVIS_FOCUSED) == 0 &&
?????????????? (pNMListView->uNewState & LVIS_FOCUSED) == LVIS_FOCUSED)
?????????? {
??????????????? sTemp.Format("%d got focus",pNMListView->iItem);
?????????? }
?
?????????? if((pNMListView->uOldState & LVIS_SELECTED) == LVIS_SELECTED &&
??????????? (pNMListView->uNewState & LVIS_SELECTED) == 0)
?????????? {
??????????????? sTemp.Format("%d losted selected",pNMListView->iItem);
?????????? }
?????????? else if((pNMListView->uOldState & LVIS_SELECTED) == 0 &&
??????????? (pNMListView->uNewState & LVIS_SELECTED) == LVIS_SELECTED)
?????????? {
??????????????? sTemp.Format("%d got selected",pNMListView->iItem);
?????????? }
???
?????????? *pResult = 0;
????? }
?
17. 得到另一個進程里的listctrl控件的item內容
http://www.codeproject.com/threads/int64_memsteal.asp
18. 選中listview中的item
Q131284: How To Select a Listview Item Programmatically
http://support.microsoft.com/kb/131284/en-us
19. 如何在CListView中使用CListCtrl的派生類
http://www.codeguru.com/cpp/controls/listview/introduction/article.php/c919/
?
20. listctrl的subitem添加圖標
????? m_list.SetExtendedStyle(LVS_EX_SUBITEMIMAGES);
????? m_list.SetItem(..); //具體參數請參考msdn
?
21. 在CListCtrl顯示文件,并根據文件類型來顯示圖標
????? 網上找到的代碼,share
????? BOOL CTest6Dlg::OnInitDialog()
????? {
?????????? CDialog::OnInitDialog();
??
?????????? HIMAGELIST himlSmall;
?????????? HIMAGELIST himlLarge;
?????????? SHFILEINFO sfi;
?????????? char? cSysDir[MAX_PATH];
?????????? CString? strBuf;
?
?????????? memset(cSysDir, 0, MAX_PATH);
??
?????????? GetWindowsDirectory(cSysDir, MAX_PATH);
?????????? strBuf = cSysDir;
?????????? sprintf(cSysDir, "%s", strBuf.Left(strBuf.Find("\\")+1));
?
?????????? himlSmall = (HIMAGELIST)SHGetFileInfo ((LPCSTR)cSysDir,?
????????????????????? 0,?
????????????????????? &sfi,
????????????????????? sizeof(SHFILEINFO),?
????????????????????? SHGFI_SYSICONINDEX | SHGFI_SMALLICON );
??
?????????? himlLarge = (HIMAGELIST)SHGetFileInfo((LPCSTR)cSysDir,?
????????????????????? 0,?
????????????????????? &sfi,?
????????????????????? sizeof(SHFILEINFO),?
????????????????????? SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
??
?????????? if (himlSmall && himlLarge)
?????????? {
??????????????? ::SendMessage(m_list.m_hWnd, LVM_SETIMAGELIST,
???????????????????????????? (WPARAM)LVSIL_SMALL, (LPARAM)himlSmall);
??????????????? ::SendMessage(m_list.m_hWnd, LVM_SETIMAGELIST,
???????????????????????????? (WPARAM)LVSIL_NORMAL, (LPARAM)himlLarge);
?????????? }
?????????? return TRUE;? // return TRUE? unless you set the focus to a control
????? }
?
????? void CTest6Dlg::AddFiles(LPCTSTR lpszFileName, BOOL bAddToDocument)
????? {
?????????? int nIcon = GetIconIndex(lpszFileName, FALSE, FALSE);
?????????? CString strSize;
?????????? CFileFind filefind;
?
?????????? //? get file size
?????????? if (filefind.FindFile(lpszFileName))
?????????? {
??????????????? filefind.FindNextFile();
??????????????? strSize.Format("%d", filefind.GetLength());
?????????? }
?????????? else
??????????????? strSize = "0";
??
?????????? // split path and filename
?????????? CString strFileName = lpszFileName;
?????????? CString strPath;
?
?????????? int nPos = strFileName.ReverseFind('\\');
?????????? if (nPos != -1)
?????????? {
??????????????? strPath = strFileName.Left(nPos);
??????????????? strFileName = strFileName.Mid(nPos + 1);
?????????? }
??
?????????? // insert to list
?????????? int nItem = m_list.GetItemCount();
?????????? m_list.InsertItem(nItem, strFileName, nIcon);
?????????? m_list.SetItemText(nItem, 1, strSize);
?????????? m_list.SetItemText(nItem, 2, strFileName.Right(3));
?????????? m_list.SetItemText(nItem, 3, strPath);
????? }
?
????? int CTest6Dlg::GetIconIndex(LPCTSTR lpszPath, BOOL bIsDir, BOOL bSelected)
????? {
?????????? SHFILEINFO sfi;
?????????? memset(&sfi, 0, sizeof(sfi));
??
?????????? if (bIsDir)
?????????? {
??????????? SHGetFileInfo(lpszPath,?
???????????????????????? FILE_ATTRIBUTE_DIRECTORY,?
???????????????????????? &sfi,?
???????????????????????? sizeof(sfi),?
???????????????????????? SHGFI_SMALLICON | SHGFI_SYSICONINDEX |
???????????????????????? SHGFI_USEFILEATTRIBUTES |(bSelected ? SHGFI_OPENICON : 0));?
??????????? return? sfi.iIcon;
?????????? }
?????????? else
?????????? {
??????????? SHGetFileInfo (lpszPath,?
???????????????????????? FILE_ATTRIBUTE_NORMAL,?
???????????????????????? &sfi,?
???????????????????????? sizeof(sfi),?
???????????????????????? SHGFI_SMALLICON | SHGFI_SYSICONINDEX |?
???????????????????????? SHGFI_USEFILEATTRIBUTES | (bSelected ? SHGFI_OPENICON : 0));
??????????? return?? sfi.iIcon;
?????????? }
?????????? return? -1;
????? }
?
22. listctrl內容進行大數據量更新時,避免閃爍
????? m_list.SetRedraw(FALSE);
????? //更新內容
????? m_list.SetRedraw(TRUE);
????? m_list.Invalidate();
????? m_list.UpdateWindow();
?
或者參考
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cwnd.3a3a.setredraw.asp
?
23. listctrl排序
Q250614:How To Sort Items in a CListCtrl in Report View
http://support.microsoft.com/kb/250614/en-us
?
24. 在listctrl中選中某個item時動態改變其icon或bitmap
Q141834: How to change the icon or the bitmap of a CListCtrl item in Visual C++
http://support.microsoft.com/kb/141834/en-us
25. 在添加item后,再InsertColumn()后導致整列數據移動的問題
Q151897: CListCtrl::InsertColumn() Causes Column Data to Shift
http://support.microsoft.com/kb/151897/en-us
?
26. 關于listctrl第一列始終居左的問題
解決辦法:把第一列當一個虛列,從第二列開始插入列及數據,最后刪除第一列。
?????
具體解釋參閱?? http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/structures/lvcolumn.asp
?
27. 鎖定column header的拖動
http://msdn.microsoft.com/msdnmag/issues/03/06/CQA/
?
28. 如何隱藏clistctrl的列
??? 把需隱藏的列的寬度設為0,然后檢測當該列為隱藏列時,用上面第27點的鎖定column 的拖動來實現
29. listctrl進行大數據量操作時,使用virtual list???
http://www.codeguru.com/cpp/controls/listview/advanced/article.php/c4151/
http://www.codeproject.com/listctrl/virtuallist.asp
?
30. 關于item只能顯示259個字符的問題
解決辦法:需要在item上放一個edit。
?
31. 響應在listctrl的column header上的鼠標右鍵單擊
Q125694: How To Find Out Which Listview Column Was Right-Clicked
http://support.microsoft.com/kb/125694/en-us
?
32. 類似于windows資源管理器的listview
Q234310: How to implement a ListView control that is similar to Windows Explorer by using DirLV.exe
http://support.microsoft.com/kb/234310/en-us
?
33. 在ListCtrl中OnTimer只響應兩次的問題
Q200054:
PRB: OnTimer() Is Not Called Repeatedly for a List Control
http://support.microsoft.com/kb/200054/en-us
34. 以下為一些為實現各種自定義功能的listctrl派生類
????????? (1)??? 拖放???????
?????????????????? http://www.codeproject.com/listctrl/dragtest.asp
?????????????????? 在CListCtrl和CTreeCtrl間拖放
?????????????????? http://support.microsoft.com/kb/148738/en-us
?
????????? (2)??? 多功能listctrl
?????????????????? 支持subitem可編輯,圖標,radiobutton,checkbox,字符串改變顏色的類
?????????????????? http://www.codeproject.com/listctrl/quicklist.asp
?
?????????????????? 支持排序,subitem可編輯,subitem圖標,subitem改變顏色的類
?????????????????? http://www.codeproject.com/listctrl/ReportControl.asp
????????? (3)??? subitem中顯示超鏈接
?????????????????? http://www.codeproject.com/listctrl/CListCtrlLink.asp
????????? (4)??? subitem的tooltip提示
?????????????????? http://www.codeproject.com/listctrl/ctooltiplistctrl.asp
????????? (5)??? subitem中顯示進度條???
?????????????????? http://www.codeproject.com/listctrl/ProgressListControl.asp
?????????????????? http://www.codeproject.com/listctrl/napster.asp
?????????????????? http://www.codeguru.com/Cpp/controls/listview/article.php/c4187/
????????? (6)??? 動態改變subitem的顏色和背景色
??????????????????? http://www.codeproject.com/listctrl/highlightlistctrl.asp
??? ??? ??? ??? ??? http://www.codeguru.com/Cpp/controls/listbox/colorlistboxes/article.php/c4757/
?
????????? (7)??? 類vb屬性對話框
??????????????????? http://www.codeproject.com/listctrl/propertylistctrl.asp
??????????????????? http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c995/
??????????????????? http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c1041/
?
????????? (8)??? 選中subitem(只高亮選中的item)
??????????????????? http://www.codeproject.com/listctrl/SubItemSel.asp
??????????????????? http://www.codeproject.com/listctrl/ListSubItSel.asp
?
????????? (9)??? 改變行高
??????????????????? http://www.codeproject.com/listctrl/changerowheight.asp
?
????????? (10)?? 改變行顏色
??????????????????? http://www.codeproject.com/listctrl/coloredlistctrl.asp
?
????????? (11)?? 可編輯subitem的listctrl
??????????????????? http://www.codeproject.com/listctrl/nirs2000.asp
??????????????????? http://www.codeproject.com/listctrl/editing_subitems_in_listcontrol.asp
?
????????? (12)?? subitem可編輯,插入combobox,改變行顏色,subitem的tooltip提示
??????????????????? http://www.codeproject.com/listctrl/reusablelistcontrol.asp
?
????????? (13)?? header 中允許多行字符串
??????????????????? http://www.codeproject.com/listctrl/headerctrlex.asp
?
????????? (14)?? 插入combobox
??????????????????? http://www.codeguru.com/Cpp/controls/listview/editingitemsandsubitem/article.php/c979/
?
????????? (15)?? 添加背景圖片
??????????????????? http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c4173/
??????????????????? http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c983/
??????????????????? http://www.vchelp.net/vchelp/archive.asp?type_id=9&class_id=1&cata_id=1&article_id=1088&search_term=
???
????????? (16)? 自適應寬度的listctrl
??????????????????? http://www.codeproject.com/useritems/AutosizeListCtrl.asp
??? ?? ?? (17)? 改變ListCtrl高亮時的顏色(默認為藍色)
??? ?? ?? ?? ?? ?? 處理 NM_CUSTOMDRAW
?????????? http://www.codeproject.com/listctrl/lvcustomdraw.asp
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
m_mm_host_ListCtrl.DeleteAllItems()
m_mm_host_ListCtrl.ModifyStyle(0,LVS_REPORT);
?////////////
?LONG lStyle = m_mm_host_ListCtrl.SendMessage(
????????LVM_GETEXTENDEDLISTVIEWSTYLE);
?lStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES |
????LVS_EX_HEADERDRAGDROP;
?m_mm_host_ListCtrl.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
???(LPARAM)lStyle);
?////////////
?或者:
LONG lStyle;
?lStyle = GetWindowLong(m_mm_host_ListCtrl.m_hWnd, GWL_STYLE);//獲取當前窗口style
?lStyle &= ~LVS_TYPEMASK; //清除顯示方式位
?lStyle |= LVS_REPORT; //設置style
?SetWindowLong(m_mm_host_ListCtrl.m_hWnd, GWL_STYLE, lStyle);//設置style
?
?DWORD dwStyle = m_mm_host_ListCtrl.GetExtendedStyle();
?dwStyle |= LVS_EX_FULLROWSELECT;//選中某行使整行高亮(只適用與report風格的listctrl)
?dwStyle |= LVS_EX_GRIDLINES;//網格線(只適用與report風格的listctrl)
?dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
?m_mm_host_ListCtrl.SetExtendedStyle(dwStyle); //設置擴展風格
?/////////////
m_mm_host_ListCtrl.InsertColumn(0,"日志序號",LVCFMT_CENTER,60,0);
?m_mm_host_ListCtrl.InsertColumn(1,"來源",LVCFMT_CENTER,80,1);
?m_mm_host_ListCtrl.InsertColumn(2,"日期",LVCFMT_CENTER,80,2);
?m_mm_host_ListCtrl.InsertColumn(3,"時間",LVCFMT_CENTER,80,3);
?m_mm_host_ListCtrl.InsertColumn(4,"分類",LVCFMT_CENTER,80,4);
?m_mm_host_ListCtrl.InsertColumn(5,"ID",LVCFMT_CENTER,50,5);
?m_mm_host_ListCtrl.InsertColumn(6,"用戶",LVCFMT_CENTER,120,6);
?m_mm_host_ListCtrl.InsertColumn(7,"計算機",LVCFMT_CENTER,120,7);
/////////////////////////////////////////////////////////////////////////
?
???? #include <stdio.h>
//#include <unistd.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#define BUFFER_SIZE 1024*64
//#define DEFAULT_FILE ?"C:\\ossec-extracted-evt.log"
FILE *fp;
int event_record=0;
/* Event logging local structure */
typedef struct _os_el
{
??? int time_of_last;?
??? char *event_name;
??? EVENTLOGRECORD *er;
??? HANDLE h;
??? DWORD record;
}os_el;
os_el el[3];
int el_last = 0;
/** int startEL(char *app, os_el *el)
?* Starts the event logging for each el
?*/
int startEL(char *app, os_el *el)
{
??? /* Opening the event log */
??? el->h = OpenEventLog(NULL, app);
??? if(!el->h)
??? {
??????? return(0);????
??? }
??? el->event_name = app;
??? GetOldestEventLogRecord(el->h, &el->record);
??? return(1);
}
?
/** char *el_GetCategory(int category_id)
?* Returns a string related to the category id of the log.
?*/
//得到一個事件的類型,,輸入是一個事件類型id輸出是漢字串
char *el_GetCategory(int category_id)
{
??? char *cat;
??? switch(category_id)
??? {
??????? case EVENTLOG_ERROR_TYPE:
??????????? cat = "錯誤";
??????????? break;
??????? case EVENTLOG_WARNING_TYPE:
??????????? cat = "警告";
??????????? break;
??????? case EVENTLOG_INFORMATION_TYPE:
??????????? cat = "信息";
??????????? break;
??????? case EVENTLOG_AUDIT_SUCCESS:
??????????? cat = "審核成功";
??????????? break;
??????? case EVENTLOG_AUDIT_FAILURE:
??????????? cat = "審核失敗";
??????????? break;
??????? default:
??????????? cat = "Unknown";
??????????? break;
??? }
??? return(cat);
}
/** int el_getEventDLL(char *evt_name, char *event_sourcename, char *event)
?* Returns the event.
?*/
int el_getEventDLL(char *evt_name, char *event_sourcename, char *event)
{
??? HKEY key;
??? DWORD ret;
??? char keyname[256];
??? keyname[255] = '\0';
??? _snprintf(keyname, 254,
??????????? "System\\CurrentControlSet\\Services\\EventLog\\%s\\%s",
??????????? evt_name,
??????????? event_sourcename);
??? /* Opening registry */????
??? if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_ALL_ACCESS, &key)
??????????? != ERROR_SUCCESS)
??? {
??????? return(0);???
??? }
??? ret = MAX_PATH -1;?
??? if (RegQueryValueEx(key, "EventMessageFile", NULL,
??????????????? NULL, (LPBYTE)event, &ret) != ERROR_SUCCESS)
??? {
??????? event[0] = '\0';?
??????? return(0);
??? }
??? RegCloseKey(key);
??? return(1);
}
?
/** char *el_Getmessage()
?* Returns a descriptive message of the event.
?*/
//輸出是時間描述信息
char *el_GetMessage(EVENTLOGRECORD *er,? char *event_name,
????? char * event_sourcename, LPTSTR *el_sstring)
{
??? DWORD fm_flags = 0;
??? char tmp_str[257];
??? char event[MAX_PATH +1];
??? char *curr_str;
??? char *next_str;
??? LPSTR message = NULL;
??? HMODULE hevt;
??? /* Initializing variables */
??? event[MAX_PATH] = '\0';
??? tmp_str[256] = '\0';
??? /* Flags for format event */
??? fm_flags |= FORMAT_MESSAGE_FROM_HMODULE;
??? fm_flags |= FORMAT_MESSAGE_ALLOCATE_BUFFER;
??? fm_flags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;
??? /* Get the file name from the registry (stored on event) */
??? if(!el_getEventDLL(event_name, event_sourcename, event))
??? {
??????? return(NULL);????
??? }????
??? curr_str = event;
??? /* If our event has multiple libraries, try each one of them */
??? while((next_str = strchr(curr_str, ';')))
??? {
??????? *next_str = '\0';
??????? next_str++;
??????? ExpandEnvironmentStrings(curr_str, tmp_str, 255);
??????? hevt = LoadLibraryEx(tmp_str, NULL, DONT_RESOLVE_DLL_REFERENCES);
??????? if(hevt)
??????? {
??????????? if(!FormatMessage(fm_flags, hevt, er->EventID,
??????????????????????? 0,
??????????????????????? (LPTSTR) &message, 0, el_sstring))
??????????? {
??????????????? message = NULL;???
??????????? }
??????????? FreeLibrary(hevt);
??????????? /* If we have a message, we can return it */
??????????? if(message)
??????????????? return(message);
??????? }
??????? curr_str = next_str;??
??? }
??? ExpandEnvironmentStrings(curr_str, tmp_str, 255);
??? hevt = LoadLibraryEx(tmp_str, NULL, DONT_RESOLVE_DLL_REFERENCES);
??? if(hevt)
??? {
??????? int hr;???
??????? if(!(hr = FormatMessage(fm_flags, hevt, er->EventID,
??????????????????????? 0,
??????????????????????? (LPTSTR) &message, 0, el_sstring)))
??????? {
??????????? message = NULL;???
??????? }
??????? FreeLibrary(hevt);
??????? /* If we have a message, we can return it */
??????? if(message)
??????????? return(message);
??? }
??? return(NULL);
}
?
/** void Read_event(os_el *el)
?* Reads the event log.
?*/
void Read_event(os_el *el, int printit)
{
??? DWORD nstr;
??? DWORD user_size;
??? DWORD domain_size;
??? DWORD read, needed;
??? int size_left;
??? int str_size;
??? char *mbuffer[BUFFER_SIZE];
??? LPSTR sstr = NULL;
??? char *tmp_str = NULL;
??? char *event_category;???//事件類型
??? char *event_sourcename;???//事件來源
??? char *event_computername;??//事件計算機名
??? char *event_descriptive_msg;?//事件描述
??? char event_el_user[257];??//事件用戶
??? char event_el_domain[257];??//事件域
??? char el_string[1025];
??? char final_out_msg[1024];??//最后輸出的信息
??? LPSTR el_sstring[57];
??? /* Er must point to the mbuffer */
??? el->er = (EVENTLOGRECORD *) &mbuffer;
??? /* Zeroing the last values */
??? el_string[1024] = '\0';
??? event_el_user[256] = '\0';
??? event_el_domain[256] = '\0';
??? final_out_msg[1023] = '\0';
??? el_sstring[56] = NULL;
??? /* Reading the event log */????
??? while(ReadEventLog(el->h,
??????????????? EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ,
??????????????? 0,
??????????????? el->er, BUFFER_SIZE -1, &read, &needed))
??? {
??????? while(read > 0)
??????? {
??????????? /* We need to initialize every variable before the loop */
???//得到事件的類型
??????????? event_category = el_GetCategory(el->er->EventType);
???//得到事件來源
??????????? event_sourcename = (LPSTR) ((LPBYTE) el->er + sizeof(EVENTLOGRECORD));
???//得到計算機名
??????????? event_computername = event_sourcename + strlen(event_sourcename) + 1;
???//給描述信息初始化
??????????? event_descriptive_msg = NULL;
??????????? /* 初始化domain/user尺寸 */
??????????? user_size = 255; domain_size = 255;
??????????? event_el_domain[0] = '\0';
??????????? event_el_user[0] = '\0';
??????????? /* 設置時間的一些描述 some description */
??????????? if(el->er->NumStrings)
??????????? {?
??????????????? size_left = 1020;?
??????????????? sstr = (LPSTR)((LPBYTE)el->er + el->er->StringOffset);
??????????????? el_string[0] = '\0';
??????????????? for (nstr = 0;nstr < el->er->NumStrings;nstr++)
??????????????? {
??????????????????? str_size = strlen(sstr);?
??????????????????? strncat(el_string, sstr, size_left);
??????????????????? tmp_str= strchr(el_string, '\0');
??????????????????? if(tmp_str)
??????????????????? {
??????????????????????? *tmp_str = ' ';??
??????????????????????? tmp_str++; *tmp_str = '\0';
??????????????????? }
??????????????????? size_left-=str_size + 1;
??????????????????? if(nstr <= 54)
??????????????????????? el_sstring[nstr] = (LPSTR)sstr;
??????????????????? sstr = strchr( (LPSTR)sstr, '\0');
??????????????????? sstr++;
?????
??????????????? }
??????????????? /* Get a more descriptive message (if available) */
??????????????? event_descriptive_msg = el_GetMessage(el->er, el->event_name, event_sourcename, el_sstring);
??????????????? if(event_descriptive_msg != NULL)
??????????????? {
??????????????????? /* Remove any \n or \r */
??????????????????? tmp_str = event_descriptive_msg;???
??????????????????? while((tmp_str = strchr(tmp_str, '\n')))
??????????????????? {
??????????????????????? *tmp_str = ' ';
??????????????????????? tmp_str++;
??????
?????
??????????????????? }???
??????????????????? tmp_str = event_descriptive_msg;???
??????????????????? while((tmp_str = strchr(tmp_str, '\r')))
??????????????????? {
??????????????????????? *tmp_str = ' ';
??????????????????????? tmp_str++;
??????//strchr(tmp_str, '\n');
??????????????????? }???
??????????????? }
??????????? }
??????????? else
??????????? {
??????????????? strncpy(el_string, "(no message)", 1020);?
??????????? }
??????????? /* 得到username */
??????????? if (el->er->UserSidLength)
??????????? {
??????????????? SID_NAME_USE account_type;
??????????????? if(!LookupAccountSid(NULL, (SID *)((LPSTR)el->er + el->er->UserSidOffset),
??????????????????????????? event_el_user, &user_size, event_el_domain, &domain_size, &account_type))??
??????????????? {
??????????????????? strncpy(event_el_user, "(no user)", 255);
??????????????????? strncpy(event_el_domain, "no domain", 255);
??????????????? }
??????????? }
??????????? else
??????????? {
??????????????? strncpy(event_el_user, "A", 255);?
??????????????? strncpy(event_el_domain, "N", 255);?
??????????? }
??????????? if(printit)
??????????? {
??????????????? tm?? *event_time?? =?? localtime((const?? long?? *)&el->er->TimeWritten);
??????????????? _snprintf(final_out_msg, 1022,
??????????????????????? "事件記錄序號:%d\n事件:%s\n日期:%.4hd-%.2hd-%.2hd\n時間: %.2hd:%.2hd:%.2hd\n事件類型:%s\n事件來源:%s\n事件ID:(%u)\n用戶:%s/%s\n計算機:%s\n描述:\n%s\n\n\n",
??????event_record,
??????el->event_name,
??????event_time->tm_year?? +?? 1900,
??????event_time->tm_mon?? +?? 1,
??????event_time->tm_mday,
??????event_time->tm_hour,
??????event_time->tm_min,
??????event_time->tm_sec,?
??????????????????????? event_category,
??????event_sourcename,
???????????????????????
??????????????????????? (WORD)el->er->EventID,
??????????????????????? event_el_domain,
??????????????????????? event_el_user,
???????????????????????
??????event_computername,
??????????????????????? event_descriptive_msg != NULL?event_descriptive_msg:el_string);?
??????????????
??????? ?fprintf(fp, "%s\n", final_out_msg);?
??????????? }
??????????? if(event_descriptive_msg != NULL)
??????????????? LocalFree(event_descriptive_msg);
??????????? /* Changing the point to the er */
??????????? read -= el->er->Length;
??????????? el->er = (EVENTLOGRECORD *)((LPBYTE) el->er + el->er->Length);
???event_record++;
??????? }??
??????? /* Setting er to the beginning of the buffer */?
??????? el->er = (EVENTLOGRECORD *)&mbuffer;
??
??? }
}
/** void win_startel()
?* Starts the event logging for windows
?*/
void win_startel(char *eventlog)
{
??? event_record=1;
?startEL(eventlog, &el[el_last]);
??? Read_event(&el[el_last],1);
??? el_last++;
}
////////////////////////////////////////////////////////
////main////////////////////////////////////////////////
////////////////////////////////////////////////////////
int main()
{
?? fp = fopen("C:\\Documents and Settings\\Administrator\\桌面\\Read_log.txt","w");
?? if(!fp)
?{
??printf("Unable to open file\n");
??exit(1);
?}
?? else
?? {
??printf("open file\n");?
?? }
?fprintf(fp, "\n\n***********安全日志***********\n\n\n");?
?win_startel("Security");
?printf("安全日志打開\n");
?fprintf(fp, "\n\n***********應用日志***********\n\n\n");?
?win_startel("Application");
?printf("應用日志打開\n");
?fprintf(fp, "\n\n***********系統日志***********\n\n\n");?
?win_startel("System");
?printf("系統日志打開\n");
?
?
?fclose(fp);
?if(fclose(fp))
?{
??printf("關閉了\n");
?}
?else
?{
??printf("還開著呢了,,抓緊關它吧\n");
?}
?return(0);
}
摘要: 第一章 文件相關的API函數
Api函數名 函數說明 適用范圍W16 W95 WNTmmioWrite 寫文件 否 是 是WriteFile 寫文件 否 是 是ExtractAssociatedIcon 從文件或相關EXE中獲取圖標句柄 否 是 是ExtractIcon 從可執行文件中返回圖標句柄 否 是 是LZRead 從壓縮文件中讀入數據 是 是 是GetPrivateProfileStr...
閱讀全文
如何實現繁簡體互換?
// j2f.cpp : 簡體(gb)==>繁體==>big5的過程
// 反向轉換是類似的.
// 注意直接從簡體-->big5不能做到一一對應.會有很多?出現,
// 故此需要先轉成繁體.再轉成big5.
// 我感覺這種方法應當和winnt或office里提供的繁簡或字符集互轉是一致的.
#include "stdafx.h"
#include
#include
#include
#include
#include
using namespace std;
void j2f(const string &s)
{
int n=s.length ();
int r=LCMapString(
MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC),
LCMAP_TRADITIONAL_CHINESE,
s.c_str (),s.length (),NULL,0);
if (!r) cout <<"error :"<
char *ft=new char[r+1];
r=LCMapString(
MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC),
LCMAP_TRADITIONAL_CHINESE,
s.c_str (),s.length (),ft,r+1);//這個api搞掂簡體轉繁體,下面會打印繁體出來
if (r) {
ft[r]=0;
cout<
wchar_t *pws=new wchar_t[r+1];
int r1=MultiByteToWideChar(936,0,ft,r,pws,r+1);
BOOL f=FALSE;
r1=WideCharToMultiByte(950,0,pws,r1,ft,r+1,"?",&f);//代碼頁切換搞掂gb->big5
ft[r1]=0;
cout<<<"(";
for (int i=0;i cout<<"";
printf("0x%02x ",(BYTE)ft[i]);
}
cout<<")"<
delete [] pws;
}
delete []ft;
}
//從標準輸入簡體國標-->big5繁體標準輸出,輸入兩個空行退出
int main(int argc, char* argv[])
{
for(;;){
char line[1024];
cin.getline (line,sizeof(line));
string s(line);
if (!cin ||s.length ()==0) break;
j2f(s);
}
_getch();
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.首先請參閱其他技術專欄中用VB6.0訪問注冊表,創建
HKEY_LOCAL_MACHINE,\SYSTEM\CurrentControlSet\Services\Eventlog\Eventlog2\Eventlog2鍵,并且寫入EventMessageFile,value為C:\WINNT\Microsoft.NET\Framework\v1.1.4322\EventLogMessages.dll
2.在C#.net使用以下代碼寫日志
//輸出日志的CLASS
using System;
using System.Diagnostics;
using System.Text;
namespace CorePlus.Framework.Utility
{
?/// <summary>
?/// 寫日志的CLASS
?/// </summary>
?public class LogUtility
?{
? public enum EVENT
? {
?? /// <summary>重大錯誤</summary>
?? EVENT_ERROR,
?? /// <summary>操作失敗</summary>
?? EVENT_FAILUREAUDIT,
?? /// <summary>一般信息</summary>
?? EVENT_INFORMATION,
?? /// <summary>有效的,成功的操作</summary>
?? EVENT_SUCCESSAUDIT,
?? /// <summary>警告</summary>
?? EVENT_WARNING,
? }
? private static TextWriterTraceListener listner = null;
? /// <summary>
? /// 構造函數
? /// </summary>
? public LogUtility () {}
? /// <param name="loginID">登錄ID</param>
? /// <param name="screenID">畫面ID</param>
? /// <param name="level">警告級別</param>
? /// <param name="message">日志信息</param>
? public static void Logging (
?? string loginID,
?? string screenID,
?? EVENT level,
?? string message )
? {
?? // 變量定義
?? StringBuilder? outputMessage = null; // 輸出的信息
?? string??? targetLevelString = null;
?? EventLogEntryType Eventtype = new EventLogEntryType();
?? switch (level)
?? {
??? case EVENT.EVENT_ERROR:
???? Eventtype = EventLogEntryType.Error;
???? break;
??? case EVENT.EVENT_FAILUREAUDIT:
???? Eventtype = EventLogEntryType.FailureAudit;
???? break;
??? case EVENT.EVENT_INFORMATION:
???? Eventtype = EventLogEntryType.Information;
???? break;
??? case EVENT.EVENT_SUCCESSAUDIT:
???? Eventtype = EventLogEntryType.SuccessAudit;
???? break;
??? case EVENT.EVENT_WARNING:
???? Eventtype = EventLogEntryType.Warning;
???? break;
?? }
?? // 日志信息的拼合
?? outputMessage = MakeMessage( loginID, screenID, targetLevelString, message );
?? // 寫日志
?? Logging( Eventtype, outputMessage.ToString() );
? }
? /// <summary>
? /// 向日志管理器寫日志
? /// </summary>
? /// <param name="level">錯誤級別</param>
? /// <param name="message">輸出的信息</param>
? private static void Logging ( EventLogEntryType level, string message )
? {
?? // 變量定義
?? string? logName? = null; // 日志名
?? string? machineName = null; // 機器名
?? string? sourceName = null; // SourceName
?? EventLog eventLog = null; // EventLog
?? logName? = "Eventlog2";? // 日志名
?? machineName = "."; // 機器名
?? sourceName = "Eventlog2"; // SourceName
?? eventLog = new EventLog( logName, machineName, sourceName );
?? eventLog.WriteEntry( message,level );
?? eventLog = null;
? }
? /// <summary>
? /// 日志最終拼合
? /// </summary>
? /// <param name="loginID">登錄ID</param>
? /// <param name="screenID">畫面ID</param>
? /// <param name="levelString">錯誤級別</param>
? /// <param name="message">日志信息</param>
? /// <returns>輸出的日志信息</returns>
? private static StringBuilder MakeMessage (
?? string loginID,
?? string screenID,
?? string levelString,
?? string message )
? {
?? // 變量定義
?? StringBuilder retMessage = new StringBuilder();
?? retMessage.Append( "【登錄ID】" );
?? retMessage.Append( loginID );
?? retMessage.Append( "\n【畫面ID】" );
?? retMessage.Append( screenID );
?? retMessage.Append( "\n【錯誤級別】" );
?? retMessage.Append( levelString );
?? retMessage.Append( "\n【錯誤信息】\n" );
?? retMessage.Append( message );
?? return retMessage;
??? }
? }
}
// 在FORM中輸出日志
? private void button1_Click(object sender, System.EventArgs e)
? {
?? LogUtility.Logging( "bbbbbb","22222222",LogUtility.EVENT.EVENT_ERROR,"3333333" );
? }
運行完程序后打開日志管理器看看~~~~~~~~~怎么樣?不錯吧,呵呵.
?
?
?
////////////////////////////////////////////////////////////////////////////
1.窗口信息
MS為我們提供了打開特定桌面和枚舉桌面窗口的函數。
hDesk=OpenDesktop(lpszDesktop,0,FALSE,DESKTOP_ENUMERATE);
//打開我們默認的Default桌面;
EnumDesktopWindows(hDesk,(WNDENUMPROC)EnumWindowProc,0);
//枚舉打開桌面上的所有窗口,由回調函數實現。
BOOL __stdcall EnumWindowProc(HWND, LPARAM);
//在回調函數中,我們可以獲得窗口的標題和相關進程,線程信息;
GetWindowText(hWnd,szWindowText,dwMaxCount);
GetWindowThreadProcessId(hWnd,&dwPID);
2.設備驅動器信息(服務和設備驅動器差不多,在此不做重復)
設備驅動信息有服務控制管理器(SCM)來管理的,我要打開服務控制管理器,并枚舉所有的設備驅動器。
OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
//以所有權限打開服務控制管理器;
EnumServicesStatus(schManager,dwDeviceType,dwDeviceState,
EnumStatus,dwBufSize,&dwBytesNeeded,
&dwDevicesReturned,&dwResumeHandle))
//枚舉所有設備的當前狀態;
CloseServiceHandle(schManager);
//記住,在結束訪問后要關閉服務句柄;
OpenService(schManager,szDeviceName,SERVICE_ALL_ACCESS);
//打開特定的設備驅動器;
QueryServiceConfig(schDevice,lpDeviceConfig,
?? 1024*8,&dwBytesNeeded);
//查詢驅動器的服務配置信息;
QueryServiceStatus(schDevice,&DeviceStatus);
//查詢設備驅動器的當前狀態;
QueryServiceConfig2(schDevice,SERVICE_CONFIG_DESCRIPTION,
(LPBYTE)lpDeviceDescription,8*1024,&dwBytesNeeded)
//查詢設備的描述信息;
StartService(schDevice,0,NULL);
//啟動設備;
ControlService(schDevice,SERVICE_CONTROL_STOP,&DeviceStatus);
//停止設備;
DeleteService(schDevice);
//刪除設備;
3.磁盤信息
我們希望獲得系統所有磁盤的信息,包括軟盤,硬盤,光盤等等;
GetLogicalDriveStrings(dwBufferLength,lpBuffer);
//獲得邏輯設備的信息;
GetVolumeInformation(lpRootPathName,lpVolumeNameBuffer,
dwVolumeNameSize,&dwVolumeSerialNumber,
&dwMaximumComponentLength,&dwFileSystemFlags,
lpFileSystemNameBuffer,dwFileSystemNameSize);
//獲得磁盤卷信息,包括卷名稱和格式類型;
GetDiskFreeSpaceEx(lpRootPathName,&FreeBytesAvailable,
? &TotalNumberOfBytes,&TotalNumberOfFreeBytes);
//探測磁盤的空間使用情況;
4.環境變量
我們可以從注冊表中獲得環境塊的信息:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment,當然要使用注冊表的函數。
RegOpenKeyEx(HKEY_LOCAL_MACHINE,RegKey,0,KEY_QUERY_VALUE,&hKey);
//打開注冊表的鍵;
RegEnumValue(hKey,dwIndex,EnvironVariable,
&dwVariableLength,NULL,NULL,NULL,NULL);
//查詢我們需要的信息值;
GetEnvironmentVariable(EnvironVariable,EnvironString,1024);
//獲得環境變量的字符串信息;
?
?
5.事件記錄信息
OpenEventLog(NULL,szLog);
//打開時間日志記錄;
GetOldestEventLogRecord(hEvent,&dwThisRecord);
//獲得最新的日志信息,以便繼續查找;
ReadEventLog(hEvent,EVENTLOG_FORWARDS_READ │ EVENTLOG_SEQUENTIAL_READ,
?? 0,pEventLogRecord,1024*32,&dwRead,&dwNeeded)
//讀去日志信息;
LookupAccountSid(NULL,pSid,szName,&dwName,szDomain,&dwDomain,&SNU);
//獲取賬戶的SID,以便獲得賬戶的用戶名稱;
GetNumberOfEventLogRecords(hEvent,&dwTotal);
//獲得事件日志的總數;
CloseEventLog(hEvent);
//不要忘記關閉事件句柄;
6.網絡共享
我們使用第二等級的網絡共享搜索;
NetShareEnum(NULL,dwLevel,(PBYTE *)&pBuf,MAX_PREFERRED_LENGTH,&entriesread,&totalentries,&resume);
//列舉所有的共享目錄及相關信息;
NetApiBufferFree(pBuf);
//釋放緩沖區;
NetShareDel(NULL,(char *)lpShareNameW,0);
//刪除網絡共享目錄;
7.網絡適配器信息
我們要探測NIC的信息和網絡流量;
GetAdaptersInfo(&AdapterInfo,&OutBufLen);
//獲取適配器信息;
8.系統性能
獲取系統的存儲器使用情況;
GetPerformanceInfo(&PerfInfo,sizeof(PERFORMACE_INFORMATION))
//獲取系統性能信息;
9.進程/線程/模塊信息
在此我們使用工具幫助函數(ToolHelp32)和系統
OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY │ TOKEN_ADJUST_PRIVILEGES,&hToken);
//打開進程的令牌,提升權限;
AdjustTokenPrivileges(hToken,FALSE,&TokenPrivileges,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
//將進程的權限提升到支持調試(Debug);
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
//創建進程的快照;
Process32First(hProcessSnap,&ProcessEntry32);
Process32First(hProcessSnap,&ProcessEntry32);
//枚舉所有進程;
OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,ProcessEntry32.th32ProcessID);
//打開特定進程,以查詢進程相關信息;
GetProcessTimes(hProcess,&CreateTime,&ExitTime,&KernelTime,&UserTime);
//獲取進程的時間信息;
GetProcessMemoryInfo(hProcess,&PMCounter,sizeof(PMCounter));
//獲取進程的存儲區信息;
GetPriorityClass(hProcess);
//獲取進程的優先權;
GetProcessIoCounters(hProcess,&IoCounters);
//獲取進程的IO使用情況;
CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID);
//創建模塊快照;
Module32First(hModuleSnap, &ModuleEntry32);
Module32Next(hModuleSnap, &ModuleEntry32);
//枚舉進程模塊信息;
CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
//創建線程快照;
Thread32First(hThreadSnap, &ThreadEntry32);
Thread32Next(hThreadSnap, &ThreadEntry32);
//枚舉線程信息;
OpenThread(THREAD_ALL_ACCESS,FALSE,ThreadEntry32.th32ThreadID);
//打開線程,須自己獲得此函數地址;
TerminateProcess(hProcess,0);
//終止進程;
SuspendThread(hThread);
//懸掛線程;
ResumeThread(hThread);
//激活線程;
?
?
10.關機
AdjustTokenPrivileges(hToken,FALSE,&TokenPrivileges,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
//調整進程令牌,使其支持關機;
ExitWindowsEx(EWX_LOGOFF,0);
//注銷系統;
LockWorkStation();
//鎖定系統;
InitiateSystemShutdown(NULL,szMessage,dwTimeout,FALSE,bSig);
//支持到記時和消息顯示的關機/重啟;
SetSystemPowerState(bSig,FALSE);
//系統休眠/冬眠;
11.用戶信息
NetUserEnum(NULL,dwLevel,FILTER_NORMAL_ACCOUNT,(LPBYTE*)&pBuf, dwPrefMaxLen,&dwEntriesRead,&dwTotalEntries,&dwResumeHandle);
//枚舉系統用戶信息;
NetUserDel(NULL,lpUserNameW);
//刪除指定用戶;
?
12.系統版本信息
GetVersionEx((LPOSVERSIONINFO)&osviex);
//獲取操作系統的版本信息;
我們也可以通過注冊表(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)獲取相關信息:
GetTickCount();
//獲取開機時間;
GetComputerName(szInfo,&dwInfo);
//獲取計算機名稱;
GetUserName(szInfo,&dwInfo);
//獲取計算機用戶名;
GetWindowsDirectory(szInfo,MAX_PATH+1);
//獲取Windows目錄;
GetSystemDirectory(szInfo,MAX_PATH+1);
//獲取系統目錄;
/////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
事件記錄信息
OpenEventLog(NULL,szLog);
//打開時間日志記錄;
GetOldestEventLogRecord(hEvent,&dwThisRecord);
//獲得最新的日志信息,以便繼續查找;
ReadEventLog(hEvent,EVENTLOG_FORWARDS_READ │ EVENTLOG_SEQUENTIAL_READ,
?? 0,pEventLogRecord,1024*32,&dwRead,&dwNeeded)
//讀去日志信息;
LookupAccountSid(NULL,pSid,szName,&dwName,szDomain,&dwDomain,&SNU);
//獲取賬戶的SID,以便獲得賬戶的用戶名稱;
GetNumberOfEventLogRecords(hEvent,&dwTotal);
//獲得事件日志的總數;
CloseEventLog(hEvent);
//不要忘記關閉事件句柄;