笔记+枚举托盘图标

本文只是个人笔记,也就是说跟别人学的,参考:

http://www.codeproject.com/KB/applications/ShellTrayInfo.aspx

http://www.vbgood.com/viewthread.php?tid=79409

 

----------------------------------头文件util.h--------------------------------------


#include <Psapi.h>
#pragma comment(lib,"Psapi.lib")

struct TRAYDATA
{
    HWND hwnd;               
    UINT uID;               
    UINT uCallbackMessage;   
    DWORD Reserved[2];       
    HICON hIcon;               
};
TCHAR GetDriveLetter(LPCTSTR lpDevicePath)
{
    TCHAR d = _T('A');
    while(d <= _T('Z'))
    {
        TCHAR szDeviceName[3] = {d,_T(':'),_T('/0')};   
        TCHAR szTarget[512] = {0};
        if(QueryDosDevice(szDeviceName, szTarget, 511) != 0)           
            if(_tcscmp(lpDevicePath, szTarget) == 0)
                return d;
        d++;
    }
    return NULL;
}

HWND FindTrayToolbarWindow()
{
    HWND hWnd = ::FindWindow(_T("Shell_TrayWnd"), NULL);
    if(hWnd)
    {
        hWnd = ::FindWindowEx(hWnd,NULL,_T("TrayNotifyWnd"), NULL);
        if(hWnd)
        {
            hWnd = ::FindWindowEx(hWnd,NULL,_T("SysPager"), NULL);
            if(hWnd)
            {               
                hWnd = ::FindWindowEx(hWnd, NULL,_T("ToolbarWindow32"), NULL);
            }
        }
    }
    return hWnd;
}

CString GetFilenameFromPid(DWORD pid)
{   
    CString strRet = _T("[Unknown Process]");
    TCHAR ImageFileName[1024] = {0};
    HANDLE ph = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pid);
    if(ph)
    {
        GetProcessImageFileName(ph,ImageFileName, 1023);
        CloseHandle(ph);

        CString sTmp = ImageFileName;
        CString strSearch = _T("//Device//HarddiskVolume");
        int ind = sTmp.Find(strSearch);
        if(ind != -1)
        {                               
            ind = sTmp.Find('//', ind + strSearch.GetLength());
            if(ind != -1)
            {                                   
                CString sReplace =_T("#:");
                sReplace.SetAt(0,GetDriveLetter(sTmp.Left(ind)));

                strRet = sReplace + sTmp.Mid(ind);
            }
        }
    }
    return strRet;
}
-------------------------------------------cpp--------------------------------------

    // TODO: 在此添加控件通知处理程序代码
    TRAYDATA trayData = {0};
    TBBUTTON btnData={0};
    HWND hTrayWnd=0;//托盘窗口句柄
    DWORD  DwTrayPid=0;//托盘进程id
    HANDLE hProcess=0;//托盘进程句柄

    hTrayWnd=FindTrayToolbarWindow();//找到托盘窗口句柄
    GetWindowThreadProcessId(hTrayWnd, &DwTrayPid);//取得托盘窗口对应的进程id
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DwTrayPid);//打开进程,取得进程句柄
    LPVOID address= VirtualAllocEx(hProcess,//在目标进程中申请一块内存,放TBBUTTON信息
                                    NULL,
                                    sizeof(TBBUTTON),
                                    MEM_COMMIT,
                                    PAGE_READWRITE);
    int count = (int)::SendMessage(hTrayWnd, TB_BUTTONCOUNT, 0, 0);//给托盘窗口发消息,得到托盘里图标个数
    for(int i=0; i<count; i++)
    {
        ::SendMessage(hTrayWnd, TB_GETBUTTON, i, (LPARAM)address);//取得TBBUTTON结构到本地
        ReadProcessMemory(hProcess,
                            (LPCVOID)address,
                            &btnData,
                            sizeof(TBBUTTON),
                            NULL);
        ReadProcessMemory(hProcess,//从目标进程address处存放的是TBBUTTON
                            (LPCVOID)btnData.dwData,//取dwData字段指向的TRAYDATA结构
                            &trayData,
                            sizeof(TRAYDATA),
                            NULL);
        DWORD dwProcessId = 0;
        GetWindowThreadProcessId(trayData.hwnd,//通过TRAYDATA里的hwnd字段取得本图标的进程id
                                &dwProcessId);
        CString path=GetFilenameFromPid(dwProcessId);//将图标拥有者进程id转为进程路径
       
    }

### 关于Java枚举的学习笔记 #### 枚举的基础概念 在Java中,`enum`是一种特殊的类,用于定义一组固定的常量。通过使用枚举可以提高代码的安全性和可读性[^1]。 #### 定义枚举类型 可以通过关键字 `enum` 来声明一个新的枚举类型: ```java public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY } ``` 上述例子展示了如何创建一个表示一周七天的枚举类型。 #### 使用枚举类型的变量 一旦定义好了枚举类型,则可以在程序中的任何地方利用它来声明具有该类型的变量,并将其赋值为预定义好的某个枚举常量之一: ```java Day day = Day.MONDAY; System.out.println(day); ``` 这段代码将会打印出 `MONDAY`。 #### 枚举方法 每个枚举都可以拥有自己的字段、构造函数以及成员方法。这使得枚举不仅仅局限于简单的命名空间集合,还可以携带额外的信息和行为逻辑。例如下面的例子展示了一个更复杂的枚举定义方式,其中包含了私有的属性、参数化的构造器还有公共的方法: ```java public enum Planet { MERCURY (3.303e+23, 2.4397e6), VENUS (4.869e+24, 6.0518e6), EARTH (5.976e+24, 6.37814e6); private final double mass; private final double radius; Planet(double mass, double radius) { this.mass = mass; this.radius = radius; } public double getMass() { return mass; } public double getRadius() { return radius; } // Other methods... } ``` 此段代码片段显示了带有自定义属性和访问器方法的行星枚举实例。 #### 枚举的应用场景 - **状态机**: 当存在有限数量的状态转换时非常适合采用枚举; - **选项列表**: 如颜色选择、性别区分等场合下也可以考虑运用枚举; - **配置项**: 对某些特定设置提供一系列合法取值范围的时候也很有用处。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值