Re: CFileDialog drives me insane. Handle Problem ?

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



See below...
On 13 Nov 2006 02:18:57 -0800, "dawjdh@xxxxxxxxxxxxxx" <dawjdh@xxxxxxxxxxxxxx> wrote:

Hi,
i want to communicate some strange Problems i have with CFileDialog.
Hope someone can push in the right direction.

1. Problem:

CFileDialog FileDlg(true);

INT_PTR nResponse = FileDlg.DoModal();

if (nResponse == IDOK){}else{return;}
****
AVOID ALL TENDENCIES TO WRITE COMPLEX CODE IN A SINGLE LINE!
if(nResponse != IDOK)
return;
is VASTLY SIMPLER, EASIER TO READ, AND EASIER TO UNDERSTAND
****

LPSTR file = FileDlg.GetFileName().GetBuffer();
****
This cannot possibly work, so don't do it! You are getting the buffer of a temporary
CString, so when the object is destroyed at the semicolon the pointer is left pointing to
nonsense. You made two serious errors here: (a) you tried to do multiple things in a
single line instead of writing multiple lines (see above comment about avoiding writing
complex single lines) and (b) you are using an LPSTR when you should be using a CString!

CString file = FileDlg.GetFileName();
and that's all! AVOID doing gratuitous conversions to LPTSTRs unless you need them, and
in this case it makes no sense to want one!
*****
LPSTR folderPath = FileDlg.GetPathName().GetBuffer();
****
CString foldPath = FileDlg.GetPathName();
Same problem as above. Too much in one line, misuse of temporary object, erroneous
thinking. And why do you assume that LPSTR makes sense? It doesn't; the return type is
LPTSTR and saying LPSTR is just flat-out WRONG! Why do you presume to change the return
type of a function?

B y the way, every GetBuffer must have a ReleaseBuffer, so there are even deeper errors
here!
****

ULONGLONG fSize = GetFileSizeInByte(fileUrl.GetBuffer());
****
Why GetBuffer? Where's the ReleaseBuffer? Why not just
ULONGLONG fSize = GetFileSizeInByte(fileUrl);
?

Perhaps you have some fixation about the use of LPSTR. This is wrong. The argument to
the function should be either
const CString &
or
LPCTSTR
then you don't need to convert the CString to something silly and meaningless like an
LPSTR.
*****

long GetFileSizeInByte(const char* sFileName)
***
Why do you presume that the character type is 'char'? LPCTSTR would make sense, but the
above code is no Unicode-aware and should NEVER be written in a modern program. Note
that if you specify LPCTSTR, then you can pass a CString in as an argument, so there is no
need to use silly GetBuffer calls

A file length is a ULONGLONG. So why are you declaring the return type as 'long' and why
are you returning negative numbers? The specification of this function makes no sense!

ULONGLONG GetFileSizeInByte(LPCTSTR fname)
{
CFile f;
if(!f.Open(fname, CFile::modeRead))
return 0;
ULONGLONG result = f.GetLength();
f.Close();
return result;
}

****
{
std::ifstream f;
f.open(sFileName, std::ios_base::binary | std::ios_base::in);
if (f.eof()) { return 0; }
****
USE TWO LINES!
****
if (!f.good()) { return -1; }
****
USE TWO LINES!
Returning -1 for a ULONGLONG is meaningless
****
if (!f.is_open()) { return -2; }
****
USE TWO LINES
Returning -2 for a ULONGLONG is erroneous
****
f.seekg(0, std::ios_base::beg);
std::ifstream::pos_type begin_pos = f.tellg();
f.seekg(0, std::ios_base::end);
****
A lot of complexity to accomplish what can be done in a single method call when CFile is
being used. Why use a complex solution when a simple solution exists?
****
return static_cast<long>(f.tellg() - begin_pos);
****
And why are you converting a size to a long when the size is a ULONGLONG? Do you really
mean to throw away the high-order 32 bits of the file size?
****
}

fSize is in 80% of cases '-1'. In 15% '-2'. Sometimes it works as
expected.
****
There are so many errors in the code that until it is rewritten as specified it is
impossible to analyze what is going wrong. The real problems are a fundamental
misunderstanding about CStrings and data types in general. Gratuitous and erroneous
conversions, and overly-complex approaches to simple problems only add to the problems.
Rewrite it.
****
If i set 'folderPath ' to a stistc value and dont call
FileDlg.DoModal(); all works 100% correct.
****
Of course. You have far too many errors in the code
****

2. Problem:
I have some customized Sub-Dialogs (With GUI-Buttons, Custom-Bkg). All
works correct until i call CFileDialog::DoModal() /
GetOpenFileDialog() with return IDOK (means if i choose a File an Click
Ok, OnCancel the Problem does'nt occur). If i do so and after that call
my Subdialog, it is completely destroyed. All the GUI Buttons are not
Visible and not all of them are clickable. The Background is gone and
just some weird rectangels are visible (a mixture of grey rect's and
the underlaying bckg).
If i call a Java FIleOpenDialog via JNI out of this app instead of
CFileDialog, all works as expected.
****
Until you rewrite the code, any further problems can be attributed to the huge number of
fundamental errors in the current code. Only after a complete rewrite as specified can
you then worry about other problems.
****

Some Ideas ?
Does someone know another imlementation of a FileDialog ?
****
The problems are not in CFileDialog. The problems are where I've indicated. CFileDialog
is irrelevant to the problem, as far as I can tell.
****

best regards,
David
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.


Quantcast