Этот код работает в созданной мной DLL-хуке. Я думаю, что проблема здесь в том, что легко получить такие вещи, как текст с иконки, но выяснить, как добраться до приложения, лежащего в основе ярлыка, - это еще одна проблема. Это знание, которое находится внутри приложения, управляющего списком, в данном случае, Explorer.
Простите за отчаянно старомодный код, я положил этот тест в старую DLL-ловушку ANSI. DebugStr - это просто оболочка для OutputDebugString. Код основан на публикации Реми.
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);
}
}
}
}