使用CreateWindowEx创建ComboBox控件
#define COMBOBOX_0 1000
#define COMBOBOX_1 1001
#define COMBOBOX_2 1002
...
CreateWindowEx(0,//扩展窗体风格
"ComboBox",//窗体类名称
NULL,//窗体名字
WS_VISIBLE| WS_CHILD| WS_BORDER| CBS_HASSTRINGS| CBS_SIMPLE,//窗体风格
10, 10, 200, 130,//窗体位置和大小
hwnd,//父窗体句柄
(HMENU)COMBOBOX_0,//菜单句柄
((LPCREATESTRUCT)lParam)->hInstance,//实例句柄
0);//
通过向组合框发送消息进行操作,消息类型
主题 目录
CB_ADDSTRING 将字符串添加到组合框的列表框中。 如果组合框没有 CBS_SORT 样式,则字符串将添加到列表末尾。 否则,字符串将插入到列表中,并且对列表进行排序。
CB_DELETESTRING 删除组合框的列表框中的字符串。
CB_DIR 将名称添加到组合框显示的列表。 该消息添加与指定字符串和文件属性集匹配的目录和文件的名称。 CB_DIR 还可以将映射的驱动器号添加到列表中。
CB_FINDSTRING 在组合框的列表框中搜索以指定字符串中的字符开头的项目。
CB_FINDSTRINGEXACT 查找与 lParam 参数中指定的字符串匹配的组合框中的第一个列表框字符串。
CB_GETCOMBOBOXINFO 获取有关指定组合框的信息。
CB_GETCOUNT 获取组合框列表框中的项数。
CB_GETCUEBANNER 获取组合框的编辑控件中显示的提示横幅文本。 显式发送此消息或使用 ComboBox_GetCueBannerText 宏发送。
CB_GETCURSEL 应用程序在组合框的列表框中发送 CB_GETCURSEL 消息以检索当前所选项(如果有)的索引。
CB_GETDROPPEDCONTROLRECT 应用程序发送 CB_GETDROPPEDCONTROLRECT 消息以检索组合框的屏幕坐标,该组合框处于下拉状态。
CB_GETDROPPEDSTATE 确定组合框的列表框是否下拉。
CB_GETDROPPEDWIDTH 获取具有 CBS_DROPDOWN 或 CBS_DROPDOWNLIST 样式的组合框列表框的最小允许宽度(以像素为单位)。
CB_GETEDITSEL 获取组合框的编辑控件中当前所选内容的起始和结束字符位置。
CB_GETEXTENDEDUI 确定组合框是具有默认用户界面还是扩展用户界面。
CB_GETHORIZONTALEXTENT 获取列表框可以水平滚动的宽度(以像素为单位), (可滚动宽度) 。 仅当列表框具有水平滚动条时,此选项才适用。
CB_GETITEMDATA 应用程序将 CB_GETITEMDATA 消息发送到组合框,以检索与组合框中指定项关联的应用程序提供的值。
CB_GETITEMHEIGHT 确定组合框中列表项或选择字段的高度。
CB_GETLBTEXT 从组合框列表中获取字符串。
CB_GETLBTEXTLEN 获取组合框中字符串的长度(以字符为单位)。
CB_GETLOCALE 获取组合框的当前区域设置。 区域设置用于确定使用CB_ADDSTRING消息添加CBS_SORT样式和文本的组合框显示文本的正确排序顺序。
CB_GETMINVISIBLE 获取组合框下拉列表中可见项的最小数目。
CB_GETTOPINDEX 应用程序发送 CB_GETTOPINDEX 消息,以检索组合框列表框部分第一个可见项的从零开始的索引。 最初,索引为 0 的项位于列表框的顶部,但如果列表框内容已滚动,则另一个项目可能位于顶部。
CB_INITSTORAGE 应用程序在将大量项添加到组合框的列表框部分之前发送 CB_INITSTORAGE 消息。 此消息分配用于存储列表框项的内存。
CB_INSERTSTRING 将字符串或项数据插入组合框列表中。 与 CB_ADDSTRING 消息不同, CB_INSERTSTRING 消息不会导致具有 CBS_SORT 样式的列表进行排序。
CB_LIMITTEXT 限制用户可在组合框的编辑控件中键入的文本长度。
CB_RESETCONTENT 从列表框中删除所有项,并编辑组合框的控件。
CB_SELECTSTRING 在组合框列表中搜索以指定字符串中的字符开头的项。 如果找到匹配项,则会选择它并将其复制到编辑控件。
CB_SETCUEBANNER 设置组合框的编辑控件显示的提示横幅文本。
CB_SETCURSEL 应用程序发送 CB_SETCURSEL 消息,以在组合框中选择字符串。 如有必要,列表会将字符串滚动到视图中。 组合框的编辑控件中的文本将更改以反映新选择,并删除列表中以前的任何选定内容。
CB_SETDROPPEDWIDTH 应用程序发送 CB_SETDROPPEDWIDTH 消息,以设置具有 CBS_DROPDOWN 或 CBS_DROPDOWNLIST 样式的组合框列表框的最大允许宽度(以像素为单位)。
CB_SETEDITSEL 应用程序发送 CB_SETEDITSEL 消息以选择组合框的编辑控件中的字符。
CB_SETEXTENDEDUI 应用程序发送 CB_SETEXTENDEDUI 消息,以选择具有 CBS_DROPDOWN 或 CBS_DROPDOWNLIST 样式的组合框的默认 UI 或扩展 UI。
CB_SETHORIZONTALEXTENT 应用程序发送 CB_SETHORIZONTALEXTENT 消息以设置宽度(以像素为单位),列表框可以水平滚动 (可滚动宽度) 。 如果列表框的宽度小于此值,水平滚动条水平滚动列表框中的项目。 如果列表框的宽度等于或大于此值,则隐藏水平滚动条;如果组合框具有 CBS_DISABLENOSCROLL 样式,则禁用。
CB_SETITEMDATA 应用程序发送 CB_SETITEMDATA 消息以设置与组合框中指定项关联的值。
CB_SETITEMHEIGHT 应用程序发送 CB_SETITEMHEIGHT 消息以设置组合框中的列表项或选择字段的高度。
CB_SETLOCALE 应用程序发送 CB_SETLOCALE 消息以设置组合框的当前区域设置。 如果组合框具有 使用 CB_ADDSTRING 添加CBS_SORT 样式和 字符串,组合框的区域设置会影响列表项的排序方式。
CB_SETMINVISIBLE 应用程序发送 CB_SETMINVISIBLE 消息,以在组合框的下拉列表中设置最小可见项数。
CB_SETTOPINDEX 应用程序发送 CB_SETTOPINDEX 消息,以确保特定项在组合框的列表框中可见。 系统滚动列表框内容,以便指定的项显示在列表框顶部或已达到最大滚动范围。
CB_SHOWDROPDOWN 应用程序发送 CB_SHOWDROPDOWN 消息以显示或隐藏具有 CBS_DROPDOWN 或 CBS_DROPDOWNLIST 样式的组合框的列表框。
CB_ADDSTRING消息用于向组合框添加消息
wParam
未使用此参数。
lParam
要添加的 NULL 终止字符串的 LPCTSTR 指针。 如果使用所有者绘制样式创建组合框,但
没有 CBS_HASSTRINGS 样式, 则 lParam 参数的值将存储为项数据,而不是将它指向的
字符串。 可以通过发送 CB_GETITEMDATA 或 CB_SETITEMDATA 消息来检索或修改项数
据。
应用程序发送 CB_SETCURSEL 消息,以在组合框中选择字符串。 如有必要,列表会将字
符串滚动到视图中。 组合框的编辑控件中的文本将更改以反映新选定内容,并删除列表
中任何以前的选定内容。
wParam
指定要选择的字符串的从零开始的索引。 如果此参数为 -1,则删除列表中的任何当前选
定内容,并清除编辑控件。
lParam
未使用此参数。
如果消息成功,则返回值是所选项的索引。 如果 wParam 大于列表中的项数,或者 如果
wParam 为 -1,则返回值CB_ERR并清除所选内容。
CB_GETCURSEL消息
应用程序在组合框的列表框中发送 CB_GETCURSEL 消息以检索当前所选项(如果有)的
索引。
CB_GETLBTEXT消息
从组合框列表中获取字符串。
wParam
要检索的字符串的从零开始的索引。
lParam
指向接收字符串的缓冲区的指针。 缓冲区必须有足够的空间用于字符串和终止 null 字
符。 可以在CB_GETLBTEXT消息之前发送CB_GETLBTEXTLEN消息,以检索字符串的长度
(以 TCHARs 为单位)。 如果是 ANSI 字符串,则为字节数,但如果它是 Unicode 字符
串,则为字符数。
返回值是字符串的长度(以 TCHAR 为单位),不包括终止 null 字符。 如果 wParam 未
指定有效的索引,则返回值CB_ERR。
示例
const char* text[4] = {"aaa","bbb","ccc","ddd"};
for(int i=0; i<4; i++){
//添加文本到组合框
SendMessage(GetDlgItem(hwnd,COMBOBOX_0), CB_ADDSTRING, i, (LPARAM)text[i]);
SendMessage(GetDlgItem(hwnd,COMBOBOX_1), CB_ADDSTRING, i, (LPARAM)text[i]);
SendMessage(GetDlgItem(hwnd,COMBOBOX_2), CB_ADDSTRING, i, (LPARAM)text[i]);
}
//设置默认选择文本
SendMessage(GetDlgItem(hwnd,COMBOBOX_0), CB_SETCURSEL, 0, 0);
SendMessage(GetDlgItem(hwnd,COMBOBOX_1), CB_SETCURSEL, 0, 0);
SendMessage(GetDlgItem(hwnd,COMBOBOX_2), CB_SETCURSEL, 0, 0);
通知类型
主题 目录
CBN_CLOSEUP 关闭组合框的列表框时,将发送 CBN_CLOSEUP 通知代码。 组合框的父窗口通过 WM_COMMAND 消息接收此通知代码。
CBN_DBLCLK 当用户双击组合框列表框中的字符串时,将发送 CBN_DBLCLK 通知代码。 组合框的父窗口通过 WM_COMMAND 消息接收此通知代码。
CBN_DROPDOWN 当组合框的列表框即将可见时,将发送 CBN_DROPDOWN 通知代码。 组合框的父窗口通过 WM_COMMAND 消息接收此通知代码。
CBN_EDITCHANGE 用户执行了可能更改组合框的编辑控件部分中的文本的操作后,将发送 CBN_EDITCHANGE 通知代码。 与 CBN_EDITUPDATE 通知代码不同,系统更新屏幕后会发送此通知代码。 组合框的父窗口通过 WM_COMMAND 消息接收此通知代码。
CBN_EDITUPDATE 当组合框的编辑控件部分即将显示更改的文本时,将发送 CBN_EDITUPDATE 通知代码。 此通知代码在控件设置文本格式后发送,但在显示文本之前。 组合框的父窗口通过 WM_COMMAND 消息接收此通知代码。
CBN_ERRSPACE 当组合框无法分配足够的内存以满足特定请求时,将发送 CBN_ERRSPACE 通知代码。 组合框的父窗口通过 WM_COMMAND 消息接收此通知代码。
CBN_KILLFOCUS 组合框失去键盘焦点时,将发送 CBN_KILLFOCUS 通知代码。 组合框的父窗口通过 WM_COMMAND 消息接收此通知代码。
CBN_SELCHANGE 当用户更改组合框列表框中的当前选定内容时,将发送 CBN_SELCHANGE 通知代码。 用户可以通过单击列表框或使用箭头键来更改选择。 组合框的父窗口以 WM_COMMAND 消息的形式接收此通知,该消息采用 wParam 参数的高序单词CBN_SELCHANGE。
CBN_SELENDCANCEL 当用户选择某个项时,将发送 CBN_SELENDCANCEL 通知代码,但随后选择另一个控件或关闭对话框。 它指示用户的初始选择将被忽略。 组合框的父窗口通过 WM_COMMAND 消息接收此通知代码。
CBN_SELENDOK 当用户选择列表项或选择某个项,然后关闭列表时,将发送 CBN_SELENDOK 通知代码。 它指示要处理用户的选择。 组合框的父窗口通过 WM_COMMAND 消息接收此通知代码。
CBN_SETFOCUS 当组合框接收键盘焦点时,将发送 CBN_SETFOCUS 通知代码。 组合框的父窗口通过 WM_COMMAND 消息接收此通知代码。
WM_COMPAREITEM 系统发送 WM_COMPAREITEM 消息,以确定新项在所有者绘制组合框或列表框的排序列表中的相对位置。 每当应用程序添加新项时,系统就会将此消息发送到使用 CBS_SORT 或 LBS_SORT 样式创建的组合框或列表框的所有者。
WM_DRAWITEM 当按钮、组合框、列表框或菜单的可视方面发生更改时, WM_DRAWITEM 消息将发送到所有者绘制按钮、组合框、列表框或菜单的父窗口。
WM_MEASUREITEM 创建控件或菜单时 ,WM_MEASUREITEM 消息发送到组合框、列表框、列表视图控件或菜单项的所有者窗口。
CBN_SELCHANGE通知代码
当用户在组合框的列表框中更改当前所选内容时发送。 用户可以通过单击列表框或使用
箭头键来更改所选内容。 组合框的父窗口以 WM_COMMAND 消息的形式接收此通知代
码。
CBN_SELCHANGE
WPARAM wParam;
LPARAM lParam;
wParam
LOWORD 包含组合框的控制标识符。 HIWORD 指定通知代码。
lParam
组合框的句柄。
若要获取当前所选内容的索引,请将 CB_GETCURSEL 消息发送到控件。
使用CB_SETCURSEL消息设置当前选择时,不会发送 CBN_SELCHANGE 通知代码。
在窗体过程函数中,对WM_COMMAND消息,判断wParam的低位是否是对应的组合框控件,判断wParam的高位,获取通知类型是否为CBN_SELCHANGE,并进行处理
...
case WM_COMMAND:
{
switch(LOWORD(wParam)){
case COMBOBOX_0:
{
if(HIWORD(wParam) == CBN_SELCHANGE){
int iSel;
iSel = SendMessage(GetDlgItem(hwnd,COMBOBOX_0), CB_GETCURSEL, 0, 0);
char text[128] = {0};
SendMessage(GetDlgItem(hwnd,COMBOBOX_0), CB_GETLBTEXT, (WPARAM)iSel, (LPARAM)text);
printf("combobox 0 current choose:%s\n",text);
}
}
break;
示例代码
#include <windows.h>
#include <stdio.h>
#define COMBOBOX_0 1000
#define COMBOBOX_1 1001
#define COMBOBOX_2 1002
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const char CLASS_NAME[] = "Sample Window Class";
WNDCLASSA wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClassA(&wc);
// Create the window.
HWND hwnd = CreateWindowExA(
0, // Optional window styles.
CLASS_NAME, // Window class
"My first window", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
CreateWindowEx(0,
"ComboBox",
NULL,
WS_VISIBLE| WS_CHILD| WS_BORDER| CBS_HASSTRINGS| CBS_SIMPLE,
10, 10, 200, 130,
hwnd,
(HMENU)COMBOBOX_0,
((LPCREATESTRUCT)lParam)->hInstance,
0);
CreateWindowEx(0,
"ComboBox",
NULL,
WS_VISIBLE| WS_CHILD| WS_BORDER| CBS_HASSTRINGS| CBS_DROPDOWN,
230, 10, 200, 130,
hwnd,
(HMENU)COMBOBOX_1,
((LPCREATESTRUCT)lParam)->hInstance,
0);
CreateWindowEx(0,
"ComboBox",
NULL,
WS_VISIBLE| WS_CHILD| WS_BORDER| CBS_HASSTRINGS| CBS_DROPDOWNLIST,
460, 10, 200, 130,
hwnd,
(HMENU)COMBOBOX_2,
((LPCREATESTRUCT)lParam)->hInstance,
0);
const char* text[4] = {"aaa","bbb","ccc","ddd"};
for(int i=0; i<4; i++){
SendMessage(GetDlgItem(hwnd,COMBOBOX_0), CB_ADDSTRING, i, (LPARAM)text[i]);
SendMessage(GetDlgItem(hwnd,COMBOBOX_1), CB_ADDSTRING, i, (LPARAM)text[i]);
SendMessage(GetDlgItem(hwnd,COMBOBOX_2), CB_ADDSTRING, i, (LPARAM)text[i]);
}
SendMessage(GetDlgItem(hwnd,COMBOBOX_0), CB_SETCURSEL, 0, 0);
SendMessage(GetDlgItem(hwnd,COMBOBOX_1), CB_SETCURSEL, 0, 0);
SendMessage(GetDlgItem(hwnd,COMBOBOX_2), CB_SETCURSEL, 0, 0);
}
return 0;
case WM_COMMAND:
{
switch(LOWORD(wParam)){
case COMBOBOX_0:
{
if(HIWORD(wParam) == CBN_SELCHANGE){
int iSel;
iSel = SendMessage(GetDlgItem(hwnd,COMBOBOX_0), CB_GETCURSEL, 0, 0);
char text[128] = {0};
SendMessage(GetDlgItem(hwnd,COMBOBOX_0), CB_GETLBTEXT, (WPARAM)iSel, (LPARAM)text);
printf("combobox 0 current choose:%s\n",text);
}
}
break;
case COMBOBOX_1:
{
if(HIWORD(wParam) == CBN_SELCHANGE){
int iSel;
iSel = SendMessage(GetDlgItem(hwnd,COMBOBOX_1), CB_GETCURSEL, 0, 0);
char text[128] = {0};
SendMessage(GetDlgItem(hwnd,COMBOBOX_1), CB_GETLBTEXT, (WPARAM)iSel, (LPARAM)text);
printf("combobox 1 current choose:%s\n",text);
}
}
break;
case COMBOBOX_2:
{
if(HIWORD(wParam) == CBN_SELCHANGE){
int iSel;
iSel = SendMessage(GetDlgItem(hwnd,COMBOBOX_2), CB_GETCURSEL, 0, 0);
char text[128] = {0};
SendMessage(GetDlgItem(hwnd,COMBOBOX_2), CB_GETLBTEXT, (WPARAM)iSel, (LPARAM)text);
printf("combobox 2 current choose:%s\n",text);
}
}
break;
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// All painting occurs here, between BeginPaint and EndPaint.
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
结果
