|
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
|
|
|
|
|
Thanks for your replies, Bob.
It actually doesn't crash when nCode is 0xFFFFFFFF or 0x00000000 (which is what it's set at when it does crash), so the nCode isn't at least obviously what's wrong. I tried putting the breakpoints back in but it kept interrupting my menu clicks by breaking, so I inserted this code first thing in CMainFrame::OnCmdMsg:
CString message;<br />
FILE * outfp;<br />
outfp = fopen("debuginfo.txt", "a");<br />
if (nID == ID_APP_EXIT) { <br />
message.Format("message: nID=0x%X, nCode=0x%X, this=0x%X\n", nID, nCode, this);<br />
fputs(message, outfp);<br />
}<br />
fclose(outfp);
That will append to the a debug file and only output when the message it's handling is ID_APP_EXIT. I opened the text file and found this:
message: nID=0xE141, nCode=0xFFFFFFFF, this=0x334AA8
message: nID=0xE141, nCode=0x0, this=0x334AA8
message: nID=0xE141, nCode=0xFFFFFFFF, this=0x334AA8
message: nID=0xE141, nCode=0x0, this=0x334AA8
So this stays valid the entire time. The only thing I have in OnAppExit() is "exit(0);".
About the stack, I fixed some bugs that I could fix earlier using the stack and it helped me figure out where things went wrong. I might pass by value here but expecting an address there, giving me access violation errors. This one just puzzles me.
|
|
|
|
|
Did you write your own OnAppExit, adding the "exit(0)" or was that in the base class? When you use AppWizard to build the program, you don't have to worry about overriding methods like OnAppExit, unless you really really need to. The base class implementation will do just fine. You don't need to add an explicit exit() call, since this will be taken care of automatically.
As far as looking at the this pointer, I was suggesting looking at the pointer in the Watch window. Once you've hit your breakpoint in the code, you can open the Watch window by selecting View->Debug Windows->Watch from the main menu. Add this to the list of watched variables, and it'll show up like a tree where you can expand and look at the member variables.
It's entirely possible that "this" or something within "this" has been destroyed while the pointer itself remains "valid." Within your block of code that dumps command info to the debug file, you may consider breaking there and just examining what's inside "this." If you see anything that looks "off kilter," that may suggest the problem.
You can always add some assertions within your debug block as well. Check things like ASSERT(GetSafeHwnd()) and do the same for the Frame's main View. At some point, the window handles may have been released without your knowledge.
Bob Ciora
|
|
|
|
|
I think I just took the template project I built onto it, but I think I put "exit(0)" there. I tried removing it and the menu didn't exit the app. I also run a function to terminate serial communications in the deconstructor and I tried remarking that out but that didn't help.
I have been looking at this because it is important. The problem is the crash occurs in uxtheme.dll under 8 layers of dll calls that I don't have the source for so I can't identify what individual variable is causing the crash so I can't trace it's path back. The last place on the stack that VS can retrieve sources for is in mfc70d.dll and I can see this and some items are null and some aren't and I don't know what to look for. The app is in the process of being deconstructed so even some items being null should be normal.
In an effort to fix the situation, I dumped the information I thought most relevant into a webpage if you want to look at what I'm looking at. Sorry if the middle column is too wide. It would have taken an immense amount of time to shift the columns over to get a better approximation of the tree structure of this, so I improvised. You have the minus and plus signs to help out, plus I applied different text styles to the page. this is bold and italic and is at the highest level. The bold items are directly under this. The italic items are directly under the bold item it follows. Again, I don't know what to look for and I have no recourse, except to strike the Exit menu item and force users to use the close box if this won't work.
|
|
|
|
|
Have you tried a full recompile of everything? I've sometimes found that this cures these problems. Sometimes, the incremental compilation/linking fails to produce correct code.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
yeah, I cleaned the project then rebuilt it, no change, both Release and Debug versions too.
|
|
|
|
|
i m working with MFC application and i have two listbox contaning float values. now i want to plot a graph as one listbox data considers as x axis and other as y axis so how to plot listbox data on graph and also how to make such as it limits changes accordingly as the values in listbox changes.
|
|
|
|
|
well, first you need to create a window to display the graph on. I'm assuming you know how to create a window already. Inside the window's OnPaint method, use the CDC object's MoveTo and LineTo functions.
-- Rocky Dean Pulley
|
|
|
|
|
There are some great free controls on codeproject for this, much simpler than doing your own.
NTGraph 2D
NTGraph 3D
|
|
|
|
|
This is not a question about some error that I may have. I am asking for your advice since this is the first (somewhat big) application for me.
Where would you save the options of a program ( like directories, and many other stuff),...in the registry...or using an options files.
And what is the best practice of those during, first the testing period (I have to give samples to my friends), and second after everything is done.
Thanks
|
|
|
|
|
Using options files is generally easier. Easier to code, and easier for users to modify directly if they need to. The other advantage to using files is that the application will be easier to port to another operating system. Outside of those advantages, the registry is a fine place to store stuff, but don't store too much junk there. If your options file ends up being a few hundred kilobytes, you may want to stick with a file and not clutter up the registry.
-- Rocky Dean Pulley
|
|
|
|
|
I would strongly recommend using one or more files. Your users (and testers) will bless you when they move your app between machines. The registry is evil. No, really.
/ravi
My new year's resolution: 2048 x 1536
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
Two votes for files...
Thanks for your suggestions
M Tarik
|
|
|
|
|
I usually Prefer Registry,as at some secure system you don't have write access in your C:\ (generally wher your program is installed).
so to play safe bet i prefer saving my option in Registry (at least even in some part of HKEY_CURRENT_USER ,even Guest account has Write Priviledge).
"I Think this Will Help"
[Vote One Here,.....]
<h5
alok gupta="" <br=""> visit me at http://www.thisisalok.tk
|
|
|
|
|
Could someone lead me to a source for writing to and reading from COM1 in pure binary mode as simple as possible. Looking to send and receive single bytes in range of 0x00-0xff. The final code needs to work on WinXP platform. Thanks.
|
|
|
|
|
|
these are my codes for image processing...im not sure why im getting this " INTERNAL COMPILER ERROR". pls help me...and pls do tell me whether if i continue with this codes, will i be able to perform thinning and edge detection..i have problems in developing the codes..pls do help me and i sincerely appreciate all the helps..thank you...
#include "stdafx.h"
#include "fvas.h"
#include "fvasDlg.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFvasDlg dialog
CFvasDlg::CFvasDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFvasDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CFvasDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CFvasDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFvasDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFvasDlg, CDialog)
//{{AFX_MSG_MAP(CFvasDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1_DISPLAY, OnDisplay)
ON_BN_CLICKED(IDC_STATIC_BITMAP, OnStaticBitmap)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFvasDlg message handlers
BOOL CFvasDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CFvasDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CFvasDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CFvasDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CFvasDlg::OnDisplay()
{
// TODO: Add your control notification handler code here
static char BASED_CODE szFilter[] = "Bitmap Files (*.bmp) |*.bmp||";
CString m_sBitmap;
CFileDialog m_ldFile(TRUE, ".bmp", m_sBitmap, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);
if (m_ldFile.DoModal() == IDOK)
{
m_sBitmap = m_ldFile.GetPathName();
HBITMAP hBitmap = (HBITMAP) ::LoadImage(AfxGetInstanceHandle(), m_sBitmap, IMAGE_BITMAP, 100,140, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
HBITMAP hGrayBitmap = (HBITMAP) ::LoadImage(AfxGetInstanceHandle(), m_sBitmap, IMAGE_BITMAP, 100,140, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
HBITMAP hGrayBitmap1 = (HBITMAP) ::LoadImage(AfxGetInstanceHandle(), m_sBitmap, IMAGE_BITMAP, 100,140, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
BITMAP bm;
BITMAP bm1;
GetObject(hGrayBitmap, sizeof(BITMAP), (LPSTR)&bm);
typedef struct tagBITMAP
{
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
}
BITMAP, *PBITMAP;
if (hGrayBitmap)
{
CStatic *pImgPicture = (CStatic*)GetDlgItem(IDC_STATIC_BITMAP);
BYTE * pImgByte = (BYTE *) bm.bmBits;
if(pImgPicture==NULL)
{
AfxMessageBox("Fail to get Picture Control");
}
else
{
INT iWidthBytes = bm.bmWidth * 3;
for ( int y = 0; y < bm.bmHeight; y++)
{
for ( int x = 0; x < bm.bmWidth*3; x++)
{
unsigned char R = pImgByte[y*iWidthBytes+x+2];
unsigned char G = pImgByte[y*iWidthBytes+x+1];
unsigned char B = pImgByte[y*iWidthBytes+x];;
INT gray = ceil(0.3*R + 0.59*G + 0.11*B);
pImgByte[y*iWidthBytes+x+2] = gray;
pImgByte[y*iWidthBytes+x+1] = gray;
pImgByte[y*iWidthBytes+x] = gray;
}
}
void threshold (struct Image *bm, struct Image *bm1, int THRES)
{
int X, Y, GO, GB;
GO= 225;
GB= 0;
for (Y=0; Y<=bm.bmHeight; Y++)
{
for (X=0; X<=bm.bmWidth*3; X++)
{
if (*(bm.bmBitsPixel + X + (long) Y * bm.bmWidth*3) > THRES)
*(bm1.bmBitsPixel + X + (long) Y * bm.bmWidth*3) = GO;
else
*(bm1.bmBitsPixel + X + (long) Y * bm.bmWidth*3) = GB;
}
}
}
pImgPicture->SetBitmap(hGrayBitmap);
}
}
}
}
|
|
|
|
|
It would help, and you'd get a lot more responses, if you'd trim your code down to just the pieces necessary to reproduce the problem.
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
/agree
I didn't feel like figuring it all out, but a suggestion would be to block comment out every method in the file except one. Then compile. If you get no errors, uncomment another function and recompile. Continue until you can at least figure out which particular function is causing the problem. Then try repeating the process with individual lines within the offending function.
Bob Ciora
|
|
|
|
|
This is definitely puzzling:
BITMAP bm;
BITMAP bm1;
GetObject(hGrayBitmap, sizeof(BITMAP), (LPSTR)&bm);
typedef struct tagBITMAP
{
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
}
BITMAP, *PBITMAP;
Defining variables of your type BITMAP before you've actually defined the structure?
Bob Ciora
|
|
|
|
|
bm and bm1 are instances of BITMAP that is defined in wingdi.h .
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|