I use a similar function to get the path and the filename, which I want to use to save a file on a Windows 8.1 machine:
void TestFunc()
{
OPENFILENAME ofn;
WCHAR szFileName[MAX_PATH] = L"C:\\Users\\biber\\AppData\\Local\\temp\\test.txt";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = (LPWSTR)szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = (LPCWSTR)L"txt";
GetSaveFileName(&ofn);
return ;
}
The problem is, that the SaveFileDialog doesn't show me initial the Temp-Path. If I change the szFileName to another path than the %TEMP%, it works.
It doesn't work with the temp path.
Related
I am making an app with ImGUI to choose pictures. So I need to call "OPENFILENAME" to call a dialog window, and there is my code to do it:
OPENFILENAME ofn;
::memset(&ofn, 0, sizeof(ofn));
TCHAR f1[MAX_PATH];
f1[0] = 0;
ofn.lStructSize = sizeof(ofn);
ofn.nFilterIndex = 2;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFile = f1;
ofn.Flags = OFN_FILEMUSTEXIST;
if (::GetOpenFileName(&ofn) != FALSE)
{
show_path = TRUE;
}
But later I need to have a path to image, which I chose in char type and lpstrFile is a THCAR type. I found anything to make THCAR into char.
Am I doing choosing file in right way, and if yes, how can I get in usual char format a path to file?
I am using GetOpenFileName() to get the file path, and then CopyFile() to copy the file to the same directory with a different file name.
By using GetLastError(), I am getting an error code:
0x2 - The system cannot find the file specified.
But when I used MessageBox() to see the file names, it showed the correct file names.
In addition to this, I have also tried to StrTrim() the file name, but still it did not work.
I am using Borland C++Builder 6.0.
CODE
OPENFILENAME ofn;
char szFile[260];
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = Form1->Handle;
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All\0*.*\0Text\0*.txt\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = 0;
GetOpenFileName(&ofn);
LPSTR FileName;
FileName = ofn.lpstrFile;
MessageBox (Form1->Handle, FileName, "File Name", MB_OK);
MessageBox (Form1->Handle, strcat(FileName, ".newfile"), "New File Name", MB_OK);
CopyFile(FileName, strcat(FileName,".newfile"), false);
EDITED CODE
I have tried using two variables, but it is still not working. Can anyone suggest a correction?
LPSTR FileName;
LPSTR NewFileName;
FileName = ofn.lpstrFile;
NewFileName = FileName;
strcat(NewFileName, ".newfile");
MessageBox (Form1->Handle, FileName, "File Name", MB_OK);
MessageBox (Form1->Handle, NewFileName, "New File Name", MB_OK);
CopyFile(FileName, NewFileName, false);
WORKING CODE
The below code works, but I had to add a Text Box / Edit Control. Is there way to do it without adding any extra control?
LPSTR FileName;
AnsiString NewFileName;
FileName = ofn.lpstrFile;
Edit1->Text = FileName;
NewFileName = Edit1->Text + ".bak";
MessageBox (Form1->Handle, FileName, "File Name", MB_OK);
MessageBox (Form1->Handle, NewFileName.c_str(), "New File Name", MB_OK);
You are using a single buffer for both arguments of CopyFile(), and you are appending the new extension to that buffer, so of course CopyFile() is not going to find the file to copy.
You need to use two separate buffers for the two arguments of CopyFile(), eg:
TCHAR szSrcFile[MAX_PATH];
TCHAR szDstFile[MAX_PATH+12];
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = Form1->Handle;
ofn.lpstrFile = szSrcFile;
ofn.lpstrFile[0] = TEXT('\0');
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFilter = TEXT("All\0*.*\0Text\0*.txt\0");
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn))
{
lstrcpy(szDstFile, szSrcFile);
lstrcat(szDstFile, TEXT(".newfile"));
MessageBox(Form1->Handle, szSrcFile, TEXT("File Name"), MB_OK);
MessageBox(Form1->Handle, szDstFile, TEXT("New File Name"), MB_OK);
CopyFile(szSrcFile, szDstFile, FALSE);
}
That being said, since you are using Borland's VCL framework, you should use the TOpenDialog component instead of GetOpenFileName() directly, and then you can use String variables for easy concatenation:
// these properties can also be set at design-time instead...
OpenDialog1->Filter = "All|*.*|Text|*.txt";
OpenDialog1->FilterIndex = 1;
OpenDialog1->Options = TOpenOptions() << ofPathMustExist << ofFileMustExist;
if (OpenDialog1->Execute())
{
String SrcFile = OpenDialog1->FileName;
String DstFile = SrcFile + ".newfile";
CopyFileA(SrcFile.c_str(), DstFile.c_str(), FALSE);
}
I'm trying to open a dialog box using GetOpenFileNameA. However, the dialog does not open. Instead, I get a nice CommDlgError 2. Searching Google and StackOverflow for this error did not produce any helpful results.
Confusingly, this code works on a school computer that also uses Visual Studio, albeit a different version.
Note: All variables not declared in this block of code are "global" variables that are only accessible within the main code module.
void GetInputFile()
{
char szFileNameIN[MAX_PATH];
char szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAME ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = LPWSTR("Any File\0*.*\0");
ofn.lpstrFile = LPWSTR(fInputPath);
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = LPWSTR(szFileNameIN);
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = LPWSTR("Select an input File");
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileNameA(LPOPENFILENAMEA(&ofn))) // user selected an input file
{
}
else {
// Get error
TCHAR error[MAX_LOADSTRING];
wsprintf(error,TEXT("%i"),CommDlgExtendedError());
MessageBox(NULL,error,TEXT("ERROR"),MB_OK);
}
}
Those awful (LPWSTR) casts tell me that you are compiling with UNICODE defined, so the OPENFILENAME struct you are using is actually OPENFILENAMEW; given that you are using GetOpenFileNameA, you have to use OPENFILENAMEA (or use straight GetOpenFileName with wide strings).
(and remember that, as a rule of thumb, if you have to cast pointers to/from anything different than void * and similar, you are probably doing something wrong; adding pointer casts will only silence the compiler, not make the error go away)
You are using the TCHAR version of OPENFILENAME. Since you are assigning Unicode string pointers to its fields, that means your project is being compiled with UNICODE defined, so TCHAR maps to wchar_t and OPENFILENAME maps to OPENFILENAMEW. But you are using ANSI character buffers and the ANSI version of GetOpenFileName(), and using incorrect type-casts all over the place.
So get rid of all the type-casts, and then either:
use proper TCHAR types and APIs for everything:
void GetInputFile()
{
TCHAR szFileNameIN[MAX_PATH];
TCHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAME ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = TEXT("Any File\0*.*\0");
ofn.lpstrFile = fInputPath; // must be TCHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = TEXT("Select an input File");
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn)) // user selected an input file
{
}
else
{
// Get error
TCHAR error[MAX_LOADSTRING];
wsprintf(error, TEXT("%i"), CommDlgExtendedError());
MessageBox(NULL, error, TEXT("ERROR"), MB_OK);
}
}
use proper CHAR/WCHAR types and APIs for everything:
void GetInputFile()
{
WCHAR szFileNameIN[MAX_PATH];
WCHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAMEW ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = L"Any File\0*.*\0";
ofn.lpstrFile = fInputPath; // must be WCHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = L"Select an input File";
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileNameW(&ofn)) // user selected an input file
{
}
else
{
// Get error
WCHAR error[MAX_LOADSTRING];
wsprintfW(error, L"%i", CommDlgExtendedError());
MessageBoxW(NULL, error, L"ERROR", MB_OK);
}
}
void GetInputFile()
{
CHAR szFileNameIN[MAX_PATH];
CHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAMEA ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = "Any File\0*.*\0";
ofn.lpstrFile = fInputPath; // must be CHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = "Select an input File";
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileNameA(&ofn)) // user selected an input file
{
}
else
{
// Get error
CHAR error[MAX_LOADSTRING];
wsprintfA(error, "%i", CommDlgExtendedError());
MessageBoxA(NULL, error, "ERROR", MB_OK);
}
}
I am trying to create a file dialog where the user selects an existing file or create a new one by selecting a location and entering a name. The browsing works fine, but when I try to save the file, it gives me the following error
fail: file != NULL.
I also have to convert the text that is meant to be written to the file from std::wstring to char *, hence the sprint. I can't figure out what I am doing wrong.
Below is the code I am currently working with:
HMODULE hModule = GetModuleHandleW(NULL);
OPENFILENAME ofn;
char szFile[260]; // buffer for file name
HWND hwnd = NULL; // owner window
HANDLE hf; // file handle
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrTitle = TEXT("Select a location to save the information");
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = TEXT("All\0*.*\0Text\0*.TXT\0");
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if(GetSaveFileName(&ofn)==TRUE)
{
wchar_t hostName[2048] = L"";
DWORD sz = 2048;
hf = CreateFile(ofn.lpstrFile, GENERIC_READ,
0, (LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
(HANDLE)NULL);
char * buffer = new char[242];
//sprintf(buffer, "%ls", hostInfo.c_str());
_snprintf_s(buffer,242, _TRUNCATE, "%ls", hostInfo.c_str());
std::ofstream stream(ofn.lpstrFile, std::ofstream::binary);
stream.write(buffer, 243);
//delete[] buffer;
stream.close();
}
EDIT:
Found the problem. I did not set the pointer for lpstrFile resulting in the selected path being NULL hence the File != NULL assert fail
I am trying to display an image, the URL of which I've loaded via GetOpenFilename. This isn't in itself the problem, I have also tried simply copying and pasting the URL of an existing image from a resource file into the LoadBitmap function, and the HBITMAP I'm assigning is NULL. How can I make this work?
void GetUserSprite(HWND hwnd, HBITMAP &Image, HBITMAP &Mask)
{
using namespace std;
OPENFILENAME ofn;
char szFileName[MAX_PATH + 1];
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = "Bitmaps (*.JPG, *.BMP, *.DIB, *.gif, *.JPEG, *.jpe, *.png)\0*.jpg;*.bmp;*.jpeg;*.png";
ofn.lpstrFile = szFileName;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
ofn.lpstrDefExt = "bmp";
if(GetOpenFileName(&ofn))
{
bDefaultSprite = false;
strImageURL = szFileName;
Image = LoadBitmap(GetModuleHandle(NULL), strImageURL.c_str());
if (Image == NULL)
{
MessageBox(hwnd, "Well, that sucks...", "", NULL);
}
Mask = CreateBitmapMask(Image, RGB(0,0,0));
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
}
}