通過學習,OCX添加方法、OCX回調JavaScript函數很簡單,沒什麼說的。關鍵在於業務邏輯需要有一段執行時間,大約在3s左右,則出現一個很不友好的現象,當頁面點擊按鈕後執行,按鈕則會卡在那等待執行完畢,頁面出現一種假死狀態,在JS中添加異步調用OCX中的方法無果,所以咬着牙要把業務邏輯的執行放到多線程下,通過子線程回調JS方法。
回調事件必須由OCX初始化時所產生的線程發起子線程發起沒試過怎麼做,思路就是子線程執行完畢後發起postMessage,定義一個消息處理方法,接收消息發起回調。
根據這個思路,得到的解決方案如下
- 定一個消息頭
#define WM_OJBK WM_USER+666
- 聲明一個消息處理函數
afx_msg LRESULT OnFinishPublic(WPARAM wParam, LPARAM lParam);
- 定義消息處理函數宏
BEGIN_MESSAGE_MAP(COcxHelloCtrl, COleControl)
ON_MESSAGE(WM_OJBK,&COcxHelloCtrl::OnFinishPublic)
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()
- 實現函數
LRESULT COcxHelloCtrl::OnFinishPublic(WPARAM wParam, LPARAM lParam)
{
//此函數是你的回調函數
onFinish(L"123");
return 0;
}
完事後跑起來,沒啥效果。。。Google半天沒有迴應
這裏需要理解一下MFC的消息機制,MFC的消息機制是在窗口的基礎上,沒有窗口就沒有消息機制。
還有解決方案是添加一個隱藏的Dialog,在ActiveX的OnCreate方法中使用
mDialog.Create(IDD_XXX,this);
創建一個隱藏的窗體,俺各種嘗試,均無果。這種方式可能適合MFC Dialog的程序使用,但是該OCX是運行在IE瀏覽器上的,我覺得是不能在IE瀏覽器上創建Dialog。
功夫不負有心人,終於找到能解決OCX無Dialog即無消息機制的方案。
重寫OnSetClientSite函數,在OnSetClientSite函數的實現中創建一個Dialog
具體代碼:
void COcxHelloCtrl::OnSetClientSite()
{
if(m_pClientSite){
VERIFY(CreateControlWindow(::GetDesktopWindow(),CRect(0,0,0,0),CRect(0,0,0,0)));
}
COleControl::OnSetClientSite();
}
運行即可,所有的消息機制都可以成功發送與接收了!
如果還有什麼不懂怎麼添加的可以留言回覆。
這裏附上我Demo項目的源碼+測試程序+註冊與註銷腳本,初學者據此加仔細琢磨必能攻克之。
謝謝。