ComboBox控件WinAPI的居中对齐编辑控件

问题描述

我有一个组合框;

CreateWindowEx(0,"comboBox",WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST|WS_VSCROLL,100,5,140,150,hwnd,HMENU(2),0);

我给它加上字体;

HFONT f=CreateFont(20,9,900,"Verdana");
SendDlgitemmessage(hwnd,2,WM_SETFONT,WParaM(f),1);

我尝试了一下,但是没有用;

COMBOBoxINFO c;
GetComboBoxInfo(GetDlgitem(hwnd,2),&c);
LONG_PTR es=getwindowlongPtr(c.hwndItem,-16); //-16 for GWL_STYLE
es+=ES_CENTER; //ineffective,so is SS_CENTER
SetwindowLongPtr(c.hwndItem,-16,es);

但是,当从es删除某些内容(例如es+=~WS_VISIBLE;)时,它是有效的。 不绘制组合框所有者,如何完成标题中的任务?还是我需要一个所有者绘制的组合框?

解决方法

您应该使用|=而不是+=。要删除某些内容,您需要使用&= ~...而不是+= ~...。并且您应该使用实际的GWL_STYLE常量而不是文字的-16

但是,最重要的是,您忽略了GetComboBoxInfo()的返回值,以了解c.hwndItem是否甚至可以使用。在这种情况下,由于您未正确初始化COMBOBOXINFO,因此很有可能失败。

尝试一下:

COMBOBOXINFO c = {};
c.cbSize = sizeof(c); // <-- add this!

if (GetComboBoxInfo(GetDlgItem(hwnd,2),&c)) // <-- check this!
{
    LONG_PTR es = GetWindowLongPtr(c.hwndItem,GWL_STYLE);
    es |= ES_CENTER;
    SetWindowLongPtr(c.hwndItem,GWL_STYLE,es);
}

注意:如果ComboBox具有一个(通过CBS_SIMPLECBS_DROPDOWN样式,而不是CBS_DROPDOWNLIST样式),则这只会使ComboBox的编辑字段居中对齐。它不会使ComboBox(下拉)ListBox中的任何项目居中对齐,因为ListBox完全不支持任何文本对齐样式。因此,如果要使ListBox项居中对齐,则必须所有者绘制ComboBox,没有其他方法。


更新:我没有注意到您实际上使用的是CBS_DROPDOWNLIST样式。在这种情况下,ComboBox根本没有编辑字段,而是有一个静态文本控件。而且AFAIK,GetComboBoxInfo()不会为该静态控件返回HWND(至少,文档是这样读取的)。因此,除非您找到访问静态控件的HWND的方法,否则您将只需要继续绘画所有内容。