|
|
I have a property sheet with a handful of property pages.
When File/New is selected, I want to clear out the data
from each property page. My code looks like:
void CView0::OnNew()
{
int page = m_pView0PropertySheet->GetActiveIndex();
if (page == 0) m_pView0PropertySheet->m_form0page1.New();
if (page == 1) m_pView0PropertySheet->m_form0page2.New();
if (page == 2) m_pView0PropertySheet->m_form0page3.New();
}
The problem with this code, is that it only clears out the
data from the active property page. Lets say I remove the
if (page == 0)
if (page == 1)
if (page == 2)
If I call this function and the 3rd property page was never
selected (never active), then I get an error because
m_pView0PropertySheet->m_form0page3 is null.
How can I safely clear the data for this example?
Please, any response any one can give me will be greatly
appreciated.
Sincerely,
Danielle Brina (an overworked graduate student)
|
|
|
|
|
You can use IsWindow() on each page to see if it has been activated. IsWindow() will return FALSE if the page has not been activated.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04
Within you lies the power for good - Use it! Honoured as one of The Most Helpful Members of 2004
|
|
|
|
|
Thank you
Elapid For The Win
|
|
|
|
|
Look in the registry at HKLM\SOFTWARE\Microsoft\.NETFramework\policy\ for things like v1.0, v1.1 etc.
|
|
|
|
|
Could someone please explain to me how to call a different program within my program?
My scheduler keeps calling a program every (let's say) 60 mins. However I do not know how to do that in my program
please help,
thank you
Elapid For The MFC
|
|
|
|
|
Take a look at CreateProcess.
Tom Wright
tawright915@yahoo.com
|
|
|
|
|
Could you pls tell me where to look for that CreateProcess?
thanks
Elapid For The Win
|
|
|
|
|
<--Dummy
Elapid For The Win
|
|
|
|
|
|
ShellExecute(NULL,"open","notepad.exe",
NULL,NULL,SW_SHOW );
suhredayan There is no spoon.
|
|
|
|
|
has anyone ever done a c++ application that edits a vrml world
for example remove pictures from a gallery or remove different objects or change there sizes
|
|
|
|
|
I don't know why I get this error but when I quit my app, I get a runtime error in the file wincore.cpp in a function named CWnd::DefWindowProc on this statement:
return ::CallWindowProc(pfnWndProc, m_hWnd, nMsg, wParam, lParam);
I look at the call stack and it's called inside several layers of uxtheme.dll, comctl32.dll, user32.dll, mfc70.dll, user32.dll again, ntdll.dll, mfc70.dll again, and on down. The last mention of my app is here, the line the error is on is in bold:
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) {<br />
if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))<br />
return TRUE;<br />
<br />
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
|
|
|
|
|
Some thoughts....
Is your m_wndView.OnCmdMsg() maybe modifying pExtra or pHandlerInfo, even though it's returning FALSE?
Which particular nID and nCode is this handler receiving? Is it the WM_QUIT message or some other termination message? If so, maybe m_wndView is somehow invalidating/destroying itself, then the default handler for OnCmdMsg() is trying to do the same (since I'm guessing that m_wndView is a subwindow of CMainFrame). This could cause this type of crash.
Can you step into CFrameWnd::OnCmdMsg and figure out exactly which sdk call crashes? That may help narrow down the whys of the problem as well.
As I said, just some thoughts about trying to figure out exactly what's going on. I hope they help.
Bob Ciora
|
|
|
|
|
Thanks for your reply.
The stack at the level of my program says:
489gui.exe!CMainFrame::OnCmdMsg(unsigned int nID=0x0000e141, int nCode=0x00000000, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 132 + 0xf C++
I kind of new to MFC programming so you'll have to bear with me while I try and understand this all.
I can double-click the top-left box of the dialog and it quits fine, if that helps. I'm not sure what WM_QUIT resolves to as a number. m_wndView is a member of the CMainFrame class.
Somehow it's stopped crashing recently though, but I have a feeling the problem will come back.
|
|
|
|
|
I just moved some stuff around, mainly inserted a new segment in the status bar. Now I get a crash before I see a window. In my InitInstance, I call "pFrame->ShowWindow(SW_SHOW);" and in there it crashes on "return m_pCtrlSite->ShowWindow(nCmdShow);" but m_pCtrlSite is a pointer to the address 0xfeeefeee which is not right. I think I know what's wrong but I have no idea how to fix this one either.
|
|
|
|
|
Creating of toolbars and status bars are generally done in the OnCreate function of the CMainFrm class. The value of your pointer indicates that the frame has not been created yet.
Steve
|
|
|
|
|
I'm curious to know of this is an AppWizard created program, or an MFC program created from scratch.
As Steve said, the toolbars and status bars are generally initialized in the Frame's OnCreate. If this was created by AppWizard, then there should already be some code there to create the initial status bar and toolbar, if you want to look at an example.
Bob Ciora
|
|
|
|
|
Thanks Steve and Bob,
This program was originally written from scratch mainly to immerse myself in Windows programming. After reaching a plateau of understanding and realizing the app code is filled with failed attempts at doing things that don't need to be done, I started a new project, using the AppWizard and simply fill in the routines from my old code.
I had a feeling the problem is because of the toolbar because that's what I changed immediately before this recent error cropped up, but I don't see how to fix it without reverting my changes. Here's the code for my status bar now:
<br />
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {<br />
... (creates view window and toolbar here) ...<br />
if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) {<br />
TRACE0("Failed to create status bar\n");<br />
return -1;
} else {<br />
int i;<br />
m_wndStatusBar.SetPaneInfo(0, ID_INDICATOR_INFOLINE, SBPS_STRETCH, 80);<br />
m_wndStatusBar.SetPaneInfo(1, ID_INDICATOR_WORKING, SBPS_NORMAL, 150);<br />
m_wndStatusBar.SetPaneInfo(2, ID_INDICATOR_COMMSETTINGS, SBPS_NORMAL, 125);<br />
m_wndStatusBar.SetPaneInfo(3, ID_INDICATOR_USIZE, SBPS_NORMAL, 125);<br />
m_wndStatusBar.SetPaneInfo(4, ID_INDICATOR_SENTLENGTH, SBPS_NORMAL, 90);<br />
m_wndStatusBar.SetPaneInfo(5, ID_INDICATOR_RECVLENGTH, SBPS_NORMAL, 120);<br />
m_wndStatusBar.SetPaneInfo(6, ID_INDICATOR_CSIZE, SBPS_NORMAL, 140);<br />
<br />
m_wndStatusBar.SetPaneText(0, "No File Loaded", true);<br />
for (i=1; i<6; i++) { m_wndStatusBar.SetPaneText(i, "", true); }<br />
... (sets toolbar style here) ...<br />
return 0;<br />
}<br />
The COMMSETTINGS toolbar segment is the one I added. CMainFrame is derived from CFrameWnd.
|
|
|
|
|
Did you remember to put the ID_INDICATOR_COMMSETTINGS in the indicators array and is it in the 3rd position (or are there at least 7 entries in the indicators array)?
Steve
|
|
|
|
|
Yes I did, here's the array declared above:
static UINT indicators[] = {<br />
ID_INDICATOR_INFOLINE,
ID_INDICATOR_WORKING,
ID_INDICATOR_COMMSETTINGS,
ID_INDICATOR_USIZE,
ID_INDICATOR_SENTLENGTH,
ID_INDICATOR_RECVLENGTH,
ID_INDICATOR_CSIZE
};
|
|
|
|
|
If you've rebuilt the application using AppWizard, you most likely don't need to call m_mainWnd::OnCmdMsg() (as you showed in your initial post). For most MFC apps, you don't have to write your own OnCmdMsg . Is there anything specific to m_mainWnd that requires you to do this?
When you quit the app with either the top right [x] or by double-clicking the top left icon, that generates a WM_CLOSE windows message. If you quit the app by selecting File->Exit, that generates an ID_APP_EXIT command, which is actually passed as the WPARAM of a WM_COMMAND windows message. WM_COMMAND messages are what are passed to OnCmdMsg, while the WM_CLOSE follows its own path.
So there are different code paths when you exit the app in those different ways. Does your m_mainWnd do something special in its OnCmdMsg when it sees the ID_APP_EXIT command? My suspicion on the whole thing is still that something is being invalidated/destroyed in m_mainWnd's OnCmdMsg , then the default CMainFrame::OnCmdMsg is trying to destroy the same thing, causing the crash.
In your OnCmdMsg handler, try adding a little "trap" at the beginning, something like this:
BOOL CMainFrame::OnCmdMsg( UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
if( nID == ID_APP_EXIT )
{
int nDummy = 0;
}
if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
You can then set a breakpoint on the "dummy" line (using F9) to trap the ID_APP_EXIT command when it's recieved. After that, you can single-step through the remainder of the function using F11 (this will step into functions) or F10 (to step over them).
I'd suggest stepping into your m_mainWnd::OnCmdMsg and see what it does when it gets this ID_APP_EXIT command.
Bob Ciora
|
|
|
|
|
I understand what you mean, I knew clicking the X or double-clicking the upper-left command box was different from the menus exit because the former still works, but I didn't know how the app handles each way.
I commented out the status bar because of the problems it's giving me which you may or may not be aware of branched off of my original thread starter.
When I add that code and I click on just File in the menu, it breaks at that point with this on the stack:
489gui.exe!CMainFrame::OnCmdMsg(unsigned int nID=0x0000e141, int nCode=0xffffffff, void * pExtra=0x0012f120, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 128 C++<br />
I tried stepping through anyway and everything seemed in order, but then again, I started to lose understand of what is happening.
I added to the if statement to catch when the ID_APP_EXIT nID is received and the nCode is 0x00000000 which is the case when the program crashes. However, both cases in which nCode is 0xFFFFFFFF and 0x00000000 happens before the menu is drawn, prematurely stopping the program before the instance in time we are waiting for when the Exit menu option is selected.
If I remove the breakpoint, I just noticed something, I don't think it's been there before, but 4 levels up from the CMainFrame::OnCmdMsg call, that the proper exit procedure is called, C489guiApp::OnAppExit(). It looks like my app is handling the menu click right but like you say, however something is getting destroyed and then is attempted to be used which crashes my app.
|
|
|
|
|
The first break would be when MFC is doing the OnUpdateUI processing for the menu item (where you can check/uncheck, enable/disable, etc. the various items in the menu), and the second break is the actual ID_APP_EXIT command. Does the program crash under both instances? The second time around is what you're really interested in.
One thing you may also consider looking at (and this may seem odd) is the "this" pointer in the Watch window, if you reenable the breakpoint. See if it's actually valid at the time of the second call. It's very possible that your MainFrame object isn't even valid (having been destroyed by your CWinApp derived class in OnAppExit . Again, this may seem odd, but it can happen.
Best of luck...isn't software fun?!!!!
Bob Ciora
|
|
|
|
|
One other thing you can do is, when you see OnAppExit in the Call Stack window, you can double-click on that entry and it'll pop up a window showing the CWinApp core code with a green hilite line showing where the next call in the call stack was made.
You can always poke around this code, and even set a breakpoint higher up so that you can single step through OnAppExit to get a feel for what it's doing prior to the call that eventually leads to the crash.
Just a few more thoughts...
Bob Ciora
|
|
|
|
|