博文
《白手起家Win32SDK应用程序》第八篇 关闭窗口的同时退出程序(2005-11-08 17:31:00)
摘要:第8篇 关闭窗口的同时退出程序
白云小飞
还记得上篇中最后说到一个问题吗?当我们关闭程序窗口时,窗口确实是关闭了,可是程序并没有退出啊。为什么呢???
一. 理解程序的退出条件:
首先,我们要先明白程序退出的条件,看上篇中的这段代码:
while(GetMessage(&msg, NULL, 0, 0)) //获取一个消息,成功后会放在msg中。
{
TranslateMessage(&msg); //消息进行必要的预处理转换。
DispatchMessage(&msg); //调用WinProc回调函数,将msg传递给WinProc函数
}
如果程序一直在这个消息循环中,程序就没能退出。只有当GetMessage收到一个WM_QUIT的消息,则返回值才会为零,退出循环,程序得以结束。(这个道理应该好理解吧?)
二. 点关闭按钮时,发生了什么
当我们点窗口右上角的关闭按钮时,到底发生了什么事呢?(请边看源代码,边体会下面的分析噢!)
第一. 它并没有(或最终没有导致)发出WM_QUIT的消息。因此GetMessage函数不会收到WM_QUIT消息,就没法跳出循环了。(那么又产生了什么消息呢?)
第二. 点关闭按钮时,产生WM_CLOSE的消息。GetMessage会收到WM_CLOSE消息的MSG结构信息。
第三. ......
《Win32SDK应用程序》第七篇 获取消息及对消息缺省处理(2005-11-08 17:29:00)
摘要:
第7篇 获取消息及对消息缺省处理
白云小飞
一 重提上篇的问题:
还记得在上一篇的最后,经过调试后我们发现的问题吗?
1. 窗口不能自动被激活(即成为当前窗口)。只有最小化其它应用程序的窗口后,才能看到我们的这个窗口。(注意:在ShowWindow(hWnd, ncmdshow);函数中ncmdshow值我说过是SW_SHOWNORMAL值,应该会将窗口激活才对啊!)
2. 无法进行调整窗口大小,移动窗口位置等等的所有对窗口的操作。
你认为是什么原因呢?
二 且听我说:
1. ShowWindow(hWnd, SW_SHOWNORMAL)函数作用虽然是显示窗口并激活窗口。它确实完成了窗口的显示,但是,它并没有去激活窗口,只是发了一系列与激活窗口有关的消息,这才是ShowWindow(…)函数所做的事。(那又由谁来激活呢?)
2. 真正激活窗口的任务是由DefWindowProc( )完成的。哦,也就是说我们得让DefWindowProc( )收到ShowWindow( )产生的消息并根据消息来执行相应任务。
3. 但ShowWindow( )产生的消息只是加入到该线程的消息队列中,并没有自动地去调用WinProc( )的回调函数对消息处理。因此,DefWindowProc( )也就没被调用,自然地就没法激活窗口了。(请边看代码边分析我的这段话吧!呵呵,你得有点想像力了!)
4. 哦,这不由地让我想起前面的创建窗口函数CreateWindowEx( ) 。这两个函数在执行中都会产生若干的消息。但CreateWindowEx会自动地调用了WinProc( ) 函数,而ShowWindow( )没有这样。
5. 同理,......
《Win32SDK应用程序》第六篇 显示你所创建的窗口(2005-11-08 17:28:00)
摘要:第六篇 显示你所创建的窗口
白云小飞
哈!到了显示窗口的时候啦!
看,下面这个函数就是用来显示窗口的:
BOOL ShowWindow( HWND hWnd, int nCmdShow);
一 ShowWindow函数的参数及返回值
hWnd就是你要显示的窗口的句柄:
nCmdShow是窗口的显示方式,其可能的值如下:
SW_HIDE 隐藏应用程序窗口
SW_SHOWNORMAL 激活并显示窗口,如果窗口被最大化或最不化,系统恢复窗口到原始大小和位置(与SW_RESTORE)
SW_RESTORE 同SW_SHOWNORMAL
SW_NORMAL
SW_SHOWMINIMIZED 激活并最小化窗口
SW_SHOWMAXIMIZED 激活并最大化窗口
SW_SHOW 激活窗口,并按其当前大小和位置显示
SW_MAXINIZE 最大化应用程序窗口
SW_MINIMIZE 最不化应用程序窗口
SW_SHOWNOACTIVATE 按最近大小和位置显示窗口,但不改变激活特性
SW_SHOWMINNOACTIVE 最小化窗口,但不改变其激活特性
SW_SHOWNA ......
《Win32SDK应用程序》第五篇 利用已注册的窗口类来创建一个窗口 (2005-10-22 21:00:00)
摘要:第五篇 利用已注册的窗口类来创建一个窗口
白云小飞
一 用CreateWindowEx函数来创建窗口
上篇中我们完成了向Windows系统进行窗口的“申请”工作(即注册一个窗口类)。本篇就是要用这个窗口类来创建一个窗口。
下面这个API函数就是专门用来创建一个窗口的:
HWND WINAPI CreateWindowEx(
DWORD dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
DWORD dwStyle,
&nbs......
《Win32SDK应用程序》第四篇 注册一个窗口类(2005-10-20 22:16:00)
摘要:第四篇 注册一个窗口类
白云小飞
一 创建并显示一个窗口的“遐想”。
? 首先,要显示的窗口在哪里呢?
要想显示你自己的窗口,显然你得事先创建一个自己的窗口。当你想要一个窗口时,Window系统才会为你创建窗口。不要时,Window再销毁这个窗口。噢,这是多么相当然的一种机制啊,你说是吧!也就是说我们得先创建一个窗口才能显示。(否则哪里来的窗口给你显示呢?)
? 其次,你想创建什么样的窗口呢?
那么,创建什么样的窗口呢?创建前,Window系统可不知道你要的是什么类型的窗口啊(比如标题栏上显示什么图标,鼠标形状是什么,窗口背景颜色等等)。这些类型信息应在你创建前事先告诉Window系统。可以采用这种方法:就是我们事先写一份要创建窗口的类型申请表,提交(注册)给Window系统。然后在创建时,可以让Windows按这个申请表来创建你所要的窗口了。也就是说我们还应该先提交一个申请表,申请成功后再根据这个表创建一个窗口。
依据上述的理由,我假想了以下几个步骤要做:
第一. 你得先填写一份你想创建的窗口类的“申请表”。
第二. 然后将这“申请表”通过一个API函数提交给Windows系统(即注册到Windows系统中)。
第三. 如果提交(注册)成功,就说明Window系统通过了你的“申请表”,Windows系统中就有了一份你所申请的窗口类(注:这个注册成功的已经注册在系统中的“申请表”我们称之为窗口类)。这样你就可以利用这个申请成功的窗口类,通过一个专门的API函数让Windows系统创建一个或多个的同一窗口类的窗口。
第四. 创建成功后,我们有了窗口。但是,虽然窗口已存在在内存中,并不一定就马上显示在屏幕上(这根据你的意愿了),所以之后的某时你可以用一个API函数来让Windows系统显示刚才创建的窗口。
Window系统就是这样设计的噢!(呵呵,这样设计不算坏,我可以接受。)
......
《Win32SDK应用程序》第一篇 预备知识(2005-10-16 12:58:00)
摘要:第一篇 预备知识
白云小飞
1 说在前面
由于VC6及MFC的特点,我们许多人从标准C++学习到VC6MFC应用程序的编程学习的过度会有一个很大的夸跃,从而感到非常的吃力。
究其原因之一:MFC类库设计虽然精巧,但我们在使用MFC设计程序时,会发现MFC到处是API函数的影子。MFC并没有象Delphi的VCL类库,VB的控件库一样封装得让人几乎完全不用知道还有Win32API函数及其操作原理,所以要想利用VC6的MFC编程,我认为就一定要先学习如何直接用Win32API函数来编程。对API编程中的一些关键的概念和原理要有一定认识,这样才会有一个比较平滑的过渡。以上就是我写这个系列的初衷。
2 我假设你已有的知识:
这里我假设你已经掌握了如下的知识,如果你在如下方面知识有点不太清楚,那要去补一补罗,否则你看到相关的内容时会有麻烦的。
下面说是我对你知识的假设:
2.1 Windows系统的文件、文件夹、路径的概念
2.2 C语言的基本知识(基本以等级考试二级C语言为准,还要有所扩充)
2.2.1 指针的概念。
2.2.2 函数指针概念。
2.2.3 各种自定义类型(最重要的是struct类型)的概念。
2.2.4 要知道函数的各种参数传递形式(值、地址、引用传递)。
2.2.5 typedef及其应用。
2.2.6 #include及其应用。
2.2.7 十进制、二进制、十六进制。
2.2.8 按位与、或、非运算的......
《Win32SDK应用程序》第二篇 创建Win32工程和主函数(2005-10-16 12:57:00)
摘要:第二篇 创建Win32工程和主函数
白云小飞
1 在D:\创建一个空的工程(工程名为MyApp)
要编写一个程序,我们就要首先用VC6应用程序向导创建一个工程,下面我将给你创建一个空工程(也就是没有任何源文件及代码的工程)
1.1 操作:
=>文件->新建…->”工程”标签->位置:”D:\”(你可以设置你想要创建的位置)->工程名:MyApp(你可以自己指定其它名)->选择”创建新的工作空间”->确定->一个空工程->完成
1.2 请查看指定位置下生成的文件:打开D:\MyApp
我们发现,它在D:\下生成了一个MyApp文件夹。
并在MyApp文件夹下生成了几个文件,如下:
MyApp.dsp
MyApp.dsw
MyApp.ncb
MyApp.opt
其中,MyApp.dsp是项目文件和MyApp.dsw是工作区文件,它们是不能删除。
项目文件的作用:生成一个EXE或DLL程序的所有相关源文件、有头文件的位置信息都记录在MyApp.dsp项目文件中。
工作区文件的作用:如果一个复杂的软件工程可能是由多个EXE和多个DLL程序组成,这样每个项目文件的位置信息又记录在MyApp.dsw工作区文件中。
当然,我们的这个工程只有一个EXE程序,所以只有一个项目,这个项目文件MyApp.dsp也同样要记录在MyApp.dsw中了。
MyApp.ncb和M......
《Win32SDK应用程序》第三篇 增加一个回调函数(2005-10-16 12:56:00)
摘要:第三篇 增加一个回调函数
白云小飞
1 请再创建一个函数。
LRESULT CALLBACK WinProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
//这里可以输入响应消息的代码
return 0;
}
此函数人称回调函数也称自定义窗口过程函数。但其实它与我们一般函数无异,你千万不要把这个函数想得太复杂了啊!
记住,函数名WinProc及各参数变量名是可以由你来指定,但是参数类型、个数、顺序、及返回值类型是不能改变的。
那么,这个函数是干什么的啊?
它是一个用来与某窗口关联的函数。当我们在窗口上的每一个操作,都会调用这个函数。这在个函数里,我们可以写上代码来完成我们在窗口上操作的相应功能。
先来看参数部分:
UINT msg :UINT类型不是我们在前面也见过吗?就是unsigned int类型了。每次程序运行时用户在窗口上操作所产生的消息都会通过msg传递进来。msg里保存的值就是我们对窗口操作时产生的消息值(即WM_CLOSE、WM_CHAR、WM_COMMAND......