当前位置: 首页 > news >正文

Win32编程:创建属于你的第一个窗口

目录

一、Win32程序的运行过程

二、创建Windows窗口

1、分析

2、完整代码 


一、Win32程序的运行过程

        Win32编程,也称为Windows编程。运行步骤主要包含:加载程序(操作系统加载程序的可执行文件(exe格式)到内存中,创建进程的地址空间,并分配必要的系统资源。),初始化(查找程序的主函数WinMain函数),消息循环(消息也就是事件响应信息,这里会获取一段信息),消息处理(收到消息,放入消息队列,程序会根据消息调用相应函数,如果为WM_QUIT,则退出程序)。

Win32 应用特点:界面一致,操作便利,所见即所得,多任务。 

二、创建Windows窗口

1、分析

 首先要编写WinMain函数,它是窗口编程的入口函数,由操作系统调用填写参数。

int WINAPI WinMain(HINSTANCE hInstance,//操作系统使用此值来标识 EXE (加载到) 可执行文件。 某些函数需要实例句柄Windows例如,加载图标或位图。HINSTANCE hPrevInstance, //没有意义。 它用于 16 位Windows,但现在始终为零。LPSTR     lpCmdLine,//用于指定程序的命令行,是指向字符串的指针类型。int       nCmdShow//是一个标志,指示主应用程序窗口是最小化、最大化还是正常显示。
)
关键词解释
HINSTANCE程序实例句柄,用来标识唯一窗口。
PSTRCHAR*
WINAPIMicrosoft 定义的一种标准调用约定,主要用于 Windows API 函数

        在创建窗口之前,需要定义窗口结构体类WNDCLASS,并向Windows注册,它是Windows API 中用于定义窗口类的结构体

typedef struct tagWNDCLASS 
{UINT style;				//窗口的风格WNDPROC lpfnWndProc;	//指定窗口的消息处理函数的窗口过程函数int cbClsExtra :		//指定分配给窗口类结构之后的额外字节数int cbwndExtra;			//指定分配给窗口实例之后的额外字节数HINSTANCE hInstance :	//指定窗口过程所对应的实例句柄HICON hIcon;			//指定窗口的图标HCURSOR hCursor;		//指定窗口的鼠标指针HBRUSH hbrBackground;	//指定窗口的背景画刷LPCTSTR lpszMenuName;	//窗口的菜单资源名称LPCTSTR lpszClassName;	//该窗口类的名称
}WNDCLASS, * PWNDCLASS;
关键词解释
UINTunsigned int
WNDPROCWindows API 中定义窗口过程的函数指针类型。窗口过程是一个回调函数,用于处理与窗口相关的消息。
HBRUSH画刷句柄
HICON图标句柄
HCURSOR光标句柄
LPCTSTRchar* 长指针常量字符串

结构体填写完后,要向Windows系统去提交注册,成功返回true,失败返回false。

RegisterClass(&wndclass)

        由定义窗口结构体可得,需要一个消息处理函数WndProc,该函数也由Windows操作系统调用,但需要在定义窗口的结构体赋值。

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM IParam)
{HDC hdc; // 设备上下文句柄,用于绘制图形  PAINTSTRUCT ps; // 用于存储绘制信息的结构体  RECT rect; // 矩形结构体,用于定义绘制区域  switch (message) {case WM_CREATE: // 当窗口被创建时接收到的消息  PlaySound(TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC); // 播放声音文件 "hellowin.wav"  return 0; // 处理完毕,返回0  case WM_PAINT: // 当窗口需要重绘时接收到的消息  hdc = BeginPaint(hwnd, &ps); // 开始绘制,获取设备上下文  GetClientRect(hwnd, &rect); // 获取窗口客户区的矩形区域  DrawText(hdc, TEXT("大家好"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); // 在客户区绘制文本 "大家好",居中显示  EndPaint(hwnd, &ps); // 结束绘制  return 0; // 处理完毕,返回0  case WM_DESTROY: // 当窗口被销毁时接收到的消息  PostQuitMessage(0); // 发送退出消息,结束应用程序  return 0; // 处理完毕,返回0  }// 对于未处理的消息,调用默认窗口过程  return DefWindowProc(hwnd, message, wParam, IParam);
}
关键词解释
CALLBACK这是一个调用约定,指示该函数是一个回调函数。Windows 在需要时会调用这个函数。
WPARAM这是一个无符号整数,通常用于传递消息的附加信息。
HWND这是一个句柄,表示窗口的句柄。
LPARAM这是一个长整型,通常用于传递消息的附加信息,具体内容也取决于消息类型。

接着是创建窗口函数CreateWindow函数

HWND WINAPI CreateWindow(	//返回值是窗口句柄LPCTSTR lpClassName,		//窗口类名,要与注册时指定的名称相同LPCTSTR lpWindowName,		//窗口标题DWORD dwStyle,				//窗口样式int X,						//窗口最初的x位置int y,						//窗口最初的y位置int nWidth,					//窗口最初的x大小int nHeight,				//窗口最初的y大小HWND hWndParent,			//父窗口句柄HMENU hMenu,				//窗口菜单句柄HINSTANCE hInstance,		//应用程序实例句柄LPVOID lpParam				//指向一个传递给窗口的参数值的指针,以便后续在程序中加以引用
);
关键词解释
HWND句柄,它是窗口的唯一标识符
LPCTSTRchar* 长指针常量字符串
HMENU指向窗口菜单的唯一标识符
DWORD双字节32位无符号整数
LPVOID指向任何类型的指针,通常用于表示通用数据指针,允许函数接受不同类型的数据。

2、完整代码 

        总结来说,先编写一个入口函数WinMain,然后在入口函数里,进行窗口结构体的定义和注册,定义好了后进行创建窗口CreateWindow,只是创建并没有显示,使用ShowWindow和UpdateWindow显示并更新窗口,然后进行消息循环,GetMessage和DispatchMessage获取并分发消息到消息处理函数WndProc(自己编写,系统调用),这样一个简单的窗口程序便结束了,以下是完整代码。

#include<Windows.h>
#pragma comment(lib, "winmm")
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM IParam)
{HDC hdc; // 设备上下文句柄,用于绘制图形  PAINTSTRUCT ps; // 用于存储绘制信息的结构体  RECT rect; // 矩形结构体,用于定义绘制区域  switch (message) {case WM_CREATE: // 当窗口被创建时接收到的消息  PlaySound(TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC); // 播放声音文件 "hellowin.wav"  return 0; // 处理完毕,返回0  case WM_PAINT: // 当窗口需要重绘时接收到的消息  hdc = BeginPaint(hwnd, &ps); // 开始绘制,获取设备上下文  GetClientRect(hwnd, &rect); // 获取窗口客户区的矩形区域  DrawText(hdc, TEXT("大家好"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); // 在客户区绘制文本 "大家好",居中显示  EndPaint(hwnd, &ps); // 结束绘制  return 0; // 处理完毕,返回0  case WM_DESTROY: // 当窗口被销毁时接收到的消息  PostQuitMessage(0); // 发送退出消息,结束应用程序  return 0; // 处理完毕,返回0  }// 对于未处理的消息,调用默认窗口过程  return DefWindowProc(hwnd, message, wParam, IParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {// 定义应用程序名称  static TCHAR szAppName[] = TEXT("HelloWorld!");HWND hwnd; // 主窗口的句柄  MSG msg; // 消息结构,用于窗口消息  WNDCLASS wndclass; // 定义窗口类的结构  // 设置窗口类属性  wndclass.style = CS_HREDRAW | CS_VREDRAW; // 如果宽度或高度变化,则重绘窗口  wndclass.lpfnWndProc = WndProc; // 指向窗口过程函数的指针  wndclass.cbClsExtra = 0; // 不需要额外的类内存  wndclass.cbWndExtra = 0; // 不需要额外的窗口内存  wndclass.hInstance = hInstance; // 应用程序实例的句柄  wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 加载默认应用程序图标  wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); // 加载默认箭头光标  wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 设置背景画刷为白色  wndclass.lpszMenuName = NULL; // 此窗口没有菜单  wndclass.lpszClassName = szAppName; // 将类名设置为应用程序名称  // 注册窗口类  if (!RegisterClass(&wndclass)) {// 如果注册失败,显示错误消息  MessageBox(NULL, TEXT("此程序的 RegisterClass 出错!"), szAppName, MB_ICONERROR);return 0; // 退出程序  }// 创建主窗口  hwnd = CreateWindow(szAppName, // 类名  TEXT("Hello 程序"), // 窗口标题  WS_OVERLAPPEDWINDOW, // 窗口样式  CW_USEDEFAULT, // 默认水平位置  CW_USEDEFAULT, // 默认垂直位置  CW_USEDEFAULT, // 默认宽度  CW_USEDEFAULT, // 默认高度  NULL, // 没有父窗口  NULL, // 没有菜单  hInstance, // 应用程序实例的句柄  NULL); // 没有额外参数  // 显示窗口并更新它  ShowWindow(hwnd, iCmdShow);UpdateWindow(hwnd);// 消息循环以处理消息  while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg); // 将虚拟键消息转换为字符消息  DispatchMessage(&msg); // 将消息分发到窗口过程WndProc  }// 返回消息的 wParam 作为退出代码  return msg.wParam;
}


http://www.mrgr.cn/news/25496.html

相关文章:

  • 贪心算法day30|452. 用最少数量的箭引爆气球(排序+多重叠的处理)、435. 无重叠区间(去除哪个才是最优)、763. 划分字母区间(类阿斯克码换算)
  • 《JavaEE进阶》----16.<Mybatis简介、操作步骤、相关配置>
  • 大模型干货 | 如何使用Unsloth框架对Llama进行微调?
  • 小众创新组合!LightGBM+BO-Transformer-LSTM多变量回归交通流量预测(Matlab)
  • 将一个链表前后交替插入,得到一个新链表
  • 2. geoserver 发布postgis数据
  • 为工程师构建生成式 AI 应用程序
  • 如何在开发与生产环境中应用 Flask 进行数据库管理:以 SQLAlchemy 和 Flask-Migrate 为例
  • 大模型微调 - 训练参数
  • 一些硬件知识(二十三)
  • Typst快速入门教程
  • 用友U8-CRM-exportdictionarySQL注入
  • Pywinauto鼠标操作指南
  • iOS 18 RC 版本更新,为相机应用引入了“暂停录制视频”功能
  • 3分钟教你学会Java抽象类
  • 牛客思维题———进制(简单)
  • mp3转文字要怎么处理?使用这4个工具就对了
  • 机器学习:逻辑回归--过采样
  • 代码随想录day21|回溯法02
  • 5个AI绘画免费,支持Midjourney【亲测有效】