windows编程(1)-第一个窗口程序
文章首发于:My Blog 欢迎大佬们前来逛逛
1. main函数入口点
win32的main函数入口点为 WinMain或者wWinMain,他们包含四个参数:
int __clrcall WinMain( [in] HINSTANCE hInstance, [in] HINSTANCE hPrevInstance, [in] LPSTR lpCmdLine, [in] int nShowCmd );
其中:
- hInstance:应用程序当前窗口的实例句柄
- hPrevInstance:应用程序上一个窗口的实例句柄
- lpCmdLine:应用程序的命令行
- nShowcmd:控制窗口的显示方式
其中wWinMain与WinMain的区别是 wWinMain适用于多字节字符集,而WinMian适用于unicode字符集。
其中第三个参数WinMain是LPSTR类型:
typedef char CHAR;
但是wWinMain是LPWSTR类型:
typedef wchar_t WCHAR;
2. 窗口函数六部曲
2.1 注册窗口类
ATOM RegisterClassExA( [in] const WNDCLASSEXA *unnamedParam1 );
其中:
- unnamedParam1:一个WNDCLASSEXA结构体指针变量,这个结构包含了我们所创建对象的窗口的属性信息
struct tagWNDCLASSEXW { UINT cbSize; /* Win 3.x */ UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCWSTR lpszMenuName; LPCWSTR lpszClassName; /* Win 4.0 */ HICON hIconSm; }
其中:比较重要的几个参数:
- hInstance:窗口的示例句柄,就是我们的WinMain包含的hInstance参数
- lpszClassName:窗口类名
- cbSize:结构体的大小,必须指定其为sizeof(WNDCLASSEX)
- style:窗口类的样式,设置水平与垂直重绘:CS_HREDRAW | CS_VREDRAW
- hbrBackground:窗口回调函数,其接受一个WNDPROC的参数,WNDPROC是一个typedef定义的函数指针,其中包含四个参数:HWND UINT WPARAMS LPARAMS。
//回调函数m_WNDPROC:lpfnWndProc的数据类型 LRESULT CALLBACK m_WNDPROC(HWND hwnd, UINT msg, WPARAM wParams, LPARAM lParams) { return DefWindowProc(hwnd, msg, wParams, lParams); }//使用return DefWindowProc作为返回值 WNDCLASSEX mWinC = {NULL}; mWinC.cbSize = sizeof(WNDCLASSEX); mWinC.hInstance = hInstance; mWinC.lpszClassName = "我的第一个窗口"; mWinC.hbrBackground = (HBRUSH)NULL; //画刷 mWinC.lpfnWndProc = m_WNDPROC; mWinC.style = CS_HREDRAW | CS_VREDRAW; //注册窗口类 RegisterClassEx(&mWinC);
2.2 创建窗口
HWND CreateWindowExA( DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
其中:重要的参数有:
- dwExStyle:设置为mWinC的style即可。
- lpClassName,lpWindowName:类名与窗口名
- dwStyle:窗口的样式,设置为WS_OVERLAPPEDWINDOW即可。
- x y Width Height:窗口的大小和宽高
- hInstance:窗口的实例句柄。
HWND hwnd = CreateWindowEx(mWinC.style, mWinC.lpszClassName, "First Window", WS_OVERLAPPEDWINDOW, 100, 100, 600, 600, NULL, NULL, mWinC.hInstance, NULL); if (!hwnd) return false;
其返回值为HWND,表示创建了一个窗口句柄hwnd,如果其为NULL,则创建失败。
2.3 显示窗口
BOOL ShowWindow( [in] HWND hWnd, [in] int nCmdShow );
- hwnd:创建的窗口实例句柄
- nCmdshow:控制窗口的显示方式
ShowWindow(hwnd, SW_SHOW);
2.4 刷新窗口
UpdateWindow(hwnd);
2.5 消息循环
接受消息
//从调用线程的消息队列中检索消息。 BOOL GetMessage( [out] LPMSG lpMsg, [in, optional] HWND hWnd, [in] UINT wMsgFilterMin, [in] UINT wMsgFilterMax );
参数:
- lpMsg:指向MSG的指针,我们需要创建一个MSG类型的变量表示消息变量。
处理消息
//将虚拟密钥消息转换为字符消息。 BOOL TranslateMessage( [in] const MSG *lpMsg );
- lpMsg:消息指针
发送消息
//将消息调度到窗口过程。 LRESULT DispatchMessage( [in] const MSG *lpMsg );
- 消息指针
// 消息循环 MSG msg{ NULL }; while (true) { //接收消息 GetMessage(&msg, NULL, NULL, NULL); //处理消息 TranslateMessage(&msg); //发送消息 DispatchMessage(&msg); }
2.6 消息处理函数
消息处理函数即:WNDPROC
我们已经在 2.1 注册窗口类时处理过了。
//消息处理函数 LRESULT CALLBACK m_WNDPROC(HWND hwnd, UINT msg, WPARAM wParams, LPARAM lParams) { return DefWindowProc(hwnd, msg, wParams, lParams); } ... ... wMinC.lpfnWndProc=m_WNDPROC ... ...
3. 完整代码
由于我们运行的时Win32程序,我们应该在:
项目 - 属性 - 连接器 - 系统 - 子系统
把控制台改为窗口
#include <Windows.h> //回调函数 LRESULT CALLBACK m_WNDPROC(HWND hwnd, UINT msg, WPARAM wParams, LPARAM lParams) { return DefWindowProc(hwnd, msg, wParams, lParams); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cCmdLine, int nShowCmd ) { // 注册窗口类 WNDCLASSEX mWinC = {NULL}; mWinC.cbSize = sizeof(WNDCLASSEX); mWinC.hInstance = hInstance; mWinC.lpszClassName = "我的第一个窗口"; mWinC.hbrBackground = (HBRUSH)NULL; mWinC.lpfnWndProc = m_WNDPROC; mWinC.style = CS_HREDRAW | CS_VREDRAW; RegisterClassEx(&mWinC); // 创建窗口类 HWND hwnd = CreateWindowEx(mWinC.style, mWinC.lpszClassName, "First Window", WS_OVERLAPPEDWINDOW, 100, 100, 600, 600, NULL, NULL, mWinC.hInstance, NULL); if (!hwnd) return false; // 显示窗口类 ShowWindow(hwnd, SW_SHOW); // 刷新窗口类 UpdateWindow(hwnd); // 消息循环 MSG msg{ NULL }; while (true) { //接收消息 GetMessage(&msg, NULL, NULL, NULL); //处理消息 TranslateMessage(&msg); //发送消息 DispatchMessage(&msg); } return true; }
本文来自博客园,作者:hugeYlh,转载请注明原文链接:https://www.cnblogs.com/helloylh/p/17300984.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)