• Windows程序设计零基础自学_3_Windows程序的显示和更新_之获取设备内容句柄_非WM_PAINT消息期间绘制显示区域


          前面看了几天的书,发现那本书太厚了1600多页,是我认真看过的最厚的书,看着就累,我不知道作者和翻译是怎么坚持下来的,这么多的文字就那么写完了;由于有工作要做,并且与计算机的联系不大,自学的时候感到很累,所以学习进度有点慢..........不过这个是我的兴趣,学起来虽然感觉累,但也乐在其中...嘿嘿

          上次说到了windows程序显示和更新窗口的WM_PAINT消息的处理机制,这次接着上次没有说完的话题继续瞎扯........

    非WM_PAINT消息期间绘制显示区域

        在应用程序编制过程中,有时不需要绘制显示区域,而只想获得一些设备内容的信息;或者我们想在非WM_PAINT消息处理期间绘
        制显示区域的某个区域,这时我们就需要采用另外一种方法了。我们通过下面的方式进行处理:
        1、获取设备内容句柄和释放设备内容句柄:
           我们可以通过下面两个API函数来获取设备内容句柄和释放设备内容句柄:
           获取设备内容句柄: GetDC
           原型: 
                     HDC GetDC(HWND);
           释放设备内容句柄:  ReleaseDC
           原型:
                    int ReleaseDC(HWMD ,HDC )
          2、Tip:
            这里和BeginPaint和EndPaint一样, GetDC和ReleaseDC函数必须成对的使用,若在某个消息处理的时使用呼叫GetDC则
          必须在同一个消息处理期间呼叫ReleaseDC函数。
            不能在处理A消息时呼叫GetDC,而在处理B消息时呼叫ReleaseDC。
          3、与BeginPaint的比较
               GetDC同样可以获取设备内容句柄,但是与BeginPaint不一样的是:GetDC不会使任何无效区域变为有效;
           这个可以理解:
              我们知道当产生无效区域的时候,系统会记录无效区域的形态同时发送一个WM_PAINT消息,同时在呼叫
           BeginPaint函数时会清除WM_PAINT消息,而GetDC函数不会清除WM_PAINT, 我们知道只要有WM_PAINT消息, 
           则会存在无效区域。
              GetDC返回的设备内容句柄具有一个剪取矩形,它等于整个显示区域,这样就可以在显示区域的某一部分绘制
           而不仅仅是在无效矩形上绘制。
           4、如何不调用BeginPaint函数而是整个区域有效,可以呼叫:
                 ValideteRect(hwnd,NULL);
               这样就可以清除系统投递到消息队列的WM_PAINT消息。
           5、使用GetDC和ReleaseDC
              可以呼叫GetDC和ReleaseDC来对键盘消息和鼠标消息作出响应, 这样就可以通过鼠标或者键盘输入来更新显
           示区域,而不需要等到窗口出现无效区域在对窗口进行绘制。
           6、GetDC与GetWindowDC
              GetDC返回一个用于在显示区域进行绘制的设备内容句柄,而GetWindow函数返回一个用于在整个窗口进行绘制的
           设备内容句柄。
              程序同样应该处理 WM_NCPAINT 非显示区域绘制消息。
     
        窗口绘制的步骤:
             1、获取要被绘制窗口的设备内容句柄
             2、调用GDI进行窗口绘制
             3、释放设备内容句柄。

    4.5 TextOut函数
         TextOut函数用于显示文字;其语法是:
         TextOut(hdc, x, y, psText,iLength);
         参数:
         hdc:  设备内容句柄,可以是GetDC和BeginPaint函数返回的句柄
                   设备内容的属性控制被显示的字符串的特征
         在设备内容中有一个属性指定文字的颜色,缺省的颜色为黑色,缺省设备内容还定义了白色的字符输出背景,在
         用TextOut函数输出文字时,就按照这个缺省的设备内容属性进行文字的输出显示。
         改文字背景色与窗口类别定义时设备的背景不相同,窗口类别中的背景是一个画刷,被windows用来擦除显示区域,不是设备
         内容的一部分。通常为了使windows擦除的窗口显示区域的背景画刷与缺省文字背景颜色相同,会将wndclass.hbrBackground
         画刷设置成白色画刷WHITE_BRUSH.

         psText: 待显示的字符串, 字符串中不能包括ASCII控制字符(如换行、回车、制表和退格),windows会将这些显示为实心块。

         x,y: x和y是字符显示时的开始坐标位置。x是水平位置,方向向右值增加; y是垂直位置,向下方向值增加。(0,0)是应用程序
         显示区域的左上角。这个坐标系成为逻辑坐标系。在Windows内部有多种坐标映像方式,这些坐标映像方式将控制GDI函数指定的逻辑
         位置转换为实际图素坐标的显示坐标。在设备内容定义,缺省方式是MM_TEXT, 其单位与实际单位相同,都是图素。

         设备内容定义了一个剪裁区域, GetDC获取的设备内容句柄为整个显示区域;而BeginPaint取得的设备内容句柄为无效区域。windows
         不会在剪裁区域之外的任何位置绘制字符串。
         
         系统字体:
             设备内容定义了TextOut显示文字时windows使用的字体, 缺省字体为系统字体,或用windows表头文件中的标识符SYSTEM_FONT,
         系统字体是windows用在标题栏、菜单和对话框中显示字符串的缺省字体。
        
          字符大小
             windows显示器的图素最小是640*480。 可以通过呼叫系统函数来获取各种信息。
            1、 GetSystemMetrics函数取得使用者接口上各类视觉组件大小的信息,
            2、 GetTextMetrics取得字体的大小,GetTextMetrics返回设备内容中当前选择的字体的信息,
                因此GetTextMetrics函数需要操作设备内容句柄, 调用这个函数时windows将文字大小不同的值赋值
                到TEXTMETRICS结构体中。
                TEXTMETRICS结构体共有20个字段,通常我们需要操作的是前面的几个字段
               
                typedef struct tagTEXTMETRIC
                   {
                        LONG  tmHeght;  //tmHeight=tmAscent+tmDescent 表示了在基准线下字符的最大高度
                        LONG  tmAscent;
                        LONG  tmDescent;
                        LONG  tmInternalLeading;
                        LONG  tmExternalLeading;
                        LONG  tmAveCharWidth;
                        LONG  tmMaxCharWidth;
                        其他字段;
                    }TEXTMETRIC, *PTEXTMETRIC;
                  leading:即间距指打印机在两行文字间插入的空间,在TEXTMETRIC结构中,内部间距包括在tmAscent中,并且通常
                 是重音符号出现的地方。tmInternalLeading字段可以设置成0,这时重音符的字母会稍稍缩短以打印重音符号。
                 TEXTMETRICS结构包含有描述字符宽度的两个字段:
                      tmAveCharWidth: 小写字母加权平均宽度
                      tmMaxCharWidth: 字体中最宽字符的宽度
                      这里要说明的是: windows使用的是非等宽的字体, 例如 W就比i宽。
                 大写字母的平均宽度: 大约可以用tmAveCharWidth * 150 % 计算。
                 上面的字段值的单位取决于选定的设备内容映像方式,在缺省的情况下,映像方式是MM_TEXT,其以图素为单位。
                
                 通过下面的方式获取文字的信息:
                  HDC hdc;
                  TEXTMETRIC tm;
                  hdc= GetDC(hwnd)
                  GetTxtMetrics(hdc, &tm);
                  ReleaseDC(hwnd,hdc);
                 这样就可以通过tm结构体变量的各个字段查看当前设备内容中关于字符的信息。

    格式化文字:
             windows启动后,系统字体的大小就不会发生改变。程序当中可以呼叫一次GetTextMetrics函数,获取系统字体的信息就可以一直使用。
             通常建议在处理WM_CREATE消息时进行上述的GetTextMetrics函数呼叫,因为WM_CREATE消息是窗口消息处理程序接收的第一个消息。
         可以这样处理:
            在消息处理程序中定义:
              static int cxChar,   //存储系统字符的宽度
                         cyChar;   //存储系统字符的高度
              而在消息处理时:
              case WM_CREATE:
                       hdc=GetDC(hwnd);
                       GetTextMetrics(hdc,&tm);
                       cxChar=tm.tmAvdCharWidth;
                       cyChar=tm.tmHeight+tm.tmExternalLeading;
                       Release(hwnd,hdc);
                       return 0;


           格式化字符串函数: sprintf和wsprintf(windows下可用)。
           wspritnf函数原型:
           int wsprintf(char *dest,char *source,...);

           Exp:
                 int iLength;
                 TCHAR szBuffer[40];
                
                 iLength=wsprintf(szBuffer,TEXT("the sum of %i and %i is %i"),iA,iB,iA+iB);
                 TextOut(hdc,x,y,szBuffer,iLength);
           wsprintf函数将格式化完的字符串放到一个字符串中,并且这个函数返回放入到字符串中的字符的个数。
           这样正好符合TextOut函数的使用的两个参数。

           因为函数的调用方式是__stdcall方式,所以可以:
                TextOut(hdc,x,y,szBuffer,wsprintf(szBuffer,TEXT("the sum of %i and %i is %i"),iA,iB,iA+iB) )。

         获取系统视觉组件大小信息: 
         GetSyetemMetrics函数
              GetSystemMetrics函数返回windows中不同视觉组件的大小信息;如图标、光标、标题栏和滚动条等。这些大小与显示卡
        和驱动程序相关。
        其函数原型是:
                int WINAPI GetSystemMetrics(int index)

          今天瞎掰就暂时到这,这里说的有点乱, 不过估计理解应该没有什么问题....................

          下一次估计要说滚动条了, 前几天看书,没太看明白, 等看明白后再来瞎掰..........

          编制windows的应用程序主要是明白其事件驱动机制以及各个功能的内在机理, 通过那本经典的书可以增强对windows程序的认识, 如果学习有一定的基础的话,同样可以学习那本经典核心编程课程,  也是1000+以上的书,估计看完要一阵子......

         计划慢慢的学完这本书,然后在看看罗老师的那本700多页的书, 估计会对windows的运行机理有个大概的认识吧.......

         也许以后转行到挨踢行业,也许就不转了.........

         谁知道以后的事情呢?

  • 相关阅读:
    高性能JavaScript
    高性能CSS
    去掉超链接文字点击后的灰色框
    高性能HTML
    css整站规划
    css hack 和问题
    IE6支持min-width、max-width CSS样式属性
    WPF草稿
    正则表达式学习日记zz
    详解Adorner Layer(zz)
  • 原文地址:https://www.cnblogs.com/volcanol/p/2078827.html
Copyright © 2020-2023  润新知