SP:创建Windows应用程序的要点详解

主要是对前面几个部分知识内容的一些总结并进行详细的分析

主函数入口点

在 main.cpp 中需要做得第一件事是包含 Win32 程序所需的头文件和定义函数入口点。 需要注意的是, Win32窗体应用程序的主函数入口点是 WinMain 函数(控制台程序的入口点是 main 函数)。 对于现在来说,我们只需要在源文件的顶部包含 windows.h 头文件即可。 源文件 main.cpp 的头文件和空的 WinMain 函数见于以下程序:

#include<Windows.h>
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmdLine, int cmdShow)
{
return 0;
}

使用 wWinMain 代替 WinMain。这两个主函数的不同在于 wWinMain 的第三个参数cmdLine 使用 Unicode 编码,而另一个使用 ANSI 编码将会转换 Unicode 为 ANSI。 因此将导致 Unicode 字符串中的字符丢失,而使用 wWinMain 则允许我们正确处理传入应用程序的 Unicode 参数。

(w)WinMain 函数有四个参数,其定义如下:

HINSTANCE hInstance: 应用程序当前实例的句柄(译者注:了解 Win32 的基本知识最好是看 Windows 程序

设计第五版)。

HINSTANCE prevInstance:应用程序的前一个实例的句柄。 根据 MSDN 的文档现在此参数将一直是 NULL。虽然此参数一直是 NULL,如果你想要确定该应用程序是否已经有实例在运行,文档推荐使用 CreateMutex函数来创建唯一名字的 mutex(互斥体)。 当已经有实例运行时,再次创建 mutex, CreateMutex 函数将会返回 ERROR_ALREADY_EXISTS。

LPSTR cmdLine :(或使用 Unicode 编码的 LPWSTR):应用程序的命令行由程序外部输入。允许你传递命令给程序,例如通过 cmd 命令终端,或者是通过快捷方式提供命令参数,等等。

int cmdShow:窗口被显示为哪个模式的 ID 号(译者注:例如最小化,正常,最大化等)。

窗口初始化

尽管上述程序能够编译运行,可是由于没有创建窗口,运行时什么也没显示。 So,下一个步骤就是创建 Win32窗口。 首先要注册一个窗口类并且创建窗口本身。 应用程序必须在系统中注册它的窗口

程序循环就是一个无限的循环,直到用户跳出该循环为止。 由接受 WM_QUIT 事件(Win32 的退出消息)来发生结束指令, 假如在主菜单中设定了用户按下 Esc 键产生该事件(当游戏中时,按下 Esc 键并没有退出,而是暂停,除非是制作者设计了该退出方式),或者你设定它退出的任何其他方式。

MSG 是一个用于持有来自于操作系统中 window 消息的 Win32 结构,它用于程序响应这些消息。如果发送一定数量的消息后程序一直没有响应,则操作系统将会报告该程序未响应。 通常我们假定它的意思就是程序被冻结或者发生了某些错误,这也意味着应用程序没有从操作系统中恢复过来。 如果程序被设计为响应式的,假设程序已经被冻结即窗口显示“未响应”消息或任务管理器显示该应用未响应,过一会儿它仍然是安全的。我就曾经多次运行十分复杂并且长时间查询在网络上的微软 Access。操作系统就报告程序未响应,尽管程序只是忙于做一些任务没有处理事件而已。

对于 window 消息,我们需要做两件事。首先需要取得新的消息并且处理它们,其次需要调度(响应)这些消息。PeekMessage 函数取得相关窗口的消息(我们使用 CreateWindow 函数创建的窗口)。此函数的第一个参数是持有消息的结构的地址,其次是窗口句柄(可选),最小最大消息过滤标志,移除标志。PM_REMOVE 移除标志,将会将消息从它的队列中移除。因为我们处理该消息,一旦处理后它将不需要留在队列中。如果有消息被 PeekMessage 函数获得,我们调用 TranslateMessage 函数和 DispatchMessage 函数来响应该消息。Win32 函数 TranslateMessage 将虚拟键消息翻译为字符消息,调度函数 DispatchMessage 将消息传给窗口过程处理,窗口过程将对于它所接受到的消息执行实际的行动。如果没有收到消息,在程序中就只做更新 Update 和渲染 rendering 这两件事。例如根据所侦测到的用户输入,物理计算,动画,更新音频缓存等的更新操作和渲染场景几何体。

拿大家熟悉的视频游戏举个例子,查看游戏循环就一目了然了。游戏程序对于每一帧的渲染做一系列的具体事情。游戏中的帧是游戏循环的单一的反复过程。大多数游戏力求达到每秒 30 或 60 帧,换句话说就是相对于真实世界中的每一秒钟,游戏做 30 到 60 次的循环。当游戏变得越来越复杂时,这一目标更难达到。 每秒的帧数通常用来衡量游戏渲染的速度,但是游戏不仅仅有渲染代码,还需要每数帧就处理游戏中的物理,碰撞, AI(人工智能) 数据流和游戏的特效。

窗口过程(回调函数)

在我们能够编译和运行我们的程序之前的最后一部分就是所提供的窗口过程,也就是窗口过程函数。窗口过程函数是回调函数,意味着在我们的程序中当获得消息后就调用该函数来处理。回调函数一般写成下面的形式:

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; }

窗口过程函数返回 LRESULT 类型并且有回调 CALLBACK 修饰。 此函数的命名遵循普通函数命名标准该回调函数接受参数窗口的句柄来调度该窗口的消息,无符号整型消息代号,两个可携带额外信息的参数(wParam 和 lParam) 。最后两个参数用于补充的数据,在回调函数中处理消息需要更多的数据时。

退出消息由调用 Win32 函数 PostQuitMessage 来处理,这将导致在应用程序循环中的 MSG 对象取得 WM_QUIT消息,然后就按照我们的设定结束应用程序循环并且退出程序。 假如想退出而又不立即退出的话,只需要发送一个退出消息即可。 例如,在微软的 Word 软件中如果没有保存就尝试退出的话,将会弹出一个对话框询问你是否保存之后再退出。

回调函数的最后一部分就是调用 DefWindowProc 函数,它有着与窗口过程函数同样的参数。 这个函数只被那些我们没有写自定义响应代码的消息所调用。 在此 Demo 中我们只响应了绘制消息和退出消息,但是还有其他大量的可以查到的消息,如按键,鼠标点击,鼠标移动,计时器等等。 DefWindowProc 函数是一个 Win32 函数,它调用默认行为处理所有的消息,来确保我们响应每一个消息,即使我们对那些消息不感兴趣。

时间: 2024-10-05 12:50:28

SP:创建Windows应用程序的要点详解的相关文章

Linux用户态程序计时方式详解

前言 良好的计时器可帮助程序开发人员确定程序的性能瓶颈,或对不同算法进行性能比较.但要精确测量程序的运行时间并不容易,因为进程切换.中断.共享的多用户.网络流量.高速缓存访问及转移预测等因素都会对程序计时产生影响. 本文将不考虑这些影响因素(相关资料可参考<深入理解计算机系统>一书),而仅仅关注Linux系统中用户态程序执行时间的计算方式.除本文所述计时方式外,还可借助外部工具统计耗时,如<Linux调试分析诊断利器——strace>一文中介绍的strace. 本文示例代码的运行环

windows API中CreateWindow()函数详解

CreateWindow函数详解 在注册完窗口类后就需要进行窗口的创建,用到的函数理所当然就是CreateWindow(), 而这个函数是基于窗口类的,所以还需要指定几个参数来制定特定的窗口.而且像一些不带边框的窗口是怎么创建的也是具有相当的技巧的,就是创建的是不带标题和边框的窗口,然后自己在客户区绘制程序的内容,能够制作个性化的应用程序. API解释 该函数创建一个重叠式窗口.弹出式窗口或子窗口.它指定窗口类,窗口标题,窗口风格,以及窗口的初始位置及大小(可选的).函数也指该窗口的父窗口或所属

windows批处理(cmd/bat)编程详解

reference: http://blog.csdn.net/bingjie1217/article/details/12947327 http://www.cnblogs.com/doit8791/archive/2012/05/20/2511001.html 开始之前先简单说明下cmd文件和bat文件的区别:在本质上两者没有区别,都是简单的文本编码方式,都可以用记事本创建.编辑和查看.两者所用的命令行代码也是共用的,只是cmd文件中允许使用的命令要比bat文件多.cmd文件只有在windo

boost asio异步读写网络聊天程序客户端 实例详解

// // chat_client.cpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://ww

windows下eclipse调试hadoop详解

1)下载Eclipse http://www.eclipse.org/downloads/ Eclipse Standard 4.3.2 64位 2) 下载hadoop版本对应的eclipse插件 我的hadoop是1.0.4,因此下载hadoop-eclipse-plugin-1.0.4.jar 下载地址:http://download.csdn.net/detail/m_star_jy_sy/7376169 3)安装hadoop插件 将hadoop-eclipse-plugin-1.0.4.

Android Widget 开发实例:桌面便签程序的实现详解和源码

桌面便签软件是Android上常用软件的一种,比如比较早的Sticky Note,就曾非常流行,而实际上使用android平台对widget开发的支持,桌面便签类软件是非常易于开发的. 本文通过逐步实现一个简单的桌面便签软件,和大家分享进行widget开发的过程和方法. 同时本程序提供完整的工程源码下载 免费下载地址在 http://linux.linuxidc.com/ 用户名与密码都是www.linuxidc.com 具体下载目录在 /pub/Android源码集锦/2011年/10月/An

Windows Nano Server安装配置详解05:在虚拟机中部署NanoServer

1.将 NanoServerImageGenerator 文件夹从 Windows Server 2016 ISO 中 \NanoServer 文件夹复制到你硬盘上的文件夹. 拷贝到C盘根目录. 2.以管理员身份启动 Windows PowerShell,将目录更改为 NanoServerImageGenerator 文件夹所在的文件夹,然后导入模块,其方法为 Import-Module .\NanoServerImageGenerator -Verbose 3.通过运行以下命令(将提示你输入新

Oracle创建表语句(Create table)语法详解及示例

Oracle创建表语句(Create table)语法详解及示例   创建表(Create table)语法详解1. ORACLE常用的字段类型ORACLE常用的字段类型有VARCHAR2 (size) 可变长度的字符串, 必须规定长度CHAR(size) 固定长度的字符串, 不规定长度默认值为1NUMBER(p,s) 数字型p是位数总长度, s是小数的长度, 可存负数最长38位. 不够位时会四舍五入.DATE 日期和时间类型LOB 超长字符, 最大可达4GCLOB 超长文本字符串BLOB 超长

Oracle 10g创建表空间的完整步骤详解

本文我们主要介绍了Oracle 10g创建表空间的完整步骤,包括表空间的创建与删除.为应用创建用户以及权限的授予等操作,希望能够对您有所帮助. AD:WOT2014:用户标签系统与用户数据化运营培训专场 Oracle 10g数据库中,当在数据库中创建用户时,基于应用性能和管理方面的考虑,最好为不同的用户创建独立的表空间. 那么创建表空间的步骤是怎样实现的呢?本文我们主要就介绍了这一部分内容,接下来就让我们一起来了解一下这部分内容吧. 1.创建表空间 不论是Lnux环境,还是Wndows环境,都要