📄 filedlg.cpp
字号:
#include "resourceppc.h"
#include <windows.h>
#include <tchar.h>
#include <commdlg.h>
#include "filedlg.h"
#define CLB_GETCURSEL (m_fDlgType == DLG_TYPE_PPC3 ? CB_GETCURSEL : LB_GETCURSEL)
#define CLB_ADDSTRING (m_fDlgType == DLG_TYPE_PPC3 ? CB_ADDSTRING : LB_ADDSTRING)
#define CLB_SETITEMDATA (m_fDlgType == DLG_TYPE_PPC3 ? CB_SETITEMDATA : LB_SETITEMDATA)
#define CLB_SETCURSEL (m_fDlgType == DLG_TYPE_PPC3 ? CB_SETCURSEL : LB_SETCURSEL)
#define CLB_GETCOUNT (m_fDlgType == DLG_TYPE_PPC3 ? CB_GETCOUNT : LB_GETCOUNT)
#define CLB_GETITEMDATA (m_fDlgType == DLG_TYPE_PPC3 ? CB_GETITEMDATA : LB_GETITEMDATA)
#define CLB_RESETCONTENT (m_fDlgType == DLG_TYPE_PPC3 ? CB_RESETCONTENT : LB_RESETCONTENT)
static const int s_nListColumnWidth[] =
{
145, 65, 75, 120
};
// public members
CFileDialog::CFileDialog(LPOPENFILENAME pofn)
{
m_pofn = pofn;
m_hwndDlg = NULL;
m_hFnt = NULL;
m_nListSort = LIST_SORT_NAME;
m_fSortOrder = TRUE;
m_fShowExt = FALSE;
m_pszFilter = NULL;
m_pszDefExt = NULL;
m_fSelMode = FALSE;
}
CFileDialog::~CFileDialog()
{
if (m_hFnt)
DeleteObject(m_hFnt);
}
int CFileDialog::DoModal(BOOL fSave)
{
if (!m_pofn)
return IDCANCEL;
m_fSave = fSave;
int nResource = GetDlgResourceID();
if (!nResource)
return FALSE;
return DialogBoxParam(g_hInst, MAKEINTRESOURCE(nResource),
m_pofn->hwndOwner, FileDlgProc, (LPARAM)this);
}
LRESULT CALLBACK ListViewProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WNDPROC p = (WNDPROC)GetWindowLong(hwnd, GWL_USERDATA);
if (uMsg == WM_GETDLGCODE)
return DLGC_WANTALLKEYS;
return CallWindowProc(p, hwnd, uMsg, wParam, lParam);
}
// protected members
BOOL CFileDialog::OnInitDialog(HWND hwndDlg)
{
m_hwndDlg = hwndDlg;
m_hwndLV = GetDlgItem(m_hwndDlg, IDC_LIST_FILE);
m_helper.SHInitDialog(m_hwndDlg);
INITCOMMONCONTROLSEX iccex;
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES;
InitCommonControlsEx(&iccex);
GetShellSettings();
CreateToolBar();
CheckWindowSize();
ParseFilter();
CreateExtList();
if (m_fDlgType == DLG_TYPE_PPC3) {
SendMessage(GetDlgItem(m_hwndDlg, IDC_COMBO_FILTER), CB_SETEXTENDEDUI, 1, 0);
}
InitListView();
SetDlgItemText(m_hwndDlg, IDC_EDIT_NAME, m_pofn->lpstrFile);
LPTSTR psz;
TCHAR sz[MAX_LOADSTRING];
if (m_pofn->lpstrInitialDir &&
_tcslen(m_pofn->lpstrInitialDir) &&
LoadFolderItem(m_pofn->lpstrInitialDir))
goto done;
_tcscpy(sz, m_pofn->lpstrFile);
if (_tcslen(sz) && LoadFolderItem(sz))
goto done;
psz = _tcsrchr(sz, _T('\\'));
if (psz) {
SetDlgItemText(m_hwndDlg, IDC_EDIT_NAME, psz + 1);
*psz = NULL;
}
if (_tcslen(sz) && LoadFolderItem(sz))
goto done;
LoadString(g_hInst, IDS_DEF_DIR, sz, MAX_LOADSTRING);
if (LoadFolderItem(sz))
goto done;
LoadFolderItem(_T("\\"));
done:
if (m_fSave)
SetFocus(GetDlgItem(m_hwndDlg, IDC_EDIT_NAME));
else
SetFocus(GetDlgItem(m_hwndDlg, IDC_LIST_FILE));
return FALSE;
}
void CFileDialog::OnOK()
{
DWORD dwAttr;
LPTSTR pszSrc = NULL, pszPath = NULL, p;
TCHAR szMsg[MAX_LOADSTRING];
TCHAR szTitle[MAX_LOADSTRING];
if (m_pofn->lpstrTitle)
_tcsncpy(szTitle, m_pofn->lpstrTitle, MAX_LOADSTRING);
else
LoadString(g_hInst, m_fSave ? IDS_SAVE_TITLE : IDS_OPEN_TITLE, szTitle, MAX_LOADSTRING);
int n = GetWindowTextLength(GetDlgItem(m_hwndDlg, IDC_EDIT_NAME));
if (!n) return;
SendMessage(GetDlgItem(m_hwndDlg, IDC_EDIT_NAME), EM_SETSEL, 0, -1);
pszSrc = new TCHAR[n + 1];
GetDlgItemText(m_hwndDlg, IDC_EDIT_NAME, pszSrc, n + 1);
if (_tcschr(pszSrc, _T('/')) ||
_tcschr(pszSrc, _T(':')) ||
_tcschr(pszSrc, _T(';')) ||
_tcschr(pszSrc, _T('?')) ||
_tcschr(pszSrc, _T(':')) ||
_tcschr(pszSrc, _T('<')) ||
_tcschr(pszSrc, _T('>')) ||
_tcschr(pszSrc, _T('|')))
goto done;
if (_tcschr(pszSrc, _T('*'))) {
// search
if (m_pszFilter) {
delete [] m_pszFilter;
m_pszFilter = NULL;
}
m_pszFilter = pszSrc; pszSrc = NULL;
LoadFolderItem(m_szCurrent, FALSE);
goto done;
}
else if (_tcschr(pszSrc, _T('\"'))) {
// multi
if (m_fSave || !(m_pofn->Flags & OFN_ALLOWMULTISELECT))
goto done;
n = m_pofn->nMaxFile;
pszPath = m_pofn->lpstrFile;
p = _tcslen(m_szCurrent) ? m_szCurrent : _T("\\");
_tcsncpy(pszPath, p, n);
n -= _tcslen(pszPath) + 2;
pszPath += _tcslen(pszPath);
*pszPath++ = NULL;
p = pszSrc;
while (n > 0 && *p != NULL) {
LPTSTR psz;
if (*p == _T('\"'))
p++;
psz = _tcschr(p, _T('\"'));
if (m_pofn->Flags & OFN_FILEMUSTEXIST) {
int nLen = MAX_PATH;
TCHAR szPath[MAX_PATH + 1] = _T("");
_tcscpy(szPath, m_szCurrent);
_tcscat(szPath, _T("\\"));
nLen -= _tcslen(m_szCurrent) + 1;
if (psz)
_tcsncat(szPath, p, min(psz - p, nLen));
else
_tcsncat(szPath, p, nLen);
dwAttr = GetFileAttributes(szPath);
if (dwAttr == 0xFFFFFFFF ||
(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) {
LoadString(g_hInst, IDS_MSG_FILE_MUST_EXIST, szMsg, MAX_LOADSTRING);
p = new TCHAR[_tcslen(szPath) + _tcslen(szMsg) + 1];
wsprintf(p, _T("%s%s"), szPath, szMsg);
MessageBox(m_hwndDlg, p, szTitle, MB_ICONEXCLAMATION | MB_OK);
delete [] p;
pszPath = NULL;
goto done;
}
}
if (psz) {
_tcsncpy(pszPath, p, min(psz - p, n));
n -= psz - p;
pszPath += psz - p;
}
else {
_tcsncpy(pszPath, p, n);
n -= _tcslen(p);
pszPath += _tcslen(p);
}
if (n > 0)
*pszPath++ = NULL;
if (!psz)
break;
p = psz;
while (*p == _T(' ') || *p == _T('\"'))
p++;
}
pszPath = NULL;
n = (n > 1) ? IDOK : IDCANCEL;
EndDialog(n);
}
else {
// single
n = (*pszSrc != _T('\\')) ? _tcslen(m_szCurrent) + _tcslen(pszSrc) + 1 : _tcslen(pszSrc);
p = _tcsrchr(pszSrc, _T('.'));
if (!p || _tcschr(p, _T('\\'))) {
if (m_pszDefExt)
n += _tcslen(m_pszDefExt);
else if (m_pofn->lpstrDefExt) {
n += _tcslen(m_pofn->lpstrDefExt) + 1;
}
else {
p = _tcschr((LPTSTR)m_listExt.GetAt(0), _T('.'));
if (p && !_tcschr(p, _T('*')))
n += _tcslen(p);
}
}
else {
if (m_pofn->lpstrDefExt && m_pszDefExt)
n += max(_tcslen(m_pszDefExt), _tcslen(m_pofn->lpstrDefExt) + 1);
else if (m_pszDefExt)
n += _tcslen(m_pszDefExt);
else if (m_pofn->lpstrDefExt)
n += _tcslen(m_pofn->lpstrDefExt) + 1;
}
pszPath = new TCHAR[n + 1];
*pszPath = NULL;
if (*pszSrc != _T('\\')) {
_tcscpy(pszPath, m_szCurrent);
_tcsncat(pszPath, _T("\\"), n);
}
_tcscat(pszPath, pszSrc);
p = _tcsrchr(pszSrc, _T('.'));
if (!p || _tcschr(p, _T('\\'))) {
if (m_pszDefExt)
_tcscat(pszPath, m_pszDefExt);
else {
dwAttr = GetFileAttributes(pszPath);
if (dwAttr != 0xFFFFFFFF &&
(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) {
if (LoadFolderItem(pszPath, FALSE)) {
goto done;
}
}
else if (m_pofn->lpstrDefExt) {
_tcscat(pszPath, _T("."));
_tcscat(pszPath, m_pofn->lpstrDefExt);
}
else {
p = _tcschr((LPTSTR)m_listExt.GetAt(0), _T('.'));
if (p && !_tcschr(p, _T('*')))
_tcscat(pszPath, p);
}
}
}
else {
dwAttr = GetFileAttributes(pszPath);
if (dwAttr == 0xFFFFFFFF ||
(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) {
if (m_pszDefExt)
_tcscat(pszPath, m_pszDefExt);
//else if (m_pofn->lpstrDefExt)
// _tcscat(pszPath, m_pofn->lpstrDefExt);
}
}
if (!m_fSave && (m_pofn->Flags & OFN_FILEMUSTEXIST)) {
dwAttr = GetFileAttributes(pszPath);
if (dwAttr == 0xFFFFFFFF ||
(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) {
LoadString(g_hInst, IDS_MSG_FILE_MUST_EXIST, szMsg, MAX_LOADSTRING);
p = new TCHAR[_tcslen(pszPath) + _tcslen(szMsg) + 1];
wsprintf(p, _T("%s%s"), pszPath, szMsg);
MessageBox(m_hwndDlg, p, szTitle, MB_ICONEXCLAMATION | MB_OK);
delete [] p;
goto done;
}
}
if (!m_fSave && (m_pofn->Flags & OFN_CREATEPROMPT)) {
dwAttr = GetFileAttributes(pszPath);
if (dwAttr == 0xFFFFFFFF ||
(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) {
LoadString(g_hInst, IDS_MSG_CREATE_PROMPT, szMsg, MAX_LOADSTRING);
p = new TCHAR[_tcslen(pszPath) + _tcslen(szMsg) + 1];
wsprintf(p, _T("%s%s"), pszPath, szMsg);
n = MessageBox(m_hwndDlg, p, szTitle, MB_ICONQUESTION | MB_YESNO);
delete [] p;
if (n == IDNO)
goto done;
}
}
if (m_fSave && (m_pofn->Flags & OFN_PATHMUSTEXIST)) {
p = _tcsrchr(pszPath, _T('\\'));
if (p) *p = NULL;
dwAttr = GetFileAttributes(pszPath);
if (p) *p = _T('\\');
if (dwAttr == 0xFFFFFFFF ||
!(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) {
LoadString(g_hInst, IDS_MSG_PATH_MUST_EXIST, szMsg, MAX_LOADSTRING);
p = new TCHAR[_tcslen(pszPath) + _tcslen(szMsg) + 1];
wsprintf(p, _T("%s%s"), pszPath, szMsg);
MessageBox(m_hwndDlg, p, szTitle, MB_ICONEXCLAMATION | MB_OK);
delete [] p;
goto done;
}
}
if (m_fSave && (m_pofn->Flags & OFN_OVERWRITEPROMPT)) {
dwAttr = GetFileAttributes(pszPath);
if (dwAttr != 0xFFFFFFFF &&
!(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) {
LoadString(g_hInst, IDS_MSG_OVERWRITE_PROMPT, szMsg, MAX_LOADSTRING);
p = new TCHAR[_tcslen(pszPath) + _tcslen(szMsg) + 1];
wsprintf(p, _T("%s%s"), pszPath, szMsg);
n = MessageBox(m_hwndDlg, p, szTitle, MB_ICONEXCLAMATION | MB_YESNO);
delete [] p;
if (n == IDNO)
goto done;
}
}
_tcsncpy(m_pofn->lpstrFile, pszPath, m_pofn->nMaxFile - 1);
m_pofn->lpstrFile[m_pofn->nMaxFile - 1] = NULL;
if (m_pofn->lpstrFileTitle && m_pofn->nMaxFileTitle) {
p = _tcsrchr(pszPath, _T('\\'));
if (p)
_tcsncpy(m_pofn->lpstrFileTitle, p + 1, m_pofn->nMaxFileTitle - 1);
else
_tcsncpy(m_pofn->lpstrFileTitle, pszPath, m_pofn->nMaxFileTitle - 1);
m_pofn->lpstrFileTitle[m_pofn->nMaxFileTitle - 1] = NULL;
}
n = (_tcslen(pszPath) + 1 <= m_pofn->nMaxFile) ? IDOK : IDCANCEL;
EndDialog(n);
}
done:
if (pszPath)
delete [] pszPath;
if (pszSrc)
delete [] pszSrc;
}
void CFileDialog::EndDialog(int nResult)
{
if (nResult == IDOK) {
int n = SendMessage(GetDlgItem(m_hwndDlg, IDC_COMBO_FILTER), CLB_GETCURSEL, 0, 0);
if (n != CB_ERR && m_pofn->lpstrFilter)
m_pofn->nFilterIndex = n + 1;
}
if (m_pszFilter) {
delete [] m_pszFilter;
m_pszFilter = NULL;
}
if (m_pszDefExt) {
delete [] m_pszDefExt;
m_pszDefExt = NULL;
}
ClearFilter();
DeleteExtList();
DestroyListView();
CommandBar_Destroy(m_hwndCB);
::EndDialog(m_hwndDlg, nResult);
}
BOOL CALLBACK CFileDialog::FileDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CFileDialog* pDlg = (CFileDialog*)GetWindowLong(hwndDlg, DWL_USER);
switch (uMsg) {
case WM_INITDIALOG:
pDlg = (CFileDialog*)lParam;
SetWindowLong(hwndDlg, DWL_USER, (DWORD)lParam);
return pDlg->OnInitDialog(hwndDlg);
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
if (GetFocus() == GetDlgItem(hwndDlg, IDC_LIST_FILE))
pDlg->OnListDblClk();
else
pDlg->OnOK();
return TRUE;
case IDCANCEL:
pDlg->EndDialog(LOWORD(wParam));
return TRUE;
case ID_LIST_STYLE_LIST:
pDlg->ChangeListStyle(LVS_LIST);
return TRUE;
case ID_LIST_STYLE_REPORT:
pDlg->ChangeListStyle(LVS_REPORT);
return TRUE;
case ID_LIST_SELECTALL:
pDlg->SelectAllItems();
return TRUE;
case ID_UP:
pDlg->OnUp();
return TRUE;
case IDC_COMBO_FILTER:
if (HIWORD(wParam) == LBN_SELCHANGE)
pDlg->OnCBSelChange();
return TRUE;
case ID_KEY_CTRL:
pDlg->OnSelMode();
return TRUE;
}
break;
case WM_NOTIFY:
{
NMHDR* pnmh = (NMHDR*)lParam;
switch (pnmh->code) {
case LVN_GETDISPINFO:
pDlg->OnGetDispInfo((NMLVDISPINFO*)lParam);
return TRUE;
case NM_CLICK:
pDlg->OnListClick();
return TRUE;
case NM_DBLCLK:
case NM_RETURN:
pDlg->OnListDblClk();
return TRUE;
case LVN_KEYDOWN:
pDlg->OnListKeyDown((NMLVKEYDOWN*)lParam);
return TRUE;
case LVN_COLUMNCLICK:
pDlg->OnListColumnClick((NMLISTVIEW*)lParam);
return TRUE;
case LVN_ITEMCHANGED:
pDlg->OnListItemChanged((NMLISTVIEW*)lParam);
return TRUE;
case LVN_ITEMCHANGING:
SetWindowLong(hwndDlg, DWL_MSGRESULT, pDlg->OnListItemChanging((NMLISTVIEW*)lParam));
return TRUE;
case UDN_DELTAPOS:
pDlg->OnSpinDeltaPos((NMUPDOWN*)lParam);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -