window控件:
控件是常见的窗口上的交互元素例如:一个按钮,一个复选框,一个列表框等。
当控件的特定功能被触发后,会主动发送消息通知父窗口,父窗口可以通过发送消息给控件控制控件的行为。
控件的本质是一个窗口
windows窗口风格
windows窗口从其特点是主要分为两大类
- 表明窗口和其他窗口关系的(WS_OVERLAPED(重叠)、WS_POPPUP(弹出)、WS_CHILD(子窗口))
- 表明窗口自身外观特征的(WS_BORDER、WS_CAPITON…)
windows标准控件:
窗口类名 | 控件名称 |
---|---|
WC_BUTTON | 按钮 |
WC_STATIC | 静态文本 |
WC_COMBOBOX | 复合框 |
WC_EDIT | 编辑框 |
WC_LISTBOX | 列表框 |
WC_SCROLLBAR | 滚动条 |
windows通用控件:
WC_LISTVIEW 列表框控件
WC_TREEVIEW 树控件
WC_TABCONTROL Tab控件
…
控件的响应
子控件通知父窗口一些事件,例如子控件被点击,需要通过以下两类消息
标准控件的消息:WM_COMMAND
通用控件的消息:WM_NOTIFY
添加一个按钮演示
{static HINSTANCE hInstance = GetModuleHandleW(NULL);switch (uMsg){case WM_CREATE://添加控件CreateWindowW(WC_BUTTON,L"按钮1",WS_CHILD|WS_VISIBLE,10,10,80,60,hwnd,(HMENU)0x100, hInstance,0);break;case WM_CLOSE:DestroyWindow(hwnd);PostQuitMessage(0);break;}return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
按钮消息处理
LRESULT CALLBACK WindowProc(_In_ HWND hwnd,_In_ UINT uMsg,_In_ WPARAM wParam,_In_ LPARAM lParam
)
{static HINSTANCE hInstance = GetModuleHandleW(NULL);switch (uMsg){case WM_CREATE://添加控件CreateWindowW(WC_BUTTON,L"按钮1",WS_CHILD|WS_VISIBLE,10,10,80,60,hwnd,(HMENU)0x100, hInstance,0);CreateWindowW(WC_BUTTON,L"按钮2",WS_CHILD|WS_VISIBLE,10,80,80,60,hwnd,(HMENU)0x101, hInstance,0);break;case WM_CLOSE:DestroyWindow(hwnd);PostQuitMessage(0);break;case WM_COMMAND:WORD ContrlId = LOWORD(wParam);if (ContrlId==0x100) {MessageBoxW(hwnd, L"按钮1", L"提示", MB_OK);}else if(ContrlId == 0x101) {MessageBoxW(hwnd, L"按钮2", L"提示", MB_OK);}break;}return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
窗口操作函数的使用
操作窗口的通用函数
函数 | 说明 |
---|---|
MoveWindow | 移动窗口 |
UpdateWindow | 更新窗口 |
GetWindowText | 获取窗口标题 |
SetWindowText | 设置窗口标题 |
FindWindow | 查找窗口返回句柄 |
GetClientRect | 获取窗口客户区大小 |
SetWindowPos | 设置窗口位置 |
EnumChildWindows | 枚举窗口下的所有子窗口 |
实现按钮(窗口)移动
#include<Windows.h>
#include<iostream>
#include<CommCtrl.h>
LRESULT CALLBACK WindowProc(_In_ HWND hwnd,_In_ UINT uMsg,_In_ WPARAM wParam,_In_ LPARAM lParam
)
{static HINSTANCE hInstance = GetModuleHandleW(NULL);switch (uMsg){case WM_CREATE://添加控件CreateWindowW(WC_BUTTON,L"移动按钮",WS_CHILD|WS_VISIBLE,10,10,80,60,hwnd,(HMENU)0x100, hInstance,0);CreateWindowW(WC_BUTTON,L"获取文本框内容",WS_CHILD|WS_VISIBLE,10,80,80,60,hwnd,(HMENU)0x101, hInstance,0);CreateWindowW(WC_BUTTON,L"设置文本框内容",WS_CHILD|WS_VISIBLE,10,160,80,60,hwnd,(HMENU)0x102, hInstance,0);CreateWindowW(WC_BUTTON,L"设置父窗口",WS_CHILD|WS_VISIBLE,10,240,80,60,hwnd,(HMENU)0x103, hInstance,0);CreateWindowW(WC_EDIT,L"文本框内容",WS_CHILD|WS_BORDER|WS_VISIBLE,10,320,80,60,hwnd,(HMENU)0x104, hInstance,0);break;case WM_CLOSE:DestroyWindow(hwnd);PostQuitMessage(0);break;case WM_COMMAND:WORD ContrlId = LOWORD(wParam);switch (ContrlId){case 0x100:{RECT rect{ 0 };GetClientRect(hwnd, &rect);int x = rand() % rect.right;int y = rand() % rect.bottom;MoveWindow((HWND)lParam, x, y, 80, 60, TRUE);}}break;}return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nCmdShow
)
{//1、创建一个窗口类WNDCLASSW myClass = { 0 };myClass.lpszClassName = L"xiaowang";myClass.lpfnWndProc = WindowProc;myClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));//2、注册窗口类RegisterClassW(&myClass);//3、创建窗口HWND hwindow=CreateWindowW(myClass.lpszClassName,L"xiaowang",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,0);//4、显示窗口ShowWindow(hwindow,SW_SHOWNORMAL );//5、获取消息MSG msg = { 0 };while (GetMessageW(&msg,0,0,0)) {DispatchMessageW(&msg);//分发消息给消息处理函数}return 0;
}
实现获取文本框内容
case 0x101:
{WCHAR buff[100]{ 0 };HWND hedit = GetDlgItem(hwnd, 0x104);GetWindowTextW(hedit, buff, 100);MessageBoxW(hwnd, buff, L"提示", MB_OK);break;
}
设置文本内容
case 0x102:
{HWND hedit = GetDlgItem(hwnd, 0x104);//SetWindowTextW(hedit, L"设置了文本内容");SetDlgItemTextW(hedit, 0x104,L"设置了文本内容SetDlgItemTextW");break;
}
设置父窗口
case 0x103:
{HWND hnote = FindWindowW(NULL, L"记事本");SetParent((HWND)lParam, hnote);break;
}
使文本框内容可编辑
加上
TranslateMessage(&msg);
//4、显示窗口ShowWindow(hwindow,SW_SHOWNORMAL );//5、获取消息MSG msg = { 0 };while (GetMessageW(&msg,0,0,0)) {TranslateMessage(&msg);DispatchMessageW(&msg);//分发消息给消息处理函数}return 0;
}
资源操作
无法直接定位到资源,并使用函数操作他们,和窗口一样,一般情况需要得到资源的句柄
LoadXXX:XXX是资源类型
LoadTcon 载入图标、LoadCursor载入光标 LoadMenu 载入菜单
图标资源:LoadIcon
光标资源:LoadCursor
菜单资源:
1、
lpszMenuName
2、
LoadMenu
CreateWindow();
3、
LoadMenu
GetSubMenu();
TrackPopupMenu()
图标
添加 一个资源
选择icon
载入图标
按钮点击后改变
#include"resource.h"
case 0x101:{//MAKEINTRESOURCEW为强制转换//IDI_ICON1为资源视图中图标的名字HICON hIcon=LoadIcon(hInstance,MAKEINTRESOURCEW(IDI_ICON1));SetClassLongW(hwnd, GCL_HICON, (LONG)hIcon);break;}
窗口创建时改变图标
//1、创建一个窗口类WNDCLASSW myClass = { 0 };myClass.lpszClassName = L"xiaowang";myClass.lpfnWndProc = WindowProc;myClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));myClass.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_ICON1));//系统提供图标//myClass.hIcon = LoadIconW(0, IDI_ERROR);//2、注册窗口类RegisterClassW(&myClass);
光标
创建光标文件
载入光标
case 0x102:
{HCURSOR hcursor = LoadCursorW(hInstance, MAKEINTRESOURCEW(IDC_CURSOR1));SetClassLongW(hwnd, GCL_HCURSOR, (LONG)hcursor);break;
}
窗口创建时改变光标
//1、创建一个窗口类WNDCLASSW myClass = { 0 };myClass.lpszClassName = L"xiaowang";myClass.lpfnWndProc = WindowProc;myClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));myClass.hCursor = LoadCursorW(hInstance, MAKEINTRESOURCEW(IDC_CURSOR1))
菜单
初始化时载入菜单
//1、创建一个窗口类WNDCLASSW myClass = { 0 };myClass.lpszClassName = L"xiaowang";myClass.lpfnWndProc = WindowProc;myClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));myClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU1);
创建窗口时
//3、创建窗口HMENU hmenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));HWND hwindow=CreateWindowW(myClass.lpszClassName,L"xiaowang",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,hmenu,hInstance,0);
通过按钮载入
case 0x100:{HMENU hmenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));SetMenu(hwnd, hmenu);
鼠标右键点击时出现菜单
switch (uMsg){case WM_CREATE:.....case WM_RBUTTONDOWN:{POINT point{ 0 };ClientToScreen(hwnd, &point);GetCursorPos(&point);HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));HMENU hSubMenu = GetSubMenu(hMenu, 0);TrackPopupMenu(hSubMenu, TPM_LEFTALIGN, point.x, point.y, 0, hwnd, NULL);break;}
捕获菜单被点击
case ID_40001:
{MessageBoxW(hwnd, L"子菜单1被点击了",L"提示",MB_OK);
}
对话框资源
对话框资源可以创建一个对话框,以及其上的子控件。通过对话框可以进行可视化编辑。
对话框有两种形式:
模态对话框、非模态对话框
区别:模态对话框会阻塞主窗口,非模态对话框不会
添加一个对话框
创建非模态对话框
#include<Windows.h>
#include<CommCtrl.h>
#include"resource.h"
INT_PTR CALLBACK Dlgproc(HWND hWnd,UINT Umsg,WPARAM wparam,LPARAM lparam
) {switch (Umsg){case WM_INITDIALOG: {MessageBox(hWnd,L"窗口创建了",L"标题",MB_OK);break;}case WM_CLOSE:{DestroyWindow(hWnd);PostQuitMessage(0);break;}default:{return FALSE;}}return TRUE;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nCmdShow
)
{HWND hwnd=CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_DIALOG1),NULL,Dlgproc);ShowWindow(hwnd, SW_SHOWNORMAL);MSG msg{ 0 };while (GetMessage(&msg,0,0,0)){TranslateMessage(&msg);DispatchMessageW(&msg);}return 0;
}