Re: CWinThread, CFrameWnd and memory leak???
"email@example.com" <firstname.lastname@example.org> wrote in message
On Feb 10, 6:25 am, Joseph M. Newcomer <newco...@flounder.com> wrote:
I had missed that the CFrameWnd is created in the secondary thread.
I agree with all the posts: bottom line, don't create windows in
especially not windows that are part of a critical framework like
Not sure why anyone would want to use MSCOMM for anything; it is so
trivial to write good
serial port code without it that I have no idea why anyone would want
to use it.
On Sat, 09 Feb 2008 10:50:17 -0600, "Doug Harrison [MVP]"
On Sat, 9 Feb 2008 07:21:14 -0800 (PST), ole.tetzsch...@gmail.com
I guess it's just me being stupid, but I been googling and trying
hours now and can't solve this problem myself.
The Problem is I have created a class (CmyUIthread) derived from
CWinThread, but when my test-app exit the compiler reports a memory
leak from a CFrameWnd object.
My test-app is just a dialog-app with 2 buttons. The first button
create and starts the ui-thread:
m_p_thread = new CmyUIthread;
And the tread starts perfect :)
The second button stops the thread:
And the thread stops :)
But when i quit my dlg-test-app the compiler reports the memory
I tried adding a third button that:
but this results in access violations.
The access violation occurs because you're relying on the auto-delete
behavior of CWinThread, which is a mistake. Go here for more:
CmyUIthread looks like this:
// TODO: perform and per-thread initialization here
CFrameWnd *wnd = new CFrameWnd;
wnd->Create( NULL, "myUIthread Window");
m_pMainWnd = wnd;
// TODO: perform any per-thread cleanup here
What is wrong??? do I miss some cleanup???
Why are you creating windows in a secondary thread? It's preferable
all the windows in the primary thread, where issues like this don't
If you are leaking a CFrameWnd object, it is due to the window not
receiving the WM_NCDESTROY message or you overriding it and not
base version, which does "delete this". You should be able to set a
breakpoint in CFrameWnd::OnNcDestroy and verify it isn't being
may be that you need to call DestroyWindow on it before exiting your
secondary thread. The tidier way would be to post WM_CLOSE, but it is
possible the frame window will decline to close, so you'd have to
this before using PostQuitMessage.
Joseph M. Newcomer [MVP]
Thank you all for the good feedback, I really appreciate it :)
I was wondering if I had to delete the "net CFrameWnd" but after
comparing it to a SDI application I could not find anywhere it was
deleted... guess that CWinApp deletes it???
My intention was to start a UI-thread with CFrameWnd and a CChildView
with no GUI (hidden anyway) and use CMCComm in that thread. The reason
for CMSComm for serial communication was just a habit... maybe it is
not a good way to do serial communication, but I had used it before in
single-thread app with satisfaction..
So maybe I should try something new :) anyway, I am still happy
that I learned a little about UI-thread :)
With kind regards, Ole :)
As mentioned previously, if you just need a window as a vehicle for
posting messages to, you can embed a CWnd-derived class into your thread
class and use that (see the code for CAsyncSocket and the 'Event Sink').
eg I use this in my UI threads for inter-thread communication rather
than using PostThreadMessage (which appears to drop messages sometimes)
// Thread class with embedded window class (outline of)
class CProtocol : public CWinThread
class CProtocolWnd : public CWnd
void AttachToProtocol ( CProtocol* pProtocol );
afx_msg LRESULT OnStartProcessing (WPARAM wParam, LPARAM lParam);
CWnd* GetProtocolWnd ();
and in the .cpp file
// Embedded window class
m_pProtocol = 0;
void CProtocol::CProtocolWnd::AttachToProtocol ( CProtocol* pProtocol )
m_pProtocol = pProtocol;
ON_MESSAGE(TM_START_THREAD, CProtocolWnd::OnStartProcessing ) // user
LRESULT CProtocol::CProtocolWnd::OnStartProcessing (WPARAM wParam,
m_pProtocol ->OnStartProcessing ( wParam, lParam ); // whatever
// Protocol Class - I do this in a Create function rather than the
m_ppWnd = new CProtocolWnd ();
if ( ! m_ppWnd->CreateEx (0,
_T("Protocol Notification Sink"),
WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL))
m_ppWnd -> AttachToProtocol ( this );
if ( m_ppWnd != 0 )
m_ppWnd -> DestroyWindow ();
m_ppWnd = 0;
To communicate with the thread, other threads can use
CWnd* pWnd = pointerToCProtocol -> GetProtocolWnd();
pWnd -> PostMessage ( ... );
etc. It's a bit simpler if all your posting is internal.