共用方式為


MFC ActiveX 控制項:子類別化 Windows 控制項

本文說明子類別化通用 Windows 控制項以建立 ActiveX 控制項的流程。 子類別化現有的 Windows 控制項是一種可快速開發 ActiveX 控制項的方式。 新的控制項將會具有已子類別化之 Windows 控制項的能力,例如繪製和回應滑鼠點選動作。 MFC ActiveX 控制項範例 BUTTON 是子類別化 Windows 控制項的範例。

重要

ActiveX 是不應該用於新開發的舊版技術。 如需取代 ActiveX 的新式技術詳細資訊,請參閱 ActiveX 控制項

若要子類別化 Windows 控制項,請完成下列工作:

覆寫 IsSubclassedControl 和 PreCreateWindow

若要覆寫 PreCreateWindowIsSubclassedControl ,請將下列程式程式碼新增至 protected 控制項類別宣告的 區段:

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
BOOL IsSubclassedControl();

在控制項實作檔 (.CPP) 中,加入下列程式碼以實作兩個覆寫的函式:

// CMyAxSubCtrl::PreCreateWindow - Modify parameters for CreateWindowEx

BOOL CMyAxSubCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
   cs.lpszClass = _T("BUTTON");
   return COleControl::PreCreateWindow(cs);
}

// CMyAxSubCtrl::IsSubclassedControl - This is a subclassed control

BOOL CMyAxSubCtrl::IsSubclassedControl()
{
   return TRUE;
}

請注意,在此範例中,Windows 按鈕控制項是在 PreCreateWindow 中指定。 不過,所有標準的 Windows 控制項都可以進行子類別化。 如需標準 Windows 控制項的詳細資訊,請參閱 控制項

在子類別化 Windows 控制項時,您可能想要指定特定視窗樣式 (WS_) 或擴充視窗樣式 (WS_EX_) 旗標,以用於建立控制項的視窗。 您可以修改 cs.stylecs.dwExStyle 結構欄位, PreCreateWindow 在成員函式中設定這些參數的值。 應該使用 OR 作業修改這些欄位,以保留 類別 COleControl 所設定的預設旗標。 例如,如果控制項是要子類別化 BUTTON 控制項,而且您想要讓控制項顯示為核取方塊,請將下列程式碼插入至 CSampleCtrl::PreCreateWindow 實作中 return 陳述式之前:

cs.style |= BS_CHECKBOX;

此作業會新增BS_CHECKBOX樣式旗標,同時讓類別 COleControl 的預設樣式旗標 (WS_CHILD) 保持不變。

修改 OnDraw 成員函式

如果您希望子類別化後的控制項保留與對應之 Windows 控制項的相同外觀,控制項的 OnDraw 成員函式應該只包含對 DoSuperclassPaint 成員函式的呼叫,如下列範例所示:

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

   DoSuperclassPaint(pdc, rcBounds);
}

DoSuperclassPaint 成員函式 (由 COleControl 所實作) 會在指定的裝置內容中使用 Windows 控制項的視窗程序將控制項繪製在周框矩形之內。 如此可讓控制項即使並未處於作用中也會成為可見狀態。

注意

成員 DoSuperclassPaint 函式只適用于允許將裝置內容當做 WM_PAINT訊息的 wParam 傳遞的控制項類型。 這包括一些標準 Windows 控制項,例如 SCROLLBAR 和 BUTTON,以及所有通用控制項。 對於不支援這個行為的控制項,您必須提供自己的程式碼以便正確顯示非現用控制項。

處理反思視窗訊息

Windows 控制項通常會將某些視窗訊息傳送給其父視窗。 其中一些訊息,例如WM_COMMAND,會向使用者提供動作的通知。 其他,例如WM_CTLCOLOR,則用來從父視窗取得資訊。 ActiveX 控制項通常會透過其他方法與父視窗進行通訊。 通知是藉由引發事件 (傳送事件通知) 進行通訊,而控制項容器的相關資訊則是藉由存取容器的環境屬性取得。 由於這些通訊技術的存在,ActiveX 控制項容器不應該處理控制項所傳送的任何視窗訊息。

為了要防止容器接收已子類別化之 Windows 控制項所傳送的視窗訊息,COleControl 會建立一個額外的視窗做為控制項的父代。 這個額外的視窗 (稱為「反映程式」) 只會針對子類別化 Windows 控制項的 ActiveX 控制項而建立,同時其大小和位置會與控制項視窗相同。 反映程式視窗會攔截某些視窗訊息,並將其傳送回控制項。 控制項 (在其視窗程序中) 接著便可以採取適用於 ActiveX 控制項的動作 (例如,引發事件),以處理這些反映的訊息。 如需攔截的視窗訊息清單及其對應的反映訊息,請參閱 反思視窗訊息識別碼

ActiveX 控制項容器可能會設計為自行執行訊息反映,如此便不需要讓 COleControl 建立反映程式視窗,同時並可降低子類別化之 Windows 控制項的執行階段負荷。 COleControl偵測容器是否支援這項功能,方法是檢查 Message反思環境屬性值為 TRUE

若要處理反映的視窗訊息,請新增一個項目至控制項訊息對應,並實作處理函式。 由於反映的訊息並不是由 Windows 定義的一套標準訊息,因此 [類別檢視] 不支援加入這類訊息處理常式。 不過,手動加入處理常式並不困難。

若要為反映的 Windows 訊息手動加入訊息處理常式,請執行下列動作:

  • 在控制項類別的 .H 檔案中,宣告處理常式函式。 函式應該有 LRESULT 傳回型別和兩個參數,分別具有 WPARAM LPARAM 類型 。 例如:

    class CMyAxSubCtrl : public COleControl
    {
    
    protected:
       LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam);
    };
    
  • 在控制項類別 中。CPP 檔案,將ON_MESSAGE專案新增至訊息對應。 這個項目的參數應該是訊息識別項和處理常式函式的名稱。 例如:

    BEGIN_MESSAGE_MAP(CMyAxSubCtrl, COleControl)
       ON_MESSAGE(OCM_COMMAND, &CMyAxSubCtrl::OnOcmCommand)
    END_MESSAGE_MAP()
    
  • 此外,在 中。CPP 檔案,實作 OnOcmCommand 成員函式來處理反映的訊息。 wParam lParam 參數與原始視窗訊息的參數相同。

如需如何處理反映訊息的範例,請參閱 MFC ActiveX 控制項範例 BUTTON 。 它示範一個 OnOcmCommand 處理常式,偵測BN_CLICKED通知程式碼,並藉由引發(傳送)事件 Click 來回應。

另請參閱

MFC ActiveX 控制項