MFC ActiveX 控制: 進階的主題
本文涵蓋的進階開發 ActiveX 控制項相關的主題。 這些需求包括:
ActiveX 控制項中使用資料庫類別
實作一個參數型的屬性
處理您的 ActiveX 控制項中的錯誤
處理控制項中的特殊鍵
存取執行階段不可見的對話方塊控制項
ActiveX 控制項中使用資料庫類別
因為 ActiveX 控制項類別的類別庫的一部分,您可以套用相同的程序和標準的 MFC 應用程式開發使用 MFC 資料庫類別的 ActiveX 控制項中使用資料庫類別的規則。
MFC 資料庫類別的一般概觀,請參閱 (DAO 和 ODBC) 的 MFC 資料庫類別。 本文介紹這兩種 MFC ODBC 類別和 MFC DAO 類別,並指引您到任何所需的詳細資訊。
注意事項 |
---|
從 Visual C++ .NET 開始,Visual C++ 環境和精靈不再支援 DAO (但該版本中仍包含 DAO 類別,您仍然可以使用這些類別)。Microsoft 建議您採用 OLE DB 樣板 或 ODBC 和 MFC 的新專案。請在維護現有應用程式時再使用 DAO。 |
實作一個參數型的屬性
參數化的屬性 (有時稱為屬性陣列) 是一種方法來公開成單一控制項的屬性值的同質集合。 比方說,您可以使用參數化的屬性來公開 (expose) 的陣列或做為屬性的字典。 在 Visual Basic 這類屬性將使用陣列標記法來存取:
x = o.Array(2, 3) ' gets element of 2D array
o.Array(2, 3) = 7 ' sets element of 2D array
使用加入屬性精靈來實作一個參數型的屬性。 加入屬性精靈會藉由新增一對讓控制項使用者使用上述標記法的屬性的 Get/Set 函式,或以標準方式來實作屬性。
類似的方法和屬性,參數型屬性也有參數允許數目上限。 如果是參數型屬性,限制為 15 個參數 (有參數保留給儲存屬性值)。
下列程序會將參數型的屬性,稱為陣列,可以當做整數的二維陣列存取。
若要新增參數型的屬性,使用加入屬性精靈
載入控制項專案。
在 [類別檢視中,展開您的控制項程式庫節點。
您的控制項 (程式庫節點的第二個節點) 的 [介面] 節點上按一下滑鼠右鍵來開啟快顯功能表。
從快速鍵功能表中,按一下 [ 新增 ,然後按一下 [ 加入屬性。
在屬性名稱方塊中,輸入Array。
在屬性型別 ] 方塊中選取 短。
對於實作 型別,按一下 [ Get/Set 方法。
在取得函式和 設定函式 ] 方塊中,輸入您 Get 及 Set 函式的唯一名稱或接受預設名稱。
加入參數,呼叫row (型別short)、 使用參數名稱和參數型別控制項。
新增第二個參數,呼叫column (型別short)。
按一下 [完成]。
所做的變更加入屬性精靈
當您新增自訂屬性時,加入屬性精靈會變更控制項類別標頭檔 (。H) 和實作 (。CPP) 裡的檔案。
下列幾行會加入至控制項類別。H 檔案中:
SHORT GetArray(SHORT row, SHORT column);
void SetArray(SHORT row, SHORT column, SHORT newVal);
這段程式碼會宣告兩個函式呼叫GetArray和SetArray ,讓使用者存取屬性時,要求特定的列和欄。
此外,加入屬性精靈加入下列幾行至控制項的分派對應,位於控制項類別實作 (。Cpp):
DISP_PROPERTY_PARAM_ID(CMyAxUICtrl, "Array", dispidArray, GetArray, SetArray, VT_I2, VTS_I2 VTS_I2)
最後,實作的GetArray和SetArray函式會新增至結尾。CPP 檔案中。 在大多數情況下,您將修改 Get 函式來傳回屬性的值。 Set 函式通常會包含使用者內容之前, 或之後的屬性變更的程式碼。
為這個屬性會很有用,也可以宣告型別的控制項類別中的二維陣列成員變數短,而儲存參數型屬性的值。 您可以修改 Get 函式來傳回儲存在適當資料列和資料行,值,由參數,然後修改 Set 函式,若要更新的資料列和資料行參數所參考的值。
處理您的 ActiveX 控制項中的錯誤
如果在控制項中,發生錯誤狀況,您可能要報告該錯誤的控制項容器。 有兩種方法可以報告錯誤,錯誤發生的情況而定。 如果錯誤發生在屬性的取得或設定函式,就是實作 OLE 自動化方法中,控制項應呼叫 COleControl::ThrowError,哪一個信號給控制項使用者已發生錯誤。 如果在任何時間,就會發生錯誤,應該呼叫控制項 COleControl::FireError,它就會引發的內建的錯誤事件。
若要指示已發生的錯誤的類型,控制項必須傳遞錯誤程式碼ThrowError或FireError。 錯誤代碼是具有 32 位元值的 OLE 狀態碼。 可能的話,請從 OLECTL 中所定義的代碼標準集合中選擇一個錯誤碼。H 標頭檔。 下表摘要說明這些代碼。
ActiveX 控制項的錯誤代碼
錯誤 |
描述 |
---|---|
CTL_E_ILLEGALFUNCTIONCALL |
不合法的函式呼叫 |
CTL_E_OVERFLOW |
溢位 |
CTL_E_OUTOFMEMORY |
記憶體不足 |
CTL_E_DIVISIONBYZERO |
以零為除數 |
CTL_E_OUTOFSTRINGSPACE |
字串空間用完 |
CTL_E_OUTOFSTACKSPACE |
沒有堆疊空間 |
CTL_E_BADFILENAMEORNUMBER |
不合法的檔案名稱或電話號碼 |
CTL_E_FILENOTFOUND |
找不到檔案 |
CTL_E_BADFILEMODE |
不合法的檔案模式 |
CTL_E_FILEALREADYOPEN |
檔案已經開啟 |
CTL_E_DEVICEIOERROR |
週邊設備 I/O 錯誤 |
CTL_E_FILEALREADYEXISTS |
檔案已經存在 |
CTL_E_BADRECORDLENGTH |
不合法的紀錄長度 |
CTL_E_DISKFULL |
磁碟已滿 |
CTL_E_BADRECORDNUMBER |
不合法的紀錄編號 |
CTL_E_BADFILENAME |
損壞的檔名 |
CTL_E_TOOMANYFILES |
太多檔案 |
CTL_E_DEVICEUNAVAILABLE |
裝置無法使用 |
CTL_E_PERMISSIONDENIED |
使用權限被拒 |
CTL_E_DISKNOTREADY |
磁碟未就緒 |
CTL_E_PATHFILEACCESSERROR |
路徑/檔案存取錯誤 |
CTL_E_PATHNOTFOUND |
找不到路徑 |
CTL_E_INVALIDPATTERNSTRING |
無效的模式比對字串 |
CTL_E_INVALIDUSEOFNULL |
NULL 的使用不正確 |
CTL_E_INVALIDFILEFORMAT |
無效的檔案格式 |
CTL_E_INVALIDPROPERTYVALUE |
無效的屬性值 |
CTL_E_INVALIDPROPERTYARRAYINDEX |
無效的屬性陣列索引 |
CTL_E_SETNOTSUPPORTEDATRUNTIME |
設定在執行階段不被支援 |
CTL_E_SETNOTSUPPORTED |
不支援的設定 (唯讀屬性) |
CTL_E_NEEDPROPERTYARRAYINDEX |
需要屬性陣列索引 |
CTL_E_SETNOTPERMITTED |
設定不允許 |
CTL_E_GETNOTSUPPORTEDATRUNTIME |
在執行階段取得不被支援 |
CTL_E_GETNOTSUPPORTED |
取得不受支援 (唯寫屬性) |
CTL_E_PROPERTYNOTFOUND |
找不到屬性 |
CTL_E_INVALIDCLIPBOARDFORMAT |
無效的剪貼簿格式 |
CTL_E_INVALIDPICTURE |
無效的圖片 |
CTL_E_PRINTERERROR |
印表機發生錯誤 |
CTL_E_CANTSAVEFILETOTEMP |
無法將檔案儲存到 TEMP |
CTL_E_SEARCHTEXTNOTFOUND |
找不到搜尋文字 |
CTL_E_REPLACEMENTSTOOLONG |
取代文字太長 |
如果有必要,請使用 CUSTOM_CTL_SCODE 巨集,以定義由其中一個標準的程式碼的條件,並不包含自訂的錯誤代碼。 這個巨集的參數應該是一個整數介於 1000年和 32767 (含)。 例如:
#define MYCTL_E_SPECIALERROR CUSTOM_CTL_SCODE(1000)
如果您要建立一種 ActiveX 控制項來取代現有的 VBX 控制項,定義您 ActiveX 控制項錯誤程式碼使用相同的數字值 VBX 控制項就會使用以確保錯誤碼都相容。
處理控制項中的特殊鍵
在某些情況下可能會想要處理特定按鍵的組合,以特殊方式 ; 比方說,插入新的一行時按下 ENTER 鍵以多行文字] 方塊控制項或編輯的群組之間移動控制項時的方向按鍵按下的識別碼。
如果您的 ActiveX 控制項的基底類別是COleControl,您可以覆寫 CWnd::PreTranslateMessage 來處理訊息前容器加以處理。 當使用這項技術時,永遠傳回 ,則為 TRUE 如果您將訊息處理您的覆寫的PreTranslateMessage。
下列程式碼範例示範可能的方式處理相關的方向鍵來移動到的任何訊息。
BOOL CMyAxUICtrl::PreTranslateMessage(MSG* pMsg)
{
BOOL bHandleNow = FALSE;
switch (pMsg->message)
{
case WM_KEYDOWN:
switch (pMsg->wParam)
{
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
bHandleNow = TRUE;
break;
}
if (bHandleNow)
{
OnKeyDown((UINT)pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
}
break;
}
return bHandleNow;
}
如需有關如何處理 ActiveX 控制項的鍵盤介面的詳細資訊,請參閱 ActiveX SDK 文件。
存取執行階段不可見的對話方塊控制項
您可以建立沒有任何使用者介面,並在執行階段不可見的對話方塊控制項。 如果您將隱藏在 run time ActiveX 控制項加入至對話方塊,並使用 CWnd::GetDlgItem 來存取控制項,控制項將無法正常運作。 相反地,您應該使用下列技術之一來取得物件,表示控制項:
使用 [加入成員變數精靈,選取控制項變數 ,然後選取控制項的 id。 請輸入一個成員變數名稱,然後選取控制項的包裝函式類別,做為控制項型別。
-或-
宣告一個區域變數和子類別為 dialog] 項目。 插入類似下列的程式碼 (CMyCtrl是包裝函式類別, IDC_MYCTRL1是控制項的 ID):
CCirc myCirc; myCirc.SubclassDlgItem(IDC_CIRCCTRL2, this); // ... use myCirc ... myCirc.UnsubclassWindow();