windows-nt/Source/XPSP1/NT/shell/osshell/accesory/packager/filedlgs.c
2020-09-26 16:20:57 +08:00

299 lines
7.1 KiB
C

/* filedlgs.c - Handles the Windows 3.1 common dialogs.
*
* Created by Microsoft Corporation.
*/
#include "packager.h"
#include <commdlg.h>
static CHAR szCustFilterSpec[CBFILTERMAX];
static CHAR szFilterSpec[CBFILTERMAX];
static CHAR szLinkCaption[CBMESSAGEMAX];
static CHAR szImportFile[CBMESSAGEMAX];
static CHAR szExportFile[CBMESSAGEMAX];
static OPENFILENAME gofn;
static VOID AddExtension(LPOPENFILENAME lpOFN);
/* OfnInit() - Initializes the standard file dialog gofn structure.
*/
VOID
OfnInit(
VOID
)
{
LPSTR lpstr;
gofn.lStructSize = sizeof(OPENFILENAME);
gofn.hInstance = ghInst;
gofn.nMaxCustFilter = CBFILTERMAX;
gofn.nMaxFile = CBPATHMAX;
gofn.lCustData = 0;
gofn.lpfnHook = NULL;
gofn.lpTemplateName = NULL;
gofn.lpstrFileTitle = NULL;
LoadString(ghInst, IDS_IMPORTFILE, szImportFile, CBMESSAGEMAX);
LoadString(ghInst, IDS_EXPORTFILE, szExportFile, CBMESSAGEMAX);
LoadString(ghInst, IDS_CHANGELINK, szLinkCaption, CBMESSAGEMAX);
LoadString(ghInst, IDS_ALLFILTER, szFilterSpec, CBMESSAGEMAX);
StringCchCat(szFilterSpec, ARRAYSIZE(szFilterSpec), "*.*");
}
/* OfnGetName() - Calls the standard file dialogs to get a file name
*/
BOOL
OfnGetName(
HWND hwnd,
UINT msg
)
{
gofn.hwndOwner = hwnd;
gofn.nFilterIndex = 1;
gofn.lpstrCustomFilter = szCustFilterSpec;
gofn.lpstrDefExt = NULL;
gofn.lpstrFile = gszFileName;
gofn.lpstrFilter = szFilterSpec;
gofn.lpstrInitialDir = NULL;
gofn.Flags = OFN_HIDEREADONLY;
Normalize(gszFileName);
switch (msg)
{
case IDM_IMPORT:
gofn.lpstrTitle = szImportFile;
gofn.Flags |= OFN_FILEMUSTEXIST;
return GetOpenFileName(&gofn);
case IDM_EXPORT:
gofn.lpstrTitle = szExportFile;
gofn.Flags |= (OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN);
return GetSaveFileName(&gofn);
default:
break;
}
return FALSE;
}
/* OfnGetNewLinkName() - Sets up the "Change Link..." dialog box
*/
HANDLE
OfnGetNewLinkName(
HWND hwnd,
HANDLE hData
)
{
BOOL fSuccess = FALSE;
HANDLE hData2 = NULL;
HANDLE hData3 = NULL;
LPSTR lpstrData = NULL;
LPSTR lpstrFile = NULL;
LPSTR lpstrLink = NULL;
LPSTR lpstrPath = NULL;
LPSTR lpstrTemp = NULL;
CHAR szDocFile[CBPATHMAX];
CHAR szDocPath[CBPATHMAX];
CHAR szServerFilter[4 * CBPATHMAX];
// this may have to GlobalAlloc(), if a class supports
// multiple extensions, like Pbrush then we could be in
// trouble. I covered PBRUSH case by making array size 256
// Get the link information
if (!(lpstrData = GlobalLock(hData)))
goto Error;
// Figure out the link's path name and file name
lpstrTemp = lpstrData;
while (*lpstrTemp++)
;
lpstrPath = lpstrFile = lpstrTemp;
while (*(lpstrTemp = CharNext(lpstrTemp)))
{
if (*lpstrTemp == '\\')
lpstrFile = lpstrTemp + 1;
}
// Copy the document name
StringCchCopy(szDocFile, ARRAYSIZE(szDocFile), lpstrFile);
*(lpstrFile - 1) = 0;
// Copy the path name
StringCchCopy(szDocPath, ARRAYSIZE(szDocPath), ((lpstrPath != lpstrFile) ? lpstrPath : ""));
// If no directory, be sure the path points to the root
if (lstrlen(szDocPath) == 2)
StringCchCat(szDocPath, ARRAYSIZE(szDocPath), "\\");
if (lpstrPath != lpstrFile) /* Restore the backslash */
*(lpstrFile - 1) = '\\';
while (*lpstrFile != '.' && *lpstrFile) /* Get the extension */
lpstrFile++;
// Make a filter that respects the link's class name
gofn.hwndOwner = hwnd;
gofn.nFilterIndex = RegMakeFilterSpec(lpstrData, lpstrFile, szServerFilter);
gofn.lpstrDefExt = NULL;
gofn.lpstrFile = szDocFile;
gofn.lpstrFilter = szServerFilter;
gofn.lpstrInitialDir = szDocPath;
gofn.lpstrTitle = szLinkCaption;
gofn.lpstrCustomFilter = szCustFilterSpec;
gofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
// If we get a file...
if (GetOpenFileName(&gofn))
{
if (!(hData2 = GlobalAlloc(GMEM_ZEROINIT, CBPATHMAX *
2)) || !(lpstrLink = lpstrTemp = GlobalLock(hData2)))
goto Error;
// ...add on the correct extension
AddExtension(&gofn);
// ... copy the server name
while (*lpstrTemp++ = *lpstrData++)
;
// ... copy the document name
lstrcpy(lpstrTemp, szDocFile);
lpstrTemp += lstrlen(lpstrTemp) + 1;
lpstrData += lstrlen(lpstrData) + 1;
// ... copy the item name
while (*lpstrTemp++ = *lpstrData++)
;
*lpstrTemp = 0;
// ... and compress the memory block to minimal size
GlobalUnlock(hData2);
hData3 = GlobalReAlloc(hData2, (DWORD)(lpstrTemp - lpstrLink + 1), 0);
if (!hData3)
hData3 = hData2;
fSuccess = TRUE;
}
Error:
if (!fSuccess)
{
if (lpstrLink)
GlobalUnlock(hData2);
if (hData2)
GlobalFree(hData2);
hData3 = NULL;
}
if (lpstrData)
GlobalUnlock(hData);
return hData3;
}
/* Normalize() - Removes the path specification from the file name.
*
* Note: It isn't possible to get "<drive>:<filename>" as input because
* the path received will always be fully qualified.
*/
VOID
Normalize(
LPSTR lpstrFile
)
{
LPSTR lpstrBackslash = NULL;
LPSTR lpstrTemp = lpstrFile;
BOOL fInQuote = FALSE;
BOOL fQState = FALSE;
while (*lpstrTemp)
{
if (*lpstrTemp == CHAR_QUOTE)
fInQuote = !fInQuote;
if (*lpstrTemp == '\\') {
fQState = fInQuote;
lpstrBackslash = lpstrTemp;
}
if (gbDBCS)
{
lpstrTemp = CharNext(lpstrTemp);
}
else
{
lpstrTemp++;
}
}
if (lpstrBackslash) {
if (fQState)
*lpstrFile++ = CHAR_QUOTE;
MoveMemory(lpstrFile, lpstrBackslash + 1,
lstrlen(lpstrBackslash) * sizeof(lpstrBackslash[0]) );
}
}
/* AddExtension() - Adds the extension corresponding to the filter dropdown.
*/
static VOID
AddExtension(
LPOPENFILENAME lpOFN
)
{
LPSTR lpstrFilter = (LPSTR)lpOFN->lpstrFilter;
// If the user didn't specify an extension, use the default
if (lpOFN->nFileExtension == (UINT)lstrlen(lpOFN->lpstrFile)
&& lpOFN->nFilterIndex)
{
// Skip to the appropriate filter
while (*lpstrFilter && --lpOFN->nFilterIndex)
{
while (*lpstrFilter++)
;
while (*lpstrFilter++)
;
}
// If we got to the filter, retrieve the extension
if (*lpstrFilter)
{
while (*lpstrFilter++)
;
lpstrFilter++;
// Copy the extension
if (lpstrFilter[1] != '*')
lstrcat(lpOFN->lpstrFile, lpstrFilter);
}
}
}