本例以获取程序托盘图标位置为例
//根据需要还可以获取不少信息
代码一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
//获取托盘区域数据 RECT CTray::GetTrayRect() { RECT rect = {0}; HWND hWnd = NULL; hWnd = FindTrayWnd(); if (hWnd != NULL) { if (!EnumNotifyWindow(rect,hWnd)) //如果没在普通托盘区 { hWnd = FindNotifyIconOverflowWindow(); //在溢出区(win7) if (hWnd != NULL) { EnumNotifyWindow(rect,hWnd); } } } return rect; } //枚举获取托盘区域位置 bool CTray::EnumNotifyWindow(RECT &rect, HWND hWnd) { //RECT rect = {0}; bool bSuc = false ; unsigned long lngPID = 0; long ret = 0,lngButtons = 0; long lngHwndAdr = 0,lngHwnd = 0; //,lngTextAdr,lngButtonID; HANDLE hProcess = NULL; LPVOID lngAddress = NULL,lngRect = NULL; if (hWnd != NULL) { ret = GetWindowThreadProcessId(hWnd, &lngPID); if (ret != 0 && lngPID != 0) { hProcess = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,0,lngPID); // if (hProcess != NULL) { lngAddress = VirtualAllocEx(hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE); lngRect = VirtualAllocEx(hProcess,0, sizeof (RECT), MEM_COMMIT, PAGE_READWRITE); lngButtons = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0); //发送消息获取托盘button数量 if (lngAddress != NULL && lngRect != NULL) { for ( int i=0 ;i< lngButtons;i++) { RECT rc = {0}; int j = i; ret = SendMessage(hWnd,TB_GETBUTTON,j, long (lngAddress)); //发送消息获取托盘项数据起始地址 ret = ReadProcessMemory(hProcess, LPVOID ( long (lngAddress) + 12),&lngHwndAdr,4,0); if (ret != 0 && lngHwndAdr != -1) { ret = ReadProcessMemory(hProcess, LPVOID (lngHwndAdr),&lngHwnd, 4,0); //获取句柄 if (ret != 0 && ( HWND )lngHwnd == m_NotifyIconData.hWnd) // { ret = ::SendMessage(hWnd,TB_GETITEMRECT,( WPARAM )j,( LPARAM )lngRect); //发送消息获取托盘项区域数据 ret = ReadProcessMemory(hProcess,lngRect,&rc, sizeof (rc),0); //读取托盘区域数据 if (ret != 0) { CWnd::FromHandle(hWnd)->ClientToScreen(&rc); rect = rc; } bSuc = true ; //在普通托盘区找到,在溢出区不再查找 break ; } } } } if (lngAddress != NULL) { VirtualFreeEx( hProcess, lngAddress, 0x4096, MEM_DECOMMIT); VirtualFreeEx( hProcess, lngAddress, 0, MEM_RELEASE); } if (lngRect != NULL) { VirtualFreeEx( hProcess, lngRect, sizeof (RECT), MEM_DECOMMIT); VirtualFreeEx( hProcess, lngRect, 0, MEM_RELEASE); } CloseHandle(hProcess); } } } return bSuc; } //获取普通托盘区窗口句柄 HWND CTray::FindTrayWnd() { HWND hWnd = NULL; HWND hWndPaper = NULL; if ((hWnd = FindWindow(_T( "Shell_TrayWnd" ), NULL)) != NULL) { if ((hWnd = FindWindowEx(hWnd, 0, _T( "TrayNotifyWnd" ), NULL)) != NULL) { hWndPaper = FindWindowEx(hWnd, 0, _T( "SysPager" ), NULL); if (!hWndPaper) hWnd = FindWindowEx(hWnd, 0, _T( "ToolbarWindow32" ), NULL); else hWnd = FindWindowEx(hWndPaper, 0, _T( "ToolbarWindow32" ), NULL); } } return hWnd; } //获取溢出托盘区窗口句柄 HWND CTray::FindNotifyIconOverflowWindow() { HWND hWnd = NULL; hWnd = FindWindow(_T( "NotifyIconOverflowWindow" ), NULL); if (hWnd != NULL) { hWnd = FindWindowEx(hWnd, NULL, _T( "ToolbarWindow32" ), NULL); } return hWnd; } |
以下代码网上收集的,变量 初始化 指针句柄 及函数是否成功都没判定
//需要的自己加下判定,有时间再改了
代码二
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
struct TRAYDATA { HWND hwnd; UINT uID; UINT uCallbackMessage; DWORD Reserved[2]; HICON hIcon; }; void CTray::GetTrayRect() { HWND hWnd,hWndPaper; unsigned long lngPID; long ret,lngButtons; HANDLE hProcess; LPVOID lngAddress; long lngTextAdr,lngHwndAdr,lngHwnd,lngButtonID; TCHAR strBuff[1024]={0}; TRAYDATA trayData = {0}; TBBUTTON btnData={0}; hWnd = FindWindow(_T( "Shell_TrayWnd" ), NULL); hWnd = FindWindowEx(hWnd, 0, _T( "TrayNotifyWnd" ), NULL); hWndPaper = FindWindowEx(hWnd, 0, _T( "SysPager" ), NULL); if (!hWndPaper) hWnd = FindWindowEx(hWnd, 0, _T( "ToolbarWindow32" ), NULL); else hWnd = FindWindowEx(hWndPaper, 0, _T( "ToolbarWindow32" ), NULL); ret = GetWindowThreadProcessId(hWnd, &lngPID); hProcess = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,0,lngPID); lngAddress = VirtualAllocEx(hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE); lngButtons = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0); RECT rc; POINT point; LPVOID lngRect = VirtualAllocEx(hProcess,0, sizeof (RECT), MEM_COMMIT, PAGE_READWRITE); CRect rect; for ( int i=0 ;i< lngButtons;i++) { int j = i; ret = SendMessage(hWnd,TB_GETBUTTON,j, long (lngAddress)); ret = ReadProcessMemory(hProcess, LPVOID ( long (lngAddress) + 16),&lngTextAdr,4,0); if (lngTextAdr != -1) { ret = ReadProcessMemory(hProcess, LPVOID (lngTextAdr),strBuff,1024,0); //ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 12),&lngHwndAdr,4,0); //获取句柄 //ret = ReadProcessMemory(hProcess, LPVOID(lngHwndAdr),&lngHwnd, 4,0); //ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 4),&lngButtonID,4,0);//获取buttonID CString str(strBuff); if (str.Compare(m_NotifyIconData.szTip) == 0) { ::SendMessage(hWnd,TB_GETITEMRECT,( WPARAM )j,( LPARAM )lngRect); ReadProcessMemory(hProcess,lngRect,&rc, sizeof (rc),0); //获取托盘图标区域 CWnd::FromHandle(hWnd)->ClientToScreen(&rc); } //以下是隐藏托盘图标 // { // if(show) // { // SendMessage(hWnd,TB_HIDEBUTTON,lngButtonID,0); // } // else // { // SendMessage(hWnd,TB_HIDEBUTTON,lngButtonID,1); // } // } } } VirtualFreeEx( hProcess, lngAddress, 0x4096, MEM_DECOMMIT); VirtualFreeEx( hProcess, lngAddress, 0, MEM_RELEASE); VirtualFreeEx( hProcess, lngRect, sizeof (RECT), MEM_DECOMMIT); VirtualFreeEx( hProcess, lngRect, 0, MEM_RELEASE); CloseHandle(hProcess); } |
代码三
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
VOID StartStorm() { HWND hMain = FindWindow( "animate_layered_window_class" , "暴风媒体中心" ); if ( hMain ) { ShowWindow(hMain, SW_HIDE); } //得到工具栏句柄 HWND hTray = FindWindow( "Shell_TrayWnd" , NULL); hTray = FindWindowEx(hTray, 0, "TrayNotifyWnd" , NULL); hTray = FindWindowEx(hTray, 0, "SysPager" , NULL); hTray = FindWindowEx(hTray, 0, "ToolbarWindow32" , NULL); //获取explore进程ID DWORD TrayPid; GetWindowThreadProcessId(hTray, &TrayPid); //打开进程 并且开辟进程空间 RECT rect; TBBUTTON tb; TBBUTTON pTb; LPVOID lpAddr; DWORD dwThreadIdOfICO; DWORD dwTempId = FindStorm( "Stormtray.exe" ); //你要点击的进程的PID TRAYDATA traydata; HANDLE hOpen = OpenProcess(PROCESS_ALL_ACCESS, FALSE, TrayPid); lpAddr = VirtualAllocEx(hOpen, NULL, sizeof (tb) + sizeof (rect), MEM_COMMIT, PAGE_READWRITE); int nCount = SendMessage(hTray, TB_BUTTONCOUNT, 0, 0); int i; DWORD dwOutWrite; for ( i = 0; i < nCount; i ++) { ZeroMemory(&tb, sizeof (tb)); ZeroMemory(&rect, sizeof (rect)); //把参数写进目标进程 WriteProcessMemory(hOpen, lpAddr, &tb, sizeof (tb), &dwOutWrite); //WriteProcessMemory(hOpen, (LPVOID)((DWORD)lpAddr + sizeof(pTb)), &rect, sizeof(rect), &dwOutWrite); //获取BUTTON SendMessage(hTray, TB_GETBUTTON, i, LPARAM (lpAddr)); //读取TBBUTTON结构 ReadProcessMemory(hOpen, lpAddr, &pTb, sizeof (TBBUTTON), &dwOutWrite); //读取TRAYDATA结构 ReadProcessMemory(hOpen, ( LPVOID )pTb.dwData, &traydata, sizeof (TRAYDATA), &dwOutWrite); GetWindowThreadProcessId(traydata.hwnd, &dwThreadIdOfICO); if ( dwThreadIdOfICO == dwTempId ) { //获取ICO的RECT LPVOID lp = ( LPVOID )(( DWORD )lpAddr + sizeof (pTb)); SendMessage(hTray, TB_GETITEMRECT, i, ( LPARAM )lp); LPVOID lpdata = ( LPVOID )(( DWORD )lpAddr + sizeof (TBBUTTON)); ReadProcessMemory(hOpen, lpdata, &rect, sizeof (rect), &dwOutWrite); int iGap = rect.right/2; //得到图标的中间坐标的间隔 //点击 SendMessage(hTray, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.right - iGap, rect.bottom - iGap)); SendMessage(hTray, WM_LBUTTONUP, 0, MAKELPARAM(rect.right - iGap, rect.bottom - iGap)); // CloseHandle(hOpen); break ;; } } } |
win7有一个溢出托盘区:以下是隐藏在托盘区中的托盘信息,用以上的方法找不到,因为在NotifyIconOverflowWindow里
Fhwnd = FindWindow("NotifyIconOverflowWindow", NULL)
参考文章:http://topic.csdn.net/u/20101003/23/859851ee-5aa1-4476-8ce1-1359826df2b0.html
代码四
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#include "stdafx.h" #include <afx.h> #include <locale.h> #include <string> using namespace std; typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) ( HANDLE , PBOOL ); BOOL IsWow64() { BOOL bIsWow64 = FALSE; LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandle(_T( "kernel32" )), "IsWow64Process" ); if (NULL != fnIsWow64Process) { if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { // handle error } } return bIsWow64; } HWND FindTrayWnd() { HWND hWnd = NULL; hWnd = FindWindow(_T( "Shell_TrayWnd" ), NULL); hWnd = FindWindowEx(hWnd, NULL, _T( "TrayNotifyWnd" ), NULL); hWnd = FindWindowEx(hWnd, NULL, _T( "SysPager" ), NULL); hWnd = FindWindowEx(hWnd, NULL, _T( "ToolbarWindow32" ), NULL); return hWnd; } HWND FindNotifyIconOverflowWindow() { HWND hWnd = NULL; hWnd = FindWindow(_T( "NotifyIconOverflowWindow" ), NULL); hWnd = FindWindowEx(hWnd, NULL, _T( "ToolbarWindow32" ), NULL); return hWnd; } void EnumNotifyWindow( HWND hWnd) { DWORD dwProcessId = 0; GetWindowThreadProcessId(hWnd,&dwProcessId); HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, dwProcessId); if ( hProcess==NULL ){ return ; } LPVOID lAddress = VirtualAllocEx(hProcess, 0, 4096, MEM_COMMIT, PAGE_READWRITE); if ( lAddress==NULL ){ return ; } DWORD lTextAdr = 0; BYTE buff[1024] = {0}; CString strFilePath; CString strTile; HWND hMainWnd = NULL; int nDataOffset = sizeof (TBBUTTON) - sizeof ( INT_PTR ) - sizeof ( DWORD_PTR ); int nStrOffset = 18; if ( IsWow64() ){ nDataOffset+=4; nStrOffset+=6; } //得到圖標個數 int lButton = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0); for ( int i = 0; i < lButton; i++) { SendMessage(hWnd, TB_GETBUTTON, i, ( LPARAM )lAddress); //讀文本地址 ReadProcessMemory(hProcess, ( LPVOID )(( DWORD )lAddress + nDataOffset), &lTextAdr, 4, 0); if ( lTextAdr!=-1 ) { //讀文本 ReadProcessMemory(hProcess, ( LPCVOID )lTextAdr, buff, 1024, 0); hMainWnd = ( HWND )(*(( DWORD *)buff)); strFilePath = ( WCHAR *)buff + nStrOffset; strTile = ( WCHAR *)buff + nStrOffset + MAX_PATH; _tprintf(_T( "%s %s\n" ),strTile,strFilePath); } } VirtualFreeEx(hProcess, lAddress, 4096, MEM_RELEASE); CloseHandle(hProcess); } int _tmain( int argc, _TCHAR* argv[]) { setlocale (LC_ALL, "chs" ); EnumNotifyWindow(FindTrayWnd()); _tprintf(_T( "\n" )); EnumNotifyWindow(FindNotifyIconOverflowWindow()); system ( "pause" ); return 0; } |
代码五
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
void CTrayDlg::OnButton1() { // TODO: Add your control notification handler code here HWND wd=::FindWindow( "Shell_TrayWnd" ,NULL); if (wd==NULL) { MessageBox( "Error1" ); return ; } HWND wtd=FindWindowEx(wd,NULL, "TrayNotifyWnd" ,NULL); if (wtd==NULL) { MessageBox( "Error2" ); return ; } HWND wd1=FindWindowEx(wtd,NULL, "ToolbarWindow32" ,NULL); if (wd1==NULL) { MessageBox( "Error3" ); return ; } DWORD pid; pid=0; GetWindowThreadProcessId(wd1,&pid); if (pid==NULL) { MessageBox( "Error4" ); return ; } HANDLE hd=OpenProcess(PROCESS_QUERY_INFORMATION ¦ PROCESS_ALL_ACCESS , true ,pid); if (hd==NULL) { MessageBox( "Error6" ); return ; } int num=::SendMessage(wd1,TB_BUTTONCOUNT ,NULL,NULL); int i; unsigned long n; TBBUTTON p,*pp; CString x; wchar_t name[256]; unsigned long whd,proid; CString temp; TBBUTTON *sp; sp= (TBBUTTON *)0x20f00; //这里应该改成用VirtualAllocEx分配内存否则有可能出错,不过人懒,就先这么着吧 for (i=0;i<num;i++) { ::SendMessage(wd1,TB_GETBUTTON,i,( LPARAM )sp); pp=&p; ReadProcessMemory(hd,sp,pp, sizeof (p),&n); // x.Format("%x %x %x %x %x %x",p.iBitmap,p.idCommand,p.fsState,p.fsStyle, p.dwData, p.iString); name[0]=0; if (p.iString!=0xffffffff) { try { ReadProcessMemory(hd,( void *)p.iString,name,255,&n); name[n]=0; } catch () { } // x+=" "; // x+=name; temp=name; try { whd=0; ReadProcessMemory(hd,( void *)p.dwData,&whd,4,&n); } catch () { } proid=0; GetWindowThreadProcessId(( HWND )whd,&proid); x.Format( "位置=%d 名称=%s 窗口句柄=%08x 进程ID=%08x" , i,( LPCTSTR )temp,whd,proid); m_list.AddString(x); } } } |
代码六
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
void CTrayDlg::OnButton1() { // TODO: Add your control notification handler code here HWND wd=::FindWindow( "Shell_TrayWnd" ,NULL); if (wd==NULL) { MessageBox( "Error1" ); return ; } HWND wtd=FindWindowEx(wd,NULL, "TrayNotifyWnd" ,NULL); if (wtd==NULL) { MessageBox( "Error2" ); return ; } HWND wd1=FindWindowEx(wtd,NULL, "ToolbarWindow32" ,NULL); if (wd1==NULL) { MessageBox( "Error3" ); return ; } DWORD pid; pid=0; GetWindowThreadProcessId(wd1,&pid); if (pid==NULL) { MessageBox( "Error4" ); return ; } HANDLE hd=OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_ALL_ACCESS , true ,pid); if (hd==NULL) { MessageBox( "Error6" ); return ; } int num=::SendMessage(wd1,TB_BUTTONCOUNT ,NULL,NULL); int i; unsigned long n; TBBUTTON p,*pp; CString x; wchar_t name[256]; unsigned long whd,proid; CString temp; TBBUTTON *sp; sp= (TBBUTTON *)0x20f00; for (i=0;i<num;i++) { ::SendMessage(wd1,TB_GETBUTTON,i,( LPARAM )sp); pp=&p; ReadProcessMemory(hd,sp,pp, sizeof (p),&n); // x.Format("%x %x %x %x %x %x",p.iBitmap,p.idCommand,p.fsState,p.fsStyle, p.dwData, p.iString); name[0]=0; if (p.iString!=0xffffffff) { try { ReadProcessMemory(hd,( void *)p.iString,name,255,&n); name[n]=0; } catch (...) { } // x+=" "; // x+=name; temp=name; try { whd=0; ReadProcessMemory(hd,( void *)p.dwData,&whd,4,&n); } catch (...) { } proid=0; GetWindowThreadProcessId(( HWND )whd,&proid); x.Format( "位置=%d 名称=%s 窗口句柄=%08x 进程ID=%08x" , i,( LPCTSTR )temp,whd,proid); m_list.AddString(x); } } } |
到此这篇关于VC通过托盘图标得到该所属进程的实现代码的文章就介绍到这了,更多相关VC托盘图标得到该所属进程内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://www.moyann.com/archives/239/