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

创建你的第一个Windows程序

第一个 Windows 程序

* 纯净版

#include<Windows.h>int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int iShowCmd
)
{MessageBox(NULL, TEXT("Hello, Windows!"), TEXT("HelloMsg"), 1);return 0;
}

* 注释版

#include<Windows.h>int WINAPI WinMain(HINSTANCE hInstance,		// 当前实例的句柄,唯一标识了我们这个程序(在Windows程序中,句柄就是一个数值,用来标识某个东西)HINSTANCE hPrevInstance,	// 前一个实例的句柄(在Win32中,此概念已弃用,因此该参数总是NULL)LPSTR lpCmdLine,			// 命令行参数int iShowCmd				// 指明程序最初如何显示(正常显示、最大化到全屏、最小化到任务栏)
)
{MessageBox(					// 函数作用:弹出一个小窗口,主要用来显示一些短消息NULL,					// 窗口句柄,唯一标识这个窗口TEXT("Hello, Windows!"),// 要在信息框里面出现的文本字符串TEXT("HelloMsg"),		// 要在标题栏上显示的文本字符串1						// 选择按钮的类型);return 0;
}/*
Windows API 中"类型"的命名规则:HINSTANCE: H + INSTANCE == handle + instance == 实例句柄LPSTR: L + P + STR == long + pointer + str == 长字符指针i == intsz == 以零结尾的字符串c == const == 常量s == static == 静态*/

编码问题

  • 早期 Windows 使用 ASCII 进行编码,对于美国自己来用,基本上足够了

  • 随着计算机的发展,世界各国都想要自己的文字能够在计算机上表示

  • 为了统一世界各国的字符编码问题,Unicode 诞生了

  • 它是通过增加位的方式来扩充,由原来的7位,变成现在的16位(方案不同,会有所出入,但只会更多,不会更少)

  • 可容纳的符号,由原来的27=128,变成现在的216=65536(方案不同,会有所出入,但只会更多,不会更少)

  • 使用 Unicode 也有缺点:就是用 Unicode 写的字符占用的空间,会比用 ASCII 写的字符所占用的空间大2倍

  • 为此,人们希望最好能够创建两个版本的程序,让不同需求的人,拿最适合自己的那一个版本即可

  • 于是,有了以下的设计:

使用 TCHAR.H 头文件,这个头文件提供了一系列的类型或函数的替代名称

一个命名为 _UNICODE 的标识符被定义了,在生成代码时

TCHAR 就自动变成 wchar_t_tprintf 就自动变成 wprintf(w:width)

一个名为 _UNICODE 的标识符没有被定义,在生成代码时

TCHAR 就自动变成 char_tprintf 就自动变成 printf

同样的道理,对于字符串而言,使用 _T("hello world")_TEXT("hello world") 也能自动变化

#include<Windows.h>
#include<tchar.h>int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{MessageBox(NULL, _T("你好,窗口!"), _T("信息窗口"), 0);return 0;
}

创建窗口

运行代码的时候:

  • 打开项目属性。
  • 导航到“链接器”>“输入”>“附加依赖项”。
  • 在“附加依赖项”字段中添加 winmm.lib(如果列表中还没有的话)

* 纯净版

#include<Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow
)
{static TCHAR szAppName[] = TEXT("HelloWin");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_APPSTARTING);wndclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);wndclass.lpszMenuName	= NULL;wndclass.lpszClassName	= szAppName;if (!RegisterClass(&wndclass)){MessageBox(NULL, TEXT("This program requires Windwos!"), szAppName, MB_ICONERROR);return 0;}hwnd = CreateWindow(szAppName,TEXT("The Hello Program"),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);}return msg.wParam;
}LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{HDC hdc;PAINTSTRUCT ps;RECT rect;switch (message){case WM_CREATE:PlaySound(TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC);return 0;case WM_PAINT:hdc = BeginPaint(hwnd, &ps);GetClientRect(hwnd, &rect);DrawText(hdc, TEXT("Hello, Windows!"), -1, &rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER);EndPaint(hwnd, &ps);return 0;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProc(hwnd, message, wParam, lParam);
}

* 注释版

#include<Windows.h>/* ------------------------------------------------------------------要创建窗口,首先需要注册一个窗口类,而窗口类又需要"窗口过程"来处理窗口消息名词解释:窗口过程,是一个函数,用于处理发送到类的所有窗口或发布到所有窗口的所有消息窗口过程是给 Windows 回调用的,它必须遵循规定的格式对窗口过程的子程序名并没有规定,对 Windows 来说,窗口过程的地址才是惟一需要的
------------------------------------------------------------------ */// 声明"窗口过程"(窗口处理函数),用于处理窗口消息
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  // 窗口过程的名字,是可以自定义命名的// Windows 程序的入口点
int WINAPI WinMain(HINSTANCE hInstance,		// 当前实例的句柄HINSTANCE hPrevInstance,	// 前一个实例的句柄(在Win32中,此参数总是NULL)PSTR szCmdLine,				// 命令行参数int iCmdShow				// 控制窗口如何显示
)
{static TCHAR szAppName[] = TEXT("HelloWin");	// 窗口类名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_APPSTARTING);	// 加载默认光标wndclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);	// 背景画刷wndclass.lpszMenuName	= NULL;									// 菜单名(这里没有使用)wndclass.lpszClassName	= szAppName;							// 窗口类名// 注册窗口类if (!RegisterClass(&wndclass)){MessageBox(NULL,TEXT("This program requires Windwos!"),szAppName,MB_ICONERROR);return 0;}// 创建窗口hwnd = CreateWindow(szAppName,					// 窗口类名TEXT("The Hello Program"),	// 窗口标题WS_OVERLAPPEDWINDOW,		// 窗口风格CW_USEDEFAULT,				// x坐标(使用默认值)CW_USEDEFAULT,				// y坐标(使用默认值)CW_USEDEFAULT,				// 宽度(使用默认值)CW_USEDEFAULT,				// 高度(使用默认值)NULL,						// 父窗口句柄(无父窗口)NULL,						// 菜单句柄(无菜单)hInstance,					// 应用实例句柄NULL						// 创建参数(这里不使用));// 显示并更新窗口ShowWindow(hwnd, iCmdShow);UpdateWindow(hwnd);// 消息循环while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);		// 翻译消息(如键盘消息到字符消息)DispatchMessage(&msg);		// 分发消息到窗口过程(窗口处理函数)}return msg.wParam;
}// 实现窗口过程(窗口处理函数)
LRESULT CALLBACK WndProc(HWND hwnd,			// 窗口句柄UINT message,		// 消息IDWPARAM wParam,		// 消息参数(对于某些消息,它表示特定的信息)LPARAM lParam		// 消息参数(对于某些消息,它通常是一个指向结构体的指针)
)
{HDC hdc;			// 设备上下文句柄,用于绘图操作PAINTSTRUCT ps;		// 绘图结构体,用于 BeginPaint 和 EndPaint 函数RECT rect;			// 矩形区域,用于描述窗口的绘图区域switch (message){case WM_CREATE:						// 窗口创建消息PlaySound(						// 播放声音文件TEXT("hellowin.wav"),		// 声音文件的路径NULL,SND_FILENAME | SND_ASYNC	// SND_FILENAME表示通过文件名播放声音,SND_ASYNC表示异步播放(不阻塞程序));return 0;case WM_PAINT:						// 窗口绘图消息hdc = BeginPaint(hwnd, &ps);	// 开始绘图GetClientRect(hwnd, &rect);		// 获取窗口客户区大小DrawText(hdc,TEXT("Hello, Windows!"),	// TEXT("Hello, Windows!"): 要绘制的文本字符串-1,							// -1: 字符串中的字符数。如果为-1,则函数会自动计算字符串长度 &rect,						// &rect: RECT结构体的指针,指定文本绘制的区域。文本将在这个矩形区域内被格式化DT_SINGLELINE | DT_CENTER | DT_VCENTER// DT_SINGLELINE | DT_CENTER | DT_VCENTER: 文本绘制选项// DT_SINGLELINE 表示文本将被格式化为单行// DT_CENTER 表示文本将在指定的矩形区域内水平居中// DT_VCENTER 表示文本将在指定的矩形区域内垂直居中);EndPaint(hwnd, &ps);			// 结束绘图return 0;case WM_DESTROY:					// 窗口销毁消息PostQuitMessage(0);				// 发出退出消息到消息队列return 0;}// 如果消息没有被窗口过程(WndProc)显式处理,则调用默认的窗口处理函数(DefWindowProc)来处理它return DefWindowProc(hwnd,		// hwnd: 窗口句柄,表示哪个窗口接收到了消息message,	// message: 消息ID,标识了要处理的消息类型wParam,		// wParam: 消息的参数之一,它的具体含义取决于消息类型lParam		// lParam: 消息的参数之二,它的具体含义也取决于消息类型);
}

常见的标识符前缀

前缀常量
CS类风格选项
CW创建窗口选项
DT文本绘制选项
IDI图标的 ID 号
IDC光标的 ID 号
MB消息框选项
SND声音选项
WM窗口消息
WS窗口风格

常用的变量名前缀

前缀数据类型
cchar 或 WCHAR 或 TCHAR
byBYTE(无符号字符)
nshort
iint
x, yint, 表示 x 坐标和 y 坐标
cx, cyint, 表示 x 或 y 的长度,c 表示 count (计数)
B 或 fBOOL(int); f 表示 flag
wWORD(无符号短整型)
lLONG(长整型)
dwDWORD(无符号长整型)
fn函数
s字符串
sz以零结束的字符串
h句柄
p指针

相关文章:

  • Github 2024-06-10开源项目周报 Top15
  • 【区分】累次极限与二重极限
  • 机器学习中的神经网络重难点!纯干货(上篇)
  • 神经网络开发
  • 【Ardiuno】实验使用ESP32单片机实现高级web服务器暂时动态图表功能(图文)
  • 计算机组成原理之定点除法
  • Android 14 蓝牙主从模式切换
  • profile-3d-contrib,github三维立体图的使用
  • JDK17 你的下一个白月光
  • Docker部署Nginx下载站点服务
  • UML与设计模式
  • sourcemap
  • vue2 + echats macarons 选中样式的树状图
  • C++移动语义
  • 基于单片机的多功能智能小车设计
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • js继承的实现方法
  • Leetcode 27 Remove Element
  • V4L2视频输入框架概述
  • Vue全家桶实现一个Web App
  • 编写符合Python风格的对象
  • 记一次删除Git记录中的大文件的过程
  • 两列自适应布局方案整理
  • 十年未变!安全,谁之责?(下)
  • 使用 @font-face
  • 微信小程序实战练习(仿五洲到家微信版)
  • 协程
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 正则表达式小结
  • ​linux启动进程的方式
  • #07【面试问题整理】嵌入式软件工程师
  • #etcd#安装时出错
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • #在 README.md 中生成项目目录结构
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)Linq学习笔记
  • (转)甲方乙方——赵民谈找工作
  • (转载)OpenStack Hacker养成指南
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .net 调用php,php 调用.net com组件 --
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • .NET企业级应用架构设计系列之技术选型
  • .net网站发布-允许更新此预编译站点
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • /usr/lib/mysql/plugin权限_给数据库增加密码策略遇到的权限问题
  • @GetMapping和@RequestMapping的区别
  • @RequestMapping处理请求异常