プログラムにDLLを挿入して、アプリケーションのメインウィンドウにチャットUIを実装しました。アプリケーションのメインウィンドウハンドルを取得し、次にDCを取得して、そこに描画できると考えました。ウィンドウには予測可能なタイトルがあります。これはFindWindow
、ハンドルを取得するために使用できることを意味します。唯一の問題は、プロセスの開始時にDLLが挿入されることです。その時点では、ウィンドウは作成されていません。つまりFindWindow
、何も見つかりません!
これに対するいくつかの解決策は何ですか?DLLにスレッドを作成し、ウィンドウが作成されたことがわかるまでしばらくスリープできますか?これは非常に不安定なようですので、やりたくありません。
私がやろうとしたSetWindowsHookEx
のは、DLLでグローバルWndProcをフックするために使用することでした。ウィンドウからメッセージが見つかるまで(つまり、メッセージが作成されるまで)メッセージをスキャンできました。次に、ハンドルを保存してプログラムを続行できます。一度に同じ名前のウィンドウが複数あることについてはあまり心配していません。唯一の問題は、私のフックが呼び出されないことです。
私は次のようにフックを作成します:
m_hWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)WndProc, m_hModule, 0);
if(!m_hWndProcHook)
{
oss << "Failed to set wndproc hook. Error code: " << GetLastError();
Log(oss.str().c_str());
return false;
}
これは有効なフックを返します。WndProcは次のようになります。
LRESULT CALLBACK CChatLibrary::WndProc(int code, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* pData;
ostringstream oss;
char wndName[256];
gChatLib->Log("WNDPROC");
if(code < 0)
return CallNextHookEx(gChatLib->GetWndProcHookHandle(), code, wParam, lParam);
else
{
//Get the data for the wndproc
pData = (CWPSTRUCT*)lParam;
//Log the message
GetWindowText(pData->hwnd, wndName, 256);
oss << "Message from window \"" << wndName << "\"";
gChatLib->Log(oss.str().c_str());
return CallNextHookEx(gChatLib->GetWndProcHookHandle(), code, wParam, lParam);
}
}
しかし、「WNDPROC」メッセージはログファイルに記録されません...以前は、ログのMessageBox
代わりにログが機能するかどうかを確認していましたが、これはひどい考えでした。「OK」をクリックするのを待っていたため、すべてのプログラムがフリーズし、ハードリセットを実行する必要がありました...コンピュータの電源を入れ直してMessageBox
ログコマンドに置き換えたところ、機能しませんでした。ただし、ログは他のすべての場所で機能するため、ログが機能することはわかっています。私はこれで何が起こっているのか非常に混乱しています。
メインウィンドウを取得する他の方法はありますか(できれば作成時に)?または、私のフックメソッドは良いのですが、実行が間違っていますか?フィードバックありがとうございます。