Winapi 所有者绘制组合框的垂直大小大于非所有者绘制组合框的垂直大小

Winapi 所有者绘制组合框的垂直大小大于非所有者绘制组合框的垂直大小,winapi,combobox,mfc,Winapi,Combobox,Mfc,我有一个包含两个组合框的对话框,一个所有者绘制和一个非所有者绘制 这是在.rc文件中定义它们的方式: COMBOBOX IDC_COMBO2,149,49,77,73, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_SORT | VS_VSCROLL COMBOBOX IDC_COMBO3,237,49,48,30, CBS_DROPDOWNLIST CBS_SO

我有一个包含两个组合框的对话框,一个所有者绘制和一个非所有者绘制

这是在.rc文件中定义它们的方式:

COMBOBOX        IDC_COMBO2,149,49,77,73,
                CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_SORT | VS_VSCROLL
COMBOBOX        IDC_COMBO3,237,49,48,30,
                CBS_DROPDOWNLIST CBS_SORT | WS_VSCROLL
它们在.rc文件中的高度完全相同,但所有者绘制的一个(左侧的一个)略高于非所有者绘制的一个:


.

首先,资源中的给定高度是下拉状态下组合框的高度

这种行为是由 设计。我相信组合框项目高度的大小是由 指定给控件的字体的字体高度。 有了一个“所有者绘制”组合框,系统就不知道了,所以它会向您发送一个 WM_MEASUREITEM使用组合框的默认大小初始化(可能是 取决于系统字体而不是gui字体)

所以您需要在父对话框中处理WM_MEASUREITEM

类似的内容可能会有所帮助(未针对编译器验证的代码):


在处理大小和布局时,组合框是Windows中最可怕的控件。由于它还支持“简单”样式,且具有单独的“编辑”和“列表框”控件始终可见,因此它不使用标准窗口边框/边缘样式,而是在需要时绘制其边框

创建控件时指定的高度实际上是下拉状态下使用的大小。它在运行时根据其字体强制编辑控件的大小。因为很多人都弄错了,所以主题化的ComCtl32 v6实现确保了下拉列表的大小是合理的,即使您最初给它一个小的大小

为了匹配系统,您需要尝试在
WM\u MEASUREITEM
中计算所需的大小,但是默认控件的确切布局当然没有记录。它可能是字体的高度+SM_C*边缘的系统度量大小,可能还有一些填充


如果您只需要文本旁边的图标,则可以使用该控件。

您需要指定组合框样式,这两种样式都适用。高度的差异可能是由于标准组合框使用的默认值与所有者绘制的不同。不过,这只是猜测。@IInspectable CBS_NOINTEGRALHEIGHT与此无关,我试过了,但没有改变任何事情。我想这只是为了下拉列表框。太好了,你救了我一天!我刚刚插入了这段代码,它的工作原理与预期一致。这对使用也很有帮助。我不知道。记住,超级版只在MS编译器中可用。
void CMyDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
  CClientDC dc(this);
  CFont* pFont = GetFont();
  CFont* pFontPrev = NULL;

  if (pFont != NULL)
    pFontPrev = dc.SelectObject(pFont);

  int iborder = ::GetSystemMetrics(SM_CYBORDER);
  CSize sz = dc.GetTextExtent(_T("0"));
  lpMeasureItemStruct->itemHeight = sz.cy + 2*iborder;

  if (pFont != NULL)
    dc.SelectObject(pFontPrev);

  __super::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}