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: 277k
Category:
Windows Kernel
Development Platform:
Visual C++
- /*++
- Copyright (c) 1990-1995, Microsoft Corporation All rights reserved.
- Module Name:
- fileopen.c
- Abstract:
- This module implements the Win32 fileopen dialogs.
- Revision History:
- --*/
- //
- // Include Files.
- //
- #include <nt.h>
- #include <ntrtl.h>
- #include <nturtl.h>
- #include <windows.h>
- #include <port1632.h>
- #include <lm.h>
- #include <winnetwk.h>
- #include <npapi.h>
- #include <shellapi.h>
- #include <shlapip.h>
- #include <commctrl.h>
- #include <comctrlp.h>
- #include <tchar.h>
- #include "privcomd.h"
- #include "fileopen.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
- //
- // Global Variables.
- //
- //
- // Caching drive list.
- //
- extern DWORD dwNumDisks;
- extern OFN_DISKINFO gaDiskInfo[MAX_DISKS];
- 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];
- //
- // For WNet apis.
- //
- HANDLE hLNDThread = NULL;
- extern HANDLE hMPR;
- extern HANDLE hMPRUI;
- TCHAR szCOMDLG32[] = TEXT("comdlg32.dll");
- TCHAR szMPR[] = TEXT("mpr.dll");
- TCHAR szMPRUI[] = TEXT("mprui.dll");
- //
- // WNet stuff from mpr.dll.
- //
- typedef DWORD (WINAPI *LPFNWNETCONNDLG)(HWND, DWORD);
- typedef DWORD (WINAPI *LPFNWNETOPENENUM)(DWORD, DWORD, DWORD, LPNETRESOURCE, LPHANDLE);
- typedef DWORD (WINAPI *LPFNWNETENUMRESOURCE)(HANDLE, LPDWORD, LPVOID, LPDWORD);
- typedef DWORD (WINAPI *LPFNWNETCLOSEENUM)(HANDLE);
- typedef DWORD (WINAPI *LPFNWNETFORMATNETNAME)(LPTSTR, LPTSTR, LPTSTR, LPDWORD, DWORD, DWORD);
- typedef DWORD (WINAPI *LPFNWNETRESTORECONN)(HWND, LPTSTR);
- LPFNWNETCONNDLG lpfnWNetConnDlg;
- LPFNWNETOPENENUM lpfnWNetOpenEnum;
- LPFNWNETENUMRESOURCE lpfnWNetEnumResource;
- LPFNWNETCLOSEENUM lpfnWNetCloseEnum;
- LPFNWNETFORMATNETNAME lpfnWNetFormatNetName;
- LPFNWNETRESTORECONN lpfnWNetRestoreConn;
- //
- // !!!!!
- // Keep CHAR until unicode GetProcAddrW.
- //
- CHAR szWNetGetConn[] = "WNetGetConnectionW";
- CHAR szWNetConnDlg[] = "WNetConnectionDialog";
- CHAR szWNetOpenEnum[] = "WNetOpenEnumW";
- CHAR szWNetEnumResource[] = "WNetEnumResourceW";
- CHAR szWNetCloseEnum[] = "WNetCloseEnum";
- CHAR szWNetFormatNetName[] = "WNetFormatNetworkNameW";
- CHAR szWNetRestoreConn[] = "WNetRestoreConnectionW";
- WNDPROC lpLBProc = NULL;
- WNDPROC lpOKProc = NULL;
- //
- // Drive/Dir bitmap dimensions.
- //
- LONG dxDirDrive = 0;
- LONG dyDirDrive = 0;
- //
- // BUG! 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_tlsiCurDir;
- extern DWORD g_tlsiCurThread;
- 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;
- //
- // BUG!!
- // 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. Ntvdm???
- //
- 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;
- //
- // Function Prototypes.
- //
- SHORT
- GetFileTitleX(
- LPTSTR lpszFile,
- LPTSTR lpszTitle,
- WORD wBufSize);
- BOOL
- GetFileName(
- POPENFILEINFO pOFI,
- WNDPROC qfnDlgProc);
- BOOL
- FileOpenDlgProc(
- HWND hDlg,
- UINT wMsg,
- WPARAM wParam,
- LPARAM lParam);
- BOOL
- FileSaveDlgProc(
- HWND hDlg,
- UINT wMsg,
- WPARAM wParam,
- LPARAM lParam);
- BOOL
- InitFileDlg(
- HWND hDlg,
- WPARAM wParam,
- POPENFILEINFO pOFI);
- INT
- InitTlsValues();
- DWORD
- InitFilterBox(
- HANDLE hDlg,
- LPCTSTR lpszFilter);
- VOID
- InitCurrentDisk(
- HWND hDlg,
- POPENFILEINFO pOFI,
- WORD cmb);
- VOID
- vDeleteDirDriveBitmap();
- BOOL
- LoadDirDriveBitmap();
- void
- SetRGBValues();
- BOOL
- FSetUpFile();
- BOOL
- FileOpenCmd(
- HANDLE hDlg,
- WPARAM wP,
- DWORD 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);
- BOOL WINAPI
- dwOKSubclass(
- HWND hOK,
- UINT msg,
- WPARAM wP,
- LPARAM lP);
- BOOL WINAPI
- dwLBSubclass(
- HWND hLB,
- UINT msg,
- WPARAM wP,
- LPARAM lP);
- 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,
- LPTSTR lpDelim);
- LPTSTR
- ChopText(
- HWND hwndDlg,
- INT idStatic,
- LPTSTR lpch);
- BOOL
- FillOutPath(
- HWND hList,
- POPENFILEINFO pOFI);
- 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();
- VOID
- LoadMPR();
- 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,
- WNDPROC qfnDlgProc);
- #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
- {
- MultiByteToWideChar( CP_ACP,
- 0,
- (LPSTR)lpszFileA,
- -1,
- 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)))
- {
- WideCharToMultiByte( CP_ACP,
- 0,
- lpszTitleW,
- -1,
- lpszTitleA,
- cbBuf,
- NULL,
- NULL );
- }
- //
- // Clean up memory.
- //
- LocalFree(lpszTitleW);
- if (lpszFileW)
- {
- LocalFree(lpszFileW);
- }
- return (fResult);
- }
- #else
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetFileTitleW
- //
- // Stub UNICODE function for GetFileTitle when this code is built ANSI.
- //
- ////////////////////////////////////////////////////////////////////////////
- SHORT WINAPI GetFileTitleW(
- LPCWSTR lpszFileW,
- LPWSTR lpszTitleW,
- WORD cbBuf)
- {
- SetLastErrorEx(SLE_WARNING, 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;
- nNeeded = (SHORT)(INT)LOWORD(ParseFile(lpszFile, TRUE, FALSE));
- if (nNeeded >= 0)
- {
- //
- // Is the filename valid?
- //
- lpszPtr = (LPTSTR)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 (mystrchr(lpszPtr, CHAR_STAR) ||
- mystrchr(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, (WNDPROC)FileOpenDlgProc) );
- }
- #else
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetOpenFileNameW
- //
- // Stub UNICODE function for GetOpenFileName when this code is built ANSI.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL WINAPI GetOpenFileNameW(
- LPOPENFILENAMEW pOFNW)
- {
- SetLastErrorEx(SLE_WARNING, 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;
- return ( GetFileName(&OFI, (WNDPROC)FileOpenDlgProc) );
- }
- #ifdef UNICODE
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetSaveFileNameA
- //
- // ANSI entry point for GetSaveFileName when this code is built UNICODE.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL WINAPI GetSaveFileNameA(
- LPOPENFILENAMEA pOFNA)
- {
- return ( GenericGetFileNameA(pOFNA, (WNDPROC)FileSaveDlgProc) );
- }
- #else
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetSaveFileNameW
- //
- // Stub UNICODE function for GetSaveFileName when this code is built ANSI.
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL WINAPI GetSaveFileNameW(
- LPOPENFILENAMEW pOFNW)
- {
- SetLastErrorEx(SLE_WARNING, 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;
- return ( GetFileName(&OFI, (WNDPROC)FileSaveDlgProc) );
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetFileName
- //
- // This is the meat of both GetOpenFileName and GetSaveFileName.
- //
- // Returns: TRUE if user specified name
- // FALSE if not
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL GetFileName(
- POPENFILEINFO pOFI,
- WNDPROC qfnDlgProc)
- {
- LPOPENFILENAME pOFN = pOFI->pOFN;
- INT iRet;
- LPTSTR lpDlg;
- HANDLE hRes, hDlgTemplate;
- WORD wErrorMode;
- HDC hdcScreen;
- HBITMAP hbmpTemp;
- static fFirstTime = TRUE;
- LPTSTR lpCurDir, lpCurThread;
- #ifdef UNICODE
- UINT uiWOWFlag = 0;
- #endif
- if (!pOFN)
- {
- StoreExtendedError(CDERR_INITIALIZATION);
- return (FALSE);
- }
- if (pOFN->lStructSize != sizeof(OPENFILENAME))
- {
- StoreExtendedError(CDERR_STRUCTSIZE);
- 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)))) &&
- #ifdef WINNT
- (!(pOFN->Flags & CD_WOWAPP)) )
- #else
- (!(GetProcessDword(GetCurrentProcessId(), GPD_FLAGS) &
- GPF_WIN16_PROCESS)) )
- #endif
- {
- #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 == (WNDPROC)FileOpenDlgProc)
- {
- return ( NewGetOpenFileName(pOFI) );
- }
- else
- {
- return ( NewGetSaveFileName(pOFI) );
- }
- }
- 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;
- }
- }
- else if (pOFN->Flags & OFN_ENABLETEMPLATEHANDLE)
- {
- hDlgTemplate = pOFN->hInstance;
- }
- else
- {
- if (pOFN->Flags & OFN_ALLOWMULTISELECT)
- {
- lpDlg = MAKEINTRESOURCE(MULTIFILEOPENORD);
- }
- else
- {
- lpDlg = MAKEINTRESOURCE(FILEOPENORD);
- }
- if (!(hRes = FindResource(g_hinst, lpDlg, RT_DIALOG)))
- {
- StoreExtendedError(CDERR_FINDRESFAILURE);
- goto TERMINATE;
- }
- if (!(hDlgTemplate = LoadResource(g_hinst, hRes)))
- {
- StoreExtendedError(CDERR_LOADRESFAILURE);
- goto TERMINATE;
- }
- }
- //
- // No kernel network error dialogs.
- //
- wErrorMode = (WORD)SetErrorMode(SEM_NOERROR);
- SetErrorMode(SEM_NOERROR | wErrorMode);
- if (LockResource(hDlgTemplate))
- {
- if (pOFN->Flags & OFN_ENABLEHOOK)
- {
- glpfnFileHook = pOFN->lpfnHook;
- }
- #ifdef UNICODE
- if (pOFN->Flags & CD_WOWAPP)
- {
- uiWOWFlag = SCDLG_16BIT;
- }
- iRet = DialogBoxIndirectParamAorW( g_hinst,
- (LPDLGTEMPLATE)hDlgTemplate,
- pOFN->hwndOwner,
- (DLGPROC)qfnDlgProc,
- (DWORD)pOFI,
- uiWOWFlag );
- #else
- iRet = DialogBoxIndirectParam( g_hinst,
- (LPDLGTEMPLATE)hDlgTemplate,
- pOFN->hwndOwner,
- (DLGPROC)qfnDlgProc,
- (DWORD)pOFI );
- #endif
- if ((iRet == 0) && (!bUserPressedCancel) && (!GetStoredExtendedError()))
- {
- StoreExtendedError(CDERR_DIALOGFAILURE);
- }
- else
- {
- FileOpenAbort();
- }
- glpfnFileHook = 0;
- }
- else
- {
- StoreExtendedError(CDERR_LOCKRESFAILURE);
- goto TERMINATE;
- }
- SetErrorMode(wErrorMode);
- if (lpCurDir = (LPTSTR)TlsGetValue(g_tlsiCurDir))
- {
- LocalFree(lpCurDir);
- }
- if (lpCurThread = (LPTSTR)TlsGetValue(g_tlsiCurThread))
- {
- LocalFree(lpCurThread);
- }
- TERMINATE:
- CleanUpFile();
- HourGlass(FALSE);
- return ((DWORD)iRet == IDOK);
- ReleaseMemDC:
- DeleteDC(hdcMemory);
- ReleaseScreenDC:
- ReleaseDC(HNULL, hdcScreen);
- CantInit:
- return (FALSE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // 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 FileOpenDlgProc(
- HWND hDlg,
- UINT wMsg,
- WPARAM wParam,
- LPARAM lParam)
- {
- POPENFILEINFO pOFI;
- BOOL bRet, bHookRet;
- if (pOFI = (POPENFILEINFO)GetProp(hDlg, FILEPROP))
- {
- if (pOFI->pOFN->lpfnHook)
- {
- bHookRet = (*pOFI->pOFN->lpfnHook)(hDlg, wMsg, wParam, lParam);
- if (bHookRet)
- {
- if (wMsg == WM_COMMAND)
- {
- 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 (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;
- }
- 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 FileSaveDlgProc(
- HWND hDlg,
- UINT wMsg,
- WPARAM wParam,
- LPARAM lParam)
- {
- POPENFILEINFO pOFI;
- BOOL bRet, bHookRet;
- TCHAR szTitle[cbCaption];
- if (pOFI = (POPENFILEINFO) GetProp(hDlg, FILEPROP))
- {
- if (pOFI->pOFN->lpfnHook)
- {
- bHookRet = (*pOFI->pOFN->lpfnHook)(hDlg, wMsg, wParam, lParam);
- if (bHookRet)
- {
- if (wMsg == WM_COMMAND)
- {
- 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 (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)))
- {
- LoadString(g_hinst, iszFileSaveTitle, (LPTSTR)szTitle, cbCaption);
- SetWindowText(hDlg, (LPTSTR)szTitle);
- LoadString(g_hinst, iszSaveFileAsType, (LPTSTR)szTitle, cbCaption);
- SetDlgItemText(hDlg, stc2, (LPTSTR)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;
- }
- default :
- {
- return (FALSE);
- }
- }
- return (TRUE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // InitFileDlg
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL InitFileDlg(
- HWND hDlg,
- WPARAM wParam,
- POPENFILEINFO pOFI)
- {
- DWORD lRet;
- LPOPENFILENAME pOFN = pOFI->pOFN;
- INT nFileOffset, nExtOffset;
- RECT rRect;
- RECT rLbox;
- BOOL bRet;
- if (!InitTlsValues())
- {
- //
- // The extended error is set inside of the above call.
- //
- EndDialog(hDlg, FALSE);
- return (FALSE);
- }
- lpLBProc = (WNDPROC)GetWindowLong(GetDlgItem(hDlg, lst2), GWL_WNDPROC);
- lpOKProc = (WNDPROC)GetWindowLong(GetDlgItem(hDlg, IDOK), GWL_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, pOFN->Flags & CD_WOWAPP);
- 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, psh15), 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, (LPARAM) 0L);
- //
- // Insert file specs into cmb1.
- // Custom filter first.
- // Must also check if filter contains anything.
- //
- if ( pOFN->lpstrFile &&
- (mystrchr(pOFN->lpstrFile, CHAR_STAR) ||
- mystrchr(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)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))
- {
- SendDlgItemMessage( hDlg,
- cmb1,
- CB_SETCURSEL,
- (WPARAM)(pOFN->nFilterIndex),
- 0L );
- SendMessage( hDlg,
- WM_COMMAND,
- GET_WM_COMMAND_MPS( cmb1,
- GetDlgItem(hDlg, cmb1),
- MYCBN_DRAW ) );
- if (!(pOFN->lpstrFile && *pOFN->lpstrFile))
- {
- LPCTSTR lpFilter;
- 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];
- lstrcpy(szText, lpFilter);
- //
- // Filtering is case-insensitive.
- //
- CharLower(szText);
- if (pOFI->szLastFilter[0] == CHAR_NULL)
- {
- lstrcpy(pOFI->szLastFilter, (LPTSTR)szText);
- }
- SetDlgItemText(hDlg, edt1, (LPTSTR)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),
- pOFN->Flags & CD_WOWAPP );
- 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, (LPTSTR)szText);
- }
- SetWindowLong(GetDlgItem(hDlg, lst2), GWL_WNDPROC, (LONG)dwLBSubclass);
- SetWindowLong(GetDlgItem(hDlg, IDOK), GWL_WNDPROC, (LONG)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;
- ScreenToClient(hDlg, (LPPOINT)&(rRect.left));
- ScreenToClient(hDlg, (LPPOINT)&(rRect.right));
- SetWindowPos( GetDlgItem(hDlg, edt1),
- 0,
- rRect.left,
- rRect.top,
- rRect.right - rRect.left,
- rRect.bottom - rRect.top,
- SWP_NOZORDER );
- }
- if (pOFN->lpfnHook)
- {
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- ThunkOpenFileNameW2A(pOFI);
- bRet = ((*pOFN->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 = ((*pOFN->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()
- {
- //
- // As long as we do not call TlsGetValue before this,
- // everything should be ok.
- //
- LPTSTR lpCurDir;
- LPDWORD lpCurThread;
- if (dwNumDlgs == MAX_THREADS)
- {
- StoreExtendedError(CDERR_INITIALIZATION);
- return (FALSE);
- }
- if (lpCurDir = (LPTSTR)LocalAlloc(LPTR, CCHNETPATH * sizeof(TCHAR)))
- {
- GetCurrentDirectory(CCHNETPATH, lpCurDir);
- if (!TlsSetValue(g_tlsiCurDir, (LPVOID)lpCurDir))
- {
- StoreExtendedError(CDERR_INITIALIZATION);
- LocalFree(lpCurDir);
- return (FALSE);
- }
- }
- else
- {
- StoreExtendedError(CDERR_MEMALLOCFAILURE);
- return (FALSE);
- }
- if (lpCurThread = (LPDWORD)LocalAlloc(LPTR, sizeof(DWORD)))
- {
- if (!TlsSetValue(g_tlsiCurThread, (LPVOID)lpCurThread))
- {
- StoreExtendedError(CDERR_INITIALIZATION);
- LocalFree(lpCurDir);
- LocalFree(lpCurThread);
- return (FALSE);
- }
- }
- else
- {
- StoreExtendedError(CDERR_MEMALLOCFAILURE);
- return (FALSE);
- }
- EnterCriticalSection(&g_csLocal);
- *lpCurThread = dwNumDlgs++;
- LeaveCriticalSection(&g_csLocal);
- return (TRUE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // 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 = SendDlgItemMessage( hDlg,
- cmb1,
- CB_ADDSTRING,
- 0,
- (LONG)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);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // InitCurrentDisk
- //
- ////////////////////////////////////////////////////////////////////////////
- VOID InitCurrentDisk(
- HWND hDlg,
- POPENFILEINFO pOFI,
- WORD cmb)
- {
- //
- // 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_tlsiCurDir) will return "" which
- // when fed to SheChangeDirEx means GetCurrentDir will be called.
- // So, the default cd behavior at startup is:
- // 1. lpstrInitialDir
- // 2. GetCurrentDir
- //
- ChangeDir(hDlg, pOFI->pOFN->lpstrInitialDir, TRUE, FALSE);
- }
- else
- {
- ChangeDir(hDlg, NULL, 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());
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // 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 FileOpenCmd(
- HANDLE hDlg,
- WPARAM wP,
- DWORD lParam,
- POPENFILEINFO pOFI,
- BOOL bSave)
- {
- LPOPENFILENAME pOFN;
- LPTSTR pch, pch2;
- WORD i, sCount, len;
- LRESULT wFlag;
- BOOL bRet, bHookRet;
- TCHAR szText[MAX_FULLPATHNAME];
- HWND hwnd;
- if (!pOFI)
- {
- return (FALSE);
- }
- pOFN = pOFI->pOFN;
- switch (GET_WM_COMMAND_ID(wP, 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 lpDefExts string.
- // Since we only have to use it in OKButtonPressed, update
- // lpstrDefExts 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(wP, lParam)) == IDOK) && pOFN->lpfnHook)
- {
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- ThunkOpenFileNameW2A(pOFI);
- bHookRet = (*pOFN->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 = (*pOFN->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)
- {
- glpfnFileHook = pOFN->lpfnHook;
- }
- RemoveProp(hDlg, FILEPROP);
- EndDialog(hDlg, bRet);
- if (pOFI)
- {
- if (((pOFN->Flags & OFN_NOCHANGEDIR) && *pOFI->szCurDir) ||
- (bUserPressedCancel))
- {
- ChangeDir(hDlg, pOFI->szCurDir, TRUE, FALSE);
- }
- }
- //
- // BUG BUG
- // 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(wP, 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(wP, lParam),
- WM_GETTEXT,
- (WPARAM)MAX_FULLPATHNAME,
- (LPARAM)(LPTSTR)szText );
- if ((iIndex = (INT)SendMessage( hLBox,
- LB_FINDSTRING,
- (WPARAM)(wIndex - 1),
- (LPARAM)(LPTSTR)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(wP, lParam)== LBN_DBLCLK)
- {
- SendMessage(hDlg, WM_COMMAND, GET_WM_COMMAND_MPS(IDOK, 0, 0));
- return (TRUE);
- }
- else if (pOFN && (GET_WM_COMMAND_CMD(wP, lParam) == LBN_SELCHANGE))
- {
- if (pOFN->Flags & OFN_ALLOWMULTISELECT)
- {
- int *pSelIndex;
- //
- // Muliselection allowed.
- //
- sCount = (SHORT)SendMessage(GET_WM_COMMAND_HWND(wP, lParam),
- LB_GETSELCOUNT,
- 0,
- 0L );
- if (!sCount)
- {
- //
- // If nothing selected, clear edit control.
- //
- SetDlgItemText(hDlg, edt1, (LPTSTR)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(wP, lParam),
- LB_GETSELITEMS,
- (WPARAM)sCount,
- (LONG)(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(wP, 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)
- {
- UINT cchPrevLen = cchTotalLength - (len + 2);
- cchMemBlockSize = cchMemBlockSize << 1;
- pch = (LPTSTR)LocalReAlloc(
- pch,
- cchMemBlockSize * sizeof(TCHAR),
- LMEM_MOVEABLE );
- if (pch)
- {
- pch2 = pch + cchPrevLen;
- }
- else
- {
- goto LocalFailure2;
- }
- }
- SendMessage( GET_WM_COMMAND_HWND(wP, lParam),
- LB_GETTEXT,
- (WPARAM)(*(pSelIndex + i)),
- (LONG)(LPTSTR)pch2 );
- if (!mystrchr((LPTSTR)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(wP, lParam),
- LB_GETCARETINDEX,
- 0,
- 0L );
- if (!(i & 0x8000))
- {
- wFlag = (SendMessage(
- GET_WM_COMMAND_HWND(wP, 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(wP, lParam),
- LB_GETCURSEL,
- 0,
- 0L );
- if (i != (WORD)LB_ERR)
- {
- i = (WORD)SendMessage( GET_WM_COMMAND_HWND(wP, lParam),
- LB_GETTEXT,
- (WPARAM)i,
- (LONG)(LPTSTR)szText );
- if (!mystrchr((LPTSTR)szText, CHAR_DOT))
- {
- if (i < MAX_FULLPATHNAME - 1)
- {
- szText[i] = CHAR_DOT;
- szText[i + 1] = CHAR_NULL;
- }
- }
- if (!bCasePreserved)
- {
- CharLower(szText);
- }
- SetDlgItemText(hDlg, edt1, (LPTSTR)szText);
- if (pOFN->lpfnHook)
- {
- i = (WORD)SendMessage(
- GET_WM_COMMAND_HWND(wP, lParam),
- LB_GETCURSEL,
- 0,
- 0L );
- wFlag = CD_LBSELCHANGE;
- }
- }
- }
- if (pOFN->lpfnHook)
- {
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- (*pOFN->lpfnHook)( hDlg,
- msgLBCHANGEA,
- lst1,
- MAKELONG(i, wFlag) );
- }
- else
- #endif
- {
- (*pOFN->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(wP, 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,
- (LPTSTR)szText,
- MAX_FULLPATHNAME - 1 );
- bRet = (!szText[0] ||
- (mystrchr((LPTSTR)szText, CHAR_STAR)) ||
- (mystrchr((LPTSTR)szText, CHAR_QMARK)));
- lstrcpy(szText, lpFilter);
- if (bRet)
- {
- CharLower(szText);
- SetDlgItemText(hDlg, edt1, (LPTSTR)szText);
- SendDlgItemMessage( hDlg,
- edt1,
- EM_SETSEL,
- (WPARAM)0,
- (LPARAM)-1 );
- }
- FListAll(pOFI, hDlg, (LPTSTR)szText);
- if (!bInitializing)
- {
- lstrcpy(pOFI->szLastFilter, (LPTSTR)szText);
- //
- // Provide dynamic lpstrDefExt updating
- // when lpstrDefExt is user initialized.
- //
- if (mystrchr((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 (!(mystrchr((LPTSTR)lpFilter, CHAR_STAR)) &&
- !(mystrchr((LPTSTR)lpFilter, CHAR_QMARK)))
- {
- while (cbLen--)
- {
- *lpTemp++ = *lpFilter++;
- }
- *lpTemp = CHAR_NULL;
- }
- }
- }
- }
- if (pOFN->lpfnHook)
- {
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- (*pOFN->lpfnHook)( hDlg,
- msgLBCHANGEA,
- cmb1,
- MAKELONG(nIndex, CD_LBSELCHANGE) );
- }
- else
- #endif
- {
- (*pOFN->lpfnHook)( hDlg,
- msgLBCHANGEW,
- cmb1,
- MAKELONG(nIndex, CD_LBSELCHANGE) );
- }
- }
- HourGlass(FALSE);
- return (TRUE);
- break;
- }
- default :
- {
- break;
- }
- }
- break;
- }
- case ( lst2 ) :
- {
- if (GET_WM_COMMAND_CMD(wP, lParam) == LBN_SELCHANGE)
- {
- if (!(pOFN->Flags & OFN_DIRSELCHANGED))
- {
- if ((DWORD)SendDlgItemMessage( hDlg,
- lst2,
- LB_GETCURSEL,
- 0,
- 0L ) != pOFI->idirSub - 1)
- {
- StripFileName(hDlg, pOFN->Flags & CD_WOWAPP);
- pOFN->Flags |= OFN_DIRSELCHANGED;
- }
- }
- return (TRUE);
- }
- else if (GET_WM_COMMAND_CMD(wP, 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(wP, lParam) == LBN_KILLFOCUS)
- {
- if (pOFN && (pOFN->Flags & OFN_DIRSELCHANGED))
- {
- pOFN->Flags &= ~OFN_DIRSELCHANGED;
- }
- else
- {
- bChangeDir = FALSE;
- }
- }
- else if (GET_WM_COMMAND_CMD(wP, 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 = SendDlgItemMessage( hDlg,
- lst2,
- LB_GETTEXT,
- (WPARAM)idirNew,
- (LONG)(LPTSTR)pOFI->szPath );
- //
- // sanity check
- //
- if (!(lpCurDir = (LPTSTR)TlsGetValue(g_tlsiCurDir)))
- {
- break;
- }
- lstrcpy((LPTSTR)szNextDir, lpCurDir);
- //
- // Fix phenom with c:\foobar - cz of incnstncy in dir
- // dsply guaranteed to have a valid lpCurDir here, right?
- //
- if (szNextDir[lstrlen(lpCurDir) - 1] != CHAR_BSLASH)
- {
- lstrcat((LPTSTR)szNextDir, TEXT("\"));
- }
- lstrcat((LPTSTR)szNextDir, pOFI->szPath);
- pstrPath = (LPTSTR)szNextDir;
- idirNew = pOFI->idirSub; // for msgLBCHANGE message
- }
- else
- {
- //
- // Need full path name.
- //
- cb = SendDlgItemMessage( hDlg,
- lst2,
- LB_GETTEXT,
- 0,
- (LONG)(LPTSTR)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((LPTSTR)pOFI->szPath))
- {
- lstrcat((LPTSTR)pOFI->szPath, TEXT("\"));
- cb++;
- }
- for (idir = 1; idir <= idirNew; ++idir)
- {
- cb += SendDlgItemMessage(
- hDlg,
- lst2,
- LB_GETTEXT,
- (WPARAM)idir,
- (LONG)(LPTSTR)&pOFI->szPath[cb] );
- pOFI->szPath[cb++] = CHAR_BSLASH;
- }
- //
- // The root is a special case.
- //
- if (idirNew)
- {
- pOFI->szPath[cb - 1] = CHAR_NULL;
- }
- pstrPath = pOFI->szPath;
- }
- if (!*pstrPath ||
- (ChangeDir(hDlg, pstrPath, FALSE, TRUE) == CHANGEDIR_FAILED))
- {
- break;
- }
- //
- // List all directories under this one.
- //
- UpdateListBoxes(hDlg, pOFI, (LPTSTR) NULL, mskDirectory);
- if (pOFN->lpfnHook)
- {
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- (*pOFN->lpfnHook)( hDlg,
- msgLBCHANGEA,
- lst2,
- MAKELONG(LOWORD(idirNew), CD_LBSELCHANGE) );
- }
- else
- #endif
- {
- (*pOFN->lpfnHook)( hDlg,
- msgLBCHANGEW,
- lst2,
- MAKELONG(LOWORD(idirNew), CD_LBSELCHANGE) );
- }
- }
- return (TRUE);
- }
- break;
- }
- case ( cmb2 ) :
- {
- switch (GET_WM_COMMAND_CMD(wP, lParam))
- {
- case ( CBN_DROPDOWN ) :
- {
- pOFN->Flags |= OFN_DRIVEDOWN;
- return (TRUE);
- break;
- }
- case ( CBN_CLOSEUP ) :
- {
- //
- // It would seem reasonable to merely do the update
- // at this point, but that would rely on message
- // ordering, which isnt a smart move. In fact, if
- // you hit ALT-DOWNARROW, DOWNARROW, ALT-DOWNARROW,
- // you receive CBN_DROPDOWN, CBN_SELCHANGE, and then
- // CBN_CLOSEUP. But if you use the mouse to choose
- // the same element, the last two messages trade
- // places. PostMessage allows all messages in the
- // sequence to be processed, and then updates are
- // done as needed.
- //
- PostMessage( hDlg,
- WM_COMMAND,
- GET_WM_COMMAND_MPS(
- cmb2,
- GET_WM_COMMAND_HWND(wP, lParam),
- MYCBN_DRAW ) );
- return (TRUE);
- break;
- }
- case ( MYCBN_LIST ) :
- {
- LoadDrives(hDlg);
- break;
- }
- case ( MYCBN_REPAINT ) :
- {
- TCHAR szRepaintDir[CCHNETPATH];
- LPTSTR lpCurDir;
- DWORD cchCurDir;
- HWND hCmb2 = (HWND)lParam;
- // sanity
- if (!(lpCurDir = (LPTSTR)TlsGetValue(g_tlsiCurDir)))
- {
- break;
- }
- lstrcpy(szRepaintDir, lpCurDir);
- // BUG BUG: Only Unicode
- cchCurDir = SheGetPathOffsetW((LPWSTR)szRepaintDir);
- szRepaintDir[cchCurDir] = CHAR_NULL;
- // Should always succeed
- SendMessage( hCmb2,