Pelles C forum

C language => Windows questions => Topic started by: jboyes on September 26, 2014, 08:36:30 PM

Title: GetOpenFileName problem with double click
Post by: jboyes on September 26, 2014, 08:36:30 PM
My new program selects files using a GetOpenFileName dialogue. The files are .PDFs and, if I double click to select one, the program crashes.

I turned to one of my previous programs that selected .DMX files and this one never crashed. I spent nearly a whole day comparing the two dalogue segments but could find no differences.

I went back to my new program and found that using any filetype other than .PDF it worked flawlessly. I tried defaulting .PDF files to be opened with other applications including Notepad but that didn't fix things either.

I have now run out of ideas and would appreciate any help from the experts.

Thank you,

John.
Title: Re: GetOpenFileName problem with double click
Post by: jj2007 on September 27, 2014, 10:07:39 AM
John,

Adobe is a recipe for crashes, but it could well be something else. Do the files open with a double click from Windows Explorer?

Try showing a messagebox with the filename before the ShellExecute (or whatever you use to open the file). Put brackets before and after: [MyFile.pdf]

There is another issue: the dialog has an internal exception, which shows up when you debug it e.g. with OllyDbg. Normally that's not a problem, though.
Title: Re: GetOpenFileName problem with double click
Post by: TimoVJL on September 27, 2014, 11:55:27 AM
Is OPENFILENAME structure initialized properly ? Zeroed first or static variable ?
Title: Re: GetOpenFileName problem with double click
Post by: jboyes on September 27, 2014, 10:20:24 PM
Many thanks for your suggestions gentlemen. I did initialise the OPENFILENAME structure but, as an experiment, I temporarily removed that code and it made no difference.

Like TimoVJL, my guess is that Adobe is to blame but I have also loaded Foxit with a view to getting rid of Adobe Reader some day. That might be significant.

I now have the program fully working. I have to keep the mouse away from filenames as much as possible to avoid tooltips. I also have to single click to select the multiple files and, if I can get back to the 'Open' button smartly, everything works fine.

I shall keep looking at the problem now and again but the panic is over.

Thank you for your help.

John.
 
Title: Re: GetOpenFileName problem with double click
Post by: frankie on September 27, 2014, 11:20:48 PM
Check what flags you set.
Try this code:
Code: [Select]
BOOL GetFileName(HWND hWnd, LPTSTR lpstrFile)
{
*lpstrFile = '\0';

OPENFILENAME ofn = {0};
ofn.hwndOwner   = hWnd;
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFile   = lpstrFile;
ofn.nMaxFile    = MAX_PATH -1;
ofn.lpstrFilter = "TXT\0*.txt\0All Files\0*.*\0\0";
ofn.lpstrTitle  = "TXT Files";
ofn.Flags       = OFN_OVERWRITEPROMPT;
ofn.lpstrDefExt = ".txt";

return GetOpenFileName(&ofn);
}
This works for me.
Title: Re: GetOpenFileName problem with double click
Post by: jboyes on September 28, 2014, 09:29:40 PM
Now here's an interesting thing:

I just tried my program again but chose 'All files' instead of 'PDF files' before selecting the file to open. It worked perfectly every time; no crashes at all.  So it must be something to do with the 'Files of type' being .PDF

This is obviously a problem due to my computer which has had every version of Acrobat Reader loaded in its time. And now I have added Foxit, the poor thing is probably getting very confused.

Its not a windows problem that I can expect to get help from in this forum so I think we shold drop the subject.

Just for completeness frankie, here is the code I use to initialise the OPENFILENAME structure:

Code: [Select]
ZeroMemory(&ofn , sizeof(ofn)); // Initialise structure to zero
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hDlg;
ofn.lpstrFile = FileName;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(FileName);
ofn.lpstrFilter = "All files\0*.*\0PDF files\0*.pdf\0\0";
ofn.nFilterIndex =2;
ofn.lpstrFileTitle = NULL;
ofn.lpstrDefExt = ".pdf";
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir=NULL;
ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_EXPLORER|OFN_ALLOWMULTISELECT;

The OPENFILENAME structure itself is declared with my globals because I use it in more than one function.

Thanks again for all the help.

John.
Title: Re: GetOpenFileName problem with double click
Post by: PhilG57 on December 28, 2014, 04:03:29 AM
Hi.  I'm now seeing the same problem where during file selection, if I hover the cursor over a file selection, my program crashes at location 401280.  I continue to experiment with the initialization of OPENFILENAME, and the actual parameters to GetOpenFileName but to no avail.  I my case, the file I am trying to select is a user file type of "vcp".  More details hopefully later.
Title: Re: GetOpenFileName problem with double click
Post by: PhilG57 on December 29, 2014, 07:50:25 PM
After playing with my code and searching the web, I've concluded this is a Windows problem, and since I'm running Pelles v7 on Windows XP, I'm not looking for a fix real soon...

The best explanation I can find is that Windows is failing in the GetOpenFileName code.  Specifically, while you're thinking about a file to select to satisfy the GetOpenFileName request, when you hover your mouse over a potential file name, Windows wants to display those file properties (type, date, size, etc.) in a little yellow box near the file name.  Somehow that causes GOFN and your program to crash.  From what I can find there is no known solution....

I have noticed that if you quickly select a file (before Windows thinks it has to display the file properties in a little yellow box), the GetOpenFileName completes normally,  Also, for me, the GOFN does not crash if I run my program in "execute" mode rather than "debug".  Hope this helps.

   
Title: Re: GetOpenFileName problem with double click
Post by: jj2007 on December 30, 2014, 07:05:21 PM
After playing with my code and searching the web, I've concluded this is a Windows problem, and since I'm running Pelles v7 on Windows XP, I'm not looking for a fix real soon...

After playing extremely often with my own GetOpenFileName code and searching the web intensely, I've concluded that problems are related to sloppy coding. Attached an executable with its source (in RTF format, assembly, sorry...). Even after intense hovering over files with Chinese names etc, I could not crash it on XP and 7-64. Attached is the Unicode version, but the ANSI version behaves exactly the same. The proggie is built in debug mode, so OllyDbg could show you how it is built.

If you are able to code a reproducible example in 32-bit code, and you can insert an _asm int 3;  right before the call to GetOpenFileName, post the example here, along with a description how to crash it, and I will be happy to find the bug.
Title: Re: GetOpenFileName problem with double click
Post by: Vortex on December 30, 2014, 07:44:20 PM
Hi PhilG57,

Checking your code :
Code: [Select]
ZeroMemory(&ofn , sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hDlg;
ofn.lpstrFile = FileName;
ofn.lpstrFile[0] = '\0';   <--- Should be : FileName[0]=0; The current code changes the pointer,not the filename
ofn.nMaxFile = sizeof(FileName);
ofn.lpstrFilter = "All files\0*.*\0PDF files\0*.pdf\0\0";
ofn.nFilterIndex =2;
ofn.lpstrFileTitle = NULL;
ofn.lpstrDefExt = ".pdf"; <--- Do not put a dot in the default extension name.
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir=NULL;
ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_EXPLORER|OFN_ALLOWMULTISELECT;

About the first modification indicated above, the dialog will crash when it can't access the buffer.

Second, the ofn.lpstrDefExt should not have a dot in it. This will prevent the dialog from opening reliably. Also when opening files, it is best to leave that line blank. It is meaningful only when assigning a default extension to new
filenames with no extension.
Title: Re: GetOpenFileName problem with double click
Post by: aardvajk on December 30, 2014, 07:58:34 PM
Quote
ofn.lpstrFile = FileName;
ofn.lpstrFile[0] = '\0';   <--- Should be : FileName[0]=0; The current code changes the pointer,not the filename
What he has, and what you propose are equivalent.

The main problems in GetOpenFileName and friends come from having dodgy shell extensions on your computer rather than failing to init the simple structure. GetOpenFileName is pretty much like having a mini-explorer in your app, except without the protection that Explorer has built in to stop it crashing.
Title: Re: GetOpenFileName problem with double click
Post by: PhilG57 on January 01, 2015, 04:52:57 PM
Hi and Happy New Year,
   I appreciate the suggestions and offers for help.  The code referenced just above by Vortex is not mine but that posted earlier by jboyes.  However my code is basically identical and changing the '\0' for 0 in the OFN fields has no effect.

   My code is attached and I will gratefully accept any offers to correct the OFN calls.  In reply to aardvajk, I do have a bunch of shell extensions like Git, Tortoise, and Change Attributes.  They have been there quite awhile so I really can't point the blame at them...

   To test: compile and run under debug; select CheckIn from the main menu, and CheckIn again from that sub-menu.  Hover over any displayed filename or directory for a second or two and the program should blow up.   

   Thanks again. 
Title: Re: GetOpenFileName problem with double click
Post by: TimoVJL on January 01, 2015, 05:22:48 PM
No crashing so far.
Title: Re: GetOpenFileName problem with double click
Post by: czerny on January 01, 2015, 05:26:43 PM
To test: compile and run under debug; select CheckIn from the main menu, and CheckIn again from that sub-menu.  Hover over any displayed filename or directory for a second or two and the program should blow up.   
You should downgrade to a proper OS like win2k!
Here is all ok!
Title: Re: GetOpenFileName problem with double click
Post by: jj2007 on January 02, 2015, 01:34:34 AM
Happy New Year & no crash on Win7-64 :)
Title: Re: GetOpenFileName problem with double click
Post by: PhilG57 on January 02, 2015, 04:21:12 PM
Thank you all for the testing; I now have to believe one of my file explorer extensions is causing the problem.  One of these days, I'll remove and test each one to find the culprit.

Another question and favor to ask: when you are testing my application, I assume you are doing so using Pelles IDE.  (To remind you, the problem does not occur if running the program with Project->Execute.)  When I run the program in debug mode, the global variable "gstDBhdr" does not show up in the list of globals.  "gstDBhdr" is defined in database.c and extern'ed to a couple of other modules.  I know the variable is actually in the program because I can follow the programs testing of values read into "gstDBhdr".  But I can't see the !@#$# thing.

Does this problem appear on your systems???

Thanks again. 
Title: Re: GetOpenFileName problem with double click
Post by: Bitbeisser on January 03, 2015, 04:00:51 AM
Thank you all for the testing; I now have to believe one of my file explorer extensions is causing the problem.  One of these days, I'll remove and test each one to find the culprit.

Another question and favor to ask: when you are testing my application, I assume you are doing so using Pelles IDE.  (To remind you, the problem does not occur if running the program with Project->Execute.)  When I run the program in debug mode, the global variable "gstDBhdr" does not show up in the list of globals.  "gstDBhdr" is defined in database.c and extern'ed to a couple of other modules.  I know the variable is actually in the program because I can follow the programs testing of values read into "gstDBhdr".  But I can't see the !@#$# thing.
That smells awfully like an uninitialized variable... :-\

Ralf
Title: Re: GetOpenFileName problem with double click
Post by: PhilG57 on January 03, 2015, 02:53:15 PM
'Morning.  Well, it's a structure and a global one at that.  Initialized or not, I should at least be able to see it during debug.  And, once again, even though I cannot display the global variable, I know it is being 'seen' and used correctly during program execution.

I know I have a ton of globals as they make early development easier; some of these globals will eventually be converted to locals as I add functionality and improve the code. 

What I'd like to know if anyone else is, or is not, able to see this global under debug so I'll know if my problem is another "feature" on my system.  Thanks.
Title: Re: GetOpenFileName problem with double click
Post by: czerny on January 03, 2015, 05:58:45 PM
It is neither seen initialized nor not initialized. It could not selected in the watch tab too. Pelles C 7RC4.
Title: Re: GetOpenFileName problem with double click
Post by: PhilG57 on January 04, 2015, 03:17:10 PM
You are absolutely right!  If I update the structure definition by adding an initialization value to it such as "gstDBhdr = {0]", then I can see the structure during debug.  Or, if I explicitely initialize a structure member such as "gstDBhdr.id = '' ';" somewhere in the program, then I can see the structure under debug as well.

What was/is confusing is that the structure gstDBhdr is initialized using ZeroMemory and is read into using ReadFile so I thought those references should suffice.  Maybe because both of those statements use an "&" in front of the structure name --ZeroMemory(&gstDBhdr, 0 , sizeof(gstDBhdr))--, the compiler didn't pick up the reference.

Anyway many thanks.  I'm a happy camper again.  Case closed.  Thanks again.
Title: Re: GetOpenFileName problem with double click
Post by: frankie on January 04, 2015, 08:27:51 PM
I'm not sure, but I think that the problem i related to *where* the variable is declared.
Uninitialized vars are by default in the BSS section, that is not present in the executable PE, but is dynamically created at loading.
Maybe PellesC still miss code to link the variable addresses against the BSS creation.
Title: Re: GetOpenFileName problem with double click
Post by: Bitbeisser on January 05, 2015, 04:00:51 AM
You are absolutely right!  If I update the structure definition by adding an initialization value to it such as "gstDBhdr = {0]", then I can see the structure during debug.  Or, if I explicitely initialize a structure member such as "gstDBhdr.id = '' ';" somewhere in the program, then I can see the structure under debug as well.
That's what I meant. This is a typical symptom when a program behaves differently between running in an IDE/debugger or standalone. When using a debugger, usually all memory space is cleared before execution, to get a "clean slate" on each debugger run. When running a program standalone, the memory area for is in a lot of cases undefined, though static global variables "should" be zeroed before program start. I have made it a good habit in +30 years of programming to never depend on such compiler behavior and always initialize all variables to a known state...

Ralf
Title: Re: GetOpenFileName problem with double click
Post by: PhilG57 on January 05, 2015, 03:40:13 PM
Yes, I too like to initialize variables even though they should have been done so by the compiler.  That's why I did the ZeroMemory thing on my global structure.

But I have to admit I thought all globals would be visible under debug regardless of whether or not they had been explicitely initialized.  I now understand I have to explicitely reference the variable (or structure member) and the "&" on ZeroMemory does not cut it.

I also have to admit I don't understand the difference, if any, between global and static global variables.  Both exist for the life of the program, and both should be visible to all compilation units that have an extern for the variable.

Thanks again.