0

別のプログラム (program2) のレポート スタイル リスト (SysListView32) にあるヘッダー (SysHeader32) の列の名前を読み取るプログラム (program1) を作成しています。

したがって、基本的には、プログラムを別のプログラムに入れて、見つけたすべてのヘッダー (SysHeader32) のタイトル名を読み取る必要があります。プログラムには多数の異なるリストと各リストのヘッダーがあるため、この関数をコールバック関数EnumChildWindowsと共に使用しEnumChildProcて、子ウィンドウのすべてのハンドルを調べることにしました。これらのハンドルを使用GetClassName()して、クラス名が何であるかを確認し、それが SysHeader32 であることを確認すると、さまざまなタイトル名を含むことができるヘッダーを見つけたことがわかります...しかし、テキストを取得するためにどのコードを使用できるかわかりませんこれらのさまざまなタイトルから、各タイトルを識別する方法もわかりません...

これまでに見つけた各 SysHeader32 ヘッダーのハンドルを見つけるコードは次のとおりです。

BOOL CALLBACK EnumChildProc (HWND hWnd, LPARAM lParam)
{
  char myBuffer [100];//buffer that will get the class name
  GetClassName(hWnd, myBuffer, 100);
  string myString (myBuffer);//converting myBuffer into a readable string

  if (myString == "SysHeader32")
  {
    ///here is where I am currently lost
    ///I just don't know how to get the text from the different titles/items
    ///in the header found
  }
}

質問 1:: ヘッダーにいくつの異なるタイトル/アイテムがあるかを確認するにはどうすればよいですか?

質問 2:: ヘッダーにある各タイトル/アイテムのテキストを取得するにはどうすればよいですか?

サンプルコードを提供してください。

4

1 に答える 1

0

残念ながら、別のプログラムによって作成されたウィンドウにアクセスする場合、システムは必要なウィンドウ メッセージのポインターのマーシャリングを行わないため、これは簡単にはできません。これは、共有 DLL ファイル (システム全体の Windows フックを作成して他のプロセスにロードする) から行うか、プロセス間メモリ アクセスなどの他のハックを使用する必要があります。


同じプログラムで SysHeader32 ウィンドウにアクセスする場合は、次のように簡単です。

  1. メッセージを送信HDM_GETITEMCOUNTすると、アイテムの数が返されます。

  2. 取得するアイテムのインデックスに設定し、適切に設定された構造へのポインターに設定してメッセージHDM_GETITEMを送信します。特に に設定して のバッファを用意し、その長さを に設定します。wParamlParamHDITEMmaskHDI_TEXTpszTextcchTextMax

例:

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);
于 2014-04-30T14:51:10.037 に答える