📄 atldlgs.h
字号:
}
HRESULT GetFileTitle(LPWSTR lpstrFileTitle, int cchLength)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg != NULL);
ATL::CComPtr<IShellItem> spItem;
HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
if(SUCCEEDED(hRet))
hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISPLAY, lpstrFileTitle, cchLength);
return hRet;
}
#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
HRESULT GetFilePath(_CSTRING_NS::CString& strFilePath)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg != NULL);
ATL::CComPtr<IShellItem> spItem;
HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
if(SUCCEEDED(hRet))
hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPATH, strFilePath);
return hRet;
}
HRESULT GetFileTitle(_CSTRING_NS::CString& strFileTitle)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg != NULL);
ATL::CComPtr<IShellItem> spItem;
HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
if(SUCCEEDED(hRet))
hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISPLAY, strFileTitle);
return hRet;
}
#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
// Helpers for IShellItem
static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN type, LPWSTR lpstr, int cchLength)
{
ATLASSERT(pShellItem != NULL);
LPWSTR lpstrName = NULL;
HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName);
if(SUCCEEDED(hRet))
{
if(lstrlenW(lpstrName) < cchLength)
{
SecureHelper::strcpyW_x(lpstr, cchLength, lpstrName);
}
else
{
ATLASSERT(FALSE);
hRet = DISP_E_BUFFERTOOSMALL;
}
::CoTaskMemFree(lpstrName);
}
return hRet;
}
#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN type, _CSTRING_NS::CString& str)
{
ATLASSERT(pShellItem != NULL);
LPWSTR lpstrName = NULL;
HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName);
if(SUCCEEDED(hRet))
{
str = lpstrName;
::CoTaskMemFree(lpstrName);
}
return hRet;
}
#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
// Implementation
void _Advise(DWORD& dwCookie)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg != NULL);
HRESULT hRet = pT->m_spFileDlg->Advise((IFileDialogEvents*)this, &dwCookie);
ATLVERIFY(SUCCEEDED(hRet));
}
void _Unadvise(DWORD dwCookie)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg != NULL);
HRESULT hRet = pT->m_spFileDlg->Unadvise(dwCookie);
ATLVERIFY(SUCCEEDED(hRet));
}
void _Init(LPCWSTR lpszFileName, DWORD dwOptions, LPCWSTR lpszDefExt, const COMDLG_FILTERSPEC* arrFilterSpec, UINT uFilterSpecCount)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg != NULL);
HRESULT hRet = E_FAIL;
if(lpszFileName != NULL)
{
hRet = pT->m_spFileDlg->SetFileName(lpszFileName);
ATLASSERT(SUCCEEDED(hRet));
}
hRet = pT->m_spFileDlg->SetOptions(dwOptions);
ATLASSERT(SUCCEEDED(hRet));
if(lpszDefExt != NULL)
{
hRet = pT->m_spFileDlg->SetDefaultExtension(lpszDefExt);
ATLASSERT(SUCCEEDED(hRet));
}
if(arrFilterSpec != NULL && uFilterSpecCount != 0U)
{
hRet = pT->m_spFileDlg->SetFileTypes(uFilterSpecCount, arrFilterSpec);
ATLASSERT(SUCCEEDED(hRet));
}
}
// Implementation - IUnknown interface
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
{
if(ppvObject == NULL)
return E_POINTER;
T* pT = static_cast<T*>(this);
if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IFileDialogEvents))
{
*ppvObject = (IFileDialogEvents*)pT;
// AddRef() not needed
return S_OK;
}
return E_NOINTERFACE;
}
virtual ULONG STDMETHODCALLTYPE AddRef()
{
return 1;
}
virtual ULONG STDMETHODCALLTYPE Release()
{
return 1;
}
// Implementation - IFileDialogEvents interface
virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFileOk(IFileDialog* pfd)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
pfd; // avoid level 4 warning
return pT->OnFileOk();
}
virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChanging(IFileDialog* pfd, IShellItem* psiFolder)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
pfd; // avoid level 4 warning
return pT->OnFolderChanging(psiFolder);
}
virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChange(IFileDialog* pfd)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
pfd; // avoid level 4 warning
return pT->OnFolderChange();
}
virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnSelectionChange(IFileDialog* pfd)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
pfd; // avoid level 4 warning
return pT->OnSelectionChange();
}
virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnShareViolation(IFileDialog* pfd, IShellItem* psi, FDE_SHAREVIOLATION_RESPONSE* pResponse)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
pfd; // avoid level 4 warning
return pT->OnShareViolation(psi, pResponse);
}
virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnTypeChange(IFileDialog* pfd)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
pfd; // avoid level 4 warning
return pT->OnTypeChange();
}
virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnOverwrite(IFileDialog* pfd, IShellItem* psi, FDE_OVERWRITE_RESPONSE* pResponse)
{
T* pT = static_cast<T*>(this);
ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
pfd; // avoid level 4 warning
return pT->OnOverwrite(psi, pResponse);
}
// Overrideables - Event handlers
HRESULT OnFileOk()
{
return E_NOTIMPL;
}
HRESULT OnFolderChanging(IShellItem* /*psiFolder*/)
{
return E_NOTIMPL;
}
HRESULT OnFolderChange()
{
return E_NOTIMPL;
}
HRESULT OnSelectionChange()
{
return E_NOTIMPL;
}
HRESULT OnShareViolation(IShellItem* /*psi*/, FDE_SHAREVIOLATION_RESPONSE* /*pResponse*/)
{
return E_NOTIMPL;
}
HRESULT OnTypeChange()
{
return E_NOTIMPL;
}
HRESULT OnOverwrite(IShellItem* /*psi*/, FDE_OVERWRITE_RESPONSE* /*pResponse*/)
{
return E_NOTIMPL;
}
};
///////////////////////////////////////////////////////////////////////////////
// CShellFileOpenDialogImpl - implements new Shell File Open dialog
template <class T>
class ATL_NO_VTABLE CShellFileOpenDialogImpl : public CShellFileDialogImpl< T >
{
public:
ATL::CComPtr<IFileOpenDialog> m_spFileDlg;
CShellFileOpenDialogImpl(LPCWSTR lpszFileName = NULL,
DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST,
LPCWSTR lpszDefExt = NULL,
const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
UINT uFilterSpecCount = 0U)
{
HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileOpenDialog);
if(SUCCEEDED(hRet))
_Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount);
}
IFileOpenDialog* GetPtr()
{
return m_spFileDlg;
}
};
///////////////////////////////////////////////////////////////////////////////
// CShellFileOpenDialog - new Shell File Open dialog without events
class CShellFileOpenDialog : public CShellFileOpenDialogImpl<CShellFileOpenDialog>
{
public:
CShellFileOpenDialog(LPCWSTR lpszFileName = NULL,
DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST,
LPCWSTR lpszDefExt = NULL,
const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
UINT uFilterSpecCount = 0U) : CShellFileOpenDialogImpl<CShellFileOpenDialog>(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount)
{ }
// Implementation (remove _Advise/_Unadvise code using template magic)
void _Advise(DWORD& /*dwCookie*/)
{ }
void _Unadvise(DWORD /*dwCookie*/)
{ }
};
///////////////////////////////////////////////////////////////////////////////
// CShellFileSaveDialogImpl - implements new Shell File Save dialog
template <class T>
class ATL_NO_VTABLE CShellFileSaveDialogImpl : public CShellFileDialogImpl< T >
{
public:
ATL::CComPtr<IFileSaveDialog> m_spFileDlg;
CShellFileSaveDialogImpl(LPCWSTR lpszFileName = NULL,
DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT,
LPCWSTR lpszDefExt = NULL,
const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
UINT uFilterSpecCount = 0U)
{
HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileSaveDialog);
if(SUCCEEDED(hRet))
_Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount);
}
IFileSaveDialog* GetPtr()
{
return m_spFileDlg;
}
};
///////////////////////////////////////////////////////////////////////////////
// CShellFileSaveDialog - new Shell File Save dialog without events
class CShellFileSaveDialog : public CShellFileSaveDialogImpl<CShellFileSaveDialog>
{
public:
CShellFileSaveDialog(LPCWSTR lpszFileName = NULL,
DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT,
LPCWSTR lpszDefExt = NULL,
const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
UINT uFilterSpecCount = 0U) : CShellFileSaveDialogImpl<CShellFileSaveDialog>(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount)
{ }
// Implementation (remove _Advise/_Unadvise code using template magic)
void _Advise(DWORD& /*dwCookie*/)
{ }
void _Unadvise(DWORD /*dwCookie*/)
{ }
};
#endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
///////////////////////////////////////////////////////////////////////////////
// CFolderDialogImpl - used for browsing for a folder
#ifndef _WIN32_WCE
template <class T>
class ATL_NO_VTABLE CFolderDialogImpl
{
public:
BROWSEINFO m_bi;
LPCTSTR m_lpstrInitialFolder;
LPCITEMIDLIST m_pidlInitialSelection;
bool m_bExpandInitialSelection;
TCHAR m_szFolderDisplayName[MAX_PATH];
TCHAR m_szFolderPath[MAX_PATH];
LPITEMIDLIST m_pidlSelected;
HWND m_hWnd; // used only in the callback function
// Constructor
CFolderDialogImpl(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UINT uFlags = BIF_RETURNONLYFSDIRS) :
m_lpstrInitialFolder(NULL), m_pidlInitialSelection(NULL), m_bExpandInitialSelection(false), m_pidlSelected(NULL), m_hWnd(NULL)
{
memset(&m_bi, 0, sizeof(m_bi)); // initialize structure to 0/NULL
m_bi.hwndOwner = hWndParent;
m_bi.pidlRoot = NULL;
m_bi.pszDisplayName = m_szFolderDisplayName;
m_bi.lpszTitle = lpstrTitle;
m_bi.ulFlags = uFlags;
m_bi.lpfn = BrowseCallbackProc;
m_bi.lParam = (LPARAM)static_cast<T*>(this);
m_szFolderPath[0] = 0;
m_szFolderDisplayName[0] = 0;
}
~CFolderDialogImpl()
{
::CoTaskMemFree(m_pidlSelected);
}
// Operations
INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
{
if(m_bi.hwndOwner == NULL) // set only if not specified before
m_bi.hwndOwner = hWndParent;
// Clear out any previous results
m_szFolderPath[0] = 0;
m_szFolderDisplayName[0] = 0;
::CoTaskMemFree(m_pidlSelected);
INT_PTR nRet = IDCANCEL;
m_pidlSelected = ::SHBrowseForFolder(&m_bi);
if(m_pidlSelected != NULL)
{
nRet = IDOK;
// If BIF_RETURNONLYFSDIRS is set, we try to get the filesystem path.
// Otherwise, the caller must handle the ID-list directly.
if((m_bi.ulFlags & BIF_RETURNONLYFSDIRS) != 0)
{
if(::SHGetPathFromIDList(m_pidlSelected, m_szFolderPath) == FALSE)
nRet = IDCANCEL;
}
}
return nRet;
}
// Methods to call before DoModal
void SetInitialFolder(LPCTSTR lpstrInitialFolder, bool bExpand = true)
{
// lpstrInitialFolder may be a file if BIF_BROWSEINCLUDEFILES is specified
m_lpstrInitialFolder = lpstrInitialFolder;
m_bExpandInitialSelection = bExpand;
}
void SetInitialSelection(LPCITEMIDLIST pidl, bool bExpand = true)
{
m_pidlInitialSelection = pidl;
m_bExpandInitialSelection = bExpand;
}
// Methods to call after DoModal
LPITEMIDLIST GetSelectedItem(bool bDetach = false)
{
LPITEMIDLIST pidl = m_pidlSelected;
if(bDetach)
m_pidlSelected = NULL;
return pidl;
}
LPCTSTR GetFolderPath() const
{
return m_szFolderPath;
}
LPCTSTR GetFolderDisplayName() const
{
return m_szFolderDisplayName;
}
int GetFolderImageIndex() const
{
return m_bi.iImage;
}
// Callback function and overrideables
static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
#ifndef BFFM_VALIDATEFAILED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -