win32 - ListView_GetItemPosition的使用

ListView_GetItemPosition : Gets the position of a list-view item

理论上获得桌面图标的正确方法是使用shell项,=> IFolderView::GetItemPosition

但是为了学习ListView_GetItemPosition的一些有用的知识,故写下来留作回顾。


 

因为我们要访问的桌面ListView与我们的应用程序存在的过程(Process)不同,所以我们所需要的POINT(由ListView_GetItemPosition提供)必须分配在拥有ListView的同一进程的地址空间中。

因此我们可以使用VirtualAllocEx()进行内存分配,然后使用该内存请求位置,然后使用ReadProcessMemory()POINT数据从该内存读取到我们自己的进程中。

一些代码:

int numberOfIcons = ListView_GetItemCount(folderView);
printf("Number Of Icons On Desktop is: %d\n", numberOfIcons);

if (numberOfIcons > 0)
{
    DWORD pid = 0;
    GetWindowThreadProcessId(folderView, &pid);

    HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ, FALSE, pid);
    if (!hProcess)
    {
        printf("OpenProcess failed, error %u\n", GetLastError());
    }
    else
    {
        LPPOINT pt = (LPPOINT) VirtualAllocEx(hProcess, NULL, sizeof(POINT), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if (!pt)
        {
            printf("VirtualAllocEx failed, error %u\n", GetLastError());
        }
        else
        {
            POINT iconPos;
            SIZE_T numRead;

            for (int i = 0; i < numberOfIcons; ++i)
            {
                if (!ListView_GetItemPosition(folderView, i, pt))
                {
                    printf("GetItemPosition failed for index %d\n", i);
                    continue;
                }

                if (!ReadProcessMemory(hProcess, pt, &iconPos, sizeof(POINT), &numRead))
                {
                    printf("ReadProcessMemory failed for index %d, error %u\n", i, GetLastError());
                    continue;
                }

                printf("Icon at Index %d, Position = %ld, %ld", i, iconPos.x, iconPos.y);
            }

            VirtualFreeEx(hProcess, pt, 0, MEM_RELEASE);
        }

        CloseHandle(hProcess);
    }
}

注:ListView_GetItemPosition不能保证桌面图标在listview控件中

 

posted @ 2020-10-15 15:27  strive-sun  阅读(551)  评论(0编辑  收藏  举报