
ダイアログボックスのボタンコントロールのフォーカスについて
教えて下さい。
モーダルダイアログにボタン「OK」を一つ貼り付けて
それを「標準のボタン」(BS_DEFPUSHBUTTON)として作成したのですが
ダイアログ表示直後は下画像(1)のようになってエンターキーを押しても
反応しません。何度かカーソルキーを押すとようやく(2)のように
ボタンに枠線がついてエンターで押せるようになるのですが
ダイアログ表示直後に(2)のようにするにはどうするべきでしょうか?
ダイアログのコールバック・プロシージャ(WM_INITDIALOG部分でボタン作成)
LRESULT CALLBACK SettingWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
switch (msg){
case WM_INITDIALOG:
CreateWindowEx(0x00000000,"BUTTON","OK",
WS_CHILD |WS_VISIBLE| WS_TABSTOP | BS_DEFPUSHBUTTON,
16,16,80,21,hWnd,(HMENU)IDOK,GetModuleHandle(0),0);
return TRUE;
}
return FALSE;
}

No.4ベストアンサー
- 回答日時:
>但し付けていただいたリンク先の説明によるとTRUEを返す場合、
>「最初の WS_TABSTOP をもつコントロールにフォーカスがセットされます。」
>ということから考えれば、TRUE戻しでもこのボタンにフォーカスが当たっても良い筈です。
>この場合何故そうならないのかはまだ分かりません。
WM_INITDIALOGのWPARAMに「フォーカスが当たる予定のコントロールID」が入って呼ばれますが、
WM_INITDIALOGをOSが発行した時点ではWM_INITDIALOGのハンドラ内で生成されるコントロールは「まだ生成されていない」ですし、付与されるコントロールIDも不明です。
となると、WM_INITDIALOGのハンドラ内で生成したコントロールにWS_TABSTOPが付いていてもその時点ではどうしようもありません。
BS_DEFPUSHBUTTONが効くのも、WM_INITDIALOGが発行される前、OS側がWM_INITDIALOGのWPARAMに設定するコントロールIDを決定するために精査するとき…と言うことなのではないでしょうか。
この回答への補足
お礼の文面の訂正を。
>>WM_INITDIALOG内でコントロールを作るなということですね。
WM_INITDIALOG内でコントロールを作るなというより
もしそこで作った場合は自分でフォーカスを合わせる、ということだと思います。
それから
>> またBS_PUSHBUTTONにした上で「フォーカス当てのFALSE戻し」にした時は
この場合は逆にフォーカスが当たらないままでした。
これは「フォーカスが当たらない」のではなくて、図(1)の状態になる(ボタンに実線枠が
付かずエンター押しが効かない)の間違いでした。
「点線」のフォーカスそのものは当たっているものと思います。
以上を訂正させて頂きます。申し訳ありません。
なるほど。確かに説明されている通りです。
解説を貰ってストンと自分でもようやく理解出来ました。
>>WM_INITDIALOGをOSが発行した時点ではWM_INITDIALOGのハンドラ内で生成されるコントロールは「まだ生成されていない」ですし、付与されるコントロールIDも不明です。
まさにそれが原因で起こっていた現象だと思います。
WM_INITDIALOG内でコントロールを作るなということですね。
リソースエディタで作成すれば大丈夫なんでしょうか?
有難うございます。またよろしくお願いします。
No.3
- 回答日時:
ダイアログボックスのクライアント内(何かのコントロール)にフォーカスが設定されていれば、
EnterキーでIDOK、ESCキーでIDCANCELが飛んでくるかと思われますが…。
ということで、作成するボタンのIDは別にしないと、デフォルト動作でIDOKが飛んでいるのかどうか判らなくなると思われます。
ダイアログボックスの最初のフォーカスはシステム側で設定されてきます。
# WM_INITDIALOGのWPARAMにコントロールIDが設定されています。
WM_INITDIALOGのメッセージ処理中に、最初のフォーカスを変更したい場合は、#1さんの掲示されているSetFocus()を使用し、
WM_INITDIALOGの応答としてFALSEを返却する必要があります。
http://wisdom.sakura.ne.jp/system/winapi/win32/w …
ダイアログプロシージャからの返却の場合、SetWindowLong()でDWL_MSGRESULTに設定して返すことになりますが…
WM_INITDIALOGの場合はそのまま返却でよい…みたいです。
http://msdn.microsoft.com/en-us/library/ms645428 …
この回答への補足
ここまでのテスト結果を。
IDをIDOKにしてはいけないという所はまだ理解が追いついてないのですが
とりあえずIDを「CommandButton1」などに替えてみてテストしてみました。
ただその時点ではまだ現象は変わりませんでした。
次にその設定のまま「SetFocusでフォーカスをボタンに当ててFALSE戻し」
にすると、これは上手くフォーカスが当たりエンター押しも効きました。
但し付けていただいたリンク先の説明によるとTRUEを返す場合、
「最初の WS_TABSTOP をもつコントロールにフォーカスがセットされます。」
ということから考えれば、TRUE戻しでもこのボタンにフォーカスが当たっても良い筈です。
この場合何故そうならないのかはまだ分かりません。
最後にBS_DEFPUSHBUTTONを「BS_PUSHBUTTON」に替えてやってみたのですが
これはTRUE戻しでも上手く行きました。だとするとDEFPUSHBUTTONは使えないの
かな、とも思ってしまうのですが、、、
またBS_PUSHBUTTONにした上で「フォーカス当てのFALSE戻し」にした時は
この場合は逆にフォーカスが当たらないままでした。
ちょっと迷いそうになってますが、もう少しテストを続けてみます。
有難うございます。書いて頂いたコード、リンクを参考にさせてもらいながら
これからこちらでもテストしたいと思います。少し時間を貰って、また報告します。
No.2
- 回答日時:
XP で試してみたところ、なぜかよくわかりませんが、BS_DEFPUSHBUTTON ではなく BS_PUSHBUTTON にするとダイアログ表示直後でも ENTER キーで反応しました。
ただし、概観はやはり BS_DEFPUSHBUTTON ではなく BS_PUSHBUTTON のものです。この回答への補足
ここまでのテスト結果を。
IDをIDOKにしてはいけないという所はまだ理解が追いついてないのですが
とりあえずIDを「CommandButton1」などに替えてみてテストしてみました。
ただその時点ではまだ現象は変わりませんでした。
次にその設定のまま「SetFocusでフォーカスをボタンに当ててFALSE戻し」
にすると、これは上手くフォーカスが当たりエンター押しも効きました。
但し付けていただいたリンク先の説明によるとTRUEを返す場合、
「最初の WS_TABSTOP をもつコントロールにフォーカスがセットされます。」
ということから考えれば、TRUE戻しでもこのボタンにフォーカスが当たっても良い筈です。
この場合何故そうならないのかはまだ分かりません。
最後にBS_DEFPUSHBUTTONを「BS_PUSHBUTTON」に替えてやってみたのですが
これはTRUE戻しでも上手く行きました。だとするとDEFPUSHBUTTONは使えないの
かな、とも思ってしまうのですが、、、
またBS_PUSHBUTTONにした上で「フォーカス当てのFALSE戻し」にした時は
この場合は逆にフォーカスが当たらないままでした。
ちょっと迷いそうになってますが、もう少しテストを続けてみます。
有難うございます。書いて頂いたコード、リンクを参考にさせてもらいながら
これからこちらでもテストしたいと思います。少し時間を貰って、また報告します。
No.1
- 回答日時:
こんばんは。
う~む、ボタンハンドルを指定してSetFocus()APIを呼び出しても無理でしょうか。
試して見ましたが、SetFocus()APIなしでも、特に問題なく反応しています。
// test.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include"stdafx.h"
#include<windows.h>
#include"resource.h"
//ダイアログ
INT CALLBACK SettingWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg)
{
case WM_INITDIALOG:
{
HWND hButton = ::CreateWindowEx(0, TEXT("BUTTON"), TEXT("OK"),
WS_CHILD |WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON,
16, 16, 80, 21, hWnd, (HMENU)IDOK, ::GetModuleHandle(NULL), 0);
//取りあえず呼んでみる
::SetFocus(hButton);
return TRUE;
}
case WM_COMMAND:
if(wp == IDOK)
{
::EndDialog(hWnd, FALSE);
}
break;
}
return FALSE;
}
//ウィンドウ
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
//左ボタンクリックでダイアログを出す
case WM_LBUTTONDOWN:
::DialogBox(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), hWnd, &::SettingWndProc);
return 0;
case WM_NCDESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
文字数制限により、WinMain()を省略。
この回答への補足
ここまでのテスト結果を。
IDをIDOKにしてはいけないという所はまだ理解が追いついてないのですが
とりあえずIDを「CommandButton1」などに替えてみてテストしてみました。
ただその時点ではまだ現象は変わりませんでした。
次にその設定のまま「SetFocusでフォーカスをボタンに当ててFALSE戻し」
にすると、これは上手くフォーカスが当たりエンター押しも効きました。
但し付けていただいたリンク先の説明によるとTRUEを返す場合、
「最初の WS_TABSTOP をもつコントロールにフォーカスがセットされます。」
ということから考えれば、TRUE戻しでもこのボタンにフォーカスが当たっても良い筈です。
この場合何故そうならないのかはまだ分かりません。
最後にBS_DEFPUSHBUTTONを「BS_PUSHBUTTON」に替えてやってみたのですが
これはTRUE戻しでも上手く行きました。だとするとDEFPUSHBUTTONは使えないの
かな、とも思ってしまうのですが、、、
またBS_PUSHBUTTONにした上で「フォーカス当てのFALSE戻し」にした時は
この場合は逆にフォーカスが当たらないままでした。
ちょっと迷いそうになってますが、もう少しテストを続けてみます。
有難うございます。書いて頂いたコード、リンクを参考にさせてもらいながら
これからこちらでもテストしたいと思います。少し時間を貰って、また報告します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA 参照先で選んだファイルをコピーし、出力先に別名で保存したい 8 2022/05/13 20:37
- JavaScript 追加ボタンを押した際に ok ボタンを押した場合のみ入力値が追記されるようにしたいです 6 2022/05/29 09:57
- JavaScript Javascriptが機能せず原因が分からないので教えて頂きたいです 3 2023/06/04 14:50
- HTML・CSS ボタンをクリックした時に、入力フォームのすぐ下部に、「入力欄が空白です」というテキストメッセージが表 1 2022/04/27 16:25
- JavaScript jsで診断コンテンツのページ内切り替えについて 1 2023/04/14 17:31
- Excel(エクセル) マクロでボタンにつける名前がどこに設定されているかわからないケースがありました。 1 2023/06/19 19:37
- Visual Basic(VBA) Vba LongPtrについて教えてください 2 2022/08/19 11:14
- JavaScript スマフォではボタンを表示させたくない 2 2023/01/20 14:26
- JavaScript ①入力フォーム→②確認表示画面→③送信完了画面のコードを書いているのです、 入力フォームから受け取っ 2 2022/05/10 16:45
- Visual Basic(VBA) 【ExcelVBA】動的にボタン、ボタン名を生成できますか? 7 2022/04/08 12:54
このQ&Aを見た人はこんなQ&Aも見ています
-
テキストボックスからフォーカス外す
C言語・C++・C#
-
画面を強制的に再描画させる方法
C言語・C++・C#
-
エディットコントロールでEnter押した時の動作
C言語・C++・C#
-
-
4
サイズ変更枠ダイアログのタイトルバー左端のアイコンを消す
C言語・C++・C#
-
5
エディットボックスの入力制限について
C言語・C++・C#
-
6
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
7
VC++でコントロールの境界線を描画する方法
C言語・C++・C#
-
8
ダイアログ内コントロールの位置取得について
C言語・C++・C#
-
9
CWnd::EnableWindow()の扱い方
C言語・C++・C#
-
10
ボタンの表示の色、フォントを変更したい
C言語・C++・C#
-
11
charからLPTSTRへの変換方法
C言語・C++・C#
-
12
EDITコントロールで入力できる文字を制限するには?
C言語・C++・C#
-
13
子ダイアログのコントロールにフォーカス(VC++2005)
C言語・C++・C#
-
14
CFileDialogの最初のディレクトリ設定
C言語・C++・C#
-
15
CString型 全角半角を意識せずに「1文字」ずつ取り出す
C言語・C++・C#
-
16
リストコンロールの一行だけを太文字に(VC++)
C言語・C++・C#
-
17
CStringについて
C言語・C++・C#
-
18
プロセスIDからウィンドウハンドルを取得する方法
C言語・C++・C#
-
19
リストコントロール(MFC or API)の最後尾にアイテムを追加するには?
C言語・C++・C#
-
20
ダイアログ表示時にチェックボックスにチェックされている状態にするには?
C言語・C++・C#
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
-
大麻の使用罪がなかった理由や法改正での変更点、他国との違いを弁護士が解説
ドイツで2024年4月に大麻が合法化され、その2ヶ月後にサッカーEURO2024が行われた。その際、ドイツ警察は大会運営における治安維持の一つの方針として「アルコールを飲んでいるグループと、大麻を吸っているグループ...
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コントロールの書式設定で、“コ...
-
DateTimePickerでに年月までし...
-
エクセルのコントロールツール...
-
スピンボタンを右クリックして...
-
C#でパネルに子パネルを上から...
-
コンボボックスでコントロール...
-
VisualStudio MFC変数が追加で...
-
アイテムを点滅させる
-
ワードのドロップダウンリスト
-
複数列リストコントロールについて
-
コモンダイアログコントロール...
-
EXCELVBA リストボックスで選択...
-
CEdit の内容が変わった時にメ...
-
regsvr32でActiveX登録を行ったocx
-
Tabコントロールに貼り付けたダ...
-
Accessのタブコントロールを2...
-
TabControlが変る瞬間イベント
-
ActiveXコントロールを.NETにイ...
-
タブコントロール上のリストコ...
-
Flash Playerをダウンロードし...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コントロールの書式設定で、“コ...
-
エクセルのコントロールツール...
-
スピンボタンを右クリックして...
-
DateTimePickerでに年月までし...
-
ActiveXコントロールを.NETにイ...
-
フォームでPDFを表示させた...
-
コモンダイアログコントロール...
-
連続で印刷すると画像が更新さ...
-
VScrollBarの点滅を何とかしたい。
-
エクセル - リストボックスのマ...
-
CEdit の内容が変わった時にメ...
-
空のリストビューで1行おきに...
-
リストコントロール(MFC or API...
-
TabControlとToolBarの背景色変更
-
タブコントロール上のリストコ...
-
アイテムを点滅させる
-
EXCELVBA リストボックスで選択...
-
regsvr32でActiveX登録を行ったocx
-
Accessのタブコントロールを2...
-
VB6.0のデザイン時 コントロー...
おすすめ情報