mirror of
https://github.com/brain-hackers/brain-essential.git
synced 2024-11-18 03:20:07 +09:00
460 lines
14 KiB
C++
460 lines
14 KiB
C++
#include "kncedlg.h"
|
|
|
|
#include <string>
|
|
#include <windows.h>
|
|
#include <knceutil.h>
|
|
|
|
#ifdef UNICODE
|
|
namespace std { typedef wstring tstring; }
|
|
#else
|
|
namespace std { typedef string tstring; }
|
|
#endif
|
|
|
|
using namespace std;
|
|
|
|
enum {
|
|
IDC_CHOOSE_FILE_FILE_LIST = 101,
|
|
IDC_CHOOSE_FILE_CURRENT_DIRECTORY_LABEL = 102,
|
|
IDC_CHOOSE_FILE_DIRECTORY_LIST = 103,
|
|
IDC_CHOOSE_FILE_FILE_NAME_BOX = 104,
|
|
IDC_CHOOSE_FILE_TYPE_COMBO = 105
|
|
};
|
|
|
|
static BOOL WINAPI dlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
static bool onInitDialog(HWND hDlg, void *createStruct);
|
|
static void onOk(HWND hDlg);
|
|
static void onCancel(HWND hDlg);
|
|
static void onFileList(HWND hDlg, int event);
|
|
static void onDirectoryList(HWND hDlg, int event);
|
|
static void onTypeCombo(HWND hDlg, int event);
|
|
static void onFileNameBox(HWND hDlg, int event);
|
|
static void updateFileList(HWND hDlg);
|
|
static void split(vector<tstring> &result, const tstring &str,
|
|
const tstring &delim);
|
|
static tstring appendFileExtension(const tstring &fileName,
|
|
const tstring &pat);
|
|
|
|
extern HINSTANCE g_hInstance;
|
|
|
|
struct KnceFileDlgData {
|
|
KnceChooseFileParams *chooseFileParams;
|
|
vector<pair<tstring, tstring> > filters;
|
|
tstring currentPath;
|
|
bool eventProcessing;
|
|
};
|
|
|
|
bool showChooseFileDialog(HWND hOwnerWindow, KnceChooseFileParams *params) {
|
|
int ret = DialogBoxParam(g_hInstance, _T("CHOOSE_FILE"), hOwnerWindow,
|
|
(DLGPROC)dlgProc, (LPARAM)params);
|
|
|
|
return ret == IDOK;
|
|
}
|
|
|
|
static BOOL WINAPI dlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|
switch (msg) {
|
|
case WM_INITDIALOG:
|
|
return onInitDialog(hDlg, (void *)lParam);
|
|
case WM_COMMAND:
|
|
{
|
|
int id = LOWORD(wParam);
|
|
int event = HIWORD(wParam);
|
|
|
|
switch (id) {
|
|
case IDOK:
|
|
onOk(hDlg);
|
|
break;
|
|
case IDCANCEL:
|
|
onCancel(hDlg);
|
|
break;
|
|
case IDC_CHOOSE_FILE_FILE_LIST:
|
|
onFileList(hDlg, event);
|
|
break;
|
|
case IDC_CHOOSE_FILE_DIRECTORY_LIST:
|
|
onDirectoryList(hDlg, event);
|
|
break;
|
|
case IDC_CHOOSE_FILE_FILE_NAME_BOX:
|
|
onFileNameBox(hDlg, event);
|
|
break;
|
|
case IDC_CHOOSE_FILE_TYPE_COMBO:
|
|
onTypeCombo(hDlg, event);
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static bool onInitDialog(HWND hDlg, void *params) {
|
|
int i;
|
|
|
|
KnceFileDlgData *data = new KnceFileDlgData();
|
|
SetWindowLong(hDlg, GWL_USERDATA, (long)data);
|
|
|
|
data->chooseFileParams = (KnceChooseFileParams *)params;
|
|
data->eventProcessing = false;
|
|
|
|
KnceUtil::adjustDialogLayout(hDlg);
|
|
|
|
vector<tstring> filterParts;
|
|
split(filterParts, data->chooseFileParams->filters, _T("|"));
|
|
|
|
int numFilters = filterParts.size() / 2;
|
|
for (i = 0; i < numFilters; i++) {
|
|
data->filters.push_back(make_pair(filterParts[i * 2],
|
|
filterParts[i * 2 + 1]));
|
|
}
|
|
|
|
HWND hFileList = GetDlgItem(hDlg, IDC_CHOOSE_FILE_FILE_LIST);
|
|
HWND hFileNameBox = GetDlgItem(hDlg, IDC_CHOOSE_FILE_FILE_NAME_BOX);
|
|
|
|
if (data->chooseFileParams->isSaveFile) {
|
|
SetWindowText(hDlg, _T("Save File"));
|
|
|
|
unsigned long style = GetWindowLong(hFileList, GWL_STYLE);
|
|
SetWindowLong(hFileList, GWL_STYLE, style | LBS_NOSEL);
|
|
SetWindowPos(hFileList, NULL, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE |
|
|
SWP_NOZORDER | SWP_FRAMECHANGED));
|
|
}
|
|
else {
|
|
ShowWindow(hFileNameBox, SW_HIDE);
|
|
|
|
RECT nameRect;
|
|
GetWindowRect(hFileNameBox, &nameRect);
|
|
|
|
RECT listRect;
|
|
GetWindowRect(hFileList, &listRect);
|
|
SetWindowPos(hFileList, NULL, 0, 0, listRect.right - listRect.left,
|
|
nameRect.bottom - listRect.top, SWP_NOMOVE | SWP_NOZORDER);
|
|
}
|
|
|
|
HWND hTypeCombo = GetDlgItem(hDlg, IDC_CHOOSE_FILE_TYPE_COMBO);
|
|
|
|
for (i = 0; i < numFilters; i++) {
|
|
SendMessage(hTypeCombo, CB_ADDSTRING, 0,
|
|
(LPARAM)data->filters[i].first.c_str());
|
|
}
|
|
|
|
if (numFilters > 0)
|
|
SendMessage(hTypeCombo, CB_SETCURSEL, 0, 0);
|
|
|
|
tstring fileName;
|
|
tstring filePath = data->chooseFileParams->fileName;
|
|
|
|
if (filePath.empty()) {
|
|
data->currentPath = data->chooseFileParams->initialPath;
|
|
if (data->currentPath.empty())
|
|
data->currentPath = _T("\\");
|
|
}
|
|
else {
|
|
int pos = filePath.rfind(_T('\\'));
|
|
if (pos == 0)
|
|
data->currentPath = _T("\\");
|
|
else
|
|
data->currentPath = filePath.substr(0, pos);
|
|
|
|
fileName = filePath.substr(pos + 1);
|
|
}
|
|
|
|
updateFileList(hDlg);
|
|
|
|
ShowWindow(hDlg, SW_SHOW);
|
|
|
|
if (data->chooseFileParams->isSaveFile) {
|
|
if (fileName.empty())
|
|
SetWindowText(hFileNameBox, _T("untitled"));
|
|
else
|
|
SetWindowText(hFileNameBox, fileName.c_str());
|
|
|
|
SendMessage(hFileNameBox, EM_SETSEL, 0, -1);
|
|
SetFocus(hFileNameBox);
|
|
|
|
return false;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
|
|
static void onOk(HWND hDlg) {
|
|
KnceFileDlgData *data =
|
|
(KnceFileDlgData *)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
HWND hDirList = GetDlgItem(hDlg, IDC_CHOOSE_FILE_DIRECTORY_LIST);
|
|
if (GetFocus() == hDirList) {
|
|
onDirectoryList(hDlg, LBN_DBLCLK);
|
|
return;
|
|
}
|
|
|
|
tstring fileName;
|
|
if (data->chooseFileParams->isSaveFile) {
|
|
HWND hFileNameBox = GetDlgItem(hDlg, IDC_CHOOSE_FILE_FILE_NAME_BOX);
|
|
|
|
TCHAR fileNameCStr[MAX_PATH];
|
|
GetWindowText(hFileNameBox, fileNameCStr, MAX_PATH);
|
|
fileName = fileNameCStr;
|
|
|
|
HWND hTypeCombo = GetDlgItem(hDlg, IDC_CHOOSE_FILE_TYPE_COMBO);
|
|
int typeIndex = SendMessage(hTypeCombo, CB_GETCURSEL, 0, 0);
|
|
tstring pat = data->filters[typeIndex].second;
|
|
|
|
vector<tstring> exts;
|
|
split(exts, pat, _T(";"));
|
|
|
|
if (!exts.empty())
|
|
fileName = appendFileExtension(fileName, exts[0]);
|
|
}
|
|
else {
|
|
HWND hFileList = GetDlgItem(hDlg, IDC_CHOOSE_FILE_FILE_LIST);
|
|
int selected = SendMessage(hFileList, LB_GETCURSEL, 0, 0);
|
|
|
|
TCHAR fileNameCStr[MAX_PATH];
|
|
|
|
if (SendMessage(hFileList, LB_GETTEXTLEN, selected, 0) < MAX_PATH) {
|
|
SendMessage(hFileList, LB_GETTEXT, selected, (LPARAM)fileNameCStr);
|
|
fileName = fileNameCStr;
|
|
}
|
|
}
|
|
|
|
tstring filePath;
|
|
if (data->currentPath == _T("\\"))
|
|
filePath = data->currentPath + fileName;
|
|
else
|
|
filePath = data->currentPath + _T("\\") + fileName;
|
|
|
|
_tcsncpy(data->chooseFileParams->fileName, filePath.c_str(), MAX_PATH);
|
|
|
|
if (data->chooseFileParams->isSaveFile) {
|
|
FILE *file = _tfopen(filePath.c_str(), _T("r"));
|
|
if (file != NULL) {
|
|
fclose(file);
|
|
tstring msg = _T("File ") + fileName + _T(" already exists. ")
|
|
_T("Overwrite?");
|
|
|
|
if (MessageBox(hDlg, msg.c_str(), _T("Confirm"),
|
|
MB_ICONEXCLAMATION | MB_YESNO) == IDNO)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
EndDialog(hDlg, IDOK);
|
|
}
|
|
|
|
static void onCancel(HWND hDlg) {
|
|
KnceFileDlgData *data =
|
|
(KnceFileDlgData *)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
EndDialog(hDlg, IDCANCEL);
|
|
}
|
|
|
|
static void onFileList(HWND hDlg, int event) {
|
|
KnceFileDlgData *data =
|
|
(KnceFileDlgData *)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
if (event != LBN_SELCHANGE || data->eventProcessing)
|
|
return;
|
|
|
|
HWND hFileList = GetDlgItem(hDlg, IDC_CHOOSE_FILE_FILE_LIST);
|
|
int selected = SendMessage(hFileList, LB_GETCURSEL, 0, 0);
|
|
if (selected == -1)
|
|
return;
|
|
|
|
tstring fileName;
|
|
TCHAR fileNameCStr[MAX_PATH];
|
|
|
|
if (SendMessage(hFileList, LB_GETTEXTLEN, selected, 0) < MAX_PATH) {
|
|
SendMessage(hFileList, LB_GETTEXT, selected, (LPARAM)fileNameCStr);
|
|
fileName = fileNameCStr;
|
|
}
|
|
|
|
HWND hFileNameBox = GetDlgItem(hDlg,
|
|
IDC_CHOOSE_FILE_FILE_NAME_BOX);
|
|
|
|
data->eventProcessing = true;
|
|
SetWindowText(hFileNameBox, fileName.c_str());
|
|
data->eventProcessing = false;
|
|
|
|
if (!data->chooseFileParams->isSaveFile) {
|
|
HWND hOkButton = GetDlgItem(hDlg, IDOK);
|
|
EnableWindow(hOkButton, true);
|
|
}
|
|
}
|
|
|
|
static void onDirectoryList(HWND hDlg, int event) {
|
|
const int dirDispLen = MAX_PATH + 2;
|
|
|
|
KnceFileDlgData *data =
|
|
(KnceFileDlgData *)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
if (event != LBN_DBLCLK)
|
|
return;
|
|
|
|
HWND hDirList = GetDlgItem(hDlg, IDC_CHOOSE_FILE_DIRECTORY_LIST);
|
|
|
|
int selected = SendMessage(hDirList, LB_GETCURSEL, 0, 0);
|
|
if (selected == -1)
|
|
return;
|
|
|
|
tstring dirDisp;
|
|
TCHAR dirDispCStr[dirDispLen];
|
|
|
|
if (SendMessage(hDirList, LB_GETTEXTLEN, selected, 0) < dirDispLen) {
|
|
SendMessage(hDirList, LB_GETTEXT, selected, (LPARAM)dirDispCStr);
|
|
dirDisp = dirDispCStr;
|
|
}
|
|
|
|
if (dirDisp == _T("(Up...)")) {
|
|
int pos = data->currentPath.rfind(_T('\\'));
|
|
if (pos == 0)
|
|
data->currentPath = _T("\\");
|
|
else
|
|
data->currentPath = data->currentPath.substr(0, pos);
|
|
}
|
|
else {
|
|
tstring dirName = dirDisp.substr(1, dirDisp.length() - 2);
|
|
if (data->currentPath == _T("\\"))
|
|
data->currentPath += dirName;
|
|
else
|
|
data->currentPath += _T("\\") + dirName;
|
|
}
|
|
|
|
updateFileList(hDlg);
|
|
}
|
|
|
|
static void onFileNameBox(HWND hDlg, int event) {
|
|
KnceFileDlgData *data =
|
|
(KnceFileDlgData *)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
if (event != EN_CHANGE || data->eventProcessing)
|
|
return;
|
|
|
|
HWND hFileList = GetDlgItem(hDlg, IDC_CHOOSE_FILE_FILE_LIST);
|
|
|
|
data->eventProcessing = true;
|
|
SendMessage(hFileList, LB_SETCURSEL, -1, 0);
|
|
data->eventProcessing = false;
|
|
}
|
|
|
|
static void onTypeCombo(HWND hDlg, int event) {
|
|
if (event == CBN_SELCHANGE)
|
|
updateFileList(hDlg);
|
|
}
|
|
|
|
static void updateFileList(HWND hDlg) {
|
|
KnceFileDlgData *data =
|
|
(KnceFileDlgData *)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
bool isRoot = data->currentPath == _T("\\");
|
|
|
|
tstring dirName;
|
|
if (isRoot)
|
|
dirName = _T("[My Device]");
|
|
else {
|
|
dirName = _T("[") + data->currentPath.substr(
|
|
data->currentPath.rfind(_T('\\')) + 1) + _T("]");
|
|
}
|
|
|
|
HWND hDirLabel = GetDlgItem(hDlg, IDC_CHOOSE_FILE_CURRENT_DIRECTORY_LABEL);
|
|
SetWindowText(hDirLabel, dirName.c_str());
|
|
|
|
HWND hTypeCombo = GetDlgItem(hDlg, IDC_CHOOSE_FILE_TYPE_COMBO);
|
|
int typeIndex = SendMessage(hTypeCombo, CB_GETCURSEL, 0, 0);
|
|
tstring pat = data->filters[typeIndex].second;
|
|
|
|
HWND hFileList = GetDlgItem(hDlg, IDC_CHOOSE_FILE_FILE_LIST);
|
|
HWND hDirList = GetDlgItem(hDlg, IDC_CHOOSE_FILE_DIRECTORY_LIST);
|
|
|
|
SendMessage(hFileList, LB_RESETCONTENT, 0, 0);
|
|
SendMessage(hDirList, LB_RESETCONTENT, 0, 0);
|
|
|
|
if (!isRoot)
|
|
SendMessage(hDirList, LB_ADDSTRING, 0, (LPARAM)_T("(Up...)"));
|
|
|
|
tstring findPath;
|
|
if (isRoot)
|
|
findPath = _T("\\*.*");
|
|
else
|
|
findPath = data->currentPath + _T("\\*.*");
|
|
|
|
WIN32_FIND_DATA fd;
|
|
HANDLE hFind = FindFirstFile(findPath.c_str(), &fd);
|
|
|
|
if (hFind != INVALID_HANDLE_VALUE) {
|
|
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
tstring dirDisp = _T("[") + tstring(fd.cFileName) + _T("]");
|
|
SendMessage(hDirList, LB_ADDSTRING, 0, (LPARAM)dirDisp.c_str());
|
|
}
|
|
else if (KnceUtil::matchMultiFileExtension(fd.cFileName, pat.c_str()))
|
|
SendMessage(hFileList, LB_ADDSTRING, 0, (LPARAM)fd.cFileName);
|
|
|
|
while (FindNextFile(hFind, &fd)) {
|
|
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
tstring dirDisp = _T("[") + tstring(fd.cFileName) + _T("]");
|
|
SendMessage(hDirList, LB_ADDSTRING, 0,
|
|
(LPARAM)dirDisp.c_str());
|
|
}
|
|
else if (KnceUtil::matchMultiFileExtension(fd.cFileName,
|
|
pat.c_str())) {
|
|
|
|
SendMessage(hFileList, LB_ADDSTRING, 0, (LPARAM)fd.cFileName);
|
|
}
|
|
}
|
|
}
|
|
|
|
FindClose(hFind);
|
|
|
|
if (!data->chooseFileParams->isSaveFile) {
|
|
HWND hOkButton = GetDlgItem(hDlg, IDOK);
|
|
EnableWindow(hOkButton, false);
|
|
}
|
|
|
|
if (SendMessage(hFileList, LB_GETCOUNT, 0, 0) > 0) {
|
|
SendMessage(hFileList, LB_SETCURSEL, 0, 0);
|
|
|
|
onFileList(hDlg, LBN_SELCHANGE);
|
|
}
|
|
|
|
int numDirs = SendMessage(hDirList, LB_GETCOUNT, 0, 0);
|
|
if (isRoot)
|
|
SendMessage(hDirList, LB_SETCURSEL, 0, 0);
|
|
else {
|
|
if (numDirs > 1)
|
|
SendMessage(hDirList, LB_SETCURSEL, 1, 0);
|
|
else
|
|
SendMessage(hDirList, LB_SETCURSEL, 0, 0);
|
|
}
|
|
}
|
|
|
|
static void split(vector<tstring> &result, const tstring &str,
|
|
const tstring &delim) {
|
|
|
|
tstring strWork = str;
|
|
|
|
int cutAt = 0;
|
|
while ((cutAt = strWork.find_first_of(delim)) != tstring::npos) {
|
|
if (cutAt > 0)
|
|
result.push_back(strWork.substr(0, cutAt));
|
|
strWork = strWork.substr(cutAt + 1);
|
|
}
|
|
|
|
if (strWork.length() > 0)
|
|
result.push_back(strWork);
|
|
}
|
|
|
|
static tstring appendFileExtension(const tstring &fileName,
|
|
const tstring &pat) {
|
|
|
|
if (KnceUtil::matchFileExtension(fileName.c_str(), pat.c_str()))
|
|
return fileName;
|
|
|
|
if (pat.length() < 2 || pat.substr(0, 2) != _T("*."))
|
|
return fileName;
|
|
|
|
return fileName + pat.substr(1);
|
|
}
|