nim_duilib/ui_components/modal_wnd/file_dialog_ex.cpp

286 lines
6.2 KiB
C++
Raw Normal View History

2019-04-19 17:19:57 +08:00
#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"
namespace nim_comp {
2019-04-19 17:19:57 +08:00
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;
}
// ʾ<><CABE>_T("Text Files(*.txt)\0*.txt\0<><30>ҳ<EFBFBD>ļ<EFBFBD>\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:<3A><><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>,key-<2D><><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD> value-<2D><><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//example:filers[L"ͼ<><CDBC><EFBFBD>ļ<EFBFBD>(*.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(kThreadUI, closure);
2019-04-19 17:19:57 +08:00
}
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(kThreadUI, closure);
2019-04-19 17:19:57 +08:00
}
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(kThreadUI, closure);
2019-04-19 17:19:57 +08:00
}
}
else if (file_dialog_type_ == FDT_SaveFile)
{
BOOL ret = ::GetSaveFileName(&m_stOFN);
StdClosure closure = nbase::Bind(file_dialog_callback2_, ret, GetPathName());
nbase::ThreadManager::PostTask(kThreadUI, closure);
2019-04-19 17:19:57 +08:00
}
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;
}
}