Thread: declaring a variable makes the "GetOpenFileName" misbehave

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    21

    declaring a variable makes "GetOpenFileName" misbehave

    Hello, I have a very strange issue. I am new to Win32 programming, therefore I am probably doing something wrong.
    I wrote a function which reads text from a file selected by the user, then puts that text inside an Edit control. The function works perfectly, however, once I declare a new variable ( int i; ), the function "GetOpenFileName" behaves strangely and always returns 0, despite the fact that "int i" is declared AFTER GetOpenFileName is called.


    Here is the short "lazy" version of my code, all lines are ommited except for the important ones (the full version is below this one):
    Code:
    void OpenTextFile(char * title, HWND targetEditControl)
    {
        HANDLE fileHandle;
        OPENFILENAME fileStruct; 
        char str[512];
        /*Structure is initlized here*/
        if (GetOpenFileName(&fileStruct)==0)
        {
            MessageBox(NULL, "Failed to open file.", title,MB_OK | MB_ICONASTERISK); //this is triggered when I uncomment "int i" below.
        }
        else
        {
            //int i;   //Once this is uncommented, GetOpenFileName will return 0.
            /*Additional code here*/
        }
        return;
        
    }
    Full code:
    Code:
    void OpenTextFile(char * title, HWND targetEditControl)
    {
        HANDLE fileHandle;
        OPENFILENAME fileStruct; 
        char str[512];
        str[0]=NULL;
        fileStruct.lStructSize=sizeof(OPENFILENAME);
        fileStruct.lpstrTitle=title;
        fileStruct.lpstrFile=str;
        fileStruct.nMaxFile=512;
        fileStruct.lpstrFilter="Text files ( .txt )\0*.txt\0All files\0*\0"; //selection filters
        fileStruct.hInstance=NULL;
        fileStruct.lpstrCustomFilter=NULL;
        fileStruct.nMaxCustFilter=NULL;
        fileStruct.nFilterIndex=NULL;
        fileStruct.lpstrFileTitle=NULL;
        fileStruct.nMaxFileTitle=NULL;
        fileStruct.lpstrInitialDir=NULL;
        fileStruct.hwndOwner=NULL;
    
    
        if (GetOpenFileName(&fileStruct)==0)
        {
            MessageBox(NULL, "Failed to open file.", title,MB_OK | MB_ICONASTERISK); //this is triggered when I uncomment "int i" below.
        }
        else
        {
            char path[1024];
            //int i;   //Once this is uncommented, GetOpenFileName will return 0, no matter what.
            HANDLE hFile;
            DWORD wmWritten;
            char strVal[1024];
            ConvertSlashes(fileStruct.lpstrFile,path);
            hFile = CreateFile(path,GENERIC_READ,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
            ReadFile(hFile,strVal,1024,&wmWritten,NULL);
            CloseHandle(hFile);
            SendToEditBox(targetEditControl,strVal);
        }
        return;
    }
    I tried omitting different combinations of lines from the "else" section, the results were strange:

    • If I omit all code, except for "int i", or ("int i" and "char path"), the problem does NOT exist. GetOpenFileName does NOT return 0, style 2 appears (see image below)
    • As I mentioned above, If only "int i" is omitted, the code works. the problem does NOT exist. GetOpenFileName does NOT return 0, style 2 appears (see image below)
    • If I omit all code, except for the variable declarations, the problem DOES exist. (no selection window appears, 0 is returned)
    • If I omit all code, except for (i,hFile) OR (i,wmWritten), The selection dialog shows up, but in a different style. (see image below)



    declaring a variable makes the "GetOpenFileName" misbehave-cboard_getopenfilename-png

    Additional info:
    I am using Windows XP, SP 2
    Code::Blocks IDE V10.05, MINGW compiler.


    Note: I had to link an additional in order to use the GetOpenFileName function, the following libraries are linked with my project:

    • libgdi32.a (gdi32)
    • libuser32.a (user32)
    • libkernel32.a (kernel32)
    • libcomdlg32.a

    The first 3 libraries are linked by default when "Win32 template" is selected in the IDE, the last one was manually linked by me(through the IDE) in order to use "GetOpenFileName".


    I also have a side question, are there names for the 2 styles in the image above?
    __


    Thanks in advance.
    Last edited by butteflymentor; 07-06-2012 at 02:11 AM. Reason: replace "manually imported" with "manually linked"

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    While I don't claim my scanning is perfect, I haven't detected any real problems in your code, apart from a nit: str[0] should be initialised to zero, not NULL [although I realise some examples from Microsoft use NULL - goes to show their programmers are human and imperfect too].

    My guess (with about 95% confidence) is that your real problem is in some other code executed before your function is even called. One dubious joy associated with pointer molestation, for example, is that symptoms do not always appear immediately, so some random area of memory is overwritten. That can cause the phenomena you describe (adding an unrelated variable causing the symptom to disappear for no apparent reason) because defining an additional variable affects the layout of memory used by your function and your program, therefore can change the observable effect of writing to memory you shouldn't.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    OPENFILENAME has many more members than the 13 you're initialising at present.

    Start with say
    memset( &fileStruct, 0, sizeof(fileStruct) );
    to at least get some consistency from the answers.

    The Flags member contains all sorts of interesting choices, and you're just passing garbage at the moment.

    Just declaring variables means you align your struct over a different pattern of garbage on the stack, and you get different answers.

    > fileStruct.lpstrTitle=title;
    > fileStruct.lpstrFile=str;
    I'm going to assume that you're actually compiling with UNICODE disabled (ie, ASCII mode) and you're not getting whole pages of warnings regarding casting from one kind of char pointer to another kind of char pointer.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Mar 2012
    Posts
    21
    Very useful information,Thank you guys!
    OPENFILENAME has many more members than the 13 you're initialising at present.
    ...
    The Flags member contains all sorts of interesting choices, and you're just passing garbage at the moment.


    Just declaring variables means you align your struct over a different pattern of garbage on the stack, and you get different answers.
    Interesting, could you please explain that further? Is it necessary to initialize all variables in C structures? Also, I don't believe that not passing flags should cause the symptoms described above.

  5. #5
    Registered User
    Join Date
    Mar 2012
    Posts
    21
    Here is what I learned by searching online, please correct me if I'm wrong:
    When a variable is declared, the stack pointer is advanced forward, but the values of the memory cells are unchanged. so basically, the variable contains garbage until it is given a value, this applies to normal variables and arrays, not just structures.

    I will try initializing the variables correctly, this is probably the problem.

  6. #6
    Registered User
    Join Date
    Mar 2012
    Posts
    21
    Some members are ignored unless there is a specific flag in the "flags" member, I don't need to initialize these, do I?Also, do I need to initialize members which are marked "Reserved" by MSDN?

  7. #7
    Registered User
    Join Date
    Mar 2012
    Posts
    21
    It's working flawlessly now (without initializing ignored and reserved members).
    Thank you guys!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 06-14-2010, 08:49 PM
  2. Replies: 6
    Last Post: 04-05-2010, 09:09 AM
  3. Replies: 2
    Last Post: 05-21-2008, 02:52 PM
  4. Error "makes pointer from integer without a cast"
    By gqchynaboy in forum C Programming
    Replies: 7
    Last Post: 02-25-2005, 11:04 AM
  5. "assignment makes integer from pointer without a cast"
    By Freez3L in forum C Programming
    Replies: 4
    Last Post: 11-04-2002, 04:26 AM

Tags for this Thread