|
K. Did that.
I walked the entire stack for this problem by setting a breakpoint inside my CRecSetupDlg::OnOK() function.
Here's the entire stack before the assertion, I'm going to walk it again looking for the ASSERT() macro:
<br />
CRecSetupDlg::OnOK(CString {"?Æ?"}) line 193<br />
<br />
_AfxDispatchCmdMsg(CCmdTarget * 0x2a07eec0 {CCmdTarget}, unsigned int 1, int 0, void (void)* 0x00bc1354 [thunk]:`vcall'{196,{flat}}' , void * 0x00000000, unsigned int 12, AFX_CMDHANDLERINFO * 0x00000000) line 88<br />
<br />
CCmdTarget::OnCmdMsg(unsigned int 1, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000, unsigned int 273) line 302 + 52 bytes<br />
<br />
CDialog::OnCmdMsg(unsigned int 1, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000, CWnd * 0x00c566ac CThreadLocal<class _AFX_THREAD_STATE>::CreateObject(void)) line 101 + 28 bytes<br />
<br />
CWnd::OnCommand(unsigned int 1, long 1231936, HWND__ * 0x0012cc40) line 2273<br />
<br />
CWnd::OnWndMsg(unsigned int 273, unsigned int 1, long 1231936, long * 0x2a07e970, long 0) line 1774 + 32 bytes<br />
<br />
CWnd::WindowProc(unsigned int 273, unsigned int 1, long 1231936, long 0) line 1762 + 44 bytes<br />
<br />
AfxCallWndProc(CWnd * 0x2a07eec0 {CWnd hWnd=0x0012ca20}, HWND__ * 0x0012ca20, unsigned int 273, unsigned int 1, long 1231936) line 233 + 36 bytes<br />
<br />
AfxWndProc(HWND__ * 0x0012ca20, unsigned int 273, unsigned int 1, long 1231936) line 398 + 28 bytes<br />
<br />
AfxWndProcBase(HWND__ * 0x0012ca20, unsigned int 273, unsigned int 1, long 1231936) line 236 + 20 bytes<br />
<br />
800453b0()<br />
Earlier, I walked it all the way back to AfxWndProcBase(...) and that's where the assertion failure happened - well, was reported anyway. Then, after entering that function, the IDE crashed and my link was broken.
{{sidebar: What's the last function: '800453b0()'? Is that the address of calling function/class? }}
|
|
|
|
|
But you need to examine the call stack after the assertion fires, not before.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
elementary dear Watson
|
|
|
|
|
Let's review. Remember how I said, "I inherited this code?" Well,... here goes! LOL
The resource file is used to reference unique IDs for form data, right? Therefore, there should be exactly _zero_ ID reference #'s that repeat, correct?
Here's my resource.h file - note that repeating numbers are the only ones displayed here; sequential numbered items are removed for brevity's sake.
<br />
#define IDR_RECORDING_TOOLBAR 130<br />
#define IDD_DATALIST 130<br />
#define IDD_MULT_MODBIN_LIST 160<br />
#define IDD_MOD_SELECT_DLG 160<br />
#define IDD_DIALOG3 165<br />
#define IDD_DATA_ITERATOR_DLG 165<br />
#define IDC_MIL 1001<br />
#define IDC_LIST_AVAILABLE 1001<br />
#define IDC_COMBO1 1016<br />
#define IDC_SPECIFIC_CODE_COMBO 1016<br />
#define IDC_TRIGGER_COMBO 1016<br />
#define IDC_COMBO_CATEGORY 1016<br />
#define IDC_CMBO_APPLICATION 1016<br />
#define IDC_COMBO3 1017<br />
#define IDC_COMBO_DOWN 1017<br />
#define IDC_MIN_COMBO 1017<br />
#define IDC_COMBO2 1018<br />
#define IDC_COMBO_APPLICATION 1018<br />
#define IDC_CMBO_CATEGORY 1018<br />
#define IDC_BUTTON1 1022<br />
#define IDC_GET_DTC 1022<br />
#define IDC_BTN_ADD 1022<br />
#define IDC_BTN_ITEMCHECK 1022<br />
#define IDC_BUTTON2 1023<br />
#define IDC_BTN_REMOVE 1023<br />
#define IDC_BUTTON3 1024<br />
#define IDC_BTN_REMOVEALL 1024<br />
#define IDC_CUSTOMDL 1029<br />
#define IDC_BUTTON4 1029<br />
#define IDC_CDL_ALL 1030<br />
#define IDC_BUTTON5 1030<br />
#define IDC_CDL_ADDED 1032<br />
#define IDC_BUTTON7 1032<br />
#define IDC_ADD 1034<br />
#define IDC_BUTTON9 1034<br />
#define IDC_REMOVE 1035<br />
#define IDC_BUTTON10 1035<br />
#define IDC_MONITOR_LIST 1047<br />
#define IDC_SAVE_CDL2 1047<br />
#define IDC_OK_CDL 1047<br />
#define IDC_TIMER 1048<br />
#define IDC_ADD_ALL 1048<br />
#define IDC_REMOVE_ALL2 1049<br />
#define IDC_RESTORE_DEFAULT 1049<br />
#define IDC_TREE1 1100<br />
#define IDC_TREE_DIR 1100<br />
#define ID_BUTTON32782 32782<br />
#define ID_PAUSE 32782<br />
<br />
#ifdef APSTUDIO_INVOKED<br />
#ifndef APSTUDIO_READONLY_SYMBOLS<br />
#define _APS_NEXT_RESOURCE_VALUE 175<br />
#define _APS_NEXT_COMMAND_VALUE 32797<br />
#define _APS_NEXT_CONTROL_VALUE 1102<br />
#define _APS_NEXT_SYMED_VALUE 101<br />
#endif<br />
#endif<br />
<br />
Could this cause me assertion problems? If so, how? I think I know; I just want to hear someone else say it.
{Sidebar: Note that 'IDC_TREE1' & 'IDC_TREE_DIR' were deleted over two weeks ago.}
|
|
|
|
|
I don't know about causing assertions, but one thing that could easily happen is for the code to reference IDC_BTN_REMOVE and the dialog template to contain IDC_BUTTON3 . Since both IDs exist, the compiler is happy. This would likely result in an assertion in the window's DoDataExchange() method, not at closing.
In any case, it might be worth the effort to clean up your project's resource.h file by removing unused IDs and maing the remaing ones sequential.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Yeah, when I saw that file a very loud klaxon rang in my head and a trekkie yelled, "Red Alert!"
That's what my work-mate and I concluded, also - cleaning it up. I was going to look around on Microsoft's site to see if any tools exist to do a more exhaustive 'cleansing' of resource files followed up by reviewing sourceforge, too. If none exist, I may make one of my own.
Also, another screwed up issue with this project is that every time I edit/create a form and save, I have to enter into the .RC file with a plain text editor and change the project name from something I think the project *used* to be named to what it is named today. After that, I have to switch back to eVC and let it detect the changes. It's very screwed up. If I knew what was causing that one section to be renamed, I'd fix it. Too late and I'm too tired to access the code tonight. *That's* another topic!
Hey, thanks for all your help today!!
Carl
|
|
|
|
|
Like2Byte wrote: ...any tools exist to do a more exhaustive 'cleansing' of resource files...
Yes, such tools exist.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
You're not calling the base class OnOk() from your override are you?
Mark
|
|
|
|
|
Do you mean calling OnOK() from within OnOK()? If so, no.
The view class uses the default (vanilla) OnOK() function.
The CRecSetupDlg class overrides the OnOK() function and calls EndDialog(IDOK) as the last statement in the OnOK() function.
|
|
|
|
|
What view class? I didn't see that mentioned before
The warning assertion you posted is because of closing a CWnd improperly - It should be done in
two steps, one for the windows object (HWND) and one for the C++ object (CWnd).
If you break in the debugger at the assertion and quickwatch the "this" pointer, what type
is the window. It sounds like it's coming from a different window than the modal dialog.
BTW, I've never coded for CE so hopefully I'm not way off here
Mark
|
|
|
|
|
Thanks for that!
This class is a SDI application. Why it wasn't designed as a dialog class, I don't know. I inherited this applicaton.
I'll see what I can dig up about the CWnd closing improperly and the this pointer. Gimme a few.
|
|
|
|
|
I have written a class as follows,
class String<br />
{<br />
char *m_string;<br />
unsigned int m_length;<br />
<br />
public :<br />
String(void);<br />
String(char *str);<br />
String(String str);<br />
virtual ~String();<br />
<br />
int GetLength(void);<br />
<br />
void operator=(char *str);<br />
<br />
String operator+(String str);<br />
String operator+(char ch);<br />
String operator+(char *str);<br />
<br />
bool operator==(String str);<br />
bool operator==(char* str);<br />
<br />
bool operator!=(String str);<br />
bool operator!=(char* str);<br />
<br />
String Trim(void);<br />
<br />
void InsertAt(int pos, char ch);<br />
};
for
String obj1("AS"), obj2("qwe");<br />
if( obj1 == obj2 )
if( obj1 == "as" )
But which function should be written to perform operation if( "as" == obj1 )
I was thinking about a '=='operator overloaded frien function. But it generate an error.
Can anyone suggest a better way for this?
When I add constructor as String(String str); It gives compile error as illegal copy constructor. Why? what is solution?
|
|
|
|
|
Aniket Salunkhe wrote: When I add constructor as String(String str); It gives compile error as illegal copy constructor.
Try String(String&& str);
For your overloaded operators, within the function you need to get a handle to your stored string and pass them both into the standard string compare functions i.e.
bool operator==(char* str)<br />
{<br />
return strcmp( str, m_string ) == 0;<br />
}
|
|
|
|
|
WalderMort wrote: String(String&& str);
twice ?
weren't you thinking to const String& instead ?
|
|
|
|
|
Well, if an address needs and address it wouldn't be const now would it , sure as hell confuse the post office though.
I have no excuse this time
|
|
|
|
|
Aniket Salunkhe wrote: But which function should be written to perform operation if( "as" == obj1 )
None.
"as" is a pointer and if you compare the pointer value with an object you will at least get an error similar to "cannot convert obj1 to char*".
You could compose your if-statement as
if( String( "as" ) == obj1 )
Regarding the copy constructor the syntax is this:
String( const String& str ) which should be similar to the syntax of the assignment operator, the difference is that the assignment operator should return a reference to the object to allow statements like
obj1 = obj2 = "MyString";
The assignment operator declaration should look like this:
String& operator=( const char* str );
String& operator=( const String& str );
"It's supposed to be hard, otherwise anybody could do it!" - selfquote
|
|
|
|
|
Thanks Roger
Roger Stoltz wrote: The assignment operator declaration should look like this:
String& operator=( const char* str ); // For assigning a string, and...
String& operator=( const String& str ); // For assigning another object
why like this?
I have written destructor as
String::~String()<br />
{<br />
free(this->m_string);<br />
this->m_length = 0;<br />
}
And I was tring to write Trim function as follows,
String String::Trim(void)<br />
{<br />
<br />
<br />
String trim_string;<br />
<br />
strcpy(trim_string.m_string, this->m_string);<br />
trim_string.m_length = this->m_length;<br />
<br />
while( trim_string.m_string[--trim_string.m_length] == ' ' );<br />
trim_string.m_string[++trim_string.m_length] = '\0';<br />
<br />
trim_string.m_string = strrev(trim_string.m_string);<br />
<br />
while( trim_string.m_string[--trim_string.m_length] == ' ' );<br />
trim_string.m_string[++trim_string.m_length] = '\0';<br />
<br />
trim_string.m_string = strrev(trim_string.m_string);<br />
<br />
return trim_string;<br />
}
But then it gives Runtime error at "return trim_string;" (OR return *trim_string; ) in Trim(). When when I remove code from Destructor function Runtime error doesn't occur.
What is the wrong?
|
|
|
|
|
Aniket Salunkhe wrote: Roger Stoltz wrote:
The assignment operator declaration should look like this:
String& operator=( const char* str ); // For assigning a string, and...
String& operator=( const String& str ); // For assigning another object
why like this?
Which part is unclear?
This is how the assignment operator should be declared to work as expected.
Regarding your destructor I see that you're mixing memory management routines from both C and C++. Don't ever do that! In C++ you shall use new and delete .
Regarding your Trim function.
A Trim function is expected to trim the object it contains, not returning a trimmed copy of the original object. Personally I would like such a function to return a reference to itself in order to allow the use of cascading, e.g. str.TrimLeft().TrimRight() where TrimRight is called on the reference to the str object returned by TrimLeft .
In order to accomplish this your function should look like this:
String& String::Trim()
{
....
return *this;
}
I suspect that the runtime error you get when calling Trim is due to the abscense of a proper copy constructor. This error will disappear if you rewrite the Trim function as suggested above, but that doesn't mean you shouldn't write a copy constructor; you most certainly should in order to avoid shallow copies.
When you write a class that dynamically allocates memory you should always define at least:
- a default constructor that initializes the internal pointers
- a destructor that deallocates memory
- a copy constructor that make deep copies
- an overloaded assignment operator
"It's supposed to be hard, otherwise anybody could do it!" - selfquote
|
|
|
|
|
Roger Stoltz wrote: A Trim function is expected to trim the object it contains, not returning a trimmed copy of the original object
I am tring to build 'String' class something similar as in C#, in that it doesn't Trim the object itself ! So what should I follow?
Can you help me to create 'String', because I am getting problem in Copy Constructor & Destructor while returning 'String' object in member function.
Should I show you 'String' class? According to your time, check where I am going wrong in 'String' class. OR else just suggest me any book/link so design a proper class.
Thanks for your Help.
|
|
|
|
|
Aniket Salunkhe wrote: Can you help me to create 'String'
Sorry, but my answer is 'no' for two reasons:
1. There are existing string classes like CString from the MFC library and std::string from the STL library that are well known and robust. If you need a string class you should use one of those.
2. If you're writing this string class in order to teach yourself then, in my opinion, the best way to learn something new is by trying it out as in "learning by doing". You will make mistakes that will become valuable experiences to you.
Don't get me wrong, of course you can ask questions to this forum, but you should have a better idea of what you want to do than simply "I want to write a string class, how do I do that". Think about how you want your string class to function and what every member function should do.
Have a look at another string class here[^]. Download the source code and try to figure out how each function works and why it works that way. It might get you some ideas of what to do and perhaps what not to do.
Post questions if you don't understand, but think about it first; if you appear lazy you won't get any answers. Don't continue this thread because the question you first asked has been covered. Start a new thread with a specific problem if you have one.
You will also benefit from others that visit CodeProject more frequently than I do.
Regarding your problems with the copy constructor and the destructor they should look something like below depending on how you treat terminating zeros and such.
String::String( const String& SrcString )
{
if( SrcString.m_string )
{
m_string = new char[SrcString.m_length];
m_length = SrcString.m_length;
memcpy( m_string, SrcString.m_string, m_length );
}
else
{
m_string = NULL;
m_length = 0;
}
}
String::~String()
{
delete [] m_string;
m_string = NULL;
m_length = 0;
} Hope this helps
--
Roger
"It's supposed to be hard, otherwise anybody could do it!" - selfquote
|
|
|
|
|
Hi,
I have to write a VC++ code which should support to send Fax to the user. Could you please let me know any APIs are available to reuse.
Thanks a lot.
Regards,
Janarthan
|
|
|
|
|
Will you please enter a display name into your profile!
|
|
|
|
|
that's boring the number of anonymous posts we're getting these days
|
|
|
|
|
|
Until the DirectX forum is up and running I guess this is the best place to ask.
I'm creating a 2D scene using Dirct3D9, for the most part I have not had many problems. Triangles, Squares and rectangles are easy to draw, but what about circles? What I am looking for is a method to draw a 2D circle which fades ( alpha blends ) towards the edges.
Any ideas?
|
|
|
|
|