Windows API 编程讲义.doc

上传人:asd****56 文档编号:70332717 上传时间:2023-01-19 格式:DOC 页数:134 大小:864KB
返回 下载 相关 举报
Windows API 编程讲义.doc_第1页
第1页 / 共134页
Windows API 编程讲义.doc_第2页
第2页 / 共134页
点击查看更多>>
资源描述

《Windows API 编程讲义.doc》由会员分享,可在线阅读,更多相关《Windows API 编程讲义.doc(134页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、目录第一章Windows API开发概述2第二章 GDI编程2第三章 文本输出与滚动条2第四章 鼠标、键盘及计时器2第五章 资源2第六章 Windows标准控件2第七章 调用DLL中的API2第八章 多任务与多线程2第一章 Windows API开发概述1. Dos 与 Windows 的主要区别系统相同点不同点联系Dos 系统1. 都是系统软件2. 都支持应用软件的操作字符界面Windows系统兼容Dos系统无鼠标单用户单任务不稳定,保密性差不支持多媒体Windows 系统图文界面有鼠标多用户多任务稳定性、保密性强支持多媒体 上表给出了两种系统的一些区别,究其主要区别还是在于Dos是基于过程

2、驱动的方式,而Windows是基于消息驱动的方式。2. 学习目的 采用Windows API直接对应用需求进行设计。尽管目前有着大量的快速开发工具可供选择,但如果不理解Windows Ring3层的基本工作原理,很难开发出好的软件,也很难在遇到特定问题时进行解决。因此,学习好本门课程对基于Windows 的软件设计来说,是十分必要的。3. 一个简单的Win32 API 应用程序:Hello World!3.1 应用程序示例#include LPCTSTR lpszAppName =TEXT(MyApp);LPCTSTR lpszTitle =TEXT(My Application); LRES

3、ULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) MSG msg; HWND hWnd; WNDCLASS wc; / 建立主要的应用程序窗口类 /. wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)WndProc; wc.cbClsExtra = 0; wc.cbWndE

4、xtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = lpszAppName; wc.lpszClassName = lpszAppName; if ( !RegisterClass( &wc ) )/注册窗口类 return( FALSE ); / 建立主要的应用程序窗口

5、/. hWnd = CreateWindow( lpszAppName, lpszTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL );/ 判断窗口是否建立成功 if ( !hWnd ) return( FALSE );/ 显示窗口 ShowWindow( hWnd, nCmdShow ); UpdateWindow( hWnd ); / 建立消息循环机制 while( GetMessage( &msg, NULL, 0, 0) ) TranslateMessa

6、ge( &msg ); DispatchMessage( &msg ); return( msg.wParam ); LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) / 处理消息 switch( uMsg ) static int uRed = 0, uGreen = 0, uBlue = 0; / 绘制消息 case WM_PAINT : RECT rect; HDC hdc; PAINTSTRUCT ps; hdc = BeginPaint(hWnd, &ps); GetClien

7、tRect( hWnd, &rect); SetTextColor( hdc, RGB(uRed, uGreen, uBlue); DrawText (hdc, TEXT (Hello, World!), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint(hWnd, &ps); break;/ 按键消息 case WM_KEYDOWN : uRed = rand() % 255; uGreen = rand() % 255; uBlue = rand() % 255; InvalidateRect(hWnd, NULL,

8、 TRUE); break;/ 窗口关闭消息 case WM_DESTROY : PostQuitMessage(0); break;/ 其它消息 default : return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ); return( 0L );3.2 程序结构解析3.2.1 Windows 的入口函数WInMainWInMain函数与C中的main函数相似,其包含4个参数:HINSTANCE hInstance:实例句柄,唯一地标识了该程序。 HINSTANCE hPrevInstance:为了与早期版本兼容,已经不再使用。 LPTS

9、TR lpCmdLine:启动命令行参数。int nCmdShow:以何种方式运行(正常、最大化、最小化)。3.2.2 窗口类结构WNDCLASStypedef struct tagWNDCLASSA UINT style;/窗口类风格 WNDPROC lpfnWndProc;/指向窗口过程的指针 int cbClsExtra;/窗口类的扩展字节数 int cbWndExtra;/窗口实例的扩展字节数 HINSTANCE hInstance;/窗口实例句柄 HICON hIcon;/类图标的句柄 HCURSOR hCursor;/类鼠标指针的句柄 HBRUSH hbrBackground;/背

10、景画刷句柄 LPCSTR lpszMenuName;/窗口菜单名称 LPCSTR lpszClassName;/窗口类名 WNDCLASS3.2.3 矩形结构typedef struct tagRECT LONG left;/左上X坐标 LONG top;/左上Y坐标 LONG right;/右下X坐标 LONG bottom;/右下Y坐标 RECT3.2.4 过程参数Windows消息的wParam参数保存了与消息相关的信息,如产生消息的窗口句柄和ID号(以后都称为“标识符”);lParam参数则保存了一些与消息无关的信息,如消息产生时鼠标位置的坐标值等。3.3 消息处理与窗口过程3.3.1

11、 消息循环在调用了UpdateWindows之后,窗口就会出现在显示器上,此时Windows就为应用程序维护了一个“消息队列”。当Windows侦测到程序的用户键盘和鼠标输入数据时,就将输入的时间转化为一个“消息”,并将此消息放到程序的消息队列中。所有的应用程序都是通过“消息循环的代码”从消息队列中取出消息,代码如下:while( GetMessage( &msg, NULL, 0, 0) ) TranslateMessage( &msg ); DispatchMessage( &msg ); 从消息队列中取出消息的函数为GetMessage,函数定义如下:BOOL GetMessageA(L

12、PMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);lpMsg:消息结构指针。hWnd:窗口句柄, 当设置为NULL时是获取所有窗口的消息。wMsgFilterMin: 获取消息ID编号最小值。wMsgFilterMax:获取消息ID编号最大值。返回值:只要消息队列中取出的消息message域不为WM_QUIT(0x0012),GetMessage就返回一个非零值。 之后进行一些键盘消息的转换:TranslateMessage( &msg );最后发送给窗口过程进行消息的处理:DispatchMessage(&msg);3.3

13、.2 消息处理每个窗口都有与之相对应的窗口过程。窗口过程能够确定其窗口的外观和行为特性,这是通过对进入到窗口过程中的窗口消息的处理完成的。在第1章中,已经讲过了窗口过程的例子,虽然它只处理几个简单的消息,但确实实现了一个标准的窗口。窗口过程总是与已注册的特定窗口类相关联的,一个应用程序可以有几个窗口类,基于每个窗口类都可以创建多个窗口(通过CreateWindow等函数创建)。也就是说,同一个窗口过程可能要处理几个窗口中产生的消息。但是,在多窗口的应用程序中,Windows怎样辨别消息队列中的消息该发给哪个窗口的窗口过程处理呢?在WinMain函数中创建窗口如下所示:hWnd = Create

14、Window (LPCTSTR lpClassName , /注册窗口类名 /与窗口相关的其他参数 )从以上代码可以看到,在创建窗口时,至少要完成两项工作:一项将窗口类及其相关联的窗口过程与新窗口关联起来,另一项是得到新窗口的句柄。这样,当新窗口中产生消息时,Windows的消息循环可以根据这个句柄找到相应的消息处理过程(窗口过程)。下面介绍窗口过程的定义,读者就会更易明白Windows的这一处理过程。LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )注意:窗口过程的hwnd参数指明

15、了产生消息的窗口,其他几个参数则表明了消息信息。这与MSG结构的前四个域是相同的。WndProc被声明为CALLBACK(回调函数),回调函数是输出函数中特殊的一种,能够在Windows环境下直接调用。一个应用程序至少有一个回调函数,因为在应用程序处理消息时,Windows会调用回调函数,即窗口过程。它对应于一个活动的窗口,回调函数必须向Windows注册,Windows实施相应的操作后就进行回调。窗口过程的名字可以任意指定,只需与窗口类结构的lpfnWndProc域指定的名字相同即可。窗口过程函数体负责接收和处理由消息循环发送来的消息。通常,通过switch和case结构确定窗口过程对发送来

16、的哪些消息进行处理,而不予处理的消息可以交给默认的窗口过程DefWindowProc来处理。switch(uMsg) case WM_PAINT:break; case WM_KEYDOWN: break; case WM_DESTROY: break; default: return(DefWindowProc(hWnd,uMsg,wParam,lParam);DefWindowProc 为窗口过程不予处理的消息提供默认的处理,由于在窗口过程中,有很多重要的工作需要Windows来完成,如果不能及时的将这些消息进行处理,则运行过程中会出现很多问题。3.4 几个重要的概念(1) 句柄Windo

17、ws中,句柄使用十分频繁,那么什么是句柄呢?句柄是一个32位的数,程序通过它来引用相应的对象(比如学号,房间号等)。(2) 标示符(标示符前缀)CS_HREDRAW,CS_VREDRAWDT_SINGLELINE,DT_VCENTERWM_KEYDOWN,WM_DESTORYCS:窗口类风格选项,DT:绘制文本选项,WM:窗口消息选项(3) 数据类型WPARAM在win16系统中位WORD(16位),LPARAM定义为LONG(32位)。WPARAM在win32系统中定义为UINT(32位),LPARAM定义为LONG(32位)。LRESULT是一个句柄LONG类型。3.5 采用C+进行封装设

18、计的必要性 上例给出了一个输出单行Hello World的示例程序。如果需求改为输出多行不同颜色的Hello Word,就要多次复制响应的代码。如果采用面向对象的设计,就可以很好的解决这一问题,也就是C+中的封装特性:class CTextpublic:CText()uRed = 0;uGreen = 0;uBlue = 0;CText();public:void SetRandColor(void)uRed = rand() % 255;uGreen = rand() % 255;uBlue = rand() % 255;void ShowText(HDC hdc,RECT &rect,ch

19、ar *pText)SetTextColor( hdc, RGB(uRed, uGreen, uBlue);DrawText (hdc, pText, -1, &rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;protected:int uRed, uGreen, uBlue;可以申请多个对象如下:CText t1,t2,t3,;设置颜色与现实函数如下:ti.SetRandColor();ti.ShowText(hdc,rect,1:Hello, World!);由此可见,在对原始处理进行封装后,可以简便、多次的调用同段功能,完整的程序代码如Hell

20、o_Class文件夹所示。3.6 思考题以CText类为基类,通过隐藏的方式构造一个新类,设计一个可以改变Hello World输出位置的ShowText接口。第二章 GDI编程2.1 什么是GDI?Windows GDI(图形设备接口)是Windows系统的重要组成部分,是Windows系统实现图形界面的基础。绝大多数图形界面应用程序的显示和输出都离不开GDI,利用GDI提供的众多结构及函数,应用程序可以很方便地在屏幕、打印机及其它设备上绘制图形、文本等操作。GDI的显著优点即是“设备无关性”,在Windows系统中,有个动态链接库GDI32.DLL,负责图形的输出。该动态链接库为应用程序提

21、供了访问设备驱动程序的方法,因此,GDI可以看做是图形设备硬件与应用程序之间交互的高级接口。GDI的内容涉及广泛,本章将围绕GDI的几个典型例子进行介绍:画笔、画刷、点及线的绘制、位图的显示等,最后将通过一个类将这些内容封装起来,达到方便个性化输出的目的。2.2 GDI的一些基本结构和接口2.2.1 颜色的表示与设置Windows采用32位无符号整形表示色彩,即COLORREF值,按照红、绿、蓝三种颜色的亮度指定一种颜色,其中,每种颜色的值占8位,范围从0-255,COLORREF的结构如下:3124231615870 |-蓝-| |-绿-| |-红-|COLORREF的结构定义如下:COLO

22、RREF RGB(BYTE byRed, BYTE byGreen, BYTE byBlue);另外,有三个宏可以获取一个COLORREF值中包含的红、绿、蓝分量值,利用如下的三个宏可以灵活地对颜色进行操作:BYTE GetRValue(DWORD rgb);BYTE GetGValue(DWORD rgb);BYTE GetBValue(DWORD rgb);2.2.2 画笔逻辑画笔是一种GDI对象,有线宽、线型、颜色等属性。逻辑画笔分为两类:Cosmetic(装饰)画笔与Geometric(几何)画笔。Cosmetic画笔包含三个属性:线宽(width)、线型(style)及颜色(colo

23、r)。它有固定的线宽,不具备按比例缩放的特性,但优点是绘制速度快,在一些适量图形系统中得到了广发应用。Geometic画笔除了以上三个属性外,还有式样(pattern)、填充图案(hatch)、端点样式(end style)和连接样式(joint style)四个属性。画笔宽度以逻辑单位计算,因此可按比例缩放。下面给出一些创建WIndows画笔的API:1. HPEN CreatePen (int fnPenStyle, int nWidth, COLORREF crColor) / Cosmetic画笔/ 画笔句柄 CreatePen (线型,线宽,颜色)2. HPEN CreatePenI

24、ndirect (CONST LOGPEN *lplgpn) / Cosmetic 画笔/画笔句柄 CreatePenIndirect (逻辑画笔结构指针)Typedef struct tagLOGPEN UINT lopnStyle; POINT lopnWidth; COLORREF lopnColor; LOGPEN, *PLOGPEN;3. HPEN ExtCreatePen (DWORD dwPenStyle, DWORD dwWidth, CONST LOGBRUSH *lplb, DWORD dwStyleCount, CONST DWORD *lpStyle) /Geometi

25、c 画笔/画笔句柄 ExtCreatePen (画笔样式,宽度,逻辑画刷指针,用于创建自定义型画笔,与dwPenStyle一样)注意,以上三个创建画笔的函数并没有与设备相关联,在绘图时需要与具体的设备描述符相关联。Windows 为我们提供了SelecctObject函数将创建好的画笔选入设备描述符表:SelectObject (hdc, hPen);在WM_DESTROY消息期间,应用程序即将结束,因此应将已创建的画笔删除,以释放系统资源,同时将最初保存的系统默认画笔选入设备描述表中:DeletObject(hPen);SelectObject(hdc,oldPen);2.2.3 画刷逻辑画

26、刷也是一种GDI对象,应用程序使用逻辑画刷填充Rectangle,Ellipse等图形的内部区域。一般画刷是一个8*8的位图,利用水平和垂直重复填充图形内部区域。由于画刷与画笔相似,因此在实际应用中可以查阅相关资料。2.2.4 GDI绘图函数GDI绘图函数是实现图形界面窗口内容的最基本的工具,本节将画点和画线的内容进行介绍,需要注意的是,所有的GDI绘图函数都使用逻辑坐标。COLORREF SetPixel (HDC hdc,int nXPos,int nYPos, COLORREF crColor);/ 颜色类型 SetPixel (设备环境句柄,横坐标,纵坐标,颜色)COLORRE Get

27、Pixel (HDC hdc,int nXPos,int nYPos);/ 颜色 GetPixel (设备环境句柄,横坐标,纵坐标)BOOL MoveTo (HDC hdc, int X, int nY);/ MoveTo (设备环境句柄,横坐标,纵坐标)BOOL LineTo (HDC hdc, int nXEnd, int nYEnd);/ LineTo (设备环境句柄,终点横坐标,终点纵坐标)2.2.5 GDI 映射模式映射模式是设备描述表的属性之一,它影响任何客户区的绘图操作,与之密切相关的内容是坐标系统、窗口和视口的设置。通过这些设备描述表属性,程序员就可以根据最方便的模式在客户去内

28、进行绘图,而不是按照默认的映射模式(坐标原点位于左上角,以像素位单位)来绘图。(1) 坐标系统在Windows应用程序中,坐标系统分为两种:设备坐标与逻辑坐标。设备坐标:直接与硬件设备的显示相关,以像素为度量单位。水平轴的正向从左到右,垂直轴的正向从上到下。逻辑坐标:是一种允许自定义的坐标系统,坐标轴方向、单位和原点位置都可以重新定义。例如将坐标原点设在客户区左下角,Y轴正向向上,逻辑单位为1cm。(2) 窗口和视口窗口和视口是Windows GDI中的两个重要概念,从逻辑坐标映射位设备坐标实际上就是从窗口到视口的映射,也就是说,窗口对应逻辑坐标,视口对应设备坐标。Windows提供了该表窗口

29、及视口原点的API,同时也提供了逻辑坐标与设备坐标的转换接口,理解上可以将窗口和视口看做画框和背景布的关系。2.3采用C+进行封装的设计为了开发的需求,通常会对某些Windows API进行个性化的封装,这些对于数据及接口的管理影响很大,比如创建画笔的函数包含三个之多,名称各异。为了使我们开发的程序易于理解,增加类设计的扩展及易用性,通常采用封装进行开发。本节应用WIndows画笔进行实验,说明面向对象设计的必要性,直接采用API设计得到的绘制直线的部分代码如下:LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,

30、LPARAM lParam) HDC hdc ; PAINTSTRUCT ps ; RECT rect ; int i; int x_length, y_length; static HPEN oldPen, cosPen4, geoPen3; LOGPEN lp; LOGBRUSH lb; POINT iPoint; switch (message) case WM_CREATE: / 创建Cosmetic 画笔 cosPen0 = CreatePen(PS_DASH, 5, RGB(255, 0, 0); cosPen1 = CreatePen(PS_DASHDOT, 5, RGB(255

31、, 255, 0); iPoint.x = 1; lp.lopnStyle = PS_DASHDOTDOT; lp.lopnWidth = iPoint; lp.lopnColor = RGB(255, 0 , 0); cosPen2 = CreatePenIndirect(&lp); lb.lbStyle = PS_SOLID; lb.lbColor = RGB(255, 0, 0); lb.lbHatch = 0; cosPen3 = ExtCreatePen(PS_COSMETIC | PS_DOT, 1,&lb, 0, NULL); return 0 ; case WM_PAINT:

32、hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; x_length = abs(rect.right - rect.left); y_length = abs(rect.bottom - rect.left); oldPen = SelectObject(hdc, GetStockObject(NULL_PEN); MoveToEx(hdc, x_length/10, y_length/10, NULL); LineTo(hdc, x_length*4/10, y_length/10); / 用Cosmetic 画笔绘制直

33、线 for(i = 0 ; i 4 ; i+) SelectObject(hdc, cosPeni); MoveToEx(hdc, x_length/10, y_length*(2*i+3)/10, NULL); LineTo(hdc, x_length*4/10, y_length*(2*i+3)/10);TextOut(hdc, x_length/10, y_length*(2*i+2)/10, cosArrayi, lstrlen(cosArrayi); SelectObject(hdc , oldPen); EndPaint (hwnd, &ps) ; return 0 ; case

34、WM_DESTROY: for(i = 0 ; i hdc = hdc;:SelectObject(hdc,cosPen);/注意hdc的保存 void Line (int x1,int y1,int x2,int y2) MoveToEx(hdc,x1,y1,NULL);LineTo(hdc,x2,y2); void Delete (void) :DeleteObject(cosPen);private: HPEN cosPen; HDC hdc;CCosPen CosPen4;LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wP

35、aram, LPARAM lParam ) switch( uMsg ) case WM_CREATE: LOGPEN lp; LOGBRUSH lb; POINT iPoint; CosPen0.CreatePen(PS_DASH, 5, RGB(255, 0, 0); CosPen1.CreatePen(PS_DASHDOT, 5, RGB(255, 255, 0); iPoint.x = 1; lp.lopnStyle = PS_DASHDOTDOT; lp.lopnWidth = iPoint; lp.lopnColor = RGB(255, 0 , 255); CosPen2.Cre

36、atePen(&lp); lb.lbStyle = PS_SOLID; lb.lbColor = RGB(200, 0, 0); lb.lbHatch = 0; CosPen3.CreatePen(PS_COSMETIC | PS_DOT, 1,&lb, 0, NULL); break; case WM_PAINT : int i; HDC hdc; PAINTSTRUCT ps;HGDIOBJ oldPen; RECT rect ;GetClientRect (hWnd, &rect) ;int x_length = abs(rect.right - rect.left);int y_len

37、gth = abs(rect.bottom - rect.left);hdc = BeginPaint(hWnd, &ps);oldPen = SelectObject(hdc, GetStockObject(NULL_PEN);/ 用Cosmetic 画笔绘制直线for(i = 0 ; i 4 ; i+) CosPeni.Init(hdc); CosPeni.Line( x_length/10, y_length*(2*i+3)/10,x_length*4/10, y_length*(2*i+3)/10); TextOut(hdc, x_length/10, y_length*(2*i+2)/10, cosArr

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁