Display image in Visual Studio not saved as resource - c++

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);
}
}

Related

Call to GetOpenFileNameA causes common dialog error 2

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);
}
}

Browsing for file location and saving wstring to file

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

GetSaveFileName can't open user's temp-dir

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.

OpenFileDialog class not working properly in c++

I want to show the file name that is opened by OpenFileDialog but it sends the wrong text into title bar. I hace changed the character set of the project but it did not help. here is my code :
OpenFileDialog .h :
class OpenFileDialog
{
public:
OpenFileDialog(){};
void CreateOpenFileDialog(HWND hWnd, LPCWSTR Title, LPCWSTR InitialDirectory, LPCWSTR Filter, int FilterIndex);
~OpenFileDialog(){};
LPCWSTR result=L"";
};
OpenFileDialog .cpp :
void OpenFileDialog::CreateOpenFileDialog(HWND hWnd, LPCWSTR Title, LPCWSTR InitialDirectory, LPCWSTR Filter, int FilterIndex)
{
OPENFILENAME ofn;
TCHAR szFile[MAX_PATH];
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
ofn.hwndOwner = hWnd;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = Filter;
ofn.nFilterIndex = FilterIndex;
ofn.lpstrTitle = Title;
ofn.lpstrInitialDir = InitialDirectory;
ofn.lpstrFileTitle = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn))
{
result = ofn.lpstrFile;
}
else
{
result = L"Empty";
}
}
and in windows procedure in WM_COMMAND :
case WM_COMMAND:
{
if (LOWORD(wParam) == ID_FILE_OPEN)
{
OpenFileDialog ofd;
ofd.CreateOpenFileDialog(hwnd, L"Test", L"C:\\", L"All files(*.*)\0*.*\0TextFiles(*.txt)\0*.txt\0", 2);
SetWindowText(hwnd, ofd.result);
}
break;
}
thanks alot.
In your function CreateOpenFileDialog(), the buffer for storing the file name is a local array szFile[MAX_PATH]. You initialize the lpstrFile = szFile in the ofn structure, making sure that the GetOpenFileName() puts the result of user entry at the right place.
The problem is that as soon as you return from CreateOpenFileDialog(), its local variables are destroyed, including the buffer containing the file name. Hence, the resultpointer that you've set with result = ofn.lpstrFile; then points to an invalid memory location.
You can solve this by allocating the buffer directly in result in the OpenFileDialog constructor (or making it an array), and using this pointer directly with ofn.lpstrFile = buffer;

GetOpenFileName triggers breakpoint

I'm trying to call GetOpenFileName like this:
int main(int argc, char* argv[])
{
OPENFILENAME ofn; // common dialog box structure
wchar_t szFile[260]; // buffer for file name
HWND hwnd; // owner window
HANDLE hf; // file handle
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
wchar_t title[500]; // to hold title
GetConsoleTitle( title, 500 );
HWND hwndConsole = FindWindow( NULL, title );
ofn.hwndOwner = hwndConsole;
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"All\0*.*\0Text\0*.TXT\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);
The prog stops (message: example.exe has triggered a breakpoint(not one I placed)) at "if (GetOpenFileName(&ofn)==TRUE)" When I break i get a message that no source is available.
If I do not break and just press continue, the dialog box pops up and works as expected. What am I doing wrong?
I just noticed that it works without problems in release mode...
One possible issue:
ofn.nMaxFile should be the number of characters, not the size in bytes of the buffer. Try this instead:
ofn.nMaxFile = sizeof(szFile) / sizeof(wchar_t);