微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何制作带有子元素的选项卡控件?

如何解决如何制作带有子元素的选项卡控件?

我正在学习 WINAPI,我读到 C# 的 TabControl 控件没有儿童控件,因此您必须自己创建元素并显示/隐藏。我读到它可以通过在选项卡页区域内绘制一个对话框来完成,所以我去创建一个无边框对话框作为选项卡控件的子项,使其具有像 C# 一样的效果。但我还是做不到。我的对话框是浮动的,而不是选项卡控件的子控件。我不知道要在标签页中设置它,我尝试将 hWndParent 设置为标签控件的 HWND 和 WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT 中的 dwExStyle 标志,但仍然浮动在标签控件上。欢迎使用不同的方法解决这个问题。我正在创建这样的选项卡控件:

void AddTabControl(HWND hwnd)
{
    hTab = CreateWindowW(WC_TABCONTROLW,NULL,WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP,30,250,hwnd,(HMENU) 9,NULL);
    InsertTabItem(hTab,10,L"A");
    InsertTabItem(hTab,11,L"B");
}

void InsertTabItem(HWND tabHwnd,UINT id,LPWSTR text)
{
    TCITEMW tci = {0};
    tci.mask = TCIF_TEXT;
    tci.pszText = text;
    tci.cchTextMax = lstrlenW(text);
    if(SendMessage(tabHwnd,TCM_INSERTITEMW,id,(LParaM) &tci) == -1) {
        MessageBox(NULL,L"Couldn't create the new tab page",L"tab errror",MB_OK | MB_ICONERROR);
    }
}

还有这样的对话框:

void CreateDialogBox(HWND hwnd)
{
  CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT,// WS_EX_TOOLWINDOW to hide window from ALT+TAB
        L"DialogClass",L"Dialog Box",WS_VISIBLE | WS_POPUP | WS_SYSMENU,100,400,150,hTab,ghInstance,NULL
  );
}

结果是:

enter image description here

预期结果(由 C# 制作,仅作为示例,忽略颜色差异,我稍后会解决此问题):

enter image description here

完整代码如下:

#pragma comment(lib,"user32.lib")
#pragma comment(lib,"Comctl32.lib")

#define UNICODE

#include <windows.h>
#include <Commctrl.h>
#include <strsafe.h>

LRESULT CALLBACK WndProc(HWND,UINT,WParaM,LParaM);
LRESULT CALLBACK DialogProc(HWND,LParaM);

void CreateDialogBox(HWND);
void RegisterDialogClass(HWND);
void AddTabControl(HWND hwnd);
void InsertTabItem(HWND tabHwnd,LPWSTR text);

HINSTANCE ghInstance;
HWND mainWindow;
HWND hTab;

int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PWSTR pCmdLine,int nCmdshow) {

  MSG  msg = {0};
  HWND hwnd;

  WNDCLASSW wc = {0};

  wc.lpszClassName = L"Window";
  wc.hInstance     = hInstance;
  wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  wc.lpfnWndProc   = WndProc;
  
  RegisterClassW(&wc);
  hwnd = CreateWindowW(wc.lpszClassName,L"Window",WS_OVERLAPPEDWINDOW | WS_VISIBLE,500,350,hInstance,NULL);  
  mainWindow = hwnd;
  ghInstance = hInstance;

  while( GetMessage(&msg,0)) {
    dispatchMessage(&msg);
  }
  
  return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WParaM wParam,LParaM lParam)
{

  switch(msg)
  {
      case WM_CREATE:
          RegisterDialogClass(hwnd);
          AddTabControl(hwnd);
          CreateDialogBox(hwnd);
          break;

      case WM_COMMAND:
          CreateDialogBox(hwnd);
          break;

      case WM_DESTROY:
      {
          PostQuitMessage(0);
          return 0;
      }
  }
  return DefWindowProcW(hwnd,msg,wParam,lParam);
}

LRESULT CALLBACK DialogProc(HWND hwnd,LParaM lParam)
{
  switch(msg) {
  
    case WM_CREATE:
        CreateWindowW(L"button",L"A",WS_VISIBLE | WS_CHILD,50,80,25,(HMENU) 1,NULL);  
        CreateWindowW(L"button",L"B",(HMENU) 2,NULL);
        CreateWindowW(L"button",L"C",(HMENU) 3,NULL); 
    break;

    case WM_COMMAND:
        DestroyWindow(hwnd);
    break;

    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;

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

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

void CreateDialogBox(HWND hwnd)
{
  CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT,NULL
  );
}

void AddTabControl(HWND hwnd)
{
    hTab = CreateWindowW(WC_TABCONTROLW,MB_OK | MB_ICONERROR);
    }
}

解决方法

当您创建对话框控件时,您缺少 WS_CHILD 样式并添加了 WS_POPUP 样式,这导致您生成的对话框浮动。

您只需将其修改为WS_CHILD样式,并适当修改控件的大小即可达到您想要的效果。

void CreateDialogBox(HWND hwnd)
{
    CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT,// WS_EX_TOOLWINDOW to hide window from ALT+TAB
        L"DialogClass",L"Dialog Box",WS_VISIBLE  | WS_SYSMENU | WS_CHILD,10,30,350,150,hTab,NULL,ghInstance,NULL
    );
}

void AddTabControl(HWND hwnd)
{
    hTab = CreateWindowW(WC_TABCONTROLW,WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP,400,250,hwnd,(HMENU)9,NULL);
    InsertTabItem(hTab,L"A");
    InsertTabItem(hTab,11,L"B");
}

它是这样工作的:

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。