ActiveX OCX控件 多線程下回調JavaScript函數

       通過學習,OCX添加方法、OCX回調JavaScript函數很簡單,沒什麼說的。關鍵在於業務邏輯需要有一段執行時間,大約在3s左右,則出現一個很不友好的現象,當頁面點擊按鈕後執行,按鈕則會卡在那等待執行完畢,頁面出現一種假死狀態,在JS中添加異步調用OCX中的方法無果,所以咬着牙要把業務邏輯的執行放到多線程下,通過子線程回調JS方法。

回調事件必須由OCX初始化時所產生的線程發起子線程發起沒試過怎麼做,思路就是子線程執行完畢後發起postMessage,定義一個消息處理方法,接收消息發起回調。

根據這個思路,得到的解決方案如下

  1. 定一個消息頭
#define WM_OJBK WM_USER+666 
  1. 聲明一個消息處理函數
afx_msg LRESULT OnFinishPublic(WPARAM wParam, LPARAM lParam);
  1. 定義消息處理函數宏
BEGIN_MESSAGE_MAP(COcxHelloCtrl, COleControl)
	ON_MESSAGE(WM_OJBK,&COcxHelloCtrl::OnFinishPublic)
	ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()
  1. 實現函數
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項目的源碼+測試程序+註冊與註銷腳本,初學者據此加仔細琢磨必能攻克之。

https://download.csdn.net/download/w1213096890/10812481

謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章