MFC ActiveX 控制元件:新增自定義事件
自定義事件與常用事件的區別在於,自定義事件不由 COleControl 類自動引發。自定義事件將控制元件開發人員確定的某一操作識別為事件。自定義事件的事件對映項由 EVENT_CUSTOM 巨集表示。下一節實現用“ActiveX 控制元件嚮導”建立的 ActiveX 控制元件專案的自定義事件。
使用“新增事件嚮導”新增自定義事件
下列過程新增特定的自定義事件 ClickIn。可以使用此過程新增其他自定義事件。用自定義事件名及其引數替換 ClickIn 事件名和引數。
使用“新增事件嚮導”新增 ClickIn 自定義事件
- 載入控制元件的專案。
- 在“類檢視”中,右擊 ActiveX 控制元件類以開啟快捷選單。
- 在快捷選單中,單擊“新增”,然後單擊“新增事件”。
此操作將開啟“新增事件嚮導”。
- 在“事件名稱”框中,鍵入“ClickIn”。
- 在“內部名稱”框中,鍵入事件的引發函式名。在本例中,使用“新增事件嚮導”提供的預設值 (
FireClickIn
)。 - 使用 Parameter Name 和 Parameter Type 控制元件,新增稱為
xCoord
(OLE_XPOS_PIXELS
型別)的引數。 - 新增另一個稱為
yCoord
(OLE_YPOS_PIXELS
型別)的引數。 - 單擊“完成”按鈕建立事件。
“新增事件嚮導”對自定義事件的更改
當您新增自定義事件時,“新增事件嚮導”會更改控制元件類 .H、.CPP 和 .IDL 檔案。下列程式碼示例專用於 ClickIn 事件。
下列程式碼行被新增到控制元件類的頭 (.H) 檔案:
複製void FireClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord) {FireEvent(eventidClickIn,EVENT_PARAM(VTS_XPOS_PIXELS VTS_YPOS_PIXELS), xCoord, yCoord);}
此程式碼聲明瞭一個稱為 FireClickIn
的行內函數,該函式用 ClickIn 事件和使用“新增事件嚮導”定義的引數呼叫
COleControl::FireEvent。
另外,下列程式碼行被新增到控制元件的事件對映,此事件對映位於控制元件類的實現 (.CPP) 檔案中:
EVENT_CUSTOM("ClickIn", FireClickIn, VTS_XPOS_PIXELS VTS_YPOS_PIXELS)
此程式碼將 ClickIn 事件對映到行內函數 FireClickIn
,並傳遞使用“新增事件嚮導”定義的引數。
最後,下列程式碼被新增到控制元件的 .IDL 檔案:
複製[id(1)] void ClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord);
這行程式碼根據 ClickIn 事件在“新增事件嚮導”事件列表中的位置,為該事件分配一個特定的 ID 號。事件列表中的項使容器得以預測該事件。例如,它可能提供在引發事件時執行的處理程式程式碼。
呼叫 FireClickIn
您已經使用“新增事件嚮導”添加了自定義事件,現在必須決定引發該事件的時間。通過在發生適當的操作時呼叫 FireClickIn
來完成此決定。在此討論中,當用戶在圓形或橢圓形區域內單擊時,控制元件使用
WM_LBUTTONDOWN 訊息處理程式中的 InCircle
函式引發 ClickIn 事件。下列過程新增
WM_LBUTTONDOW 處理程式。
使用“新增事件嚮導”新增訊息處理程式
- 載入控制元件的專案。
- 在“類檢視”中,選擇 ActiveX 控制元件類。
- 在“屬性”視窗中,單擊“訊息”按鈕。
“屬性”視窗顯示可由 ActiveX 控制元件處理的訊息列表。任何以粗體顯示的訊息都有一個分配的處理函式。
- 在“屬性”視窗中,選擇要處理的訊息。在本例中,選擇“WM_LBUTTONDOWN”。
- 從右邊的下拉列表框中,選擇“<新增> OnLButtonDown”。
- 在“類檢視”中雙擊新的處理函式,跳轉到 ActiveX 控制元件的實現 (.CPP) 檔案中的訊息處理程式程式碼。
下面的程式碼示例在每次在控制元件視窗中單擊滑鼠左鍵時呼叫 InCircle 函式。該示例可在 Circ 示例摘要中的 WM_LBUTTONDOWN 處理函式 OnLButtonDown 中找到。
複製void CSampleCtrl::OnLButtonDown(UINT nFlags, CPoint point) { if (InCircle(point)) FireClickIn(point.x, point.y); COleControl::OnLButtonDown(nFlags, point); }
注意 當“新增事件嚮導”建立滑鼠按鈕操作的訊息處理程式時,將自動新增對基類的相同訊息處理程式的呼叫。不要移除此呼叫。如果控制元件使用任何常用滑鼠訊息,則必須呼叫基類中的訊息處理程式,以確保正確地處理滑鼠捕獲。
在下例中,僅當在控制元件中的圓形或橢圓形區域內發生單擊操作時才引發事件。若要實現此行為,可以將 InCircle
函式放置在控制元件的實現 (.CPP) 檔案中:
BOOL CSampleCtrl::InCircle(CPoint& point) { CRect rc; GetClientRect(rc); // Determine radii double a = (rc.right - rc.left) / 2; double b = (rc.bottom - rc.top) / 2; // Determine x, y double x = point.x - (rc.left + rc.right) / 2; double y = point.y - (rc.top + rc.bottom) / 2; // Apply ellipse formula return ((x * x) / (a * a) + (y * y) / (b * b) <= 1); }
還需要將下列 InCircle
函式宣告新增到控制元件的頭 (.H) 檔案:
BOOL InCircle( CPoint& point );
具有常用名的自定義事件
可以建立與常用事件同名的自定義事件,但不能在同一控制元件中同時實現這兩個事件。例如,您可能想建立一個稱為 Click 的自定義事件,此事件在通常引發常用 Click 事件時不引發。然後,可以通過呼叫此 Click 事件的引發函式隨時引發它。
下列過程新增自定義 Click 事件。
新增使用常用事件名的自定義事件
- 載入控制元件的專案。
- 在“類檢視”中,右擊 ActiveX 控制元件類以開啟快捷選單。
- 在快捷選單中單擊“新增”,然後單擊“新增事件”。
此操作將開啟“新增事件嚮導”。
- 在“事件名稱”下拉列表中選擇一個常用事件名。在本例中,選擇“Click”。
- 在“事件型別”中,選擇“自定義”。
- 單擊“完成”按鈕建立事件。
- 在程式碼中的適當位置呼叫
FireClick
。