Blame | Last modification | View Log | RSS feed
#ifndef _BRWSDLG_RUL_#define _BRWSDLG_RUL_#include "FileBrowseDlg.h"prototype Kernel32.RtlMoveMemory(BYREF STRING, POINTER, NUMBER);typedef STR260beginSTRING sz[260];end;/////////////////////////////////////////////////////////////////////////////////// FileBrowseDlg() uses the Windows GetFileNameA function to allow single file// selection. Callers specify filter, dialog title, and initial browse// directory. SEE END OF FILE FOR EXAMPLE ON HOW TO USE//// Inputs://// szFile: String variable into which FileBrowseDlg() will place the selected// file's fully qualified pathname. The variable passed in as szFile can// be dynamically sized. szFile is passed by reference.//// szFilter: Filter spec for dialog. In the form "<descr>|<ext>||". For example://// "Text files (*.txt)|*.txt|All files (*.*)|*.*||"//// The description ("Text files (*.txt)" above) must be separated from// the extension ("*.txt" above) by a pipe "|" character. The entire// string must end in a double || ("||").//// szDialogTitle: A string containig the title to display on the file// browse dialog.//// szInitialDir: A string specifying the directory the browse dialog// initially opens to.//// bMultiSel: Set to TRUE if you wish to enable multiple selection.//// listFiles: List that will be loaded with directory and filenames if// multiple selection is enabled (i.e. bMultiSel = TRUE).// List is passed by reference (by default, since list variables// are pointers).//// bDerefLinks: Set to TRUE if you want to dereference shell links (also// known as shortcuts). If TRUE, then choosing a shell link causes// it to be dereferenced by the shell.//// Returns://// Returns 0 when a file is successfully selected. Returns less than// zero when when the user cancels/closes the browse dialog or an// error occurs. If an error occurs, a message box displays the error// identifier.//// History://// 03-12-99 RBS Updated this header to correctly document bDerefLinks.// 06-01-01 RBS Merged in changes from latest on InstallShield's site./////////////////////////////////////////////////////////////////////////////////function FileBrowseDlg( szFile, szFilter, szDialogTitle, szInitialDir,bMultiSel, listFiles, bDerefLinks)OPENFILENAME ofn;STRING szMsg, szFileTitle[260];STRING szCustomFilter[260], szTemp[260];LONG nLen, nCount, nResult, n, nFlags, nErr;STR260 str;begin// Replace each '|' character in szFilter with '\0' since that is// what is required by the Win32 API.nLen = StrLength( szFilter );nLen = nLen - 1;nCount = 0;for nCount = 0 to nLenif ( szFilter[nCount] = '|' ) thenszFilter[nCount] = '\0';endif;endfor;UseDLL(WINSYSDIR ^ "comdlg32.dll");nFlags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY| OFN_NOCHANGEDIR | OFN_EXPLORER;if bMultiSel thennFlags = nFlags | OFN_ALLOWMULTISELECT;endif;if bDerefLinks = FALSE thennFlags = nFlags | OFN_NODEREFERENCELINKS;endif;nResult = GetWindowHandle(HWND_INSTALL);ofn.lStructSize = SizeOf(ofn);ofn.hwndOwner = nResult;// The string pointed to by ofn.lpstrFile is modified by// GetOpenFileName. The only way to have a string in// script to reflect the change is to point lpstrFile// to a structure that contains just a string member.str.sz = szFile;ofn.lpstrFile = &str;ofn.nMaxFile = SizeOf(str);// Notice how the address of an explicitly sized string// is used when assigning to a member who was declared// as a LONG string pointer (lpstr). For example, &szFilter.ofn.lpstrFilter = &szFilter;ofn.nFilterIndex = 1;ofn.lpstrFileTitle = &szFileTitle;ofn.nMaxFileTitle = 260;ofn.lpstrTitle = &szDialogTitle;ofn.Flags = nFlags;ofn.lpstrDefExt = &szTemp;ofn.lpstrInitialDir = &szInitialDir;ofn.hInstance = 0;ofn.lpstrCustomFilter = &szCustomFilter;ofn.nMaxCustFilter = 260;ofn.lpfnHook = 0;nResult = GetOpenFileNameA(&ofn);if nResult = 1 thenif bMultiSel then// A direct assignment in the form of szFile = str.sz// will result in all data beyond the first null to be// lost. This only happend when the string is assigned// with a structure member. This is the reason why a// very indirect method is being used the transfer the// contents of str.sz to szFile.Resize( szFile, SizeOf(str));RtlMoveMemory( szFile, &str, SizeOf(str));StrGetTokens( listFiles, szFile, "");elseszFile = str.sz;endif;else// We had an error in GetOpenFileNameA() so get the error string.nErr = CommDlgExtendedError();switch (nErr)case CDERR_DIALOGFAILURE: szMsg = CDERR_DIALOGFAILURE_MSG;case CDERR_FINDRESFAILURE: szMsg = CDERR_FINDRESFAILURE_MSG;case CDERR_INITIALIZATION: szMsg = CDERR_INITIALIZATION_MSG;case CDERR_LOADRESFAILURE: szMsg = CDERR_LOADRESFAILURE_MSG;case CDERR_LOADSTRFAILURE: szMsg = CDERR_LOADSTRFAILURE_MSG;case CDERR_LOCKRESFAILURE: szMsg = CDERR_LOCKRESFAILURE_MSG;case CDERR_MEMALLOCFAILURE: szMsg = CDERR_MEMALLOCFAILURE_MSG;case CDERR_MEMLOCKFAILURE: szMsg = CDERR_MEMLOCKFAILURE_MSG;case CDERR_NOHINSTANCE: szMsg = CDERR_NOHINSTANCE_MSG;case CDERR_NOHOOK: szMsg = CDERR_NOHOOK_MSG;case CDERR_NOTEMPLATE: szMsg = CDERR_NOTEMPLATE_MSG;case CDERR_REGISTERMSGFAIL: szMsg = CDERR_REGISTERMSGFAIL_MSG;case CDERR_STRUCTSIZE: szMsg = CDERR_STRUCTSIZE_MSG;case FNERR_BUFFERTOOSMALL: szMsg = FNERR_BUFFERTOOSMALL_MSG;case FNERR_INVALIDFILENAME: szMsg = FNERR_INVALIDFILENAME_MSG;case FNERR_SUBCLASSFAILURE: szMsg = FNERR_SUBCLASSFAILURE_MSG;endswitch;if nErr != 0 then// User did not close or cancel dialog box.MessageBox("FileBrowseDlg() error:\n\n" + szMsg, SEVERE);endif;return -1;endif;UnUseDLL(WINSYSDIR ^ "comdlg32.dll");return 0;end;///////////////////////////////////////////////////////////////////////////////// //Need declarations for FileBrowseDlg and friends.// #include "brwsdlg.h"//// STRING szFile, svFileList, svTemp, szFilter;// NUMBER nResult, nReturn;// BOOL bMultiSel, bDerefLinks;// LIST listFiles;//// // If I want to support multiple selection, set bMultiSel to TRUE// // and pass in a valid string list.// bMultiSel = TRUE;// bDerefLinks = FALSE;// listFiles = ListCreate(STRINGLIST);// szFilter = "Text files (*.txt)|*.txt|All files (*.*)|*.*||";//// // Open the file browse dialog.// nResult = FileBrowseDlg( szFile,// szFilter,// "Select the DCOM98.EXE File",// "c:\\",// bMultiSel,// listFiles,// bDerefLinks );// if nResult = 0 then// if bMultiSel then// // If I chose multiple selection, I must parse the info, which is stored// // in list. First item will be dir, all others are individual filenames.// nReturn = ListGetFirstString(listFiles, svTemp);// while nReturn != END_OF_LIST// svFileList = svFileList + svTemp + "\n";// nReturn = ListGetNextString(listFiles, svTemp);// endwhile;// MessageBox("Directory (first item) and selected files:\n\n" + svFileList, 0);// else// // No multiple selection, so a single file/path was set.// MessageBox("Selected file:\n\n" + szFile, 0);// endif;// endif;//// ListDestroy(listFiles);///////////////////////////////////////////////////////////////////////////////#endif