Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
fileopen.c
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 300k
Category:
Windows Kernel
Development Platform:
Visual C++
- /*++
- Copyright (c) 1990-1998, Microsoft Corporation All rights reserved.
- Module Name:
- fileopen.c
- Abstract:
- This module implements the Win32 fileopen dialogs.
- Revision History:
- --*/
- //
- // Include Files.
- //
- #if (_WIN32_WINNT < 0x0500)
- #undef _WIN32_WINNT
- #define _WIN32_WINNT 0x0500
- #endif
- #include "comdlg32.h"
- #include <lm.h>
- #include <winnetwk.h>
- #include <winnetp.h>
- #include <shellapi.h>
- #include <shlobj.h>
- #include <commctrl.h>
- #include <shsemip.h>
- #include "fileopen.h"
- #include "util.h"
- //
- // Constant Declarations.
- //
- #define WNTYPE_DRIVE 1
- #define MIN_DEFEXT_LEN 4
- #define BMPHIOFFSET 9
- //
- // hbmpDirs array index values.
- // Note: Two copies: for standard background, and hilite.
- // Relative order is important.
- //
- #define OPENDIRBMP 0
- #define CURDIRBMP 1
- #define STDDIRBMP 2
- #define FLOPPYBMP 3
- #define HARDDRVBMP 4
- #define CDDRVBMP 5
- #define NETDRVBMP 6
- #define RAMDRVBMP 7
- #define REMDRVBMP 8
- //
- // If the following disktype is passed to AddDisk, then bTmp will be
- // set to true in the DISKINFO structure (if the disk is new).
- //
- #define TMPNETDRV 9
- #define MAXDOSFILENAMELEN (12 + 1) // 8.3 filename + 1 for NULL
- //
- // Maximum number of filters on one filter line.
- //
- #define MAXFILTERS 36
- //
- // File exclusion bits (don't show files of these types).
- //
- #define EXCLBITS (FILE_ATTRIBUTE_HIDDEN)
- //
- // Global Variables.
- //
- //
- // Caching drive list.
- //
- extern DWORD dwNumDisks;
- extern OFN_DISKINFO gaDiskInfo[MAX_DISKS];
- extern TCHAR g_szInitialCurDir[MAX_PATH];
- DWORD dwNumDlgs = 0;
- //
- // Used to update the dialogs after coming back from the net dlg button.
- //
- BOOL bGetNetDrivesSync = FALSE;
- LPTSTR lpNetDriveSync = NULL;
- BOOL bNetworkInstalled = TRUE;
- //
- // Following array is used to send messages to all dialog box threads
- // that have requested enumeration updating from the worker
- // thread. The worker thread sends off a message to each slot
- // in the array that is non-NULL.
- //
- HWND gahDlg[MAX_THREADS];
- //
- // Strings for Filter Parsing.
- //
- const static TCHAR szSemiColonSpaceTab[] = TEXT("; t");
- const static TCHAR szSemiColonTab[] = TEXT(";t");
- //
- // For WNet apis.
- //
- HANDLE hLNDThread = NULL;
- WNDPROC lpLBProc = NULL;
- WNDPROC lpOKProc = NULL;
- //
- // Drive/Dir bitmap dimensions.
- //
- LONG dxDirDrive = 0;
- LONG dyDirDrive = 0;
- //
- // BUGBUG: This needs to be on a per dialog basis for multi-threaded apps.
- //
- WORD wNoRedraw = 0;
- UINT msgWOWDIRCHANGE;
- UINT msgLBCHANGEA;
- UINT msgSHAREVIOLATIONA;
- UINT msgFILEOKA;
- UINT msgLBCHANGEW;
- UINT msgSHAREVIOLATIONW;
- UINT msgFILEOKW;
- BOOL bInChildDlg;
- BOOL bFirstTime;
- BOOL bInitializing;
- //
- // Used by the worker thread to enumerate network disk resources.
- //
- extern DWORD cbNetEnumBuf;
- extern LPTSTR gpcNetEnumBuf;
- //
- // List Net Drives global variables.
- //
- extern HANDLE hLNDEvent;
- BOOL bLNDExit = FALSE;
- extern CRITICAL_SECTION g_csLocal;
- extern CRITICAL_SECTION g_csNetThread;
- extern DWORD g_tlsiCurDlg;
- extern HDC hdcMemory;
- extern HBITMAP hbmpOrigMemBmp;
- HBITMAP hbmpDirDrive = HNULL;
- //
- // Static Declarations.
- //
- static WORD cLock = 0;
- //
- // Not valid RGB color.
- //
- static DWORD rgbWindowColor = 0xFF000000;
- static DWORD rgbHiliteColor = 0xFF000000;
- static DWORD rgbWindowText = 0xFF000000;
- static DWORD rgbHiliteText = 0xFF000000;
- static DWORD rgbGrayText = 0xFF000000;
- static DWORD rgbDDWindow = 0xFF000000;
- static DWORD rgbDDHilite = 0xFF000000;
- TCHAR szCaption[TOOLONGLIMIT + WARNINGMSGLENGTH];
- TCHAR szWarning[TOOLONGLIMIT + WARNINGMSGLENGTH];
- LPOFNHOOKPROC glpfnFileHook = 0;
- //
- // BUGBUG:
- // Of course, in the case where there is a multi-threaded process
- // that has > 1 threads simultaneously calling GetFileOpen, the
- // following globals may cause problems.
- //
- static LONG dyItem = 0;
- static LONG dyText;
- static BOOL bChangeDir = FALSE;
- static BOOL bCasePreserved;
- //
- // Used for formatting long unc names (ex. banyan).
- //
- static DWORD dwAveCharPerLine = 10;
- //
- // Context Help IDs.
- //
- const static DWORD aFileOpenHelpIDs[] =
- {
- edt1, IDH_OPEN_FILENAME,
- stc3, IDH_OPEN_FILENAME,
- lst1, IDH_OPEN_FILENAME,
- stc1, IDH_OPEN_PATH,
- lst2, IDH_OPEN_PATH,
- stc2, IDH_OPEN_FILETYPE,
- cmb1, IDH_OPEN_FILETYPE,
- stc4, IDH_OPEN_DRIVES,
- cmb2, IDH_OPEN_DRIVES,
- chx1, IDH_OPEN_READONLY,
- pshHelp, IDH_HELP,
- psh14, IDH_PRINT_NETWORK,
- 0, 0
- };
- const static DWORD aFileSaveHelpIDs[] =
- {
- edt1, IDH_OPEN_FILENAME,
- stc3, IDH_OPEN_FILENAME,
- lst1, IDH_OPEN_FILENAME,
- stc1, IDH_OPEN_PATH,
- lst2, IDH_OPEN_PATH,
- stc2, IDH_SAVE_FILETYPE,
- cmb1, IDH_SAVE_FILETYPE,
- stc4, IDH_OPEN_DRIVES,
- cmb2, IDH_OPEN_DRIVES,
- chx1, IDH_OPEN_READONLY,
- pshHelp, IDH_HELP,
- psh14, IDH_PRINT_NETWORK,
- 0, 0
- };
- //
- // Function Prototypes.
- //
- SHORT
- GetFileTitleX(
- LPTSTR lpszFile,
- LPTSTR lpszTitle,
- WORD wBufSize);
- BOOL
- GetFileName(
- POPENFILEINFO pOFI,
- DLGPROC qfnDlgProc);
- BOOL_PTR CALLBACK
- FileOpenDlgProc(
- HWND hDlg,
- UINT wMsg,
- WPARAM wParam,
- LPARAM lParam);
- BOOL_PTR CALLBACK
- FileSaveDlgProc(
- HWND hDlg,
- UINT wMsg,
- WPARAM wParam,
- LPARAM lParam);
- BOOL_PTR
- InitFileDlg(
- HWND hDlg,
- WPARAM wParam,
- POPENFILEINFO pOFI);
- int
- InitTlsValues(
- POPENFILEINFO pOFI);
- DWORD
- InitFilterBox(
- HANDLE hDlg,
- LPCTSTR lpszFilter);
- VOID
- InitCurrentDisk(
- HWND hDlg,
- POPENFILEINFO pOFI,
- WORD cmb);
- VOID
- vDeleteDirDriveBitmap();
- BOOL
- LoadDirDriveBitmap();
- void
- SetRGBValues();
- BOOL
- FSetUpFile();
- BOOL_PTR
- FileOpenCmd(
- HANDLE hDlg,
- WPARAM wParam,
- LPARAM lParam,
- POPENFILEINFO pOFI,
- BOOL bSave);
- BOOL
- UpdateListBoxes(
- HWND hDlg,
- POPENFILEINFO pOFI,
- LPTSTR lpszFilter,
- WORD wMask);
- BOOL
- OKButtonPressed(
- HWND hDlg,
- POPENFILEINFO pOFI,
- BOOL bSave);
- BOOL
- MultiSelectOKButton(
- HWND hDlg,
- POPENFILEINFO pOFI,
- BOOL bSave);
- LRESULT WINAPI
- dwOKSubclass(
- HWND hOK,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam);
- LRESULT WINAPI
- dwLBSubclass(
- HWND hLB,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam);
- int
- InvalidFileWarning(
- HWND hDlg,
- LPTSTR szFile,
- DWORD wErrCode,
- UINT mbType);
- VOID
- MeasureItem(
- HWND hDlg,
- LPMEASUREITEMSTRUCT mis);
- int
- Signum(
- int nTest);
- VOID
- DrawItem(
- POPENFILEINFO pOFI,
- HWND hDlg,
- WPARAM wParam,
- LPDRAWITEMSTRUCT lpdis,
- BOOL bSave);
- BOOL
- SpacesExist(
- LPTSTR szFileName);
- void
- StripFileName(
- HANDLE hDlg,
- BOOL bWowApp);
- LPTSTR
- lstrtok(
- LPTSTR lpStr,
- LPCTSTR lpDelim);
- LPTSTR
- ChopText(
- HWND hwndDlg,
- int idStatic,
- LPTSTR lpch);
- BOOL
- FillOutPath(
- HWND hList,
- POPENFILEINFO pOFI);
- BOOL
- ShortenThePath(
- LPTSTR pPath);
- int
- FListAll(
- POPENFILEINFO pOFI,
- HWND hDlg,
- LPTSTR szSpec);
- int
- ChangeDir(
- HWND hDlg,
- LPCTSTR lpszDir,
- BOOL bForce,
- BOOL bError);
- BOOL
- IsFileSystemCasePreserving(
- LPTSTR lpszDisk);
- BOOL
- IsLFNDriveX(
- HWND hDlg,
- LPTSTR szPath);
- int
- DiskAddedPreviously(
- TCHAR wcDrive,
- LPTSTR lpszName);
- int
- AddDisk(
- TCHAR wcDrive,
- LPTSTR lpName,
- LPTSTR lpProvider,
- DWORD dwType);
- VOID
- EnableDiskInfo(
- BOOL bValid,
- BOOL bDoUnc);
- VOID
- FlushDiskInfoToCmb2();
- BOOL
- CallNetDlg(
- HWND hWnd);
- UINT
- GetDiskType(
- LPTSTR lpszDisk);
- DWORD
- GetUNCDirectoryFromLB(
- HWND hDlg,
- WORD nLB,
- POPENFILEINFO pOFI);
- VOID
- SelDisk(
- HWND hDlg,
- LPTSTR lpszDisk);
- VOID
- LNDSetEvent(
- HWND hDlg);
- VOID
- UpdateLocalDrive(
- LPTSTR szDrive,
- BOOL bGetVolName);
- VOID
- GetNetDrives(
- DWORD dwScope);
- VOID
- ListNetDrivesHandler();
- VOID
- LoadDrives(
- HWND hDlg);
- DWORD
- GetDiskIndex(
- DWORD dwDriveType);
- VOID
- CleanUpFile();
- VOID
- FileOpenAbort();
- VOID
- TermFile();
- #ifdef UNICODE
- //VOID // prototype in fileopen.h
- //ThunkOpenFileNameA2WDelayed(
- // POPENFILEINFO pOFI);
- //BOOL // prototype in fileopen.h
- //ThunkOpenFileNameA2W(
- // POPENFILEINFO pOFI);
- //BOOL // prototype in fileopen.h
- //ThunkOpenFileNameW2A(
- // POPENFILEINFO pOFI);
- BOOL
- GenericGetFileNameA(
- LPOPENFILENAMEA pOFNA,
- DLGPROC qfnDlgProc);
- LPWSTR
- ThunkANSIStrToWIDE(
- LPWSTR pDestW,
- LPSTR pSrcA,
- int cChars);
- LPWSTR
- ThunkMultiANSIStrToWIDE(
- LPWSTR pDestW,
- LPSTR pSrcA,
- int cChars);
- BOOL
- Multi_strcpyAtoW(
- LPWSTR pDestW,
- LPCSTR pSrcA,
- int cChars);
- INT
- Multi_strlenA(
- LPCSTR str);
- #endif
- #ifndef SheChangeDirEx
- #undef SheChangeDirEx
- #define SheChangeDirEx SetCurrentDirectory
- #endif
- #ifdef UNICODE
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetFileTitleA
- //
- // ANSI entry point for GetFileTitle when this code is built UNICODE.
- //
- ////////////////////////////////////////////////////////////////////////////
- SHORT WINAPI GetFileTitleA(
- LPCSTR lpszFileA,
- LPSTR lpszTitleA,
- WORD cbBuf)
- {
- LPWSTR lpszFileW;
- LPWSTR lpszTitleW;
- BOOL fResult;
- DWORD cbLen;
- //
- // Init File string.
- //
- if (lpszFileA)
- {
- cbLen = lstrlenA(lpszFileA) + 1;
- if (!(lpszFileW = (LPWSTR)LocalAlloc(LPTR, (cbLen * sizeof(WCHAR)))))
- {
- StoreExtendedError(CDERR_MEMALLOCFAILURE);
- return (FALSE);
- }
- else
- {
- SHAnsiToUnicode((LPSTR)lpszFileA,lpszFileW,cbLen );
- }
- }
- else
- {
- lpszFileW = NULL;
- }
- if (!(lpszTitleW = (LPWSTR)LocalAlloc(LPTR, (cbBuf * sizeof(WCHAR)))))
- {
- StoreExtendedError(CDERR_MEMALLOCFAILURE);
- if (lpszFileW)
- {
- LocalFree(lpszFileW);
- }
- return (FALSE);
- }
- if (!(fResult = GetFileTitleW(lpszFileW, lpszTitleW, cbBuf)))
- {
- SHUnicodeToAnsi(lpszTitleW,lpszTitleA,cbBuf);
- }
- else if (fResult > 0)
- {
- //
- // Buffer is too small - Ansi size needed (including null terminator).
- // Get the offset to the filename.
- //
- SHORT nNeeded = (SHORT)(INT)LOWORD(ParseFile(lpszFileW, TRUE, FALSE, FALSE));
- LPSTR lpA = (LPSTR)lpszFileA;
- lpA += WideCharToMultiByte( CP_ACP,
- 0,
- lpszFileW,
- nNeeded,
- NULL,
- 0,
- NULL,
- NULL );
- fResult = lstrlenA(lpA) + 1;
- if (fResult <= cbBuf)
- {
- lstrcpyA(lpszTitleA, lpA);
- fResult = 0;
- }
- }
- //
- // Clean up memory.
- //
- LocalFree(lpszTitleW);
- if (lpszFileW)
- {
- LocalFree(lpszFileW);
- }
- return ((SHORT)fResult);
- }
- #else
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetFileTitleW
- //
- // Stub UNICODE function for GetFileTitle when this code is built ANSI.
- //
- ////////////////////////////////////////////////////////////////////////////
- SHORT WINAPI GetFileTitleW(
- LPCWSTR lpszFileW,
- LPWSTR lpszTitleW,
- WORD cbBuf)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return (FALSE);
- }
- #endif
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetFileTitle
- //
- // The GetFileTitle function returns the name of the file identified
- // by the lpCFile parameter. This is useful if the file name was
- // received via some method other than GetOpenFileName
- // (e.g. command line, drag drop).
- //
- // Returns: 0 on success
- // < 0, Parsing failure (invalid file name)
- // > 0, buffer too small, size needed (including NULL terminator)
- //
- ////////////////////////////////////////////////////////////////////////////
- SHORT WINAPI GetFileTitle(
- LPCTSTR lpCFile,
- LPTSTR lpTitle,
- WORD cbBuf)
- {
- LPTSTR lpFile;
- DWORD cbLen;
- SHORT fResult;
- //
- // Init File string.
- //
- if (lpCFile)
- {
- cbLen = lstrlen(lpCFile) + 1;
- if (!(lpFile = (LPTSTR)LocalAlloc(LPTR, (cbLen * sizeof(TCHAR)))))
- {
- StoreExtendedError(CDERR_MEMALLOCFAILURE);
- return (FALSE);
- }
- else
- {
- lstrcpy(lpFile, lpCFile);
- }
- }
- else
- {
- lpFile = NULL;
- }
- fResult = GetFileTitleX(lpFile, lpTitle, cbBuf);
- //
- // Clean up memory.
- //
- if (lpFile)
- {
- LocalFree(lpFile);
- }
- return (fResult);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetFileTitleX
- //
- // Worker routine for the GetFileTitle api.
- //
- // Assumes: lpszFile points to NULL terminated DOS filename (may have path)
- // lpszTitle points to buffer to receive NULL terminated file title
- // wBufSize is the size of buffer pointed to by lpszTitle
- //
- // Returns: 0 on success
- // < 0, Parsing failure (invalid file name)
- // > 0, buffer too small, size needed (including NULL terminator)
- //
- ////////////////////////////////////////////////////////////////////////////
- SHORT GetFileTitleX(
- LPTSTR lpszFile,
- LPTSTR lpszTitle,
- WORD wBufSize)
- {
- SHORT nNeeded;
- LPTSTR lpszPtr;
- //
- // New 32 bit apps will get a title based on the user's preferences.
- //
- if ((GetProcessVersion(0) >= 0x040000) && !(CDGetAppCompatFlags() & CDACF_FILETITLE))
- {
- SHFILEINFO info;
- DWORD_PTR result;
- if (!lpszFile || !*lpszFile)
- {
- return (PARSE_EMPTYSTRING);
- }
- //
- // If we have a root directory name (eg. c:), then we need to go
- // to the old implementation so that it will return -1.
- // SHGetFileInfo will return the display name for the directory
- // (which is the volume name). This is incompatible with Win95
- // and previous versions of NT.
- //
- if ((lstrlen(lpszFile) != 3) ||
- (lpszFile[1] != CHAR_COLON) || (!ISBACKSLASH(lpszFile, 2)))
- {
- result = SHGetFileInfo( lpszFile,
- FILE_ATTRIBUTE_NORMAL,
- &info,
- sizeof(info),
- SHGFI_DISPLAYNAME | SHGFI_USEFILEATTRIBUTES );
- if (result && (*info.szDisplayName))
- {
- UINT uDisplayLen = lstrlen(info.szDisplayName);
- //
- // If no buffer or insufficient size, return the required chars.
- // Original GetFileTitle API did not copy on failure.
- //
- if (!lpszTitle || (uDisplayLen >= (UINT)wBufSize))
- {
- return ( (SHORT)(uDisplayLen + 1) );
- }
- //
- // We already know it fits, so we don't need lstrcpyn.
- //
- lstrcpy(lpszTitle, info.szDisplayName);
- return (0);
- }
- }
- }
- //
- // Use the old implementation.
- //
- nNeeded = (SHORT)(int)LOWORD(ParseFile(lpszFile, TRUE, FALSE, FALSE));
- if (nNeeded >= 0)
- {
- //
- // Is the filename valid?
- //
- lpszPtr = lpszFile + nNeeded;
- if ((nNeeded = (SHORT)lstrlen(lpszPtr) + 1) <= (int)wBufSize)
- {
- //
- // ParseFile() fails if wildcards in directory, but OK if in name.
- // Since they arent OK here, the check is needed here.
- //
- if (StrChr(lpszPtr, CHAR_STAR) || StrChr(lpszPtr, CHAR_QMARK))
- {
- nNeeded = PARSE_WILDCARDINFILE;
- }
- else
- {
- lstrcpy(lpszTitle, lpszPtr);
- //
- // Remove trailing spaces.
- //
- lpszPtr = lpszTitle + lstrlen(lpszTitle) - 1;
- while (*lpszPtr && *lpszPtr == CHAR_SPACE)
- {
- *lpszPtr-- = CHAR_NULL;
- }
- nNeeded = 0;
- }
- }
- }
- return (nNeeded);
- }
- #ifdef UNICODE
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetOpenFileNameA
- //
- // ANSI entry point for GetOpenFileName when this code is built UNICODE.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL WINAPI GetOpenFileNameA(
- LPOPENFILENAMEA pOFNA)
- {
- if (!pOFNA)
- {
- StoreExtendedError(CDERR_INITIALIZATION);
- return (FALSE);
- }
- return ( GenericGetFileNameA(pOFNA, FileOpenDlgProc) );
- }
- #else
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetOpenFileNameW
- //
- // Stub UNICODE function for GetOpenFileName when this code is built ANSI.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL WINAPI GetOpenFileNameW(
- LPOPENFILENAMEW pOFNW)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return (FALSE);
- }
- #endif
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetOpenFileName
- //
- // The GetOpenFileName function creates a system-defined dialog box
- // that enables the user to select a file to open.
- //
- // Returns: TRUE if user specified name
- // FALSE if not
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL WINAPI GetOpenFileName(
- LPOPENFILENAME pOFN)
- {
- OPENFILEINFO OFI;
- ZeroMemory(&OFI, sizeof(OPENFILEINFO));
- if (!pOFN)
- {
- StoreExtendedError(CDERR_INITIALIZATION);
- return (FALSE);
- }
- OFI.pOFN = pOFN;
- OFI.ApiType = COMDLG_WIDE;
- OFI.iVersion = OPENFILEVERSION;
- return (GetFileName(&OFI, FileOpenDlgProc));
- }
- #ifdef UNICODE
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetSaveFileNameA
- //
- // ANSI entry point for GetSaveFileName when this code is built UNICODE.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL WINAPI GetSaveFileNameA(
- LPOPENFILENAMEA pOFNA)
- {
- return (GenericGetFileNameA(pOFNA, FileSaveDlgProc));
- }
- #else
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetSaveFileNameW
- //
- // Stub UNICODE function for GetSaveFileName when this code is built ANSI.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL WINAPI GetSaveFileNameW(
- LPOPENFILENAMEW pOFNW)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return (FALSE);
- }
- #endif
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetSaveFileName
- //
- // The GetSaveFileName function creates a system-defined dialog box
- // that enables the user to select a file to save.
- //
- // Returns: TRUE if user desires to save file and gave a proper name
- // FALSE if not
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL WINAPI GetSaveFileName(
- LPOPENFILENAME pOFN)
- {
- OPENFILEINFO OFI;
- ZeroMemory(&OFI, sizeof(OPENFILEINFO));
- OFI.pOFN = pOFN;
- OFI.ApiType = COMDLG_WIDE;
- OFI.iVersion = OPENFILEVERSION;
- return ( GetFileName(&OFI, FileSaveDlgProc) );
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetFileName
- //
- // This is the meat of both GetOpenFileName and GetSaveFileName.
- //
- // Returns: TRUE if user specified name
- // FALSE if not
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL GetFileName(
- POPENFILEINFO pOFI,
- DLGPROC qfnDlgProc)
- {
- LPOPENFILENAME pOFN = pOFI->pOFN;
- LPOPENFILENAME pofnOld = NULL;
- INT_PTR iRet;
- LPTSTR lpDlg;
- HANDLE hRes, hDlgTemplate;
- WORD wErrorMode;
- HDC hdcScreen;
- HBITMAP hbmpTemp;
- LPCURDLG lpCurDlg;
- static fFirstTime = TRUE;
- #ifdef UNICODE
- UINT uiWOWFlag = 0;
- #endif
- OPENFILENAME ofn = {0};
- LANGID LangID = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
- if (!pOFN)
- {
- StoreExtendedError(CDERR_INITIALIZATION);
- return (FALSE);
- }
- if (pOFN->lStructSize == OPENFILENAME_SIZE_VERSION_400)
- {
- // lets go ahead and convert it over to the new stuff
- ofn = *pOFN;
- ofn.lStructSize = SIZEOF(ofn);
- //Make sure the additional members are set to NULL
- ofn.pvReserved = NULL;
- ofn.dwReserved = 0;
- ofn.FlagsEx = 0;
- pofnOld = pOFN;
- pOFN = &ofn;
- pOFI->pOFN = pOFN;
- pOFI->iVersion = OPENFILEVERSION_NT4;
- }
- if ((pOFN->lStructSize != sizeof(OPENFILENAME))
- )
- {
- StoreExtendedError(CDERR_STRUCTSIZE);
- return (FALSE);
- }
- #ifdef FEATURE_MONIKER_SUPPORT
- if (pOFN->Flags & OFN_USEMONIKERS)
- {
- if ( !(pOFN->Flags & OFN_EXPLORER) ||
- (!pOFN->rgpMonikers || !pOFN->cMonikers)
- )
- {
- StoreExtendedError(CDERR_INITIALIZATION);
- return (FALSE);
- }
- }
- else
- #endif // FEATURE_MONIKER_SUPPORT
- if (pOFN->nMaxFile == 0)
- {
- //Bail out for NULL lpstrFile Only for NT5 and above applications
- if (!IS16BITWOWAPP(pOFN) && (pOFI->iVersion >= OPENFILEVERSION_NT5))
- {
- StoreExtendedError(CDERR_INITIALIZATION);
- return (FALSE);
- }
- }
- //
- // See if the application should get the new look.
- //
- // Do not allow the new look if they have hooks, templates, or
- // multi select without the OFN_EXPLORER bit.
- //
- // Also don't allow the new look if we are in the context of
- // a 16 bit process.
- //
- if ( ((pOFN->Flags & OFN_EXPLORER) ||
- (!(pOFN->Flags & (OFN_ENABLEHOOK |
- OFN_ENABLETEMPLATE |
- OFN_ENABLETEMPLATEHANDLE |
- OFN_ALLOWMULTISELECT)))) &&
- (!IS16BITWOWAPP(pOFN)) )
- {
- BOOL fRet;
- #ifdef UNICODE
- //
- // To be used by the thunking routines for multi selection.
- //
- pOFI->bUseNewDialog = TRUE;
- #endif
- //
- // Show the new explorer look.
- //
- StoreExtendedError(0);
- bUserPressedCancel = FALSE;
- if (qfnDlgProc == FileOpenDlgProc)
- {
- fRet = (NewGetOpenFileName(pOFI));
- }
- else
- {
- fRet = (NewGetSaveFileName(pOFI));
- }
- // copy it back to the original if necessary.
- if (pofnOld)
- CopyMemory(pofnOld, (pOFI->pOFN), pofnOld->lStructSize);
- return fRet;
- }
- if (fFirstTime)
- {
- //
- // Create a DC that is compatible with the screen and find the
- // handle of the null bitmap.
- //
- hdcScreen = GetDC(HNULL);
- if (!hdcScreen)
- {
- goto CantInit;
- }
- hdcMemory = CreateCompatibleDC(hdcScreen);
- if (!hdcMemory)
- {
- goto ReleaseScreenDC;
- }
- hbmpTemp = CreateCompatibleBitmap(hdcMemory, 1, 1);
- if (!hbmpTemp)
- {
- goto ReleaseMemDC;
- }
- hbmpOrigMemBmp = SelectObject(hdcMemory, hbmpTemp);
- if (!hbmpOrigMemBmp)
- {
- goto ReleaseMemDC;
- }
- SelectObject(hdcMemory, hbmpOrigMemBmp);
- DeleteObject(hbmpTemp);
- ReleaseDC(HNULL, hdcScreen);
- fFirstTime = FALSE;
- }
- if (pOFN->Flags & OFN_ENABLEHOOK)
- {
- if (!pOFN->lpfnHook)
- {
- StoreExtendedError(CDERR_NOHOOK);
- return (FALSE);
- }
- }
- else
- {
- pOFN->lpfnHook = NULL;
- }
- HourGlass(TRUE);
- StoreExtendedError(0);
- //
- // Force re-compute for font changes between calls.
- //
- dyItem = dyText = 0;
- bUserPressedCancel = FALSE;
- if (!FSetUpFile())
- {
- StoreExtendedError(CDERR_INITIALIZATION);
- goto TERMINATE;
- }
- if (pOFN->Flags & OFN_ENABLETEMPLATE)
- {
- if (!(hRes = FindResource( pOFN->hInstance,
- pOFN->lpTemplateName,
- RT_DIALOG )))
- {
- StoreExtendedError(CDERR_FINDRESFAILURE);
- goto TERMINATE;
- }
- if (!(hDlgTemplate = LoadResource(pOFN->hInstance, hRes)))
- {
- StoreExtendedError(CDERR_LOADRESFAILURE);
- goto TERMINATE;
- }
- LangID = GetDialogLanguage(pOFN->hwndOwner, hDlgTemplate);
- }
- else if (pOFN->Flags & OFN_ENABLETEMPLATEHANDLE)
- {
- hDlgTemplate = pOFN->hInstance;
- LangID = GetDialogLanguage(pOFN->hwndOwner, hDlgTemplate);
- }
- else
- {
- if (pOFN->Flags & OFN_ALLOWMULTISELECT)
- {
- lpDlg = MAKEINTRESOURCE(MULTIFILEOPENORD);
- }
- else
- {
- lpDlg = MAKEINTRESOURCE(FILEOPENORD);
- }
- LangID = GetDialogLanguage(pOFN->hwndOwner, NULL);
- if (!(hRes = FindResourceEx(g_hinst, RT_DIALOG, lpDlg, LangID)))
- {
- StoreExtendedError(CDERR_FINDRESFAILURE);
- goto TERMINATE;
- }
- if (!(hDlgTemplate = LoadResource(g_hinst, hRes)))
- {
- StoreExtendedError(CDERR_LOADRESFAILURE);
- goto TERMINATE;
- }
- }
- //
- // Warning! Warning! Warning!
- //
- // We have to set g_tlsLangID before any call for CDLoadString
- //
- TlsSetValue(g_tlsLangID, (LPVOID) LangID);
- //
- // No kernel network error dialogs.
- //
- wErrorMode = (WORD)SetErrorMode(SEM_NOERROR);
- SetErrorMode(SEM_NOERROR | wErrorMode);
- if (LockResource(hDlgTemplate))
- {
- if (pOFN->Flags & OFN_ENABLEHOOK)
- {
- glpfnFileHook = GETHOOKFN(pOFN);
- }
- #ifdef UNICODE
- if (IS16BITWOWAPP(pOFN))
- {
- uiWOWFlag = SCDLG_16BIT;
- }
- iRet = DialogBoxIndirectParamAorW( g_hinst,
- (LPDLGTEMPLATE)hDlgTemplate,
- pOFN->hwndOwner,
- qfnDlgProc,
- (DWORD_PTR)pOFI,
- uiWOWFlag );
- #else
- iRet = DialogBoxIndirectParam( g_hinst,
- (LPDLGTEMPLATE)hDlgTemplate,
- pOFN->hwndOwner,
- qfnDlgProc,
- (DWORD)pOFI );
- #endif
- if (iRet == -1 || ((iRet == 0) && (!bUserPressedCancel) && (!GetStoredExtendedError())))
- {
- StoreExtendedError(CDERR_DIALOGFAILURE);
- }
- else
- {
- FileOpenAbort();
- }
- glpfnFileHook = 0;
- }
- else
- {
- StoreExtendedError(CDERR_LOCKRESFAILURE);
- goto TERMINATE;
- }
- SetErrorMode(wErrorMode);
- if (lpCurDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg))
- {
- // restore the thread list to the previous dialog (if any)
- TlsSetValue(g_tlsiCurDlg, (LPVOID)lpCurDlg->next);
- LocalFree(lpCurDlg->lpstrCurDir);
- LocalFree(lpCurDlg);
- }
- TERMINATE:
- // make sure the original
- if (pofnOld)
- CopyMemory(pofnOld, (pOFI->pOFN), pofnOld->lStructSize);
- CleanUpFile();
- HourGlass(FALSE);
- return (iRet == IDOK);
- ReleaseMemDC:
- DeleteDC(hdcMemory);
- ReleaseScreenDC:
- ReleaseDC(HNULL, hdcScreen);
- CantInit:
- return (FALSE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // FileHookCmd
- //
- // Called when a hook function processes a WM_COMMAND message.
- // Called by FileOpenDlgProc and FileSaveDlgProc.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL FileHookCmd(
- HANDLE hDlg,
- WPARAM wParam,
- LPARAM lParam,
- POPENFILEINFO pOFI)
- {
- switch (GET_WM_COMMAND_ID(wParam, lParam))
- {
- case ( IDCANCEL ) :
- {
- //
- // Set global flag stating that the
- // user pressed cancel.
- //
- bUserPressedCancel = TRUE;
- // Fall Thru...
- }
- case ( IDOK ) :
- case ( IDABORT ) :
- {
- #ifdef UNICODE
- //
- // Apps that side-effect these messages may
- // not have their internal unicode strings
- // updated. They may also forget to gracefully
- // exit the network enum'ing worker thread.
- //
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- ThunkOpenFileNameA2W(pOFI);
- }
- #endif
- break;
- }
- case ( cmb1 ) :
- case ( cmb2 ) :
- {
- switch (GET_WM_COMMAND_CMD(wParam, lParam))
- {
- case ( MYCBN_DRAW ) :
- case ( MYCBN_LIST ) :
- case ( MYCBN_REPAINT ) :
- case ( MYCBN_CHANGEDIR ) :
- {
- //
- // In case an app has a hook, and returns
- // true for processing WM_COMMAND messages,
- // we still have to worry about our
- // internal message that came through via
- // WM_COMMAND.
- //
- FileOpenCmd( hDlg,
- wParam,
- lParam,
- pOFI,
- FALSE );
- break;
- }
- }
- break;
- }
- }
- return (TRUE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // FileOpenDlgProc
- //
- // Gets the name of a file to open from the user.
- //
- // edt1 = file name
- // lst1 = list of files in current directory matching current pattern
- // cmb1 = lists file patterns
- // stc1 = is current directory
- // lst2 = lists directories on current drive
- // cmb2 = lists drives
- // IDOK = is Open pushbutton
- // IDCANCEL = is Cancel pushbutton
- // chx1 = is for opening read only files
- //
- // Returns the normal dialog proc values.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL_PTR CALLBACK FileOpenDlgProc(
- HWND hDlg,
- UINT wMsg,
- WPARAM wParam,
- LPARAM lParam)
- {
- POPENFILEINFO pOFI;
- BOOL_PTR bRet, bHookRet;
- if (pOFI = (POPENFILEINFO)GetProp(hDlg, FILEPROP))
- {
- if (pOFI->pOFN->lpfnHook)
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFI->pOFN);
- bHookRet = (*lpfnHook)(hDlg, wMsg, wParam, lParam);
- if (bHookRet)
- {
- if (wMsg == WM_COMMAND)
- {
- return (FileHookCmd(hDlg, wParam, lParam, pOFI));
- }
- return (bHookRet);
- }
- }
- }
- else if (glpfnFileHook &&
- (wMsg != WM_INITDIALOG) &&
- (bHookRet = (*glpfnFileHook)(hDlg, wMsg, wParam, lParam)))
- {
- return (bHookRet);
- }
- switch (wMsg)
- {
- case ( WM_INITDIALOG ) :
- {
- pOFI = (POPENFILEINFO)lParam;
- SetProp(hDlg, FILEPROP, (HANDLE)pOFI);
- glpfnFileHook = 0;
- //
- // If we are being called from a Unicode app, turn off
- // the ES_OEMCONVERT style on the filename edit control.
- //
- // if (pOFI->ApiType == COMDLG_WIDE)
- {
- LONG lStyle;
- HWND hEdit = GetDlgItem(hDlg, edt1);
- //
- // Grab the window style.
- //
- lStyle = GetWindowLong(hEdit, GWL_STYLE);
- //
- // If the window style bits include ES_OEMCONVERT,
- // remove this flag and reset the style.
- //
- if (lStyle & ES_OEMCONVERT)
- {
- lStyle &= ~ES_OEMCONVERT;
- SetWindowLong(hEdit, GWL_STYLE, lStyle);
- }
- }
- bInitializing = TRUE;
- bRet = InitFileDlg(hDlg, wParam, pOFI);
- bInitializing = FALSE;
- HourGlass(FALSE);
- return (bRet);
- break;
- }
- case ( WM_ACTIVATE ) :
- {
- if (!bInChildDlg)
- {
- if (bFirstTime == TRUE)
- {
- bFirstTime = FALSE;
- }
- else if (wParam)
- {
- //
- // If becoming active.
- //
- LNDSetEvent(hDlg);
- }
- }
- return (FALSE);
- break;
- }
- case ( WM_MEASUREITEM ) :
- {
- MeasureItem(hDlg, (LPMEASUREITEMSTRUCT)lParam);
- break;
- }
- case ( WM_DRAWITEM ) :
- {
- if (wNoRedraw < 2)
- {
- DrawItem(pOFI, hDlg, wParam, (LPDRAWITEMSTRUCT)lParam, FALSE);
- }
- break;
- }
- case ( WM_SYSCOLORCHANGE ) :
- {
- SetRGBValues();
- LoadDirDriveBitmap();
- break;
- }
- case ( WM_COMMAND ) :
- {
- return (FileOpenCmd(hDlg, wParam, lParam, pOFI, FALSE));
- break;
- }
- case ( WM_SETFOCUS ) :
- {
- //
- // This logic used to be in CBN_SETFOCUS in fileopencmd,
- // but CBN_SETFOCUS is called whenever there is a click on
- // the List Drives combo. This causes the worker thread
- // to start up and flicker when the combo box is refreshed.
- //
- // But, refreshes are only needed when someone focuses out of
- // the common dialog and then back in (unless someone is logged
- // in remote, or there is a background thread busy connecting!)
- // so fix the flicker by moving the logic here.
- //
- if (!wNoRedraw)
- {
- LNDSetEvent(hDlg);
- }
- return (FALSE);
- break;
- }
- case ( WM_HELP ) :
- {
- if (IsWindowEnabled(hDlg))
- {
- WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
- NULL,
- HELP_WM_HELP,
- (ULONG_PTR)(LPTSTR)aFileOpenHelpIDs );
- }
- break;
- }
- case ( WM_CONTEXTMENU ) :
- {
- if (IsWindowEnabled(hDlg))
- {
- WinHelp( (HWND)wParam,
- NULL,
- HELP_CONTEXTMENU,
- (ULONG_PTR)(LPVOID)aFileOpenHelpIDs );
- }
- break;
- }
- default :
- {
- return (FALSE);
- }
- }
- return (TRUE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // FileSaveDlgProc
- //
- // Obtains the name of the file that the user wants to save.
- //
- // Returns the normal dialog proc values.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL_PTR CALLBACK FileSaveDlgProc(
- HWND hDlg,
- UINT wMsg,
- WPARAM wParam,
- LPARAM lParam)
- {
- POPENFILEINFO pOFI;
- BOOL_PTR bRet, bHookRet;
- TCHAR szTitle[cbCaption];
- if (pOFI = (POPENFILEINFO)GetProp(hDlg, FILEPROP))
- {
- if (pOFI->pOFN->lpfnHook)
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFI->pOFN);
- bHookRet = (*lpfnHook)(hDlg, wMsg, wParam, lParam);
- if (bHookRet)
- {
- if (wMsg == WM_COMMAND)
- {
- return (FileHookCmd(hDlg, wParam, lParam, pOFI));
- }
- return (bHookRet);
- }
- }
- }
- else if (glpfnFileHook &&
- (wMsg != WM_INITDIALOG) &&
- (bHookRet = (*glpfnFileHook)(hDlg, wMsg, wParam, lParam)))
- {
- return (bHookRet);
- }
- switch (wMsg)
- {
- case ( WM_INITDIALOG ) :
- {
- pOFI = (POPENFILEINFO)lParam;
- if (!(pOFI->pOFN->Flags &
- (OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE)))
- {
- CDLoadString(g_hinst, iszFileSaveTitle, szTitle, cbCaption);
- SetWindowText(hDlg, szTitle);
- CDLoadString(g_hinst, iszSaveFileAsType, szTitle, cbCaption);
- SetDlgItemText(hDlg, stc2, szTitle);
- }
- glpfnFileHook = 0;
- SetProp(hDlg, FILEPROP, (HANDLE)pOFI);
- //
- // If we are being called from a Unicode app, turn off
- // the ES_OEMCONVERT style on the filename edit control.
- //
- // if (pOFI->ApiType == COMDLG_WIDE)
- {
- LONG lStyle;
- HWND hEdit = GetDlgItem(hDlg, edt1);
- //
- // Grab the window style.
- //
- lStyle = GetWindowLong(hEdit, GWL_STYLE);
- //
- // If the window style bits include ES_OEMCONVERT,
- // remove this flag and reset the style.
- //
- if (lStyle & ES_OEMCONVERT)
- {
- lStyle &= ~ES_OEMCONVERT;
- SetWindowLong (hEdit, GWL_STYLE, lStyle);
- }
- }
- bInitializing = TRUE;
- bRet = InitFileDlg(hDlg, wParam, pOFI);
- bInitializing = FALSE;
- HourGlass(FALSE);
- return (bRet);
- break;
- }
- case ( WM_ACTIVATE ) :
- {
- if (!bInChildDlg)
- {
- if (bFirstTime == TRUE)
- {
- bFirstTime = FALSE;
- }
- else if (wParam)
- {
- //
- // If becoming active.
- //
- if (!wNoRedraw)
- {
- LNDSetEvent(hDlg);
- }
- }
- }
- return (FALSE);
- break;
- }
- case ( WM_MEASUREITEM ) :
- {
- MeasureItem(hDlg, (LPMEASUREITEMSTRUCT)lParam);
- break;
- }
- case ( WM_DRAWITEM ) :
- {
- if (wNoRedraw < 2)
- {
- DrawItem(pOFI, hDlg, wParam, (LPDRAWITEMSTRUCT)lParam, TRUE);
- }
- break;
- }
- case ( WM_SYSCOLORCHANGE ) :
- {
- SetRGBValues();
- LoadDirDriveBitmap();
- break;
- }
- case ( WM_COMMAND ) :
- {
- return (FileOpenCmd(hDlg, wParam, lParam, pOFI, TRUE));
- break;
- }
- case ( WM_SETFOCUS ) :
- {
- //
- // This logic used to be in CBN_SETFOCUS in fileopencmd,
- // but CBN_SETFOCUS is called whenever there is a click on
- // the List Drives combo. This causes the worker thread
- // to start up and flicker when the combo box is refreshed.
- //
- // But, refreshes are only needed when someone focuses out of
- // the common dialog and then back in (unless someone is logged
- // in remote, or there is a background thread busy connecting!)
- // so fix the flicker by moving the logic here.
- //
- if (!wNoRedraw)
- {
- LNDSetEvent(hDlg);
- }
- return (FALSE);
- break;
- }
- case ( WM_HELP ) :
- {
- if (IsWindowEnabled(hDlg))
- {
- WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
- NULL,
- HELP_WM_HELP,
- (ULONG_PTR)(LPTSTR)aFileSaveHelpIDs );
- }
- break;
- }
- case ( WM_CONTEXTMENU ) :
- {
- if (IsWindowEnabled(hDlg))
- {
- WinHelp( (HWND)wParam,
- NULL,
- HELP_CONTEXTMENU,
- (ULONG_PTR)(LPVOID)aFileSaveHelpIDs );
- }
- break;
- }
- default :
- {
- return (FALSE);
- }
- }
- return (TRUE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // InitFileDlg
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL_PTR InitFileDlg(
- HWND hDlg,
- WPARAM wParam,
- POPENFILEINFO pOFI)
- {
- DWORD lRet, nFilterIndex;
- LPOPENFILENAME pOFN = pOFI->pOFN;
- int nFileOffset, nExtOffset;
- RECT rRect;
- RECT rLbox;
- BOOL_PTR bRet;
- if (!InitTlsValues(pOFI))
- {
- //
- // The extended error is set inside of the above call.
- //
- EndDialog(hDlg, FALSE);
- return (FALSE);
- }
- lpLBProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, lst2), GWLP_WNDPROC);
- lpOKProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, IDOK), GWLP_WNDPROC);
- if (!lpLBProc || !lpOKProc)
- {
- StoreExtendedError(FNERR_SUBCLASSFAILURE);
- EndDialog(hDlg, FALSE);
- return (FALSE);
- }
- //
- // Save original directory for later restoration if necessary.
- //
- *pOFI->szCurDir = 0;
- GetCurrentDirectory(MAX_FULLPATHNAME + 1, pOFI->szCurDir);
- //
- // Check out if the filename contains a path. If so, override whatever
- // is contained in lpstrInitialDir. Chop off the path and put up only
- // the filename.
- //
- if ( pOFN->lpstrFile &&
- *pOFN->lpstrFile &&
- !(pOFN->Flags & OFN_NOVALIDATE) )
- {
- if (DBL_BSLASH(pOFN->lpstrFile + 2) &&
- ((*(pOFN->lpstrFile + 1) == CHAR_COLON)))
- {
- lstrcpy(pOFN->lpstrFile , pOFN->lpstrFile + sizeof(TCHAR));
- }
- lRet = ParseFile(pOFN->lpstrFile, TRUE, IS16BITWOWAPP(pOFN), FALSE);
- nFileOffset = (int)(SHORT)LOWORD(lRet);
- nExtOffset = (int)(SHORT)HIWORD(lRet);
- //
- // Is the filename invalid?
- //
- if ( (nFileOffset < 0) &&
- (nFileOffset != PARSE_EMPTYSTRING) &&
- (pOFN->lpstrFile[nExtOffset] != CHAR_SEMICOLON) )
- {
- StoreExtendedError(FNERR_INVALIDFILENAME);
- EndDialog(hDlg, FALSE);
- return (FALSE);
- }
- }
- pOFN->Flags &= ~(OFN_FILTERDOWN | OFN_DRIVEDOWN | OFN_DIRSELCHANGED);
- pOFI->idirSub = 0;
- if (!(pOFN->Flags & OFN_SHOWHELP))
- {
- HWND hHelp;
- EnableWindow(hHelp = GetDlgItem(hDlg, pshHelp), FALSE);
- //
- // Move the window out of this spot so that no overlap will be
- // detected.
- //
- MoveWindow(hHelp, -8000, -8000, 20, 20, FALSE);
- ShowWindow(hHelp, SW_HIDE);
- }
- if (pOFN->Flags & OFN_CREATEPROMPT)
- {
- pOFN->Flags |= (OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST);
- }
- else if (pOFN->Flags & OFN_FILEMUSTEXIST)
- {
- pOFN->Flags |= OFN_PATHMUSTEXIST;
- }
- if (pOFN->Flags & OFN_HIDEREADONLY)
- {
- HWND hReadOnly;
- EnableWindow(hReadOnly = GetDlgItem(hDlg, chx1), FALSE);
- //
- // Move the window out of this spot so that no overlap will be
- // detected.
- //
- MoveWindow(hReadOnly, -8000, -8000, 20, 20, FALSE);
- ShowWindow(hReadOnly, SW_HIDE);
- }
- else
- {
- CheckDlgButton(hDlg, chx1, (pOFN->Flags & OFN_READONLY) != 0);
- }
- SendDlgItemMessage(hDlg, edt1, EM_LIMITTEXT, (WPARAM)MAX_PATH, 0L);
- //
- // Insert file specs into cmb1.
- // Custom filter first.
- // Must also check if filter contains anything.
- //
- if ( pOFN->lpstrFile &&
- (StrChr(pOFN->lpstrFile, CHAR_STAR) ||
- StrChr(pOFN->lpstrFile, CHAR_QMARK)) )
- {
- lstrcpy(pOFI->szLastFilter, pOFN->lpstrFile);
- }
- else
- {
- pOFI->szLastFilter[0] = CHAR_NULL;
- }
- if (pOFN->lpstrCustomFilter && *pOFN->lpstrCustomFilter)
- {
- SHORT nLength;
- SendDlgItemMessage( hDlg,
- cmb1,
- CB_INSERTSTRING,
- 0,
- (LONG_PTR)pOFN->lpstrCustomFilter );
- nLength = (SHORT)(lstrlen(pOFN->lpstrCustomFilter) + 1);
- SendDlgItemMessage( hDlg,
- cmb1,
- CB_SETITEMDATA,
- 0,
- (LONG)(nLength) );
- SendDlgItemMessage( hDlg,
- cmb1,
- CB_LIMITTEXT,
- (WPARAM)(pOFN->nMaxCustFilter),
- 0L );
- if (pOFI->szLastFilter[0] == CHAR_NULL)
- {
- lstrcpy(pOFI->szLastFilter, pOFN->lpstrCustomFilter + nLength);
- }
- }
- else
- {
- //
- // Given no custom filter, the index will be off by one.
- //
- if (pOFN->nFilterIndex != 0)
- {
- pOFN->nFilterIndex--;
- }
- }
- //
- // Listed filters next.
- //
- if (pOFN->lpstrFilter && *pOFN->lpstrFilter)
- {
- if (pOFN->nFilterIndex > InitFilterBox(hDlg, pOFN->lpstrFilter))
- {
- pOFN->nFilterIndex = 0;
- }
- }
- else
- {
- pOFN->nFilterIndex = 0;
- }
- pOFI->szSpecCur[0] = CHAR_NULL;
- //
- // If an entry exists, select the one indicated by nFilterIndex.
- //
- if ((pOFN->lpstrFilter && *pOFN->lpstrFilter) ||
- (pOFN->lpstrCustomFilter && *pOFN->lpstrCustomFilter))
- {
- LPCTSTR lpFilter;
- SendDlgItemMessage( hDlg,
- cmb1,
- CB_SETCURSEL,
- (WPARAM)(pOFN->nFilterIndex),
- 0L );
- nFilterIndex = pOFN->nFilterIndex;
- SendMessage( hDlg,
- WM_COMMAND,
- GET_WM_COMMAND_MPS( cmb1,
- GetDlgItem(hDlg, cmb1),
- MYCBN_DRAW ) );
- pOFN->nFilterIndex = nFilterIndex;
- if (pOFN->nFilterIndex ||
- !(pOFN->lpstrCustomFilter && *pOFN->lpstrCustomFilter))
- {
- lpFilter = pOFN->lpstrFilter +
- SendDlgItemMessage( hDlg,
- cmb1,
- CB_GETITEMDATA,
- (WPARAM)pOFN->nFilterIndex,
- 0L );
- }
- else
- {
- lpFilter = pOFN->lpstrCustomFilter +
- lstrlen(pOFN->lpstrCustomFilter) + 1;
- }
- if (*lpFilter)
- {
- TCHAR szText[MAX_FULLPATHNAME];
- // BUGBUG: lpFilter can be longer than MAX_FULLPATHNAME!!!
- lstrcpy(szText, lpFilter);
- //
- // Filtering is case-insensitive.
- //
- CharLower(szText);
- if (pOFI->szLastFilter[0] == CHAR_NULL)
- {
- lstrcpy(pOFI->szLastFilter, szText);
- }
- if (!(pOFN->lpstrFile && *pOFN->lpstrFile))
- {
- SetDlgItemText(hDlg, edt1, szText);
- }
- }
- }
- InitCurrentDisk(hDlg, pOFI, cmb2);
- bFirstTime = TRUE;
- bInChildDlg = FALSE;
- SendMessage( hDlg,
- WM_COMMAND,
- GET_WM_COMMAND_MPS(cmb2, GetDlgItem(hDlg, cmb2), MYCBN_DRAW) );
- SendMessage( hDlg,
- WM_COMMAND,
- GET_WM_COMMAND_MPS(cmb2, GetDlgItem(hDlg, cmb2), MYCBN_LIST) );
- if (pOFN->lpstrFile && *pOFN->lpstrFile)
- {
- TCHAR szText[MAX_FULLPATHNAME];
- lRet = ParseFile( pOFN->lpstrFile,
- IsLFNDriveX(hDlg, pOFN->lpstrFile),
- IS16BITWOWAPP(pOFN),
- FALSE );
- nFileOffset = (int)(SHORT)LOWORD(lRet);
- nExtOffset = (int)(SHORT)HIWORD(lRet);
- //
- // Is the filename invalid?
- //
- if ( !(pOFN->Flags & OFN_NOVALIDATE) &&
- (nFileOffset < 0) &&
- (nFileOffset != PARSE_EMPTYSTRING) &&
- (pOFN->lpstrFile[nExtOffset] != CHAR_SEMICOLON) )
- {
- StoreExtendedError(FNERR_INVALIDFILENAME);
- EndDialog(hDlg, FALSE);
- return (FALSE);
- }
- lstrcpy(szText, pOFN->lpstrFile);
- SetDlgItemText(hDlg, edt1, szText);
- }
- SetWindowLongPtr(GetDlgItem(hDlg, lst2), GWLP_WNDPROC, (LONG_PTR)dwLBSubclass);
- SetWindowLongPtr(GetDlgItem(hDlg, IDOK), GWLP_WNDPROC, (LONG_PTR)dwOKSubclass);
- if (pOFN->lpstrTitle && *pOFN->lpstrTitle)
- {
- SetWindowText(hDlg, pOFN->lpstrTitle);
- }
- //
- // By setting dyText to rRect.bottom/8, dyText defaults to 8 items showing
- // in the listbox. This only matters if the applications hook function
- // steals all WM_MEASUREITEM messages. Otherwise, dyText will be set in
- // the MeasureItem() routine. Check for !dyItem in case message ordering
- // has already sent WM_MEASUREITEM and dyText is already initialized.
- //
- if (!dyItem)
- {
- GetClientRect(GetDlgItem(hDlg, lst1), (LPRECT) &rRect);
- if (!(dyText = (rRect.bottom / 8)))
- {
- //
- // If no size to rectangle.
- //
- dyText = 8;
- }
- }
- // The template has changed to make it extremely clear that
- // this is not a combobox, but rather an edit control and a listbox. The
- // problem is that the new templates try to align the edit box and listbox.
- // Unfortunately, when listboxes add borders, they expand beyond their
- // borders. When edit controls add borders, they stay within their
- // borders. This makes it impossible to align the two controls strictly
- // within the template. The code below will align the controls, but only
- // if they are using the standard dialog template.
- //
- if (!(pOFN->Flags & (OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE)))
- {
- GetWindowRect(GetDlgItem(hDlg, lst1), (LPRECT)&rLbox);
- GetWindowRect(GetDlgItem(hDlg, edt1), (LPRECT)&rRect);
- rRect.left = rLbox.left;
- rRect.right = rLbox.right;
- MapWindowPoints(NULL, hDlg, (LPPOINT)&rRect, 2);
- SetWindowPos( GetDlgItem(hDlg, edt1),
- 0,
- rRect.left,
- rRect.top,
- rRect.right - rRect.left,
- rRect.bottom - rRect.top,
- SWP_NOZORDER );
- }
- if (pOFN->lpfnHook)
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFN);
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- ThunkOpenFileNameW2A(pOFI);
- bRet = ((*lpfnHook)( hDlg,
- WM_INITDIALOG,
- wParam,
- (LPARAM)pOFI->pOFNA ));
- //
- // Strange win 31 example uses lCustData to
- // hold a temporary variable that it passes back to
- // calling function.
- //
- ThunkOpenFileNameA2W(pOFI);
- }
- else
- #endif
- {
- bRet = ((*lpfnHook)( hDlg,
- WM_INITDIALOG,
- wParam,
- (LPARAM)pOFN ));
- }
- }
- else
- {
- #ifdef UNICODE
- //
- // Have to thunk A version even when there isn't a hook proc so it
- // doesn't reset W version on delayed thunk back.
- //
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- pOFI->pOFNA->Flags = pOFN->Flags;
- }
- #endif
- bRet = TRUE;
- }
- //
- // At first, assume there is net support !
- //
- if ((pOFN->Flags & OFN_NONETWORKBUTTON))
- {
- HWND hNet;
- if (hNet = GetDlgItem(hDlg, psh14))
- {
- EnableWindow(hNet = GetDlgItem(hDlg, psh14), FALSE);
- ShowWindow(hNet, SW_HIDE);
- }
- }
- else
- {
- AddNetButton( hDlg,
- ((pOFN->Flags & OFN_ENABLETEMPLATE)
- ? pOFN->hInstance
- : g_hinst),
- FILE_BOTTOM_MARGIN,
- (pOFN->Flags & (OFN_ENABLETEMPLATE |
- OFN_ENABLETEMPLATEHANDLE))
- ? FALSE
- : TRUE,
- (pOFN->Flags & OFN_NOLONGNAMES)
- ? FALSE
- : TRUE,
- FALSE);
- }
- return (bRet);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // InitTlsValues
- //
- ////////////////////////////////////////////////////////////////////////////
- int InitTlsValues(
- POPENFILEINFO pOFI)
- {
- //
- // As long as we do not call TlsGetValue before this,
- // everything should be ok.
- //
- LPCURDLG lpCurDlg, lpPrevDlg;
- DWORD dwError;
- LPTSTR lpCurDir;
- if (dwNumDlgs == MAX_THREADS)
- {
- dwError = CDERR_INITIALIZATION;
- goto ErrorExit0;
- }
- // alloc for the current directory
- if (lpCurDir = (LPTSTR)LocalAlloc(LPTR, CCHNETPATH * sizeof(TCHAR)))
- {
- GetCurrentDirectory(CCHNETPATH, lpCurDir);
- if ( (pOFI->pOFN->Flags & OFN_ALLOWMULTISELECT) &&
- (StrChr(lpCurDir, CHAR_SPACE)) )
- {
- GetShortPathName(lpCurDir, lpCurDir, CCHNETPATH);
- }
- }
- else
- {
- dwError = CDERR_MEMALLOCFAILURE;
- goto ErrorExit0;
- }
- // add a CurDlg struct to the list for this thread
- if (lpCurDlg = (LPCURDLG)LocalAlloc(LPTR, sizeof(CURDLG)))
- {
- // get start of CURDLG list for this thread
- // Note: lpPrevDlg will be NULL if there wasn't a previous dialog
- lpPrevDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg);
- // make sure TlsGetValue() actually succeeded (a NULL return could
- // mean there wasn't a previous dialog in the list)
- if (GetLastError() != NO_ERROR)
- {
- dwError = CDERR_INITIALIZATION;
- goto ErrorExit2;
- }
- // push the new dlg to the front of the list
- lpCurDlg->next = lpPrevDlg;
- lpCurDlg->lpstrCurDir = lpCurDir;
- PathAddBackslash(lpCurDlg->lpstrCurDir);
- EnterCriticalSection(&g_csLocal);
- lpCurDlg->dwCurDlgNum = dwNumDlgs++;
- LeaveCriticalSection(&g_csLocal);
- // save the new head of the list for the thread
- if (!TlsSetValue(g_tlsiCurDlg, (LPVOID)lpCurDlg))
- {
- dwError = CDERR_INITIALIZATION;
- goto ErrorExit2;
- }
- }
- else
- {
- dwError = CDERR_MEMALLOCFAILURE;
- goto ErrorExit1;
- }
- return(TRUE);
- ErrorExit2:
- LocalFree(lpCurDlg);
- ErrorExit1:
- LocalFree(lpCurDir);
- ErrorExit0:
- StoreExtendedError(dwError);
- return (FALSE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // InitFilterBox
- //
- // Places the double null terminated list of filters in the combo box.
- // The list should consist of pairs of null terminated strings, with
- // an additional null terminating the list.
- //
- ////////////////////////////////////////////////////////////////////////////
- DWORD InitFilterBox(
- HANDLE hDlg,
- LPCTSTR lpszFilter)
- {
- DWORD nOffset = 0;
- DWORD nIndex = 0;
- register WORD nLen;
- while (*lpszFilter)
- {
- //
- // First string put in as string to show.
- //
- nIndex = (DWORD) SendDlgItemMessage( hDlg,
- cmb1,
- CB_ADDSTRING,
- 0,
- (LPARAM)lpszFilter );
- nLen = (WORD)(lstrlen(lpszFilter) + 1);
- (LPTSTR)lpszFilter += nLen;
- nOffset += nLen;
- //
- // Second string put in as itemdata.
- //
- SendDlgItemMessage( hDlg,
- cmb1,
- CB_SETITEMDATA,
- (WPARAM)nIndex,
- nOffset );
- //
- // Advance to next element.
- //
- nLen = (WORD)(lstrlen(lpszFilter) + 1);
- (LPTSTR)lpszFilter += nLen;
- nOffset += nLen;
- }
- return (nIndex);
- }
- void TokenizeFilterString(LPTSTR pszFilterString, LPTSTR *ppszFilterArray, int cFilterArray, BOOL bLFN)
- {
- LPCTSTR pszDelim = bLFN ? szSemiColonTab : szSemiColonSpaceTab;
- int nFilters = 0;
- //
- // Find the first filter in the string, and add it to the
- // array.
- //
- ppszFilterArray[nFilters] = lstrtok(pszFilterString, pszDelim);
- //
- // Now we are going to loop through all the filters in the string
- // parsing the one we already have, and then finding the next one
- // and starting the loop over again.
- //
- while (ppszFilterArray[nFilters] && (nFilters < cFilterArray))
- {
- //
- // Check to see if the first character is a space. If so, remove
- // the spaces, and save the pointer back into the same spot. We
- // need to do this because the FindFirstFile/Next api will still
- // work on filenames that begin with a space since they also
- // look at the short names. The short names will begin with the
- // same first real letter as the long filename. For example, the
- // long filename is " my document" the first letter of this short
- // name is "m", so searching on "m*.*" or " m*.*" will yield the
- // same results.
- //
- if (bLFN && (*ppszFilterArray[nFilters] == CHAR_SPACE))
- {
- LPTSTR pszTemp = ppszFilterArray[nFilters];
- while ((*pszTemp == CHAR_SPACE) && *pszTemp)
- {
- pszTemp = CharNext(pszTemp);
- }
- ppszFilterArray[nFilters] = pszTemp;
- }
- //
- // Ready to move on to the next filter. Find the next
- // filter based upon the type of file system we're using.
- //
- ppszFilterArray[++nFilters] = lstrtok(NULL, pszDelim);
- //
- // In case we found a pointer to NULL, then look for the
- // next filter.
- //
- while (ppszFilterArray[nFilters] && !*ppszFilterArray[nFilters])
- {
- ppszFilterArray[nFilters] = lstrtok(NULL, pszDelim);
- }
- }
- }
- BOOL FoundFilterMatch(LPCTSTR pszIn, BOOL bLFN)
- {
- TCHAR szFilter[MAX_FULLPATHNAME];
- LPTSTR pszF[MAXFILTERS + 1];
- BOOL fFoundMatches = FALSE;
- int i;
- StrCpyN(szFilter, pszIn, SIZECHARS(szFilter));
- TokenizeFilterString(szFilter, pszF, ARRAYSIZE(pszF), bLFN);
- for (i = 0; i < ARRAYSIZE(pszF) && pszF[i] && !fFoundMatches; i++)
- {
- HANDLE hff;
- WIN32_FIND_DATA FindFileData;
- //
- // Find First for each filter.
- //
- hff = FindFirstFile(pszF[i], &FindFileData);
- if (hff == INVALID_HANDLE_VALUE)
- {
- continue;
- }
- do
- {
- if ((FindFileData.dwFileAttributes & EXCLBITS) ||
- (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- continue;
- }
- fFoundMatches = TRUE;
- break;
- } while (FindNextFile(hff, &FindFileData));
- FindClose(hff);
- }
- return fFoundMatches;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetAppOpenDir
- //
- ////////////////////////////////////////////////////////////////////////////
- void GetAppOpenDir(LPCTSTR pszDir, LPTSTR pszOut, LPITEMIDLIST *ppidl)
- {
- BOOL fUseMyDocs = FALSE;
- TCHAR szPersonal[MAX_PATH];
- *pszOut = 0; // prepare to return empty string
- if (ppidl)
- *ppidl = NULL;
- if (SHGetSpecialFolderPath(NULL, szPersonal, CSIDL_PERSONAL, FALSE))
- {
- if (*pszDir)
- {
- //
- // if the current directory is a temp dir
- // or is the mydocs dir, then use my docs
- // otherwise we should just use this directory
- //
- if ((0 == lstrcmpi(pszDir, szPersonal) || PathIsTemporary(pszDir)))
- fUseMyDocs = TRUE;
- }
- else
- {
- TCHAR szPath[MAX_FULLPATHNAME];
- if (GetCurrentDirectory(ARRAYSIZE(szPath), szPath)
- && (PathIsTemporary(szPath) || (0 == lstrcmpi(szPath, szPersonal))))
- fUseMyDocs = TRUE;
- }
- }
- if (fUseMyDocs)
- {
- lstrcpy(pszOut, szPersonal);
- if (ppidl)
- *ppidl = CreateMyDocsIDList();
- }
- else
- lstrcpy(pszOut, pszDir);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // InitCurrentDisk
- //
- ////////////////////////////////////////////////////////////////////////////
- VOID InitCurrentDisk(HWND hDlg, POPENFILEINFO pOFI, WORD cmb)
- {
- TCHAR szPath[MAX_FULLPATHNAME];
- //
- // Clear out stale unc stuff from disk info.
- // Unc \servershares are persistent through one popup session
- // and then we resync with the system. This is to fix a bug
- // where a user's startup dir is unc but the system no longer has
- // a connection and hence the cmb2 appears blank.
- //
- EnableDiskInfo(FALSE, TRUE);
- if (pOFI->pOFN->lpstrInitialDir)
- {
- //
- // Notice that we force ChangeDir to succeed here
- // but that TlsGetValue(g_tlsiCurDlg)->lpstrCurDir will return "" which
- // when fed to SheChangeDirEx means GetCurrentDir will be called.
- // So, the default cd behavior at startup is:
- // 1. lpstrInitialDir
- // 2. GetCurrentDir
- //
- szPath[0] = 0;
- if ( (pOFI->pOFN->Flags & OFN_ALLOWMULTISELECT) &&
- (StrChr(pOFI->pOFN->lpstrInitialDir, CHAR_SPACE)) &&
- (GetShortPathName( pOFI->pOFN->lpstrInitialDir,
- szPath,
- MAX_FULLPATHNAME )) &&
- (szPath[0] != 0) )
- {
- ChangeDir(hDlg, szPath, TRUE, FALSE);
- }
- else
- {
- ChangeDir(hDlg, pOFI->pOFN->lpstrInitialDir, TRUE, FALSE);
- }
- }
- else
- {
- GetAppOpenDir(TEXT(""),szPath, NULL);
- ChangeDir(hDlg, szPath, TRUE, FALSE);
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // vDeleteDirDriveBitmap
- //
- // Gets rid of bitmaps, if they exist.
- //
- ////////////////////////////////////////////////////////////////////////////
- VOID vDeleteDirDriveBitmap()
- {
- if (hbmpOrigMemBmp)
- {
- SelectObject(hdcMemory, hbmpOrigMemBmp);
- if (hbmpDirDrive != HNULL)
- {
- DeleteObject(hbmpDirDrive);
- hbmpDirDrive = HNULL;
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // LoadDirDriveBitmap
- //
- // Creates the drive/directory bitmap. If an appropriate bitmap
- // already exists, it just returns immediately. Otherwise, it
- // loads the bitmap and creates a larger bitmap with both regular
- // and highlight colors.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL LoadDirDriveBitmap()
- {
- BITMAP bmp;
- HANDLE hbmp, hbmpOrig;
- HDC hdcTemp;
- BOOL bWorked = FALSE;
- if ( (hbmpDirDrive != HNULL) &&
- (rgbWindowColor == rgbDDWindow) &&
- (rgbHiliteColor == rgbDDHilite))
- {
- if (SelectObject(hdcMemory, hbmpDirDrive))
- {
- return (TRUE);
- }
- }
- vDeleteDirDriveBitmap();
- rgbDDWindow = rgbWindowColor;
- rgbDDHilite = rgbHiliteColor;
- if (!(hdcTemp = CreateCompatibleDC(hdcMemory)))
- {
- goto LoadExit;
- }
- if (!(hbmp = LoadAlterBitmap(bmpDirDrive, rgbSolidBlue, rgbWindowColor)))
- {
- goto DeleteTempDC;
- }
- GetObject(hbmp, sizeof(BITMAP), (LPTSTR)&bmp);
- dyDirDrive = bmp.bmHeight;
- dxDirDrive = bmp.bmWidth;
- hbmpOrig = SelectObject(hdcTemp, hbmp);
- hbmpDirDrive = CreateDiscardableBitmap(hdcTemp, dxDirDrive * 2, dyDirDrive);
- if (!hbmpDirDrive)
- {
- goto DeleteTempBmp;
- }
- if (!SelectObject(hdcMemory, hbmpDirDrive))
- {
- vDeleteDirDriveBitmap();
- goto DeleteTempBmp;
- }
- BitBlt(hdcMemory, 0, 0, dxDirDrive, dyDirDrive, hdcTemp, 0, 0, SRCCOPY);
- SelectObject(hdcTemp, hbmpOrig);
- DeleteObject(hbmp);
- if (!(hbmp = LoadAlterBitmap(bmpDirDrive, rgbSolidBlue, rgbHiliteColor)))
- {
- goto DeleteTempDC;
- }
- hbmpOrig = SelectObject(hdcTemp, hbmp);
- BitBlt(hdcMemory, dxDirDrive, 0, dxDirDrive, dyDirDrive, hdcTemp, 0, 0, SRCCOPY);
- SelectObject(hdcTemp, hbmpOrig);
- bWorked = TRUE;
- DeleteTempBmp:
- DeleteObject(hbmp);
- DeleteTempDC:
- DeleteDC(hdcTemp);
- LoadExit:
- return (bWorked);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // SetRGBValues
- //
- // This sets the various system colors in static variables. It's
- // called at init time and when system colors change.
- //
- ////////////////////////////////////////////////////////////////////////////
- void SetRGBValues()
- {
- rgbWindowColor = GetSysColor(COLOR_WINDOW);
- rgbHiliteColor = GetSysColor(COLOR_HIGHLIGHT);
- rgbWindowText = GetSysColor(COLOR_WINDOWTEXT);
- rgbHiliteText = GetSysColor(COLOR_HIGHLIGHTTEXT);
- rgbGrayText = GetSysColor(COLOR_GRAYTEXT);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // FSetUpFile
- //
- // This loads in the resources & initializes the data used by the
- // file dialogs.
- //
- // Returns: TRUE if successful
- // FALSE if any bitmap fails
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL FSetUpFile()
- {
- if (cLock++)
- {
- return (TRUE);
- }
- SetRGBValues();
- return (LoadDirDriveBitmap());
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetPathOffset
- //
- ////////////////////////////////////////////////////////////////////////////
- int GetPathOffset(LPTSTR lpszDir)
- {
- LPTSTR lpszSkipRoot;
- if (!lpszDir || !*lpszDir)
- {
- return (-1);
- }
- lpszSkipRoot = PathSkipRoot(lpszDir);
- if (lpszSkipRoot)
- {
- return (int)((lpszSkipRoot - 1) - lpszDir);
- }
- else
- {
- //
- // Unrecognized format.
- //
- return (-1);
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // FileOpenCmd
- //
- // Handles WM_COMMAND for Open & Save dlgs.
- //
- // edt1 = file name
- // lst1 = list of files in current directory matching current pattern
- // cmb1 = lists file patterns
- // stc1 = is current directory
- // lst2 = lists directories on current drive
- // cmb2 = lists drives
- // IDOK = is Open pushbutton
- // IDCANCEL = is Cancel pushbutton
- // chx1 = is for opening read only files
- //
- // Returns the normal dialog proc values.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL_PTR FileOpenCmd(
- HANDLE hDlg,
- WPARAM wParam,
- LPARAM lParam,
- POPENFILEINFO pOFI,
- BOOL bSave)
- {
- LPOPENFILENAME pOFN;
- LPTSTR pch, pch2;
- WORD i, sCount, len;
- LRESULT wFlag;
- BOOL_PTR bRet, bHookRet;
- TCHAR szText[MAX_FULLPATHNAME];
- HWND hwnd;
- LPCURDLG lpCurDlg;
- if (!pOFI)
- {
- return (FALSE);
- }
- pOFN = pOFI->pOFN;
- switch (GET_WM_COMMAND_ID(wParam, lParam))
- {
- case ( IDOK ) :
- {
- #ifdef UNICODE
- //
- // Apps that side-effect this message may not have their
- // internal unicode strings updated (eg. Corel Mosaic).
- //
- // NOTE: Must preserve the internal flags.
- //
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- DWORD InternalFlags = pOFN->Flags & OFN_ALL_INTERNAL_FLAGS;
- ThunkOpenFileNameA2W(pOFI);
- pOFN->Flags |= InternalFlags;
- }
- #endif
- //
- // If the focus is on the directory box, or if the selection
- // within the box has changed since the last listing, give a
- // new listing.
- //
- if (bChangeDir || ((GetFocus() == GetDlgItem(hDlg, lst2)) &&
- (pOFN->Flags & OFN_DIRSELCHANGED)))
- {
- bChangeDir = FALSE;
- goto ChangingDir;
- }
- else if ((GetFocus() == (hwnd = GetDlgItem(hDlg, cmb2))) &&
- (pOFN->Flags & OFN_DRIVEDOWN))
- {
- //
- // If the focus is on the drive or filter combobox, give
- // a new listing.
- //
- SendDlgItemMessage(hDlg, cmb2, CB_SHOWDROPDOWN, FALSE, 0L);
- break;
- }
- else if ((GetFocus() == (hwnd = GetDlgItem(hDlg, cmb1))) &&
- (pOFN->Flags & OFN_FILTERDOWN))
- {
- SendDlgItemMessage(hDlg, cmb1, CB_SHOWDROPDOWN, FALSE, 0L);
- lParam = (LPARAM)hwnd;
- goto ChangingFilter;
- }
- else
- {
- #ifdef UNICODE
- //
- // Visual Basic passes in an uninitialized lpstrDefExt string.
- // Since we only have to use it in OKButtonPressed, update
- // lpstrDefExt here along with whatever else is only needed
- // in OKButtonPressed.
- //
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- ThunkOpenFileNameA2WDelayed(pOFI);
- }
- #endif
- if (OKButtonPressed(hDlg, pOFI, bSave))
- {
- bRet = TRUE;
- if (pOFN->lpstrFile)
- {
- if (!(pOFN->Flags & OFN_NOVALIDATE))
- {
- if (pOFN->nMaxFile >= 3)
- {
- if ((pOFN->lpstrFile[0] == 0) ||
- (pOFN->lpstrFile[1] == 0) ||
- (pOFN->lpstrFile[2] == 0))
- {
- bRet = FALSE;
- StoreExtendedError(FNERR_BUFFERTOOSMALL);
- }
- }
- else
- {
- bRet = FALSE;
- StoreExtendedError(FNERR_BUFFERTOOSMALL);
- }
- }
- }
- goto AbortDialog;
- }
- }
- SendDlgItemMessage(hDlg, edt1, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
- return (TRUE);
- break;
- }
- case ( IDCANCEL ) :
- {
- bRet = FALSE;
- bUserPressedCancel = TRUE;
- goto AbortDialog;
- }
- case ( IDABORT ) :
- {
- bRet = (BYTE)lParam;
- AbortDialog:
- //
- // Return the most recently used filter.
- //
- pOFN->nFilterIndex = (WORD)SendDlgItemMessage( hDlg,
- cmb1,
- CB_GETCURSEL,
- (WPARAM)0,
- (LPARAM)0 );
- if (pOFN->lpstrCustomFilter)
- {
- len = (WORD)(lstrlen(pOFN->lpstrCustomFilter) + 1);
- sCount = (WORD)lstrlen(pOFI->szLastFilter);
- if (pOFN->nMaxCustFilter > (DWORD)(sCount + len))
- {
- lstrcpy(pOFN->lpstrCustomFilter + len, pOFI->szLastFilter);
- }
- }
- if (!pOFN->lpstrCustomFilter ||
- (*pOFN->lpstrCustomFilter == CHAR_NULL))
- {
- pOFN->nFilterIndex++;
- }
- if (((GET_WM_COMMAND_ID(wParam, lParam)) == IDOK) && pOFN->lpfnHook)
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFN);
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- ThunkOpenFileNameW2A(pOFI);
- bHookRet = (*lpfnHook)( hDlg,
- msgFILEOKA,
- 0,
- (LPARAM)pOFI->pOFNA );
- //
- // For apps that side-effect pOFNA stuff and expect it to
- // be preserved through dialog exit, update internal
- // struct after the hook proc is called.
- //
- ThunkOpenFileNameA2W(pOFI);
- }
- else
- #endif
- {
- bHookRet = (*lpfnHook)( hDlg,
- msgFILEOKW,
- 0,
- (LPARAM)pOFI->pOFN );
- }
- if (bHookRet)
- {
- HourGlass(FALSE);
- break;
- }
- }
- if (pOFN->Flags & OFN_ALLOWMULTISELECT)
- {
- LocalShrink((HANDLE)0, 0);
- }
- wNoRedraw = 0;
- if (pOFI->pOFN->Flags & OFN_ENABLEHOOK)
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFN);
- glpfnFileHook = lpfnHook;
- }
- RemoveProp(hDlg, FILEPROP);
- EndDialog(hDlg, bRet);
- if (pOFI)
- {
- if ((pOFN->Flags & OFN_NOCHANGEDIR) && *pOFI->szCurDir)
- {
- ChangeDir(hDlg, pOFI->szCurDir, TRUE, FALSE);
- }
- }
- //
- // BUGBUG:
- // If the app subclasses ID_ABORT, the worker thread will never
- // get exited. This will cause problems. Currently, there are
- // no apps that do this, though.
- //
- return (TRUE);
- break;
- }
- case ( edt1 ) :
- {
- if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
- {
- int iIndex, iCount;
- HWND hLBox = GetDlgItem(hDlg, lst1);
- WORD wIndex = (WORD)SendMessage(hLBox, LB_GETCARETINDEX, 0, 0);
- szText[0] = CHAR_NULL;
- if (wIndex == (WORD)LB_ERR)
- {
- break;
- }
- SendMessage( GET_WM_COMMAND_HWND(wParam, lParam),
- WM_GETTEXT,
- (WPARAM)MAX_FULLPATHNAME,
- (LPARAM)szText );
- if ((iIndex = (int)SendMessage( hLBox,
- LB_FINDSTRING,
- (WPARAM)(wIndex - 1),
- (LPARAM)szText )) != LB_ERR)
- {
- RECT rRect;
- iCount = (int)SendMessage(hLBox, LB_GETTOPINDEX, 0, 0L);
- GetClientRect(hLBox, (LPRECT)&rRect);
- if ((iIndex < iCount) ||
- (iIndex >= (iCount + rRect.bottom / dyText)))
- {
- SendMessage(hLBox, LB_SETCARETINDEX, (WPARAM)iIndex, 0);
- SendMessage(hLBox, LB_SETTOPINDEX, (WPARAM)iIndex, 0);
- }
- }
- return (TRUE);
- }
- break;
- }
- case ( lst1 ) :
- {
- //
- // A double click means OK.
- //
- if (GET_WM_COMMAND_CMD(wParam, lParam)== LBN_DBLCLK)
- {
- SendMessage(hDlg, WM_COMMAND, GET_WM_COMMAND_MPS(IDOK, 0, 0));
- return (TRUE);
- }
- else if (pOFN && (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_SELCHANGE))
- {
- if (pOFN->Flags & OFN_ALLOWMULTISELECT)
- {
- int *pSelIndex;
- //
- // Muliselection allowed.
- //
- sCount = (SHORT)SendMessage(GET_WM_COMMAND_HWND(wParam, lParam),
- LB_GETSELCOUNT,
- 0,
- 0L );
- if (!sCount)
- {
- //
- // If nothing selected, clear edit control.
- //
- SetDlgItemText(hDlg, edt1, szNull);
- }
- else
- {
- DWORD cchMemBlockSize = 2048;
- DWORD cchTotalLength = 0;
- pSelIndex = (int *)LocalAlloc(LPTR, sCount * sizeof(int));
- if (!pSelIndex)
- {
- goto LocalFailure1;
- }
- sCount = (SHORT)SendMessage(
- GET_WM_COMMAND_HWND(wParam, lParam),
- LB_GETSELITEMS,
- (WPARAM)sCount,
- (LONG_PTR)(LPTSTR)pSelIndex );
- pch2 = pch = (LPTSTR)
- LocalAlloc(LPTR, cchMemBlockSize * sizeof(TCHAR));
- if (!pch)
- {
- goto LocalFailure2;
- }
- for (*pch = CHAR_NULL, i = 0; i < sCount; i++)
- {
- len = (WORD)SendMessage(
- GET_WM_COMMAND_HWND(wParam, lParam),
- LB_GETTEXTLEN,
- (WPARAM)(*(pSelIndex + i)),
- (LPARAM)0 );
- //
- // Add the length of the selected file to the
- // total length of selected files. + 2 for the
- // space that goes in between files and for the
- // possible dot added at the end of the filename
- // if the file does not have an extension.
- //
- cchTotalLength += (len + 2);
- if (cchTotalLength > cchMemBlockSize)
- {
- LPTSTR pTemp;
- UINT cchPrevLen = cchTotalLength - (len + 2);
- cchMemBlockSize = cchMemBlockSize << 1;
- pTemp = (LPTSTR)LocalReAlloc(
- pch,
- cchMemBlockSize * sizeof(TCHAR),
- LMEM_MOVEABLE );
- if (pTemp)
- {
- pch = pTemp;
- pch2 = pch + cchPrevLen;
- }
- else
- {
- LocalFree(pch);
- goto LocalFailure2;
- }
- }
- SendMessage( GET_WM_COMMAND_HWND(wParam, lParam),
- LB_GETTEXT,
- (WPARAM)(*(pSelIndex + i)),
- (LONG_PTR)pch2 );
- if (!StrChr(pch2, CHAR_DOT))
- {
- *(pch2 + len++) = CHAR_DOT;
- }
- pch2 += len;
- *pch2++ = CHAR_SPACE;
- }
- if (pch2 != pch)
- {
- *--pch2 = CHAR_NULL;
- }
- SetDlgItemText(hDlg, edt1, pch);
- LocalFree((HANDLE)pch);
- LocalFailure2:
- LocalFree((HANDLE)pSelIndex);
- }
- LocalFailure1:
- if (pOFN->lpfnHook)
- {
- i = (WORD)SendMessage( GET_WM_COMMAND_HWND(wParam, lParam),
- LB_GETCARETINDEX,
- 0,
- 0L );
- if (!(i & 0x8000))
- {
- wFlag = (SendMessage(
- GET_WM_COMMAND_HWND(wParam, lParam),
- LB_GETSEL,
- (WPARAM)i,
- 0L )
- ? CD_LBSELADD
- : CD_LBSELSUB);
- }
- else
- {
- wFlag = CD_LBSELNOITEMS;
- }
- }
- }
- else
- {
- //
- // Multiselection is not allowed.
- // Put the file name in the edit control.
- //
- szText[0] = CHAR_NULL;
- i = (WORD)SendMessage( GET_WM_COMMAND_HWND(wParam, lParam),
- LB_GETCURSEL,
- 0,
- 0L );
- if (i != (WORD)LB_ERR)
- {
- i = (WORD)SendMessage( GET_WM_COMMAND_HWND(wParam, lParam),
- LB_GETTEXT,
- (WPARAM)i,
- (LONG_PTR)szText );
- if (!StrChr(szText, CHAR_DOT))
- {
- if (i < MAX_FULLPATHNAME - 1)
- {
- szText[i] = CHAR_DOT;
- szText[i + 1] = CHAR_NULL;
- }
- }
- if (!bCasePreserved)
- {
- CharLower(szText);
- }
- SetDlgItemText(hDlg, edt1, szText);
- if (pOFN->lpfnHook)
- {
- i = (WORD)SendMessage(
- GET_WM_COMMAND_HWND(wParam, lParam),
- LB_GETCURSEL,
- 0,
- 0L );
- wFlag = CD_LBSELCHANGE;
- }
- }
- }
- if (pOFN->lpfnHook)
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFN);
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- (*lpfnHook)( hDlg,
- msgLBCHANGEA,
- lst1,
- MAKELONG(i, wFlag) );
- }
- else
- #endif
- {
- (*lpfnHook)( hDlg,
- msgLBCHANGEW,
- lst1,
- MAKELONG(i, wFlag) );
- }
- }
- SendDlgItemMessage(hDlg, edt1, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
- return (TRUE);
- }
- break;
- }
- case ( cmb1 ) :
- {
- switch (GET_WM_COMMAND_CMD(wParam, lParam))
- {
- case ( CBN_DROPDOWN ) :
- {
- if (wWinVer >= 0x030A)
- {
- pOFN->Flags |= OFN_FILTERDOWN;
- }
- return (TRUE);
- break;
- }
- case ( CBN_CLOSEUP ) :
- {
- PostMessage( hDlg,
- WM_COMMAND,
- GET_WM_COMMAND_MPS(cmb1, lParam, MYCBN_DRAW) );
- return (TRUE);
- break;
- }
- case ( CBN_SELCHANGE ) :
- {
- //
- // Need to change the file listing in lst1.
- //
- if (pOFN->Flags & OFN_FILTERDOWN)
- {
- return (TRUE);
- break;
- }
- }
- case ( MYCBN_DRAW ) :
- {
- SHORT nIndex;
- LPCTSTR lpFilter;
- HourGlass(TRUE);
- pOFN->Flags &= ~OFN_FILTERDOWN;
- ChangingFilter:
- nIndex = (SHORT)SendDlgItemMessage( hDlg,
- cmb1,
- CB_GETCURSEL,
- 0,
- 0L );
- if (nIndex < 0)
- {
- //
- // No current selection.
- //
- break;
- }
- //
- // Must also check if filter contains anything.
- //
- if (nIndex ||
- !(pOFN->lpstrCustomFilter && *pOFN->lpstrCustomFilter))
- {
- lpFilter = pOFN->lpstrFilter +
- SendDlgItemMessage( hDlg,
- cmb1,
- CB_GETITEMDATA,
- (WPARAM)nIndex,
- 0L );
- }
- else
- {
- lpFilter = pOFN->lpstrCustomFilter +
- lstrlen(pOFN->lpstrCustomFilter) + 1;
- }
- if (*lpFilter)
- {
- GetDlgItemText( hDlg,
- edt1,
- szText,
- MAX_FULLPATHNAME - 1 );
- bRet = (!szText[0] ||
- (StrChr(szText, CHAR_STAR)) ||
- (StrChr(szText, CHAR_QMARK)));
- lstrcpy(szText, lpFilter);
- if (bRet)
- {
- CharLower(szText);
- SetDlgItemText(hDlg, edt1, szText);
- SendDlgItemMessage( hDlg,
- edt1,
- EM_SETSEL,
- (WPARAM)0,
- (LPARAM)-1 );
- }
- FListAll(pOFI, hDlg, szText);
- if (!bInitializing)
- {
- lstrcpy(pOFI->szLastFilter, szText);
- #ifdef WINNT
- //
- // Provide dynamic lpstrDefExt updating
- // when lpstrDefExt is user initialized.
- //
- if (StrChr((LPTSTR)lpFilter, CHAR_DOT) &&
- pOFN->lpstrDefExt)
- {
- DWORD cbLen = MIN_DEFEXT_LEN - 1; // only 1st 3
- LPTSTR lpTemp = (LPTSTR)(pOFN->lpstrDefExt);
- while (*lpFilter++ != CHAR_DOT);
- if (!(StrChr((LPTSTR)lpFilter, CHAR_STAR)) &&
- !(StrChr((LPTSTR)lpFilter, CHAR_QMARK)))
- {
- while (cbLen--)
- {
- *lpTemp++ = *lpFilter++;
- }
- *lpTemp = CHAR_NULL;
- }
- }
- #endif
- }
- }
- if (pOFN->lpfnHook)
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFN);
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- (*lpfnHook)( hDlg,
- msgLBCHANGEA,
- cmb1,
- MAKELONG(nIndex, CD_LBSELCHANGE) );
- }
- else
- #endif
- {
- (*lpfnHook)( hDlg,
- msgLBCHANGEW,
- cmb1,
- MAKELONG(nIndex, CD_LBSELCHANGE) );
- }
- }
- HourGlass(FALSE);
- return (TRUE);
- break;
- }
- default :
- {
- break;
- }
- }
- break;
- }
- case ( lst2 ) :
- {
- if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_SELCHANGE)
- {
- if (!(pOFN->Flags & OFN_DIRSELCHANGED))
- {
- if ((DWORD)SendDlgItemMessage( hDlg,
- lst2,
- LB_GETCURSEL,
- 0,
- 0L ) != pOFI->idirSub - 1)
- {
- StripFileName(hDlg, IS16BITWOWAPP(pOFN));
- pOFN->Flags |= OFN_DIRSELCHANGED;
- }
- }
- return (TRUE);
- }
- else if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_SETFOCUS)
- {
- EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
- SendMessage( GetDlgItem(hDlg, IDCANCEL),
- BM_SETSTYLE,
- (WPARAM)BS_PUSHBUTTON,
- (LPARAM)TRUE );
- }
- else if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_KILLFOCUS)
- {
- if (pOFN && (pOFN->Flags & OFN_DIRSELCHANGED))
- {
- pOFN->Flags &= ~OFN_DIRSELCHANGED;
- }
- else
- {
- bChangeDir = FALSE;
- }
- }
- else if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_DBLCLK)
- {
- TCHAR szNextDir[CCHNETPATH];
- LPTSTR lpCurDir;
- DWORD idir;
- DWORD idirNew;
- int cb;
- LPTSTR pstrPath;
- ChangingDir:
- bChangeDir = FALSE;
- pOFN->Flags &= ~OFN_DIRSELCHANGED;
- idirNew = (DWORD)SendDlgItemMessage( hDlg,
- lst2,
- LB_GETCURSEL,
- 0,
- 0L );
- //
- // Can use relative path name.
- //
- *pOFI->szPath = 0;
- if (idirNew >= pOFI->idirSub)
- {
- cb = (int) SendDlgItemMessage( hDlg,
- lst2,
- LB_GETTEXT,
- (WPARAM)idirNew,
- (LPARAM)pOFI->szPath );
- //
- // sanity check
- //
- if (!(lpCurDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg)) ||
- !(lpCurDir = lpCurDlg->lpstrCurDir))
- {
- break;
- }
- lstrcpy(szNextDir, lpCurDir);
- //
- // Fix phenom with c:\foobar - because of inconsistency
- // in directory display guaranteed to have a valid
- // lpCurDir here, right?
- //
- PathAddBackslash(szNextDir);
- lstrcat(szNextDir, pOFI->szPath);
- pstrPath = szNextDir;
- idirNew = pOFI->idirSub; // for msgLBCHANGE message
- }
- else
- {
- //
- // Need full path name.
- //
- cb = (int) SendDlgItemMessage( hDlg,
- lst2,
- LB_GETTEXT,
- 0,
- (LPARAM)pOFI->szPath );
- //
- // The following condition is necessary because wb displays
- // \servershare (the disk resource name) for unc, but
- // for root paths (eg. c:) for device conns, this in-
- // consistency is hacked around here and in FillOutPath.
- //
- if (DBL_BSLASH(pOFI->szPath))
- {
- lstrcat(pOFI->szPath, TEXT("\"));
- cb++;
- }
- for (idir = 1; idir <= idirNew; ++idir)
- {