1 / 21

( 第十八讲 )

( 第十八讲 ). 吉林大学远程教育课件. Windows A P I 编 程. ( 第十八讲 ). 学 时: 48. 主讲人 : 翟慧杰. 本实例的作用是通过程序捕获键盘消息, 然后将 wParam 参数所包含的数据进行分解, 最后将各项信息通过窗口显示出来。实例 的源文件包含了 Initlnstance 、 MyRegisterClass 、 ShowKey 、 WinMain 和 WndProc 五个函数。程序的基本思路

snowy
Download Presentation

( 第十八讲 )

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. (第十八讲) 吉林大学远程教育课件 Windows A P I编 程 (第十八讲) 学 时:48 主讲人 : 翟慧杰

  2. 本实例的作用是通过程序捕获键盘消息, 然后将wParam参数所包含的数据进行分解, 最后将各项信息通过窗口显示出来。实例 的源文件包含了Initlnstance、 MyRegisterClass、ShowKey、WinMain 和WndProc五个函数。程序的基本思路 是以WinMain函数作为程序入口,再调用 MyRegisterClass函数和 InitInstance函数注册窗口类并创建和保存窗日,然后创建和显示窗口,最后进入消息循环。 下面重点分析函数WndProc和ShowKey。

  3. 1.WndProc函数 在本实例中WndProc函数处理的消息 主要有WM_CREATE、WM_SIZE、 WM_PAINT和键盘消息。 case WM_CREATE://处理窗口创建的消息 hdc = GetDC (hwnd);   //设定字体 SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));   //检取当前字体的度量数据 GetTextMetrics (hdc, &tm);  xChar = tm.tmAveCharWidth;//保存字体平均宽度 yChar = tm.tmHeight;//保存字体高度 ReleaseDC (hwnd, hdc);  rc.top = 3 * yChar / 2;  return 0;

  4. 这一程序段的主要作用是将字体对象选入 当前窗体的设备描述表中,同时取得字体 高度和平均宽度,再初始化编辑区的滚屏 区域的右上角Y坐标。进入该程序段后, 首先通过GetDC函数获得当前窗体的 设备描述表,再通过GetStockObject函数 获得系统字体,然后用 SelectObject函数 将字体对家选入窗体的设备描述表中。其中,hdc为设备描述表句柄。在完成所有操作后,程序还必须通过ReleaseDC函数释放设备描述表。在该程序段中使用了GetTextMetrics函数来获得字体的几何尺寸。GetTextMetrics函效的原型定义如下: BOOL GetTextMetrics( HDC hdc, // 指向设备描述表的句柄 LPTEXTMETRIC lptm // TEXTMETRIC结构体变量的指针 // 所获得的所有信息保存在TEXTMETRIC结构体变量中 ));

  5. 其中lptm是一个指向 TEXTMETRIC 结构体的指针。 TEXTMETRIC结构体 包含了与字体的几何尺寸相关的基本信息。 该结构体的具体定义如下: typedef struct tagTEXTMETRIC{ // tm LONG tmHeight;// 字体高度 LONG tmAscent;//字体高于基准线的高度 LONG tmDescent;// 字体低于基准线的高度 LONG tmInternalLeading;// 给大写字母留出的空间 LONG tmExtenalLeading; // 由字体设计者推荐的附加行距 LONG tmAveCharWidth;// 字体平均宽度 LONG tmMaxCharWidth;// 字体最大宽度 LONG tmWeight; // 字体黑度 LONG tmOverhang; // 在合成斜体或黑体时加在字符上的附加宽度值 LONG tmDigitizedAspectX;// 字体所适合的高宽比的宽 LONG tmDigitizedAspectY; // 字体所适合的高宽比的高

  6. BCHAR tmFirstChar; // 字体中定义的第一个字符 BCHAR tmLastChar; //字体中定义的最后一个字符 BCHAR trnDefaultChar; //字体中的默认字符 BCHAR trnBreakChar; // windows在调整文本时用于分裂词的字符 BYTE tmItalic; // 取非零值时表示斜体字体 BYTE tmUnderLined; // 取非零值时表示下划线字体 BYTE tmStruckOut;// 取非零值时为删除线字体 BYTE tmPitchAndFamily; // 低二位为字符间距,高四位为系列值 BYTE tmCharSet; // 指定字符集 }TEXTMETRIC; 该结构中所有的字体大小都是按逻辑单位给出的,这就是说字体的大小取决于当前显示设备的映射模式。

  7. 在例中,所获得的字体几何尺寸保存在 TEXTMETRIC结构体变量tm中。滚屏区域 的范围是通过RECT结构体变量re保存的, RECT结构体变量可以通过记录矩形区域 的右上角和左下角的坐标来确定一个矩形 区域。RECT结构的原型定义如下: typedef struc RECT{ LONG left; // 矩形左上角 X坐标 LONG top; // 左上角 Y坐标 LONG right; // 右下角 X坐标 LONG bottom; // 右下角Y坐标 } RECT; 该结构定义了一个矩形区域的左上角和右下角的坐标。由结构的原型定义我们可以知道该结构包括四个域,其中left域表示矩形的左上角X坐标,top域表示左上角Y坐标,right域表示右下角X坐标,bottom域表示右下角Y坐标。通常用于一个矩形区域范围的记录和传递。

  8. 例如,通过RECT结构的变量将一个矩形 区域范围的四个角的值传递FillRect函数, 则调用该函数后,矩形区域除了最下方的 一行和最右方一列外都被填充。 在本实例中,初始化编辑区的滚屏区域的 左上角Y坐标时,使用了如下程序: rc . top=3 * yChar/2; 这是因为在窗口中首先要输出两行的题头信息,一行为中文,一行为下划线。中文字符的高度为1个字体高度单位,而下划线的高度为半个字体高度单位。这两行信息是一直保持,不参与滚屏的。因此,滚屏区域的左上角Y坐标从3/2个字体高度处开始。

  9. 在WndProc函数中,处理WM_ SIZE 消息的程序段如下: case WM_SIZE: //处理窗口大小改变的消息 //窗体改变后保存新的滚屏区域右下角坐标 rc.right = LOWORD (lParam); rc.bottom = HIWORD (lParam); UpdateWindow (hwnd); return 0; 该程序段比较简单,只是当窗口的尺寸改变时重新设定滚屏区域的右下角坐标,并更新窗口。值得注意的是, WM_SIZE消息的wParam变量保存了窗体新尺寸的左上角坐标,变量的32位分为两个部分,低16位保存X坐标,高16位保存Y坐标。 lParam变量保存了窗体新尺寸的右下角坐标,保存方式与wParam变量相同。在编程过程中,通常通过LOWORD宏定义来获得32位变量的低16位数值,通过HIWORD宏定义来获得32位变量的高历位数值。

  10. 该程序段比较简单,只是当窗口的尺寸改变 时重新设定滚屏区域的右下角坐标,并更新 窗口。值得注意的是, WM_SIZE消息的 wParam变量保存了窗体新尺寸的左上角坐标, 变量的32位分为两个部分,低16位保存X坐标, 高16位保存Y坐标。 lParam变量保存了窗体新 尺寸的右下角坐标,保存方式与wParam变量 相同。在编程过程中,通常通过LOWORD宏定义来获得32位变量的低16位数值,通过HIWORD宏定义来获得32位变量的高历位数值。

  11. WndProc函数中,处理WM _PAINT 消息的程序段如下: case WM_PAINT: //处理窗口重绘消息 InvalidateRect (hwnd, NULL, TRUE);   hdc = BeginPaint (hwnd, &ps);   SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;   SetBkMode (hdc, TRANSPARENT) ;   TextOut (hdc, xChar, yChar / 2, szTop, (sizeof szTop) - 1) ;   TextOut (hdc, xChar, yChar / 2, szUnd, (sizeof szUnd) - 1) ;   EndPaint (hwnd, &ps);   return 0; 该程序段首先调用InvalidateRect函数使窗口无效,InvalidateRect函数的功能是使窗口的某一部分无效,也就是通知Windows该部分需要被刷新和重画。 在InvalidateRect函数之后,程序调用函数BeginPaint准备重画窗口。

  12. BeginPaint函数的原型定义如下: HDC BeginPaint( HWND hwnd , //重画窗口的句柄 LPPAINTSTRUCT lpPaint // 指向一个用于保存所有重 // 画信息的PAINTSTRUCT结构体变量的指针 ); BeginPaint函数的作用是完成重画窗体之前的准备,并将重画窗体的数据保存在一个PAINTSTRUCT结构体变量中。PAINTSTRUCT结构体可以用于保存窗口重画时的数据以方便以后使用。

  13. PAINTSTRUCT结构体的定义如下: typedef struct tagPAINTSTRUCT{ // ps HDC hdc; // 重画区域所在窗口的句柄 BOOL fErase;// 是否擦去背景 RECT rcPaint; // 指定重画窗体的范围 BOOL fRestore; // 系统保留域 BOOL fIncUpdate;// 系统保留域 BYTE rgbReserved[32];// 系统保留 )PA INTSTRU CT;

  14. BeginPaint函数如果操作成功会返回一个 被操作窗口的设备描述表的句柄。如果操作 不成功则函数返回NULL值,表明显示设备 不可用。该函数在运行过程中,会进行自动 调整,使得所有区域都包含在刷新区域的范围 内。而原有需要刷新的区域是由 InvalidateRect函数或 InvalidateRgn函数指定的。一般来说,只有当程序处理 WM_PAINT消息时才调用BeginPaint函数,而且,每次调用BeginPaint函数都需要对应调用一个EndPaint函数来结束重画过程。在BeginPaint函数调用后,会将插入符光标自动隐藏。EndPaint函数原型定义如下: BOOL EndPaint ( HWND hWnd, // 窗口句柄 CONST PAINTSTRUCT* lpPaint // 指向 PAINTSTRUCT结构体变量的指针 );

  15. EndPaint函数标志着窗口重画过程的结束。 该函数执行后总返回一个非零值。如果在 BeginPaint函数执行时将插入符号隐藏了, 那么EndPaint函数会重新显示插入符号。 消息处理函数WndProc处理的键盘消息有: WM_ KEYDOWN、WM_KEYUP WM_CHAR、 WM_DEADCHAR、WM_SYSKEYDOWN、 WM_SYSKEYUP、WM_SYSCHAR和WM_SYSDEADCHAR。根据不同的消息,程序会用不同的参数调用ShowKey函数在窗口中显示各键盘消息的相关信息。

  16. 2.ShowKey函数 ShowKey函数是用户自定义函数,其 作用是从键盘消息的各域中提取信息 并显示在窗口中。 ShowKey函数的具体定义如下: // 作用:实现在窗口中显示按键信息 void ShowKey (HWND hwnd, int iType, char *szMessage,WPARAM wParam, LPARAM lParam)  {  static char *szFormat[2] = { "%-14s %3d %c %6u %4d %5s %5s %6s %6s", "%-14s %3d %c %6u %4d %5s %5s %6s %6s" } ;   char szBuffer[80];   HDC hdc;

  17. SelectObject(hdc, GetStockObject (SYSTEM_FIXED_FONT)); TextOut (hdc, xChar, rc.bottom - yChar, szBuffer,wsprintf (szBuffer, szFormat [iType], szMessage, //消息 wParam, //虚拟键代码 (BYTE) (iType ? wParam : ' '),//显示字符值 LOWORD (lParam), //重复次数 HIWORD (lParam) & 0xFF, //OEM键盘扫描码 //判断是否为增强键盘的扩展键 (PSTR) (0x01000000 & lParam ? "是" : "否"), //判断是否同时使用了ALT键 (PSTR) (0x20000000 & lParam ? "是" : "否"), (PSTR) (0x40000000 & lParam ? "按下" : "抬起"), //判断前一次击键状态 (PSTR) (0x80000000 & lParam ? "按下" : "抬起")) //判断转换状态 ); }

  18. ShowKey函数首先定义了szFormat字符串,并 在其中针对字符消息和非字符消息定义了两种 不同的输出格式。 然后调用ScrollWindowEx 函数使显示区域滚屏,为信息输出作准备。 ScrollWindowEx函数的主要功能是使窗口编辑 区中的某一矩形区域产生滚屏效果。 ScrollWindowEx函数的原型定义如下: int ScrollWindowEx ( HWND hwnd, // 发生滚屏的窗口的句柄 int dx, // 水平滚屏的数值 int dy, // 垂直滚屏的数值 CONST RECT*prcScroll //记录发生滚屏的矩形区域的RECT结构体的地址 CONST RECT* prcClip, //记录发生剪切的矩形区域的 RECT结构体的地址 HRGN hrgnUpdate,// 需要更新区域的句柄 LPRECT prcUpdate, // 记录需要更新矩形区域的 RECT结构体的地址 UINT flags // 滚屏控制标志 );

  19. 其中,dx参数给出了以设备单位尺寸 (对于显示器为像素)为单位的每一次 水平滚屏的度量值。dx参数取正值表示 向右滚屏,取负值表示向左滚屏。如参数 给出了以设备单位尺寸(对于显示器为 像素)为单位的每一次垂直滚屏的度量值。 如参数取正值表示向下滚屏,取负值表示 向上滚屏。dx和dy两个参数不能同时取非零值,也就是说,ScrollWindowEx函数不能使编辑区同时向水平和垂直方向滚屏。 prcScroll参数为一个指向记录滚屏的矩形区域的RECT结构体变量的指针,如果取值为NULL,则整个编辑区发生滚屏。 hrgnUpdate参数为因滚屏而变得无效的矩形区域的句柄,多数情况下可以取NULL。 prcUpdate参数指向一个记录因为滚屏而变得无效的矩形区域的 RECT结构体变量。多数情况下取NULL。

  20. flags变量可以通过不同的取值来控制滚屏的 状况,其取值和意义如下所示。 SW_ ERASE当和 SW_INVALIDATE值 同时使用时,会通过向 window发送 一个 WM_ ERASEBKGND消息将最近变得无效 的区域抹去; SW_INVALIDATE在发生滚屏后使由hrgnUpdate参数指定的区域无效; SW_SCROLLCHILDREN使所有的子窗口都发生滚屏; SW_ SMOOTHSCROLL在 Windows 95及以后的版本中使窗口发生平滑滚屏。如果ScrollWindowEx函数执行成功,则返回值为以下三者之一: SIMPLEREGION表示有一个矩形的无效区域; COMPLEXREGION表示没有无效区域和重叠区域; NULLREGION表示没有无效区域。 如果ScrollWindowEx函数执行不成功,则返回ERROR。

  21. ScrollWindowEx函数的功能也可以通过 ScrollWindow函数来实现,ScrollWindow 函数的原型定义如下: BOOL Scrollwindow( HWND hwnd //窗口句柄 int XAmount, // 水平滚屏的数值 int YAmount, // 垂直滚屏的数值 CONST RECT* lpReCt, //记录发生滚屏的矩形区域的 RECT结构体的地址 CONST RECT* lpClipRect //记录发生剪切的矩形区域的 RECT结构体的地址 ); 可以看出,ScrollWindow函数与ScrollWindowEx函数十分相似,其参数的意义也基本相同。事实上,ScrollWindow函数是为了保持对较低版本的Windows兼容而设计的,用户在编程时,除非需要考虑程序的向下兼容,否则一般都应使用ScrollWindowEx函数。

More Related