vs2017開發ActiveX(主講OCX)(四)、繪製ActiveX控件


參考 MFC ActiveX Controls: Painting an ActiveX Control
本文介紹ActiveX控件繪製過程以及如何更改繪製代碼以優化過程。(有關如何經過不使控件單獨恢復之前選擇的GDI對象來優化繪圖的技術,請參閱優化控制圖。在繪製完全部控件後,容器能夠自動恢復原始對象。)
本文中的示例來自MFC ActiveX控件嚮導使用默認設置建立的控件。

繪製控件的整個過程以及ActiveX控件嚮導建立的代碼以支持繪製

ActiveX控件的繪製過程

最初顯示或重繪ActiveX控件時,它們遵循與使用MFC開發的其餘應用程序相似的繪製過程,但有一個重要區別:ActiveX控件能夠處於活動狀態或非活動狀態。web

ActiveX控件容器中的子窗口表示活動控件。與其餘窗口同樣,它在接收WM_PAINT消息時負責繪製自身。控件的基類COleControl在其OnPaint函數中處理此消息。此默認實現調用OnDraw控件的功能。設計模式

非活動控件的繪製方式不一樣。當控件處於非活動狀態時,其窗口要麼不可見,要麼不存在,所以沒法接收繪製消息。相反,控件容器直接調用控件的OnDraw功能。這與活動控件的繪製過程不一樣,由於OnPaint永遠不會調用成員函數。app

如前面段落中所討論的,ActiveX控件的更新方式取決於控件的狀態。可是,由於框架OnDraw在兩種狀況下都調用成員函數,因此在此成員函數中添加大部分繪製代碼。框架

該OnDraw成員函數處理控制繪畫。當控件處於非活動狀態時,控件容器調用OnDraw,傳遞控件容器的設備上下文和控件佔用的矩形區域的座標。svg

框架傳遞給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功能。spa

ActiveX控件繪製的默認實現繪製整個控件區域。這對於簡單的控件來講已經足夠了,可是在許多狀況下,若是僅從新繪製須要更新的部分而不是整個控件,則從新繪製控件會更快。

該OnDraw函數經過傳遞rcInvalid提供了一種簡單的優化方法,rcInvalid是須要重繪的控件的矩形區域。使用此區域(一般小於整個控制區域)可加快繪製過程。

如何使用元文件繪製控件

在大多數狀況下,函數的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 SetROP2 SetStretchBltMode
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容器中。

在「 控制」菜單上,單擊「 繪製圖元文件」。

將出現一個單獨的窗口,其中顯示元文件。您能夠更改此窗口的大小以查看縮放如何影響控件的圖元文件。您能夠隨時關閉此窗口。

相關文章
相關標籤/搜索