window控件:
控件是常见的窗口上的交互元素例如:一个按钮,一个复选框,一个列表框等。
当控件的特定功能被触发后,会主动发送消息通知父窗口,父窗口可以通过发送消息给控件控制控件的行为。
控件的本质是一个窗口

windows窗口风格
windows窗口从其特点是主要分为两大类

  1. 表明窗口和其他窗口关系的(WS_OVERLAPED(重叠)、WS_POPPUP(弹出)、WS_CHILD(子窗口))
  2. 表明窗口自身外观特征的(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#include#includeLRESULT 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#include#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;}