vs2017开发ActiveX(主讲OCX)(四)、绘制ActiveX控件⽂章⽬录
参考
本⽂介绍ActiveX控件绘制过程以及如何更改绘制代码以优化过程。(有关如何通过不使控件单独恢复以前选择的GDI对象来优化绘图的技术,请参阅优化控制图。在绘制完所有控件后,容器可以⾃动恢复原始对象。)
本⽂中的⽰例来⾃MFC ActiveX控件向导使⽤默认设置创建的控件。
绘制控件的整个过程以及ActiveX控件向导创建的代码以⽀持绘制
ActiveX控件的绘制过程
最初显⽰或重绘ActiveX控件时,它们遵循与使⽤MFC开发的其他应⽤程序类似的绘制过程,但有⼀个重要区别:ActiveX控件可以处于活动状态或⾮活动状态。
ActiveX控件容器中的⼦窗⼝表⽰活动控件。与其他窗⼝⼀样,它在接收WM_PAINT消息时负责绘制⾃⾝。控件的基类COleControl在其OnPaint函数中处理此消息。此默认实现调⽤OnDraw控件的功能。
⾮活动控件的绘制⽅式不同。当控件处于⾮活动状态时,其窗⼝要么不可见,要么不存在,因此⽆法接收绘制消息。相反,控件容器直接调⽤控件的OnDraw功能。这与活动控件的绘制过程不同,因为OnPaint永远不会调⽤成员函数。
如前⾯段落中所讨论的,ActiveX控件的更新⽅式取决于控件的状态。但是,因为框架OnDraw在两种情况下都调⽤成员函数,所以在此成员函数中添加⼤部分绘制代码。
该OnDraw成员函数处理控制绘画。当控件处于⾮活动状态时,控件容器调⽤OnDraw,传递控件容器的设备上下⽂和控件占⽤的矩形区域的坐标。
框架传递给OnDraw成员函数的矩形包含控件占⽤的区域。如果控件处于活动状态,则左上⾓为(0,0),并且传递的设备上下⽂⽤于包含控件的⼦窗⼝。如果控件处于⾮活动状态,则左上⾓坐标不⼀定是(0,0),并且传递的设备上下⽂是针对包含控件的控件容器。
注意重要的是,您的修改OnDraw不依赖于矩形的左上⾓等于(0,0),⽽是仅在传递给矩形的内部绘制OnDraw。如果绘制超出矩形区域,则可能会出现意外结果。
控件实现⽂件(.CPP)中的MFC ActiveX控件向导提供的默认实现(如下所⽰)使⽤⽩⾊笔刷绘制矩形,并使⽤当前背景颜⾊填充椭圆。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);
}
注意在绘制控件时,不应该假设将作为pdc参数传递给OnDraw函数的设备上下⽂的状态。有时,设备上下⽂由容器应⽤程序提供,不⼀定会初始化为默认状态。特别是,明确选择绘图代码所依赖的笔,画笔,颜⾊,字体和其他资源。
如何优化绘制过程
优化你的绘制代码
控件成功绘制后,下⼀步是优化OnDraw功能。
ActiveX控件绘制的默认实现绘制整个控件区域。这对于简单的控件来说已经⾜够了,但是在许多情况下,如果仅重新绘制需要更新的部分⽽不是整个控件,则重新绘制控件会更快。
该OnDraw函数通过传递rcInvalid提供了⼀种简单的优化⽅法,rcInvalid是需要重绘的控件的矩形区域。使⽤此区域(通常⼩于整个控制区域)可加快绘制过程。
activex 控件如何使⽤元⽂件绘制控件
在⼤多数情况下,函数的pdc参数OnDraw指向屏幕设备上下⽂(DC)。然⽽,当打印控件的图像时或在打印预览会话期间,接收⽤于渲染的DC是称为“元⽂件DC”的特殊类型。与⽴即处理发送给它的请求的屏幕DC不同,元⽂件DC存储稍后要回放的请求。在设计模式下,某些容器应⽤程序还可以选择使⽤图元⽂件DC来呈现控制图像。
元数据绘图请求可以由容器通过两个接⼝函数进⾏:( IViewObject::Draw此函数也可以调⽤⾮元⽂件绘图)和IDataObject::GetData。当元⽂件DC作为参数之⼀传递时,MFC框架调⽤COleControl :: OnDrawMetafile。因为这是⼀个虚拟成员函数,所以在控件类中重写此函数可以进⾏任何特殊处理。默认⾏为调⽤COleControl::OnDraw。
要确保可以在屏幕和元⽂件设备上下⽂中绘制控件,必须仅使⽤屏幕和图元⽂件DC中都⽀持的成员函数。请注意,坐标系可能⽆法以像素为单位进⾏测量。
因为默认实现OnDrawMetafile调⽤控件的OnDraw函数,所以只使⽤适合元⽂件和屏幕设备上下⽂的成员函数,除⾮你重写OnDrawMetafile。下⾯列出了CDC可以在元⽂件和屏幕设备上下⽂中使⽤的成员函数的⼦集。有关这些函数的更多信息,请参阅MFC参考中的类CDC。
Arc BibBlt Chord
Ellipse Escape ExcludeClipRect
ExtTextOut FloodFill IntersectClipRect
LineTo MoveTo OffsetClipRgn
OffsetViewportOrg OffsetWindowOrg PatBlt
Pie Polygon Polyline
PolyPolygon RealizePalette RestoreDC
RoundRect SaveDC ScaleViewportExt
ScaleWindowExt SelectClipRgn SelectObject
SelectPalette SetBkColor SetBkMode
SetMapMode SetMapperFlags SetPixel
SetPolyFillMode SetROP2SetStretchBltMode
SetTextColor SetTextJustification SetViewportExt
SetViewportOrg SetWindowExt SetWindowORg
StretchBlt TextOut
除了CDC成员函数之外,还有⼀些在图元⽂件DC中兼容的其他函数。这些包括CPalette :: AnimatePalette,CFont :: CreateFontIndirect,以及三个成员函数CBrush:CreateBrushIndirect,CreateDIBPatternBrush和CreatePatternBrush。
未记录在图元⽂件中的函数有:
DrawFocusRect,DrawIcon,DrawText,ExcludeUpdateRgn,FillRect,FrameRect,GrayString,InvertRect,ScrollDC和TabbedTextOut。由于元⽂件DC实际上并未与设备关联,因此不能将SetDIBits,GetDIBits和CreateDIBitmap与图元⽂件DC⼀起使⽤。您可以使⽤SetDIBitsToDevice和StretchDIBits将元⽂件DC作为⽬标。CreateCompatibleDC,CreateCompatibleBitmap和CreateDiscardableBitmap 对于元⽂件DC没有意义。
使⽤图元⽂件DC时要考虑的另⼀点是,坐标系可能⽆法以像素为单位进⾏测量。出于这个原因,所有的绘图代码应该进⾏调整,以适应传递到矩形OnDraw的rcBounds参数。这可以防⽌在控件外部意外绘制,因为rcBounds表⽰控件窗⼝的⼤⼩。
为控件实现元⽂件呈现后,使⽤Test Container测试元⽂件。有关如何访问测试容器的信息,请参阅使⽤测试容器测试属性和事件。
使⽤Test Container测试控件的元⽂件
在“测试容器”的“ 编辑”菜单上,单击“ 插⼊新控件”。
在“ 插⼊新控件”框中,选择该控件,然后单击“ 确定”。
该控件将出现在Test容器中。
在“ 控制”菜单上,单击“ 绘制图元⽂件”。
将出现⼀个单独的窗⼝,其中显⽰元⽂件。您可以更改此窗⼝的⼤⼩以查看缩放如何影响控件的图元⽂件。您可以随时关闭此窗⼝。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。