Click to See Complete Forum and Search --> : SendMessage/PostMessage from thread?
asafaa
November 2nd, 2004, 03:48 AM
i have a simple Worker thread with a pointer to the class that operate him.
i use that pointer to call the class functions from inside the thread.
i want to send messages to another CFrameWnd class from inside the thread ,but i get an assertion failure for that.
Why can't i send messages (by postmessage/Sendmessage) from inside the thread?
How can i "talk" with another class from inside the thread ?
please help!
Kheun
November 2nd, 2004, 04:00 AM
MFC is not thread-safe. Object created in one thread cannot be directly access into another different thread. For passing messages, you shouldn't be using the member function of CWnd class but rather you should use the global ::SendMessage() and ::PostMessage() with the Window handle.
r_kalidass
November 2nd, 2004, 04:04 AM
Instead of pointer to the class pass the window handle to the worker thread.
asafaa
November 2nd, 2004, 04:09 AM
Thank you for the replies,
So what you are both saying is that if i have a thread in class 1 and i want to communicate with class 2 from inside the class 1 thread , i should get the class 2 window handle , insert it to the class 1 thread and communicate by PostMessage from there ?
how can i get the class 2 window handle from class 1 ?
Kheun
November 2nd, 2004, 04:21 AM
You can retrive the Window handle from Base class method, CWnd::GetSafeHwnd(), and then pass it as the parameter for the thread function.
DWORD WINAPI ThreadFunc( LPVOID lpParam )
{
HWND handle = (HANDLE)lpParam;
::PostMessage(handle, MY_MESSAGE, 0, 0);
return 0;
}
asafaa
November 2nd, 2004, 04:34 AM
Thanks , but i still dont have an answer....
how can i get the class 2 window handle inside class 1 ?
GetSafeHWnd can get the class 2 window handle only from class 2 , am i right ?
the two classes are not connected , they don't know about each other , thats why i what to use the PostMessage() , so that the CFrameWnd mesages will connect them and they will be able to "Talk".
Kheun
November 2nd, 2004, 04:55 AM
Let try to look at it this way. When your program starts, the main thread will be creating objects, for example instance of class 2. In other words, class 2 belongs to the main thread. After the main thread spawn off another thread and the handle of class 2 instance is also passed over to the thread function. Within the thread function, the second thread can create an instance of class 1 and the handle is passed to it. Then the second thread properly loops within a member function of class 1. In the event that instance of class 1 needs to send/post message to instance of class 2, it can use the global SendMessage or PostMessage with the handle.
Hope this helps.
JohnCz
November 2nd, 2004, 06:54 AM
global SendMessage or PostMessage with the handle. :confused:
SendMessage and PostMessage are either members of CWnd class that wrap API SendMessage and PostMessage or native Windows API calls. What is "global" here?
JohnCz
November 2nd, 2004, 06:56 AM
how can i get the class 2 window handle inside class 1 ?
Assuming class 1 and 2 are derived from CWnd and window is attached to both, you can always obtain handle to any window in the application. What classes are you referring to?
asafaa
November 2nd, 2004, 07:17 AM
i want the Classes to work seperatly ,
class 1 = receives data from COM1 by a thread , after all the data ( protocol ) is received , class 1 notifies class 2.
When class 2 is notified of the new data , it uses it ( lets say save it to file )
2 questions :
1.how does class 1 notify class 2 of the new data ?
2.Were should i put the shared buffer ?
i thought that if the two classes are CFrameWnd derived ,class 1 can send message to class 2 about the new data. but class 1 doesn't have the class 2 handle. how do i "connect" between the 2 classes ?
JohnCz
November 2nd, 2004, 07:22 AM
I do not know architecture of your application. There is always a way of obtaining pointer to some object from another object.
Using that pointer you can ask for Window handle.
Kheun
November 2nd, 2004, 07:44 PM
:confused:
SendMessage and PostMessage are either members of CWnd class that wrap API SendMessage and PostMessage or native Windows API calls. What is "global" here?Actually, I mean the native Windows API. I used the term global because it is residing within the global scope.
MikeAThon
November 3rd, 2004, 02:03 AM
:confused:
SendMessage and PostMessage are either members of CWnd class that wrap API SendMessage and PostMessage or native Windows API calls. What is "global" here?
The wrappers don't work in different threads. The reason is that the temporary and permamnent handle maps are stored in thread-local stoage. As a consequence, when you ask for a CWnd pointer from a different thread, you get one with a bad/undefined m_hWnd member, and the wrapper functions all fail (which is probably what the OP is seeing).
If the CWnd pointer is passed to the thread from the "owner" thread, such as in the LPVOID parameter that accompanies the thread function, then m_hWnd *should* be OK.
Mike
Marc from D
November 3rd, 2004, 02:26 AM
What I do, and it works fine for me until now, is the following:
if (HwndDialog)
PostMessage(HwndDialog, WM_TEXT1, i, 1);
"HwndDialog" is a global variable, just filled with a value from GetSafeHwnd inside the class I want to send my message to.
The receiving class has certainly to reset the variable to "0" when it closes.
I'm aware, that I do not support the classes-idea doing this, but it is working and little effort.
Marc
Andreas Masur
November 3rd, 2004, 03:03 AM
iHow can i "talk" with another class from inside the thread ?
Take a look at the following FAQ (http://www.codeguru.com/forum/showthread.php?t=312454)...
JohnCz
November 3rd, 2004, 07:57 AM
The wrappers don't work in different threads. . .
Where did I say that they would? This was a statement and question for Kheun, who referred to SendMessage and PostMessage as global. It has nothing to do with passing CWnd pointer to a thread.
:confused:
SendMessage and PostMessage are either members of CWnd class that wrap API SendMessage and PostMessage or native Windows API calls. What is "global" here?
JohnCz
November 3rd, 2004, 08:01 AM
"HwndDialog" is a global variable, . . .You do not need global variable. You can pass window’s handle as LPVOID parameter in AfxBeginThread call. In a thread procedure cast it to HWND and use to send/post messages.
Kheun
November 3rd, 2004, 08:09 PM
I thought I have already explained in this post (http://www.codeguru.com/forum/showpost.php?p=1041015&postcount=12) . :confused:
I have to agree that using the term "Windows native API" is more accruate. In global scope, I mean we can call it just like any global function since it is not part of any class.
void foo()
{
// :: is the scope operator.
// With prepending with any name before ::,
// we call the function in the global scope.
::SendMessage(...);
}
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.