他アプリのproc取得(GetWindowLong)がうまくいかない

解決


よっち  2007-06-15 16:46:45  No: 65408  IP: 192.*.*.*

アプリA(一般に出回っているソフト)のあるイベントを
アプリB(作成中のソフト)で拾いたいと思っています。
色々調べた結果、GetWindowLong でアプリAの proc関数アドレスを
拾ってきて、SetWindowLong で自作したproc関数に呼び込もうと
思っています。
spy+で見たところ、このウィンドウのこのイベント!
というところまでは見つけました。

アプリB側で アプリAのインスタンスやスタイルは
うまく取得できているようですが、GWLP_WNDPROC が
取得できていないようなのです。

GetWindowLong()  GWL_HINSTANCE  = [  400000] 
GetWindowLong()  GWL_STYLE      = [34cf0000] 
GetWindowLong()  GWL_EXSTYLE    = [     100] 
GetWindowLong()  GWL_ID         = [   40235] 
GetWindowLong()  GWL_WNDPROC    = [       0] 

何かご存知の方、いらっしゃいませんでしょうか?
アプリBは SDK で作成したいと思っています。
VisualC++.NET 2003, WindowsXP


実は、アプリB内のエディットコントロールの改行を拾いたくて
上と同じように GetWindowLong()で procを取得し、
SetWindowLong()で自作のprocに飛ばすことが出来ています。
同じアプリ内だとWNDPROCがうまく行って、他のアプリだと
うまく行かないことってあるのでしょうか。

よろしくお願いします。<m(__)m>

編集 削除
よっち  2007-06-15 16:53:03  No: 65409  IP: 192.*.*.*

GWLP_WNDPROC と書かれていますが、
GWL_WNDPROC  の間違いです。失礼しました。

GWL_WNDPROC の問い合わせ後に
GetLastError()をかけ、 FormatMessage()でエラーメッセージを
確認したところ、

ErrorMsg = 既に存在するファイルを作成することはできません。

と出ました。
ん?  違うエラーメッセージかな・・・???

よろしくお願いします。

編集 削除
よっち  2007-06-15 18:23:04  No: 65410  IP: 192.*.*.*

追記します。
間違っていましたら、ご指摘おねがいします。
アプリAのウィンドウハンドルを FindWindow を使って
取得しました。
そこから、今回のイベントを取得したいコントロール
(Editコントロール)のハンドルを取得しました。

HWND w0 = ::FindWindow( NULL, "アプリAのウィンドウキャプション");
HWND hEdit = GetDlgItem( w0,  IDC_EDIT_アプリAのエディットコントロールID  );
WNDPROC OrgEditProc=(WNDPROC)GetWindowLong(w,GWL_WNDPROC);

hEditは SetWindowText()や GetWindowText()がうまく行くことから、
合っているかなと思っています。
よろしくお願いします。

編集 削除
n  2007-06-15 21:18:55  No: 65411  IP: 192.*.*.*

MSDN Library SetWindowLong
>GWL_WNDPROC   ウィンドウプロシージャのアドレスを書き換えます。
>Windows NT/2000:この属性は、ウィンドウが関数を呼び出したスレッドと
>同じプロセスに属していないと変更できません。

これのせいで取得も出来なくなっているみたいですが...
WNDPROCの書き換えとメッセージフックのどちらを利用するにしても
SetWindowsHookEx()で対象プロセスに自作DLLをロードする必要がありそうです

編集 削除
よっち  2007-06-15 22:00:44  No: 65412  IP: 192.*.*.*

見落としていました。そうでしたか・・・
フック用のDLLをこしらえないといけないんですね。
道理でサイトをさがしていると、DLLの記述が多いわけですね。

ということは、アプリBは exe で作成していますが、
アプリAをフックするための DLL が必要ということですね。

調べてみます。有難う御座います。<m(__)m>

編集 削除
よっち  2007-06-17 06:32:25  No: 65413  IP: 192.*.*.*

フックDLLを作成し、そのDLLの中で、
以下のように SetWindowsHookEx を使ってみました。

hHookWnd = SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)MyCallWndProc, g_hDll, g_idThread );

hHookWnd には NULL以外だったので、きっとうまくいったのでしょうね。

それで、MyCallWndProc は以下のようにしました。
要は、まだ何もせず抜けたいのですが、これで何か問題ありますでしょうか。
というのも、これを実行すると アプリAが落ちてしまいます。

LRESULT CALLBACK MyCallWndProc(int nCode,WPARAM wParam,LPARAM lParam)
{
return CallNextHookEx(hHookWnd, nCode, wParam, lParam); //次のフックを呼ぶ
}

心当たりございませんでしょうか?


ひとつ気になったのは  このDLLの中で
GetWindowLong()をやってみたら、 
 GWL_WNDPROC    = [       0]  でした。
あれ・・・  DLL内で行えば、動くんですよね・・?
スタイル等は正常に取得できています。

編集 削除
よっち  2007-06-18 08:21:19  No: 65414  IP: 192.*.*.*

SetWindowsHookEx() については、
うまくメッセージを受信できるようになりました。
単純なミスで switch case 文の break が抜けていて、
思わぬ動きをしていました。汗

GetWindowLong (GWL_WNDPROC)は DLL内で行なうと、
あいかわらず 0 になってしまいますが、
メッセージフックの方で行けそうなので、
これで作業を進めたいと思います。

とりあえず解決とします。有難う御座います。
<m(__)m>

編集 削除