タブ押下を制御汁...

CreateWindow()で作成したコントロールのタブ押下はうまいこと動いてくれない...
ダイアログボックスとして作成されれば自動でなんかうまいことをやってくれるらしいのですが。
なので、とりあえずサブクラス化してお茶を濁す。
管理が面倒なので、インスタンスが破棄されるときに勝手にサブクラス化もぶち消えてくれるように、 デストラクタを作る。
んー、うまく継承したクラスが作れない...
プロシジャがスタティックなのが都合わるす。
んー、スレッドクラスは独自のデータをかませるので流用可能なすばらしいクラスが作れるのですがー。
まあ暫定でこんな感じ。タブを全角すぺーすで展開しているので貼り付けても使えません。
なんか、だれかもっと簡単で応用の利く実装を教えてプリーズ。





class SubClass{
   set<HWND> m_lWndList;   //サブクラス化したリスト
   static LRESULT CALLBACK SubProc(HWND hWnd,UINT msg, WPARAM wParam, LPARAM lParam)
   {
      if( msg == WM_KEYDOWN ){
         switch( wParam ){
            case VK_TAB:{
               HWND hWndParent   = ::GetParent( hWnd );
               HWND hTabWnd   = ::GetNextDlgTabItem( hWndParent, hWnd, FALSE );
               if( hTabWnd ){
                  ::SetFocus( hTabWnd );
               }
               break;
            }

            case VK_RETURN:{
               HWND hWndParent   = ::GetParent( hWnd );
               ::SendMessage( hWndParent, WM_CTRLCMD, MAKELONG(::GetDlgCtrlID( hWnd ),WM_KEYDOWN), (LPARAM)VK_RETURN);
               break;
            }
         }//switch
      }//msg

      WNDPROC pWp = (WNDPROC)::GetProp( hWnd, "proc");
      return pWp(hWnd, msg, wParam, lParam );
   }

public:

   virtual ~SubClass(){
      set<HWND>::iterator itr = m_lWndList.begin();
      while( itr != m_lWndList.end()){
         HWND hWnd = (HWND)(*itr);
         Detach( hWnd );
         itr = m_lWndList.begin();
      }
   }

   BOOL Attach( HWND hWndTarget ){
      //アタッチするウインドウのプロシジャを取得
      WNDPROC lProc = (WNDPROC)::GetWindowLong( hWndTarget, GWL_WNDPROC);
      if( lProc ){
         //タブ制御用のプロシジャを設定する
         ::SetWindowLong( hWndTarget, GWL_WNDPROC, (LONG)m_pWndProc);
         ::SetProp( hWndTarget, "proc", lProc );
         m_lWndList.insert( hWndTarget );
         return TRUE;
      }
      return FALSE;
   }

   void Detach(HWND hWndTarget){

      WNDPROC lParam = (WNDPROC)::GetProp( hWndTarget, "proc");
      if( lParam ){
         ::SetWindowLong( hWndTarget, GWL_WNDPROC, (LONG)lParam);   //元に戻す
         ::RemoveProp( hWndTarget, "proc");              //削除
         m_lWndList.erase( hWndTarget );
      }
   }

};


[Back]