前言
- 各位师傅大家好,我是qmx_07,今天给大家讲解按钮控件和编辑框的相关知识
控件
- 概念:Windows Software Development Kit(SDK)提供的一组可重用的用户界面元素,在应用程序使用的可视化界面,比如:文本框,图片加载,按钮提交,菜单等元素信息
按钮控件
- 介绍:按钮通常用于触发某个操作或事件,如提交表单、启动任务或导航到其他界面,最常见的是:接收账号密码,将数据提交到后端处理文件
- 按钮类型:单选按钮,复选框按钮,分组框
- 用户单击一个按钮时会收到键盘焦点。 系统向按钮的父窗口发送包含 BN_CLICKED 通知代码的 WM_COMMAND 消息
单选按钮
创建按钮
- 由常量 BS_PUSHBUTTON 和 BS_DEFPUSHBUTTON 定义
语法:
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
100, // Button width
100, // Button height
m_hwnd, // Parent window
NULL, // No menu.
(HINSTANCE)GetWindowLongPtr(m_hwnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
- 演示:
VOID MyWindows(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
80, // Button width
20, // Button height
hWnd, // Parent window
NULL, // No menu.
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
MyWindows(hWnd, message, wParam, lParam);
break;
}
- WM_CREATE 用于创建控件信息,用作窗口初始化的一些信息
通过控件ID 实现改变按钮文本内容
- 定义按钮 全局控件ID
#define IDC_BUTTON_CHECK_1 0
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
80, // Button width
20, // Button height
hWnd, // Parent window
IDC_BUTTON_CHECK_1, // 将控件ID加载在这里
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL);
- 当我们获取到控件ID的时候,就可以对这个控件进行修改操作
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
MyWindows(hWnd, message, wParam, lParam);
break;
}
case WM_COMMAND:
{
if (LOWORD(wParam) == IDC_BUTTON_CHECK_1)
{
HWND change = GetDlgItem(hWnd, IDC_BUTTON_CHECK_1);
SetWindowText(change, L"qmx_07");
}
- 用户点击按钮之后,会将消息发送到WM_COMMAND里面
- wParam 的低位字(LOWORD)是按钮的 ID
- 通过wparam判断按钮是否被点击
画面演示:
通过控件ID 显示隐藏按钮 ,启用 禁用按钮
- 定义全局变量控件ID
#define IDC_BUTTON_CHECK_1 0
#define IDC_BUTTON_CHECK_2 1
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"隐藏", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
80, // Button width
20, // Button height
hWnd, // Parent window
IDC_BUTTON_CHECK_1, // No menu.
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
50, // y position
80, // Button width
20, // Button height
hWnd, // Parent window
(HMENU)IDC_BUTTON_CHECK_2, // No menu.
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
- 定义两个windows单选按钮,创建多个控件时 IDC需要(HMENU)强转
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
MyWindows(hWnd, message, wParam, lParam);
break;
}
case WM_COMMAND:
{
if (LOWORD(wParam) == IDC_BUTTON_CHECK_1)
{
HWND change = GetDlgItem(hWnd, IDC_BUTTON_CHECK_2);
if (IsWindowVisible(change))
{
ShowWindow(change, SW_HIDE);
}
else
{
ShowWindow(change, SW_SHOW);
}
}
-
IsWindowVisible API函数,用于检索一个窗口句柄是否要隐藏,如果已经隐藏则显示,如果显示则隐藏
-
SW_HIDE 隐藏
-
SW_SHOW 显示
画面演示:
-
想要启用 禁用 按钮,调用WINDOW API就好
case WM_COMMAND:
{
if (LOWORD(wParam) == IDC_BUTTON_CHECK_1)
{
HWND change = GetDlgItem(hWnd, IDC_BUTTON_CHECK_2);
if (IsWindowEnabled(change))
{
EnableWindow(change, FALSE);
}
else
{
EnableWindow(change, TRUE);
}
}
- IsWindowEnabled函数判断指定的窗口是否启用。当窗口启用时,用户可以与窗口进行交互;当窗口禁用时,用户无法与窗口进行交互
- EnableWindow函数是Windows API中的一个函数,用于启用或禁用一个窗口
画面演示:
获取按钮文本信息
case WM_COMMAND:
{
if (LOWORD(wParam) == IDC_BUTTON_CHECK_1)
{
HWND change = GetDlgItem(hWnd, IDC_BUTTON_CHECK_2);
DWORD dwlength = GetWindowTextLength(change);
WCHAR* szBuffer = new WCHAR[dwlength+1];
GetWindowText(change, szBuffer, 256);
SetWindowText((HWND)lParam, szBuffer);
}
- GetWindowTextLength 获取文本长度
- GetWindowText 将按钮2的内容 复制到 szBuffer里面
- SetWindowText 将szBuffer 改变按钮1的内容
- lparam代表按钮本身
画面演示:
多选框按钮
- 多选框按钮 分为 手动复选框 和 自动复选框
- 分别由常量 BS_CHECKBOX、BS_AUTOCHECKBOX定义
创建自动复选框:
CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, //将这里改成BS_AUTOCHECKBOX就好
10, // x position
50, // y position
80, // Button width
20, // Button height
hWnd, // Parent window
(HMENU)IDC_BUTTON_CHECK_1, // No menu.
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
创建手动复选框:
CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"改变", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_CHECKBOX, // Styles
10, // x position
10, // y position
80, // Button width
20, // Button height
hWnd, // Parent window
IDC_BUTTON_CHECK_2, // No menu.
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
画面效果:
- 可以看到BS_AUTOCHECKBOX可以勾选,而BS_CHECKBOX点击无响应
- 需要做以下操作:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
MyWindows(hWnd, message, wParam, lParam);
break;
}
case WM_COMMAND:
{
switch (HIWORD(wParam))
{
case BN_CLICKED:
SendMessage((HWND)lParam, BM_SETCHECK, !SendMessage((HWND)lParam, BM_GETCHECK, 0, 0), 0);
}
- switch (HIWORD(wParam)):获取与 WM_COMMAND 消息相关的控制标识符的高位字
- case BN_CLICKED::表示按钮被点击
- SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) 用于获取指定控件(由 lParam 表示的控件)的选中状态
- SendMessage((HWND)lParam, BM_SETCHECK,!SendMessage((HWND)lParam, BM_GETCHECK, 0, 0), 0)就是将选中状态取反,如果按钮当前被选中,它会被设置为未选中
- 手动多选框按钮 和 自动多选框按钮 只能选择一种
分组框按钮
VOID MyWindows(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hGroup = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"BUTTON", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_GROUPBOX, // Styles
50, // x position
10, // y position
200, // Button width
200, // Button height
hWnd, // Parent window
IDC_BUTTON_CHECK_1, // No menu.
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"BUTTON1", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, // Styles
50, // x position
40, // y position
100, // Button width
40, // Button height
hGroup, // Parent window
(HMENU)IDC_BUTTON_CHECK_2, // No menu.
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"BUTTON2", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, // Styles
50, // x position
80, // y position
100, // Button width
20, // Button height
hGroup, // Parent window
(HMENU)IDC_BUTTON_CHECK_2, // No menu.
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
}
- 需要子按钮控件里面填入父亲窗口句柄
画面演示:
确认选中状态
VOID MyWindows(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, // Styles
10, // x position
10, // y position
80, // Button width
20, // Button height
hWnd, // Parent window
IDC_BUTTON_CHECK_1, // 将控件ID加载在这里
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL);
CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
80, // y position
80, // Button width
20, // Button height
hWnd, // Parent window
(HMENU)IDC_BUTTON_CHECK_3, // 将控件ID加载在这里
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL);
}
- 生成一个自动多选框 和 单选按钮
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
MyWindows(hWnd, message, wParam, lParam);
break;
}
case WM_COMMAND:
{
switch (HIWORD(wParam))
{
case BN_CLICKED:
{
if (LOWORD(wParam) == IDC_BUTTON_CHECK_3)
{
HWND hSWnd = GetDlgItem(hWnd, IDC_BUTTON_CHECK_1);
if (SendMessage(hSWnd, BM_GETCHECK, 0, 0) == TRUE)
{
MessageBox(NULL, L"选中", L"Msg", MB_OK);
}
else
{
MessageBox(NULL, L"未选中", L"Msg", MB_OK);
}
}
}
- 当点击按钮的时候,SendMessage(hSWnd, BM_GETCHECK, 0, 0) 判断多选框的选中状态
创建静态文本
CreateWindow(L"static", L"Hello, this is a static text.",
WS_CHILD | WS_VISIBLE | SS_LEFT,
10, 10, 200, 20,
hWnd, NULL, NULL, NULL);
- 左对齐,不换行
- 左对齐并换行
- 居中对齐
- 右对齐
- 简单
- 分别由常量 SS_LEFTNOWORDWRAP、SS_LEFT、SS_CENTER、SS_RIGHT 和 SS_SIMPLE 定义
画面演示:
创建编辑框
CreateWindowEx(
0, L"EDIT", // predefined class
NULL, // no window title
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
300, 20, 100, 200, // set size in WM_SIZE message
hWnd, // parent window
(HMENU)IDC_BUTTON_CHECK_1, // edit control ID
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL);
- WS_VSCROLL(垂直滚动条)、ES_MULTILINE(多行模式)和ES_AUTOVSCROLL(自动垂直滚动)
总结
- 讲解了按钮、静态文本和编辑框控件,这些了解就好,后面 会有拖动版本