Design of ActiveX Control Using MFC-Step 2

Source: Internet
Author: User
The following is a wonderful reply from the boss of jiangsheng (Jiang Sheng. MSMVP2004Jan:

Knowledge Base Article Q157437: "Fireev.exe
Fires Events from a Second Thread"

Http://support.microsoft.com/support/kb/articles/q157/4/37.asp
Knowledge Base Article Q196026: "PRB:
Firing Event in Second Thread
Causes IPF or GPF"
Http://support.microsoft.com/support/kb/articles/q196/0/26.asp
Michael Lindig's ATL: Firing events from
Worker threads article on CodeGuru.com

Http://www.codeguru.com/atl/ThreadEvents.shtml
Knowledge Base Article Q280512: "SAMPLE:
ATLCPImplMT Encapsulates ATL Event Firing
Across COM Apartments"
Http://support.microsoft.com/support/kb/articles/q280/5/12.asp
Com faq 11: HOWTO: Post messages
A hidden window for raising events
From an Apartment-threaded object
Employing worker threads
Http://www.mvps.org/vcfaq/com/11.htm

This section is taken from csdn (I am sorry I forgot my original position). It mainly addresses how ActiveX controls trigger events from the work thread, I have encountered this problem before, so I will try again today.
Callback routine

1. Create a windowless activation Control TFire and add three methods: void Start (), void End (), void Trigger (LPCTSTR strParam), and event void FireThreadEvent (LPCTSTR strEvent ). Here, Start is used to Start the worker thread, End is used to End the worker thread, Trigger is used to make the worker thread generate events, and ThreadEvent is the name of the generated event.
The idea is as follows:
In the Start method of CTFireCtrl, create the thread MyThread and create the hidden CMyWindow. In the Trigger method, use SetEvent
The notification thread PostMessage is used to hide the window, And CMyWindow calls the FireTheadEvent trigger event of CTFireCtrl.
The End method of CTFireCtr ends the MyThead thread and destroys the hidden window.

2. derive a CMyWindow class from CWnd to hide the window,
A. Add a member variable CTFireCtrl * m_pCtrl to call the FireThreadEvent of CTFireCtrl to generate an event.
B. define the custom message define WM_THREADEVENT WM_USER + 101.
C. Add the custom message processing function LRESULT OnFireThreadEvent (WPARAM wParam, LPARAM lParam) and add it to the Message ing macro, as shown below:

BEGIN_MESSAGE_MAP (CMyWindow, CWnd)
// {AFX_MSG_MAP (CMyWindow)
// NOTE-the ClassWizard will add and remove mapping macros here.
//} AFX_MSG_MAP
ON_MESSAGE (WM_THREADEVENT, OnFireThreadEvent)
END_MESSAGE_MAP ()

The OnFireThreadEvent function is defined as follows. Here, you must first change the FireThreadEvent of CTFireCtrl from protected to public. Of course, you can also create a new function in CTFireCtrl. In this function, Fire is not enough, the method is the same as that in the Fireev routine:

LRESULT CMyWindow: OnFireThreadEvent (WPARAM wParam, LPARAM lParam)
{
M_pCtrl-> FireThreadEvent (LPCTSTR) lParam );
Return 0;
}

D. Add the HWND Create () member function to Create a window and return the window handle for the PostMessage thread. The function is defined as follows:

HWND CMyWindow: Create ()
{
// Register a window class
LPCTSTR classname = 0;
Classname = AfxRegisterWndClass (0 );

// Create the window and return it's handle
CWnd: CreateEx (NULL, classname, NULL, NULL, 1, 1, 1, NULL, NULL );
ASSERT (m_hWnd! = NULL );
Return m_hWnd;
}
E. Rewrite the PostNcDestroy virtual function to delete the CMyWindow class object when the window is destroyed.

Void CMyWindow: PostNcDestroy ()
{
// TODO: Add your specialized code here and/or call the base class
CWnd: PostNcDestroy ();
Delete this;
}

3. Define thread Functions
DWORD MyThread (LPVOID pParam)
{
CTFireCtrl * pctrl = (CTFireCtrl *) pParam;
While (! Pctrl-> m_bEnd ){
DWORD dwRes = WaitForSingleObject (pctrl-> m_hEvent, 100 );
If (dwRes = WAIT_OBJECT_0 ){
PostMessage (pctrl-> m_hMyWnd, WM_THREADEVENT, 0, (LPARAM) LPCTSTR (pctrl-> m_strParam ));
}
}
Return 0;
}
4. We can see that many variables are needed in the thread function. Therefore, the member variables defined in CTFireCtrl are as follows:
BOOL m_bEnd; // determines whether the thread ends.
HANDLE m_hEvent; // event HANDLE, which is not described in detail.
HWND m_hMyWnd; // The Window handle of CMyWindow, which is obtained by its Create function.
CString m_strParam; // The string passed to the event parameter. It is for reference only and obtained by the Trigger method value assignment.

5. Define the Start Function

Void CTFireCtrl: Start ()
{
// TODO: Add your dispatch handler code here
// Initialize the variables passed to the thread
M_bEnd = FALSE;
M_hEvent = CreateEvent (NULL, FALSE, FALSE, NULL );

// Create a hidden window for passing events
CMyWindow * pwnd = new CMyWindow;
Pwnd-> m_pCtrl = this;
M_hMyWnd = pwnd-> Create ();

// Create a working thread
DWORD dwID;
CreateThread (NULL, NULL, (LPTHREAD_START_ROUTINE) MyThread, this, NULL, & dwID );

}

6. Define the Trigger Method

Void CTFireCtrl: Trigger (LPCTSTR strParam)
{
// TODO: Add your dispatch handler code here
M_strParam = strParam;
If (m_hEvent ){
SetEvent (m_hEvent );
}
}

7. Define the End Method

Void CTFireCtrl: End ()
{
// TODO: Add your dispatch handler code here
M_bEnd = TRUE;
Sleep (100 );
CloseHandle (m_hEvent );
M_hEvent = NULL;
: DestroyWindow (m_hMyWnd );
}

8. It should be okay. Compile and start the VB project.
Add a control TFire1 and a button Command1 to Form1 of VB.
The Code is as follows:
Private Sub commandementclick ()
TFire1.Trigger "Hello"
End Sub

Private Sub Form_Load ()
TFire1.Start
End Sub

Private Sub Form_Unload (Cancel As Integer)
TFire1.End
End Sub

Private Sub tfire=threadevent (ByVal strEvent As String)
MsgBox strEvent
End Sub

Debug and run.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.