ActiveX之绘制过程

一、ActiveX控件的绘制过程

    当ActiveX控件被显示或被重绘时,绘制过程类似于其它用MFC开发的应用程序,不过有一点不同:ActiveX控件具有active、inactive二种状态。

    ActiveX控件容器中的ActiveX控件可以看作是一个子窗口,像其它窗口一样,当接收到WM_PAINT消息的时候能够自绘。ActiveX的基类COleControl在它的OnPaint中处理这个消息,缺省情况下是调用你的ActiveX控件的OnDraw方法。

    当ActiveX控件的状态是inactive时,它的绘制过程又不同。这时控件的窗口是无效的或是不存在,因此它不能够接收pain消息。这时控件的容器会直接调用控件的OnDraw方法,这有别于active状态下的控件绘制过程,因为OnPaint成员函数是不会被调用的。

    像上一自然段讨论的那样,ActiveX控件的绘制依赖于状态有二种绘制方式,这二种方式都是框架调用OnDraw成员函数,所以应该在OnDraw方法中添加绘制的主要代码。

    OnDraw方法处理控件的绘制,当控件为inactive时,控件容器调用OnDraw时传递容器的设备上下文以及控件所占据的矩形区域的坐标。

    被框架传入的矩形包含了控件占据的面积,如果控件是active的,那么矩形的左上角坐标是(0,0),而所传的设备上下文是包含控件的子窗口的上下文。如果ActiveX是inactive的,那么矩形的左上角并不一定是(0,0),设备上下文是包含控件的窗口的上下文。

Ps:OnDraw中,不要依赖于矩形的左上角坐标来绘图是很重要的。如果依赖这个坐标可能会出现意想不到的结果。

缺省的OnDraw如下:

void CMyAxUICtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   if (!pdc)
      return;

   // TODO: Replace the following code with your own drawing code.
   pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
   pdc->Ellipse(rcBounds);
}
ps:当绘制控件时,不要去假设被传入到OnDraw方法中的设备上下文的状态,因为有时容器传入的上下文并不一定会被初始化为默认的状态,所以你要明确的指出你绘制代码中的pen,brushes,colors,fonts等。

二、绘制代码优化

在控件成功重绘之后,下一步就是优化OnDraw方法。

缺省条件下,控件的重绘是控件整体重绘,这对于简单的控件是适合的。但在多数情况下仅重绘控件需要重绘的部分区域可以提高绘制速度。

OnDraw方法提供一个简便的优化方式——使用参数rcInvalid,这个参数表示控件中需要重绘的区域。通常这个区域小于控件本身,因为可加速绘制过程。

三、使用元文件绘制控件

    在多数情况下,OnDraw的参数pdc指向的是一个屏幕的设备上下文。然而,在绘制控件图像或是在打印预览时,接收到的DC是特殊的类型——元文件DC(metafile DC)。有别屏幕DC那样立即处理绘制请求,元文件DC会存储操作,并在稍后的时间里回放绘制操作。一些容器应用程序在设计模式时可能会选择元文件DC来渲染控件图片。

    元文件的绘图请求可由容器通过二个接口函数产生:一个是IViewObject::Draw,这个函数能够被非元文件绘图调用。另一个是IdataObjet::GetData。当元文件DC被当作参数传递时,MFC框架对COleControl::OnDrawMetafile产生一个调用请求,因为它是一个虚函数,所以在control类中重写这个函数来做一些特殊的处理。缺省下是调用COleControl::OnDraw。

    为了保证控件在二种DC下都能被绘制,所使用的绘图方法必须同时支持这二种DC。你要意识到坐标系统并不是以像素来衡量的。

    因为OnDrawMetafile缺省的实现会调用控件的OnDraw方法。所以仅能使用那些同时支持二种DC的方法,除非你重写了OnDrawMetafile方法。下面的列表给出了可同进支持二种DC的方法,详细信息参考CDC类


更多内容参考MSDN:http://msdn.microsoft.com/en-us/library/552z1tz3.aspx#_core_the_painting_process_of_an_activex_control



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值