Win32のTabControlにフォーカスを設定しない方法。
標準ではタブをクッリクするとフォーカスが設定されて、フォーカスレクトの四角が表示される。
タブコントロールのウインドウスタイルTCS_FOCUSNEVERを指定すればフォーカスが設定されないと思ったのだが、うまくいかなかった。フォーカスレクトが表示されてしまう。
そこで次に考えられるのがオーナードローにする方法だが、これだと全部自分で書かなければならなくなるのでやりたくない。
そこで、フック機能をつかって実現することができた。
SetWindowsHookExでWH_CBTを指定すれば、コールバック関数がHCBT_SETFOCUSで呼ばれる。ここで1を返せば、フォーカスをさせないことができる。
よって具体的な実装方法は以下のようになる。
- WM_CREATEの時にSetWindowsHookExでフックを仕掛ける。
- コールバック関数で、タブにフォーカスが来たときはそれを無効にする。
- WM_DESTROYの時にUnhookWindowsHookExを呼んでフックを解除する。
コードの断片は以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
int CNofocustabDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; gHook = SetWindowsHookEx(WH_CBT, cbtHook, NULL, GetCurrentThreadId()); return 0; } void CNofocustabDlg::OnDestroy() { CDialog::OnDestroy(); UnhookWindowsHookEx(gHook); } LRESULT CALLBACK cbtHook(int nCode, WPARAM wParam, LPARAM lParam) { if ( nCode < 0 ) return CallNextHookEx(gHook, nCode, wParam, lParam); switch( nCode ) { case HCBT_SETFOCUS: { return ghTab != NULL && ghTab==(HWND)wParam; } break; } return CallNextHookEx(gHook, nCode, wParam, lParam); } |