ツリー ビューがリモート プロセスにある場合でも、ツリー ビュー アイテムのテキストを生成できる関数を作成しました。この関数は、リモート プロセスに 2 つのメモリ チャンクを割り当て、TVITEM 構造体 (リモート プロセスにコピーされたもの) を設定し、TVM_GETITEM メッセージを送信し、最後に 2 番目のリモート メモリ チャンクの内容をローカル バッファに読み込みます。これはコードです:
std::string getTreeViewItemText( HWND treeView, HTREEITEM item )
{
DWORD pid;
::GetWindowThreadProcessId( treeView, &pid );
HANDLE proc = ::OpenProcess( PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, pid );
if ( !proc )
// handle error
TVITEM tvi;
ZeroMemory( &tvi, sizeof(tvi) );
LPVOID tvi_ = ::VirtualAllocEx( proc, NULL, sizeof(tvi), MEM_COMMIT, PAGE_READWRITE);
if ( !tvi_ )
// handle error
TCHAR buffer[100] = { 'X' };
LPVOID txt_ = ::VirtualAllocEx( proc, NULL, sizeof(buffer), MEM_COMMIT, PAGE_READWRITE );
if ( !txt_ )
// handle error
tvi.mask = TVIF_TEXT | TVIF_HANDLE;
tvi.pszText = (LPTSTR)txt_;
tvi.cchTextMax = sizeof(buffer) / sizeof(buffer[0] );
tvi.hItem = item;
if ( !::WriteProcessMemory( proc, tvi_, &tvi, sizeof(tvi), NULL ) )
// handle error
if ( !::SendMessage( treeView, TVM_GETITEM, 0, (LPARAM)tvi_ ) )
// handle error
if ( !::ReadProcessMemory( proc, (LPCVOID)txt_, buffer, sizeof( buffer ), NULL ) )
// handle error
::VirtualFreeEx( proc, tvi_, 0, MEM_RELEASE );
::VirtualFreeEx( proc, txt_, 0, MEM_RELEASE );
::CloseHandle( proc );
return buffer;
}
WC_TREEVIEW
このコードは、クラス名をに渡すときに得られる単純なツリー ビューと非常にうまく連携しますCreateWindow
。ただし、MS Common Controls v5 (comctl32.ocx) または MS Common Controls v6 (mscomctl.ocx) によって提供される新しいツリーでは機能しないことに気付きました。そのような場合、返されるテキストは常に空です (バッファはすべてゼロです)。また、SendMessage 呼び出しがゼロを返すことにも気付きました (したがって、// handle error
上記のコメントで示されているエラー処理が開始されます)。これが本当にエラーを示しているかどうかは不明です。いずれにせよ、バッファはすべてゼロで埋められています。
他のすべてのツリー ビュー メッセージ (TVM_GETITEMRECT など) は完全に機能しているようです。
それがなぜなのか誰か知っていますか?UNICODE フラグをいじってみました (またはTVM_GETITEM
に定義されていることに気付きました) が、それは役に立たなかったようです。TVM_GETITEMA
TVM_GETITEMW