cant get GetOpenFIleName() to return string.

Apr 25, 2014 at 2:22pm
Below is my code.
hEditOPenSiteFile is global and is initialized in WM_CREATE,
below is the code i cant get to work.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
	case IDC_BUTTON_OPENSITE:
{
OPENFILENAME sitesfilesname;
ZeroMemory(&sitesfilesname, sizeof(sitesfilesname));
sitesfilesname.lStructSize = sizeof(OPENFILENAME);
sitesfilesname.hwndOwner = hWnd;
sitesfilesname.nMaxFile = 300;
sitesfilesname.Flags = OFN_EXPLORER;
sitesfilesname.lpstrFilter = NULL;
sitesfilesname.lpstrCustomFilter = NULL;
sitesfilesname.nFilterIndex = 0;
sitesfilesname.lpstrFileTitle = NULL;
sitesfilesname.lpstrInitialDir = NULL;
sitesfilesname.lpstrTitle = NULL;
sitesfilesname.lpstrFilter = L"Source\0*.CSV";
sitesfilesname.nFilterIndex = 1;
if (GetOpenFileName(&sitesfilesname))
{
MessageBox(hEditOpenSiteFile,sitesfilesname.lpstrFile,L"test",MB_OK);
SetWindowText(hEditOpenSiteFile,sitesfilesname.lpstrFile);
}
break;
}


The messagebox and windowtext of the handle both come up blank, i am assuming that they are displaying NULL. I don't understand what i did wrong as MSDN states:
"If the user specifies a file name and clicks the OK button, the return value is nonzero. The buffer pointed to by the lpstrFile member of the OPENFILENAME structure contains the full path and file name specified by the user."

If i replaced the sitesfilename.lpstrFile with L"anytext" the anytext is displayed. UNICODE is the character set.

Thanks for your help in advance.
Apr 25, 2014 at 2:43pm
Your 'lpstFilter' string is missing a null character, you need two of them at the end. I don't know if that is causing your issue though.
Last edited on Apr 25, 2014 at 2:43pm
Apr 25, 2014 at 3:08pm
Added the NULL character and it still behaves the same, i saw no difference between having the NULL and not having the NULL character.
Apr 25, 2014 at 3:17pm
I didn't think it would fix the issue, the documentation says it should be there though. Have you tried explicitly calling "GetOpenFileNameW()"?
Apr 25, 2014 at 3:49pm
if (GetOpenFileNameW(&sitesfilesname) == true)

Dd not work either

SetWindowText(hEditOpenSiteFile,GetOpenFileNameW(&sitesfilesname.lpstrFile));
and
SetWindowText(hEditOpenSiteFile,GetOpenFileNameW(sitesfilesname.lpstrFile));

wont compile, incompatible error. Any other ideas?
Apr 25, 2014 at 3:55pm
Of course that wont compile... "GetOpenFileName()" doesn't return a string. I'm getting the impression that you're a bit fatigued.
Apr 25, 2014 at 4:02pm
I think I found it. You never set the 'lpstrFile' member to point to anything, see the example code for the "GetOpenFileName()" function: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646829(v=vs.85).aspx#open_file
Apr 25, 2014 at 4:27pm
THankl you gfor looking but i dont understand. I read the link but the only thing i see is .lpstrFile[0] = '\0' and as soon as i add the array brackets, [], to sitesfilesname.lpstrFile = '\0'; i get: Access violation writing location 0x00000000.
AM i getting this error becouse i am trying to write to a null locations, what should i do to fix this?
Apr 25, 2014 at 4:35pm
You need to actually read that article. 'lpstrFile' is a pointer, you need to allocate a buffer for it to fill. In the link I posted this is done on Line 11. 'szFile' is an array allocated at Line 3.
Apr 25, 2014 at 4:54pm
Note: If you are using wide characters, you want the Unicode version GetOpenFileNameW.

GetOpenFileName uses TCHARs, and TCHARs are retarded.

Same with SetWindowText. SetWindowText uses TCHARs. SetWindowTextW uses wide chars.

Here's an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// This will return a string with the selected file path
//  or will return an empty string if the user hit cancel.
//
// 'owner' should be the HWND of the window you want to own
//  this dialog, or NULL if you don't care/don't want an owner.
std::wstring getOpenFileName(HWND owner)
{
    wchar_t buffer[MAX_PATH] = "";

    OPENFILENAMEW ofn = {0};

    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = owner;
    ofn.lpstrFilter = L"Text Files\0*.txt\0All Files\0*\0\0";
    ofn.nFilterInex = 1;
    ofn.lpstrFile = buffer;
    ofn.nMaxFile = MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;

    if( !GetOpenFileNameW( &ofn ) )
        return L"";

    return buffer;
}



Or if you want TCHARs:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::basic_string<TCHAR> getOpenFileName(HWND owner)
{
    TCHAR buffer[MAX_PATH] = TEXT("");

    OPENFILENAME ofn = {0};

    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = owner;
    ofn.lpstrFilter = TEXT("Text Files\0*.txt\0All Files\0*\0\0");
    ofn.nFilterInex = 1;
    ofn.lpstrFile = buffer;
    ofn.nMaxFile = MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;

    if( !GetOpenFileName( &ofn ) )
        return TEXT("");

    return buffer;
}
Last edited on Apr 25, 2014 at 4:59pm
Apr 25, 2014 at 5:00pm
I have read it and add:
CHAR szFile[260]; // buffer for file name

and

sitesfilesname.lpstrFile = szFile;
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
// use the contents of szFile to initialize itself.
sitesfilesname.lpstrFile[0] = '\0';

and now i get cvalue of CHAR* can not be assigned to an entry of type LPWSTR.

I tried changing szfile to a lpwstr, did not work
tried seting sitesfielname.lpstrFile to both *szFile and &szFile and those did not work either.
I think i understand about setting the pointer to a value but why wont the MSDN code work?
Apr 25, 2014 at 5:05pm
You're using Unicode so you need to change any instances of 'CHAR' to 'WCHAR'.

EDIT: Disch was kind enough to hand you the answer: http://www.cplusplus.com/forum/general/130259/#msg703215
Last edited on Apr 25, 2014 at 5:06pm
Apr 25, 2014 at 5:13pm
I got it to work, i had to change the char to a WCHAR, these UNICODE semi compatible types is annoying.

Apr 25, 2014 at 5:32pm
I got it to work, i had to change the char to a WCHAR, these UNICODE semi compatible types is annoying.


The problem is you are using TCHARs. And TCHARs are confusing and stupid.

Note: WCHAR is still wrong, since you're probably using the TCHAR version and not the WCHAR version.


If you are using char, use:
OPENFILENAMEA, GetOpenFileNameA, SetWindowTextA

If you are using wchar_t (or WCHAR), use:
OPENFILENAMEW, GetOpenFileNameW, SetWindowTextW

If you are using TCHARs, use:
OPENFILENAME, GetOpenFileName, SetWindowText


Note again that TCHARs are stupid and confusing, and using them properly is extremely difficult. Save yourself a headache and just use with the A/W version of any/all WinAPI functions. Messing with TCHARs is a complete waste of time.

Further reading:
http://www.cplusplus.com/forum/windows/105027/#msg566862
http://www.cplusplus.com/forum/windows/105027/#msg566904
Last edited on Apr 25, 2014 at 5:33pm
Topic archived. No new replies allowed.