|
From: Ajay Kalra on 2 May 2008 17:32 On May 2, 5:03 pm, Nick Schultz <NickSchu...(a)discussions.microsoft.com> wrote: > OK, I tried overriding both PostNcDestroy and OnPressCloseButton functions > and it still isn't working the way I would like it to... > > When I create the window, it starts out docked to the main frame. If I > undock the window and then close it, those functions do not get called. If I > leave it docked, or undock it and dock it again and then close the window, > those functions get called. > > After going through those two functions, I then get an Access violation: > > Unhandled exception at 0x78a75e55 (mfc90ud.dll) in CanAnalyzer.exe: > 0xC0000005: Access violation reading location 0xfeef000e. > > and the break point is at the return statement: > > LRESULT CWnd::Default() > { > // call DefWindowProc with the last message > _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData(); > return DefWindowProc(pThreadState->m_lastSentMsg.message, > pThreadState->m_lastSentMsg.wParam, pThreadState->m_lastSentMsg.lParam); > > } > > Here is the code of the closing functions: > > void CGrapher::OnPressCloseButton() > { > DestroyWindow(); } > > void CGrapher::PostNcDestroy(){ > delete this; > > } > > So i guess I got a couple questions now, why am i getting that access > violation and why wont those functions get called when the CDockablePane is > undocked(floating)? > > Thanks for the help, > > Nick > > "Joseph M. Newcomer" wrote: > > If you are allocating them on the heap, with new, the easiest way is to add a > > PostNcDestroy handler to your class whose body says > > delete this; > > replacing the TODO: line. > > > You cannot delete an object earlier than the PostNcDestroy handler. > > joe > > > On Fri, 2 May 2008 10:59:01 -0700, Nick Schultz <NickSchu...(a)discussions.microsoft.com> > > wrote: > > > >Hi there, > > > >My user will need to be able to open any number of graphing > > >windows(CDockablePane) in my application. When the window is closed, I want > > >the pane to be destroyed. > > > >In order to do this I will have my window catch the press close button event > > >(CPane::OnPressCloseButton) and then have it call DestroyWindow(). > > > >reading DestroyWindow description, it looks like it does everything but it > > >does not destroy the CWnd object. > > > >So how do I destroy the CWnd object? Do i just simply need to call delete > > >(pointer to graph window). I was thinking I could override the NotifyParent > > >function to catch child destroyed event and then deleting it then, however > > >the parent gets notified BEFORE any destruction takes place. > > > >I'm not sure if this is possible, but after calling DestroyWindow() within > > >the OnPressCloseButton() function, could I just call "delete this" to free > > >up any memory used by the graph window? > > > >Any suggestions are greatly appreciated. > > > >Nick > > Joseph M. Newcomer [MVP] > > email: newco...(a)flounder.com > > Web:http://www.flounder.com > > MVP Tips:http://www.flounder.com/mvp_tips.htm Also, I have not installed the feature pack so I cant confirm but does CDockablePane override PostNcDestroy? If it does, what is it doing in it? Also, you should call the base class in PostNcDestroy before calling delete this. You should also read this: http://msdn.microsoft.com/en-us/library/5zba4hah(VS.80).aspx --- Ajay
From: Nick Schultz on 2 May 2008 17:58 Alright, using PostMessage(WM_CLOSE) got rid of the access violation. However the docked panel stays painted on the screen(i can also "paint" other windows in the area as well) until I resize the main window (when the paint method gets called) The main window only has one control and it is a CListCtrl. Thanks Ajay, it looks like I'm getting closer, however these functions don't get called at all when the CDockablePane is not docked. I am confirming this by setting breakpoints and watching the thread list in Process Explorer. "Ajay Kalra" wrote: > On May 2, 5:03 pm, Nick Schultz > <NickSchu...(a)discussions.microsoft.com> wrote: > > OK, I tried overriding both PostNcDestroy and OnPressCloseButton functions > > and it still isn't working the way I would like it to... > > > > When I create the window, it starts out docked to the main frame. If I > > undock the window and then close it, those functions do not get called. If I > > leave it docked, or undock it and dock it again and then close the window, > > those functions get called. > > > > After going through those two functions, I then get an Access violation: > > > > Unhandled exception at 0x78a75e55 (mfc90ud.dll) in CanAnalyzer.exe: > > 0xC0000005: Access violation reading location 0xfeef000e. > > > > and the break point is at the return statement: > > > > LRESULT CWnd::Default() > > { > > // call DefWindowProc with the last message > > _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData(); > > return DefWindowProc(pThreadState->m_lastSentMsg.message, > > pThreadState->m_lastSentMsg.wParam, pThreadState->m_lastSentMsg.lParam); > > > > } > > > > Here is the code of the closing functions: > > > > void CGrapher::OnPressCloseButton() > > { > > DestroyWindow(); } > > > > void CGrapher::PostNcDestroy(){ > > delete this; > > > > } > > > > So i guess I got a couple questions now, why am i getting that access > > violation and why wont those functions get called when the CDockablePane is > > undocked(floating)? > > > > Thanks for the help, > > > > Nick > > > > "Joseph M. Newcomer" wrote: > > > If you are allocating them on the heap, with new, the easiest way is to add a > > > PostNcDestroy handler to your class whose body says > > > delete this; > > > replacing the TODO: line. > > > > > You cannot delete an object earlier than the PostNcDestroy handler. > > > joe > > > > > On Fri, 2 May 2008 10:59:01 -0700, Nick Schultz <NickSchu...(a)discussions.microsoft.com> > > > wrote: > > > > > >Hi there, > > > > > >My user will need to be able to open any number of graphing > > > >windows(CDockablePane) in my application. When the window is closed, I want > > > >the pane to be destroyed. > > > > > >In order to do this I will have my window catch the press close button event > > > >(CPane::OnPressCloseButton) and then have it call DestroyWindow(). > > > > > >reading DestroyWindow description, it looks like it does everything but it > > > >does not destroy the CWnd object. > > > > > >So how do I destroy the CWnd object? Do i just simply need to call delete > > > >(pointer to graph window). I was thinking I could override the NotifyParent > > > >function to catch child destroyed event and then deleting it then, however > > > >the parent gets notified BEFORE any destruction takes place. > > > > > >I'm not sure if this is possible, but after calling DestroyWindow() within > > > >the OnPressCloseButton() function, could I just call "delete this" to free > > > >up any memory used by the graph window? > > > > > >Any suggestions are greatly appreciated. > > > > > >Nick > > > Joseph M. Newcomer [MVP] > > > email: newco...(a)flounder.com > > > Web:http://www.flounder.com > > > MVP Tips:http://www.flounder.com/mvp_tips.htm > > Dont call DestroyWindow; use PostMessage(WM_CLOSE) instead. See if > that helps. > > -- > Ajay >
From: Nick Schultz on 2 May 2008 19:37 It still doesn't look like I am destroying the CDockable Panel correctly. I am getting some very wierd responses. I'll try to list all of the occurances I'm noticing, perhaps somebody will see something: 1. When a CDockablePanel is docked and I hit the 'X' button, the window disapears and memory and thread is cleared,which is the desired action, however it looks like there is a base control still there, since the ListCtrl in the mainframe will not resize to take up the whole frame. This disapears when I resize, move, or create a new panel. 2. If the panel is in autohide mode and i close it, the panel disapears, HOWEVER the tab bar stays with the tab for the panel, if I try to resize or move , I get an access violation. I also get an access violation if I hover the mouse over the tab. 3. If the panel is floating and I hit the 'X' button, the panel goes away, however my OnPressCloseButton function does not get called, thus does not free resources 4. When the panel is floating, I right click on the window and I get a menu of ( Docking,X Floating,or Hide). If i select Hide, the OnPressCloseButton function gets called and resources are freed 5. If the panel is floating, and I create another panel and dock it with the floating panel, I can then hit the 'X' on one of the docked panels and it will free resources AND removes the panel from the screen. This is the desired result, however I want to be able to push the "X". (So it looks like it has to be docked for the OnPressCloseButton to be called, when it floats it uses a miniframe, so should is there a message that the miniframe would post when it's "X" is pushed?) 6. If the panel is docked and I right click and select Hide, resources are freed, however the panel stays and I get the same results as in [1]&[2]. Thanks you guys for the help, Nick "Nick Schultz" <NickSchultz(a)discussions.microsoft.com> wrote in message news:8824E7C6-FA47-487A-9242-49A5028321E5(a)microsoft.com... > Alright, using PostMessage(WM_CLOSE) got rid of the access violation. > However the docked panel stays painted on the screen(i can also "paint" > other > windows in the area as well) until I resize the main window (when the > paint > method gets called) The main window only has one control and it is a > CListCtrl. > > Thanks Ajay, it looks like I'm getting closer, however these functions > don't > get called at all when the CDockablePane is not docked. I am confirming > this > by setting breakpoints and watching the thread list in Process Explorer. > > "Ajay Kalra" wrote: > >> On May 2, 5:03 pm, Nick Schultz >> <NickSchu...(a)discussions.microsoft.com> wrote: >> > OK, I tried overriding both PostNcDestroy and OnPressCloseButton >> > functions >> > and it still isn't working the way I would like it to... >> > >> > When I create the window, it starts out docked to the main frame. If I >> > undock the window and then close it, those functions do not get called. >> > If I >> > leave it docked, or undock it and dock it again and then close the >> > window, >> > those functions get called. >> > >> > After going through those two functions, I then get an Access >> > violation: >> > >> > Unhandled exception at 0x78a75e55 (mfc90ud.dll) in CanAnalyzer.exe: >> > 0xC0000005: Access violation reading location 0xfeef000e. >> > >> > and the break point is at the return statement: >> > >> > LRESULT CWnd::Default() >> > { >> > // call DefWindowProc with the last message >> > _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData(); >> > return DefWindowProc(pThreadState->m_lastSentMsg.message, >> > pThreadState->m_lastSentMsg.wParam, >> > pThreadState->m_lastSentMsg.lParam); >> > >> > } >> > >> > Here is the code of the closing functions: >> > >> > void CGrapher::OnPressCloseButton() >> > { >> > DestroyWindow(); } >> > >> > void CGrapher::PostNcDestroy(){ >> > delete this; >> > >> > } >> > >> > So i guess I got a couple questions now, why am i getting that access >> > violation and why wont those functions get called when the >> > CDockablePane is >> > undocked(floating)? >> > >> > Thanks for the help, >> > >> > Nick >> > >> > "Joseph M. Newcomer" wrote: >> > > If you are allocating them on the heap, with new, the easiest way is >> > > to add a >> > > PostNcDestroy handler to your class whose body says >> > > delete this; >> > > replacing the TODO: line. >> > >> > > You cannot delete an object earlier than the PostNcDestroy handler. >> > > joe >> > >> > > On Fri, 2 May 2008 10:59:01 -0700, Nick Schultz >> > > <NickSchu...(a)discussions.microsoft.com> >> > > wrote: >> > >> > > >Hi there, >> > >> > > >My user will need to be able to open any number of graphing >> > > >windows(CDockablePane) in my application. When the window is >> > > >closed, I want >> > > >the pane to be destroyed. >> > >> > > >In order to do this I will have my window catch the press close >> > > >button event >> > > >(CPane::OnPressCloseButton) and then have it call DestroyWindow(). >> > >> > > >reading DestroyWindow description, it looks like it does everything >> > > >but it >> > > >does not destroy the CWnd object. >> > >> > > >So how do I destroy the CWnd object? Do i just simply need to call >> > > >delete >> > > >(pointer to graph window). I was thinking I could override the >> > > >NotifyParent >> > > >function to catch child destroyed event and then deleting it then, >> > > >however >> > > >the parent gets notified BEFORE any destruction takes place. >> > >> > > >I'm not sure if this is possible, but after calling DestroyWindow() >> > > >within >> > > >the OnPressCloseButton() function, could I just call "delete this" >> > > >to free >> > > >up any memory used by the graph window? >> > >> > > >Any suggestions are greatly appreciated. >> > >> > > >Nick >> > > Joseph M. Newcomer [MVP] >> > > email: newco...(a)flounder.com >> > > Web:http://www.flounder.com >> > > MVP Tips:http://www.flounder.com/mvp_tips.htm >> >> Dont call DestroyWindow; use PostMessage(WM_CLOSE) instead. See if >> that helps. >> >> -- >> Ajay >>
From: Joseph M. Newcomer on 2 May 2008 22:58
See below... On Fri, 2 May 2008 16:37:38 -0700, "Nick Schultz" <nick.schultz(a)flir.com> wrote: >It still doesn't look like I am destroying the CDockable Panel correctly. I >am getting some very wierd responses. I'll try to list all of the >occurances I'm noticing, perhaps somebody will see something: > >1. When a CDockablePanel is docked and I hit the 'X' button, the window >disapears and memory and thread is cleared,which is the desired action, >however it looks like there is a base control still there, since the >ListCtrl in the mainframe will not resize to take up the whole frame. This >disapears when I resize, move, or create a new panel. **** Yes, that is correct behavior. You will need to call RecalcLayout (if I am remembering the name correctly). If you don't force the recalculation of the layout explicitly, it won't happen. **** > >2. If the panel is in autohide mode and i close it, the panel disapears, >HOWEVER the tab bar stays with the tab for the panel, if I try to resize or >move , I get an access violation. I also get an access violation if I >hover the mouse over the tab. **** I've not tried this, so I don't have a clue here...I suspect the issue is related to the fact that the tab has not been told to go away, because your destruction happens at a level below the window that is managing the tab. You will probably need to PostMessage to the parent a notification that the window is being destroyed, so you can force the tab to go away. Beyond that, I can't say **** > >3. If the panel is floating and I hit the 'X' button, the panel goes away, >however my OnPressCloseButton function does not get called, thus does not >free resources **** It would be worthwhile studying what sequence of messages is sent, using Spy++. The OnPressClose button should not free ANY resources at all; any resources that must be freed should be freed in the OnDestroy handler. That will help. **** > >4. When the panel is floating, I right click on the window and I get a menu >of ( Docking,X Floating,or Hide). If i select Hide, the OnPressCloseButton >function gets called and resources are freed **** This sounds odd. I'd be suspicious of what triggers on OnPressCloseButton message **** > >5. If the panel is floating, and I create another panel and dock it with >the floating panel, I can then hit the 'X' on one of the docked panels and >it will free resources AND removes the panel from the screen. This is the >desired result, however I want to be able to push the "X". (So it looks like >it has to be docked for the OnPressCloseButton to be called, when it floats >it uses a miniframe, so should is there a message that the miniframe would >post when it's "X" is pushed?) **** I suspect that what is happening is that you have a view inside the frame, so putting handlers for messages in the view will *not* handle any messages sent to the containing frame. This is why you want to put your resource-freeing logic in the OnDestroy handler, because that makes it independent of who is doing the destruction. **** > >6. If the panel is docked and I right click and select Hide, resources are >freed, however the panel stays and I get the same results as in [1]&[2]. **** The RecalcLayout method should fix this. Note that it must be called in the containing frame window, not in the view itself. That's all I can think of at the moment; I have virtually no experience with docking windows. joe **** > >Thanks you guys for the help, > >Nick > > > >"Nick Schultz" <NickSchultz(a)discussions.microsoft.com> wrote in message >news:8824E7C6-FA47-487A-9242-49A5028321E5(a)microsoft.com... >> Alright, using PostMessage(WM_CLOSE) got rid of the access violation. >> However the docked panel stays painted on the screen(i can also "paint" >> other >> windows in the area as well) until I resize the main window (when the >> paint >> method gets called) The main window only has one control and it is a >> CListCtrl. >> >> Thanks Ajay, it looks like I'm getting closer, however these functions >> don't >> get called at all when the CDockablePane is not docked. I am confirming >> this >> by setting breakpoints and watching the thread list in Process Explorer. >> >> "Ajay Kalra" wrote: >> >>> On May 2, 5:03 pm, Nick Schultz >>> <NickSchu...(a)discussions.microsoft.com> wrote: >>> > OK, I tried overriding both PostNcDestroy and OnPressCloseButton >>> > functions >>> > and it still isn't working the way I would like it to... >>> > >>> > When I create the window, it starts out docked to the main frame. If I >>> > undock the window and then close it, those functions do not get called. >>> > If I >>> > leave it docked, or undock it and dock it again and then close the >>> > window, >>> > those functions get called. >>> > >>> > After going through those two functions, I then get an Access >>> > violation: >>> > >>> > Unhandled exception at 0x78a75e55 (mfc90ud.dll) in CanAnalyzer.exe: >>> > 0xC0000005: Access violation reading location 0xfeef000e. >>> > >>> > and the break point is at the return statement: >>> > >>> > LRESULT CWnd::Default() >>> > { >>> > // call DefWindowProc with the last message >>> > _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData(); >>> > return DefWindowProc(pThreadState->m_lastSentMsg.message, >>> > pThreadState->m_lastSentMsg.wParam, >>> > pThreadState->m_lastSentMsg.lParam); >>> > >>> > } >>> > >>> > Here is the code of the closing functions: >>> > >>> > void CGrapher::OnPressCloseButton() >>> > { >>> > DestroyWindow(); } >>> > >>> > void CGrapher::PostNcDestroy(){ >>> > delete this; >>> > >>> > } >>> > >>> > So i guess I got a couple questions now, why am i getting that access >>> > violation and why wont those functions get called when the >>> > CDockablePane is >>> > undocked(floating)? >>> > >>> > Thanks for the help, >>> > >>> > Nick >>> > >>> > "Joseph M. Newcomer" wrote: >>> > > If you are allocating them on the heap, with new, the easiest way is >>> > > to add a >>> > > PostNcDestroy handler to your class whose body says >>> > > delete this; >>> > > replacing the TODO: line. >>> > >>> > > You cannot delete an object earlier than the PostNcDestroy handler. >>> > > joe >>> > >>> > > On Fri, 2 May 2008 10:59:01 -0700, Nick Schultz >>> > > <NickSchu...(a)discussions.microsoft.com> >>> > > wrote: >>> > >>> > > >Hi there, >>> > >>> > > >My user will need to be able to open any number of graphing >>> > > >windows(CDockablePane) in my application. When the window is >>> > > >closed, I want >>> > > >the pane to be destroyed. >>> > >>> > > >In order to do this I will have my window catch the press close >>> > > >button event >>> > > >(CPane::OnPressCloseButton) and then have it call DestroyWindow(). >>> > >>> > > >reading DestroyWindow description, it looks like it does everything >>> > > >but it >>> > > >does not destroy the CWnd object. >>> > >>> > > >So how do I destroy the CWnd object? Do i just simply need to call >>> > > >delete >>> > > >(pointer to graph window). I was thinking I could override the >>> > > >NotifyParent >>> > > >function to catch child destroyed event and then deleting it then, >>> > > >however >>> > > >the parent gets notified BEFORE any destruction takes place. >>> > >>> > > >I'm not sure if this is possible, but after calling DestroyWindow() >>> > > >within >>> > > >the OnPressCloseButton() function, could I just call "delete this" >>> > > >to free >>> > > >up any memory used by the graph window? >>> > >>> > > >Any suggestions are greatly appreciated. >>> > >>> > > >Nick >>> > > Joseph M. Newcomer [MVP] >>> > > email: newco...(a)flounder.com >>> > > Web:http://www.flounder.com >>> > > MVP Tips:http://www.flounder.com/mvp_tips.htm >>> >>> Dont call DestroyWindow; use PostMessage(WM_CLOSE) instead. See if >>> that helps. >>> >>> -- >>> Ajay >>> > Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm |