c++ 獲取桌面圖標的坐標與名稱


轉載:https://www.cnblogs.com/iwana/p/13857583.html

https://www.cnblogs.com/strive-sun/p/13820834.html

#include<Windows.h>
#include<commctrl.h>
#include <stdio.h>
 
  
 
  
 
typedef struct tagLVITEM64A
{
UINT mask;
int iItem;
int iSubItem;
UINT state;
UINT stateMask;
INT64 pszText;
int cchTextMax;
int iImage;
LPARAM lParam;
#if (_WIN32_IE >= 0x0300)
int iIndent;
#endif
#if (_WIN32_WINNT >= 0x501)
int iGroupId;
UINT cColumns; // tile view columns
PUINT puColumns;
#endif
} LVITEM64A, *LPLVITEM64A;
 
 
void GetChromePT(HWND h)
{
 
DWORD dwProcessId;
HWND hDeskTop;
hDeskTop = ::FindWindow(L"progman", NULL);
hDeskTop = ::FindWindowEx(hDeskTop, 0, L"shelldll_defview", NULL);
hDeskTop = ::FindWindowEx(hDeskTop, 0, L"syslistview32", NULL); //獲取桌面窗口bai句柄du;
GetWindowThreadProcessId(hDeskTop, &dwProcessId);//通過桌面窗口句柄獲取此窗口所在進程的PID,其實就是explorer進程
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);//打開zhi指定PID進程,取得進程句柄
 
tagLVITEM64A *_lv,lvi;
LPVOID lpvPt = VirtualAllocEx(hProcess, NULL, sizeof(POINT), MEM_COMMIT, PAGE_READWRITE);//在指定進程里面申請一個POINI結構大小的空間.
 
_lv = (tagLVITEM64A*)VirtualAllocEx(hProcess, NULL, sizeof(tagLVITEM64A), MEM_COMMIT, PAGE_READWRITE);//在指定進程里面申請一個文本結構大小的空間.
 
 
char item[512] = { 0 };
char *_item;
POINT pt;
 
//獲取窗口listbox 句柄  與 獲取桌面圖標信息無關 可忽略
HWND h_list = GetListHandle(h);
int m_iconCount = ListView_GetItemCount(hDeskTop);
_item = (char*)VirtualAllocEx(hProcess, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
 
 
ZeroMemory(&lvi, sizeof(LVITEM));
//lv.mask = LVIF_TEXT;
lvi.cchTextMax = 512;
 
 
for (size_t i = 1; i < m_iconCount; i++)
{
//坐標
ListView_GetItemPosition(hDeskTop, i, lpvPt);//獲取第一個圖標的坐標,存入lpvPt
ReadProcessMemory(hProcess, lpvPt, &pt, sizeof(POINT), NULL);
//名稱
lvi.iSubItem = 0;
lvi.pszText = (INT64)_item;
WriteProcessMemory(hProcess, _lv,&lvi,sizeof(LVITEM),NULL);
SendMessage(hDeskTop, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lv);
ReadProcessMemory(hProcess, _item, item, 512,NULL );
wchar_t pt_char[MAXBYTE] = { 0 };
//填充listbox
wsprintf(pt_char, L"%ld---%ld--name:%s", pt.x,pt.y, item); //一句話解決
SendMessage(h_list, LB_ADDSTRING, 0, (LPARAM)pt_char);
}
//lpvPt不是本進程里面的,不能使用,所以就要
//利用ReadProcessMemory從指定進程給讀出來
VirtualFreeEx(hProcess, lpvPt, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, _lv, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, _item, 0, MEM_RELEASE);
//釋放申請的空間
CloseHandle(hProcess);//關閉句柄
 
}

 

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控件中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM