从实例看Windows API程序设计

发表于:2007-07-14来源:作者:点击数: 标签:
作者: 刘雨楠、谭章熹 来源:www.ccidnet.com 用户在使用VC++ 开发 应用程序时,主要有两种方法:调用 Windows 提供的API函数(Application Programming Interface)和直接使用Microsoft提供的MFC类库(Microsoft Foundation Class)。与MFC相比,API更贴近操作
作者: 刘雨楠、谭章熹

来源:www.clearcase/" target="_blank" >ccidnet.com

用户在使用VC++开发应用程序时,主要有两种方法:调用Windows提供的API函数(Application Programming Interface)和直接使用Microsoft提供的MFC类库(Microsoft Foundation Class)。与MFC相比,API更贴近操作系统,也是每一个Windows程序员必须掌握的。

本文将以一个类似Windows的计算器程序为例,简述Windows API程序设计的方法和一些基本技巧。

思路和算法
1、首先构造输入和输出界面
首先构造输入和输出界面。在主窗口中,用CreateWindow( )函数来创建按钮和编辑框等子窗口控件。这样,用户可通过按钮进行输入,并通过编辑框显示计算结果。
2、本程序通过表达式堆栈算法来支持科学计算功能
以字符型数组express[ ]存放整个表达式,并定义void Push(char)和void Pop(void)来实现向数据堆栈OVS和算符堆栈OPS压入和弹出一个操作符或数据。
3、为了进行正常的计算,必须保证表达式的合法性
程序一方面要对用户的输入加上必要的过滤,例如不允许出现非法表达式,另一方面要对非法运算数据作判断。
4、用户点击“=”完成所有的输入后,调用void CalculateOperation()函数进行计算
具体实现方法如下:用指针i从express中扫描输入的表达式,若扫描到数值,则压入数据栈OVS,若扫描到运算符则判断其优先级是否大于或等于算符堆栈OPS栈顶的优先级,如果大于其优先级则压入OPS并扫描下一字符,反之则弹出OVS和OPS栈顶元素进行一次运算,并将结果压入OVS栈。反复执行此过程,直到完成表达式的计算。

程序主体结构
本程序以WinMain( )函数为入口,并依次进行窗口类的初始化和登记,以及窗口的创建和显示。在消息循环里,主函数反复调用WinProc( )回调函数(CallBack Function)以处理捕获的消息。因此全部消息的响应代码要写在WinProc( )中,这也是用Windows API编写程序最核心的部分。

另外,用API设计程序的一大特点就是对任何元素操作都需要通过获得相应的句柄(Handle)来实现。

程序功能及特色
本程序除一般的科学计算功能外,还有一些扩展功能。

1. 可动态更换背景图案
类似Winamp播放器有各种各样的Skin,本程序也可动态更换背景。其核心思路就是在WM_ERASEBKGND消息响应时,不用系统缺省的白色画刷,而用资源中的位图来重画背景。为了提高重画效率和避免闪烁,开发时一定注意不要把背景重画代码放在WM_PAINT消息响应中。

另外为使背景图案能跟随窗口尺寸变化,在显示位图时,采用StretchBlt函数代替BitBlt函数,这样在更换背景图案时,不论资源中的位图是否与当前窗口的大小相等,都会自动拉伸或收缩以适应窗口的尺寸。具体代码如下:

case WM_ERASEBKGND:
{
RECT rc;
hdc = (HDC)wParam;
// wParam的值为当前窗口的hDC
SelectObject(hdcmem,hbitmap);
GetClientRect(hwnd,&&rc);
//获得客户区域大小
StretchBlt( hdc,0,0,rc.right,rc.bottom,hdcmem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY );
}
break;
其中,hdc是当前窗口的DC,hdcmem是与当前屏幕兼容的内存镜像设备句柄。

为了使用方便,在选单中可创建背景子选单。资源文件的代码如下:

// Menu
MENU MENU DISCARDABLE
BEGIN
POPUP "设置(&&M)"
BEGIN
POPUP "背景(&&B)"
BEGIN
MENUITEM "GREEN", IDM_GREEN
MENUITEM "SNOW", IDM_SNOW
MENUITEM "BUTTERFLY", IDM_BUTTERFLY
MENUITEM "FLOWER", IDM_FLOWER
END
END
END
// Bitmap
SNOW BITMAP MOVEABLE PURE "snow.bmp"
GREEN BITMAP MOVEABLE PURE "green.bmp"
BUTTERFLY BITMAP MOVEABLE PURE "butterfly.bmp"
FLOWER BITMAP MOVEABLE PURE "flower.bmp"
其中,IDM_GREEN等是与选单项对应的ID(定义在头文件中),snow.bmp等是位图文件的文件名。

2. 高级功能与一般功能的切换
Windows中的“计算器”程序,可实现“科学型”与“标准型”的切换。同样,本程序也设有类似功能。在选单中,点击“统计计算”,窗口会向外拉出一块,显示与统计计算有关的几个新按钮,再点击一次,窗口又会恢复原状。

为实现此功能,我们首先在响应WM_CREATE消息时,将几个“统计计算”按钮事先创建在窗口区域之外,使这几个按钮不可见,用户便不能通过这几个按钮进行输入。当“统计计算”的选单项被选中时,用SetWindowPos( )函数来扩大窗口边界,使这几个按钮变为可见,这样就等于增加了新的功能。具体代码如下:

case IDM_STATISTIC:
// IDM_STATISTIC是与“统计计算”选单项对应的ID
{
HMENU hmnu = GetMenu(hwnd);
//获取选单句柄
RECT rc;
if(statistic==FALSE)
{
CheckMenuItem(hmnu,IDM_STATISTIC,MF_CHECKED);
SetWindowPos(hwnd,0,0,0,600,250,SWP_NOZORDER| SWP_NOMOVE);
//拉大窗口尺寸
statistic=TRUE;
}
else
{
CheckMenuItem(hmnu,IDM_STATISTIC,MF_UNCHECKED);
SetWindowPos(hwnd,0,0,0,500,250,SWP_NOZORDER | SWP_NOMOVE);
//收缩窗口尺寸
statistic=FALSE;
}
GetClientRect(hwnd,&&rc);
InvalidateRect(hwnd,&&rc,TRUE);
UpdateWindow(hwnd);
//重画当前窗口
}
break;

3. ShellAPI函数的应用
(1)有些程序在选单中点击“说明”后,应用程序会调出Windows的记事本并打开一个文本文件。我们可以通过调用ShellExecute( )函数实现此功能。具体实现代码如下:

ShellExecute(NULL,"open","readme.txt",NULL,NULL,SW_SHOWNORMAL);
其中“open”代表执行打开操作,“readme.txt”是要打开的文件名。
  
(2)一般程序都设有“关于”选项,用来介绍程序的作者。初学者一般使用一个模态或非模态对话框来实现此功能。在本程序中,笔者通过ShellAbout( )函数,使用了Windows中公共的“关于”对话框,就像使用Windows中公共的MessageBox一样。使用方法如下:

ShellAbout(hwnd,"迷你计算器","制作人:刘雨楠",NULL);
可在第二和第三个参数处点写对话框的标题和内容。

4. 声音(WAV)文件的简单应用
为了使程序更加精致与完美,我们可在程序中加入声音的播放。这只需在要发声的位置简单地加入以下代码:

PlaySound(TEXT("*.wav"),NULL,SND_FILENAME|SND_ASYNC);
  
本程序的编制过程充分体现了Windows API程序设计的风格和基本特点,程序应用的各种技巧同样可用于其他API程序。

原文转自:http://www.ltesting.net