C++ Question Open File Dialog creates Orbiter.cfg and other files

fred18

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,667
Reaction score
115
Points
78
Hi all,

I am working on my dialog for the Multistage module.

I managed to do most of the items, and I inserted a way to pick files for meshes and configs directly.

BUT

if I use the standard way to open files it works, but then I find inside the directory of the opened files also the folder images, the file Orbiter.log, Orbiter.cfg and Orbiter_NG.cfg :OMG:

I'm too beginner to understand this :shrug:

any idea?

this is the code of the function:

Code:
	OPENFILENAME ofn;       // common dialog box structure
	char szFile[260];       // buffer for file name
	HWND hwnd;              // owner window
	HANDLE hf;              // file handle

	// Initialize OPENFILENAME
	ZeroMemory(&ofn, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = hwnd;
	ofn.lpstrFile = szFile;
	// Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
	// use the contents of szFile to initialize itself.
	ofn.lpstrFile[0] = '\0';
	ofn.nMaxFile = sizeof(szFile);
	ofn.lpstrFilter = "*.msh\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.lpstrInitialDir = NULL;
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

	// Display the Open dialog box. 
	if (GetOpenFileName(&ofn)==TRUE) {
	hf = CreateFile(ofn.lpstrFile, 
			GENERIC_READ,
			0,
			(LPSECURITY_ATTRIBUTES) NULL,
			OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL,
			(HANDLE) NULL);

Note that in the and all i want is the name of the file, nothing else (so the ofn.lpstrFile value).
 
Is this the only thing you do to open the file? Aren't you using somewhere for example SetCurrentDirectory function, which would explain why the files and directories are created by Orbiter in the target (working) directory?
 
Thanks, I just found out that GetOpenFileName automatically calls the SetCurrentDirectory to the folder from which you pick file.

I solved it as follow, I post the entire routine. It also maybe useful for someone.

Code:
char* DevModeDlg::PickFileName(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	OPENFILENAME ofn;       // common dialog box structure
	char szFile[260];       // buffer for file name
	HANDLE hf;              // file handle

	// Initialize OPENFILENAME
	ZeroMemory(&ofn, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = hWnd;
	ofn.lpstrFile = szFile;
	// Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
	// use the contents of szFile to initialize itself.
	ofn.lpstrFile[0] = '\0';
	ofn.nMaxFile = sizeof(szFile);
	ofn.lpstrFilter = "*.*\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.lpstrInitialDir = NULL;
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
				
	// Display the Open dialog box. 
	[B][COLOR="red"]char currentdir[MAX_PATH];
	GetCurrentDirectory(sizeof(currentdir)/sizeof(char),currentdir);[/COLOR][/B]
	
	if (GetOpenFileName(&ofn)==TRUE) {
				hf = CreateFile(ofn.lpstrFile, 
				GENERIC_READ,
				0,
				(LPSECURITY_ATTRIBUTES) NULL,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL,
				(HANDLE) NULL);}
	
        [B][COLOR="Red"]SetCurrentDirectory(currentdir);[/COLOR][/B]

	return szFile;
}

Thanks again
 
Last edited:
You should set the size of your currentdir buffer to 260, which is the maximum length a file path can be under Windows in most circumstances. Else you could have problems.

---------- Post added at 01:26 ---------- Previous post was at 01:24 ----------

Addendum: You should also use sizeof(currentdir)/sizeof(char), which is the same thing for char, but not for int. Not that it matters in this situation, as you could just put how big the buffer is, as you already know how big it is since you just defined it.
 
You should set the size of your currentdir buffer to 260, which is the maximum length a file path can be under Windows in most circumstances. Else you could have problems.

---------- Post added at 01:26 ---------- Previous post was at 01:24 ----------

Addendum: You should also use sizeof(currentdir)/sizeof(char), which is the same thing for char, but not for int. Not that it matters in this situation, as you could just put how big the buffer is, as you already know how big it is since you just defined it.

You are definitely right. I copied that "solution" from the internet but I was experiencing a lot of issues!

now I'll update the first thread with the correct solution! thanks! :tiphat:

---------- Post added at 20:25 ---------- Previous post was at 02:40 ----------

Hi all again,

I don't want to spam the forum with multiple threads about Winapi etc so I'll just post here another question to those kind souls who will have the patience to answer me :hail:

In my project there is a dialog with a tree control and a client area. Depending on the tree control selection the type of child dialog in the client should change.
All this is controlled within a dedicated class.

In order to create multiple child dialogs I thought that it was enough to create an array of HWNDs, then when the WM_INITDIALOG message is passed to the parent dialog to call the CreateDialogParam for each of the type of child dialogs I want to have and then simply play with ShowWindow for each of them.

I did all the setup of the first child dialog and worked perfectly, but now I'm adding the second and the issue is that only the first child defined during dialog initialization works. The second is there somewhere but never get shown. I tried everything with ShowWindow and SetWindowPos but totally without success...

The code snippet is simply:

Code:
switch (uMsg) {
case WM_INITDIALOG: {
				
InitDialog(hWnd,uMsg,wParam,lParam); //This is a function that initializes the Tree Control
hChild[CD_VIEW]=CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_VIEWTXT),hDlg,DlgProcViewTxt,LPARAM(this));
hChild[CD_PLD]= CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_PAYLOADS),hDlg,DlgProcPld,LPARAM(this));
				
return FALSE;

So if I use the above the child dialog hChild[CD_VIEW] appears and works, while hChild[CD_PLD] never gets shown.

If I do the opposite so:


Code:
switch (uMsg) {
case WM_INITDIALOG: {
				
InitDialog(hWnd,uMsg,wParam,lParam); //This is a function that initializes the Tree Control
hChild[CD_PLD]= CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_PAYLOADS),hDlg,DlgProcPld,LPARAM(this));	
 hChild[CD_VIEW]=CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_VIEWTXT),hDlg,DlgProcViewTxt,LPARAM(this));
          
				
return FALSE;

hChild[CD_PLD] works perfectly, while hChild[CD_VIEW] never gets shown...


I'm surely missing something about the usage of CreateDialogParam, does it work only once per class? or something like this?

Thank you very much to anyone that will be so kind to help!

Fred
 
Back
Top