windows_sdk编程系列文章02_----_简单窗口程序.pdf
《windows_sdk编程系列文章02_----_简单窗口程序.pdf》由会员分享,可在线阅读,更多相关《windows_sdk编程系列文章02_----_简单窗口程序.pdf(11页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、windows sdk 编程系列文章-简单窗口程序 2008-04-08 06:37 理论:Windows 程序中,在写图形用户界面时需要调用大量的标准 Windows Gui 函数。其实这对用户和程序员来说都有好处,对于用户,面对的是同一套标准的窗口,对这些窗口的操作都是一样的,所以使用不同的应用程序时无须重新学习操作。对程序员来说,这些 Gui 源代码都是经过了微软的严格测试,随时拿来就可以用的。当然至于具体地写程序对于程序员来说还是有难度的。为了创建基于窗口的应用程序,必须严格遵守规范。作到这一点并不难,只要用模块化或面向对象的编程方法即可。下面我就列出在桌面显示一个窗口的几个步骤:1.
2、得到您应用程序的句柄(对于 C 程序,可选);2.得到命令行参数(如果您想从命令行得到参数,可选);3.注册窗口类(必需,除非您使用 Windows 预定义的窗口类,如 MessageBox 或 dialog box;4.产生窗口(必需);5.在桌面显示窗口(必需,除非您不想立即显示它);6.刷新窗口客户区;7.进入无限的获取窗口消息的循环;8.如果有消息到达,由负责该窗口的窗口回调函数处理;9.如果用户关闭窗口,进行退出处理。相对于单用户的 DOS 下的编程来说,Windows 下的程序框架结构是相当复杂的。但是 Windows 和 DOS 在系统架构上是截然不同的。Windows 是一个多
3、任务的操作系统,故系统中同时有多个应用程序彼此协同运行。这就要求 Windows 程序员必须严格遵守编程规范,并养成良好的编程风格。例子:(见光盘 FirstWindow)#include Windows.h#include tchar.h HWND hWinMain;TCHAR szClassName=_T(MyClass);TCHAR szCaptionMain=_T(My First Window!);TCHAR szText=_T(Win32 program,Simple and powerful!);WNDCLASSEX stdWndClass;/如果有消息到达,由负责该窗口的窗口回
4、调函数处理 LRESULT CALLBACK ProcWinMain(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam )switch(Msg)/如果用户关闭窗口,进行退出处理 case WM_CLOSE:DestroyWindow(hWinMain);PostQuitMessage(NULL);break;default:return DefWindowProc(hWnd,Msg,wParam,lParam);return 0;int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstanc
5、e,LPSTR lpCmdLine,int nCmdShow)MSG stMsg;WNDCLASSEX stdWndClass;RtlZeroMemory(&stdWndClass,sizeof(stdWndClass);stdWndClass.hCursor=LoadCursor(0,IDC_ARROW);stdWndClass.cbSize=sizeof(stdWndClass);stdWndClass.style=CS_HREDRAW|CS_VREDRAW;stdWndClass.lpfnWndProc=ProcWinMain;stdWndClass.hbrBackground=(HBR
6、USH)COLOR_WINDOW;stdWndClass.lpszClassName=szClassName;stdWndClass.hInstance=hInstance;/注册窗口 RegisterClassEx(&stdWndClass);/产生窗口 hWinMain=CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain,WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL);if(!hWinMain)return 0;/在桌面显示窗口 ShowWindow(
7、hWinMain,SW_SHOWNORMAL);/刷新窗口客户区 UpdateWindow(hWinMain);/进入无限的获取窗口消息的循环 while(GetMessage(&stMsg,NULL,0,0)TranslateMessage(&stMsg);DispatchMessage(&stMsg);return stMsg.wParam;分析:看到一个简单的 Windows 程序有这么多行,您是不是有点想撤?但是您必须要知道的是上面的大多数代码都是模板而已,模板的意思即是指这些代码对差不多所有标准 Windows 程序来说都是相同的。在写 Windows 程序时您可以把这些代码拷来拷去
8、,当然把这些重复的代码写到一个库中也挺好。其实真正要写的代码集中在 WinMain 中。这和一些 C 编译器一样,无须要关心其它杂务,集中精力于 WinMain 函数。唯一不同的是 C 编译器要求您的源代码有必须有一个函数叫 WinMain。否则 C 无法知道将哪个函数和有关的前后代码链接。相对 C,汇编语言提供了较大的灵活性,它不强行要求一个叫 WinMain 的函数。下面我们开始分析,您可得做好思想准备,这可不是一件太轻松的活。头文件:windows.h 是编写 windows 程序必须要包含的,因为其中包含大量要用到的常量和结构的定义,windowd.h 还没有包含 windows 所有
9、的常量和结构定义,对于程序中我们用到的在 windows.h 定义之外的,我们可以通过察看 msdn,找到该结构和函数所在的头文件和库文件,包含进来就行。tchar.h 定义了我们用得宏 _T(x).我们的程序调用的 API 在 user32.dll(譬如:CreateWindowEx,RegisterWindowClassEx)和 kernel32.dll(ExitProcess)中的函数,所以必须链接这两个库。接下来我如果问:您需要把什么库链入您的程序呢?答案是:先查到您要调用的函数在什么库中,然后包含进来。在 VC6 的 settings 中已经包含了常用的 lib.如图所示。因此,我们
10、在代码中就无需显式的加载用到的库。显式加载的方法是在代码中加入一句,例如:#pragma comment(lib,kernel32.lib“)我们在前面曾经讲过,windows 提供的 API 函数封装在几个 DLL 中,调用 DLL 中的这些 API 函数,有两种方法,我们现在用的就是其中一种,即静态加载办法。还有一种是动态加载,我们将在后面讲 DLL 的时候,再给大家介绍。windows 应用程序中必须要有 WinMain 函数,这个函数是由 C 编译器需要的,代码编译后,在程序运行时,该函数由 C 运行库调用,传入 4 个参数。用户可以把它看作是程序的入口。该函数共有 4 个参数:应用程
11、序的实例句柄,该应用程序的前一实例句柄,命令行参数串指针和窗口如何显示。Win32 没有前一实例句柄的概念,所以第二个参数总为 0。之所以保留它是为了和 Win16 兼容的考虑,在 Win16 下,如果 hPrevInst 是 NULL,则该函数是第一次运行。函数声明如下:int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow);特别注意:WIN32 下的实例句柄实际上是您应用程序在内存中的线性地址。即HINSTANCE hInstance。如果你要处理命令行,可以从
12、 LPSTR lpCmdLine 参数中得到程序传入的命令行串。WINAPI 是一个宏,#define WINAPI _stdcall#define CALLBACK _stdcall 这个是一种函数调用约定。在 windows API 中几乎所有的函数,都是采用 WINAPI这种函数约定。这种调用约定称为标准调用约定。指定了调用一个函数时,函数采用从右到左的压栈方式,自己在退出时清空堆栈。VC 将函数编译后会在函数名前面加上下划线前缀,在函数名后加上和参数的字节数。还有几种调用约定在这里也稍作比对介绍。_cdecl c 调用约定,按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于传送参数
13、的内存栈是由调用者来维护的(正因为如此,实现可变参数的函数只能使用该调用约定)。另外,在函数名修饰约定方面也有所不同。_cdecl 是 C和 C程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall 函数的大。函数采用从右到左的压栈方式。VC 将函数编译后会在函数名前面加上下划线前缀。是 MFC 缺省调用约定。_fastcall 调用约定是人如其名,它的主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用 ECX 和 EDX 传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的
14、内存栈),在函数名修饰约定方面,它和前两者均不同。_fastcall 方式的函数采用寄存器传递参数,VC 将函数编译后会在函数名前面加上前缀,在函数名后加上和参数的字节数。关键字 _stdcall、_cdecl 和_fastcall 可以直接加在要输出的函数前,也可以在编译环境的 Setting.C/C+Code Generation 项选择。当加在输出函数前的关键字与编译环境中的选择不同时,直接加在输出函数前的关键字有效。它们对应的命令行参数分别为/Gz、/Gd 和/Gr。缺省状态为/Gd,即_cdecl。WinMain 函数中用的 RtlZeroMemory,是一个宏。#define Rt
15、lZeroMemory(Destination,Length)memset(Destination),0,(Length)在 WinMain 中主要概念就是窗口类(window class),一个窗口类就是一个有关窗口的规范,这个规范定义了几个主要的窗口的元素,如:图标、光标、背景色、和负责处理该窗口的函数。您产生一个窗口时就必须要有这样的一个窗口类。如果您要产生不止一个同种类型的窗口时,最好的方法就是把这个窗口类存储起来,这种方法可以节约许多的内存空间。如果您要定义自己的创建窗口类就必须:在一个 WINDCLASS 或 WINDOWCLASSEXE 结构体中指明您窗口的组成元素,然后调用 R
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- windows_sdk 编程 系列 文章 02 简单 窗口 程序
限制150内