Re: CFileDialog drives me insane. Handle Problem ?
- From: "dawjdh@xxxxxxxxxxxxxx" <dawjdh@xxxxxxxxxxxxxx>
- Date: 14 Nov 2006 06:59:23 -0800
Thank you for your patience, that was realy helpful. I spend the whole
day to convert all the unwell done stuff in my code and was amazed that
most of my Problems that dont have directly to with the changes are
gone (including the on with the CFileDialog).
Joseph M. Newcomer schrieb:
The reason my answers had little to do with what you asked was that you were asking about
CFileDialog, when all the major failure modes were completely unrelated to CFileDialog and
critically related to the failure to properly use CString values. Your analysis of the
problem was flawed, based on a misperception of how the code worked.
Whenever you have a problem like this, the FIRST thing to do is to take those awful
multioperator expressions and reduce them to "single assignment" expressions with lots of
intermediate variables; then you can use the debugger to analyze the problem. You had not
done that, nor had you reported on what the debugger was revealing about the values of the
variables.
I think it is unlikely any of your problems are associated with CFileDialog and there are
so many fatal bugs in how you tried to handle strings that until the string problems are
fixed (and the fatal errors about file length being an 'int') that until those huge number
of bugs are removed, you can't even TALK about problems with CFileDialog.
The basic type you care about is CString. This is the equivalent to the Java 'String'
type. There are rare cases in which you need a LPTSTR pointer, but throwing LPSTRs (not
even LPTSTRs) around is just flat-out wrong. The number of times you would need an LPSTR
is so vanishingly small that when the very rare cases where the need arises, it becomes
obvious.
There are low-level data types of the C language, and they are rarely needed. But the
C/C++ languages support these. So they are always there, and there are some rare cases
where you use them, but think of these as exceptions. The raw data types of C/C++ are
const char * - const pointer to 8-bit characters. Obsolete, avoid
char * - non-const pointer to 8-bit characters. Obsolete, avoid
const wchar_t * - const pointer to Unicode characters. Obsolete, avoid.
wchar_t * - non-const pointer to Unicode characters. Obsolete, avoid.
"xxx", 'x' - 8-bit string or character constants. Rarely needed; avoid.
L"xxx", L'x' - Unicode string or character constants. Rarely needed; avoid.
Actually, they aren't 'obsolete' in that the LPxSTR typedefs are written in terms of these
underlying types, but the actual *coding* of the primitive data types should be thought of
as an obsolete style. Windows builds on these types using typedefs and macros:
LPSTR - pointer to 8-bit characters; rarely needed, avoid except in exceptional
circumstances where strings are guaranteed to be 8-bit characters.
LPCSTR - const verwsion of LPSTR; see LPSTR for qualifications
LPTSTR - pointer to non-constant ANSI or Unicode string. Fundamental
data type, but rarely needed.
LPCTSTR - pointer to contant ANSI or Unicode string. Fundamental
data type, but very rarely needed
Primarily used by API calls that take string arguments, but most
commonly used in cases where GetBuffer is used to unwrap
the internal buffer of a CString
LPWSTR - pointer to non-const Unicode characters. Rarely needed.
LPCWSTR - pointer to const Unicode characters. Rarely needed.
_T("xxx"), _T('x') - ANSI or Unicode string or character constants. This should
be the ONLY way you code a character or string constant, unless
there are the very rare circumstances where an 8-bit or Unicode constant
is actually required.
MFC then adds a real 'String' datatype, CString:
CString - used in almost all cases in programming MFC. Holds ANSI or Unicode
string based on compilation mode
CStringA - CString containing only 8-bit characters. Usage is about as rare as
LPSTR, but in most cases is preferred to using a raw LPSTR
CStringW - CString containing only Unicode characters. Usage is about as rare
as LPWSTR, but in most cases is preferred to using a raw LPWSTR
const CString & - most efficient way to pass a CString as a parameter,
because no copy of the string is made
CString & - most common way to pass a reference to a CString
CString * - very rarely needed; typical example is passing a CString across
thread boundaries
GetBuffer - unwraps a buffer of a CString so it can be written to. Rarely used.
Using ReleaseBuffer is *mandatory*
std::string - while part of the Standard C++ Library, has little applicability
in MFC programming, and has little advantge over CString
Note that any API call or other case where an LPCTSTR is specified, there is an implied
(LPCTSTR) cast operator applied, which returns a pointer to a constant string.
Key to good programming is to use as few operators per statement as possible. There is
rarely an advantage to this, and it results in code that is hard to read, hard to
understand, hard to debug, and hard to maintain. Had you not introduced gratuitous usage
of LPSTR and used intermediate variables you would have immediately seen in the debugger
what was going on, and the error caused by the implied destructor of temporary objects
could not have occurred.
Because the debugger is line-oriented, writing more than one statement per line generally
results in code that is difficult-to-impossible to debug. Program vertically, one
statement per line. Never use a comma in a declaration list. One variable, one line.
CString a, b, c; // bad style
CString a; // one variable per line.
CString b;
CString c;
if(test) dosomething; // bad style
if(test) // test is on separate line from then or else
dosomething;
if(test) {} else {dosomething} // *exceptionally* bad style
if(!test) // good style
dosomething;
joe
On 13 Nov 2006 06:14:05 -0800, "dawjdh@xxxxxxxxxxxxxx" <dawjdh@xxxxxxxxxxxxxx> wrote:
Hi,Joseph M. Newcomer [MVP]
thank you for that qualified corrections. I'll try to fix that and to
understand the principles behind that. I will see if that was the
Problem, but what i want to know (you have to confess that the things
you answered have nothing directly to do with what i asked for) , are
there any problems you had before with that CFileOpenDialog alike that
i have ? I just want to be shure and exclude the possibility that
CFileOpenDialog makes some Problems. Is that question ok ? So you push
me in that direction ..... is there any recommendable literature out
there to understand and learn to write that clean code you want me to
write ? It seems to be a real good idea to rewrite that code. I am a
little confused about that hundreds of String types out there. I come
from Java, so there you have only one type for a string. I dont
understand why there are that much possibilities to make the same
thing.
best regards,
David
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- Re: CFileDialog drives me insane. Handle Problem ?
- From: Joseph M . Newcomer
- Re: CFileDialog drives me insane. Handle Problem ?
- References:
- CFileDialog drives me insane. Handle Problem ?
- From: dawjdh@xxxxxxxxxxxxxx
- Re: CFileDialog drives me insane. Handle Problem ?
- From: David Lowndes
- Re: CFileDialog drives me insane. Handle Problem ?
- From: dawjdh@xxxxxxxxxxxxxx
- Re: CFileDialog drives me insane. Handle Problem ?
- From: Joseph M . Newcomer
- Re: CFileDialog drives me insane. Handle Problem ?
- From: dawjdh@xxxxxxxxxxxxxx
- Re: CFileDialog drives me insane. Handle Problem ?
- From: Joseph M . Newcomer
- CFileDialog drives me insane. Handle Problem ?
- Prev by Date: array from c++ to vb
- Next by Date: Re: array from c++ to vb
- Previous by thread: Re: CFileDialog drives me insane. Handle Problem ?
- Next by thread: Re: CFileDialog drives me insane. Handle Problem ?
- Index(es):
Relevant Pages
|