http://www.codeproject.com/shell/ctrayiconposition.asp
使用方式
代碼: 選擇全部
HRESULT res= S_FALSE;
HWND hWndTray = GetTrayNotifyWnd();
if (hWndTray == NULL)
{
return S_FALSE;
}
//now we have to get an ID of the parent process for system tray
DWORD dwTrayProcessID = -1;
GetWindowThreadProcessId(hWndTray, &dwTrayProcessID);
if(dwTrayProcessID <= 0)
{
return S_FALSE;
}
HANDLE hTrayProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID);
if(hTrayProc == NULL)
{
return S_FALSE;
}
int iButtonsCount = ::SendMessage(hWndTray, TB_BUTTONCOUNT, 0, 0);
//We want to get data from another process - it's not possible to just send messages like TB_GETBUTTON with a localy
//allocated buffer for return data. Pointer to localy allocated data has no usefull meaning in a context of another
//process (since Win95) - so we need to allocate some memory inside Tray process.
//We allocate sizeof(TBBUTTON) bytes of memory - because TBBUTTON is the biggest structure we will fetch. But this buffer
//will be also used to get smaller pieces of data like RECT structures.
LPVOID lpData = VirtualAllocEx(hTrayProc, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);
if( lpData == NULL || iButtonsCount < 1 )
{
CloseHandle(hTrayProc);
return S_FALSE;
}
for(int iButton=0; iButton<iButtonsCount; iButton++)
{
DWORD dwBytesRead = -1;
TBBUTTON buttonData;
::SendMessage(hWndTray, TB_GETBUTTON, iButton, (LPARAM)lpData);
ReadProcessMemory(hTrayProc, lpData, &buttonData, sizeof(TBBUTTON), &dwBytesRead);
if(dwBytesRead < sizeof(TBBUTTON))
{
continue;
}
//now let's read extra data associated with each button: there will be a HWND of the window that created an icon and icon ID
DWORD dwExtraData[2] = { 0,0 };
ReadProcessMemory(hTrayProc, (LPVOID)buttonData.dwData, dwExtraData, sizeof(dwExtraData), &dwBytesRead);
if(dwBytesRead < sizeof(dwExtraData))
{
continue;
}
// get the window handle and iconid from trayicon , these are two identity key to find out the tray icon.
HWND hWndOfIconOwner = (HWND) dwExtraData[0];
int iIconId = (int) dwExtraData[1];
// we can also get the ProcessID from window handle by GetWindowThreadProcessId API.
DWORD dwProcessId = 0;
GetWindowThreadProcessId(hWndOfIconOwner,&dwProcessId);
// we can do some thing here.
// res = S_OK; or res = S_FALSE;
}
VirtualFreeEx(hTrayProc, lpData, NULL, MEM_RELEASE);
CloseHandle(hTrayProc);
return res;