#include "stdafx.h" #include #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 { 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& filters) { std::map::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); } 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); } 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); } } 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); } 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; } }