问题描述
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_SIMPLE
或CBS_DROPDOWN
样式,而不是CBS_DROPDOWNLIST
样式),则这只会使ComboBox的编辑字段居中对齐。它不会使ComboBox(下拉)ListBox中的任何项目居中对齐,因为ListBox完全不支持任何文本对齐样式。因此,如果要使ListBox项居中对齐,则必须所有者绘制ComboBox,没有其他方法。
更新:我没有注意到您实际上使用的是CBS_DROPDOWNLIST
样式。在这种情况下,ComboBox根本没有编辑字段,而是有一个静态文本控件。而且AFAIK,GetComboBoxInfo()
不会为该静态控件返回HWND
(至少,文档是这样读取的)。因此,除非您找到访问静态控件的HWND
的方法,否则您将只需要继续绘画所有内容。