Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

PostThreadMessage question

Posted on 2000-03-20
11
Medium Priority
?
821 Views
Last Modified: 2013-11-20
I need to call a notification function from worker thread, in such a maner that it will run from the main thread. I figured that PostThreadMessage would be the best way. For some reason, PostThreadMessage returns 0, and the function is not being called. Here's my code:

class CDll : public CWinApp
{
public:
      void SyncExecute(void*, LONG);
      void AsyncExecute(void*, void*);
      BOOL InitInstance();
      BOOL ExitInstance();
      
protected:
      //{{AFX_MSG(CDll)
            // NOTE - the ClassWizard will add and remove member functions here.
            //    DO NOT EDIT what you see in these blocks of generated code !
      afx_msg void OnSyncExecute(WPARAM wParam, LPARAM lParam);
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()


typedef void(NPROC)(LONG);

BEGIN_MESSAGE_MAP(CDll, CWinApp)
      //{{AFX_MSG_MAP(CDll)
            // NOTE - the ClassWizard will add and remove mapping macros here.
            //    DO NOT EDIT what you see in these blocks of generated code!
            ON_THREAD_MESSAGE(1272, OnSyncExecute)
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()




//Adds a function from the main thread to execution queue. Used in order to call notification functions from a worker thread
void
CDll::SyncExecute(void *address, LONG param)
{
      PostThreadMessage(1272, (WPARAM)address, (LPARAM)param);
      int n=GetLastError();
}

//Actualy executes the function
void
CDll::OnSyncExecute(WPARAM wParam, LPARAM lParam)
{
      NPROC *address = (NPROC*)wParam;
      address(lParam);
}




---
Thanks in advance

0
Comment
Question by:MikeP090797
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
11 Comments
 
LVL 7

Expert Comment

by:tchalkov
ID: 2636259
Probably for some reason your mainthread does not have a message queue(this is possible if your apllication is a DLL).

Try first to create another object which inherits CWinThread, and create another thread using AfxCreateThread.
Then post your message to that thread.

If this helps then the problem is that your main thread does not have a message loop.

If this does not solve the problem, try calling GetLastError to see what is the error after PostThreadMessage
0
 
LVL 5

Expert Comment

by:Wyn
ID: 2636465
You main thread derive from CWinapp ,so I think you have a message-loop in mainthread.
If you post message from worker thread,you'd specify the correct thread object in your worker thread,i.e:

AfxGetApp( )->Postthreadmessage(....);


Regards
W.Yinan
(I'm not a qualified MFC expert,if wrong,please correct me:)
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 2636538
No need to correct Wyn's comment ... CWinThread::PostThreadMessage() sends the message to the thread represantated by the CWinThread object used with the call.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 7

Expert Comment

by:tchalkov
ID: 2636943
The fact that the application has an object derived from CWinApp does not mean that it has a message loop
0
 
LVL 8

Author Comment

by:MikeP090797
ID: 2637161
The application is a DLL, forgot to mention that. GetLastError returns 0. How do I create a message queue for the thread?

Thanks
0
 
LVL 7

Expert Comment

by:tchalkov
ID: 2639165
As far as your application is a DLL it does not have a main thread - a DLL is called from the thread of the main program.

So if you want to have a separate thread where to do some work, create an object, which is derived from CWinThread. Use AfxBeginThread, to run a thread and pass your class to the function.

In tth above class add the necessaty macros and functions to handle your message.
0
 
LVL 8

Author Comment

by:MikeP090797
ID: 2639716
I already have that. AsyncExecute() creates a new worker thread. That works fine. Now, from that worker thread, I need to cause an execution of another function, but in such a manner that it will run from the main thread, and not the worker. If there is another way besides PostThreadMessage, I'm listening..


Thanks
0
 
LVL 7

Accepted Solution

by:
tchalkov earned 600 total points
ID: 2639731
MikeP, there is NO main thread when you have a DLL. The Application has threads. The DLL only contains functions which Application calls. So what do you mean by main thread?

The only solution is to create a thread, and use this thread to execute all things you want to execute in main thread.

Of course you can modify your application which will use your DLL to have a message pump and to hande your message , but I don't think this is a good idea.
0
 
LVL 8

Author Comment

by:MikeP090797
ID: 2639948
By main thread I mean the application thread. Here is how things work:
An application calls an exported function in a dll. That function starts a thread. When the thread completes, I want it to call another function in the dll, but as if it was called from the application thread, and not the worker. I guess you can call it a thread context.
0
 
LVL 7

Expert Comment

by:tchalkov
ID: 2640266
Although it is possible to do this, there are a lot of limitations.

1. When you start the second thread, you must start retrieving messages from the main thread's message loop, and wait for the message from the second thread. However this will block the main thread and will not return to the caller until the second thread finishes. It seems that this is not what you want.

2. The second way to do this is to modify the application's message loop to look for messages from the second thread and to call a function in the DLL whenever recieves such message. However this solution requires every application which uses this dll to handle the message from the second thread

3. Another way to do this is if you are sure that the main application has a window. Then you can create a hook and monitor all messages sent to the application, and when you recieve the message from the second thread you can call the function in the DLL. However this solution will work only if the main application has a window.
Generally I have not tried if it is possible to hook a thread message loop. But even if it is possible, the main application must have a message loop.

So you can't find a perfect solution of what you want without cooperation with the main app
0
 
LVL 8

Author Comment

by:MikeP090797
ID: 2640355
Ok, thanks for your help.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn different types of Android Layout and some basics of an Android App.
Ready to get certified? Check out some courses that help you prepare for third-party exams.
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.
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …

715 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