Hi,

I am currently writing an application, which have to create on run-time a
new Control ( for example a CEdit-Control ) in a sperate thread. But when
the thread tries to create the new Control with a call to Create the
application hangs. The class which holds the Thread looks like the following
( The code is only for demonstration purpose ):

class Testing
{
public:
Testing() : bCreate(true)
{
}
void set_parent(CWnd* pWnd)
{
m_pWnd = pWnd;
}
void start_thread()
{
m_hThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
processing,
(LPVOID) this, 0, NULL);
}

void finish()
{
::CloseHandle(m_hThread);
}

static int processing(LPVOID pParam)
{
// try to get the processor-object to have access to the
Communication-Interface
// and all the other Processor-Specific-Things
Testing* pProcessor = static_cast<Testing* >(pParam);
while(true)
{
if(pProcessor->bCreate)
{
pProcessor->edit.Create(0, CRect(50, 50, 180, 180),
pProcessor->m_pWnd, 0);
pProcessor->bCreate = false;
}
}
return 0;
}
protected:
CWnd* m_pWnd;
HANDLE m_hThread;
bool bCreate;
CEdit edit;
};

In the InitInstance of my Dialog-based-MFC-Application I call then:
_testing.set_parent(this);
_testing.start_thread();

Whereby _testing is an object of Testing and a class member of the
Dialog-Class.

Maybe it looks strange, that for the creation of the thread I use an
SDK-function and not the MFC to create a thread, but the problem is, that in
my project the Thread-Creation is done by another vendor by the SDK and I
dont wanna change it, only if there is no other possibility?

How can I solve this problem?

Thanks in advance
Sebastian

Re: create controls in a seperate thread by Ali

Ali
Fri Nov 21 16:41:10 CST 2003

Are you trying to send a pointer to CWnd object to another thread and use it
as the parent for a control created there!
Unfortunatly that will not work!
I am not 100% sure, but I think that you might be able to send it's m_hWnd
member over to the thread and create using that. But like I said I am not
sure. It's generally not a good practice to create control for a window in a
separate thread than the parent window!

Ali R.

"Sebastian Faust" <sfaust_deleteme@logic-software.de> wrote in message
news:bpm2rn$ngh$02$1@news.t-online.com...
> Hi,
>
> I am currently writing an application, which have to create on run-time a
> new Control ( for example a CEdit-Control ) in a sperate thread. But when
> the thread tries to create the new Control with a call to Create the
> application hangs. The class which holds the Thread looks like the
following
> ( The code is only for demonstration purpose ):
>
> class Testing
> {
> public:
> Testing() : bCreate(true)
> {
> }
> void set_parent(CWnd* pWnd)
> {
> m_pWnd = pWnd;
> }
> void start_thread()
> {
> m_hThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
> processing,
> (LPVOID) this, 0, NULL);
> }
>
> void finish()
> {
> ::CloseHandle(m_hThread);
> }
>
> static int processing(LPVOID pParam)
> {
> // try to get the processor-object to have access to the
> Communication-Interface
> // and all the other Processor-Specific-Things
> Testing* pProcessor = static_cast<Testing* >(pParam);
> while(true)
> {
> if(pProcessor->bCreate)
> {
> pProcessor->edit.Create(0, CRect(50, 50, 180,
180),
> pProcessor->m_pWnd, 0);
> pProcessor->bCreate = false;
> }
> }
> return 0;
> }
> protected:
> CWnd* m_pWnd;
> HANDLE m_hThread;
> bool bCreate;
> CEdit edit;
> };
>
> In the InitInstance of my Dialog-based-MFC-Application I call then:
> _testing.set_parent(this);
> _testing.start_thread();
>
> Whereby _testing is an object of Testing and a class member of the
> Dialog-Class.
>
> Maybe it looks strange, that for the creation of the thread I use an
> SDK-function and not the MFC to create a thread, but the problem is, that
in
> my project the Thread-Creation is done by another vendor by the SDK and I
> dont wanna change it, only if there is no other possibility?
>
> How can I solve this problem?
>
> Thanks in advance
> Sebastian
>
>



Re: create controls in a seperate thread by Igor

Igor
Fri Nov 21 16:43:54 CST 2003

"Sebastian Faust" <sfaust_deleteme@logic-software.de> wrote in message
news:bpm2rn$ngh$02$1@news.t-online.com...
> I am currently writing an application, which have to create on
run-time a
> new Control ( for example a CEdit-Control ) in a sperate thread.

Don't even think of doing that. Having a child window created by a
thread different from that of its parent window is one of the easy ways
to get a deadlock in Windows. On top of that, MFC uses thread-local
storage heavily and is not thread-safe.
--
With best wishes,
Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken



Re: create controls in a seperate thread by Sebastian

Sebastian
Fri Nov 21 16:49:49 CST 2003

Why isnt it a good practice?

What can be another solution, cause what I am doing is that over the serial
port some data comes in, and if for example I receive over the COM-Port the
command EDIT I will create a new control. I listen to the COM-Port in
another thread, not to block the main thread.

Bye
Sebastian



Re: create controls in a seperate thread by Sebastian

Sebastian
Fri Nov 21 16:51:00 CST 2003

Hi,

what what then be a solution to my problem?

Bye,
Sebastian



Re: create controls in a seperate thread by Igor

Igor
Fri Nov 21 17:11:12 CST 2003

"Sebastian Faust" <sfaust_deleteme@logic-software.de> wrote in message
news:bpm4ss$uip$03$1@news.t-online.com...
> what what then be a solution to my problem?

Post a message from the worker thread to the main window, have the main
window create the control.
--
With best wishes,
Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken



Re: create controls in a seperate thread by Sebastian

Sebastian
Fri Nov 21 17:13:28 CST 2003

Hi,

"Ali R." <nospam@company.com> schrieb im Newsbeitrag
news:awwvb.4849$CV6.2450625578@newssvr30.news.prodigy.com...
> Are you trying to send a pointer to CWnd object to another thread and use
it
> as the parent for a control created there!
> Unfortunatly that will not work!
> I am not 100% sure, but I think that you might be able to send it's m_hWnd
> member over to the thread and create using that. But like I said I am not
> sure. It's generally not a good practice to create control for a window in
a
> separate thread than the parent window!
Sadly it doesnt work either with the m_hWnd. Any other ideas?

Thanks in advance
Sebastian



Re: create controls in a seperate thread by Scott

Scott
Fri Nov 21 17:24:54 CST 2003

Sebastian Faust wrote:
> Why isnt it a good practice?
>
> What can be another solution, cause what I am doing is that over the serial
> port some data comes in, and if for example I receive over the COM-Port the
> command EDIT I will create a new control. I listen to the COM-Port in
> another thread, not to block the main thread.
>
> Bye
> Sebastian

Your plan is way beyond good practice - there are several reasons that
it cannot work. A window (the edit control) needs a message pump. So
even if you could create a CEdit in a non-MFC thread (you can't) the
window would not work in your thread because it doesn't have a message
pump.

You must create the CEdit in the GUI thread. When your serial thread
wants the GUI thread to do something it should post a user-defined
message to the GUI thread. See...

http://www.mvps.org/vcfaq/mfc/12.htm

--
Scott McPhillips [VC++ MVP]


Re: create controls in a seperate thread by Joseph

Joseph
Fri Nov 21 18:10:39 CST 2003

Don't waste your time trying to make this work. Don't do it.

Don't use CreateThread in an MFC app. You are begging for a first-class disaster.

There is no need to do this. If you think there is a need, read the previous sentence (I'm
currently shipping several realtime apps that have to update controls, and all the
controls are in the main GUI thread.

Any attempt to build child controls in a separate thread is a doomed effort.

Read my essay on worker threads on my MVP Tips site.
joe

On Fri, 21 Nov 2003 23:16:15 +0100, "Sebastian Faust" <sfaust_deleteme@logic-software.de>
wrote:

>Hi,
>
>I am currently writing an application, which have to create on run-time a
>new Control ( for example a CEdit-Control ) in a sperate thread. But when
>the thread tries to create the new Control with a call to Create the
>application hangs. The class which holds the Thread looks like the following
>( The code is only for demonstration purpose ):
>
>class Testing
>{
> public:
> Testing() : bCreate(true)
> {
> }
> void set_parent(CWnd* pWnd)
> {
> m_pWnd = pWnd;
> }
> void start_thread()
> {
> m_hThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
>processing,
> (LPVOID) this, 0, NULL);
> }
>
> void finish()
> {
> ::CloseHandle(m_hThread);
> }
>
> static int processing(LPVOID pParam)
> {
> // try to get the processor-object to have access to the
>Communication-Interface
> // and all the other Processor-Specific-Things
> Testing* pProcessor = static_cast<Testing* >(pParam);
> while(true)
> {
> if(pProcessor->bCreate)
> {
> pProcessor->edit.Create(0, CRect(50, 50, 180, 180),
>pProcessor->m_pWnd, 0);
> pProcessor->bCreate = false;
> }
> }
> return 0;
> }
> protected:
> CWnd* m_pWnd;
> HANDLE m_hThread;
> bool bCreate;
> CEdit edit;
>};
>
>In the InitInstance of my Dialog-based-MFC-Application I call then:
>_testing.set_parent(this);
>_testing.start_thread();
>
>Whereby _testing is an object of Testing and a class member of the
>Dialog-Class.
>
>Maybe it looks strange, that for the creation of the thread I use an
>SDK-function and not the MFC to create a thread, but the problem is, that in
>my project the Thread-Creation is done by another vendor by the SDK and I
>dont wanna change it, only if there is no other possibility?
>
>How can I solve this problem?
>
>Thanks in advance
>Sebastian
>

Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Re: create controls in a seperate thread by Sebastian

Sebastian
Fri Nov 21 20:00:39 CST 2003

Hi,

> Don't waste your time trying to make this work. Don't do it.
>
> Don't use CreateThread in an MFC app. You are begging for a first-class
disaster.
>
> There is no need to do this. If you think there is a need, read the
previous sentence (I'm
> currently shipping several realtime apps that have to update controls, and
all the
> controls are in the main GUI thread.
>
> Any attempt to build child controls in a separate thread is a doomed
effort.
>
> Read my essay on worker threads on my MVP Tips site.
> joe
>
You really have lots of interesting articles on your web-page. I read about
defining User-Defined-Messages and wonder how to use the macro:
DECLARE_USER_MESSAGE

Can you give me an examle how to use it?

I tried the following, but that doesnt work:
pProcessor->m_pWnd->SendMessage(DECLARE_USER_MESSAGE(UWM_CREATE));

What is wrong with that?

Thanks in advance
Sebastian



Re: create controls in a seperate thread by Joseph

Joseph
Sat Nov 22 00:23:51 CST 2003

The article shows that to use my DECLARE_MESSAGE macro, you have to have done a #define of
a name which is the string for the Registered Window Message. That is, in a header file
you put

#define UWM_DOSOMETHING_MSG _T("UWM_DOSOMETHING-guidhere")

and then you can write

DECLARE_MESSAGE(UWM_DOSOMETHING)

which actually expands to

static UINT UWM_DOSOMETHING = ::RegisterWindowMessage(UWM_DOSOMETHING_MSG);

The trick that makes it work is the naming convention of putting _MSG at the end of the
#define constant.

Then you can use that name in a SendMessage:
wnd->SendMessage(UWM_DOSOMETHING, someWvalue, someLvalue);
joe

On Sat, 22 Nov 2003 03:00:39 +0100, "Sebastian Faust" <sfaust_deleteme@logic-software.de>
wrote:

>Hi,
>
>> Don't waste your time trying to make this work. Don't do it.
>>
>> Don't use CreateThread in an MFC app. You are begging for a first-class
>disaster.
>>
>> There is no need to do this. If you think there is a need, read the
>previous sentence (I'm
>> currently shipping several realtime apps that have to update controls, and
>all the
>> controls are in the main GUI thread.
>>
>> Any attempt to build child controls in a separate thread is a doomed
>effort.
>>
>> Read my essay on worker threads on my MVP Tips site.
>> joe
>>
>You really have lots of interesting articles on your web-page. I read about
>defining User-Defined-Messages and wonder how to use the macro:
>DECLARE_USER_MESSAGE
>
>Can you give me an examle how to use it?
>
>I tried the following, but that doesnt work:
>pProcessor->m_pWnd->SendMessage(DECLARE_USER_MESSAGE(UWM_CREATE));
>
>What is wrong with that?
>
>Thanks in advance
>Sebastian
>

Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Re: create controls in a seperate thread by Alexander

Alexander
Sat Nov 22 09:50:11 CST 2003

Registered message is an overkill for internal messages. Better to use some
from WM_APP range.

"Joseph M. Newcomer" <newcomer@flounder.com> wrote in message
news:q00urvossu5jdaoaodk01ru9k97rc06a56@4ax.com...
> The article shows that to use my DECLARE_MESSAGE macro, you have to have
done a #define of
> a name which is the string for the Registered Window Message. That is, in
a header file
> you put
>
> #define UWM_DOSOMETHING_MSG _T("UWM_DOSOMETHING-guidhere")
>
> and then you can write
>
> DECLARE_MESSAGE(UWM_DOSOMETHING)
>
> which actually expands to
>
> static UINT UWM_DOSOMETHING =
::RegisterWindowMessage(UWM_DOSOMETHING_MSG);
>
> The trick that makes it work is the naming convention of putting _MSG at
the end of the
> #define constant.
>
> Then you can use that name in a SendMessage:
> wnd->SendMessage(UWM_DOSOMETHING, someWvalue, someLvalue);
> joe
>



Re: create controls in a seperate thread by Joseph

Joseph
Sun Nov 23 03:54:55 CST 2003

This is not a reliable method. In fact, it is so unreliable that it cost one of my clients
quite a lot of money to fix; I'd been using WM_APP (I was younger and more innocent in
those days), and they added a third-party DLL that also used the same WM_APP messages.
Their programmer wasn't clever enough to figure it out; eventually, after a couple weeks,
they called me, and I found it it a few hours. That's when I stopped using WM_APP
messages. I consider it extremely important that a program remain robust under
maintenance, and this means that I won't introduce features that have this potential for
conflict.
joe

On Sat, 22 Nov 2003 07:50:11 -0800, "Alexander Grigoriev" <alegr@earthlink.net> wrote:

>Registered message is an overkill for internal messages. Better to use some
>from WM_APP range.
>
>"Joseph M. Newcomer" <newcomer@flounder.com> wrote in message
>news:q00urvossu5jdaoaodk01ru9k97rc06a56@4ax.com...
>> The article shows that to use my DECLARE_MESSAGE macro, you have to have
>done a #define of
>> a name which is the string for the Registered Window Message. That is, in
>a header file
>> you put
>>
>> #define UWM_DOSOMETHING_MSG _T("UWM_DOSOMETHING-guidhere")
>>
>> and then you can write
>>
>> DECLARE_MESSAGE(UWM_DOSOMETHING)
>>
>> which actually expands to
>>
>> static UINT UWM_DOSOMETHING =
>::RegisterWindowMessage(UWM_DOSOMETHING_MSG);
>>
>> The trick that makes it work is the naming convention of putting _MSG at
>the end of the
>> #define constant.
>>
>> Then you can use that name in a SendMessage:
>> wnd->SendMessage(UWM_DOSOMETHING, someWvalue, someLvalue);
>> joe
>>
>

Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm