首页 > 解决方案 > 如何使 tab 键在此对话框控件中起作用?

问题描述

我添加IsDialogMessage()到我的主循环中,tab 键确实有效,但它卡在选项卡控件的顶部,并且没有进入对话框内的控件。我该如何解决?我已经尝试WS_GROUP过第一个控件和WS_TABSTOP所有下一个创建的控件,但它没有工作。

选项卡控件的创建方式如下:

hTabControl =
          CreateWindowW(WC_TABCONTROLW, NULL,
            WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP | WS_GROUP | WS_EX_CONTROLPARENT,
            10, 30, 400, 250,
            hwnd,
            (HMENU) ID_MAIN_TABCONTROL,
            NULL,
            NULL);

和对话框:

      CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT,
            "DialogBox",
            L"Dialog Box",
            WS_SYSMENU | WS_CHILD | WS_GROUP | WS_TABSTOP | WS_VISIBLE,
            10, 30, 350, 150,
            hTabControl, NULL, ghInstance,  NULL
      );

      // ...

  WNDCLASSEXW wc = {0};
  wc.cbSize           = sizeof(WNDCLASSEXW);
  wc.lpfnWndProc      = DialogProc;
  wc.hInstance        = ghInstance;
  wc.hbrBackground    = GetSysColorBrush(COLOR_3DFACE);
  wc.lpszClassName    = "DialogClass";
  RegisterClassExW(&wc);

然后是 DialogProc 过程:

LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch(msg)
  {
  
    case WM_CREATE:
        CreateWindowW(L"button", L"A",
          WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP,
          50, 50, 80, 25, hwnd, (HMENU) ID_TAB1_BUTTONA, NULL, NULL);  
        CreateWindowW(L"button", L"B", 
          WS_VISIBLE | WS_CHILD | WS_TABSTOP,
          150, 50, 80, 25, hwnd, (HMENU) ID_TAB1_BUTTONB, NULL, NULL);
        CreateWindowW(L"button", L"C",
          WS_VISIBLE | WS_CHILD | WS_TABSTOP,
          250, 50, 80, 25, hwnd, (HMENU) ID_TAB1_BUTTONC, NULL, NULL);
        CreateWindowW(L"button", L"D",
          WS_VISIBLE | WS_CHILD | WS_TABSTOP,
          50, 100, 80, 25, hwnd, (HMENU) ID_TAB1_BUTTOND, NULL, NULL);
        CreateWindow(L"Edit", NULL,
          WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP,
          150, 100, 80, 20, hwnd, (HMENU) ID_TAB1_EDIT1, NULL, NULL);
    break;

    case WM_COMMAND:
        
        switch(LOWORD(wParam))
        {
          // didn't do anything
          default: 
          break;

          case ID_TAB1_BUTTONA:
          {
            MessageBox(NULL, L"Click on A button", L"Welcome to the jungle!", MB_OK);
          }
          break;
        }

    break;

    case WM_CLOSE:
        DestroyWindow(hwnd);
    break;

  }
  
  return DefWindowProcW(hwnd, msg, wParam, lParam);
}

和主循环:

  while (GetMessage(&msg, NULL, 0, 0))
  {
      if (!IsDialogMessage(hwnd, &msg)) {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
      }
  

}

标签: cwindowswinapi

解决方案


您通常不会将交互式窗口/控件创建为选项卡控件的子项,这很奇怪但确实如此。将内部对话框创建为外部对话框的子项,而不是选项卡控件。

此 MSDN 示例创建内部对话框作为主对话框的子对话框。

正如这篇博文中所解释的WS_EX_CONTROL­PARENT将窗口/控件从选项卡顺序中取出。

这是纯Win32的东西,Delphi/C++Builder等带有自定义UI工具包的环境,往往将tab控件实现为真正的容器。


推荐阅读