I need to set a hook on mouse clicks, using C++, Win API. So that when an icon on the desktop is being clicked I get the event. How will this happen? I think th开发者_运维技巧e only information I get in mouse hook event are the coordinates for the mouse, right? Now how do I make sure that the thing clicked is an icon on the desktop?
Implement a mouse hook in a DLL and use SetWindowsHookEx() to install the hook for just the thread that is managin the desktop window. Use GetDesktopWindow() and GetWindowThreadProcessId() to get that thread ID. then, whenever your hook is triggered, the hook will tell you which window the user is clicking on, and which mouse operation is being performed. Use GetClassName() to determine if the window triggering the hook is a ListView, and if so then use the ListView API to query the window for its icon information at the provided mouse coordinates.
Checkout Microsoft Active Accessibility and SetWinEventHook on MSDN. I think you can achieve it using them effectively.
This code works in a hook DLL that I created. I think the issue here is that it's easy to get things like the text from the icon, but figuring out how to get to the app underlying a shortcut is another problem entirely. That's knowledge that resides inside the app managing the listview, in this case, Explorer.
Forgive the desperately old-fashioned code, I shoe-horned this test into an old ANSI hook DLL. DebugStr is just a wrapper for OutputDebugString. The code is based upon Remy's posting.
LRESULT DLL_CALL MouseFunc (int nCode, WPARAM wParam, LPARAM lParam)
{
BOOL bGoActive = TRUE;
char szDebug [200];
char szBuff [100];
MOUSEHOOKSTRUCT * pmhs = (MOUSEHOOKSTRUCT *)lParam;
LVFINDINFO lvfi;
LVITEM lvi;
int iIndexItem;
long lx = pmhs->pt.x;
long ly = pmhs->pt.y;
if (nCode >= 0)
{
if (wParam == WM_LBUTTONDOWN)
{
GetClassName (pmhs->hwnd, szBuff, sizeof(szBuff));
wsprintf (szDebug, "wparam=0x%X, nCode=%d, HTC=%d, class='%s', x=%d, y=%d",
wParam, nCode, pmhs->wHitTestCode, szBuff, lx, ly);
DebugStr (szDebug);
if (strcmpi (szBuff, TEXT("SysListView32")) == 0)
{
ZeroMemory (&lvfi, sizeof(lvfi));
lvfi.flags = LVFI_NEARESTXY;
lvfi.pt.x = lx;
lvfi.pt.y = ly;
ScreenToClient (pmhs->hwnd, &(lvfi.pt));
lvfi.vkDirection = VK_NEXT;
iIndexItem = ListView_FindItem (pmhs->hwnd, -1, &lvfi);
if (iIndexItem != -1)
{
ZeroMemory (&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT;
lvi.iItem = iIndexItem;
lvi.pszText = szBuff;
lvi.cchTextMax = sizeof(szBuff);
if (ListView_GetItem (pmhs->hwnd, &lvi))
{
wsprintf (szDebug, "item text = '%s'", szBuff);
DebugStr (szDebug);
}
}
}
}
精彩评论