Windows API for 2000XP实例精解 - search readpudncom.ppt
2019/10/23,1,Windows 编程技术,2005年9月,2019/10/23,2,Windows API for 2000/XP实例精解,第一章 概述第二章 文本输出和滚动条第三章 深入GDI第四章 键盘、鼠标和计时器第五章 资源第六章 Windows 2000标准控件第七章 驱动器、目录和文件,2019/10/23,3,第一章 主要内容,Windows 家族简介Win32 API 基础Win32 API 应用程序框架结构Unicode字符,2019/10/23,4,第一章 §3 Win32 API 应用程序框架结构,Demo: “Hello”当按下键盘上的任意一个键时,窗口显示的文本颜色将随机地发生改变。应用程序实例,i,2019/10/23,5,第一章 §3 Win32 API 应用程序框架结构(二),头文件的类型函数和数据结构消息结构窗口类结构矩形结构消息机制消息循环消息及消息处理句柄、标识符,i,i,i,i,i,i,i,i,i,2019/10/23,6,头文件的类型,在每一个用C编写的Windows程序中,都会用到一个头文件WINDOWS.H。它是包含了其它头文件的综合文件。WINDOWS.H只是一个包含其他头文件的头文件,他所包含的头文件有:WINDEF.H基本类型的定义。WINNT.H支持Unicode的类型定义。WINGDI.H图形设备接口的定义。WINUSER.H用户接口的定义。WINBASE.H内核函数的定义。WINSOCK.H和WINSOCK2.H用于网络通信的套接字的定义。,2019/10/23,7,函数和数据结构,在Windows应用程序中有一个入口函数WinMain,int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow),该句柄唯一地标识了该程序,为了与早期的版本兼容,这里未用,其值总是NULL,运行程序的命令行参数串,程序运行时的显示方式(正常、最大化、最小化等),2019/10/23,8,消息结构,消息结构定义一个用于发送的消息,在程序接收到消息后,根据其中包含的信息做出相应的处理。,typedef struct tagMSG HWND hwnd;/获得消息的窗口句柄 UINT message;/消息标志 WPARAM wParam;/消息的附加信息 LPARAM lParam;/消息的附加信息 DWORD time;/消息的发送时间 POINT pt;/当消息发送时,鼠标所处的屏幕位置 MSG, *PMSG,2019/10/23,9,窗口类结构,窗口类用来标识处理窗口消息的窗口过程。在一个窗口类的基础上可以创建多个窗口的实例。,typedef struct tagWNDCLASSW UINT style;/ 窗口类的风格 WNDPROC lpfnWndProc;/ 指向窗口过程的指针 int cbClsExtra;/ 分派给窗口类的扩展的字节数 int cbWndExtra;/ 分派给窗口实例的扩展的字节数 HINSTANCE hInstance;/ 窗口的实例句柄 HICON hIcon;/ 类图标的句柄 HCURSOR hCursor;/ 类鼠标指针的句柄 HBRUSH hbrBackground;/ 刷新背景所用的画刷的句柄 LPCWSTR lpszMenuName;/ 窗口类包含的菜单的名称 LPCWSTR lpszClassName;/ 窗口类名 WNDCLASSW, *PWNDCLASSW;,例如:,2019/10/23,10,窗口类结构实例,WNDCLASS wc; / Register the main application window class. /. wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = NULL; wc.lpszClassName = lpszAppName;,2019/10/23,11,注册窗口类,if ( !RegisterClass( ,2019/10/23,12,创建窗口函数,HWND CreateWindow( LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam );,2019/10/23,13,消息机制,主要解决两个问题消息循环消息及消息处理,i,i,2019/10/23,14,消息循环,while( GetMessage( ,只要从消息队列中取出的消息的message域不为WM_QUIT,则返回非零,,进行一些键盘消息转换,把消息发送到窗口处理程序中,或者说,回调窗口处理程序,msg结构,2019/10/23,15,消息及消息处理,窗口过程接收的每一个消息都是用数值标示的,并在WINUSER.H中作了定义。 例如:WM_PAINT, WM_KEYDOWN, WM_DESTROY一般用switch和case的结构来确定窗口过程接收到的是什么消息。,例如,2019/10/23,16,switch case结构,switch (message) case WM_CREATE:.return 0 ; case WM_SIZE:.return 0 ; case WM_PAINT :.return 0 ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; return DefWindowProc (hwnd, message, wParam, lParam) ;,2019/10/23,17,WM_PAINT消息,(a) 在创建窗口时,客户区将变得无效。此时,整个客户区都是无效的。在程序运行函数UpdateWindow时,将发送第一个WM_PAINT的消息,只是窗口过程在客户区域画一些东西。(b) 改变应用程序窗口的大小时,窗口的整个客户区将变得无效。因为在定义窗口类的第一个域style时,曾经将标志设置为CS_HREDRAW和CS_VREDRAW,这一设置将指示Windows在窗口改变大小后,使整个窗口无效。此时,又将发送一个WM_PAINT的消息。(c) 在移动窗口并发生窗口重叠时,窗口客户区将变得无效。此时,Windows将不会保存本窗口中被另外一个窗口覆盖部分的客户区内容。此时,窗口客户区将变成无效,发送一个WM_PAINT的消息。,2019/10/23,18,对WM_PAINT消息的处理,对消息WM_PAINT的处理,一般都从BeginPaint函数调用开始,其调用方法是: HDC hdc; PAINTSTRUCT ps; hdc = BeginPaint(hWnd, ,2019/10/23,19,WM_KEYDOWN消息,当系统侦测到用户键盘按键信息时,就会产生一个WM_KEYDOWN的消息,2019/10/23,20,WM_DESTROY消息,这个消息指示Windows根据用户输入的命令来清除窗口。该消息在用户单击“Close”按钮或在程序的系统菜单(通过单击窗口图标或使用快捷键Alt+space获得)。通过调用函数PostQuitMessage以标准的方式响应WM_DESTROY消息以退出消息循环。,2019/10/23,21,WinMain ( hInst, hPrev, )MSG msg;ReigsterClass ();CreateWindow ();ShowWindow ();UpdateWindow ();While ( GetMessage (,WndProc ( hWnd, msg, wParam, lParam )switch ( msg ) case WM_CREATE : case WM_PAINT : case WM_KEYDOWN : case WM_DESTROY : PostQuitMessage(0); break; default : return( DefWindowProc ( . ) );return (0);,case WM_CLOSE : DestroyWindow (.);,2,1,3,5,6,7,8,消息队列,WM_CLOSE,WM_DESTROY,WM_QUIT,WM_CREATE,2019/10/23,22,1、初始化过程调用CreateWindow,为程序建立了一个窗口,送出WM_CREATE直接给窗口函数,后者可在此做些初始化操作2、程序运行过程中,不断以GetMessage从消息队列中抓取消息,如果这个消息是WM_QUIT, GetMessage会传回0而结束循环,进而结束整个程序3、 DispatchMessage把消息分派至窗口函数。消息将在该处被识别并处理4、程序不断进行2和3的操作5、当使用者按下系统菜单的Close命令项时,系统送出WM_CLOSE。通常程序不拦截此消息,于是DefWindowProc处理它6、 DefWindowProc收到WM_CLOSE后,调用DestroyWindow把窗口清除。 DestroyWindow本身又会送出WM_DESTROY7、程序对WM_DESTROY的标准反应是调用PostQuitMessage8、 PostQuitMessage没什么其它操作,就只送出WM_QUIT消息,准备让消息循环中的GetMessage取得,如步骤2,结束消息循环,2019/10/23,23,句柄,句柄是一个32位的数,代表一个对象。常用的句柄有:HANDLE:指向对象的句柄。HBITMAP:指向位图的句柄。HBRUSH:指向画刷的句柄。HCURSOR:指向鼠标光标的句柄。HDC:指向设备环境的句柄。HFILE:指向文件的句柄。HGLOBAL:指向全局内存块的句柄。HMETAFILE:指向元文件的句柄。HMODULE:指向模块的句柄。HMUNU:指向菜单的句柄。HPEN:指向画笔的句柄。HWND:指向窗口的句柄。,2019/10/23,24,标识符,在Windows头文件中定义CS 窗口类风格选项CW 创建窗口选项WM 窗口消息选项MB 消息框选项IDI 图标的ID号IDC 光标的ID号,2019/10/23,25,数据类型,以C/C+的类型作为Windows程序的基本类型,为了区别某些基本类型相同,但意义不同的类型,因此在WINDOWS.H文件中用容易记忆的标示符进行重新定义,如HANDLE, HWND, UINT, BYTE, WORD, DWORD, LONG, BOOL, LPSTR等等。,i,2019/10/23,26,第一章 §4 Unicode字符,Unicode字符是ASCII字符编码的扩展。 在Unicode中,每个字符是16位的。 在C语言中,涉及到的字符都只占一个字节,即sizeof(char)为1。引入Unicode和宽字符的概念后,char数据类型没有改变。但用wchar_t来表示基于双字节的。即:typedef unsigned short wchar_t;,2019/10/23,27,第二章 主要内容,窗口过程与消息文本输出滚动条,2019/10/23,28,窗口过程与消息,窗口过程总是与已注册的特定窗口类相关联的,一个应用程序可以有几个窗口类,基于每个窗口类都可以创建多个窗口(通过CreateWindow等函数创建)。 WndProc被声明为CALLBACK回调函数,回调函数是输出函数中特殊的一种,能够在Windows环境下直接调用。一个应用程序至少有一个活动的窗口,因为在应用程序处理消息时,Windows会调用回调函数,即窗口过程。窗口过程的名字可以任意指定,只需与窗口类结构的lpfnWndProc域指定的名字相同即可。,2019/10/23,29,CreateWindow函数实例,hWnd = CreateWindow( lpszAppName, lpszTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL );,2019/10/23,30,窗口处理函数WndProc,LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )switch( uMsg ) case WM_PAINT :break;case WM_DESTROY :PostQuitMessage(0);break; default :return( DefWindowProc( hWnd, uMsg, wParam,lParam ) ); return( 0L );,2019/10/23,31,lpfnWndProc域,WNDCLASS wc; / Register the main application window class. /. wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 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;,2019/10/23,32,文本输出,文本输出是Win32应用程序最常见的客户区图形输出(文本输出也被看做是GDI图形输出),在字处理、排版等系统中应用广泛。文本输出程序示例获取设备描述表 WM_PAINT消息的响应和处理 字体的设置 文本的格式化输出 文本输出函数比较,2019/10/23,33,文本输出程序示例,Demo: TextOut1.dsw他利用GDI函数TextOut输出了两段文本,并采用了一些文本格式化技巧,实现文本对齐等。SetTextAlign实现文本对齐等。SetTextAlign(hdc,A_RIGHT| A_TOP);常用的文本对齐样式有:TA_LEFT,TA_CENTER,TA_RIGHT,TA_TOP,TA_BOTTOM,TA_BASELINE,2019/10/23,34,获取设备描述表,设备描述表(DC:Device Context)是GDI内部保存的一种数据结构,它定义了一系列的图形对象、相关的属性及绘图模式等一些信息。Windows GDI函数依赖于设备描述表,实际上这些函数在设备描述表环境中显示文本和图形设备描述表是Windows应用程序,也是输出设备之间的桥梁。所以,在屏幕上和打印机上输出文本和图形的操作过程是一样的。当程序获得设备描述表句柄后,Windows就是用默认的属性值填充设备描述表结构。然后就可以用这些获得的设备环境使用GDI函数绘制文本和图形了。当然,有一些GDI函数可以获取和改变设备描述表的属性值。,2019/10/23,35,获取设备描述表(2),调用BeginPaint返回设备描述表句柄 调用GetDC函数获得设备描述表句柄 使用CreateDC函数获得设备描述表句柄 其它获得设备描述表句柄的函数,2019/10/23,36,调用BeginPaint返回设备描述表句柄,PAINTSTRUCT ps ;hdc = BeginPaint (hwnd, ,2019/10/23,37,调用GetDC函数获得设备描述表句柄,在一些非WM_PAINT消息的处理期间,也许程序需要绘制客户区或者想得到有关设备描述表的信息。这是利用GetDC函数可以返回设备描述表句柄,hdc=GetDC(hwnd);用GetDC获得的设备描述表句柄需要用ReleaseDC函数释放。,2019/10/23,38,使用CreateDC函数获得设备描述表句柄,前面两种方法都是针对视频显示器的,但获取设备描述表更通用的函数是CreateDC。他不但可以获得视频显示器的设备描述表句柄,还可以获得打印机及其他输出显示设备的设备描述表句柄。hdc = CreateDC(pszDriver,pszDevice,pszOutput,pData);同样,利用DeleteDC(hDC)函数可以释放设备描述表句柄。,2019/10/23,39,其它获得设备描述表句柄的函数,2019/10/23,40,WM_PAINT消息的响应和处理,Windows是一个多任务环境,显示设备视为多个应用程序公用的,某个应用程序的窗口上面可能被对话框或窗口覆盖。当撤销这些对话框或窗口时,这个应用程序窗口中就有一个“空洞”,这个“空洞”就是一块无效的客户区域。像这种情况还很多。比如改变窗口尺寸后,客户区的部分内容被遮盖,窗口最消化、客户区的滚动等WM_PAINT消息在Windows消息队列中的优先级很低,这就是其他许多消息能够先于WM_PAINT消息被送交给窗口过程处理。只有在没有其他消息的情况下,才从队列中取出WM_PAINT消息进行处理。这样做是为了让应用程序首先完成影响窗口显示结果的其他操作,不致因为频繁地执行输出操作而引起显示器的闪烁。,2019/10/23,41,WM_PAINT消息的响应和处理(2),Windows并非WM_PAINT消息的唯一来源,使用InvalidateRect或InvalidateRgn函数也可以产生绘图窗口的WM_PAINT消息。这两个函数把客户区部分或全部标记成无效区域而要求重新显示。 InvalidateRect 重画一个指定矩形框范围内的客户区InvalidateRgn 重画一个指定范围内的客户区。,2019/10/23,42,InvalidateRect和InvalidateRgn,BOOL InvalidateRect (HWND hWnd, CONST RECT *lpRect, BOOL bErase);BOOL InvalidateRgn (HWND hWnd, HRGN hRgn ,BOOL bErase);,2019/10/23,43,字体的设置,使用GetTextMetrics函数获取设备描述表中的字体信息使用CreateFont或CreateFontIndirect函数创建逻辑字体使用SelectObject函数将字体选入DC,2019/10/23,44,文本的格式化输出,Windows API提供了对文本输出格式的强有力的支持,主要有三类函数可以用于文本的格式化。获取和设置设备描述表的文本格式化属性的函数。获取字体宽度信息的函数。获取字符串宽度和高度信息的函数。,2019/10/23,45,文本的格式化函数(1),1 文本对齐函数(1) SetTextAlign 设置文本基于输出参考点的对齐方式。 (2) GetTextAlign 获取文本基于输出参考点的对齐方式。,2019/10/23,46,文本的格式化函数(2),2 调整字符间距函数(1) SetTextCharsetExtra 用于在文本输出是调整字符的输出间距,默认的字符间距为零。(2) GetTextCharsetExtra 程序可以通过本函数获取当前的字符间距。,2019/10/23,47,文本的格式化函数(3),3 文本和背景颜色函数 (1) SetTextColor 改变指定环境中的文本颜色。 (2) SetBkColor 改变指定环境中的背景颜色。 (3) GetTextColor 获得指定环境中的文本颜色。 (4) GetBkColor 获得指定环境中的背景颜色。,2019/10/23,48,文本的格式化函数(4),4 段落对齐函数(1) GetTextExtentPoint32 用于计算指定字符串的长度和宽度。 (2) SetTextJustification 用于指定在字符串中,空格应占的字符数。,2019/10/23,49,文本输出函数比较,DrawTextExExtTextOutTabbedTextOut,2019/10/23,50,滚动条,滚动条的特性和设置滚动条的创建:在CreateWindow的第三个参数即窗口风格表示附中包括风格WS_VSCROLL和WS_HSCROLL改进的文本输出程序实例TextOut2.dsw滚动条消息处理当用户单机滚动条或者拖曳滚动框时,Windows给窗口过程发送WM_VSCROLL和WM_HSCROLL消息。这两个消息的wParam参数的低字节包含了一个称为“通知码”的标识符,分别标识每条消息产生的原因。,2019/10/23,51,WS_VSCROLL设置,hwnd = CreateWindow (szAppName, TEXT ("TextOut2 with Scroll"), WS_OVERLAPPEDWINDOW | WS_VSCROLL ,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL) ;,设置垂直滚动条,2019/10/23,52,滚动条通知码,#define SB_LINEUP 0#define SB_LINELEFT 0#define SB_LINEDOWN 1#define SB_LINERIGHT 1#define SB_PAGEUP 2#define SB_PAGELEFT 2#define SB_PAGEDOWN 3#define SB_PAGERIGHT 3#define SB_THUMBPOSITION 4#define SB_THUMBTRACK 5#define SB_TOP 6#define SB_LEFT 6#define SB_BOTTOM 7#define SB_RIGHT 7#define SB_ENDSCROLL 8,2019/10/23,53,滚动条信息结构和相关函数,滚动条信息结构和相关函数typedef struct tagSCROLLINFO UINT cbSize;/ SCROLLINFO结构的大小 UINT fMask;/ 标定对结构进行的操作方式 int nMin; / 滚动位置最小值 int nMax; / 滚动位置最大值 UINT nPage;/ 窗口显示的页的大小 int nPos; / 滚动条当前位置 int nTrackPos;/ 当前拖动时滚动框的位置 SCROLLINFO, *SCROLLINFO;fMask是一些以SIF为前缀的标志,例如,当需要设置滚动条位置时,就需要将其设置为SIF_POS标志。其他标志还有SIF_RANGE和SIF_PAGE等。,2019/10/23,54,滚动条信息结构和相关函数(2),1 SetScrollInfo此函数用于设置滚动条的有关信息2 GetScrollInfo此函数用于获得滚动条的有关信息3 ScrollWindowEx滚动指定的客户区内窗口的内容,2019/10/23,55,第三章 主要内容,Windows GDI 的基本概念和原理颜色、画笔和画刷GDI 绘图函数GDI 映射模式位图,2019/10/23,56,Windows GDI的基本概念和原理,Windows GDI即图形设备接口,是Windows系统的重要组成部分,是Windows系统实现图形界面的基础。 GDI 绘图函数具有设备无关性从程序员的角度看,GDI提供了几百个函数调用和一些相关的结构、宏和数据类型,便于程序员对显示器、打印机等硬件设备进行图输出 设备描述表;程序有绘图请求时被创建并得以维持,他负责为程序准备相关的信息,起到为程序屏蔽具体物理设备的作用。当程序希望获得具体物理设备信息时,可以通过一些GDI函数来获得。,2019/10/23,57,颜色、画笔和画刷,画笔和画刷是应用程序进行图形输出时最常用的工具,应用程序能够选择Windows系统备用的画笔和画刷进行绘图,也能够创建自定义的画笔和画刷,并将他们选入设备描述表中,按照自定义的风格进行图形绘制。色度学理论认为,任何颜色都可以由红、绿、蓝三种基本颜色按不同的比例混合得到,例如:黄色可以由红、绿各一半混合而成。因此,红、绿、蓝被称为三原色,简称RGB三原色。,2019/10/23,58,颜色,Windows采用32位无符号长整数表示色彩COLORREFCOLORREF RGB (BYTE r, BYTE g, BYTE b) 获取红、绿、蓝的分量值:BYTE GetRValue (DWORD rgb);BYTE GetGValue (DWORD rgb);BYTE GetBValue (DWORD rgb);GetDeviceCaps (HDC hdc, int nIndex),2019/10/23,59,关于画笔,逻辑画笔是一种GDI对象,有线宽、线形、颜色等属性备用画笔(stock pen) hPen = GetStockObject(WHITE_PEN); hOldPen = SelectObject(hdc,hPen);自定义画笔Cosmetic: 线宽(width)、线形(style)、颜色(color)Geometric:线宽(width)、线形(style)、颜色(color) 式样、填充图案、端点样式、连接样式,2019/10/23,60,关于画笔,创建自定义画笔所使用的函数CreatePenCreatePenIndirectExCreatePen创建画笔的工作大多在WM_CREATE消息期间完成,Cosmetic画笔,Geometric画笔,2019/10/23,61,关于画笔,在WM_DESTROY消息期间,应用程序即将结束,程序不再需要以创建的逻辑画笔,所以应该将这些画笔删除以释放其占用的系统资源。DeleteObject(hPen);SelectObject(hdc,hOldPen);画笔程序实例,PenCreating.cpp,2019/10/23,62,画刷相关函数和结构,CreateSolidBrush 创建一个solid画刷(solid画刷使用指定的颜色定义的纯色画刷)GetStockObject 创建一个stock画刷CreateHatchBrush 创建一个hatch画刷,hatch画刷是以一定的图案进行填充的位图,图形不在以纯色填充,而是一些纹理图案。CreatePatternBrush 创建基于GDI位图的pattern画刷。CreateBurshIndirect 此函数使用定义的结构间接创建画刷。,2019/10/23,63,GDI绘图函数与结构,GDI绘图函数是实现图形界面窗口内容的最基本的工具 1 画点和画线2 绘制曲线 3 绘制填充区域,2019/10/23,64,画点和画线,(1) SetPixel此函数用于设置指定点的颜色信息(2) GetPixel此函数用于获得指定点的颜色信息 (3) LineTo此函数使用设备描述表中的画笔来画出一条线 (4) MoveToEx此函数用于移动画笔到指定的点,2019/10/23,65,画点和画线(2),(5) Polyline此函数用于一次绘制一条连续直线,各段直线的段点由数组指定。(6) PolylineTo此函数把当前画笔所在的点作为连续直线的起点,并把连续直线的终点作为新的画笔位置点,用于一次绘制一条连续直线。(7) PolyPolyline此函数用于一次绘制几条连续直线,常用在希望一次性地定义并绘制整个图形,2019/10/23,66,绘制曲线,(1) Arc 此函数以(0,0)为基准点绘制椭圆弧线。在默认情况下,椭圆弧按逆时针方向绘制。(2) ArcTo 绘制椭圆弧线。在默认情况下,椭圆弧按逆时针方向绘制。有一条直线从当前位置连到椭圆弧开始点,当前位置更新为椭圆弧结束点。,2019/10/23,67,绘制曲线,(3) PolyBezier 此函数用于绘制一条或多条三次Bezier样条曲线。(4) PolyDraw此函数用于绘制一系列的直线和三次Bezier样条曲线。,2019/10/23,68,绘制填充区域,(1) Rectangle 从左上角(upX,upY)向右下角(lowX,lowY)绘制矩形.用当前笔画显示矩形,用当前画刷自动填充矩形.(2) Ellipse 通过指定椭圆的边界矩形来定义椭圆. (3) Pie 扇形图是一个包含弧和两条线的对象,这两条线分别以弧的端点和中心点为端点 (4) Chord 此函数用于绘制弦图 (5) RoundRect 绘制圆角矩形(6) Polygon 绘制多边形的填充区域,2019/10/23,69,GDI映射模式,坐标系统 几种映射模式的比较 窗口和视口映射模式程序实例 MapMode,2019/10/23,70,坐标系统,在Windows应用程序中,有两种坐标系统:设备坐标和逻辑坐标。设备坐标系统直接与硬件设备的显示相关,以像素为度量单位。水平轴(即x轴)的正方向从左向右,垂直轴(即y轴)的正方向从上向下,并且整个坐标轴的单位和方向固定不变。设备坐标系统可分为:屏幕坐标系统、窗口坐标系统和客户区坐标系统。 逻辑坐标系统与设备描述表的属性映射模式相关,他是一种允许自定义的坐标系统,坐标轴方向、单位和原点位置都可以重新定义。,2019/10/23,71,坐标系统(续),绝大多数GDI函数都使用逻辑坐标,而非GDI函数都永远使用设备坐标,所有的消息也都使用设备坐标。逻辑坐标系统下绘出的图形必须映射到设备坐标系统下,才能在屏幕上显示出来。 使设备坐标和逻辑坐标下的坐标相互转换的函数: BOOL DPtoLP( HDC hdc, LPPOINT lpPoints, / array of points int nCount / count of points in array ); BOOL LPtoDP( HDC hdc, LPPOINT lpPoints, int nCount );,