转载: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控件中