ボタンのフォーカス状態について

[戻る]
べーちゃん 2002/05/09(木) 05:43:37
べーちゃんと申します。ログイン用ダイアログを作っていたときボタン
フォーカスについてわからないことがでてきてきたので質問させてください。

フォームはダイアログフォームにエディットコントロールを2つ、
ボタンコントロールを2つ貼り付けただけの簡単なものです。

PreTranslateMessage関数においてエディットコントロールでRETURNキー
または上下の矢印キーが押されると次のコントロールにSetFocus関数で
フォーカスを移すようにしているだけです。

なお。ボタンはIDOKを消して、独自のID_LOGINというボタンを使って
います。IDCANCELはそのまま使っています。

通常にTABキーでフォーカスを移動しているとボタンにフォーカスが
入ったときはフォーカスライン?(点線)が表示されボタンも強調表示
されるのですが、PreTranslateMessage関数でSetFocus関数を使って
フォーカスを移動させた場合、ボタンにフォーカスが入っても強調表示
にはなりません。特に初めてボタンにフォーカスが移ったときには
フォーカスラインすらも表示されません。

機能的には問題なく動作しているのでVBだとあきらめるところなのですが、
VCだとなんとか制御できないか知りたくなりました。

そこで、
1.SetFocus関数でボタンにフォーカスを移したときでもフォーカス
 ラインが表示され強調表示になるようにできないでしょうか。

2.逆にボタンにフォーカスが入ってもボタンにフォーカスラインも
 強調表示もされないようボタンを設定することは可能でしょうか。

「フォーカス」「点線」で過去ログも検索しましたが思ったような
内容が見つかりませんでした。

どうかご存知の方がいらっしゃいましたらご教授願います。

開発環境
Windows2000Pro + Visual C++ V6.0 (MFC使用)でいずれも英語版です。

よろしくお願いします。

sugar 2002/05/09(木) 09:13:21
> 1.SetFocus関数でボタンにフォーカスを移したときでもフォーカス
>  ラインが表示され強調表示になるようにできないでしょうか。
> 
一般に、ダイアログ上のコントロールのフォーカス指定は、
CWnd::SetFocus()ではなく、CDialog::GotoDlgCtrl()を使用します。
あまり知られていないようですが...
試してみてください。

> 2.逆にボタンにフォーカスが入ってもボタンにフォーカスラインも
>  強調表示もされないようボタンを設定することは可能でしょうか。
> 
ボタンをオーナー描画すればできると思いますが、
ちょっとそれ以外に、お手軽にできる方法は思い当たりませんね。

ひいらぎきんぐ 2002/05/09(木) 09:22:54
確かにSetFocusだとボタンの周りが強調表示されませんね。知りませんでした。
こんな感じでやれば、ダブオーダー順に移動してくれると思います。

switch (pMsg->message) {
case WM_KEYDOWN:
    if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_DOWN) {
        PostMessage(WM_NEXTDLGCTL, 0L, 0L);
        return TRUE;
    } else if (pMsg->wParam == VK_UP) {
        PostMessage(WM_NEXTDLGCTL, 1L, 0L);
        return TRUE;
    }
    break;
}

べーちゃん 2002/05/10(金) 02:12:15
sugarさん、ひいらぎきんぐさんありがとうございます。べーちゃんです。

貴重なヒントありがとうございます。

>一般に、ダイアログ上のコントロールのフォーカス指定は、
>CWnd::SetFocus()ではなく、CDialog::GotoDlgCtrl()を使用します。
>あまり知られていないようですが...
>試してみてください。

そうだったんですか。過去ログでフォーカスの制御を調べているときに
SetFocusのことしか見てなくて(というかVBではSetFocusしか使わないので)
てっきりそれしかないと思っていました。(さすがVCは奥が深い)

そこでsugarさんのいわれる通り、GotoDlgCtrl関数でフォーカス移動を
行うように変更しました。すると強調表示ができるようになりました。
ところが、それでも最初にエディットコントロールからボタンコントロールに
フォーカスが移動したときにはフォーカスラインの描画が行われません。

ちなみにひいらぎきんぐさんのサンプルコードをヒントにMSDNで
NextDlgCtrl関数とPrevDlgCtrl関数を見つけてそれを使うようにも
書き換えてみたのですが、結果はGotoDlgCtrl関数を使ったときと同じで
強調表示にはなりますが、最初にボタンフォーカスに入ったときに
フォーカスラインは描画されません。

それで、できましたらもう少し情報をいただけると助かります。
お願いします。


追伸:
>> 2.逆にボタンにフォーカスが入ってもボタンにフォーカスラインも
>>  強調表示もされないようボタンを設定することは可能でしょうか。
>> 
>ボタンをオーナー描画すればできると思いますが、
>ちょっとそれ以外に、お手軽にできる方法は思い当たりませんね。

そうですか、まあこちらは簡単にできたらいいな程度だったので
もう少しスキルアップしてからチャレンジしてみます。

sugar 2002/05/10(金) 09:28:01
> ところが、それでも最初にエディットコントロールからボタンコントロールに
> フォーカスが移動したときにはフォーカスラインの描画が行われません。
> 
えぇぇ、そうなんですか?
私の環境では、問題ないのですが。

そんな時は、テスト目的で、もっとシンプルな状況で試してみましょう。
新規にダイアログベースのMFCアプリケーションを作り、
ダイアログリソースからはエディットボックスを1つ追加。
C***Dlg::PreTranslateMessage()にひいらぎきんぐさんの提示するコードを追記してビルド
します。
ボタンにフォーカスが当たっても、きちんと点線の矩形が表示されませんか?
勿論、PostMessage()をNextDlgCtrl()等に置換えても、同じです。

ちなみに私の開発環境はべーちゃんさんと同じです。
英語版ではありませんが。
VSには、sp5があたってます。

ひいらぎきんぐ 2002/05/10(金) 09:41:12
>>最初にボタンフォーカスに入ったときに
>>フォーカスラインは描画されません。
フォーカスラインというものはボタンコントロールの内側、ボタン文字列の
周りに描画される点線という認識でよいですよね?

ウィザードからダイアログベースを選択してIDOKを削除して別のボタン、
2個のエディットを配置して前に書いたソースを貼り付けて見ましたが
表示されています。手順等に誤りがありましたらご指摘ください。

私の環境はWindows2000Pro(SP2) VisualStudio6.0(SP5)日本語環境です。

べーちゃん 2002/05/11(土) 00:29:47
[[解決]]
sugarさん、ひいらぎきんぐさんありがとうございます。べーちゃんです。

>フォーカスラインというものはボタンコントロールの内側、ボタン文字列の
>周りに描画される点線という認識でよいですよね?

その通りです。

>そんな時は、テスト目的で、もっとシンプルな状況で試してみましょう。

そうですね。ということでやってみたのですが、結果は全く変わりません
でした。

ただ、私は自宅に同じWindows2000Pro(SP2)+Visual Studio6.0(SPなし)
の日本語版環境を持っているので、実は同じソースで試してみました。

するとっ・・・・・なんと動きました。あれれ???なんでやろ?

もしかすると英語版特有の問題なのかな???
ということで最後に少しすっきりしない部分が残ってはしまいましたが
とりあえずアプローチとしては正しい方法がわかりました。
どうもありがとうございました。

追伸:
もしこの英語版と日本語版の相違部分に関して、情報をお持ちの方は
どうか教えてください。

古いスレッドには追加発言できません。