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的运行机理有个大概的认识吧.......

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

     谁知道以后的事情呢?

你可能感兴趣的:(windows)