|
John,
I really should clarify something here. The only reason I'm saying this project is multithreaded is because the project settings are set to multithreaded. I haven't been in this program long enough to know for sure. I'll be working on this program a lot more over the next few weeks, so I'll be able to provide more detailed information.
Jim
Also, just a side note, I created this static bitmap control while viewing the dialog it goes in. I also tried another method, copying an existing bitmap control on the same dialog. The dialog runs fine as long as I don't add a member variable to the bitmap control. As soon as I do this, even if I don't do anything with the member variable, the program asserts.
|
|
|
|
|
Have you changed the order of things in your OnInitDialog as the base class must be called before any UpdateData() calls?
John
|
|
|
|
|
John, here's a look at the call stack. There is an updatedata() call. It looks like it's firing before OnInitDialog. If this is the problem then why wouldn't it affect other controls?
CWnd::SubclassWindow(HWND__ * 0x00c605c2) line 3866
DDX_Control(CDataExchange * 0x0012e654, int 1131, CWnd & {CWnd hWnd=0x00c605c2}) line 628 + 12 bytes
RunningDlg::DoDataExchange(CDataExchange * 0x0012e654) line 42
CWnd::UpdateData(int 0) line 3109
CDialog::OnInitDialog() line 677 + 10 bytes
RunningDlg::OnInitDialog() line 284
AfxDlgProc(HWND__ * 0x003705e8, unsigned int 272, unsigned int 12846602, unsigned int 12846602) line 35 + 14 bytes
USER32! 77d67b5b()
USER32! 77d6cf23()
USER32! 77d571b9()
USER32! 77d5b7e5()
USER32! 77d6ce12()
USER32! 77d45cc9()
USER32! 77d45ce8()
CWnd::DefWindowProcA(unsigned int 272, unsigned int 12846602, long 0) line 1000 + 32 bytes
CWnd::Default() line 249
CDialog::HandleInitDialog(unsigned int 12846602, unsigned int 12846602) line 621 + 8 bytes
CWnd::OnWndMsg(unsigned int 272, unsigned int 12846602, long 0, long * 0x0012ea60) line 1815 + 17 bytes
CWnd::WindowProc(unsigned int 272, unsigned int 12846602, long 0) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x0012f7c4 {RunningDlg hWnd=0x003705e8}, HWND__ * 0x003705e8, unsigned int 272, unsigned int 12846602, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x003705e8, unsigned int 272, unsigned int 12846602, long 0) line 368
USER32! 77d67b5b()
USER32! 77d6ce12()
USER32! 77d45696()
USER32! 77d58273()
5000000e()
|
|
|
|
|
Ok guys, thanks for all the suggestions. Interestingly, the error is occuring after several levels of code on the DDX for another variable completely. The DDX statements are:
void RunningDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(RunningDlg)
DDX_Control(pDX, IDC_QT_STATUS_OFF, m_testit); *** my addition **
DDX_Control(pDX, IDC_MUTE, m_Mute);
DDX_Control(pDX, IDC_VIEW_LOG, m_ViewLogButton);
DDX_Control(pDX, IDC_LOG_STATUS, m_LogStatusIndicator);
DDX_Control(pDX, IDC_STATUS, m_Status);
DDX_Control(pDX, IDC_LAST_SYNC, m_LastSync);
DDX_Control(pDX, IDC_SCHED_EVENTS, m_EventList); ** problem **
//}}AFX_DATA_MAP
}
The line in wincore.cpp where the failure is occuring is ASSERT(FALSE);
Is this a debug setting designed to prevent additions? Maybe I need to take this project off debug mode to further develop it?
Here's the whole function in wincore.cpp:
/////////////////////////////////////////////////////////////////////////////
// Extra CWnd support for dynamic subclassing of controls
BOOL CWnd::SubclassWindow(HWND hWnd)
{
if (!Attach(hWnd))
return FALSE;
// allow any other subclassing to occur
PreSubclassWindow();
// now hook into the AFX WndProc
WNDPROC* lplpfn = GetSuperWndProcAddr();
WNDPROC oldWndProc = (WNDPROC)::SetWindowLong(hWnd, GWL_WNDPROC,
(DWORD)AfxGetAfxWndProc());
ASSERT(oldWndProc != (WNDPROC)AfxGetAfxWndProc());
if (*lplpfn == NULL)
*lplpfn = oldWndProc; // the first control of that type created
#ifdef _DEBUG
else if (*lplpfn != oldWndProc)
{
TRACE0("Error: Trying to use SubclassWindow with incorrect CWnd\n");
TRACE0("\tderived class.\n");
TRACE3("\thWnd = $%04X (nIDC=$%04X) is not a %hs.\n", (UINT)hWnd,
_AfxGetDlgCtrlID(hWnd), GetRuntimeClass()->m_lpszClassName);
ASSERT(FALSE); ******* this is where it's failing ******
// undo the subclassing if continuing after assert
::SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)oldWndProc);
}
#endif
return TRUE;
}
Any ideas?? Thanks a lot guys. Jim
|
|
|
|
|
SublimeRide wrote: DDX_Control(pDX, IDC_SCHED_EVENTS, m_EventList); ** problem **
In the .rc file, what type of control is IDC_SCHED_EVENTS assigned to? What type of variable is m_EventList ?
SublimeRide wrote: Is this a debug setting designed to prevent additions?
No, it's letting you know that something unexpected was encountered (the code asserted that something should be true but ended up being false).
SublimeRide wrote: Maybe I need to take this project off debug mode to further develop it?
Don't do this until all errors have been removed. The assertions will only fire in debug mode. They compile to nothing in release mode, but that does not mean the cause of the problem has also gone away.
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
Thanks again.
Some answers:
IDC_SCHED_EVENTS is a list control. It basically has a text list of upcoming events in order.
The member variable m_Eventlist is a control for the list. It is used to add/delete/reorder the lists items.
This functions fine with no assert failures as long as I don't add any member variables to anything on the page.
The variable I added m_test is also a control variable for a static bitmap. I'm only intending to use it to show/hide the bitmap based on a condition (that is not associated with the list control in any way).
I guess what I'm struggling with is the line ASSERT(FALSE); This is a guaranteed failure.
The code above it is:
if (*lplpfn == NULL)
*lplpfn = oldWndProc; // the first control of that type created
#ifdef _DEBUG
else if (*lplpfn != oldWndProc)
{
This code seems to me to be indicating that if I'm in debug mode, and more than one (or a subclassed) control of a particular type is created then this will fail. There is more than one list control (they're on separate dialogs) but why would this fail by adding a member variable to a bitmap control? Just thinking out loud.
Jim
|
|
|
|
|
SublimeRide wrote: IDC_SCHED_EVENTS is a list control.
Looking in the project's resource.h file, does it have a value the same as any other control on that dialog?
If you comment out the DDX_Control(pDX, IDC_SCHED_EVENTS, m_EventList) statement, does the assertion fire?
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
I'll have to check on this tomorrow. I'm working from home today and the project will not run on my setup. Both setups are VC++ 6.0, but for some reason my home setup gives an error in appui.cpp before it gets to the debug assertion failure.
Anyway, I'm able to view the files from here and I can say that the list control doesn't have the same value as any other controls. There are a few other pairs of controls that do have the same value, but they each seem to be on different dialogs.
I'll check out commenting out the DDX line for the list control tomorrow or later tonight if I have time to get the project running on my setup at home.
Thanks, Jim
|
|
|
|
|
Just a follow-up. If I comment out the DDX line for the list control, the assertion still fires. And as I noted in the previous response, there are no other controls at all with the same value in the resource.h file.
I'll be back on this project Friday. If you have any ideas please let me know.
Just a note, this program does compile and run in release mode. I know I have to get this fixed in debug mode as well, just some additional info there.
Thanks, Jim
|
|
|
|
|
SublimeRide wrote: If I comment out the DDX line for the list control, the assertion still fires.
Then comment out all of the lines in the DoDataExchange() method and add them back in one at a time until the assertion fires. You can also set a breakpoint on the ASSERT() statement. When that breakpoint is hit, simply look at the call stack to see how the code got to that point.
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
Ok I have some information that may shed some light. There were originally 6 controls on this dialog with member variables (and DDX statements). The reason I thought the list control was the culprit (and it was asserting at the time) was because when I added a member variable, it became the 7th DDX statement and the one failing.
I've since found that if I add 4 member variables (making a total of 10 DDX statements), the program always asserts on the 7th DDX statement, no matter which one is there.
It seems like as soon as any member variables are added beyond the 6 original ones the program had already contained, then the program asserts. I can even put all my new variables at the top of DDX list and they pass fine. The 7th one always asserts no matter what it is. It almost seems as if there is a max amount of controls allowed on the page.
Does this help at all?
Jim
|
|
|
|
|
Also, you asked about the call stack. Here it is at the line that asserts. Note, that whatever DDX statement is the 7th one this will assert. Just an FYI from the previous post. There were originally 6 controls with member variables on the dialog. As soon as I add one or more, the 7th DDX statement always asserts.
Call stack:
CWnd::SubclassWindow(HWND__ * 0x00c605c2) line 3866
DDX_Control(CDataExchange * 0x0012e654, int 1131, CWnd & {CWnd hWnd=0x00c605c2}) line 628 + 12 bytes
RunningDlg::DoDataExchange(CDataExchange * 0x0012e654) line 42
CWnd::UpdateData(int 0) line 3109
CDialog::OnInitDialog() line 677 + 10 bytes
RunningDlg::OnInitDialog() line 284
AfxDlgProc(HWND__ * 0x003705e8, unsigned int 272, unsigned int 12846602, unsigned int 12846602) line 35 + 14 bytes
USER32! 77d67b5b()
USER32! 77d6cf23()
USER32! 77d571b9()
USER32! 77d5b7e5()
USER32! 77d6ce12()
USER32! 77d45cc9()
USER32! 77d45ce8()
CWnd::DefWindowProcA(unsigned int 272, unsigned int 12846602, long 0) line 1000 + 32 bytes
CWnd::Default() line 249
CDialog::HandleInitDialog(unsigned int 12846602, unsigned int 12846602) line 621 + 8 bytes
CWnd::OnWndMsg(unsigned int 272, unsigned int 12846602, long 0, long * 0x0012ea60) line 1815 + 17 bytes
CWnd::WindowProc(unsigned int 272, unsigned int 12846602, long 0) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x0012f7c4 {RunningDlg hWnd=0x003705e8}, HWND__ * 0x003705e8, unsigned int 272, unsigned int 12846602, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x003705e8, unsigned int 272, unsigned int 12846602, long 0) line 368
USER32! 77d67b5b()
USER32! 77d6ce12()
USER32! 77d45696()
USER32! 77d58273()
5000000e()
|
|
|
|
|
In the OnInitDialog() method, remove the call to UpdateData() . It is hardly, if ever, needed.
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
David/John,
I just wanted to bring closure to this thread. The problem is fixed, although I'm not exactly sure how. In the end I deleted the member variable and four controls I had created (two static bitmaps and two static labels). I then added them back to the dialog. This time I added a member variable first to one of the label controls. It compiled and ran without any errors at all. I then began adding member variables to the rest of the controls, again with no errors.
One thing I did differently. Instead of creating the bitmap and associating it with the bitmap led resource, I left it blank. I then created a class variable of HBITMAP type and set it to the led resource. Then used the control's member variable to 'set bitmap' to the HBITMAP.
I'm not sure if those changes were the answer or just deleting and re-adding the controls. Anyway, this vague problem is fixed and it runs in debug mode without assertion failures.
Thanks again for all the help. Jim
|
|
|
|
|
Hi,
I have a MFC/COM exe application which loads the DLL, which is a separate component DLL and not included in main MFC/COM exe project workspace. I want to debug the function calls made by exe on DLL(I have the DLL code).
I built both exe and DLL in Debug mode, registered the DLL and tried to debug. But when the DLL interface call comes the exe not stepping into that DLL call, instead stepping over that DLL call and continuing rest of the execution in the exe.
If someone help me how to debug this DLL call from exe, I will appreciate that.
|
|
|
|
|
I would think the problem is that the debugger can not find the source files for the dll. You could try add the path to the dll files to the directories searched by VS. In VS6 it is Tools->Options->Directories. I am sorry I am not sure where it is in VS7.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" - mYkel - 21 Jun '04
"There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05
Within you lies the power for good - Use it!
|
|
|
|
|
Thanks a lot. It helped me to findout the problem.
|
|
|
|
|
Babto wrote: not included in main MFC/COM exe project workspace
can you put it into that workspace?
if not, open the DLL's workspace, go to Project / Settings / Debug and give the path to your MFC app in the "Executable for debug session" field. then 'run' your DLL. it will launch your app, and you can set breakpoints in your DLL code (but not in your app's code).
putting the DLL in your app's workspace (even if just temporarily) is really the best way to do it, though.
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
I have a application in which i need a timer event
to fire at some regular interval say 1 to 10 seconds.
But durint this interval other Buttons on the Dialogbox
are not responing .
So i want a method were i can call this timer function by
which it runs on non UI thread.
any idea
thank you
|
|
|
|
|
You can use CreateWaitableTimer. It will create a timer that uses events.
|
|
|
|
|
I Guess using CreateWaitableTimer with SetTimer and WaitForSingleObject may block ur thread !
Cause is my effort;
Effect is God's effort
|
|
|
|
|
You can't use WaitForSingleObject you have to use MsgWaitForMultipleObjects then Dispatch the message to the other controls while you wait on the timer.
|
|
|
|
|
If you feel teh timer function takes alot of time .then You can do this .
Wherever_Timer_creation_required
{
setTimer(X,Y,MULL)
pthread=AfxCreateThread();
}
OnTimer()
{
pthread->PostThreadMessage(Message)
}
Now you can handle that message in pthread .
Cause is my effort;
Effect is God's effort
|
|
|
|
|
Use SetTimer() and OnTimer()
Danny
The stupidity of others amazes me!
|
|
|
|
|
SetTimer will work just fine. Pass NULL as the HWND and specify a TimerProc callback function.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" - mYkel - 21 Jun '04
"There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05
Within you lies the power for good - Use it!
|
|
|
|
|