Activexがブラウザに埋め込まれたときにスレッドがイベントをトリガー
3482 ワード
8
推奨
ブラウザにactivexを埋め込むと、スレッドでトリガーされるイベントは動静せず、デバッグした場合、ブラウザに不正なエラーが発生していることもわかります.同じactivexでアプリケーションを使用して呼び出すと正常です.
解決策は,スレッド内でメッセージを送信し,コントロールがメッセージに応答してFireEventする巧みな方法である.
1.
コントロールアイテムを作成します.
2.
クラスウィザードでは、Addメソッドを使用して2スレッドが起動し、戻ります.次のコード表示方法は、2スレッドを起動し、すぐにMFCActiveXコントロールに戻ります.グローバル関数は、2スレッドの作業関数として宣言されます:
LONG ThreadProc(LPVOID pParam);
void CFireeventCtrl::StartLengthyProcess()
{
DWORD dwID;
HANDLE threadHandle = CreateThread(NULL,NULL,
(LPTHREAD_START_ROUTINE)ThreadProc,
(LPVOID)this, NULL, &dwID);
TRACE("Started the thread %x
",dwID);
}
3. クラスウィザードの2スレッドを使用してイベントを励起するものを追加します.
4.
2スレッドからカスタムメールを送信するように定義します.また、コントロールメッセージマッピングにメッセージマッピング項目を追加してカスタムメッセージを受信すると、メッセージ処理関数が呼び出されます.このメッセージハンドラは、必要なイベントをトリガーします.サンプルがこのMFCActiveXコントロールをどのように実行するか:
//define a custom message:
#define WM_THREADFIREEVENT WM_APP+101
//add an entry for the message to the message map of the control
BEGIN_MESSAGE_MAP(CFireeventCtrl, COleControl)
//{{AFX_MSG_MAP(CFireeventCtrl)
//}}AFX_MSG_MAP
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
ON_MESSAGE(WM_THREADFIREEVENT,OnFireEventForThread) //custom handler
END_MESSAGE_MAP()
//add a handler for the custom message that will fire our event
LRESULT CFireeventCtrl::OnFireEventForThread(WPARAM wParam,
LPARAM lParam)
{
FireLengthyProcessDone();
return TRUE;
}
5. 2スレッドの場合、スレッド中にイベントがトリガーされると、メインスレッドステップ3で定義されたカスタムメッセージが時間的に貼り付けられます.イベントを刺激する.次のコードの説明:
LONG ThreadProc(LPVOID pParam)
{
Sleep(2000); //simulate lengthy processing
CFireeventCtrl *pCtrl = (CFireeventCtrl*)pParam;
PostMessage(pCtrl->m_hWnd,
WM_THREADFIREEVENT,
(WPARAM)NULL,
(LPARAM)NULL);
return TRUE;
}
また、ブラウザはactivexのウィンドウを作成していないようなので、ウィンドウを作成するコードも追加します.MFCは、コントロールウィンドウを作成するためにCOleControl::CreateControlWindow()を呼び出す関数を提供します.MFC実装IOleObject::SetClientSite()コールCOleControl::OnSetClientSite()以下を-COleControl派生クラスに移動します.
// CMyControl is derived from COleControl.
void CMyControl::OnSetClientSite()
{
if (m_pClientSite)
// It doesn't matter who the parent window is or what the size of
// the window is because the control's window will be reparented
// and resized correctly later when it's in-place activated.
VERIFY (CreateControlWindow (::GetDesktopWindow(), CRect(0,0,0,0),
CRect(0,0,0,0)));
COleControl::OnSetClientSite();
}
:
http://topic.csdn.net/t/20040109/17/2650433.html#
http://support.microsoft.com/kb/195188/zh-cn
http://support.microsoft.com/kb/157437