如何从选项卡控件获取宽度和高度?

How do I get the width and height from a tab control?

我有一个选项卡控件,我想在其中获取其宽度和高度以创建一个 window 来填充该区域。 但我不太明白如何获得这个宽度和高度。根据我的发现,从 TabCtrl_GetItemRect() 获得的值以对话单位为单位,因此我需要转换为像素,例如 int width = tr.right - tr.left 我会这样做,但是如果我传递该值,该值是错误的对于 CreateWindowExW() 它创建了一个小控件,它甚至不到目标宽度和高度的 1/4。我用来从对话单位转换为像素的例程是:

void DlgUnitsToPxs(RECT *rect)
{
  long units = GetDialogBaseUnits();
  int xBaseUnit = LOWORD(units);
  int yBaseUnit = HIWORD(units);

  rect->left   = MulDiv(rect->left,   xBaseUnit, 4);
  rect->right  = MulDiv(rect->right,  xBaseUnit, 4);
  rect->top    = MulDiv(rect->top,    yBaseUnit, 8);
  rect->bottom = MulDiv(rect->bottom, yBaseUnit, 8);
}

获取这样的值:

RECT tr = {0};
TabCtrl_GetItemRect(hTabControl, 0, &tr);
DlgUnitsToPxs(&tr);
int width = tr.right - tr.left;
int height = tr.bottom - tr.top;

我错过了什么?

您将使用 GetClientRect 函数和 TCM_ADJUSTRECT 消息(wParam 设置为 TRUE,lParam 是指向要调整的 RECT 的指针)。我通常会创建将显示为选项卡子项的 windows,并将选项卡作为实际父项 window,这样我就不需要在该 RECT 上使用 MapWindowPoints。

例如(虽然我通常会实际使用 C++ 样式初始化):

...
case WM_SIZE:
 {
  RECT rc;
  TCITEM item;
  HWND hWndChild;
  HWND hWndTab = GetDlgItem(hWnd, ID_TAB);
  _ASSERT(hWndTab);

  item.mask = TCIF_PARAM;
  SendMessage(hWndTab, TCM_GETITEM, SendMessage(hWndTab, TCM_GETCURFOCUS, 0, 0), &item);

  _ASSERT(item.lParam);
  hWndChild = (HWND)item.lParam;

  GetClientRect(hWndTab, &rc);
  SendMessage(hWndTab, TCM_ADJUSTRECT, TRUE, (LPARAM)&rc);

  SetWindowPos(hWndChild, nullptr, rc.left, rc.top, rc.right, rc.bottom, SWP_NOACTIVATE|SWP_NOMOVE);
 }
 return 0;