windows API程序设计

发布时间:2013-07-16 14:55:46

Windows API程序

设计

2013 05 30


简单的Windows API程序设计

Windows 是一个基于图形界面的多用户多任务操作系统,它提供了许多可用于C++程序的设计资源对象,如菜单、对话框、工具按钮、光标、位图、字体等,在C++程序中可以直接应用这些对象,高效、快捷地设计出具有Windows风格的应用程序。

VC++进行面向对象的Windows程序设计主要有两种方法:一种是使用Windows提供的API函数编程,称API程序设计;另一种是直接使用微软的MFC类库编程,称为MFC程序设计。本次实验主要采用第一种方法利用Windows提供的API函数进行编程。

一、实验目的

本实验主要编写一个简单的 Windows API 程序。通过本实验你将能:

(1) 了解 Windows API 程序的 VC++ 开发环境;

(2) 学习开发简单的 Windows API 程序;

(3) 理解 Windows 程序中的消息循环;

二、实验环境

电脑一台,Windows XP操作系统,VC++6.0编译环境。

三.实验内容及完成情况

编程过程如下:

(1) 启动VC++6.0,选择菜单“文件|新建”,在弹出的“新建”对话框中选择“工程”标签页,如图(一)所示。

(2) 选中“工程”对话框中的“Win32 Application”列表项,并在“位置”编辑框中指定本项目建立的磁盘目录,然后在“工程”编辑框中输入项目文件的名字。

(3) 单击“确定”按钮,并在弹出的对话框中选中“一个空工程。”单选项,然后单击“完成”按钮。最后将得到如图(二)所示的空项目文件窗口。

图(一)新建项目

4选择菜单“文件|新建”,然后在弹出的对话框中选择“文件”标签,并选择列表中的“C++ Source File”项目,然后在“文件”编辑框中输入源程序文件名“API”如图(三)所示,输入完成后,单击“结束”按钮。

图(二)新建的空项目窗口

图(三)向空项目添加一个C++源文件

API.cpp中输入下面的程序代码。

#include

#pragma comment(lib,"winmm.lib")

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,

PSTR szCmdLine,int iCmdShow) {

HWND hwnd;

MSG msg;

WNDCLASS wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc = WndProc;

wndclass.cbClsExtra = 0;

wndclass.cbWndExtra = 0;

wndclass.hInstance = hInstance;

wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);

wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);

wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);

wndclass.lpszMenuName=NULL;

wndclass.lpszClassName="lao zheng";

RegisterClass(&wndclass);

hwnd=CreateWindow("lao zheng",

TEXT("郑文超的简单程序设计"),

WS_OVERLAPPEDWINDOW /*& ~WS_MAXIMIZEBOX*/,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

NULL,

NULL,

hInstance,

NULL);

ShowWindow(hwnd,SW_SHOWNORMAL);

UpdateWindow(hwnd);

while(GetMessage (&msg,NULL,0,0))

{TranslateMessage(&msg);

DispatchMessage(&msg);

}

return msg.wParam ;

}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,

WPARAM wParam,LPARAM lParam)

{

HDC hdc;

HPEN hPen,hPenOld;

HBRUSH hBrush,HbruOld;

PAINTSTRUCT ps;

static POINT Rect[20],Elli[20]; //Rect保存矩形的鼠标点,Elli保存椭圆的鼠标点

static int n=0,m=0; //nm分别用于记录RectElli中点的个数

int i,j;

switch(message) //消息处理

{

case WM_CREATE:

PlaySound(TEXT( "I:\\You Raise Me Up.wav"),NULL,SND_FILENAME|SND_ASYNC);

return 0;

case WM_LBUTTONDOWN:

Rect[n].x=LOWORD(lParam); //计算鼠标的x坐标

Rect[n].y=HIWORD(lParam); //计算鼠标的y坐标

InvalidateRect(hwnd,NULL,FALSE); //产生WM_PAINT消息

n++;

return 0;

case WM_RBUTTONDOWN:

Elli[m].x=LOWORD(lParam);

Elli[m].y=HIWORD(lParam);

InvalidateRect(hwnd,NULL,TRUE);

m++;

break;

case WM_PAINT:

HDC hdc;

PAINTSTRUCT ps;

hdc=BeginPaint(hwnd,&ps);

TextOut(hdc,0,0,"点击鼠标左键画矩形、鼠标右键画椭圆",strlen("点击鼠标左键画矩形、鼠标右键画椭圆"));

//创建绿色实线画笔

hPen=(HPEN)CreatePen(PS_SOLID,10,RGB(81,255,0));

//创建黄色网格线画刷

hBrush=(HBRUSH)CreateHatchBrush(HS_CROSS,RGB(238,255,0));

//下面用SelectObject函数将创建的画笔和画刷选入Windows系统,选入之后所有的图形函数都会用新建的

//绿色画笔画图,用黄色的网格画刷填充图形

hPenOld=(HPEN)SelectObject(hdc,hPen); //选新画笔,返回旧画笔句柄

HbruOld=(HBRUSH)SelectObject(hdc,hBrush);//选新画刷,返回旧画刷句柄

for(i=0;i绘制矩形

Rectangle(hdc,Rect[i].x,Rect[i].y,Rect[i].x+180,

Rect[i].y+60); //绘制椭圆

for(j=0;j

Ellipse(hdc,Elli[j].x,Elli[j].y,

Elli[j].x+120,Elli[j].y+60);

EndPaint(hwnd,&ps);

break;

case WM_CLOSE:

if(IDYES==MessageBox(hwnd,"是否真的结束?","lao zheng",MB_YESNO))

{

DestroyWindow(hwnd);

}

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hwnd,message,wParam,lParam);

}

return 0;

}

编译并运行程序,将得到如图(四)所示的运行结果。在窗口创建时是播放音乐"I:\\You Raise Me

图(四)程序运行结果

在窗口的客户区域,单击鼠标左键画绿色边框矩形,并有黄色网格线填充。单击鼠标右键,画绿色边框椭圆,并有黄色网格线填充。如图(五)所示。

图(五)

改变窗口大小,后绘制的图形仍然存在,如图(六)所示:

图(六)

单击窗口右上角的关闭按钮,将会弹出消息框,提示是否真的结束程序,点击否仍然存在,点击是程序将退出,如图(七)所示:

图(七)

四、程序代码分析及调试过程

本程序是Windows程序处理消息的典型方式。在窗口创建完成后会调用“PlaySound”函数,播放自己插入的音乐,单击左键产生WM_LBUTTONDOWM,单击右键时产生WM_LBUTTONDOWN消息,同时会将鼠标的坐标位置信息保存在lParam参数中,低字节是x坐标,可用宏LOWORD将它计算出来,高字节是y坐标,可用HIWORD宏将它计算出来。函数InvalidateRect()产生一条WM_PAINT消息,导致WM_PAINT中的两处for循环被执行,它们将以Rect数组中的POINT点为中心画矩形,以Elli数组中的POINT点为中心画圆。

调试过程主要问题:一、窗口的重绘。当移动窗口,通过滚动窗口,移走覆盖在窗口客户区上面的对象,改变窗口大小或激活另一个程序时,都会产生WM_PAINT消息,而这些时间都需要重新绘制窗口的内容。为了在窗口改变时,函数输出数据仍然存在,我采用了将Windows程序数据的输出放在了WM_PAINT消息处理中来实现,窗口的重绘问题也就迎刃而解了。二,在程序调试的过程中,发现点击鼠标左键画矩形正常,但是在点击鼠标右键时,画椭圆会出现混乱,要么只有几个椭圆能实现重绘,要么椭圆的显示位置会出现错误,问题的原因一直找不到,后来在老师的帮助下,发现在右键计算椭圆的坐标时与左键计算矩形的坐标使用重复,改正后问题也就立马解决了。

五、心得体会

通过这段时间对Windows API程序设计的学习,对VC++6.0的开发环境,和Windows程序的执行流程有了初步的了解。Windows程序的执行主要靠事件来驱动,每发生一个事件,就会产生一个与之对应的特定消息,该消息会被Windows系统捕获。Windows系统对捕获的消息进行分析后,会将消息传递给产生它的应用程序。每个应用程序都有一个消息队列和一个消息循环机构,消息队列用于存放有Windows系统传递给它的消息,循环机构则不断地重复查看程序的消息队列,如果队列中有消息,就将其取出并执行相应的消息处理代码。

windows API程序设计

相关推荐