@Phil Lyle, MFC is a pretty substantial framework for creating windows desktop applications. If all you really want to do is use an open file dialog then you don't need MFC.
As @Viorel pointed out the GetOpenFileName function is available. Also, the IFileDialog interface is available to create an open file dialog without MFC.
Following is a minimal Win32 sample that demonstrates both methods.
#include <Windows.h>
#include <ShObjIdl.h>
#include <stdio.h>
#include <tchar.h>
#define IDM_OLD_OFD 100
#define IDM_NEW_OFD 200
#define IDM_EXIT 500
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
VOID OnOldOfd(HWND);
VOID OnNewOfd(HWND);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrev, _In_ LPTSTR szCmdLine, _In_ int nShow)
{
WNDCLASS wc{CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInstance,
LoadIcon(NULL, IDI_APPLICATION),
LoadCursor(NULL, IDC_ARROW),
(HBRUSH) (COLOR_WINDOW + 1),
NULL,
_T("OFDCLASS")};
CoInitialize(NULL);
ATOM atom = RegisterClass(&wc);
if (!atom)
{
MessageBox(NULL, _T("RegisterClass failed"), _T("OFDSample"), MB_ICONERROR);
return 1;
}
HMENU hBar = CreateMenu();
HMENU hFile = CreatePopupMenu();
AppendMenu(hFile, MF_STRING, IDM_OLD_OFD, _T("GetOpenFileName..."));
AppendMenu(hFile, MF_STRING, IDM_NEW_OFD, _T("IFileDialog..."));
AppendMenu(hFile, MF_SEPARATOR, 0, 0);
AppendMenu(hFile, MF_STRING, IDM_EXIT, _T("Exit"));
AppendMenu(hBar, MF_POPUP, (UINT_PTR)hFile, _T("File"));
HWND hwnd = CreateWindow(_T("OFDCLASS"), _T("Demo Window"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, hBar, hInstance, NULL);
if (!hwnd)
{
MessageBox(NULL, _T("Window Creation failed"), _T("OFDSample"), MB_ICONERROR);
return 1;
}
ShowWindow(hwnd, nShow);
UpdateWindow(hwnd);
MSG msg{};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
CoUninitialize();
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_COMMAND:
{
switch (LOWORD(wParam)) {
case IDM_OLD_OFD:
OnOldOfd(hwnd);
break;
case IDM_NEW_OFD:
OnNewOfd(hwnd);
break;
case IDM_EXIT:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
VOID OnOldOfd(HWND hwnd)
{
TCHAR szBuffer[MAX_PATH]{};
OPENFILENAME ofn{ sizeof ofn};
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = _T("Text Files (*.txt, *.log)\0*.txt;*.log\0All Files (*.*)\0*.*\0");
ofn.lpstrFile = szBuffer;
ofn.nMaxFile = ARRAYSIZE(szBuffer);
ofn.Flags = OFN_DONTADDTORECENT | OFN_NOCHANGEDIR;
ofn.lpstrDefExt = _T("txt");
if (GetOpenFileName(&ofn))
{
MessageBox(hwnd, ofn.lpstrFile, _T("Selected Item"), MB_ICONINFORMATION);
}
else
{
DWORD err = CommDlgExtendedError();
if (err != 0)
{
TCHAR szMsg[128]{};
_stprintf_s(szMsg, _T("GetOpenFileName error code was 0x%X"), err);
MessageBox(hwnd, szMsg, _T("Error"), MB_ICONERROR);
}
}
}
VOID OnNewOfd(HWND hwnd)
{
IFileDialog* pfd{};
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
if (SUCCEEDED(hr))
{
const COMDLG_FILTERSPEC rgTypes[] = {
{L"Text files", L"*.txt;*.log"},
{L"All files", L"*.*"}
};
FILEOPENDIALOGOPTIONS fos{};
hr = pfd->GetOptions(&fos);
fos |= FOS_DONTADDTORECENT | FOS_NOCHANGEDIR;
hr = pfd->SetOptions(fos);
hr = pfd->SetFileTypes(ARRAYSIZE(rgTypes), rgTypes);
hr = pfd->Show(hwnd);
if (SUCCEEDED(hr))
{
IShellItem* psi{};
hr = pfd->GetResult(&psi);
if (SUCCEEDED(hr))
{
LPWSTR pwszpath{};
hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pwszpath);
MessageBoxW(hwnd, pwszpath, L"Selected Item", MB_ICONINFORMATION);
CoTaskMemFree(pwszpath);
psi->Release();
}
}
else
{
if (hr != HRESULT_FROM_WIN32(ERROR_CANCELLED))
{
WCHAR szMsg[128]{};
swprintf_s(szMsg, L"IFileDialog::Show error code was 0x%X", hr);
MessageBoxW(hwnd, szMsg, L"Error", MB_ICONERROR);
}
}
pfd->Release();
}
}