環境はVS2008 MFC
Spy++のように別アプリケーションのキャプションやクラスを
正確に表示するにはどうすればよいでしょうか?
あるnotMFCのマウスのLDOWNメッセージのグローバルHookDLLから
HWNDがメッセージに添付されて送られてきてそれに対して以下のような実装をしています
CString s1, s2
CWnd* p = FromHandle(hwnd);
s1 = p->GetRuntimeClass()->m_lpszClassName;
p->GetWindowText(s2);
このhwndはEditですが
s1 = CWnd, s2 = "
になります。Spy++ではs1 = Edit, s2 = xxxx とウィンドウに表示されているものが
きちんと取得できているようなので方法はあると思うのですが
EnumWindows()して、得られた複数のHWND(トップレベル)に対して
EnumChildWindows()を再帰的に適用します。
マウスポインタで指定したい場合は、WindowFromPoint()を
使う手もあります。Spy++はこっちでしょう(たぶん)。
得られたHWNDを使ってGetWindowLongPtr()や
GetClassLongPtr()使用すれば、マニュアルにあるような
さまざまな情報が得られます。
> CWnd* p = FromHandle(hwnd);
CWnd::FromHandle() は hwnd の実際のクラスに合わせた MFC のクラスを返してはくれな
い。↓を走らせてみると判り易いかと。
{
CEdit edit;
edit.Attach(hwnd); // 管理クラスに hwnd のMFCクラスは「edit」だと登録される
CEdit *pwnd = CEdit::FromHandle(hwnd); // 登録されているので「edit」が返される
CStringA st;
st.Format(%08x, %08x, %s, &edit, pwnd,
pwnd->GetRuntimeClass()->m_lpszClassName);
MessageBoxA(st);
edit.Detach(); // 管理クラスから hwnd が除外される
pwnd = CEdit::FromHandle(hwnd); // (未登録の)hwndのMFCクラスが要求されたので
一時的な≒CWndクラスが用意される
st.Format(%08x, %08x, %s, &edit, pwnd,
pwnd->GetRuntimeClass()->m_lpszClassName);
MessageBoxA(st);
}
> p->GetWindowText(s2);
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633520.aspxのRemarks参照
要すると「他プロセスのcaption持ってないウィンドウの場合は空文字返すよ。そういう
場合はWM_GETTEXTを直で投げれば良いよ」
> きちんと取得できているようなので方法はあると思うのですが
という事なんでクラス名は GetClassName()、文字は WM_GETTEXT でいけるんじゃないか。
仲澤さん、gakさん
回答ありがとうございます。GetClassNameとWM_GETTEXTで動作確認しましてOKでした!