|
zuma77
Hope I understood your question
I see you use DDX_Control then (I think)you can't use Oncreate for create edit
I suggestion(Im not sure that is very good) you enter your code in the
function in classs derived(ccombobox) but with one if (if m_Eidt.m_hwnd==NULL then create)
|
|
|
|
|
Thanks for your help.
The PreSubclassWindow function was the key.
|
|
|
|
|
DDX_Control calls SubclassDlgItem for an existing control. In this case, the control has already been created. You will need to locate and subclass the edit control.
Software Zen: delete this;
|
|
|
|
|
Thanks for your help.
It works now
|
|
|
|
|
Hi,
How to simulate DoEvents() function of Visual Basic in Visual C++? Please help if you know.
|
|
|
|
|
Something might work
void DoEvents()<br />
{<br />
MSG dispatch;<br />
while (::PeekMessage( &dispatch, NULL, 0, 0, PM_NOREMOVE))<br />
{<br />
if (!AfxGetThread()->PumpMessage());<br />
}<br />
}
|
|
|
|
|
|
|
i am defining a bunch of exception classes from a dll that are supposed to be thrown from within the DLL code to the GUI which loaded the dll.
it seems that i'm having trouble with the STL std::string::c_str() function when releasing its string.
here is my code :
DLL Exceptions header :
<font color=blue>#ifdef</font> VCALCPARSER_EXPORTS
<font color=blue>#define</font> VCALCPARSER_API <font color=blue>__declspec</font>(<font color=blue>dllexport</font>)
#else
<font color=blue>#define</font> VCALCPARSER_API <font color=blue>__declspec</font>(<font color=blue>dllimport</font>)
<font color=blue>#endif</font>
<font color=blue>#include</font> <STRING> <font color=green>
<font color=blue>class</font> VCALCPARSER_API CVCalcParserException {
<font color=blue>protected</font>:
ExceptionNumbers m_enExceptionNumber;
std::string m_strExceptionMsg;
<font color=blue>long</font> m_iErrorPos;
CVCalcParserException(ExceptionNumbers enExceptionNumber,
<font color=blue>const</font> std::string& strExceptionMsg,
<font color=blue>int</font> iErrorPos);
<font color=blue>public</font>:
<font color=blue>virtual</font> ~CVCalcParserException();
ExceptionNumbers GetExceptionNumber();
std::string GetMessage();
<font color=blue>long</font> GetErrorPos();
};
<font color=blue>class</font> VCALCPARSER_API CSyntaxException : <font color=blue>public</font> CVCalcParserException {
<font color=blue>protected</font>:
CSyntaxException(ExceptionNumbers enExceptionNumber,
const</font> std::string& strExceptionMsg,
<font color=blue>int</font> iErrorPos);
<font color=blue>public</font>:
<font color=blue>virtual</font> ~CSyntaxException();
};
<font color=blue>class</font> VCALCPARSER_API CMathematicExpressionExpectedException : <font color=blue>public</font> CSyntaxException {
<font color=blue>public</font>:
CMathematicExpressionExpectedException(<font color=blue>int</font> iErrorPos);
~CMathematicExpressionExpectedException();
};
then, when an such an error occurs (Mathematic expression expected), i send this exception :
VALUES_TYPE CVCalcParser::Evaluate(<font color=blue>const</font> std::string& strSource)
<font color=blue>throw</font>(CVCalcParserException) {
<font color=blue>this</font>->ResetParserMembers(strSource);
<font color=blue>try</font> {
VALUES_TYPE valResult = <font color=blue>this</font>->Level_1();
<font color=green></font>
}
<font color=blue>catch</font> (CVCalcParserException) {
<font color=blue>throw</font>;
}
<font color=blue>catch</font> (...) {
<font color=blue>throw</font> CUnknownException(0);
}
}
VALUES_TYPE CVCalcParser::Level_1(<font color=blue>void</font>)
<font color=blue>throw</font>(CVCalcParserException) {
VALUES_TYPE valLeftOperand = <font color=blue>this</font>->Level_2();
<font color=green></font>
}
VALUES_TYPE CVCalcParser::Level_2(<font color=blue>void</font>)
<font color=blue>throw</font>(CVCalcParserException) {
VALUES_TYPE valLeftOperand = <font color=blue>this</font>->Level_3();
<font color=green></font>
}
VALUES_TYPE CVCalcParser::Level_3(<font color=blue>void</font>)
<font color=blue>throw</font>(CVCalcParserException) {
VALUES_TYPE valLeftOperand = <font color=blue>this</font>->Level_4();
<font color=green></font>
}
VALUES_TYPE CVCalcParser::Level_4(<font color=blue>void</font>)
<font color=blue>throw</font>(CVCalcParserException) {
VALUES_TYPE valLeftOperand = <font color=blue>this</font>->Level_5();
<font color=green></font>
}
VALUES_TYPE CVCalcParser::Level_5(<font color=blue>void</font>)
<font color=blue>throw</font>(CVCalcParserException) {
VALUES_TYPE valLeftOperand = <font color=blue>this</font>->Primary();
<font color=green></font>
}
VALUES_TYPE CVCalcParser::Primary(<font color=blue>void</font>)
<font color=blue>throw</font>(CVCalcParserException) {
<font color=blue>this</font>->GetToken();
<font color=blue>switch</font> (<font color=blue>this</font>->m_tokCurrentToken) {
<font color=blue>case</font> ...:
<font color=green></font>
<font color=blue>default</font>:
<font color=blue>throw</font> CMathematicExpressionExpectedException(<font color=blue>this</font>->m_iCurrentIndex);
}
}
and at last, i catch this exception thrown from the dll in my GUI MFC project :
<font color=blue>void</font> CVisualCalcDlg::OnCalculate() {
CString strSource, strDest;
m_peInput->GetWindowText(strSource);
<font color=green>
<font color=blue>try</font> {
VALUES_TYPE valResult = m_Parser.Evaluate((LPCTSTR)strSource);
<font color=green></font>
}
<font color=blue>catch</font> (CSyntaxException& ex) {
strDest.Format(<font color=gray>"Syntax error %d : %s"</font>, ex.GetExceptionNumber(), ex.GetMessage().<code>c_str()</code>);
m_peInput->SetSel(ex.GetErrorPos(), ex.GetErrorPos());
}
<font color=blue>catch</font> (...) {
strDest.Format(<font color=gray>"Unknown parser internal error"</font>);
}
<font color=green></font>
}
when i look at the call stack, i see that the destructor of the std::string object is call at that point (it didn't leave the scope yet), and sope other functions are called down, until i get a dark message, that seems to say that i have a pointer that's been invalidated.
when i put a breakpoint on the line which contains that c_str() call and watch the ex exception object, all his datas (exception description message, position and error code) are correctly set.
i'm really stuck about that, because that behavior weren't happening when the code that i moved in the DLL was in the same project as the GUI.
any hint anybody ?
|
|
|
|
|
Probably what's happening (not sure at all) is that the string is allocating dynamically memory for its internal purpose. Then, when firing the exception, it will be catched in your exe and upon calling the destructor of this string, it will try to delete this memory. Unfortunately, as it hasn't been allocated by the same module (by the dll and not by your exe) this will crash.
But this is difficult to understand because you don't know how it works internally. A thing is sure: when you allocate memory in a dll and try to delete it inside your exe, this will crash the program. That's why classes exported from a dll have a Destroy method (it is just a delete this).
But here, I don't know how it works when an exception is fired...
|
|
|
|
|
hum, so you suggest me to have a Destroy() function in each my classes exported by the DLL ?
anyway, this seems to be much complicated, so i ask you a favour : can i send you the sources by email ?
thank you very much.
|
|
|
|
|
v2.0 wrote: hum, so you suggest me to have a Destroy() function in each my classes exported by the DLL ?
No, sorry, you misunderstood what I was saying (I took that just as an example).
I'm still thinking hard about what's happening here. One thing is almost sure: the string allocates memory dynamically for its own purpose. Now, as it is a template, I think (but at this point, my brain give me headache ) that the memory will be freed by your application when destructor is called. But at this point, I'm not sure. But if this is the case, this is what is causing the crash.
Can you tell me at which point the program breaks (I know it will be in a specific file). So give me the file and the line number. I have VC2005 installed so chances are that the files will be different. Can you post some code around the crashing point ?
That will help me to check if I'm right or not.
Otherwise I'm thinking of a solution but I don't find one right now. I'll keep searching
|
|
|
|
|
one more thing.
instead of
catch (CSyntaxException& ex) {
strDest.Format("Syntax error %d : %s", ex.GetExceptionNumber(), ex.GetMessage().c_str());
m_peInput->SetSel(ex.GetErrorPos(), ex.GetErrorPos());
}
i also tried the following codes, unsuccelsfully (all resulting in the same runtime crash when calling c_str() ) :
catch (CSyntaxException& ex) {
CString strTmp = ex.GetMessage().<code>c_str()</code>;
strDest.Format("Syntax error %d : %s", ex.GetExceptionNumber(), strTmp);
m_peInput->SetSel(ex.GetErrorPos(), ex.GetErrorPos());
}
catch (CSyntaxException& ex) {
char* strTmp = new char[ex.GetMessage().size()+1];
strcpy(strTmp, ex.GetMessage().<code>c_str()</code>);
strDest.Format("Syntax error %d : %s", ex.GetExceptionNumber(), strTmp);
m_peInput->SetSel(ex.GetErrorPos(), ex.GetErrorPos());
}
|
|
|
|
|
And what happens if you don't do anything in the catch block ?
If I'm right, then it should crash also, even if you don't call c_str(). Otherwise, I don't know what's happening
|
|
|
|
|
i emailed you with the project sources.
tell me if there are any points that you don't understand
cheers
ps : i'm going home, don't mind if i don't answer immediately
|
|
|
|
|
Yep I can take a look but this week-end I'm away until tuesday.
And it would be nice if you explain me the steps to reproduce the behavior (otherwise I'll spend too much time searching how to fire the exception )
|
|
|
|
|
very easy to reproduce
compile, link, launch, then type enter key when the dialog box appears.
it should display an error message saying "Mathematic expression expected", but it crashes there.
|
|
|
|
|
Damn, Cedric, i'm so happy, simply changing the DLL project runtime library property to multithreaded DLL (/MD or /MDd for debud version) solved the problem...
well, thanks you very much, you were more than useful on this point.
and you have the chance to be the 1st one playing with VisualCalc 3.0 beta 1(at the condition that you rebuild it correctly ).
hope to be able to update the article soon...
humm, well, so have a nice easter week-end dear
-- modified at 14:41 Saturday 15th April, 2006
|
|
|
|
|
Cool !
I'm glad it helped
BTW, I didn't receive your source code, that's strange.
Happy Easter for you too
|
|
|
|
|
Maybe a possible solution. I found that looking on the net (on this page[^])
Does getFileName() comes from a DLL? If so, make sure that your EXE and the<br />
DLL are both compiled with /MD (/MDd in debug builds) so you're both using<br />
the DLL version of the runtime. If you don't do that, you can't pass<br />
std::strings (or many other things) between the DLL and the EXE (or two<br />
DLLs, whatever the case may be).
Hope this will help
|
|
|
|
|
both DLL and exe projects are compiled in debug mode ('cause in the same solution).
|
|
|
|
|
Yep, but go in the properties of your project and go to the code generation tab. There you will have a selection for Runtime Mibrary. Check if this is well Multi-threaded DLL (I don't know exactly how it will affect your code) for both projects. There is also some valuable info in the thread I gave you (and I think I was at least partially right )
|
|
|
|
|
I found another interesting link[^]
I think this is more or less the problem you have.
|
|
|
|
|
A general rule of thumb is that it is not safe to throw an exception across a DLL boundary. Like most rules of thumb if you really know what you're doing you may be able to isolate specific cases in which it if safe to ignore it but in general the rule is sound.
Steve
|
|
|
|
|
Why is VC++ the best language to write an Office COM addin? I mean, why not VB, VBA, java or .NET?
---
With best regards,
A Manchester United Fan
The Genius of a true fool is that he can mess up a foolproof plan!
|
|
|
|