BOOL FileDroppedAtIcon(const HWND a_hWndOwner, const int a_iButtonID, const PPOINT pPoint)
{
HWND hWndTray = FindTrayToolbarWindow();
//now we have to get an ID of the parent process for system tray
DWORD dwTrayProcessID = -1;
GetWindowThreadProcessId(hWndTray, &dwTrayProcessID);
//here we get a
handle to tray application process
HANDLE hTrayProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID);
//now we check how many buttons is there - should be more than 0
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 locally
//allocated buffer for return data. Pointer to locally 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);
BOOL bIconFound = FALSE;
for(int iButton=0; iButton<iButtonsCount; iButton++)
{
//first let's read TBUTTON information
//about each button in a task bar of tray
DWORD dwBytesRead = -1;
TBBUTTON buttonData;
SendMessage(hWndTray, TB_GETBUTTON, iButton, (LPARAM)lpData);
//we filled lpData with details of iButton icon of toolbar
//- now let's copy this data from tray application
//back to our process
ReadProcessMemory(hTrayProc, lpData, &buttonData, sizeof(TBBUTTON), &dwBytesRead);
//let's read extra data of 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);
HWND hWndOfIconOwner = (HWND) dwExtraData[0];
int iIconId = (int) dwExtraData[1];
if(hWndOfIconOwner != a_hWndOwner || iIconId != a_iButtonID)
{
continue;
}
//we found our icon - in WinXP it could be hidden - let's check it:
if( buttonData.fsState & TBSTATE_HIDDEN )
{
break;
}
//now just ask a tool bar of rectangle of our icon
RECT rcPosition = {0,0};
SendMessage(hWndTray, TB_GETITEMRECT, iButton, (LPARAM)lpData);
// ReadProcessMemory(hTrayProc, lpData, lprcPosition/*&rcPosition*/, sizeof(RECT), &dwBytesRead);
ReadProcessMemory(hTrayProc, lpData, &rcPosition, sizeof(RECT), &dwBytesRead);
MapWindowRect(hWndTray,NULL,&rcPosition);
if (pPoint->x > rcPosition.left && pPoint->x < rcPosition.right &&
pPoint->y > rcPosition.top && pPoint->y < rcPosition.bottom)
{
OutputDebugString("Stuff dropped at our icon...!!!");
bIconFound = TRUE;
break;
}
break;
}
VirtualFreeEx(hTrayProc, lpData, NULL, MEM_RELEASE);
CloseHandle(hTrayProc);
return bIconFound;
}