Solved

Error when launching a dialog in debug mode

Posted on 2009-05-20
21
498 Views
Last Modified: 2013-12-21
I have built an Windows Mobile MFC dialog based program in debug mode and started to run it in the emulator.  
The first dialog screen shows up fine but when I press a button to launch the next 'main menu' screen I get an error at line 1. below:  (Please see the attached file for the error).  

void CBegin::OnOkButton()
{
       1. CMainMenu dlgMainMenu;
       2. dlgMainMenu.DoModal();
}

What could be causing this to happen?
Error.jpg
0
Comment
Question by:Wanting2LearnMan
  • 10
  • 9
  • 2
21 Comments
 

Author Comment

by:Wanting2LearnMan
ID: 24430319
Now when I try to dun this in debug on my actual device I get the following problem at the above line of code:

Debug Assertian Failed
Program: \ProgramFIles\MyProgram\MyProgram.exe
File: f:\sp\vctools\vc7libsce\ship\altmfc\include\afxwin2.inl Line 63

(Press Retry to debug the application )


Why is this happening????????? arrrrrrrrrrrrrrrghhhhhhhhh!
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 24430343
Hi Wanting2LearnMan,

a stack overflow most probably results from calling a function recursive which never terminates (or i.e. two functions which call each other or a message handler function which itself causes the handled message to be sent, i.e. calling RedrawWindow from a WM_PAINT message handler).

The problem here is that the call stack cannot e displayed any more so you can only locate the problem by debugging - first set a breakpoint in CMainMenu::OnInitDialog and step through its code and see if the stack overflow happens there.

Since it seems the stack overflow results from a message handler function maybe a possibility to find the message which causes the problem by using the 'Spy++' tool - start the application, then find the window with Spy++, select 'Spy->Log messages', then press the launch button. This way maybe you will see which messages are sent until the stack overflow happens.


The assertion in 'afxwin2.inl' simply indicates that CWnd::GetFont() is called for a CWnd-object which isn't attached to a existing window. Do you see in the call stack from where the 'GetFont' was called?

Hope that helps,

ZOPPO
0
 
LVL 24

Expert Comment

by:alexey_gusev
ID: 24430403
do you use TRACE() macros? if yes, it had some limit for the buffer length
0
 

Author Comment

by:Wanting2LearnMan
ID: 24430614
Thanks for the replies:

>>do you use TRACE() macros
No

>>first set a breakpoint in CMainMenu::OnInitDialog
I have set a breakpoint here but it never reaches here.  I get the error when it comes to:
CMainMenu dlgMainMenu;
and not
dlgMainMenu.DoModal();

I have nothing in the constructor or CMainMenu either.

I notice that when I step into the code it gets to the constructor then the message appears:
CMainMenu::CMainMenu(CWnd* pParent /*=NULL*/)
      : CDialog(CMainMenu::IDD, pParent)
{    <---- THE ERROR MESSAGE APPEARS JUST HERE
      m_bActivate = true;


0
 
LVL 30

Expert Comment

by:Zoppo
ID: 24430767
hm - IMO this either means the CDialog-constructor fails or the constructor of a member of CMainMenu fails - I guess the second one is the reason.

What members are declared in CMainMenu? Do you use any classes there which themselve do something in ther constructors?

ZOPPO
0
 

Author Comment

by:Wanting2LearnMan
ID: 24430768
>>The assertion in 'afxwin2.inl' simply indicates that CWnd::GetFont() is called for a CWnd-object which isn't attached to a existing window. Do you see in the call stack from where the 'GetFont' was called?

Yes I have noticed that the CMainMenu class has a variable of:
CMyBmpButton m_BitmapButton;

now CMyBmpButton is a class derived from CBitmapButton and in its constructor it calls a function which does:
                     LOGFONT lf;
      memset(&lf, 0, sizeof(LOGFONT));

      lf.lfHeight = nHeight;
      lf.lfWeight = nWeight;
      lf.lfCharSet = ANSI_CHARSET;
      lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
      lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
      lf.lfPitchAndFamily = VARIABLE_PITCH|FF_ROMAN;
      lstrcpy(lf.lfFaceName, szFont);

      m_fontInfo.CreateFontIndirect(&lf);
      SetFont(&m_fontInfo);                         <----PROBLEM IS HERE

It is at this SetFont(&m_fontInfo); line where it bombs out.

Why is this a problem in debug and not release, how can I fix this???
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 24430803
Ah, then it's clear. You can't call most functions on CWnd-derived classes before they are attached to existing windows. The windows themself are created inside the DoModal() function. I guess you added that member using ClassWizard or similar, so that member won't be attached before the first call to CMainMenu::UpdateData() - this is normally called the first time from 'CDialog::OnInitDialog'.

So, best is you add a initialization function, i.e. 'Init' to CMyBmpButtom and call this for the 'm_BitmapButton' in CMainSetup::OnInitDialog after CDialog::OInInitDialog is called.

ZOPPO
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 24430820
The difference between Release and Debug is that the Debug build tries to show an ASSERTion dialog - for any reason this leads to the stack-overflow. In Release build this ASSERTion isn't shown, the 'SetFont' simply fails since the WM_SETFONT (which is called by CWnd::SetFont) is simply sent to a NULL-window.
0
 

Author Comment

by:Wanting2LearnMan
ID: 24431075
Excellent.  Thanks.

One more problem before I can hopefully close this.

When I go to launch another dialog it bombs out again in the OnINit where I try to do:
m_bmpOpt1.AutoLoad(IDC_MENU1_BUTTON, this);
      m_bmpOpt2.AutoLoad(IDC_MENU2_BUTTON, this);
      m_bmpOpt3.AutoLoad(IDC_MENU3_BUTTON, this);
      m_bmpOpt4.AutoLoad(IDC_MENU4_BUTTON, this);

      m_bmpOpt1.LoadBitmaps(IDB_XPBUTTONGREEN_BITMAP, IDB_XPBUTTONGREEN_BITMAP, 0, IDB_XPBTNMENUDIS_BITMAP);
      m_bmpOpt2.LoadBitmaps(IDB_XPBTNMENUUPGREENMED_BITMAP, IDB_XPBTNMENUUPGREENMED_BITMAP, 0, IDB_XPBTNMENUGREENMEDDIS_BITMAP);
      m_bmpOpt3.LoadBitmaps(IDB_XPBTNMENUUPGREENMED_BITMAP, IDB_XPBTNMENUUPGREENMED_BITMAP, 0, IDB_XPBTNMENUGREENMEDDIS_BITMAP);
      m_bmpOpt4.LoadBitmaps(IDB_XPBUTTONGREEN_BITMAP, IDB_XPBUTTONDOWN_BITMAP, 0, IDB_XPBTNMENUGREENMEDDIS_BITMAP);


m_bmpOpt1.AutoLoad(IDC_MENU1_BUTTON, this);<<--It BOMBS OUT HERE

this m_bmpOpt1 is also of type CMyBmpButton.

When I step into m_bmpOpt1.AutoLoad(IDC_MENU1_BUTTON, this);
I find that it it eventually crashes here:

// LoadBitmaps will load in one, two, three or all four bitmaps
// returns TRUE if all specified images are loaded
BOOL CBitmapButton::LoadBitmaps(LPCTSTR lpszBitmapResource,
      LPCTSTR lpszBitmapResourceSel, LPCTSTR lpszBitmapResourceFocus,
      LPCTSTR lpszBitmapResourceDisabled)
{
      // delete old bitmaps (if present)
      m_bitmap.DeleteObject();
      m_bitmapSel.DeleteObject();
      m_bitmapFocus.DeleteObject();
      m_bitmapDisabled.DeleteObject();

      if (!m_bitmap.LoadBitmap(lpszBitmapResource))<-- CRASHES HERE
      {
#ifndef _WIN32_WCE
            TRACE(traceAppMsg, 0, "Failed to load bitmap for normal image.\n");
#else      //!_WIN32_WCE
            TRACE0( "Failed to load bitmap for normal image.\n");
#endif       //_WIN32_WCE
            return FALSE;   // need this one image
      }
      BOOL bAllLoaded = TRUE;



I have did the exact same in the previous dialog to load bitmaps like this.

Any Ideas???
0
 

Author Comment

by:Wanting2LearnMan
ID: 24431140
When I right-click on IDC_MENU1_BUTTON and select go to definition I see that there are multiple entries in the Resource.h file  like so:

#define IDC_BUTTON5                     1017
#define IDC_D_BUTTON                    1017
#define IDC_MENU1_BUTTON                1017
#define IDC_U14_BUTTON                  1017
#define IDC_SQUAD3_BUTTON               1017
#define IDC_BUTTON1a                    1017
#define IDC_BUTTON6                     1018
#define IDC_E_BUTTON                    1018
#define IDC_MENU2_BUTTON                1018

should all these not be unique??
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 30

Expert Comment

by:Zoppo
ID: 24431355
Hi again,

I guess the problem with 'AutoLoad' is a naming issue - to get 'AutoLoad' working properly you need to have four bitmaps with resource identifer strings (not just numeric IDs) which exactly have to be the text of the button plus the endings 'U', 'D', 'F' and 'X', so if your button's test is i.e. 'StartButton' the bitmaps need to be names 'StartButtonU', 'StartButtonD', 'StartButtonF' and 'StartButtonX' - if this is not correct the 'LoadBitmaps' throws an ASSERTion.

To the other question: the IDs only need to be unique when used within one and the same dialog - in general the resource editer avoid that it can happen that two or more objects have the same numerical ID (except IDC_STATIC, this can occur multiple times).

ZOPPO
0
 

Author Comment

by:Wanting2LearnMan
ID: 24431655
>>if this is not correct the 'LoadBitmaps' throws an ASSERTion.

But when I run my program in release mode all is ok, is this expected??
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 24431724
Well, the question is why you need this AutoLoad at all since later on you use LoadBitmaps to load the bitmaps which are finally used. If you wouldn't do this you simply would see no bitmaps. I think you can simply skip these AutoLoad calls ...

ZOPPO
0
 

Author Comment

by:Wanting2LearnMan
ID: 24431916
I have 4 buttons on my menu with IDs of: IDC_MENU1_BUTTON, IDC_MENU2_BUTTON, IDC_MENU3_BUTTON & DC_MENU4_BUTTON

I want to do the following:
m_bmpOpt1.SetDrawText(true);
m_bmpOpt1.SetFontInfo(24, FW_NORMAL);
m_bmpOpt1.SetTextColor(COLOR_Black);

If I dont do AutoLoad how do I associate the bitmap with the button then??

Thanks

If I dont
0
 
LVL 30

Accepted Solution

by:
Zoppo earned 500 total points
ID: 24432017
Well, as you already do it with
> m_bmpOpt1.LoadBitmaps(IDB_XPBUTTONGREEN_BITMAP, IDB_XPBUTTONGREEN_BITMAP, 0, IDB_XPBTNMENUDIS_BITMAP);

'AutoLoad' doesn't much more than calling 'LoadBitmaps', it just uses the button's caption to build resource identifier strings. So IMO you don't need the 'AutoLoad' at all.

The only thing 'AutoLoad' does beside this is subclassing the button-controls to the CWnd derived instance.

I'm not sure how you added the four button members - if you did add them manually (so not with ClassWizard) the controls aren't subclassed, so you will have to explicit do this - you can do it like this:

...
> m_bmpOpt1..SubclassDlgItem( IDC_MENU1_BUTTON, this );
> m_bmpOpt1.LoadBitmaps(IDB_XPBUTTONGREEN_BITMAP, IDB_XPBUTTONGREEN_BITMAP, 0, IDB_XPBTNMENUDIS_BITMAP);
...

ZOPPO
0
 

Author Comment

by:Wanting2LearnMan
ID: 24432165
SubclassDlgItem did the trick for me.

All this code has been upgraded from eVC++4.o to VS2005 and has never been put through a debugger til now.

Thanks for all your help.
0
 

Author Closing Comment

by:Wanting2LearnMan
ID: 31583441
Excellent answers,
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 24432215
You're welcome - I glad I could help.

BTW: I think it's alway a good idea to test both Debug and Release builds. ASSERTions in Debug builds often show an indication about real problems, sometimes problems which lead to bugs in Release build which cannot be reproduced. And Release builds sometimes show bugs which don't occur in Debug builds since i.e. not initialized variables implicit are initialized in Debug builds but not in Release builds.

Have a nice day,

best regards,

ZOPPO
0
 

Author Comment

by:Wanting2LearnMan
ID: 24432345
Yeah I'm trying to trackdown a resource leak in my app and its a real pain....

Thanks
0
 
LVL 24

Expert Comment

by:alexey_gusev
ID: 24432397
as an afterthought for the memory leak - maybe try to install SOTI and observe in real time what happens with the memory usage when you execute your app on the device
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 24432681
Well, I don't know if this is helpful for you since I don't know if it helps for mobile development, but here you can find an interesting article about GDI leaks including a tool and source code which can help to find them: http://msdn.microsoft.com/en-us/magazine/cc188782.aspx
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Window placement 17 64
Dynamically allocate memory 9 47
Unresolved External Symbols 3 53
C++ mouse_event mouse look 7 21
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now