桌面图标弹出提示

来源:岁月联盟 编辑:exp 时间:2011-11-15

 

之前看见过某些软件,安装完毕后会在桌面图标的旁边弹出一个提示框.然后就尝试着自己也实现一下这个效果.

先来看看最终效果:

 

 

/
 
/

 

实现方法

首先,必须知道图标在屏幕上的位置.用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位有问题,以下为修正后的代码

http://www.2cto.com/uploadfile/2011/1115/20111115061757821.zip

 

 

 

摘自 邓学彬(泪闯天涯)的专栏