GDI 简介

要在窗口的显示区域绘图,可以使用Windows的图形设备接口(GDI)函数。Windows提供了几个GDI函数,用于将字符串输出到窗口的显示区域内。我们已经在上一章看过DrawText函数,但是目前使用最为普遍的文字输出函数是TextOut。该函数的格式如下:

TextOut (hdc, x, y, psText, iLength) ;

当程序需要绘图时,它必须先取得设备内容句柄。在取得了该句柄后,Windows用内定的属性值填入内部设备内容结构。在后面的

章节中您会看到,可以通过呼叫不同的GDI函数改变这些默认值。利用其它的GDI函数可以取得这些属性的目前值。当然,还有其它

的GDI函数能够在窗口的显示区域真正地绘图。

当程序在显示区域绘图完毕后,它必须释放设备内容句柄。句柄被程序释放后就不再有效,且不能再被使用。程序必须在处理单个

消息处理期间取得和释放句柄。除了呼叫CreateDC(函数,在本章暂不讲述)建立的设备内容之外,程序不能在两个消息之间保

存其它设备内容句柄。

Windows应用程序一般使用两种方法来取得设备内容句柄,以备在屏幕上绘图。

 

取得设备内容句柄:方法一

在处理WM_PAINT消息时,使用这种方法。它涉及BeginPaint和EndPaint两个函数,这两个函数需要窗口句柄(作为参数传给

窗口消息处理程序)和PAINTSTRUCT结构的变量(在WINUSER.H表头文件中定义)的地址为参数。Windows程序写作者通常

把这一结构变量命名为ps并且在窗口消息处理程序中定义它:

PAINTSTRUCT ps ;
        

在处理WM_PAINT消息时,窗口消息处理程序首先呼叫BeginPaint。BeginPaint函数一般在准备绘制时导致无效区域的背景被

擦除。该函数也填入ps结构的字段。BeginPaint传回的值是设备内容句柄,这一传回值通常被保存在叫做hdc的变量中。它在

窗口消息处理程序中的定义如下:

HDC hdc ;
        

HDC数据型态定义为32位的无正负号整数。然后,程序就可以使用需要设备内容句柄的TextOut等GDI函数。呼叫EndPaint即可

释放设备内容句柄。

一般地,处理WM_PAINT消息的形式如下:

caseWM_PAINT:
        
  hdc = BeginPaint (hwnd, &ps) ;
        
         使用GDI函数
        
  EndPaint (hwnd, &ps) ;
        
  return 0 ;

在处理WM_PAINT消息时,必须成对地呼叫BeginPaint和EndPaint。如果窗口消息处理程序不处理WM_PAINT消息,则它必须将WM_PAINT消息传递给Windows中DefWindowProc(内定窗口消息处理程序)。DefWindowProc以下列代码处理WM_PAINT消息:

case WM_PAINT:
        
    BeginPaint (hwnd, &ps) ;
        
    EndPaint (hwnd, &ps) ;
        
   return 0 ;
        

这两个BeginPaint和EndPaint呼叫之间中没有任何叙述,仅仅使先前无效区域变为有效。但以下方法是错误的:

case WM_PAINT:
        
    return 0 ;   // WRONG !!!
        

Windows将一个WM_PAINT消息放到消息队列中,是因为显示区域的一部分无效。如果不呼叫BeginPaint和EndPaint

(或者ValidateRect),则Windows不会使该区域变为有效。相反,Windows将发送另一个WM_PAINT消息,且一直发送下去。

 

 

取得设备内容句柄:方法二

虽然最好是在处理WM_PAINT消息处理期间更新整个显示区域,但是您也会发现在处理非WM_PAINT消息处理期间绘制显示区

域的某个部分也是非常有用的。或者您需要将设备内容句柄用于其它目的,如取得设备内容的信息。

要得到窗口显示区域的设备内容句柄,可以呼叫GetDC来取得句柄,在使用完后呼叫ReleaseDC:

hdc = GetDC (hwnd) ;
        
使用GDI函数
        
ReleaseDC (hwnd, hdc) ;
        

与BeginPaint和EndPaint一样,GetDC和ReleaseDC函数必须成对地使用。如果在处理某消息时呼叫GetDC,则必须在退出窗口

消息处理程序之前呼叫ReleaseDC。不要在一个消息中呼叫GetDC却在另一个消息呼叫ReleaseDC。

与从BeginPaint传回设备内容句柄不同,GetDC传回的设备内容句柄具有一个剪取矩形,它等于整个显示区域。可以在显示区域

的某一部分绘图,而不只是在无效矩形上绘图(如果确实存在无效矩形)。与BeginPaint不同,GetDC不会使任何无效区域变为

有效。如果需要使整个显示区域有效,可以呼叫

ValidateRect (hwnd, NULL) ;
        

一般可以呼叫GetDC和ReleaseDC来对键盘消息(如在字处理程序中)和鼠标消息(如在画图程序中)作出反应。此时,程序

可以立刻根据使用者的键盘或鼠标输入来更新显示区域,而不需要考虑为了窗口的无效区域而使用WM_PAINT消息。不过,

一旦确实收到了WM_PAINT消息,程序就必须要收集足够的信息后才能更新显示。

与GetDC相似的函数是GetWindowDC。GetDC传回用于写入窗口显示区域的设备内容句柄,而GetWindowDC传回写入整个

窗口的设备内容句柄。例如,您的程序可以使用从GetWindowDC传回的设备内容句柄在窗口的标题列上写入文字。然而,程序

同样也应该处理WM_NCPAINT (「非显示区域绘制」)消息。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值