📄 filedlg.cpp
字号:
{
lvc.fmt = s_nListColumnFmt[i];
lvc.cx = s_nListColumnWidth[i]*scale;
lvc.iSubItem = i;
m_helper.LoadString(s_nListColumnTextId[i], sz, MAX_LOADSTRING);
ListView_InsertColumn(m_hwndLV, 3, &lvc);
}
m_ImageList.Init(m_fDlgType == DLG_TYPE_SMALL);
ListView_SetImageList(m_hwndLV, (HIMAGELIST)m_ImageList, LVSIL_SMALL);
SendMessage(m_hwndCB, TB_SETSTATE, ID_LIST_STYLE_LIST, TBSTATE_CHECKED | TBSTATE_ENABLED);
SendMessage(m_hwndCB, TB_SETSTATE, ID_LIST_STYLE_REPORT, TBSTATE_ENABLED);
}
void CFileDialog::DestroyListView()
{
DeleteAllListItem();
m_ImageList.Destroy();
}
void CFileDialog::DeleteAllListItem()
{
for (int i = 0; i < ListView_GetItemCount(m_hwndLV); i++) {
LIST_ITEM_INFO* pDel = GetListItemInfo(i);
if (pDel->pszDispName) delete[] pDel->pszDispName;
if (pDel->pszDispSize) delete[] pDel->pszDispSize;
if (pDel->pszDispType) delete[] pDel->pszDispType;
if (pDel->pszDispTime) delete[] pDel->pszDispTime;
delete[] pDel->pszName;
delete pDel;
}
ListView_DeleteAllItems(m_hwndLV);
}
BOOL CFileDialog::LoadFolderItem(LPCTSTR pszPath, BOOL fFocus)
{
if (!pszPath)
return FALSE;
DWORD dwAttr = GetFileAttributes(pszPath);
if (dwAttr == 0xFFFFFFFF ||
!(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
return FALSE;
HCURSOR hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
ShowWindow(m_hwndLV, SW_HIDE);
m_helper.SHChangeNotifyDeregister(m_hwndDlg);
DeleteAllListItem();
TCHAR sz[MAX_PATH];
TCHAR szPath[MAX_PATH];
WIN32_FIND_DATA wfd;
_tcscpy(szPath, pszPath);
LPTSTR psz = _tcsrchr(szPath, _T('\\'));
if (psz && *(psz + 1) == NULL)
*psz = NULL;
// folder
wsprintf(sz, _T("%s\\*.*"), szPath);
HANDLE hFind = FindFirstFile(sz, &wfd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)||m_listExt.IsEmpty()||IsFolderShortcut(szPath, wfd.cFileName))
AddListItem(szPath, &wfd);
}
while (FindNextFile(hFind, &wfd));
FindClose(hFind);
}
// files
if (m_pszFilter) {
wsprintf(sz, _T("%s\\%s"), szPath, m_pszFilter);
hFind = FindFirstFile(sz, &wfd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
!IsFolderShortcut(szPath, wfd.cFileName))
AddListItem(szPath, &wfd);
}
while (FindNextFile(hFind, &wfd));
FindClose(hFind);
}
}
else {
int n = m_listExt.GetCount();
for (int i = 0; i < n; i++) {
LPTSTR p = (LPTSTR)m_listExt.GetAt(i);
wsprintf(sz, _T("%s\\%s"), szPath, p);
hFind = FindFirstFile(sz, &wfd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
!IsFolderShortcut(szPath, wfd.cFileName))
AddListItem(szPath, &wfd);
}
while (FindNextFile(hFind, &wfd));
FindClose(hFind);
}
}
}
if (ListView_GetItemCount(m_hwndLV)) {
SortList();
ListView_SetItemState(m_hwndLV, 0, LVIS_FOCUSED, LVIS_FOCUSED);
}
_tcscpy(m_szCurrent, szPath);
SetDlgItemText(m_hwndDlg, IDC_STATIC_CURRENT_TEXT, GetDisplayName(m_szCurrent));
BOOL fUp = (_tcslen(szPath) && _tcscmp(szPath, bslash) != 0);
SendMessage(m_hwndCB, TB_SETSTATE, ID_UP, fUp ? TBSTATE_ENABLED : TBSTATE_INDETERMINATE);
SHCHANGENOTIFYENTRY scne={-1,m_szCurrent};
m_helper.SHChangeNotifyRegister(m_hwndDlg,&scne);
SetCursor(hCursor);
ShowWindow(m_hwndLV, SW_SHOW);
UpdateWindow(m_hwndLV);
if (fFocus)
SetFocus(m_hwndLV);
return TRUE;
}
void CFileDialog::SortList()
{
const PFNLVCOMPARE fnSort[]={ListSortCompareFuncByName,ListSortCompareFuncByExt,ListSortCompareFuncBySize,ListSortCompareFuncByTime};
ListView_SortItems(m_hwndLV, fnSort[m_nListSort], m_fSortOrder);
}
void CFileDialog::AddListItem(LPCTSTR pszPath, WIN32_FIND_DATA* pwfd, int ix)
{
LVITEM li;
LIST_ITEM_INFO* p;
if (!m_fViewAll && (pwfd->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
return;
if (pwfd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
p = new LIST_ITEM_INFO;
p->type = ITEM_TYPE_DIR;
p->pszName = new TCHAR[_tcslen(pwfd->cFileName) + 1];
memset(p->pszName, 0, sizeof(TCHAR) * (_tcslen(pwfd->cFileName) + 1));
_tcscpy(p->pszName, pwfd->cFileName);
p->llSize = 0;
p->ft = pwfd->ftCreationTime;
li.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
li.iItem = ix;
li.iSubItem = 0;
li.iImage = I_IMAGECALLBACK;
li.lParam = (DWORD)p;
li.pszText = LPSTR_TEXTCALLBACK;
ListView_InsertItem(m_hwndLV, &li);
ListView_SetItemText(m_hwndLV, 0, 2, LPSTR_TEXTCALLBACK);
}
else {
p = new LIST_ITEM_INFO;
p->type = ITEM_TYPE_FILE;
p->pszName = new TCHAR[_tcslen(pwfd->cFileName) + 1];
memset(p->pszName, 0, sizeof(TCHAR) * (_tcslen(pwfd->cFileName) + 1));
_tcscpy(p->pszName, pwfd->cFileName);
p->llSize = ((ULONGLONG)pwfd->nFileSizeHigh << 32) | pwfd->nFileSizeLow;
p->ft = pwfd->ftLastWriteTime;
FileTimeToLocalFileTime(&p->ft, &p->ft);
li.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
li.iItem = ix;
li.iSubItem = 0;
li.iImage = I_IMAGECALLBACK;
li.lParam = (DWORD)p;
li.pszText = LPSTR_TEXTCALLBACK;
ListView_InsertItem(m_hwndLV, &li);
ListView_SetItemText(m_hwndLV, 0, 1, LPSTR_TEXTCALLBACK);
ListView_SetItemText(m_hwndLV, 0, 2, LPSTR_TEXTCALLBACK);
ListView_SetItemText(m_hwndLV, 0, 3, LPSTR_TEXTCALLBACK);
}
}
LIST_ITEM_INFO* CFileDialog::GetListItemInfo(int nIndex)
{
LVITEM li;
li.iItem = nIndex;
li.iSubItem = 0;
li.mask = LVIF_PARAM;
ListView_GetItem(m_hwndLV, &li);
return (LIST_ITEM_INFO*)li.lParam;
}
int CFileDialog::GetSelectedItemIndex(int nStart)
{
int nIndex = -1;
int nItemCount = ListView_GetItemCount(m_hwndLV);
for (int i = nStart; i < nItemCount; i++) {
if (ListView_GetItemState(m_hwndLV, i, LVIS_SELECTED) == LVIS_SELECTED)
return i;
}
return -1;
}
void CFileDialog::OnGetDispInfo(NMLVDISPINFO* pnmdi)
{
LIST_ITEM_INFO* p = GetListItemInfo(pnmdi->item.iItem);
if (pnmdi->item.mask & LVIF_IMAGE) {
if (p->nIcon == -1)
p->nIcon = m_ImageList.GetImageListIndex(p->pszName, m_szCurrent);
pnmdi->item.iImage = p->nIcon;
}
if ((pnmdi->item.mask & LVIF_TEXT)) {
if (p->type == ITEM_TYPE_DIR) {
switch (pnmdi->item.iSubItem) {
case 0: //Name
pnmdi->item.pszText = p->pszName;
break;
case 2: //Type
{
if (!p->pszDispType) {
TCHAR sz[MAX_PATH];
SHFILEINFO shfi;
p->pszDispType = new TCHAR[80]; // ???
wsprintf(sz, _T("%s\\%s"), m_szCurrent, p->pszName);
SHGetFileInfo(sz, NULL, &shfi, sizeof(shfi), SHGFI_TYPENAME);
_tcscpy(p->pszDispType, shfi.szTypeName);
}
pnmdi->item.pszText = p->pszDispType;
break;
}
default: break;
}
}
else
{
switch (pnmdi->item.iSubItem) {
case 0: //Name
{
if (!p->pszDispName) {
if (m_fShowExt) {
pnmdi->item.pszText = p->pszName;
break;
}
else {
p->pszDispName = new TCHAR[_tcslen(p->pszName) + 1];
_tcscpy(p->pszDispName, p->pszName);
LPTSTR psz = _tcsrchr(p->pszDispName, _T('.'));
if (psz)
*psz = NULL;
}
}
pnmdi->item.pszText = p->pszDispName;
break;
}
case 1: //Size
{
if (!p->pszDispSize) {
p->pszDispSize = new TCHAR[64];
SetFormatSize((DWORD)p->llSize, p->pszDispSize, _T("%s KB"), _T("%s MB"));
// todo : 2^32 bytes埲忋偺僼傽僀儖懳墳
}
pnmdi->item.pszText = p->pszDispSize;
break;
}
case 2: //Type
{
if (!p->pszDispType) {
TCHAR sz[MAX_PATH];
SHFILEINFO shfi;
p->pszDispType = new TCHAR[80]; // ???
wsprintf(sz, _T("%s\\%s"), m_szCurrent, p->pszName);
SHGetFileInfo(sz, NULL, &shfi, sizeof(shfi), SHGFI_TYPENAME);
_tcscpy(p->pszDispType, shfi.szTypeName);
}
pnmdi->item.pszText = p->pszDispType;
break;
}
case 3: //Date
{
if (!p->pszDispTime)
{
p->pszDispTime = new TCHAR[32];
SYSTEMTIME st;
FileTimeToSystemTime(&p->ft, &st);
SetFormatDateTime(&st, p->pszDispTime, 32);
}
pnmdi->item.pszText = p->pszDispTime;
break;
}
default: break;
}
}
}
}
void CFileDialog::CreateExtList()
{
DeleteExtList();
HWND hwndCombo = GetDlgItem(m_hwndDlg, IDC_COMBO_FILTER);
int nIndex = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
if (nIndex == CB_ERR)
return;
TCHAR sz[MAX_LOADSTRING];
LPTSTR p;
LPTSTR pszSrc = (LPTSTR)SendMessage(hwndCombo, CB_GETITEMDATA, nIndex, 0);
while (TRUE) {
p = sz;
while (*pszSrc != _T(';') && *pszSrc != _T(',') && *pszSrc != NULL) {
*p++ = *pszSrc;
pszSrc++;
}
*p = NULL;
p = new TCHAR[_tcslen(sz) + 1];
_tcscpy(p, sz);
m_listExt.Add((DWORD)p);
if (*pszSrc == NULL)
break;
pszSrc++;
}
}
void CFileDialog::DeleteExtList()
{
LPTSTR p;
while (!m_listExt.IsEmpty()) {
p = (LPTSTR)m_listExt.RemoveAt(0);
delete [] p;
}
}
void CFileDialog::OnCBSelChange()
{
if (m_pszFilter) {
delete [] m_pszFilter;
m_pszFilter = NULL;
}
CreateExtList();
LoadFolderItem(m_szCurrent, FALSE);
}
LPTSTR CFileDialog::GetDisplayName(LPTSTR pszPath)
{
if (!_tcslen(pszPath) || _tcscmp(pszPath, bslash) == 0)
return m_szRootName;
else
return pszPath;
}
void CFileDialog::ChangeListStyle(DWORD dwNewStyle)
{
DWORD dwStyle = GetWindowLong(m_hwndLV, GWL_STYLE);
#if 0
switch (dwStyle & LVS_TYPEMASK) {
case LVS_ICON: dwStyle ^= LVS_ICON; break;
case LVS_SMALLICON: dwStyle ^= LVS_SMALLICON; break;
case LVS_LIST: dwStyle ^= LVS_LIST; break;
case LVS_REPORT: dwStyle ^= LVS_REPORT; break;
}
#else
dwStyle &= ~DWORD(LVS_TYPEMASK);
#endif
dwStyle |= dwNewStyle;
SetWindowLong(m_hwndLV, GWL_STYLE, dwStyle);
if (m_fDlgType == DLG_TYPE_PPC3 && dwNewStyle == LVS_REPORT) {
ListView_SetExtendedListViewStyle(m_hwndLV, ListView_GetExtendedListViewStyle(m_hwndLV) |
0x00000040 /*LVS_EX_ONECLICKACTIVATE*/ | LVS_EX_FULLROWSELECT | LVS_EX_TRACKSELECT);
}
else
ListView_SetExtendedListViewStyle(m_hwndLV, 0);
SendMessage(m_hwndCB, TB_SETSTATE, ID_LIST_STYLE_LIST, TBSTATE_ENABLED|((dwNewStyle == LVS_LIST)?TBSTATE_CHECKED:0));
SendMessage(m_hwndCB, TB_SETSTATE, ID_LIST_STYLE_REPORT, TBSTATE_ENABLED|((dwNewStyle == LVS_REPORT)?TBSTATE_CHECKED:0));
TBBUTTON tbb;
SendMessage(m_hwndCB, TB_GETBUTTON, 1, (LPARAM)&tbb);
HMENU hMenu=HMENU(tbb.dwData);
if(hMenu)
{
CheckMenuRadioItem(hMenu,ID_LIST_STYLE_LIST,ID_LIST_STYLE_REPORT,(dwNewStyle == LVS_LIST)?ID_LIST_STYLE_LIST:ID_LIST_STYLE_REPORT,MF_BYCOMMAND);
}
}
void CFileDialog::OnUp()
{
TCHAR szPath[MAX_PATH] = _T("");
if (!_tcslen(m_szCurrent) || _tcscmp(m_szCurrent, bslash) == 0)
return;
_tcscpy(szPath, m_szCurrent);
LPTSTR psz = _tcsrchr(szPath, _T('\\'));
if (psz) *psz = NULL;
LoadFolderItem(szPath);
}
void CFileDialog::OnListClick()
{
if (m_fDlgType == DLG_TYPE_PPC3 &&
!GetAsyncKeyState(VK_CONTROL) &&
!GetAsyncKeyState(VK_SHIFT) &&
ListView_GetSelectedCount(m_hwndLV) < 2)
OnListDblClk();
}
void CFileDialog::OnListDblClk()
{
int nIndex = GetSelectedItemIndex(0);
if (nIndex != -1) {
TCHAR szPath[MAX_PATH];
LIST_ITEM_INFO* p = GetListItemInfo(nIndex);
if (p->type == ITEM_TYPE_DIR) {
wsprintf(szPath, _T("%s\\%s"), m_szCurrent, p->pszName);
LoadFolderItem(szPath);
}
else if (IsFolderShortcut(m_szCurrent, p->pszName)) {
TCHAR szTarget[MAX_PATH];
wsprintf(szPath, _T("%s\\%s"), m_szCurrent, p->pszName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -