「クロスプロセスサブクラス化」に関する問題
-
08-10-2019 - |
質問
2つの質問。
1)これは予想される結果でなければならないと理解していますが、誰かが私が間違っていることを私に言うことができるかもしれません。私はグローバルフックですべてのウィンドウクラスをサブクラス化しようとしていますが、必要に応じてショップを閉鎖することができないことを除いて機能します。プログラムが最初にフックを登録しているときにフックと出口を登録すると、サブクラス化されたアプリケーションがクラッシュし始めます。
これが私がそれをやろうとしている方法です。
// stores original wndprocs. In the hook dll, outside the shared memory.
map<HWND, WNDPROC> origWndProcs;
// in an EnumWindows callback, executed for all HWND's, also in the hook dll (UWM_REMOVE_HOOK is a registered unique message)
SendMessageTimeout(hWnd, UWM_REMOVE_HOOK, 0, 0, SMTO_ABORTIFHUNG | SMTO_NORMAL, 15000, res);
// Still in the same hook, in the subclassing wndproc..
if (msg == UWM_REMOVE_HOOK) {
if (origWndProcs.find(hwnd) != origWndProcs.end()) {
SetWindowLongPtr(hwnd, GWL_WNDPROC, (LONG_PTR)origWndProcs[hwnd]);
}
}
// clears the hook..
__declspec(dllexport) BOOL ClearHooks(HWND hWnd) {
BOOL unhooked = UnhookWindowsHookEx(hook) &&
UnhookWindowsHookEx(kb_hook) &&
UnhookWindowsHookEx(mouse_hook) &&
UnhookWindowsHookEx(cbt_hook);
if(unhooked)
hWndServer = NULL;
return unhooked;
}
dllmainでは、dll_process_detachで何もしません。代わりに、ClearHooks()は元々フックを登録しているプログラムから呼び出され、そこでフックがenumwindows操作を実行したというメッセージを送信した後にのみ(元のwndprocsを復元する、上記参照)。
WNDPROCフックのウィンドウをサブクラス化します。メッセージを受信し、現在のWNDProcがDLLのものではないすべての目に見えるウィンドウがサブクラス化されています。
基本的に、WindowsがWNDProcを交換したときのものに戻すように見えるという事実にもかかわらず、すべての(私が知る限り)アプリケーションが出口でクラッシュします。誰かが私が間違っていることを手がかりがありますか?
2)WM_MINMAXINFOをインターセプトし、ウィンドウを最大化するたびにウィンドウMaxSizeを変更するためにこれが必要です。残念ながら、DLLでこれを行うことはできませんが、サイズ情報を取得するためにプログラムと話をする必要があります。それで、そのウィンドウに話すための最良の方法は何ですか。元のwm_minmaxinfoメッセージに付属している構造を変更できるように、情報を渡す必要があります。 wm_copydataの構造は、sendmessagetimeoutの呼び出しが戻るまでデータを保存しますか?
ありがとう
解決
ここには多くの問題点があります。他のコードがウィンドウをサブクラス化しないと仮定します。そして、そのようなコードは正しい順序でそれをサブカラス化するでしょう。正しい順序はありません。あなたのフックはプログラムの実行から非常に非同期です。
しかし、回避策は十分に簡単です。あなたはすでにsetwindowshookexと一緒にフックしています。 Wh_callwndprocまたはwh_callwndprocret、あなたがしたいことに応じて。