VC呼叫OCX的方法
可以開發 MFC ActiveX 控制元件作為自動化伺服器,用來以程式設計方式將控制元件嵌入其他應用程式,並從應用程式呼叫控制元件中的方法。這樣的控制元件仍可以在 ActiveX 控制元件容器中被承載。
建立控制元件作為自動化伺服器
- 新增方法。
- 重寫 IsInvokeAllowed。有關更多資訊,請參見知識庫文章 Q146120。
- 生成控制元件。
以程式設計方式訪問自動化伺服器中的方法
- 建立應用程式,例如 MFC exe。
- 在 InitInstance 函式的開始處新增下列程式碼行: 複製 AfxOleInit();
- 在“類檢視”中右擊專案節點,並選擇“從型別庫新增類”以匯入型別庫。
此操作將副檔名為 .h 和 .cpp 的檔案新增到專案。
- 在將要呼叫 ActiveX 控制元件中的一個或多個方法的類的標頭檔案中新增此行:
#include filename.h
,其中的檔名為匯入型別庫時建立的標頭檔案名。 - 在將要呼叫 ActiveX 控制元件中的方法的函式中,新增建立控制元件包裝類的物件和建立 ActiveX 物件的程式碼。例如,下列 MFC 程式碼例項化
CtlTest
控制元件、呼叫 Multiply 方法並在單擊對話方塊中的“確定”按鈕時顯示結果: void CMultiply::OnOK() {UpdateData(); // Get the current data from the dialog box. _DCtlTest test; // Create a wrapper class for the ActiveX object. COleException e; // In case of errors// Create the ActiveX object. // The name is the control's progid; look it up using OleViewif (test.CreateDispatch( "CTLTEST.CtlTestCtrl.1", &e )) {// call the Multiply method of your ActiveX object// get the result into m_product m_product = test.Multiply( m_a, m_b ); UpdateData( FALSE ); // Display the string in the dialog box. } else { // An error char buf[255]; e.GetErrorMessage( buf, sizeof( buf ) ); AfxMessageBox( buf ); // Display the error message. }}
如果在應用程式中使用 ActiveX 控制元件後將方法新增到 ActiveX 控制元件中,則可以通過刪除在匯入型別庫時建立的檔案,開始在應用程式中使用控制元件的最新版本。然後再次匯入型別庫。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+災難性故障原因
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
在其中一個 OLE 容器不支援控制元件的情況下包容,可能想要使用 OLE 控制元件作為自動化伺服器來訪問其屬性和方法。這篇文
章解釋了您需要 OLE 控制元件作為普通的自動化伺服器以便進行必要的修改。
之前到 Visual c + + 4.0,OLE 控制元件可以用作自動化伺服器而無需進行任何修改。然而,在 MFC 4.0,框架的實現的
IDispatch::Invoke 呼叫虛擬函式確定自動化伺服器是否處於適當的狀態來處理自動化 IsInvokeAllowed 呼叫。預設實現中
CCmdTarget::IsInvokeAllowed,返回真,暗伺服器可以處理自動化呼叫。
在一個 OLE 控制元件的情況下 COleControl::IsInvokeAllowed 檢查是否控制元件已被初始化或通過持久儲存介面正確載入。如果該
控制元件中有適當的狀態資訊,則此函式返回 TRUE。建立 OLE 控制元件時為普通的自動化伺服器,它不會建立為一個嵌入在客戶
端中。因此的持久狀態初始化任何會因此導致 IsInvokeAllowed 返回 FALSE 的地方。此操作的效果是自動化物件方法的調
用生成的 (8000ffff) 執行時錯誤:"災難性失敗"。
若要使用 OLE 控制元件只能作為自動化伺服器,必須重寫 COleControl::IsInvokeAllowed() 並返回 TRUE。如果任何控制元件的屬
性和方法不應訪問作為一個普通的自動化伺服器呼叫時,然後該自動化函式可能會跳過並/或 COleControl::m_bInitialized
為 FALSE 時返回的錯誤程式碼。
BOOL CMyOleControl::IsInvokeAllowed (DISPID)
{
// You can check to see if COleControl::m_bInitialized is FALSE
// in your automation functions to limit access.
return TRUE;
}
VC MFC程式呼叫OCX的方法:
HRESULT hr = NULL;
IDispatch* pIDispatch = NULL;
wchar_t progid[] = L"MFCOCX.MfcocxCtrl.1"; //元件名
CLSID clsid;
hr = ::CLSIDFromProgID(progid, &clsid);
hr = ::CoInitialize(NULL);
_DMfc_ocx obj;
hr = obj.CreateDispatch("MFCOCX.MfcocxCtrl.1"); // 必需的
if(SUCCEEDED(hr))
{
int rv = obj.Add(1,2);
}