残念ながら、別のプログラムによって作成されたウィンドウにアクセスする場合、システムは必要なウィンドウ メッセージのポインターのマーシャリングを行わないため、これは簡単にはできません。これは、共有 DLL ファイル (システム全体の Windows フックを作成して他のプロセスにロードする) から行うか、プロセス間メモリ アクセスなどの他のハックを使用する必要があります。
同じプログラムで SysHeader32 ウィンドウにアクセスする場合は、次のように簡単です。
メッセージを送信HDM_GETITEMCOUNT
すると、アイテムの数が返されます。
取得するアイテムのインデックスに設定し、適切に設定された構造へのポインターに設定してメッセージHDM_GETITEM
を送信します。特に に設定して のバッファを用意し、その長さを に設定します。wParam
lParam
HDITEM
mask
HDI_TEXT
pszText
cchTextMax
例:
int count = SendMessage(hWnd, HDM_GETITEMCOUNT, 0, 0);
std::cout << "There are " << count << " items.\n";
for (int i = 0; i < count; i++) {
TCHAR name[260];
HDITEM hdi;
hdi.mask = HDI_TEXT;
hdi.pszText = name;
hdi.cchTextMax = 260;
SendMessage(hWnd, HDM_GETITEM, i, reinterpret_cast<LPARAM>(&hdi));
std::cout << " " << i << ") " << hdi.pszText << "\n";
}
入力メモリと出力メモリを別のプログラムの空間に格納する必要があるため、次のようなものが必要です (お好みでエラー チェックなどを追加してください)。
struct InterProcessData {
HDITEM hdi;
TCHAR buffer[260];
};
// Open the owning process and allocate a buffer big enough for
// our inter-process communication
DWORD dwProcessId;
GetWindowThreadProcessId(hWnd, &dwProcessId);
HANDLE hProcess = OpenProcess(
PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
FALSE, dwProcessId);
InterProcessData* pRemoteData = reinterpret_cast<InterProcessData*>(
VirtualAllocEx(hProcess, NULL, sizeof(InterProcessData), MEM_COMMIT, PAGE_READWRITE));
int count = SendMessage(hWnd, HDM_GETITEMCOUNT, 0, 0);
std::cout << "There are " << count << " items.\n";
for (int i = 0; i < count; i++) {
InterProcessData data;
data.hdi.mask = HDI_TEXT;
data.hdi.pszText = pRemoteData->buffer;
data.hdi.cchTextMax = 260;
// Write the HDITEM structure to the space in the remote process
// (without the buffer, its contents are undefined anyway)
WriteProcessMemory(hProcess, pRemoteData, &data, sizeof(data.hdi), NULL);
// Send the message itself, passing the remote address in lParam
SendMessage(hWnd, HDM_GETITEM, i, reinterpret_cast<LPARAM>(&pRemoteData->hdi));
// Read the data back, HDITEM and the buffer
ReadProcessMemory(hProcess, pRemoteData, &data, sizeof(data), NULL);
// The documentation says that the pszText can point elsewhere -
// copy it to our buffer in that case
if (data.hdi.pszText != pRemoteData->buffer)
ReadProcessMemory(hProcess, data.hdi.pszText, data.buffer, data.hdi.cchTextMax * sizeof(TCHAR), NULL);
std::cout << " " << i << ") " << data.buffer << "\n";
}
// Cleanup
VirtualFreeEx(hProcess, pRemoteData, 0, MEM_RELEASE);
CloseHandle(hProcess);