之前看見過某些軟體,安裝完畢後會在案頭表徵圖的旁邊彈出一個提示框.然後就嘗試著自己也實現一下這個效果.
先來看看最終效果:
實現方法
首先,必須知道表徵圖在螢幕上的位置.用SPY類工具探測了一下(這裡我用的是彗星小助手),
發現"案頭"是一個ListView控制項,既然是這個控制項,那就可以發送LVM_GETITEMTEXT訊息來擷取各個表徵圖的名稱,判斷哪個是我們要找的.
然後發送LVM_GETITEMRECT訊息擷取表徵圖的位置.
最後在表徵圖旁邊建立一個提示視窗,這裡我使用了UpdateLayeredWindow
需要注意的是:在64位作業系統上,LVM_GETITEMTEXT時那個LVITEM結構不太一樣.需要判斷一下作業系統是否64位的.
部分代碼
- BOOL CIconToolTipDlg::GetIconRect(HWND hDeskWnd,CString strIconName,LPRECT lpRect)
- {
- BOOL bRet=FALSE;
- //-----------------------------
- //遍曆外部進程所有表徵圖
- DWORD PID=0;
- GetWindowThreadProcessId(hDeskWnd,&PID);
- HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);
- if(!hProcess){
- TRACE(_T("擷取進程控制代碼操作失敗hWnd=%dPID=%d"),hDeskWnd,PID);
- }else{
- LVITEMA* pLVITEM=(LVITEMA*)VirtualAllocEx(hProcess,NULL,sizeof(LVITEM),MEM_COMMIT,PAGE_READWRITE);
- char* pszText=(char*)VirtualAllocEx(hProcess,NULL,512,MEM_COMMIT,PAGE_READWRITE);
- RECT* pItemRc=(RECT*)VirtualAllocEx(hProcess,NULL,sizeof(RECT),MEM_COMMIT,PAGE_READWRITE);
- RECT rc;
- if(!pItemRc || !pLVITEM){
- TRACE(_T("無法分配記憶體!"));
- }else{
- LVITEMA LVITEM;
- LVITEM.mask=LVIF_TEXT;
- LVITEM.cchTextMax=512;
- LVITEM.pszText=pszText;
- char ItemBuf[512];
- int nCount=::SendMessage(hDeskWnd,LVM_GETITEMCOUNT,0,0);
- for(int iItem=0;iItem<nCount;iItem++){
- LVITEM.iItem=iItem;
- LVITEM.iSubItem=0;
- //將設定好的結構插入目標進程
- WriteProcessMemory(hProcess,pLVITEM,&LVITEM,sizeof(LVITEM),NULL);
- //發送LVM_GETITEM訊息
- BOOL r=(BOOL)::SendMessage(hDeskWnd,LVM_GETITEMTEXTA,iItem,(LPARAM)pLVITEM);
- //擷取pszText
- ReadProcessMemory(hProcess,pszText,ItemBuf,512,NULL);
- CString str=CString(ItemBuf);
- //AfxMessageBox(str);
- if(str==strIconName){
- ::SendMessage (hDeskWnd,LVM_GETITEMRECT,iItem,(LPARAM)pItemRc);
- ReadProcessMemory(hProcess,pItemRc,&rc,sizeof(RECT),NULL);
- memcpy(lpRect,&rc,sizeof(RECT));
- bRet=TRUE;
- break;
- }
-
- }
- VirtualFreeEx(hProcess,pLVITEM,0,MEM_RELEASE);
- VirtualFreeEx(hProcess,pszText,0,MEM_RELEASE);
- VirtualFreeEx(hProcess,pItemRc,0,MEM_RELEASE);//釋放記憶體
- }
- CloseHandle(hProcess);
- }
- //-----------------------------
- return bRet;
- }
完整代碼下載:
以下代碼在VS2005、Windows7x64環境測試通過.如果哪位測試不行請留言說明一下作業系統.
最早上傳的代碼判斷是否64位有問題,以下為修正後的代碼