281 lines
6.2 KiB
C++
281 lines
6.2 KiB
C++
#include "stdafx.h"
|
|
#include <tchar.h>
|
|
#include "file_dialog_ex.h"
|
|
#include "async_do_modal.h"
|
|
#include "base/thread/thread_manager.h"
|
|
#include "base/util/string_util.h"
|
|
#include "base/file/file_util.h"
|
|
|
|
CFileDialogEx::CFileDialogEx(void)
|
|
{
|
|
memset(&m_szDefExt, 0, sizeof(m_szDefExt));
|
|
memset(&m_szFilter, 0, sizeof(m_szFilter));
|
|
memset(&m_szFileName, 0, sizeof(m_szFileName));
|
|
memset(&m_stOFN, 0, sizeof(OPENFILENAME));
|
|
|
|
m_lpszFileName = NULL;
|
|
file_dialog_type_ = FDT_None;
|
|
m_stOFN.lStructSize = sizeof(OPENFILENAME);
|
|
m_stOFN.Flags = OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER|OFN_NOCHANGEDIR|OFN_EXTENSIONDIFFERENT;
|
|
m_stOFN.lpstrDefExt = m_szDefExt;
|
|
m_stOFN.lpstrFilter = m_szFilter;
|
|
m_stOFN.lpstrFile = m_szFileName;
|
|
m_stOFN.nMaxFile = MAX_PATH;
|
|
}
|
|
|
|
CFileDialogEx::~CFileDialogEx(void)
|
|
{
|
|
if (m_lpszFileName != NULL)
|
|
{
|
|
delete []m_lpszFileName;
|
|
m_lpszFileName = NULL;
|
|
}
|
|
}
|
|
|
|
void CFileDialogEx::SetDefExt(LPCTSTR lpszDefExt)
|
|
{
|
|
wcsncpy_s(m_szDefExt, lpszDefExt, sizeof(m_szDefExt) / sizeof(TCHAR));
|
|
}
|
|
|
|
void CFileDialogEx::SetFileName(LPCTSTR lpszFileName)
|
|
{
|
|
wcsncpy_s(m_szFileName, lpszFileName, sizeof(m_szFileName) / sizeof(TCHAR));
|
|
}
|
|
|
|
void CFileDialogEx::SetFlags(DWORD dwFlags)
|
|
{
|
|
m_stOFN.Flags = dwFlags;
|
|
}
|
|
|
|
// 示例_T("Text Files(*.txt)\0*.txt\0网页文件\0*.htm;*.html\0All Files(*.*)\0*.*\0\0")
|
|
void CFileDialogEx::SetFilter(LPCTSTR lpszFilter)
|
|
{
|
|
LPTSTR lpsz = (LPTSTR)lpszFilter;
|
|
LPTSTR lpszOld;
|
|
int i = 0;
|
|
|
|
while(1)
|
|
{
|
|
if (i >= MAX_PATH - 1)
|
|
break;
|
|
|
|
m_szFilter[i] = *lpsz;
|
|
i++;
|
|
lpszOld = lpsz;
|
|
lpsz = _tcsinc(lpsz);
|
|
|
|
if (*lpszOld == '\0' && *lpsz == '\0')
|
|
{
|
|
m_szFilter[i] = *lpsz;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//param:过滤字符串对,key-描述字符串 value-过滤字符串
|
|
//参数可以指定多组过滤类型
|
|
//example:filers[L"图像文件(*.jpg)"] = L"*.jpg";
|
|
void CFileDialogEx::SetFilter(std::map<LPCTSTR,LPCTSTR>& filters)
|
|
{
|
|
std::map<LPCTSTR,LPCTSTR>::iterator it = filters.begin();
|
|
const int size = filters.size()*100;
|
|
wchar_t* filterstring= new wchar_t[size];
|
|
int offset = 0;
|
|
for(;it != filters.end();it++)
|
|
{
|
|
_tcscpy(filterstring + offset,it->first);
|
|
offset += _tcslen(it->first) + 1;
|
|
_tcscpy(filterstring + offset,it->second);
|
|
offset += _tcslen(it->second) + 1;
|
|
}
|
|
*(filterstring + offset) = '\0';
|
|
SetFilter(filterstring);
|
|
delete[] filterstring;
|
|
}
|
|
|
|
void CFileDialogEx::SetMultiSel(BOOL bMultiSel/* = TRUE*/)
|
|
{
|
|
if (bMultiSel)
|
|
{
|
|
m_stOFN.Flags |= OFN_ALLOWMULTISELECT;
|
|
SetFileNameBufferSize(4096);
|
|
}
|
|
else
|
|
m_stOFN.Flags &= ~OFN_ALLOWMULTISELECT;
|
|
}
|
|
|
|
void CFileDialogEx::SetParentWnd(HWND hParentWnd)
|
|
{
|
|
m_stOFN.hwndOwner = hParentWnd;
|
|
}
|
|
|
|
void CFileDialogEx::SetTitle(LPCTSTR lpszTitle)
|
|
{
|
|
m_stOFN.lpstrTitle = lpszTitle;
|
|
}
|
|
|
|
void CFileDialogEx::SetFileNameBufferSize(DWORD dwSize)
|
|
{
|
|
if (m_lpszFileName != NULL)
|
|
{
|
|
delete []m_lpszFileName;
|
|
m_lpszFileName = NULL;
|
|
}
|
|
|
|
if (dwSize <= (sizeof(m_szFileName) / sizeof(TCHAR)))
|
|
{
|
|
m_stOFN.lpstrFile = m_szFileName;
|
|
m_stOFN.nMaxFile = MAX_PATH;
|
|
}
|
|
else
|
|
{
|
|
m_lpszFileName = new TCHAR[dwSize];
|
|
if (m_lpszFileName != NULL)
|
|
{
|
|
memset(m_lpszFileName, 0, dwSize * sizeof(TCHAR));
|
|
m_stOFN.lpstrFile = m_lpszFileName;
|
|
m_stOFN.nMaxFile = dwSize;
|
|
}
|
|
else
|
|
{
|
|
m_stOFN.lpstrFile = m_szFileName;
|
|
m_stOFN.nMaxFile = MAX_PATH;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CFileDialogEx::AyncShowOpenFileDlg(FileDialogCallback2 file_dialog_callback2)
|
|
{
|
|
file_dialog_callback2_ = file_dialog_callback2;
|
|
file_dialog_type_ = FDT_OpenFile;
|
|
AsyncDoModal(this);
|
|
}
|
|
|
|
void CFileDialogEx::AyncShowSaveFileDlg(FileDialogCallback2 file_dialog_callback2)
|
|
{
|
|
file_dialog_callback2_ = file_dialog_callback2;
|
|
file_dialog_type_ = FDT_SaveFile;
|
|
AsyncDoModal(this);
|
|
}
|
|
|
|
void CFileDialogEx::SyncShowModal()
|
|
{
|
|
if (file_dialog_type_ == FDT_OpenFile)
|
|
{
|
|
BOOL ret = ::GetOpenFileName(&m_stOFN);
|
|
if ( (m_stOFN.Flags & OFN_ALLOWMULTISELECT) > 0)
|
|
{
|
|
uint32_t get_length = 0;
|
|
std::wstring file_directory = m_stOFN.lpstrFile;
|
|
get_length = file_directory.size()+1;
|
|
std::wstring file_name = m_stOFN.lpstrFile + get_length;
|
|
if (file_name.size() == 0)
|
|
{
|
|
StdClosure closure = nbase::Bind(file_dialog_callback2_, ret, file_directory);
|
|
nbase::ThreadManager::PostTask(kThreadMain, closure);
|
|
}
|
|
else
|
|
{
|
|
while (file_name.size() > 0)
|
|
{
|
|
std::wstring file_path = file_directory + L"\\" + file_name;
|
|
if (nbase::FilePathIsExist(file_path, false))
|
|
{
|
|
StdClosure closure = nbase::Bind(file_dialog_callback2_, ret, file_path);
|
|
nbase::ThreadManager::PostTask(kThreadMain, closure);
|
|
}
|
|
get_length += file_name.size()+1;
|
|
file_name = m_stOFN.lpstrFile + get_length;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
StdClosure closure = nbase::Bind(file_dialog_callback2_, ret, GetPathName());
|
|
nbase::ThreadManager::PostTask(kThreadMain, closure);
|
|
}
|
|
}
|
|
else if (file_dialog_type_ == FDT_SaveFile)
|
|
{
|
|
BOOL ret = ::GetSaveFileName(&m_stOFN);
|
|
StdClosure closure = nbase::Bind(file_dialog_callback2_, ret, GetPathName());
|
|
nbase::ThreadManager::PostTask(kThreadMain, closure);
|
|
}
|
|
else
|
|
{
|
|
assert(FALSE);
|
|
}
|
|
}
|
|
|
|
std::wstring CFileDialogEx::GetPathName()
|
|
{
|
|
return m_stOFN.lpstrFile;
|
|
}
|
|
|
|
std::wstring CFileDialogEx::GetFileName()
|
|
{
|
|
return L"";
|
|
}
|
|
|
|
std::wstring CFileDialogEx::GetFileExt()
|
|
{
|
|
return L"";
|
|
}
|
|
|
|
std::wstring CFileDialogEx::GetFileTitle()
|
|
{
|
|
return L"";
|
|
}
|
|
|
|
std::wstring CFileDialogEx::GetFolderPath()
|
|
{
|
|
return L"";
|
|
}
|
|
|
|
|
|
POSITION CFileDialogEx::GetStartPosition()
|
|
{
|
|
return (POSITION)m_stOFN.lpstrFile;
|
|
}
|
|
|
|
std::wstring CFileDialogEx::GetNextPathName(POSITION& pos)
|
|
{
|
|
LPTSTR lpsz = (LPTSTR)pos;
|
|
if (lpsz == m_stOFN.lpstrFile) // first time
|
|
{
|
|
if ((m_stOFN.Flags & OFN_ALLOWMULTISELECT) == 0)
|
|
{
|
|
pos = NULL;
|
|
return m_stOFN.lpstrFile;
|
|
}
|
|
|
|
// find char pos after first Delimiter
|
|
while(*lpsz != '\0')
|
|
lpsz = _tcsinc(lpsz);
|
|
lpsz = _tcsinc(lpsz);
|
|
|
|
// if single selection then return only selection
|
|
if (*lpsz == '\0')
|
|
{
|
|
pos = NULL;
|
|
return m_stOFN.lpstrFile;
|
|
}
|
|
}
|
|
|
|
std::wstring strBasePath = m_stOFN.lpstrFile;
|
|
std::wstring strFileName = lpsz;
|
|
if (strBasePath.substr(strBasePath.length() - 1) != _T("\\"))
|
|
strBasePath += _T("\\");
|
|
std::wstring strPath = strBasePath + strFileName;
|
|
|
|
// find char pos at next Delimiter
|
|
while(*lpsz != '\0')
|
|
lpsz = _tcsinc(lpsz);
|
|
lpsz = _tcsinc(lpsz);
|
|
if (*lpsz == '\0') // if double terminated then done
|
|
pos = NULL;
|
|
else
|
|
pos = (POSITION)lpsz;
|
|
|
|
return strPath;
|
|
} |