WM_SETFOCUSのフック – プログラミング – Home

通知
すべてクリア

[解決済] WM_SETFOCUSのフック


VAL
 VAL
(@VAL)
ゲスト
結合: 22年前
投稿: 14
Topic starter  

タイトルに書いた通り、WM_SETFOCUSメッセージをフックしたいのですがその方法が分か
りません。

SetWindowsHookExでフックルーチンを設定していますが、1つ目のパラメータには何を
指定すれば良いのかが分かりません。

WH_CALLWNDPROC,WH_GETMESSAGE,WH_MSGFILTERともに試しましたが、フックルーチンでは
WM_SETFOCUSが取れませんでした。

最終的にフォーカスを受け取る前に自前の処理を行うことが目的です。
(EN_SETFOCUSなどを受け取るコントロールに対しても自前の処理を行いたいと考えてい
ます。)

なにか良案がありましたらご指南お願いします。

VC6とSDKです。


引用未解決
トピックタグ
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

WH_CALLWNDPROCでWM_SETFOUCSをフックできますよ。


返信引用
VAL
 VAL
(@VAL)
ゲスト
結合: 22年前
投稿: 14
Topic starter  

WH_CALLWNDPROCで解決出来ました。
dairygoodsさんどうもありがとうございました。

(最初うまく行かなかったのは、私のミスでした(汗))

ところで、EN_SETFOCUS等はフックルーチンで取れないですよね?
ボタンなどへの通知メッセージも、フックルーチンではWM_COMMANDではなくて
WM_SETFOCUSとして来ているようなのでボタンなのかどうかクラス名で判断して処理する
ようにしましたが、これでいいのでしょうか?
今はうまく動いていますが、私の知らないコントロールがあったり、今後新たなコント
ロールが増えた場合に修正する必要があるので。

ちなみに、フックルーチンではWM_SETFOCUSが来る直前を知らせるユーザーメッセージを
送るような作りにしています。


返信引用
VAL
 VAL
(@VAL)
ゲスト
結合: 22年前
投稿: 14
Topic starter  

深刻な問題が発生しました。

そう言ってもフック関係では無くなってしまったのですが、最初から説明します。

【やりたいこと】
エディットボックスへ入力する前にメッセージボックスを表示して、その後に入力を行
いたいです。
場合によっては入力をさせたくありません。

【プログラムベース】
VC6とSDKを使用してダイアログベースのプログラムを作っています。

【作ったプログラム】
(これはモーダルダイアログのウィンドウプロシージャ例ですが、問題は再現しま
す。)
static BOOL focus;
switch (msg)
{
case WM_INITDIALOG:
SetWindowText(GetDlgItem(hwnd, IDC_EDIT1), 12345);
focus = FALSE;
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_EDIT1:
if (HIWORD(wParam) == EN_SETFOCUS && !focus)
{
focus = TRUE;
MessageBox(hwnd, 入力します, ", MB_OK);
focus = FALSE;
}
break;
}
break;

【問題点】
エディットボックスをクリックしてメッセージボックスを表示させてOKボタンを押し
て閉じた後、マウスを左右に動かすだけでエディットボックス内のテキスト選択状態が
変わってしまいます。
マウスをクリックしたままテキストを選択する時と同じ動作になっているみたいです。

【対策】
EN_SETFOCUSの時にメッセージボックスを表示するのに問題があると見て、フックを使用
してEN_SETFOCUSを受け取る前にメッセージボックスを表示させてみました。

ここまで試行錯誤しましたが、どうしても問題が解決しません。
なにか根本的に間違いがあるのでしょうか?


返信引用
たみあ
 たみあ
(@たみあ)
ゲスト
結合: 22年前
投稿: 57
 

試していません、解決するかわかりません

フックを使わずに、EN_SETFOCUSで処理する方向性で

EN_SETFOCUS の中で処理をせずに
ユーザー定義メッセージを自分自身にPostMessageして
ユーザー定義メッセージ側で MessageBox する

という方法でうまくいかないかな?
うまくいかなかったらごめんなさい


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> ところで、EN_SETFOCUS等はフックルーチンで取れないですよね?
> ボタンなどへの通知メッセージも、フックルーチンではWM_COMMANDではなくて
> WM_SETFOCUSとして来ているようなのでボタンなのかどうかクラス名で判断して処理する
> ようにしましたが、これでいいのでしょうか?

WM_SETFOCUSを受け取ったエディットボックスが、
WM_COMMANDにEN_SETFOCUSを指定して親ウィンドウに通知しているのです。

どちらもフックできます。
ただし、通知メッセージは他の種類のコントロールの通知メッセージと
値が重なっている可能性があるので、ウィンドウクラス名の判定は必要です。

> マウスをクリックしたままテキストを選択する時と同じ動作になっているみたいです。

現象から想像するに、ボタンが押されてフォーカスを受け取ったとたんに
メッセージボックスが表示され、フォーカスを失ってしまうために、
ボタンを放すメッセージがエディットボックスに届いていないのでしょう。

エディットボックスにWM_LBUTTONUPを送ってあげれば
うまく行くかもしれません。


返信引用
VAL
 VAL
(@VAL)
ゲスト
結合: 22年前
投稿: 14
Topic starter  

たみあさん
>ユーザー定義メッセージを自分自身にPostMessageして
>ユーザー定義メッセージ側で MessageBox する
実はこれは真っ先に思い付いたのですが、プログラムが少しごちゃごちゃしてしまう気
がしたので、汎用的なフックルーチンを作って奇麗にまとめようという気になってまし
た。
後で書きますように問題は解決しましたが、解決方法から考えるとたみあさんの方法で
も良かったのではないかという気がします。

dairygoodsさん
>WM_SETFOCUSを受け取ったエディットボックスが、
>WM_COMMANDにEN_SETFOCUSを指定して親ウィンドウに通知しているのです。
そうでしたか。それならばクラス名の判定は仕方ないですね。

>エディットボックスにWM_LBUTTONUPを送ってあげれば
これで解決しました!
長いこと悩んでいたのが愚かに思えるくらいです。

たみあさん、dairygoodsさん、どうもありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました