轉載: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控件中