📄 filedlg.c
字号:
break;
/* Filetype combo box */
case IDC_FILETYPE:
FILEDLG95_FILETYPE_OnCommand(hwnd,wNotifyCode);
break;
/* LookIn combo box */
case IDC_LOOKIN:
FILEDLG95_LOOKIN_OnCommand(hwnd,wNotifyCode);
break;
/* --- toolbar --- */
/* Up folder button */
case FCIDM_TB_UPFOLDER:
FILEDLG95_SHELL_UpFolder(hwnd);
break;
/* New folder button */
case FCIDM_TB_NEWFOLDER:
FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_NEWFOLDERA);
break;
/* List option button */
case FCIDM_TB_SMALLICON:
FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWLISTA);
break;
/* Details option button */
case FCIDM_TB_REPORTVIEW:
FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWDETAILSA);
break;
/* Details option button */
case FCIDM_TB_DESKTOP:
FILEDLG95_SHELL_BrowseToDesktop(hwnd);
break;
case IDC_FILENAME:
break;
}
/* Do not use the listview selection anymore */
fodInfos->DlgInfos.dwDlgProp &= ~FODPROP_USEVIEW;
return 0;
}
/***********************************************************************
* FILEDLG95_OnWMGetIShellBrowser
*
* WM_GETISHELLBROWSER message handler
*/
static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
{
FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
TRACE("\n");
SetWindowLongPtrW(hwnd,DWLP_MSGRESULT,(LONG_PTR)fodInfos->Shell.FOIShellBrowser);
return TRUE;
}
/***********************************************************************
* FILEDLG95_SendFileOK
*
* Sends the CDN_FILEOK notification if required
*
* RETURNS
* TRUE if the dialog should close
* FALSE if the dialog should not be closed
*/
static BOOL FILEDLG95_SendFileOK( HWND hwnd, FileOpenDlgInfos *fodInfos )
{
/* ask the hook if we can close */
if(IsHooked(fodInfos))
{
LRESULT retval;
TRACE("---\n");
/* First send CDN_FILEOK as MSDN doc says */
retval = SendCustomDlgNotificationMessage(hwnd,CDN_FILEOK);
if (GetWindowLongPtrW(fodInfos->DlgInfos.hwndCustomDlg, DWLP_MSGRESULT))
{
TRACE("canceled\n");
return (retval == 0);
}
/* fodInfos->ofnInfos points to an ASCII or UNICODE structure as appropriate */
retval = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg,
fodInfos->HookMsg.fileokstring, 0, (LPARAM)fodInfos->ofnInfos);
if (GetWindowLongPtrW(fodInfos->DlgInfos.hwndCustomDlg, DWLP_MSGRESULT))
{
TRACE("canceled\n");
return (retval == 0);
}
}
return TRUE;
}
/***********************************************************************
* FILEDLG95_OnOpenMultipleFiles
*
* Handles the opening of multiple files.
*
* FIXME
* check destination buffer size
*/
BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed)
{
WCHAR lpstrPathSpec[MAX_PATH] = {0};
UINT nCount, nSizePath;
FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
TRACE("\n");
if(fodInfos->unicode)
{
LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
ofn->lpstrFile[0] = '\0';
}
else
{
LPOPENFILENAMEA ofn = (LPOPENFILENAMEA) fodInfos->ofnInfos;
ofn->lpstrFile[0] = '\0';
}
COMDLG32_GetDisplayNameOf( fodInfos->ShellInfos.pidlAbsCurrent, lpstrPathSpec );
if ( !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) &&
( fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST) &&
! ( fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG ) )
{
LPWSTR lpstrTemp = lpstrFileList;
for ( nCount = 0; nCount < nFileCount; nCount++ )
{
LPITEMIDLIST pidl;
pidl = GetPidlFromName(fodInfos->Shell.FOIShellFolder, lpstrTemp);
if (!pidl)
{
WCHAR lpstrNotFound[100];
WCHAR lpstrMsg[100];
WCHAR tmp[400];
static const WCHAR nl[] = {'\n',0};
LoadStringW(COMDLG32_hInstance, IDS_FILENOTFOUND, lpstrNotFound, 100);
LoadStringW(COMDLG32_hInstance, IDS_VERIFYFILE, lpstrMsg, 100);
lstrcpyW(tmp, lpstrTemp);
lstrcatW(tmp, nl);
lstrcatW(tmp, lpstrNotFound);
lstrcatW(tmp, nl);
lstrcatW(tmp, lpstrMsg);
MessageBoxW(hwnd, tmp, fodInfos->title, MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
/* move to the next file in the list of files */
lpstrTemp += lstrlenW(lpstrTemp) + 1;
COMDLG32_SHFree(pidl);
}
}
nSizePath = lstrlenW(lpstrPathSpec) + 1;
if ( !(fodInfos->ofnInfos->Flags & OFN_EXPLORER) )
{
/* For "oldstyle" dialog the components have to
be separated by blanks (not '\0'!) and short
filenames have to be used! */
FIXME("Components have to be separated by blanks\n");
}
if(fodInfos->unicode)
{
LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
lstrcpyW( ofn->lpstrFile, lpstrPathSpec);
memcpy( ofn->lpstrFile + nSizePath, lpstrFileList, sizeUsed*sizeof(WCHAR) );
}
else
{
LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos;
if (ofn->lpstrFile != NULL)
{
nSizePath = WideCharToMultiByte(CP_ACP, 0, lpstrPathSpec, -1,
ofn->lpstrFile, ofn->nMaxFile, NULL, NULL);
if (ofn->nMaxFile > nSizePath)
{
WideCharToMultiByte(CP_ACP, 0, lpstrFileList, sizeUsed,
ofn->lpstrFile + nSizePath,
ofn->nMaxFile - nSizePath, NULL, NULL);
}
}
}
fodInfos->ofnInfos->nFileOffset = nSizePath;
fodInfos->ofnInfos->nFileExtension = 0;
if ( !FILEDLG95_SendFileOK(hwnd, fodInfos) )
return FALSE;
/* clean and exit */
FILEDLG95_Clean(hwnd);
return EndDialog(hwnd,TRUE);
}
/***********************************************************************
* FILEDLG95_OnOpen
*
* Ok button WM_COMMAND message handler
*
* If the function succeeds, the return value is nonzero.
*/
#define ONOPEN_BROWSE 1
#define ONOPEN_OPEN 2
#define ONOPEN_SEARCH 3
static void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText)
{
WCHAR strMsgTitle[MAX_PATH];
WCHAR strMsgText [MAX_PATH];
if (idCaption)
LoadStringW(COMDLG32_hInstance, idCaption, strMsgTitle, sizeof(strMsgTitle)/sizeof(WCHAR));
else
strMsgTitle[0] = '\0';
LoadStringW(COMDLG32_hInstance, idText, strMsgText, sizeof(strMsgText)/sizeof(WCHAR));
MessageBoxW(hwnd,strMsgText, strMsgTitle, MB_OK | MB_ICONHAND);
}
BOOL FILEDLG95_OnOpen(HWND hwnd)
{
LPWSTR lpstrFileList;
UINT nFileCount = 0;
UINT sizeUsed = 0;
BOOL ret = TRUE;
WCHAR lpstrPathAndFile[MAX_PATH];
WCHAR lpstrTemp[MAX_PATH];
LPSHELLFOLDER lpsf = NULL;
int nOpenAction;
FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
TRACE("hwnd=%p\n", hwnd);
/* get the files from the edit control */
nFileCount = FILEDLG95_FILENAME_GetFileNames(hwnd, &lpstrFileList, &sizeUsed, '\0');
/* try if the user selected a folder in the shellview */
if(nFileCount == 0)
{
BrowseSelectedFolder(hwnd);
return FALSE;
}
if(nFileCount > 1)
{
ret = FILEDLG95_OnOpenMultipleFiles(hwnd, lpstrFileList, nFileCount, sizeUsed);
goto ret;
}
TRACE("count=%u len=%u file=%s\n", nFileCount, sizeUsed, debugstr_w(lpstrFileList));
/*
Step 1: Build a complete path name from the current folder and
the filename or path in the edit box.
Special cases:
- the path in the edit box is a root path
(with or without drive letter)
- the edit box contains ".." (or a path with ".." in it)
*/
/* Get the current directory name */
if (!COMDLG32_GetDisplayNameOf(fodInfos->ShellInfos.pidlAbsCurrent, lpstrPathAndFile))
{
/* last fallback */
GetCurrentDirectoryW(MAX_PATH, lpstrPathAndFile);
}
PathAddBackslashW(lpstrPathAndFile);
TRACE("current directory=%s\n", debugstr_w(lpstrPathAndFile));
/* if the user specifyed a fully qualified path use it */
if(PathIsRelativeW(lpstrFileList))
{
lstrcatW(lpstrPathAndFile, lpstrFileList);
}
else
{
/* does the path have a drive letter? */
if (PathGetDriveNumberW(lpstrFileList) == -1)
lstrcpyW(lpstrPathAndFile+2, lpstrFileList);
else
lstrcpyW(lpstrPathAndFile, lpstrFileList);
}
/* resolve "." and ".." */
PathCanonicalizeW(lpstrTemp, lpstrPathAndFile );
lstrcpyW(lpstrPathAndFile, lpstrTemp);
TRACE("canon=%s\n", debugstr_w(lpstrPathAndFile));
MemFree(lpstrFileList);
/*
Step 2: here we have a cleaned up path
We have to parse the path step by step to see if we have to browse
to a folder if the path points to a directory or the last
valid element is a directory.
valid variables:
lpstrPathAndFile: cleaned up path
*/
if (nFileCount &&
(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) &&
!(fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST))
nOpenAction = ONOPEN_OPEN;
else
nOpenAction = ONOPEN_BROWSE;
/* don't apply any checks with OFN_NOVALIDATE */
{
LPWSTR lpszTemp, lpszTemp1;
LPITEMIDLIST pidl = NULL;
static const WCHAR szwInvalid[] = { '/',':','<','>','|', 0};
/* check for invalid chars */
if((strpbrkW(lpstrPathAndFile+3, szwInvalid) != NULL) && !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE))
{
FILEDLG95_OnOpenMessage(hwnd, IDS_INVALID_FILENAME_TITLE, IDS_INVALID_FILENAME);
ret = FALSE;
goto ret;
}
if (FAILED (SHGetDesktopFolder(&lpsf))) return FALSE;
lpszTemp1 = lpszTemp = lpstrPathAndFile;
while (lpszTemp1)
{
LPSHELLFOLDER lpsfChild;
WCHAR lpwstrTemp[MAX_PATH];
DWORD dwEaten, dwAttributes;
LPWSTR p;
lstrcpyW(lpwstrTemp, lpszTemp);
p = PathFindNextComponentW(lpwstrTemp);
if (!p) break; /* end of path */
*p = 0;
lpszTemp = lpszTemp + lstrlenW(lpwstrTemp);
/* There are no wildcards when OFN_NOVALIDATE is set */
if(*lpszTemp==0 && !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE))
{
static const WCHAR wszWild[] = { '*', '?', 0 };
/* if the last element is a wildcard do a search */
if(strpbrkW(lpszTemp1, wszWild) != NULL)
{
nOpenAction = ONOPEN_SEARCH;
break;
}
}
lpszTemp1 = lpszTemp;
TRACE("parse now=%s next=%s sf=%p\n",debugstr_w(lpwstrTemp), debugstr_w(lpszTemp), lpsf);
/* append a backslash to drive letters */
if(lstrlenW(lpwstrTemp)==2 && lpwstrTemp[1] == ':' &&
((lpwstrTemp[0] >= 'a' && lpwstrTemp[0] <= 'z') ||
(lpwstrTemp[0] >= 'A' && lpwstrTemp[0] <= 'Z')))
{
PathAddBackslashW(lpwstrTemp);
}
dwAttributes = SFGAO_FOLDER;
if(SUCCEEDED(IShellFolder_ParseDisplayName(lpsf, hwnd, NULL, lpwstrTemp, &dwEaten, &pidl, &dwAttributes)))
{
/* the path component is valid, we have a pidl of the next path component */
TRACE("parse OK attr=0x%08x pidl=%p\n", dwAttributes, pidl);
if(dwAttributes & SFGAO_FOLDER)
{
if(FAILED(IShellFolder_BindToObject(lpsf, pidl, 0, &IID_IShellFolder, (LPVOID*)&lpsfChild)))
{
ERR("bind to failed\n"); /* should not fail */
break;
}
IShellFolder_Release(lpsf);
lpsf = lpsfChild;
lpsfChild = NULL;
}
else
{
TRACE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -