I am simply trying to make a C++ dll, which opens a folder and allows user to select one of the files in this directory (via a mouse click), then the path of this file shall be passed to another program (which uses this dll).
I am using Visual Studio Express 2017.
Operating system is windows.
I am total newbie in C++ (but I have good programming experience in C programming language).
"As a first step", I am trying to write a simple C++ program which can perform the functionality mentioned above.
But when I tried to use the code from "closed account (j3Rz8vqX)", it throws an exception at the function "GetOpenFileName".
The exception says --> Unhandled exception at 0x75876344 (comdlg32.dll) in Open_folder_select_file.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC.
The easiest issue I can spot is that you're returning a pointer to a local variable (szFileName), so that's undefined behavior. You might want to pass szFileName[MAX_PATH] buffer in as a paramater.
C++ also forbids pointing a non-const char* to a string literal, so you should make your first two char* variables be const char*.
You should really compile with warnings enabled.
main.cpp:9:10: warning: address of local variable 'szFileName' returned [-Wreturn-local-addr]
char szFileName[MAX_PATH];
I tried your code, and it runniny on my PC, and I also realized that the exception was being thrown because I commented out these 2 lines from the code:
If you have Unicode enabled (you do), then c-style casting a char* to a wchar* might be part of the problem.
I can't check right now, but try changing all your chars to TCHARs and add _T("text") around all your string literals.
Shouldn't need to do dubious casting.
Also, for the GetOpenFileName call, you can rework the logic to see if what comdlg errors happened.
msdn wrote:
If the user cancels or closes the Open dialog box or an error occurs, the return value is zero. To get extended error information, call the CommDlgExtendedError function, which can return one of the following values.
unicde strings and ascii strings won't compare equally so if looking for a specific file, it won't match -- you compare something like "f i l e . t x t" against "file.txt" for example (not exactly, the spaces are really zero null chars). you have to promote the ascii text to unicode then compare them.
You shouldn't even think about not using Unicode these days. First you need to understand the difference between multibyte, unicode and "TCHAR"s, which is either "char" or "wchar_t" in windows.
Yopu should use wchar_t directly always and functions specificcally ended in "W" in win32 API ( there are APIs which ONLY support Unicode ). These are not windows 95 days.
Here is an alternate "canned" routine, that I copied directly from Microsoft's documentation. It creates the standard file open dialog box. I modified it slightly, to be used as as function:
This should give you the functionality that you need. You can name the function anything that you want. Same with the string that you use to hold the file name and path. "MAX_PATH" is a Microsoft defined macro. Currently, the value is 260. If you're curious, here is the MS page where I found the code:
Just to confirm, to make a string use wide char, I just put an 'L' prefix before it, am I correct?
for example constwchar_t myDir = L"C:\\c_plus_plus_trial"
@anachronon, many thanks for the code and the link, I shall try it today.
L is NOT unicode, its wide (16 bits) char type conversion.
You need to read the material a few times to get this down. Its very confusing because a bunch of different solutions to the problem were produced in short order between the ascii or 1-byte code days and the unicode days. I am a little rusty on this (I am not doing anything major in c++ now); L may produce valid unicode strings but I think the behavior of L depends on your compiler settings (?) or locale settings(?) somewhat. See what you can make of https://stackoverflow.com/questions/6384118/what-does-the-l-in-front-a-string-mean-in-c
You shouldn't even think about not using Unicode these days.
I mostly agree, esp for UIs, but...
-- there is nothing wrong with using ascii when it is appropriate. It would be a big mess to write my personal work tools, mostly 20-50 c++ lines xml crawlers, for unicode when the files are in ascii char set format. It is much harder to work with, and there are times and places where it isn't helpful to go there.
Win32 API has Windows specific functions for file system management. With C++17 there is the <filesystem> library that works with any OS. https://en.cppreference.com/w/cpp/filesystem
But I was only able to find a way to get a list of the files in a directory, using the <filesystem> library.
But is there a way using the <filesystem> library to open the directory in a new window, and allow the user to select a file in this directory (using mouse select), and then a path to this file would be returned?
But is there a way using the <filesystem> library to open the directory in a new window, and allow the user to select a file in this directory (using mouse select), and then a path to this file would be returned?
But is there a way using the <filesystem> library to open the directory in a new window, and allow the user to select a file in this directory (using mouse select), and then a path to this file would be returned?
The "canned" function that I posted above, should do just that. Don't forget to add the #include item that I mentioned at the bottom. Notes on calling the function are also described at the bottom. Once you have called that function, the string variable "szFilePath[]" will contain the complete path to the file.