【白话Windows编程】第一章 看透Windows之一
第一篇 看透 Windows“看透Windows”前言终于开始Windows编程了。我们也无可避免地,开始和Windows打交道。记得在《白话C++》里,我们试图用“程序员”的眼光来重新认识什么叫电脑,认为电脑中的一切都是0和1。现在,更艰巨的任务摆在我们面前。本课程前些章节的内容就是:看透Windows。(不要和我抬杠,说Windows那么复杂,你怎么能看得透,你明白,我们的任务主要是尽量从程序的角度来看Windows这个操作系统。)从 Windows3.1 到 Windows 95、98、Me、及今天的 Windows XP,其间还有WindowsNT,Windows 2000。Windows这一操作系统,早已经遍布世界上各个角落上的电脑。所以你应该对Windows并不陌生。但是你以前不是程序员,或者说不是“Windows 程序员”。所以,你看到的Windows,一定和我看到的,不太一样。当我把自己的身份切换“最终的电脑用户”时,我也和许多人一样,骂过Windows,骂它体积太大,速度太慢,容易死机,很不安全。而当我意识到自己是一个程序员时,我就闭嘴了。我可以保证,学习所有的“看透Windows”,你就是一个标准的“Windows"程序员——因为你立可就可以写出多个真正的Windows程序。并且这些程序个个直达 Windows世界的要点。到时,你也会我一样,明白“Windows 不是一日可以写成的”。从而对Windows不再有抱怨。当然,我们的身份是双重的,你随时可以让把自己的身份强行切换到“最终用户”,然后结合你所学的程序知识,在Windows身上出点气。而且,其实我也很乐意教这些的:D你看看这张图,一会儿我们就要写这么一个程序:

双击放在表单上的按钮。出现代码编辑窗口。现在的代码中应有这些内容:void __fastcallTForm1::Button1Click(TObject *Sender){}在上面的一对 { }之间填写以下内容:(行号不要键入!)//先得到屏幕的长宽:1) int ScreenWidth =Screen->Width;2) int ScreenHeight =Screen->Height;3) HDC hDC = ::GetDC(0);//得到“画布(Canvas)”4) TCanvas* ScreenCanvas = newTCanvas;5) ScreenCanvas->Handle= hDC;//设置画布的画笔(Pen)6) ScreenCanvas->Pen->Color= clRed; //画笔的颜色为红色(Red)7) ScreenCanvas->Pen->Width= 10; //画笔的粗细//开始画叉啦,需要画两笔,这是第一笔:左上到右下8) ScreenCanvas->MoveTo(0,0); //把画笔移到(Move to)坐标0,0处,即屏幕最左上角9) ScreenCanvas->LineTo(ScreenWidth,ScreenHeight); //从当前位置画一条线(Line to)到屏幕的右下角。//第二笔:右上到左下:10) ScreenCanvas->MoveTo(ScreenWidth,0);11) ScreenCanvas->LineTo(0,ScreenHeight);//释放“画布”:12) ScreenCanvas->Handle= 0;13) delete ScreenCanvas;14) ::ReleaseDC(0,hDC);保存工程。编译: Ctrl + F9。如果报错,说明你代码有误。运行:F9。窗口出现了。上面有一个按钮。如果你的CB6正在显示,把它最小化以露出Windows的桌面。然后,点按钮。本章最前头的图片效果就应该出来了。不知道你在想什么?但我想通过这个程序来告诉你:你每天都在面对的Windows,都在使用的Windows,它的一切都是画出来的。普通用户没有“权力”去参与这件工作。但程序员有权参与——仅管我们看上去是在搞破坏。代码解释:我们并不想在"看透"的章节里,就讲太多的技术细节与实现原理。但幸好上面的代码都很自然。如果你不懂什么叫“类(class)”,那么需要继续学习《白话 C++》。上面用到了两个类:TScreen 和 TCanvas。Screen 变量CB 的程序会在程序运行时,就自动产生一个 Screen 变量,它的数据类型为 TScreen 。如其名,它是封装了“屏幕”的一些信息和功能。我们这里仅仅想得知屏幕的分辨率是多少?我的电脑是(1024* 768),别的电脑可能也是,或者是800 *600,最惨就是640 * 480了。(注1) 得到屏幕长宽后(第1、2行),我们也就没有在使用Screen了。Screen由CB自动生成,是一个全局变量,它的释放工作不归我们管。ScreenCanvas 变量TCanvas 类,它封装有关Windows绘画操作的绝大部分数据和功能。所以虽然它的名字为“画布”,但其实包含了“画笔(Pen)、画刷(Brush)”等等。在CB中,窗口会自带一个Canvas变量,但可惜我们现在是要在屏幕上的任何地方画。(第一道线就从从屏幕的左上角一直穿过整个桌面,直到落上右下角的时间区)。这是一种很霸道的行为。CB当然不会为我们这种行为事先准备一个这样的“画布”。所以我们需要生成一个Canvas变量,我命名它为:ScreenCanvas(屏幕画布)。这是第4行做的事:生成一个画布变量。虽然取名为“屏幕画布(ScreenCanvas)”。但事实上新生成的画布都是“空画布”。因为程序这里还不知道你到底想画到哪里。我们想画到整个屏幕上(事实上,如果你有其它程序正在屏幕上显示着,则会画到那个程序的界面)。这就需要向Windows提出申请,请它把整个电脑屏幕的“画布”都交给我们。Windows 是用C和汇编写的,二者都不是面向对象的语言。Windwos大多数数据和功能本身也没做面向对象的封装(后来的COM对象开始有了面向对象的特征,这是后话)。在Windows里,类型画布的东西,称为DC。第三行:HDC hDC =::GetDC(0); 得到了屏幕DC。 参数 0 正是指明要的是整个屏幕的画布。第五行:ScreenCanvas->Handle = hDC; 通过ScreenCanvas 的 Handle属性,得到了整个屏幕的画布。(这些解释,你可能觉得还有不少地方没讲到,但没关系。)其它的,就是画线的过程。代码中已有详细的注释。最后12,13,14三行,用于返还、释放屏幕画布。这就是我们的第一个例子。在屏幕上打一个叉。下一章我们仍然是要画画。不过我们将会规矩一点,只在合适地方,在合适的时间,画上合适的内容。猜一猜,我们会画什么内容?是一个在编程界流传很广,也很古董的内容。当初学习《白话C++》时,我们就做过了!——此言一出,台下一片失望之色。注一:可以这样查看你的电脑屏幕分辨率:在Windows桌面点右键,出现的菜单中选“属性”,然后选择到“设置”页。应该就能找到分辨率,如果没有,可以找一个“高级”按钮,点击后在出现的各页里查找。