此文介绍如何打开本地文本文件、文件夹对话框
方法一:
效果图:



源码
#include <iostream>
#include <objbase.h>
#include <ShObjIdl.h>
using namespace std;
int main()
{
cout << "start=====" << endl;
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED |
COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr))
{
IFileOpenDialog* pFileOpen;
// Create the FileOpenDialog object.
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr))
{
// Show the Open dialog box.
hr = pFileOpen->Show(NULL);
// Get the file name from the dialog box.
if (SUCCEEDED(hr))
{
IShellItem* pItem;
hr = pFileOpen->GetResult(&pItem);
if (SUCCEEDED(hr))
{
PWSTR pszFilePath;
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
// Display the file name to the user.
if (SUCCEEDED(hr))
{
MessageBoxW(NULL, pszFilePath, L"File Path", MB_OK);
CoTaskMemFree(pszFilePath);
}
pItem->Release();
}
}
pFileOpen->Release();
}
CoUninitialize();
}
return 0;
}
出现错误
1、2、IID_IFileOpenDialog' was not declared in this scope
将
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
改为
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFileOpen));
2、 error: invalid use of incomplete type 'IFileDialog {aka struct IFileDialog}'
原因:默认情况下,MinGW将NTDDI_VERSION宏的值设置为0x05020000 (NTDDI_WS03),这会禁用shobjidl.h中的IFileDialog定义。宏的值必须至少为0x06000000 (NTDDI_VISTA)才能启用定义。下面列出了这些宏的可能值及其含义:
将以下内容放在源文件的开头(在include之前)应该可以修复编译错误:
#define NTDDI_VERSION 0x0A000006 //NTDDI_WIN10_RS5
#define _WIN32_WINNT 0x0A00 // _WIN32_WINNT_WIN10, the _WIN32_WINNT macro must also be defined when defining NTDDI_VERSION
如果您没有链接所需的库,则可能仍然存在链接错误。你列出的程序需要ole32.dll和uuid.dll,所以编译命令看起来像这样:

方法二:
效果图:
选择要尝试的文件对话框类型

打开对话框效果




源码
ShellHelpers.h
#pragma once
#pragma once
#define STRICT_TYPED_ITEMIDS // in case you do IDList stuff you want this on for better type saftey
#define UNICODE 1
#include <windows.h>
#include <windowsx.h> // for WM_COMMAND handling macros
#include <shlobj.h> // shell stuff
#include <shlwapi.h> // QISearch, easy way to implement QI
#include <propkey.h>
#include <propvarutil.h>
#include <strsafe.h>
#include <objbase.h>
#pragma comment(lib, "shlwapi.lib") // link to this
#pragma comment(lib, "comctl32.lib") // link to this
#pragma comment(lib, "propsys.lib") // link to this
// set up common controls v6 the easy way
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
__inline HRESULT ResultFromKnownLastError() { const DWORD err = GetLastError(); return err == ERROR_SUCCESS ? E_FAIL : HRESULT_FROM_WIN32(err); }
// map Win32 APIs that follow the return BOOL/set last error protocol
// into HRESULT
//
// example: MoveFileEx()
__inline HRESULT ResultFromWin32Bool(BOOL b)
{
return b ? S_OK : ResultFromKnownLastError();
}
#if (NTDDI_VERSION >= NTDDI_VISTA)
__inline HRESULT ShellExecuteItem(HWND hwnd, PCWSTR pszVerb, IShellItem* psi)
{
// how to activate a shell item, use ShellExecute().
PIDLIST_ABSOLUTE pidl;
HRESULT hr = SHGetIDListFromObject(psi, &pidl);
if (SUCCEEDED(hr))
{
SHELLEXECUTEINFO ei = { sizeof(ei) };
ei.fMask = SEE_MASK_INVOKEIDLIST;
ei.hwnd = hwnd;
ei.nShow = SW_NORMAL;
ei.lpIDList = pidl;
ei.lpVerb = pszVerb;
hr = ResultFromWin32Bool(ShellExecuteEx(&ei));
CoTaskMemFree(pidl);
}
return hr;
}
__inline HRESULT GetItemFromView(IFolderView2* pfv, int iItem, REFIID riid, void** ppv)
{
*ppv = NULL;
HRESULT hr = S_OK;
if (iItem == -1)
{
hr = pfv->GetSelectedItem(-1, &iItem); // Returns S_FALSE if none selected
}
if (S_OK == hr)
{
hr = pfv->GetItem(iItem, riid, ppv);
}
else
{
hr = E_FAIL;
}
return hr;
}
// set the icon for your window using WM_SETICON from one of the set of stock system icons
// caller must call ClearDialogIcon() to free the HICON that is created
__inline void SetDialogIcon(HWND hdlg, SHSTOCKICONID siid)
{
SHSTOCKICONINFO sii = { sizeof(sii) };
if (SUCCEEDED(SHGetStockIconInfo(siid, SHGFI_ICON | SHGFI_SMALLICON, &sii)))
{
SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)sii.hIcon);
}
if (SUCCEEDED(SHGetStockIconInfo(siid, SHGFI_ICON | SHGFI_LARGEICON, &sii)))
{
SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM)sii.hIcon);
}
}
#endif
// free the HICON that was set using SetDialogIcon()
__inline void ClearDialogIcon(HWND hdlg)
{
DestroyIcon((HICON)SendMessage(hdlg, WM_GETICON, ICON_SMALL, 0));
DestroyIcon((HICON)SendMessage(hdlg, WM_GETICON, ICON_BIG, 0));
}
__inline HRESULT SetItemImag

本文提供两个C++代码示例,演示如何使用WindowsAPI中的CoCreateInstance和IFileOpenDialog接口来打开本地文件和文件夹对话框。方法一涉及解决编译错误,方法二包含更丰富的ShellHelpers头文件,包含了处理文件和文件夹选择的辅助函数。这两个方法都展示了如何在用户选择文件后进行操作。
最低0.47元/天 解锁文章

1万+

被折叠的 条评论
为什么被折叠?



