zoukankan      html  css  js  c++  java
  • 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的运行机理有个大概的认识吧.......

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

         谁知道以后的事情呢?

  • 相关阅读:
    JAVA基础——编程练习(二)
    JAVA基础——面向对象三大特性:封装、继承、多态
    JVM内存
    50. Pow(x, n) (JAVA)
    47. Permutations II (JAVA)
    46. Permutations (JAVA)
    45. Jump Game II (JAVA)
    43. Multiply Strings (JAVA)
    42. Trapping Rain Water (JAVA)
    41. First Missing Positive (JAVA)
  • 原文地址:https://www.cnblogs.com/volcanol/p/2078827.html
Copyright © 2011-2022 走看看