none
SetActiveViewとSetFocusについて RRS feed

  • 質問

  • いつもお世話になっております。
    VC++ MFCのSDIでプログラムを作っています。
    今の所とくに困ったことがあるわけではないのですが、SetActiveViewとSetFocusについてどう使い分ければいいのか分かりません。
    アクティブウィンドウとフォーカスがあるウィンドウと何が違うのでしょうか?

    2009年12月18日 5:29

回答

  • SetActiveView/GetActiveView は、現在アクティブなビュー(CViewの派生クラス==フレームウィンドウのクライアント領域全面を覆っている子ウィンドウ)を設定、取得するためのものです。
    これに対し、SetFocus/GetFocus は、現在フォーカスを持つ(==キー入力を受け付けている)ウィンドウを設定、取得するためのものです。
    前者は、MFC専用で、CFormView ベースの場合でも必ずビューを対象とするのに対し、
    後者は、API(ラッパー)ですので、HWND(CWndの派生クラス)にたいして作用するものとなります。

    SDIで、ビューが一つの場合、ビューの寿命とアプリケーションの寿命はほぼ一対なのであまり意識しないかもしれませんが
    複数のビューを切り替える仕組みを持っている場合や、印刷機能を有している場合に意外と便利に使えたりします。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/
    2009年12月18日 6:19
  • CFrameWnd::SetActiveView()は「アクティブウィンドウ」を設定するのではなく、
    MFCで定義された「アクティブビュー」を設定するものです。

    MFCでのアクティブビューは、ひとつのフレームウィンドウに対して複数のビューがある時、
    どのビューにコマンドをディスパッチしたら良いかを決定するために、
    フレームワークによって使われるものなのです。
    詳しくは、コマンドの振り分け (ルーティング) (MFC) を参照ください。

    ということで、SDIではCSplitterWndでも使わない限り、
    SetActiveView()を呼び出す必要があるようなことはほぼないと思います。

    CWnd::SetFocus()はヘルプにあるように、キーボードフォーカスをセットするためのものです。
    フォーカスのあるウィンドウに対してすべてのキーボードメッセージが送られることになります。

    一方で、通常「アクティブウィンドウ」と言えば、Windowsでいう"Active Window"の事になると思います。
    アクティブウィンドウに関しては、こちらを参照ください。
    http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx#active

    使い分けですが、ごくごく簡単に言えば、
    複数のCView派生クラスがあるとき、CView派生クラスに対しては、CFrameWnd::SetActiveView()、
    ダイアログ上のコントロールに対しては、CWnd::GotoDlgCtrl()、
    それ以外にはCWnd::SetFocus()
    くらいを基本にして、あとは特殊な事情に個別に対応すればいいと思います。
    2009年12月18日 6:37
  • 「トップに表示されるウィンドウ」というのは何か違う気がしますが、
    いずれにしても提示したリンク先と、
    CWnd::SetFocus(), CFrameWnd::SetActiveView()のヘルプを
    読んでいただければお分かりいただけると思います。

    2009年12月21日 0:24

すべての返信

  • SetActiveView/GetActiveView は、現在アクティブなビュー(CViewの派生クラス==フレームウィンドウのクライアント領域全面を覆っている子ウィンドウ)を設定、取得するためのものです。
    これに対し、SetFocus/GetFocus は、現在フォーカスを持つ(==キー入力を受け付けている)ウィンドウを設定、取得するためのものです。
    前者は、MFC専用で、CFormView ベースの場合でも必ずビューを対象とするのに対し、
    後者は、API(ラッパー)ですので、HWND(CWndの派生クラス)にたいして作用するものとなります。

    SDIで、ビューが一つの場合、ビューの寿命とアプリケーションの寿命はほぼ一対なのであまり意識しないかもしれませんが
    複数のビューを切り替える仕組みを持っている場合や、印刷機能を有している場合に意外と便利に使えたりします。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/
    2009年12月18日 6:19
  • CFrameWnd::SetActiveView()は「アクティブウィンドウ」を設定するのではなく、
    MFCで定義された「アクティブビュー」を設定するものです。

    MFCでのアクティブビューは、ひとつのフレームウィンドウに対して複数のビューがある時、
    どのビューにコマンドをディスパッチしたら良いかを決定するために、
    フレームワークによって使われるものなのです。
    詳しくは、コマンドの振り分け (ルーティング) (MFC) を参照ください。

    ということで、SDIではCSplitterWndでも使わない限り、
    SetActiveView()を呼び出す必要があるようなことはほぼないと思います。

    CWnd::SetFocus()はヘルプにあるように、キーボードフォーカスをセットするためのものです。
    フォーカスのあるウィンドウに対してすべてのキーボードメッセージが送られることになります。

    一方で、通常「アクティブウィンドウ」と言えば、Windowsでいう"Active Window"の事になると思います。
    アクティブウィンドウに関しては、こちらを参照ください。
    http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx#active

    使い分けですが、ごくごく簡単に言えば、
    複数のCView派生クラスがあるとき、CView派生クラスに対しては、CFrameWnd::SetActiveView()、
    ダイアログ上のコントロールに対しては、CWnd::GotoDlgCtrl()、
    それ以外にはCWnd::SetFocus()
    くらいを基本にして、あとは特殊な事情に個別に対応すればいいと思います。
    2009年12月18日 6:37
  • とっちゃんさん
    Atsushi777さん

    hiro-taです。
    早速の回答ありがとうございました。 SetFocusはキー入力に関するものなんですね。
    丁寧にご説明いただきもやもやしていものがだいぶ晴れてきました。
    整理すると以下のような感じで合っていますでしょうか?

    SetFocus    キーボード入力を受け付けるウィンドウを決める
    SetActiveView    MFC専用でフレームがコマンドメッセージをどこに送るかを決める
    SetActiveWindow   アクティブウィンドウ(トップに表示されるウィンドウ)を決める


    2009年12月18日 6:56
  • 「トップに表示されるウィンドウ」というのは何か違う気がしますが、
    いずれにしても提示したリンク先と、
    CWnd::SetFocus(), CFrameWnd::SetActiveView()のヘルプを
    読んでいただければお分かりいただけると思います。

    2009年12月21日 0:24
  • こんにちは、フォーラムオペレーターの高橋春樹です。

    とっちゃんさん、Atsushi777さん
    いつもお世話になっております。

    hiro-taさん、MSDNフォーラムのご利用有難うございます。

    とっちゃんさんとAtsushi777さんさんから、疑問点についてのアドバイスを頂いたと思うのですが、如何でしょうか?
    皆様からのアドバイスが、フォーラムを閲覧している方にとっても、有用な情報だと思いましたので、
    勝手ながら、回答マークを付けさせてもらいました。
    もし、疑問点がありましたら、新たに投稿して頂きたいと思います。

    今後ともMSDNフォーラムを宜しくお願いします(^_^)


    マイクロソフト株式会社 フォーラム オペレーター 高橋春樹
    2010年1月15日 9:49