Solved

Communication between MFC ocx and a thread

Posted on 2004-09-28
9
462 Views
Last Modified: 2013-11-20
Situation :
I've created an ocx in MFC. In one of its method, I need to create a thread.
The main thread of the ocx, continues processing after creating this working thread. This working thread receives during its creation a pointer to the ocx so it can use its public member functions.

Problem :
The main thread must be able to process messages send by the worker thread (now done by SendMessage). Once the main thread receives such a message, it'll call its private Event dispatching method.
I don't succeed in sending a message from the worker thread to the main thread.
The method 'SendMessage' hangs, I try to send a message to a hidden window created by the main thread.
How should this be handeld.
Thanks for any advice.
jlsjls
0
Comment
Question by:jlsjls
  • 4
  • 4
9 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 12169391
'This working thread receives during its creation a pointer to the ocx so it can use its public member functions.'
That might not be a good idea.  Use messages to initiate processing and return results via event/memory protected by CCriticalSection or other mechanism.

'The main thread must be able to process messages send by the worker thread (now done by SendMessage). '
SendMessage could cause a blockage (each thread waiting for the other to respond before continuing), PostMessage would be more advisable.
Does your thread have a HWND for the OCX to pass the messages to.  (Using CWnd pointers and the like is dangerous between threads).
0
 
LVL 3

Author Comment

by:jlsjls
ID: 12169659
The reason why the worker thread uses 'SendMessage' is that it needs to wait till the ocx (application) has handled the event. The worker thread sends a message to a hidden window in the ocx. The window procedure should handle this message and fire an event to the application. The application needs to (based on parameters of the event) set some values in this event. When finished, the worker thread can process the results.

Sounds complicated, maybe I'm not at a good track.
0
 
LVL 44

Accepted Solution

by:
AndyAinscow earned 500 total points
ID: 12169823
You could use logic like
PostMessage(....)
WaitForEvent(...)
as you are firing an event back to signal the thread to continue.

Back to your original question.  
Are you passing the HWND of this hidden window to the thread.  pWnd->GetSafeHwnd() will get the HWND of a CWnd* object.  If you aren't using the HWND then that could be why the SendMessage isn't getting to the hidden window.
0
 
LVL 3

Author Comment

by:jlsjls
ID: 12170269
Yes, I'm passing the HWND of the hidden window to the thread. I set it as a public member on my ocx and a pointer to this ocx is passed in the creation of the worker thread.
When debugging my worker thread, I can see the value of the HWND and it's the same as the one I noticed by using Spy++ (where I see the handle of the hidden window).
Maybe I don't need to create the hidden window, you refer to 'pWnd->GetSafeHwnd()' ; how can I retrieve that from an ocx.
I've created a hidden window by the method 'CreateWindow'. This returns a handle to a window which I'm using in my worker thread.
I need to leave the office now, so I won't immediately respond to your answer.
... I'll be back...
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 44

Expert Comment

by:AndyAinscow
ID: 12170329
pWnd->GetSafeHwnd() was just to give an example of getting a HWND from a CWnd pointer.

Lets concentrate on the message not getting to your OCX.
Can you put a messagebox into the message handler in your hidden window (that way we see if it is getting a message or not).
0
 
LVL 3

Author Comment

by:jlsjls
ID: 12170548
When I'm debugging, I don't receive the message in the message handler of the hidden window.
I've already added logging in this message handler.
I'm not sure if my message handler is correct?? Should I use some windows dispatching (thread with GetMessage() ;  DispatchMessage()?? How should this be done?

This is how I create the hidden window with its message handler :
WNDCLASSEX WndClass =
{
sizeof(WNDCLASSEX),             // cbSize
0,                              // style
s_PPPWindowProc,                        // lpfnWndProc
0,                              // cbClsExtra
sizeof( void* ),                // cbWndExtra
AfxGetInstanceHandle(),                  // hInstance
NULL,                           // hIcon
NULL,                           // hCursor
NULL,                           // hbrBackground
NULL,                           // lpszMenuName
g_WindowName_PPPEvents,            // lpszClassName
NULL                            // hIconSm
};
ATOM Atom = RegisterClassEx( &WndClass );
// Create the hidden window
hWdnBanksys = NULL;
hWdnBanksys = CreateWindowEx(
0,                              // extended window style
g_WindowName_PPPEvents,     // pointer to registered class name
g_WindowName_PPPEvents,     // pointer to window name
0,                              // window style
0,                              // horizontal position of window
0,                              // vertical position of window
0,                              // window width
0,                              // window height
NULL,                           // handle to parent or owner window
0,                              // handle to menu, or child-window identifier
AfxGetInstanceHandle(),                  // handle to application instance
this );                         // pointer to window-creation data

if (hWdnBanksys == NULL)
{      
 DWORD dwError = ::GetLastError();
}
else
{
::wsprintf(szPPPText,"Creation of hidden window succeeded.");
}

And window procedure (message handler) :
static LRESULT CALLBACK s_PPPWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static CBanksysCtrl* pThis;
switch (uMsg)
{
case WM_CREATE:
      pThis = (CBanksysCtrl*)((LPCREATESTRUCT) lParam)->lpCreateParams;
      ::SetWindowLong( hwnd, 0, (LONG) pThis );
      return 0;

case WM_PPP_DISPLAYDATA:
      //the worker thread uses WM_PPP_DISPLAYDATA in SendMessage to the hidden window
      ...            
      return 0;
}        
return ::DefWindowProc( hwnd, uMsg, wParam, lParam );
}

0
 
LVL 3

Author Comment

by:jlsjls
ID: 12564914
My error; the reason why the main thread wasn't responding is due to the fact that :
I've added the call WaitForSingleObject(...,INFINITE) and waited for an event which
wasn't fired by the worker thread.
AndyAinscow thanks anyhow for your effort to help me.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 12564964
Your welcome.  Glad you could get it sorted out.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now