要在其他進程的 SysListView32 控件中選取特定項目,需發送 LVM_SETITEMSTATE 訊息。但 LVITEM 結構包含指標成員(pszText、lParam),指標在目標進程地址空間無效,因此必須:
FindWindow/FindWindowEx)。OpenProcess,需 PROCESS_ALL_ACCESS)。VirtualAllocEx)存放 LVITEM 結構。WriteProcessMemory),設定 state = LVIS_SELECTED、stateMask = LVIS_SELECTED、iItem 為目標索引。SendMessage),wParam 為項目索引,lParam 為遠端結構位址。VirtualFreeEx、CloseHandle)。#include <windows.h>
#include <commctrl.h>
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
HWND hwnd = FindWindow("#32770", "Windows 任務管理器");
hwnd = FindWindowEx(hwnd, 0, "#32770", 0);
hwnd = FindWindowEx(hwnd, 0, "SysListView32", 0);
if (!hwnd) { MessageBox(NULL, "任務管理器未啟動", "錯誤", MB_OK); return 0; }
DWORD pid; GetWindowThreadProcessId(hwnd, &pid);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hProcess) { MessageBox(NULL, "開啟進程失敗", "錯誤", MB_OK); return 0; }
LVITEM* plvitem = (LVITEM*)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM),
MEM_COMMIT, PAGE_READWRITE);
if (!plvitem) { MessageBox(NULL, "記憶體配置失敗", "錯誤", MB_OK); return 0; }
LVITEM lvitem = {0};
lvitem.state = LVIS_SELECTED;
lvitem.stateMask = LVIS_SELECTED;
int iItem = 5; // 第 6 項(0-based)
WriteProcessMemory(hProcess, plvitem, &lvitem, sizeof(LVITEM), NULL);
SendMessage(hwnd, LVM_SETITEMSTATE, (WPARAM)iItem, (LPARAM)plvitem);
VirtualFreeEx(hProcess, plvitem, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}
LVITEM 結構大小必須與目標進程一致(同為 32 位元環境)。LVM_GETITEMTEXT、LVM_SETITEMTEXT 等訊息,只需調整結構欄位與讀寫方向。本技術常用於自動化測試、外掛工具開發,使用時請注意安全性與相容性。