一、创建一个应用程序窗口

代码如下:

// 头文件
#include <windows.h> // 全局变量
WCHAR g_lpszClassName[] = L"CLASSNAME";
WCHAR g_lpszWindowName[] = L"哈喽,新的征程"; // 函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // 应用程序主函数
INT APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, INT nCmdShow)
{
// 1.设计一个窗口类
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WndProc;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = g_lpszClassName;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // 2.注册这个窗口类
if (RegisterClassEx(&wcex) == ((ATOM)0))
{
MessageBox(NULL, L"注册窗口类失败!", L"错误", MB_YESNO | MB_ICONERROR);
exit(-1);
} // 3.创建窗口
HWND hWnd = CreateWindowEx(NULL, g_lpszClassName, g_lpszWindowName, WS_OVERLAPPEDWINDOW, 10, 10, 800, 800, NULL, NULL, hInstance, NULL);
if (hWnd == NULL)
{
MessageBox(NULL, L"创建窗口失败!", L"错误", MB_YESNO | MB_ICONERROR);
exit(-1);
} // 4.更新和显示窗口
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd); // 5.应用程序消息循环
MSG msg = { 0 };
BOOL bRet;
// 调用 GetMessage 函数从调用线程的消息队列中取得一个消息
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet != -1)
{
TranslateMessage(&msg); // 将虚拟键消息转换为字符消息
DispatchMessage(&msg); // 将消息分发到窗口处理
}
} return msg.wParam;
} // 应用程序消息处理回调函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0); // 程序退出
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam); // 默认的窗口处理程序
}
return 0;
}

二、程序分析

1.首先设计一个窗口类。

不懂可以看我的这篇文章:Win32 程序开发:窗口类结构体 WNDCLASS 和 WNDCLASSEX ,此处就不多赘述了。

2.注册先前设计的窗口类。

调用 RegisterClassEx 函数注册窗口。函数原型:

// 返回值(ATOM,原子):成功返回注册的原子,失败返回 0。
ATOM WINAPI RegisterClassExW(_In_ CONST WNDCLASSEXW *); // 参数:为我们设计的窗口类

3.创建窗口。

调用 CreateWindowEx 函数创建窗口。函数原型:

// 返回值:创建成功返回创建的窗口句柄,失败返回NULL
HWND WINAPI CreateWindowExW(
_In_ DWORD dwExStyle, // 窗口扩展风格
_In_opt_ LPCWSTR lpClassName, // 我们注册的窗口类的名称
_In_opt_ LPCWSTR lpWindowName, // 窗口的名称(说白了就是窗口的标题)
_In_ DWORD dwStyle, // 窗口创建的风格(跟dwExStyle不同)
_In_ int X, // 窗口左上角的点位于屏幕的横坐标
_In_ int Y, // 窗口左上角的点位于屏幕的纵坐标
_In_ int nWidth, // 窗口的宽度
_In_ int nHeight, // 窗口的高度
_In_opt_ HWND hWndParent, // 窗口所有者的句柄
_In_opt_ HMENU hMenu, // 菜单句柄
_In_opt_ HINSTANCE hInstance, // 所在模块的实例句柄
_In_opt_ LPVOID lpParam); // 在WM_CREATE中进行传递的参数

4.更新和显示窗口。

调用 ShowWindow 函数显示窗口。函数原型:

// 返回值:成功返回非0,失败返回0
BOOL WINAPI ShowWindow(
_In_ HWND hWnd, // 显示的窗口句柄
_In_ int nCmdShow); // 窗口显示的方式(全屏,最大化窗口,最小化窗口,······)

调用 UpdateWindow 函数更新窗口。函数原型:

// 返回值:成功返回非0,失败返回0
BOOL WINAPI UpdateWindow(
_In_ HWND hWnd); // 更新的窗口

5.应用程序消息循环。

调用 GetMessage 函数从调用线程的消息队列中取得一个消息。函数原型:

// 返回值:获取错误返回-1,消息为WM_QUIT返回0,其他为非0
BOOL WINAPI GetMessageW(
_Out_ LPMSG lpMsg, // 接收从消息队列中获取的消息
_In_opt_ HWND hWnd, // 接收消息的窗口句柄
_In_ UINT wMsgFilterMin, // 指定被检测的最小消息值
_In_ UINT wMsgFilterMax); // 指定被检测的最大消息值

调用 TranslateMessage 函数将虚拟键消息转换为字符消息。函数原型:

// 返回值:成功返回非0,失败返回0
BOOL WINAPI TranslateMessage(
_In_ CONST MSG *lpMsg); // 接收的消息

调用 DispatchMessage 函数将消息分发到窗口处理。函数原型:

// 返回值:窗口处理过程的返回值
LRESULT WINAPI DispatchMessageW(
_In_ CONST MSG *lpMsg); // 分发的消息

示例中的使用:

while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet != -1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

while 循环的结束,当 GetMessage 获取到的消息为 WM_QUIT 窗口退出,则返回 0(false) 当 GetMessage 的返回值不为 -1(获取消息失败)的时候,进行虚拟键转换和分发消息。

6.窗口消息处理过程。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0); // 程序退出
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam); // 默认的窗口处理程序
} return 0;
}

参数:

  • hWnd:窗口处理过程的窗口句柄

  • message:消息ID

  • wParam:附加消息

  • lParam:附加消息

参考:

Win32 程序开发:创建一个应用程序窗口

Win32 程序开发:创建一个应用程序窗口的更多相关文章

  1. 微信小程序开发2-第一个小程序开发准备

    1.首先在官网上注册一个账号( https://mp.weixin.qq.com/ )申请一个AppID(类似于人的身份证,小程序也需要身份证) 注册过程不多说 2.安装开发工具( https://m ...

  2. [Ruby on Rails系列]3、初试Rails:使用Rails开发第一个Web程序

    本系列前两部分已经介绍了如何配置Ruby on Rails开发环境,现在终于进入正题啦! Part1.开发前的准备 本次的主要任务是开发第一个Rails程序.需要特别指出的是,本次我选用了一个(Paa ...

  3. SpringMVC基础入门,创建一个HelloWorld程序

    ref:http://www.admin10000.com/document/6436.html 一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要 ...

  4. 如何用java创建一个jdbc程序

    第一个jdbc程序 JDBC简介 Java数据库连接(Java Database Connectivity,JDBC),是一种用于执行SQL语句的Java API,它由一组用Java编程语言编写的类和 ...

  5. (4opencv)如何基于GOCW,创建一个实时视频程序

    直接使用提供的代码框架进行修改,是最快得到效果的方法:但是这样的灵活性较差,而且真正的程序员从来都不会停滞在这一步:我们需要的是"将框架解析到最小化.理清楚每个构建之间的关系",只 ...

  6. Django 创建一个应用程序

    1. 认识Django Django是一个高级的Python Web框架,它鼓励快速开发和清洁,务实的设计. 由经验丰富的开发人员构建,它负责Web开发的许多麻烦,因此您可以专注于编写应用程序,而无需 ...

  7. DevExpress XtraReports 入门六 控件以程序方式创建一个 交叉表 报表

    原文:DevExpress XtraReports 入门六 控件以程序方式创建一个 交叉表 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用的,为了帮助 ...

  8. 用java自带jdk开发第一个java程序

    [学习笔记] 1.用java自带jdk开发第一个java程序:   下面要讲的eclipse要想正常工作,需要先学会配置这里的jdk.jdk要想正常工作,需先学会配置JAVA_HOME和ClassPa ...

  9. eclipse3.62开发第一个java程序HelloWorld

    [学习笔记] 用eclipse3.62开发第一个java程序: 使用eclipse之前们需要先配置一下jdk.window/preference/java/installed JREs,详细请见视频. ...

随机推荐

  1. FCC---CSS Flexbox: Add Flex Superpowers to the Tweet Embed

    To the right is the tweet embed that will be used as the practical example. Some of the elements wou ...

  2. elasticsearch对无意义的词进行屏蔽——停用词

    介绍 在使用elasticsearch进行搜索业务的时候,发现一篇和搜索关键字完全不匹配的文章排在最前面.打开它发现原来是这篇文章含有非常多的"的"这个无意义的词.而我的搜索关键字 ...

  3. Excel 2003 与 Excel 2007之间有什么不同?

    如果您使用Excel 2003已有数年,您可能会意识到使用更多最新版本的Excel(2007.2010.2013或Excel 2016)的人员或组织的数量正在增加.您甚至可能收到了自己的Excel工作 ...

  4. JavaScript-----14.内置对象 Array()和String()

    5. 数组对象 5.1数组的创建 之前提到过数组的创建方式 字面量 new Array() //创建数组的两种方式 //1.利用数组字面量 var arr = [1, 2, 3]; console.l ...

  5. Java之String类

    String类概述 java.lang.String 类代表字符串.Java程序中所有的字符串文字(例如 "abc" )都可以被看作是实现此类的实例.其实就是说:程序当中所有的双引 ...

  6. 剑指Offer-45.扑克牌顺子(C++/Java)

    题目: LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定 ...

  7. SpringCloud gateway (史上最全)

    疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之 -25[ 博客园 总入口 ] 前言 ### 前言 疯狂创客圈(笔者尼恩创建的高并发研习社群)Springcloud 高并发系列文章,将为大家 ...

  8. 如何编写高质量的 JS 函数(4) --函数式编程[实战篇]

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/ZoXYbjuezOWgNyJKmSQmTw作者:杨昆 [编写高质量函数系列],往期精彩内容: ...

  9. 深度学习VGG16模型核心模块拆解

    原文连接:https://blog.csdn.net/qq_40027052/article/details/79015827 注:这篇文章是上面连接作者的文章.在此仅作学习记录作用. 如今深度学习发 ...

  10. python __iter__和__getitem__区别

    __getitem__ 单独实现这个魔法函数,可以让这个类成为一个可迭代的对象,并且可以通过使用下标获取类中元素值下标的元素 class Library(object): def __init__(s ...