I searching function something like OpenFileDialog on .NET but on win32, i can't find this function on this name on msdn and i remember this function exists.
Can anyone give me name?
Greetings,
I believe you are looking for the GetOpenFileName.
//make sure this is commented out in all code (usually stdafx.h)
// #define WIN32_LEAN_AND_MEAN
#include <windows.h>
OPENFILENAME ofn; // common dialog box structure
TCHAR szFile[260] = { 0 }; // if using TCHAR macros
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hWnd;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = _T("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) == TRUE)
{
// use ofn.lpstrFile
}
Taken from Displaying Open File Dialog using WinApi
Related
I had this code that uses the legacy API function GetOpenFileName
#include <windows.h>
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
OPENFILENAME ofn;
char szFile[260];
HWND hwnd = NULL;
HANDLE hf;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "Txt files (*.txt)\0*.txt\0Task files (*01.*)\0*01.*\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn)==TRUE)
hf = CreateFile(ofn.lpstrFile, GENERIC_READ,
0, (LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
return 0;
}
The filter name "Task files (*01.*)" is correctly shown in the dialog:
enter image description here
I've rewritten the code to use the FileDialog object as follows:
#include <windows.h>
#include <shobjidl.h>
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED |
COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr))
{
IFileOpenDialog *pFileOpen;
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr))
{
COMDLG_FILTERSPEC fileTypes[] =
{
{L"Txt files (*.txt)", L"*.txt"},
{L"Task files (*01.*)", L"*01.*"},
};
hr = pFileOpen->SetFileTypes(ARRAYSIZE(fileTypes), fileTypes);
if (SUCCEEDED(hr))
{
hr = pFileOpen->Show(NULL);
pFileOpen->Release();
}
CoUninitialize();
}
}
return 0;
}
But now the filter name is garbled, as the pattern is appended to it.
enter image description here
Is it a bug in the FileDialog object or am I doing something wrong?
I have one win32 prog where i want to call GetOpenFileName() but every time it got crash and CommDlgExtendedError() return error code as 1008. Please help me out.
char Filestring[MAX_PATH] = "\0";
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFile = (LPWSTR)Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileName(&ofn) == TRUE)
{
}
else
{
int err = CommDlgExtendedError();
}
You are using the TCHAR version of the GetOpenFileName() API, which maps to either the ANSI (GetOpenFileNameA()) or Unicode (GetOpenFileNameW()) API depending on whether UNICODE is defined.
Since ofn.lpstrFile is accepting a LPWSTR (wchar_t*) pointer, expecting it to point at a wchar[] buffer, your project clearly has UNICODE defined. But you are giving it a type-casted pointer to a char[] buffer instead, which has 1/2 the storage space than you are telling the API is available for it to write to.
Your type-cast on the ofn.lpstrFile field is lying to the API. The code is calling the Unicode API, so it will write Unicode data to your char[] buffer, giving you mojibake output, and risking a buffer overflow.
You should use a TCHAR[] buffer instead to match what the API is expecting, eg:
TCHAR Filestring[MAX_PATH] = TEXT("\0");
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileName(&ofn))
{
...
}
else
{
int err = CommDlgExtendedError();
...
}
Otherwise, use the ANSI or Unicode API explicitly, depending on your desired character encoding, eg:
CHAR Filestring[MAX_PATH] = "\0";
OPENFILENAMEA ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileNameA(&ofn))
{
...
}
else
{
int err = CommDlgExtendedError();
...
}
WCHAR Filestring[MAX_PATH] = L"\0";
OPENFILENAMEW ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileNameW(&ofn))
{
...
}
else
{
int err = CommDlgExtendedError();
...
}
I want Sketchup can import muliple files. But unfortunately, Sketchup API dosen't support it. So i created one dll library. It call Window API function: GetOpenFileName for displaying multi-select dialog, get selected file names and display them in formatted string (selected directory | filename1 |filename2...). Then i put it and Win32API.so into Plugin folder of Sketchup. But when i open Sketchup, it display error: Error Loading File GetProcAddress: ShowDialog or ShowDialogA (ShowDialog is one function of my dll )
Here is my code in dllmain.cpp (C++ code)
#define EXPORT _declspec(dllexport)
HWND hDlg = NULL;
wchar_t* buffer = new wchar_t[32768];
EXPORT void ShowDialog(void)
{
OPENFILENAME ofn;
wchar_t szFile[32768];
// Initialize OPENFILENAME
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hDlg;
ofn.lpstrFile = (wchar_t*)szFile;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_ALLOWMULTISELECT | OFN_ENABLESIZING | OFN_EXPLORER;
if(GetOpenFileName(&ofn) == TRUE)
{
if(szFile[ofn.nFileOffset-1] != '\0')
{
wcscpy_s(buffer,sizeof(szFile),szFile);
}
else
{
//Multi-select
wchar_t* p= szFile;
int i =0;
while(*p)
{
wchar_t* temp = new wchar_t[1024];
//Copy p into temp
wcscpy_s(temp,1024,p);
if(i==0)
{
wcscpy_s(buffer,1024,temp);
}
else
{
wcscat_s(buffer,1024,temp);
}
wcscat_s(buffer, sizeof(buffer) * wcslen(buffer), L"|");
i++;
p += lstrlen(p) + 1;
}
}
int len = wcslen(buffer);
buffer[len]='\0';
}
EXPORT void GetResult(char* pString)
{
int len = wcslen(buffer);
for(int i =0 ; i < wcslen(buffer);i++)
{
pString[i] = (char)buffer[i];
}
pString[len]='\0';
}
Here is my script in ruby file.
require 'sketchup.rb'
require "Win32API"
path = Sketchup.find_support_file("\Plugins\\")
#my dll has name MultiUploadProject.dll
mydll = path + "\\MultiUploadProject.dll"
if (!FileTest.exist?( mydll ) )
UI.messagebox(sprintf("MultiUploadProject.dll not found in SketchUp plugins folder: %s\n",mydll))
end
ShowDialog = Win32API.new(mydll,"ShowDialog",["V"],"V")
GetResult = Win32API.new(mydll,"GetResult",["P"],"V")
def load_dialog
ShowDialog.call
string = " " * 32768
GetResult.call(string)
end
I use Visual Studio 2012 to build dll and My Sketchup is Sketchup 8
Any suggestions would be appreciated.
The export needs to be C exports (without C++ name mangling). Try defining the EXPORT macro like this:
#define EXPORT extern "C" _declspec(dllexport)
or define the exported functions inside extern "C"
extern "C" {
// Exported functions here.
}
When I call glGetIntergerv, or any other opengl function, and step through it in gdb, upon reaching it, gdb would skip a few lines and continue stepping later in the code.
Below is the code for loading opengl, and windows. It is the only code that runs before glGetIntergerv, the first opengl call.
HWND window;
HDC dev_context;
HGLRC rend_context;
//Creating the Window
char const *name = "Opengl Test";
HINSTANCE inst = (HINSTANCE)GetModuleHandle(0);
WNDCLASS windowClass;
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
windowClass.lpfnWndProc = (WNDPROC) WndProcedure;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = inst;
windowClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = name;
RegisterClass(&windowClass);
window = CreateWindowEx(dwExStyle, name, name, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 0, 0, NULL, NULL, inst, NULL);
//Context
dev_context = GetDC( window );
std::cout << dev_context << std::endl;
//Get pixel format
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
int nPixelFormat = ChoosePixelFormat(dev_context, &pfd);
SetPixelFormat( dev_context, nPixelFormat, &pfd );
HGLRC temp_rend_context = wglCreateContext( dev_context );
wglMakeCurrent( dev_context, temp_rend_context );
HGLRC (WINAPI *wglCreateContextAttribsARB) (HDC hDC, HGLRC hShareContext, const int *attribList) = (HGLRC (WINAPI *) (HDC hDC, HGLRC hShareContext, const int *attribList)) gl3wGetProcAddress("wglCreateContextAttribsARB");
const int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB*/0, 0};
rend_context = wglCreateContextAttribsARB(dev_context, 0, attribs);
wglMakeCurrent(0,0);
wglDeleteContext(temp_rend_context);
wglMakeCurrent(dev_context, rend_context);
gl3wInit();
int glVersion[2] = {-1, -1};
glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); //First gl call
glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]);
Below is my WndProcedure function:
static LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){
switch(Msg){
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
return 0;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
}
I am using the gl3w library for loading the opengl functions.
It sounds like you have a mismatch either in calling convention or parameter list, or both, which is corrupting the stack enough to screw up the call return address.
Double check that the opengl .h file(s) you're compiling with match the version of the opengl .dll(s) that you're calling. Double check that any conditional defines required for Windows are defined and enabled for the .h file. The norm for calling conventions in Win API calls is STDCALL. If you see no calling convention on the gl functions in your .h file, be suspicious.
I vaguely recall that STDCALL and cdecl calling conventions push the parameters onto the stack in the same order (right to left) but differ in who is responsible for adjusting the stack pointer after the call. I believe STDCALL expects the callee to pop the stack, whereas with cdecl the caller restores the stack pointer after the call returns.
What this means is if the caller is making a cdecl call but the callee is actually STDCALL, the parameters will make it into the call just fine but all hell will break loose on the return. Depending on which way the mismatch runs, either the stack pointer won't be adjusted at all or it will be over adjusted (adjusted twice).
Here is the code I use create a GL context and use GL3 features.
Now I know this is C# but you get the picture. There is no reason to create two GL contexts to use OpenGL3... unless im totally missing what your saying.
void Init(IntPtr handle, bool fullscreen, bool vSync)
{
this.handle = handle;
#if WINDOWS
//Get DC
dc = WGL.GetDC(handle);
WGL.SwapBuffers(dc);
//Set BackBuffer format
WGL.PIXELFORMATDESCRIPTOR pfd = new WGL.PIXELFORMATDESCRIPTOR();
WGL.ZeroPixelDescriptor(ref pfd);
pfd.nVersion = 1;
pfd.dwFlags = WGL.PFD_DRAW_TO_WINDOW | WGL.PFD_SUPPORT_OPENGL | WGL.PFD_DOUBLEBUFFER;
pfd.iPixelType = (byte)WGL.PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cAlphaBits = 8;
pfd.cDepthBits = 16;
pfd.iLayerType = (byte)WGL.PFD_MAIN_PLANE;
unsafe{pfd.nSize = (ushort)sizeof(WGL.PIXELFORMATDESCRIPTOR);}
int pixelFormatIndex = WGL.ChoosePixelFormat(dc, ref pfd);
if (pixelFormatIndex == 0) Debug.ThrowError("Video", "ChoosePixelFormat failed");
if (WGL.SetPixelFormat(dc, pixelFormatIndex, ref pfd) == 0) Debug.ThrowError("Video", "Failed to set PixelFormat");
ctx = WGL.CreateContext(dc);
if (ctx == IntPtr.Zero) Debug.ThrowError("Video", "Failed to create GL context");
if (WGL.MakeCurrent(dc, ctx) == 0) Debug.ThrowError("Video", "Failed to make GL context current");
WGL.Init();//<< load 'wglSwapIntervalEXT'
WGL.SwapInterval(vSync ? 1 : 0);
}
And to load GL extensions:
public const string DLL = "opengl32";
[DllImport(DLL, EntryPoint = "wglGetProcAddress", ExactSpelling = true)]
private static extern IntPtr getProcAddress(string procedureName);
how to convert char to LPCTSTR in vc++
I am using MVC.
QByteArray qBary;
qBary.append(temp);
char toChar[512];
for(int ii = 0; ii < 512; ii++)
{
toChar[ii] = qBary[ii];
if(qBary[ii] == '\0')
{
break;
}
}
SHFILEOPSTRUCT sf;
memset(&sf, 0, sizeof(sf));
sf.hwnd = 0;
sf.wFunc = FO_COPY;
sf.pFrom = toChar; // error occurring here
if you are using MFC (is your label supposed to be MFC instead of MVC?):
char name[] = "your name";
CString sName(name);
LPCTSTR lpszName = sName;
if you are using Qt, take a look at QString and QByteArray
// (1)
QString filename;
LPCWSTR lpszFilename = filename.utf16(); // alternatively, .unicode()
// alternatively, (2)
QByteArray qBA("abcdef.txt");
QString qString(qBA);
LPCWSTR lpszFileName = qString.utf16(); // or, .unicode() , .utf8()
...
sf.pFrom = lpszFileName;