本ページは公開が終了した情報の複製であり、掲載時点での情報です。本ページに記載されている内容について各所に問い合わせることはご遠慮下さい。
サポート技術情報

[VC10] CSplitterWnd クラスでフォーカスが戻らない

文書番号: 108434

最終更新日: 2004/01/23


この資料は以下の製品について記述したものです。


現象

CSplitterWnd クラスを使用した分割ウィンドウのビューで、分割バーをクリックすると入力フォーカスが失われ、分割バーのドラッグ終了時にフォーカスがアクティブなビューに戻りません。

原因

CSplitterWnd::StopTracking () は SetActiveView (pOldActiveView) を呼び出すことでアクティブなビューに入力フォーカスを戻そうとします。
pOldActiveView は StopTracking() 関数内で現在のアクティブなビューがセットされた変数です。
ここでは入力フォーカスが以前のアクティブなビューにあったと仮定しています。

問題は、そのビューを m_pViewActive (現在のアクティブなビュー) と同様なビューとみなし、SetActiveView() が入力フォーカスの設定に失敗していることです。
この場合、アクティブなビュー上に既に入力フォーカスがあると仮定しているため、SetActiveView() 関数は単純に戻ります。

この仮定は、フレームのアクティブなビュー ポインタを保存できずに復元して取り残し、分割バーがフォーカスを得る事からも間違いであることがわかります。

解決方法

この障害は、Visual C++ 1.5 では修正されています。
Visual C++ 1.0 においては、MFC のソースコードに同様な修正を施して再構築することで、この問題に対処することができます。

修正済みのコードにおける CSplitterWnd::StopTracking() は、SetActiveView() の呼び出し後に明示的にフォーカスをセットするように修正されています。
以下は、そのコードです:
    if (pOldActiveView == pParent->GetActiveView())
    {
        pParent->SetActiveView(pOldActiveView); // Re-activate.
        if (pOldActiveView != NULL)
            pOldActiveView->SetFocus(); // Make sure focus is restored.
    }
WINSPLIT.CPP に実装されている CSplitterWnd::StopTracking を修正し、『クラス ライブラリ ユーザーズ ガイド』の付録 B 、またはより詳細に記述されている \MSVC\MFC\SRC\README.TXT に従い MFC のライブラリを再構築してください。

MFC の再構築を避けたい場合、分割ウィンドウのトラッキング中に入力フォーカスの保存と復元をしつづける方法でも対処できます。
この場合、CSplitterWnd クラスにおいて WM_LBUTTONDOWN と WM_LBUTTONUP メッセージを処理します。

サンプル コード

   class CMySplit:public CSplitterWnd    // derive from it.
   {
       public:
       // This is the pointer to the window that
       // has focus when the splitter starts resizing.
       HWND hWndFocus;

       // ...rest of your declaration.
   }

   void CMySplit::OnLButtonDown(UINT nFlags, CPoint point)
   {
       //Get CWnd with current focus
       hWndFocus = ::GetFocus();

       // Remember to call the base class handler.
       CSplitterWnd::OnLButtonDown(nFlags,point);
   }

   void CMySplit::OnLButtonUp(UINT nFlags, CPoint point)
   {
       //restore focus
       ::SetFocus(hWndFocus);

       // Remember to call the base class handler.
       CSplitterWnd::OnLButtonUp(nFlags,point);
   }
このコードでは、OnLButtonDown() ハンドラが呼ばれる前に分割ウィンドウのどれかにフォーカスが設定されると仮定しています。すなわち、マウス ボタンが離されたとき分割ウィンドウ外のウィンドウにフォーカスがセットされることは望まれないでしょう。処理後にフォーカスが分割ウィンドウにセットされるかどうか確認するには、フレーム ウィンドウのメンバ変数 m_pActiveView をチェックするコードを追加します。

関連情報

この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 108434 (最終更新日 1999-02-25) をもとに作成したものです。


Additional query words: 1.00 2.00 2.10 splitter focus kbNoUpdate

Keywords: 2.00 2.10 VC10 VC15 KB108434
Technology: kbAudDeveloper kbMFC kbvc100 kbVC16bitSearch kbVC32bitSearch kbVCsearch

inserted by FC2 system