Skip to content

Instantly share code, notes, and snippets.

@coolxv
Last active April 30, 2021 08:36
Show Gist options
  • Save coolxv/2c623711f35f91743ff96e04c89c5f3c to your computer and use it in GitHub Desktop.
Save coolxv/2c623711f35f91743ff96e04c89c5f3c to your computer and use it in GitHub Desktop.
windows_icon_get
#include <iostream>
#include<Windows.h>
#include <tchar.h>
#include <Commctrl.h>
#include <Shlwapi.h>
#pragma comment(lib,"Shlwapi.lib")
typedef void (WINAPI* LPFN_PGNSI)(LPSYSTEM_INFO);
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 ResizeListView(HWND hwndListView, HWND hwndParent)
{
RECT rc;
GetClientRect(hwndParent, &rc);
MoveWindow(hwndListView,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
TRUE);
//only call this if we want the LVS_NOSCROLL style
//PositionHeader(hwndListView);
}
void SwitchView(HWND hwndListView, DWORD dwView)
{
DWORD dwStyle = GetWindowLong(hwndListView, GWL_STYLE);
SetWindowLong(hwndListView, GWL_STYLE, (dwStyle & ~LVS_TYPEMASK) | dwView);
ResizeListView(hwndListView, GetParent(hwndListView));
}
BOOL Is64Bit_OS() {
BOOL bRetVal = FALSE;
SYSTEM_INFO si = { 0 };
LPFN_PGNSI pGNSI =
(LPFN_PGNSI)GetProcAddress(GetModuleHandle(_T("kernel32.dll")),
"GetNativeSystemInfo");
if (pGNSI == NULL) {
return FALSE;
}
pGNSI(&si);
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
bRetVal = TRUE;
}
return bRetVal;
}
BOOL GetIconRect32(HWND hDeskWnd, char* strIconName, LPRECT lpRect) {
BOOL bRet = FALSE;
//-----------------------------
//遍历外部进程所有图标
DWORD PID = 0;
GetWindowThreadProcessId(hDeskWnd, &PID);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
if (hProcess != NULL) {
LVITEMA* pLVITEM = (LVITEMA*)VirtualAllocEx(hProcess, NULL,
sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
char* pszText = (char*)VirtualAllocEx(hProcess, NULL, 512, MEM_COMMIT,
PAGE_READWRITE);
RECT* pItemRc = (RECT*)VirtualAllocEx(hProcess, NULL, sizeof(RECT),
MEM_COMMIT, PAGE_READWRITE);
RECT rc;
if (pItemRc != NULL && pLVITEM != NULL) {
LVITEMA LVITEM;
LVITEM.mask = LVIF_TEXT;
LVITEM.cchTextMax = 512;
LVITEM.pszText = pszText;
char ItemBuf[512];
int nCount = ::SendMessage(hDeskWnd, LVM_GETITEMCOUNT, 0, 0);
for (int iItem = 0; iItem < nCount; iItem++) {
LVITEM.iItem = iItem;
LVITEM.iSubItem = 0;
//将设置好的结构插入目标进程
WriteProcessMemory(hProcess, pLVITEM, &LVITEM, sizeof(LVITEM), NULL);
//发送LVM_GETITEM消息
BOOL r = (BOOL)::SendMessage(hDeskWnd, LVM_GETITEMTEXTA, iItem, (
LPARAM)pLVITEM);
//获取pszText
ReadProcessMemory(hProcess, pszText, ItemBuf, 512, NULL);
if (StrCmpA(ItemBuf, strIconName) == 0) {
::SendMessage(hDeskWnd, LVM_GETITEMRECT, iItem, (LPARAM)pItemRc);
ReadProcessMemory(hProcess, pItemRc, &rc, sizeof(RECT), NULL);
memcpy(lpRect, &rc, sizeof(RECT));
bRet = TRUE;
break;
}
}
VirtualFreeEx(hProcess, pLVITEM, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pszText, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pItemRc, 0, MEM_RELEASE);//释放内存
}
CloseHandle(hProcess);
}
return bRet;
}
BOOL GetIconRect64(HWND hDeskWnd, char* strIconName, LPRECT lpRect) {
BOOL bRet = FALSE;
//遍历外部进程所有图标
DWORD PID = 0;
GetWindowThreadProcessId(hDeskWnd, &PID);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
if (hProcess != NULL) {
LVITEM64A* pLVITEM = (LVITEM64A*)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM64A), MEM_COMMIT, PAGE_READWRITE);
char* pszText = (char*)VirtualAllocEx(hProcess, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
RECT* pItemRc = (RECT*)VirtualAllocEx(hProcess, NULL, sizeof(RECT), MEM_COMMIT, PAGE_READWRITE);
RECT rc;
if (pItemRc != NULL || pLVITEM != NULL) {
LVITEM64A LVITEM;
LVITEM.mask = LVIF_TEXT;
LVITEM.cchTextMax = 512;
LVITEM.pszText = (INT64)pszText;
char ItemBuf[512];
int nCount = ::SendMessage(hDeskWnd, LVM_GETITEMCOUNT, 0, 0);
for (int iItem = 0; iItem < nCount; iItem++) {
LVITEM.iItem = iItem;
LVITEM.iSubItem = 0;
//将设置好的结构插入目标进程
WriteProcessMemory(hProcess, pLVITEM, &LVITEM, sizeof(LVITEM), NULL);
//发送LVM_GETITEM消息
BOOL r = (BOOL)::SendMessage(hDeskWnd, LVM_GETITEMTEXTA, iItem, (LPARAM)pLVITEM);
//获取pszText
ReadProcessMemory(hProcess, pszText, ItemBuf, 512, NULL);
if (StrCmpA(ItemBuf, strIconName) == 0) {
::SendMessage(hDeskWnd, LVM_GETITEMRECT, iItem, (LPARAM)pItemRc);
ReadProcessMemory(hProcess, pItemRc, &rc, sizeof(RECT), NULL);
memcpy(lpRect, &rc, sizeof(RECT));
bRet = TRUE;
break;
}
}
VirtualFreeEx(hProcess, pLVITEM, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pszText, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pItemRc, 0, MEM_RELEASE);//释放内存
}
CloseHandle(hProcess);
}
return bRet;
}
//==取桌面图标位置=======================
BOOL GetIconRect(char* strIconName, LPRECT lpRect, HWND& hDeskListView) {
HWND hDeskWnd = NULL;//桌面上SysListView32的窗口句柄
HWND hWnd = ::FindWindow(_T("WorkerW"), NULL);//先当WIN7系统查找
while (hWnd) {
HWND hShellView = ::FindWindowEx(hWnd, NULL, _T("SHELLDLL_DefView"),
NULL);
if (hShellView) {
hDeskWnd = ::FindWindowEx(hShellView, NULL, _T("SysListView32"), NULL);
break;
}
hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
}
if (!hDeskWnd) { // 如果没找到,再按XP方式查找
hWnd = ::FindWindow(_T("Progman"), _T("Program Manager"));
if (hWnd) {
hWnd = ::FindWindowEx(hWnd, NULL, _T("SHELLDLL_DefView"), NULL);
hDeskWnd = ::FindWindowEx(hWnd, NULL, _T("SysListView32"), NULL);
}
}
if (!hDeskWnd) {
return FALSE;
}
hDeskListView = hDeskWnd;
//SwitchView(hDeskListView, LVS_ICON);
//SwitchView(hDeskListView, LVS_LIST);
BOOL bRet = FALSE;
if (Is64Bit_OS()) {
bRet = GetIconRect64(hDeskWnd, strIconName, lpRect);
}
else {
bRet = GetIconRect32(hDeskWnd, strIconName, lpRect);
}
if (bRet) {
POINT pt;
pt.x = lpRect->left;
pt.y = lpRect->top;
::ClientToScreen(hDeskWnd, &pt);
OffsetRect(lpRect, pt.x - lpRect->left, pt.y - lpRect->top);
}
return bRet;
}
int main()
{
RECT lpRect;
HWND hDeskListView;
char name[] = "Asymptote";
GetIconRect(name, &lpRect, hDeskListView);
std::cout << lpRect.left << std::endl;
std::cout << lpRect.top << std::endl;
std::cout << lpRect.right << std::endl;
std::cout << lpRect.bottom << std::endl;
return 0;
}
//https://github.com/microsoft/Windows-classic-samples
//https://stackoverflow.com/questions/25625949/c-listview-hide-item
//https://docs.microsoft.com/en-us/windows/win32/controls/use-groups-in-a-list-view
//https://www.codeproject.com/Articles/2890/Using-ListView-control-under-Win32-API
//https://www.nirsoft.net/utils/sysexp.html
//https://labs.f-secure.com/archive/memory-allocation-how-injecting-into-your-own-tools-might-help-you-compromise-a-windows-domain/
//https://www.nirsoft.net/utils/gui_prop_view.html
//https://github.com/odzhan/injection
//https://www.codeproject.com/Articles/7891/Using-virtual-lists
//https://www.codeproject.com/Articles/79/Neat-Stuff-to-Do-in-List-Controls-Using-Custom-Dra
//https://www.codeproject.com/Articles/2890/Using-ListView-control-under-Win32-API
//https://docs.microsoft.com/en-us/windows/win32/controls/custom-draw
//https://www.codeproject.com/Articles/8985/Customizing-the-Appearance-of-CSliderCtrl-Using-Cu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment