none
ラジオボタンがフォーカスを得たとき・・・ RRS feed

  • 質問

  • VC++6.0で作成した画面上に、クリック時にある動きをするラジオボタンを配置しているのですが、
    フォーカスを得ただけ(クリックではなく、Tabキーでラジオボタンにフォーカス遷移させた)だけで
    クリックのイベントが走ります。

    すいません、当たり前の話しかもしれないのですが、ラジオボタンとはフォーカスを得るだけで
    クリックイベントが走るものなのでしょうか。ちなみにVB6.0でも同じ動きをしました。

    「フォーカスを得る」=「クリックイベントが走る」がどうも納得行きません。ラジオボタンのそもそもの
    動き方の仕様(?)が知りたいと思っています。
    ・「そういうもの」であればそう理解したいと思いますが、何かしらそれを解説しているような文献なりが
     あれば教えていただけないでしょうか。
    ・また何らかの設定に注意が必要とか、フォーカスを得ただけで、クリックイベント自体を走らせない
     ようにすることが可能であれば、そのポイントを教えていただけないでしょうか。

    よろしくお願いします。。

    2009年6月27日 14:45

回答

  • 次の URL にボタン系コントロールのメッセージの仕様が説明されています。

     Button Messages
     http://msdn.microsoft.com/en-us/library/bb775941(VS.85).aspx

    この中の "Button Default Message Processing" の項目の WM_SETFOCUS の説明には、

     Draws a focus rectangle on the button getting the focus. For radio buttons and automatic radio buttons, the parent window is sent a BN_CLICKED notification message.

    と書かれていますので、仕様はそうなっています。
    この動きと違う動きをしたいということは、Windows の標準動作から外れてしまうわけで...。
    2009年6月27日 17:53
  • コントロールの仕様から外れた処理をするからには、何らかの処理の組み込みは必要になると思います。

    マウス操作による BN_CLICKED は WM_LBUTTONDOWN と WM_LBUTTONUP の組み合わせで発生するので、
    例えば CWnd::PreTranslateMessage あたりでラジオボタンに WM_LBUTTONUP が通知されたことを記憶しておいて、
    ラジオボタンのクリック イベント時にその通知の有無との合わせ技で判定するという方法は考えられます。
    ただし、この場合ですと、本当にキーボードでラジオボタンにチェックする場合はどうするかなど、色々と考慮すべきケースは出てきます。
    2009年6月29日 3:10
  • 私も以前この動作でトラブった事があります。
    Windows3.0の16ビット環境で問題ない動作をしていたアプリケーションが
    Windows95で使用されるようになってからトラブルになりました。

    以後、私のアプリケーションではこの問題を
    たとえばFormViewの派生クラスなら
    そのON_WM_SETFOCUSメッセージハンドラで

    void CDerivedFormeView::OnSetFocus(CWnd* pOldWnd)
    {
     m_bOnFocus = true;
     CFormView::OnSetFocus(pOldWnd);
     m_bOnFocus = false;
    }

    としますとBN_CLICKED通知が
    CFormView::OnSetFocus(pOldWnd);
    内部で発生しますので

    CDerivedFormView::OnRadioCliched()
    {
         if (m_bOnFocus)
             return;
       // 通常処理
    }

    というようにプログラムすることで回避しています。

    とんま


    Tomma
    2009年6月29日 6:08

すべての返信

  • 次の URL にボタン系コントロールのメッセージの仕様が説明されています。

     Button Messages
     http://msdn.microsoft.com/en-us/library/bb775941(VS.85).aspx

    この中の "Button Default Message Processing" の項目の WM_SETFOCUS の説明には、

     Draws a focus rectangle on the button getting the focus. For radio buttons and automatic radio buttons, the parent window is sent a BN_CLICKED notification message.

    と書かれていますので、仕様はそうなっています。
    この動きと違う動きをしたいということは、Windows の標準動作から外れてしまうわけで...。
    2009年6月27日 17:53
  • totojo様

    返信ありがとうございます。ご教示いただいた仕様があること、
    理解致しました。大変助かりました。

    ただ、そもそものラジオボタンの設計に問題があったのかと悩むところではあります。

    ラジオボタンの動きとして、

     ・クリックされた時にだけ、ある処理を動かしたい
     ・ただし、Tabキーなどによってフォーカスを得たときはこの処理を動かしたくない

    こういう仕様は一般的ではないのでしょうか。

    仮に、「こういう仕様もあり得ること」であった場合、ラジオボタンのクリックイベントの中に、
    ラジオボタンへのチェック有無の状態判断などを組み込むようにして防ぐのが一般的なのでしょうか。

    すいません、VC++言語依存の話しでなく、方向が少しずれた質問になってしまうかもですが、
    参考までにみなさまのご意見を聞かせていただけないでしょうか。

    よろしくお願いします。
    2009年6月28日 18:13
  • コントロールの仕様から外れた処理をするからには、何らかの処理の組み込みは必要になると思います。

    マウス操作による BN_CLICKED は WM_LBUTTONDOWN と WM_LBUTTONUP の組み合わせで発生するので、
    例えば CWnd::PreTranslateMessage あたりでラジオボタンに WM_LBUTTONUP が通知されたことを記憶しておいて、
    ラジオボタンのクリック イベント時にその通知の有無との合わせ技で判定するという方法は考えられます。
    ただし、この場合ですと、本当にキーボードでラジオボタンにチェックする場合はどうするかなど、色々と考慮すべきケースは出てきます。
    2009年6月29日 3:10
  • 私も以前この動作でトラブった事があります。
    Windows3.0の16ビット環境で問題ない動作をしていたアプリケーションが
    Windows95で使用されるようになってからトラブルになりました。

    以後、私のアプリケーションではこの問題を
    たとえばFormViewの派生クラスなら
    そのON_WM_SETFOCUSメッセージハンドラで

    void CDerivedFormeView::OnSetFocus(CWnd* pOldWnd)
    {
     m_bOnFocus = true;
     CFormView::OnSetFocus(pOldWnd);
     m_bOnFocus = false;
    }

    としますとBN_CLICKED通知が
    CFormView::OnSetFocus(pOldWnd);
    内部で発生しますので

    CDerivedFormView::OnRadioCliched()
    {
         if (m_bOnFocus)
             return;
       // 通常処理
    }

    というようにプログラムすることで回避しています。

    とんま


    Tomma
    2009年6月29日 6:08
  • こんにちは、フォーラムオペレータの高橋です。

    totojoさん
    アドバイスありがとうございました。

    Tomma_NO1さん
    サンプルコードを投稿して頂き有難うございます。
    皆様の参考となるので、大変助かります

    ちっちゃいもの倶楽部副部長さん、こんにちは。
    MSDNフォーラムのご利用ありがとうございます。

    totojoさんとTomma_NO1さんからアドバイスを頂いたと思うのですが、
    如何でしょうか?
    今回totojoさんとTomma_NO1さんから頂いた情報が有用なものだと思いましたので
    勝手ながら、回答マークを付けさせてもらいました。

    今後ともMSDNフォーラムをよろしくお願いします。


    マイクロソフト株式会社 フォーラム オペレータ 高橋春樹
    2009年7月7日 8:21