组合框和列表框同样也是控件,所以我们在应用组合框和列表框时同样也需要父窗口,现在我们以
创建项目时程序自行创建的窗口作为父窗口展开如下的控件创建与应用
在进行组合框与列表框的讲解前,我们首先在程序中定义几个宏作为我们在编写程序时的控件ID:
#define IDC_BUTTON_CHECK_1 0
#define IDC_BUTTON_CHECK_2 1
#define IDC_BUTTON_CHECK_3 2
#define IDC_COMBOBOX_CITY 0x8001
#define IDC_LIST_COMM 0x9001
组合框的创建
组合框(COMBOBOX):也叫下拉框,用于指定由列表框和类似于编辑控件的选择字段组成的控件。
如图便是一个组合框
此时我们于消息循环的WM_CREATE消息下创建一个简单组合框:
HWND hWndCombobox = CreateWindow(L"Combobox", L"", WS_CHILD | WS_VISIBLE |
WS_OVERLAPPED | CBS_DROPDOWN | CBS_HASSTRINGS, 100, 100, 200,200,hWnd,
(HMENU)IDC_COMBOBOX_CITY, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
如图便是我们创建的组合框
组合框内容的填充
const WCHAR * szCity[5] = { L"北京",L"上海", L"深圳", L"广州", L"曹县" }; 此时我们创建了一个数
组用于保存我们要填充的消息
for (size_t i = 0; i < 5; i++)
{
SendMessage(hWndCombobox,CB_ADDSTRING,NULL,(LPARAM)szCity[i]); 给下拉框发送添
加字符串的消息
}
如图便是我们此时创建的下拉框
SendMessage(hWndCombobox, CB_SETCURSEL, 0, NULL); 设置默认选中的字符串,此处设置
的是北京作为默认字符串
如图,此时下拉框便有了默认值
组合柜的应用
组合框的消息处理在WM_COMMAND中进行获取对于应用的消息
case WM_COMMAND:
{
if (HIWORD(wParam) == CBN_SELCHANGE) 判断是不是下拉框的选择消息,
CBN_SELCHANGE:当用户更改组合框列表框中的当前选择时发送的通知代码
{
if (LOWORD(wParam) == IDC_COMBOBOX_CITY) 判断是不是我们想要的下拉框
{
int ItemIndex = SendMessage((HWND)lParam, CB_GETCURSEL, NULL, NULL); 发送
消息获取当前选择的索引
WCHAR *szCityName = new WCHAR[50];
SendMessage((HWND)lParam, CB_GETLBTEXT, ItemIndex, (LPARAM)szCityName);
发送消息,获取指定索引的值
MessageBox(hWnd, szCityName, L"Msg", MB_OK); 对获取的值进行显示
}
}
}
完成以上代码后,我们在下拉框列表中选择相应的值时,会弹出相应的窗口
如图我们选择了深圳的值以后,会弹出窗口,点击确认以后,下拉框的值会变成深圳
列表的创建
此控件需要包含头文件#include <commctrl.h>
HWND hWndListView = CreateWindow(L"SysListView32", L"", LVS_REPORT | WS_CHILD |
WS_VISIBLE | WS_BORDER, 10, 10, 400, 300, hWnd, (HMENU)IDC_LIST_COMM,
((LPCREATESTRUCT)lParam)->hInstance, NULL);
此时生成了一个空白列表
列表风格的设置
首先我们要设置列表的风格
LRESULT lStyle = SendMessage(hWndListView, LVM_GETEXTENDEDLISTVIEWSTYLE,
NULL, NULL); 获取原有风格
lStyle |= (LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
SendMessage(hWndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, NULL, lStyle); 设置风
格
此时我们已经设置好了列表的风格
列表表头的填写
通常我们有2种方式对表头的填写:1.消息,2.宏
LV_COLUMN lvc = { 0 }; 初始化LV_COLUMN表头结构
lvc.mask |= (LVCF_TEXT | LVCF_WIDTH); mask设置标记,填充文本类型 也可以填充图标
lvc.pszText = new WCHAR[50]; 填充文本需要开辟空间
lvc.cx = 100; 设置列宽,即单个表头所占长度
memset(lvc.pszText, 0, 50); 清空文本空间
memcpy(lvc.pszText, L"List1", 12);
SendMessage(hWndListView, LVM_INSERTCOLUMN, 0, (LPARAM)&lvc); 利用消息的方式填
充表头,发送插入列消息,WParam是列下标,最后一个参数是结构
此时便有了一个表头,我们接下来依如上的方式多次填充文本:
memset(lvc.pszText, 0, 50);
memcpy(lvc.pszText, L"List2", 12);
SendMessage(hWndListView, LVM_INSERTCOLUMN, 1, (LPARAM)&lvc);
memset(lvc.pszText, 0, 50);
memcpy(lvc.pszText, L"List3", 12);
SendMessage(hWndListView, LVM_INSERTCOLUMN, 2, (LPARAM)&lvc);
memset(lvc.pszText, 0, 50);
memcpy(lvc.pszText, L"List4", 12);
ListView_InsertColumn(hWndListView, 3, &lvc); 利用宏的方式填充表头
此时便有了四个表头
列表内容的填充
LVITEM vItem = { 0 }; 初始化LVITEM值结构
vItem.mask = LVIF_TEXT; 对mask进行填充文本
vItem.pszText = new WCHAR[50]; 开辟填充值的空间
for (size_t i = 0; i < 10; i++)
{
vItem.iItem = i; 表示第几行进行插入值内容
vItem.iSubItem = 0; 表示从第0列进行插入值内容
memset(vItem.pszText, 0, 50); 初始化值内容空间
swprintf(vItem.pszText, L"List1Value%d", i); 在指定的缓冲区填充数据
ListView_InsertItem(hWndListView, &vItem); 将值内容插到指定窗口,第一次添加值叫做插入
vItem.iItem = i;
vItem.iSubItem = 1;
memset(vItem.pszText, 0, 50);
swprintf(vItem.pszText, L"List2Value%d", i);
ListView_SetItem(hWndListView, &vItem); 注:除了第一次使用ListView_InsertItem进行插入以
后,都需要使用ListView_SetItem进行色织
vItem.iItem = i;
vItem.iSubItem = 2;
memset(vItem.pszText, 0, 50);
swprintf(vItem.pszText, L"List3Value%d", i);
ListView_SetItem(hWndListView, &vItem);
vItem.iItem = i;
vItem.iSubItem = 3;
memset(vItem.pszText, 0, 50);
wprintf(vItem.pszText, L"List4Value%d", i);
ListView_SetItem(hWndListView, &vItem);
}
如图便是我们填充的结果
列表消息应用
列表中的消息处理在WM_NOTIFY中,是一个独立的消息
case WM_NOTIFY:
{
switch (((LPNMHDR)lParam)->code)
{
case NM_CLICK: 左键点击列表弹窗内容
{
HWND hSWnd = GetDlgItem(hWnd, IDC_LIST_COMM); 获取当前点击的位置,行数索引
DWORD dwItemIndex = ListView_GetSelectionMark(hSWnd); 获取文本
CHAR * szBuffer = new WCHAR[50]; 设置文本缓冲区
ListView_GetItemText(hSWnd, dwItemIndex, 2, szBuffer, 50); 将获取文本填充到缓冲区中,
仅限于第二列的内容
MessageBox(hWnd, szBuffer, L"Msg", MB_OK);弹窗显示获取到的文本
break;
}
case NM_RCLICK: 右键点击列表删除选择行
{
HWND hSWnd = GetDlgItem(hWnd, IDC_LIST_COMM); 获取当前点击的位置,行数索引
DWORD dwItemIndex = ListView_GetSelectionMark(hSWnd);
SendMessage(hSWnd, LVM_DELETEITEM , dwItemIndex, NULL); 删除选择行
break;
}
default:
break;
}
break;
}