C++ MFC

Moderators: Lundin
Number of threads: 3354
Number of posts: 9032

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
threads.. a beginner's agony.. Posted by arthea on 8 Feb 2004 at 9:40 PM
I need to create a new thread to run program in a subDialog box.
The subDialog is a drawing function that consists of a self-defined drawing requirement and an on-paint function that initialize the self function. This subDialog calls on variables from the Main dialog to see how many objects it needs to draw.
Effect: When the Main Prog runs real-time, the sub Prog will show the number of objects simultanously.

So, in creating a thread in the main dialog, how do you create a pointer to point back the subDialog class to the main Dialog?
What do you write for the source code?
Report
Re: threads.. a beginner's agony.. Posted by DB1 on 8 Feb 2004 at 11:54 PM
: I need to create a new thread to run program in a subDialog box.
: The subDialog is a drawing function that consists of a self-defined drawing requirement and an on-paint function that initialize the self function. This subDialog calls on variables from the Main dialog to see how many objects it needs to draw.
: Effect: When the Main Prog runs real-time, the sub Prog will show the number of objects simultanously.
:
: So, in creating a thread in the main dialog, how do you create a pointer to point back the subDialog class to the main Dialog?
: What do you write for the source code?
:

There's a few ways you can do that. One way would be to get a CWnd to the main window and use that to access the main dialog..
 // in ThreadProc
CWnd *CWndParent = AfxGetMainWnd();
 // or
CWnd *CWndParent = GetParent();

((CMyMainDialog*)CWndParent)->DoSomething();

Or the way I would do it is to pass the main dialogs CWnd to the new thread via the CreateThread's lpParameter, then I can use it in the thread.
CWinThread *pThread = AfxBeginThread(ThreadProc, (LPVOID)this, THREAD_PRIORITY_NORMAL);
 // or
HANDLE pThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)this, 0, &pThreadID);

 // in ThreadProc
CWnd *CWndParent = (CWnd*)lpParam;
((CMyMainDialog*)CWndParent)->DoSomething();



To understand recursive, first you need to understand recursive

Report
Re: threads.. a beginner's agony.. Posted by suhredayan on 10 Feb 2004 at 5:12 AM
This message was edited by suhredayan at 2004-2-10 6:5:57


You cannot pass a CWnd object pointer like this between threads. Instead you have to pass the window handle , from which a pointer to the original object can be reconstructed using the static
CWnd::FromHandle function;

eg :
UINT int thread_func (void *arg) 
{
     HWND hwnd = (HWND)arg; 
     CWnd *pWnd = CWnd::FromHandle (hwnd); 
// proceed to use pWnd..
} 



greatest thing is to do wot others think you can't..
suhredayan@omniquad.com



Report
Re: threads.. a beginner's agony.. Posted by dwccgc on 10 Feb 2004 at 6:59 AM
What's wrong with this. It has always worked for me.
void CMyView::StartThread()
{
    AfxBeginThread(MyThread, this, THREAD_PRIORITY_BELOW_NORMAL);
    return;
}

UINT MyThread(LPVOID pParam)
{
    CMyView *pMyView = (CMyView *) pParam;
    
    ...
    ...
    ...
    
    return 0;
}


: This message was edited by suhredayan at 2004-2-10 6:5:57

:
: You cannot pass a CWnd object pointer like this between threads. Instead you have to pass the window handle , from which a pointer to the original object can be reconstructed using the static
: CWnd::FromHandle function;
:
: eg :
:
: UINT int thread_func (void *arg) 
: {
:      HWND hwnd = (HWND)arg; 
:      CWnd *pWnd = CWnd::FromHandle (hwnd); 
: // proceed to use pWnd..
: } 
: 

:
:
: greatest thing is to do wot others think you can't..
: suhredayan@omniquad.com
:
:
:
:

Report
Re: threads.. a beginner's agony.. Posted by suhredayan on 10 Feb 2004 at 8:31 PM


You're breaking a cardinal rule of MFC: Don't pass CWnd objects between
threads. The fact that the code happens to work is a fluke. More
complicated code would definitely be hitting asserts all over the place.

__________________________________________
greatest thing is to do wot others think you can't..
suhredayan@omniquad.com


Report
Re: threads.. a beginner's agony.. Posted by DB1 on 12 Feb 2004 at 9:24 AM
:
:
: You're breaking a cardinal rule of MFC: Don't pass CWnd objects between
: threads. The fact that the code happens to work is a fluke. More
: complicated code would definitely be hitting asserts all over the place.
:

: __________________________________________
: greatest thing is to do wot others think you can't..
: suhredayan@omniquad.com

:
:

Ahh yes, thanks for correcting me. MSDN Technical Note TN003 (Mapping of Windows Handles to Objects) explains it very well.


To understand recursive, first you need to understand recursive

Report
Re: threads.. a beginner's agony.. Posted by stober on 12 Feb 2004 at 11:04 AM
: :
: :
: : You're breaking a cardinal rule of MFC: Don't pass CWnd objects between
: : threads. The fact that the code happens to work is a fluke. More
: : complicated code would definitely be hitting asserts all over the place.
: :

: : __________________________________________
: : greatest thing is to do wot others think you can't..
: : suhredayan@omniquad.com

: :
: :
:
: Ahh yes, thanks for correcting me. MSDN Technical Note TN003 (Mapping of Windows Handles to Objects) explains it very well.
:
:
: To understand recursive, first you need to understand recursive
:
:

The way I do that is to send private messages from thread 2 to its parent thread and let the parent thread update the window, or dialog, or whatever. My program crashed bigtime the first time I attempted to update a dialog in thread #2.

Report
Re: threads.. a beginner's agony.. Posted by DB1 on 12 Feb 2004 at 7:34 PM
: : :
: : :
: : : You're breaking a cardinal rule of MFC: Don't pass CWnd objects between
: : : threads. The fact that the code happens to work is a fluke. More
: : : complicated code would definitely be hitting asserts all over the place.
: : :

: : : __________________________________________
: : : greatest thing is to do wot others think you can't..
: : : suhredayan@omniquad.com

: : :
: : :
: :
: : Ahh yes, thanks for correcting me. MSDN Technical Note TN003 (Mapping of Windows Handles to Objects) explains it very well.
: :
: :
: : To understand recursive, first you need to understand recursive
: :
: :
:
: The way I do that is to send private messages from thread 2 to its parent thread and let the parent thread update the window, or dialog, or whatever. My program crashed bigtime the first time I attempted to update a dialog in thread #2.
:
:


Ok here's what I'm doing..
I'm creating a new thread and passing it the main Dialog's 'm_hWnd' member. In the new thread, I'm creating a new CWnd object using CWnd::FromHandle() on the HWND I passed to it. When I want to notify the main dialog of something, I use MyNewCWnd->PostMessage() with a user-defined message and a user-defined message handler in the main thread to handle it.

Now, if MyNewCWnd->PostMessage() works fine, shouldn't I also be able to call a function directly.. ex: MyNewCWnd->SomeFunction(); or should I only stick to using PostMessage()?




To understand recursive, first you need to understand recursive

Report
Re: threads.. a beginner's agony.. Posted by suhredayan on 12 Feb 2004 at 10:17 PM
: : : :
: : : :
: : : : You're breaking a cardinal rule of MFC: Don't pass CWnd objects between
: : : : threads. The fact that the code happens to work is a fluke. More
: : : : complicated code would definitely be hitting asserts all over the place.
: : : :

: : : : __________________________________________
: : : : greatest thing is to do wot others think you can't..
: : : : suhredayan@omniquad.com

: : : :
: : : :
: : :
: : : Ahh yes, thanks for correcting me. MSDN Technical Note TN003 (Mapping of Windows Handles to Objects) explains it very well.
: : :
: : :
: : : To understand recursive, first you need to understand recursive
: : :
: : :
: :
: : The way I do that is to send private messages from thread 2 to its parent thread and let the parent thread update the window, or dialog, or whatever. My program crashed bigtime the first time I attempted to update a dialog in thread #2.
: :
: :
:
:
: Ok here's what I'm doing..
: I'm creating a new thread and passing it the main Dialog's 'm_hWnd' member. In the new thread, I'm creating a new CWnd object using CWnd::FromHandle() on the HWND I passed to it. When I want to notify the main dialog of something, I use MyNewCWnd->PostMessage() with a user-defined message and a user-defined message handler in the main thread to handle it.
:
: Now, if MyNewCWnd->PostMessage() works fine, shouldn't I also be able to call a function directly.. ex: MyNewCWnd->SomeFunction(); or should I only stick to using PostMessage()?
:
:
:
:
: To understand recursive, first you need to understand recursive
:
:

The object maps are thread-local. ie, if you are in a thread and do a CWnd::FromHandle you will get a new, temporary window object which is not the same C++ object that represented your class initially. Thus this is always fatal in a thread.

instead u can use
CMyWindowClass * me =
(CMyWindowClass *)CWnd::FromHandlePermanent(hWnd);
to get the permanent handle. But only if you actually created the window in that UI-thread itself.

so i feel its better to use stober's idea of sending private messages to the parent thread


__________________________________________
greatest thing is to do wot others think you can't..
suhredayan@omniquad.com


Report
Re: threads.. a beginner's agony.. Posted by DB1 on 13 Feb 2004 at 1:34 AM
: : : The way I do that is to send private messages from thread 2 to its parent thread and let the parent thread update the window, or dialog, or whatever. My program crashed bigtime the first time I attempted to update a dialog in thread #2.
: : :
: : :
: :
: :
: : Ok here's what I'm doing..
: : I'm creating a new thread and passing it the main Dialog's 'm_hWnd' member. In the new thread, I'm creating a new CWnd object using CWnd::FromHandle() on the HWND I passed to it. When I want to notify the main dialog of something, I use MyNewCWnd->PostMessage() with a user-defined message and a user-defined message handler in the main thread to handle it.
: :
: : Now, if MyNewCWnd->PostMessage() works fine, shouldn't I also be able to call a function directly.. ex: MyNewCWnd->SomeFunction(); or should I only stick to using PostMessage()?
: :
: :
: :
: :
: : To understand recursive, first you need to understand recursive
: :
: :
:
: The object maps are thread-local. ie, if you are in a thread and do a CWnd::FromHandle you will get a new, temporary window object which is not the same C++ object that represented your class initially. Thus this is always fatal in a thread.
:
: instead u can use
: CMyWindowClass * me =
: (CMyWindowClass *)CWnd::FromHandlePermanent(hWnd);
: to get the permanent handle. But only if you actually created the window in that UI-thread itself.
:
: so i feel its better to use stober's idea of sending private messages to the parent thread
:

:
: __________________________________________
: greatest thing is to do wot others think you can't..
: suhredayan@omniquad.com

:
:



I'm thinking it's best to simply pass the new thread the main window's m_hWnd, and in the thread use ::PostMessage((HWND)lpParam, WM_SOME_MESSAGE);

What method of sending 'private messges' do you use Stober?





To understand recursive, first you need to understand recursive

Report
Re: threads.. a beginner's agony.. Posted by stober on 13 Feb 2004 at 4:50 AM
This message was edited by stober at 2004-2-13 4:52:25

:
: What method of sending 'private messges' do you use Stober?
:

I use CreateThread() to create thread #2. The 4th parameter ("ThreadParameter") is the current thread ID obtained by calling GetCurrentThreadId().

The new thread calls PostThreadMessage() with the parent's threadID from the thread's argument.


Report
Re: threads.. a beginner's agony.. Posted by suhredayan on 13 Feb 2004 at 5:29 AM
:
: What method of sending 'private messges' do you use Stober?
:

:I use CreateThread() to create thread #2. The 4th parameter
:("ThreadParameter") is the current thread ID obtained by calling
: GetCurrentThreadId().

:The new thread calls PostThreadMessage() with the parent's threadID from the thread's argument.
:


Be carefule that MFC will not dispatch PostThreadMessage() to message or command handlers.You will have to override PreTranslateMessage() function of your CWinApp-derived class.

Also Messages sent to a UI thread through PostThreadMessage will be lost
if the messages are posted while the user is manipulating a window owned by the thread.So Rather than using PostThreadMessage to post messages to a UI thread, use PostMessage to post messages to a window owned by that thread.


__________________________________________
greatest thing is to do wot others think you can't..
suhredayan@omniquad.com


Report
thread got too long so started it over Posted by stober on 13 Feb 2004 at 5:50 AM
: :
: : What method of sending 'private messges' do you use Stober?
: :
:
: :I use CreateThread() to create thread #2. The 4th parameter
: :("ThreadParameter") is the current thread ID obtained by calling
: : GetCurrentThreadId().
:
: :The new thread calls PostThreadMessage() with the parent's threadID from the thread's argument.
: :
:
:
: Be carefule that MFC will not dispatch PostThreadMessage() to message or command handlers.You will have to override PreTranslateMessage() function of your CWinApp-derived class.
:
: Also Messages sent to a UI thread through PostThreadMessage will be lost
if the messages are posted while the user is manipulating a window owned by the thread.So Rather than using PostThreadMessage to post messages to a UI thread, use PostMessage to post messages to a window owned by that thread.
:

:

The parent thread catches the message in PreTranslateMessage() and then reposts with PostMessage() or takes other appropriate action
Report
Re: thread got too long so started it over Posted by suhredayan on 13 Feb 2004 at 8:50 PM
:
: The parent thread catches the message in PreTranslateMessage() and then reposts with PostMessage() or takes other appropriate action
:


But stober still the threat of loosing the message is there b'coz its send to a user interface thread using PostThreadMessage().
(Ref : MSDN ->ID: Q183116)
Wot about sending the message directly to the window of the main thread using PostMessage() function ..

suhredayan@omniquad.com
__________________________________________
greatest thing is to do wot others think you can't..


Report
Re: thread got too long so started it over Posted by stober on 14 Feb 2004 at 4:49 AM
:
:
: But stober still the threat of loosing the message is there b'coz its send to a user interface thread using PostThreadMessage().
: (Ref : MSDN ->ID: Q183116)
: Wot about sending the message directly to the window of the main thread using PostMessage() function ..
:



I'm sending it to CWinApp-derived class, which is not a window.

Here are some additional thoughts on this: And read the reader's comments at the end of the article.

http://www.codeproject.com/tips/gbTestSDI.asp#xx718454xx

and here is another, better article
http://www.codeguru.com/misc/lenop.html
Report
Re: thread got too long so started it over Posted by dwccgc on 14 Feb 2004 at 8:46 AM
I haven't been following this conversation completely, but I thought I would try to give a suggestion. I have a CFormView which executes a thread every minute. If a certain situation occurs, I update a text box on the CFormView. Here is how I do it.

Thread that will post a message to CMainFrame
UINT MyThread(LPVOID pParam)
{
    ::PostMessage(AfxGetMainWnd()->m_hWnd, WM_MY_MSG, NULL, pParam);
    return 0;
}



Thread that will post a message to CFormView
LRESULT CMainFrame::OnMyMsg(WPARAM wParam, LPARAM lParam)
{
	GetActiveView()->PostMessage(WM_MY_MSG, wParam, lParam);
	return 0;
}


CFormView
LRESULT CMyFormView::OnMyMsg(WPARAM wParam, LPARAM lParam)
{
    // Update text box
    ....
    .... 
    ....
    return 0
}


I hope this helps. If not, just ignore me.




: :
: :
: : But stober still the threat of loosing the message is there b'coz its send to a user interface thread using PostThreadMessage().
: : (Ref : MSDN ->ID: Q183116)
: : Wot about sending the message directly to the window of the main thread using PostMessage() function ..
: :

:
:
: I'm sending it to CWinApp-derived class, which is not a window.
:
: Here are some additional thoughts on this: And read the reader's comments at the end of the article.
:
: http://www.codeproject.com/tips/gbTestSDI.asp#xx718454xx
:
: and here is another, better article
: http://www.codeguru.com/misc/lenop.html
:

Report
Re: thread got too long so started it over Posted by J.B. on 15 Feb 2004 at 9:27 AM
I am just wondering,

if there is any particular reason, that PostMessage() should be used, but not SendMessage(). In my multi-threaded application, I have always used SendMessage() and check the return value for successfully corresponding function calls. In my knowledge, it is safe to manipulate variables/objects (via function calls) between threads using it. Is it correct?

J.B.

: I haven't been following this conversation completely, but I thought I would try to give a suggestion. I have a CFormView which executes a thread every minute. If a certain situation occurs, I update a text box on the CFormView. Here is how I do it.
:
: Thread that will post a message to CMainFrame
:
: UINT MyThread(LPVOID pParam)
: {
:     ::PostMessage(AfxGetMainWnd()->m_hWnd, WM_MY_MSG, NULL, pParam);
:     return 0;
: }
: 

:
:
: Thread that will post a message to CFormView
:
: LRESULT CMainFrame::OnMyMsg(WPARAM wParam, LPARAM lParam)
: {
: 	GetActiveView()->PostMessage(WM_MY_MSG, wParam, lParam);
: 	return 0;
: }
: 

:
: CFormView
:
: LRESULT CMyFormView::OnMyMsg(WPARAM wParam, LPARAM lParam)
: {
:     // Update text box
:     ....
:     .... 
:     ....
:     return 0
: }
: 

:
: I hope this helps. If not, just ignore me.

Report
Re: thread got too long so started it over Posted by suhredayan on 15 Feb 2004 at 9:19 PM
: I am just wondering,
:
: if there is any particular reason, that PostMessage() should be used, but not SendMessage(). In my multi-threaded application, I have always used SendMessage() and check the return value for successfully corresponding function calls. In my knowledge, it is safe to manipulate variables/objects (via function calls) between threads using it. Is it correct?
:
: J.B.


check the following article b4 comin to any conclusion..
http://www.codeproject.com/dialog/messagemgmt.asp

suhredayan@omniquad.com
__________________________________________
greatest thing is to do wot others think you can't..





 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.