
WIN32 程序和MFC 程序生成的都是Windows应用程序。不同的是,Win32程序使用Windows SDK框架生成应用程序框架,默认该框架程序不使用MFC(微软基础类),生成的都是面向过程的程序框架,程序的入口时WinMain,使用这个框架需要对Windows SDK程序比较熟悉;MFC程序,可以选择单文档、多文档和对话框的应用程序框架,该框架支持MFC,生成的程序框架,都是C++面向对象的应用程序,程序的入口是CXXXApp。
因此不会对一些基础的知识作过多的讲解。如果大家有需要,我在就某些细节作进一步的解释。编写Windows下面的GUI程序,比较有影响力的就是MS的Visual Studio系列和Borland的BCB系列。BCB需要在程序发布的时候,多带一些borland提供的库,比较的麻烦。所以我很少用。如果用VS系列来编写GUI程序,主要有两个方式,第一就是用微软提供的MFC来作,第二就是用纯的Win32 SDK来编写GUI程序。众所周知的原因,MFC对Win32 SDK的包装比较的失败,不如BCB那样的流畅,有时候你很难在程序中发挥自己的思路,因此,我一般就是用纯的Win32 SDK来编写GUI程序,而不用晦涩的MFC,因为用MFC,你不仅仅要知道Win32 SDK,还需要查询MFC的一些技巧,实在得不偿失。用Win32 SDK编写GUI的难处在于,有时候你需要为了一个简单的事情而查询很多的资料与SDK文档。但是你得到的却是对Windows系统的透彻理解和程序运行的高效,轻量化。因为用Win32 SDK需要的库都是内含在每一个Windows系统中的。理论上来说,只要是Windows系统,你的程序就可以正确无误的运行。下面就我最近编写Windows GUI程序的碰到的一些问题一一说明。首先,看一下程序的最终运行效果图(我的编译器是VC6): 1 用VC6的Win32程序搭好框架之后,就添加自己的模式对话框,碰到的第一个问题就是如何设置Radio控件(有的中文书翻译为 单选按钮)的初始状态和查询最终的结果。经过一番努力查询Win32 SDK之后,标准答案如下:设置Radio的初始状态:BOOL CheckDlgButton(HWNDhDlg,int nlDButton,UINT uCheck)获得Radio控件的最终状态:UINT IsDlgButtonChecked(HWND hDlg,Int nlDBUtton)2 如何处理slider control(中文叫做滑竿控件)的相关事件。slider control,其实和上面的那个简单的radio control还是有本质的区别的。radio control是内含在windows的一般库里面的。不需要特别的库的支持,而slider control(英文也叫track bar)是需要COMCTL32.lib的支持,要用这个slider control,你需要作三个动作。a 在源文件里面加入COMCTL32.lib的引用。b 在头文件里面加入对commctl.h的声明,一般加到stdafx.h即可。#include // Add by liuzhi.c 在程序里面,需要加入使用common control的宏:InitCommonControls()否则,程序会闪一下就会退出的。因为程序没有申请到该有的资源。 加入对slider control的声明后。需要处理slider control的一些事件。这是需要特别注意的是,slider control不像radio control那样子直接用SDK API就可以处理了。需要特殊的消息机制,下面一一道来:2.1 获得控件的窗口句柄。slider control也是一个窗口,是对话框的子窗口,因此,要用GetDlgItem来实现:backlight_wnd = GetDlgItem(hDlg, IDC_SLIDER_BACKLIGHT)2.2 设置slider control的区间,是给slider control发TBM_SETRANGE消息,比如我设置0到100就是:SendMessage(backlight_wnd,TBM_SETRANGE, (WPARAM)1,(LPARAM)MAKELONG(0,100))2.3 设置滑块的初始位置是发送TBM_SETPOS消息来实现的: SendMessage(backlight_wnd,TBM_SETPOS, (WPARAM)1,(LPARAM)BacklightPercentage)
2.4 slider control和用户的交互,则是通过WM_HSCROLL消息来实现的,需要在WM_HSCROLL的响应函数里面发送TBM_GETPOS消息得到当前滑块的位置:BacklightPercentage = (unsigned char)SendMessage(backlight_wnd,TBM_GETPOS,0,0)2.5 旁边的一个当前刻度的数字的说明,需要先设定一个Static text文本控件,然后动态给该控件发送WM_SETTEXT消息来实现动态的更新数字:SendMessage(GetDlgItem(hDlg, IDC_STATIC_BACKLIGHT_VALUE), WM_SETTEXT, 0, LPARAM(szBacklightPercentage))最后面的那个参数,szBacklightPercentage是一个字符串。3 如何在对话框里面显示图标或者图片:如果程序没有图片,总是显得十分的死板,因此,在程序上面显示图片,图标是必要的美化程序的方法。网上关于程序显示图片的说明也很多。但是都比较的复杂。如果仅仅显示静态的图标,其实不用那么复杂的。3.1 需要好的icon素材。漂亮的icon素材就如程序的脸蛋一样。是必须的,要得到好的icon素材,第一是到网上“淘宝”。看看能不能找到你满意的。另外也有搜索自己电脑上漂亮图标的工具。因为windows自己也提供了很多的图标资源。这里推荐一个叫做 IconExtract 的小软件。大家可以网上下载,它可以很方便的把本地的图标都挖出来。一般情况下,够我们用的了。找好自己喜欢的图标之后,记得在资源里面的icon项目下引用进来。3.2 显示图标:如果不是动态显示,就只是简单的在对话框上面加picture控件,然后在属性里面指定icon的来源即可。4 如何响应电源插拔事件:在笔记本上面,ac电源插上和拔出的时候,会有背光亮度的改变,因此需要在知道这个电源来源改变的时候来重新获得当前背光,经查询,程序需要响应WM_POWERBROADCAST消息。如果wParam是PBT_APMPOWERSTATUSCHANGE,就需要重新获得当然背光: case WM_POWERBROADCAST:
if (wParam == PBT_APMPOWERSTATUSCHANGE) // Power source maybe changed, check the backlight again.
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_ICON_CONFIG2)// IDI_SMALL这样子修改之后,你会发现,程序运行的显示图标是改变了。但是程序exe的图标还是没有改变,这是因为exe和dll默认都显示id为最低的那个icon的图标。因此,在resource.h里面把自己希望显示的图标id和现有的程序图标id换一下就可以了。#define IDI_ICON_CONFIG2 107 // make sure the icon ID is lowest.
好了。
如果你是一个编程初学者,如果你刚刚结束C语言的课程。你可能会有点失望和怀疑:这就是C语言吗?靠它就能编出软件?无法想象Windows桌面上一个普通的窗口是怎样出现在眼前的。从C语言的上机作业到Windows编程确实有比较大的gap。或许你已经看了programming Windows的前三章,但是对于那个hellowin程序甚为迷惘。希望hfire的这篇文章能帮你填补这个gap,并提供一些学习的经验。为什么是浅谈,因为hfire知道的也不够深,肯定会有错误,请批评指正。
程序与运行时环境及 *** 作系统
当你用Turbo C编写了一个C程序,然后编译连结它,得到了一个可执行文件。在Dos的命令提示符下键入这个exe文件的文件名,然后它就执行了。表面看事情就是这些。作为一个应用程序员,我们不用考虑背后的事情,但是有一个简单的事实我们必须清楚的认识:程序不只是靠自己运行,它需要运行时环境的配合。考虑一下用一个printf函数显示一个字符串的过程。显然这个函数不是你自己写的。或许你听说过C-Runtime Library,C运行时库,没错,你的程序只有依靠它才能运行。printf的代码就在C运行时库中,因此你可以轻松的调用它而不管它是怎么实现的。但是,C运行时库也会调用一些别的函数,这些函数是由 *** 作系统提供的,称为中断服务程序,而 *** 作系统的中断服务程序会进一步的调用BIOS中断服务程序。可以看出,程序的运行是由一层一层的服务支撑起来的。在这里面, *** 作系统担当了非常重要的角色。它提供了程序员可以直接使用的例程,也可以称为Application Programming Interface (应用程序编程界面,API) 。Dos中一般没有API的说法,Dos的编程界面是由中断服务程序充当。在Windows中编程就要常常和API打交道。32位Windows的API有2000多个,一方面它提供了功能强大的编程界面,另一方面它使初学者望而却步。
Windows *** 作系统基本常识
Windows是一个单用户多任务图形化 *** 作系统。所谓单用户,指同时只能由一个用户(一个人)通过Windows系统 *** 作电脑;所谓多任务,指同时可以有多个进程并发执行。既然Windows系统有这些特点,那么Windows编程就会体现这些特点。为了做到多任务,Windows程序使用消息机制,有我的消息我才干活,没我的消息就把CPU让给别人;为了做到图形化,Windows程序必须显示窗口并自己绘制客户区,就连显示字符串也必须画到客户区上。还有一点,Windows广泛使用动态链接。Windows的API就放在动态链接库中,以供程序运行时调用。在Windows 98中有32位的gdi32.dll,user32.dll,kernel32.dll和16位的gdi.exe,user.exe,krnl386.exe,API就存在于这些动态链接库中。
什么是Windows SDK
SDK即software develope kit(软件开发工具包),它包含了进行Windows软件开发的文档和API函数的输入库、头文件(因为API在动态链接库中,这些动态链接库是系统的组成部分因此不用再提供,而输入库和头文件则必须,这样才能在你的程序中使用API函数)。早期SDK是一个单独发放的包,现在在Visual C++和其他一些开发环境中已经包含了它。如果你已经安装了VC++那么就可以开始编写Windows程序了。随着Windows系统的发展,SDK的内容越来越多,我们只要抓住最基本的方面。至于其他专门的主题,就根据自己的兴趣和技术方向进一步学习了。
不用被第一个Windows程序吓住
如果你已经开始,你的教材应该是那本经典的programming windows (petzold)或者是一本相似的书。但无论哪本书,一开始你都会面对一个基本的Windows SDK程序,这个程序有几十行。尽管也不算长,但比C版的hello world长多了。更糟的是,里面充斥着奇怪的变量类型和常量定义,不过先不用被它吓住,让我们看看这里面有些什么。首先会有一个#include ,嗯,没什么奇怪的,这和#inclde 没什么两样。然后是一个函数声明:LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) 有点困惑了,一下子就出来了好几个“生词”,而且函数名前面有两个修饰符也是以前没有遇到的。好在我们还可以辨认出这是一个函数声明。再往下看是WinMain函数,又是一堆生词,我猜想你可能已经开始郁闷了。想一遍看懂这个程序确实困难,所以看不懂也没关系。看不下去了可以看看书上的讲解。这篇文章并不是要完整分析这个程序的,hfire不可能有petzold讲的好。在这里hfire帮你分析一下一些陌生的东西。
首先说Windows的数据类型。尽管这些数据类型看上去很陌生,其实它们是由C的基本数据类型define的。比如UINT就是unsinged int,PSTR就是pointer to string 的意思,猜猜就知道是char * 。Windows还有很多系统定义的结构体,比如WNDCLASS,MSG等,这些东西见的多了就自然明白了。Windows还有一个重要的概念,句柄。通过句柄就可以 *** 作Windows对象。HWND,HINSTANCE,HDC等都是句柄。
再说说Windows程序的结构。一般有一个WinMain函数作为程序的入口点,在WinMain里面定义窗口类,进行消息循环。消息循环就是那个普通的while循环,在其中接收消息、分发消息。然后是窗口函数WndProc,名字可以自己定。在其中用一个大的switch结构检索消息,在每个case下面写处理消息的代码。最简单的Windows SDK程序只要写这两个函数就够了。等你的程序写长了,就要把特定的消息处理代码写成函数,以便在处理消息时调用,甚至你可以使用C++来写程序。等你熟悉这种结构以后,就可以任意发挥了。
其他的不想说太多,学SDK很重要的是不要期望在开始时把每行代码都搞清楚。
学习的方法
当然是多写程序了。每个主题都写一个。从一开始的窗口,文本显示到图形显示、控件、对话框,多写就能领会Windows编程的内涵。当第一部分学的差不多了,可以写一个综合点的程序。最后你会发现你可以写很长的程序了,1000多行也不算长,但对于当时学C时是难以想象的。还有重要的是多上一些专门的网站,比如VC知识库(www.vckbase.com)和VC之路(有一本很好的教程,不过现在网站的东西都没了,正在恢复),另外www.csdn.net也是一个不错的地方。
几种Windows编程方法的辨析及其它
很多初学者往往会将Windows编程和VC++混为一谈。打开VC++的新建项目,可以看到VC++支持很多种工程。包括命令行的,MFC的,还有就是Win32 Application,即SDK程序。使用VC++未必是编写SDK程序,编写SDK程序也未必要用VC++。 编写Windows程序的方法也不止SDK一种,还包括使用类库如MFC,OWL,使用快速开发工具如VB,Delphi。这些方法各有各的用处。使用SDK无疑是最麻烦的了,我们学习SDK也并非是为了用它来编软件,虽然它可以,主要是为了对Windows编程有比较清晰的认识,这样你使用MFC时就可以做到“胸中自有沟壑”。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)