Mega Code Archive

 
Categories / Delphi / VCL
 

Use an alternative for topendialog-tsavedialog

{ Today I want to display how you may use the simple functions as alternative for TOpenDialog/TSaveDialog components. Problem is that Borland incorrectly wrote those components and when Microsoft add some new extended features in own dialogs, standard TOpenDialog and TSaveDialog still use old style. For example, when Microsoft added placebar in own dialogs, VCL's dialog still use old style without placebars. Personally I prefer to use applications that support all features of installed OS. This is a reason why I wrote the function as wrapper for Windows API call for dialogs and now I use this function instead components. It allow not only to use all new features from Windows, but also reduce a size for exe-file and allow to use same function for both TOpenDialog and TSaveDialog functionality. For example: 1. to display the "OpenDialog" for text files s := 'aaa.txt'; if OpenSaveFileDialog(Application.Handle, 'txt', 'Text Files|*.txt', 'c:\', 'Select text file', s, True) then ShowMessage(s + ' file was selected for open') 2. to display the "Save dialog": s := 'data.dbf'; if OpenSaveFileDialog(Application.Handle, 'dbf', 'dBase tables|*.dbf|All files|*.*', 'c:\', 'Select table', s, False) then ShowMessage(s + ' table was selected for save') See full code below. Hope you'll find this code useful. } uses Windows; function OpenSaveFileDialog(ParentHandle: THandle; const DefExt, Filter, InitialDir, Title: string; var FileName: string; IsOpenDialog: Boolean): Boolean; implementation uses ShlObj, SysUtils; type POpenFilenameA = ^TOpenFilenameA; POpenFilename = POpenFilenameA; tagOFNA = packed record lStructSize: DWORD; hWndOwner: HWND; hInstance: HINST; lpstrFilter: PAnsiChar; lpstrCustomFilter: PAnsiChar; nMaxCustFilter: DWORD; nFilterIndex: DWORD; lpstrFile: PAnsiChar; nMaxFile: DWORD; lpstrFileTitle: PAnsiChar; nMaxFileTitle: DWORD; lpstrInitialDir: PAnsiChar; lpstrTitle: PAnsiChar; Flags: DWORD; nFileOffset: Word; nFileExtension: Word; lpstrDefExt: PAnsiChar; lCustData: LPARAM; lpfnHook: function(Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): UINT stdcall; lpTemplateName: PAnsiChar; end; TOpenFilenameA = tagOFNA; TOpenFilename = TOpenFilenameA; function GetOpenFileName(var OpenFile: TOpenFilename): Bool; stdcall; external 'comdlg32.dll' name 'GetOpenFileNameA'; function GetSaveFileName(var OpenFile: TOpenFilename): Bool; stdcall; external 'comdlg32.dll' name 'GetSaveFileNameA'; const OFN_DONTADDTORECENT = $02000000; OFN_FILEMUSTEXIST = $00001000; OFN_HIDEREADONLY = $00000004; OFN_PATHMUSTEXIST = $00000800; function CharReplace(const Source: string; oldChar, newChar: Char): string; var i: Integer; begin Result := Source; for i := 1 to Length(Result) do if Result[i] = oldChar then Result[i] := newChar end; function OpenSaveFileDialog(ParentHandle: THandle; const DefExt, Filter, InitialDir, Title: string; var FileName: string; IsOpenDialog: Boolean): Boolean; var ofn: TOpenFileName; szFile: array[0..MAX_PATH] of Char; begin Result := False; FillChar(ofn, SizeOf(TOpenFileName), 0); with ofn do begin lStructSize := SizeOf(TOpenFileName); hwndOwner := ParentHandle; lpstrFile := szFile; nMaxFile := SizeOf(szFile); if (Title <> '') then lpstrTitle := PChar(Title); if (InitialDir <> '') then lpstrInitialDir := PChar(InitialDir); StrPCopy(lpstrFile, FileName); lpstrFilter := PChar(CharReplace(Filter, '|', #0)+#0#0); if DefExt <> '' then lpstrDefExt := PChar(DefExt); end; if IsOpenDialog then begin if GetOpenFileName(ofn) then begin Result := True; FileName := StrPas(szFile); end; end else begin if GetSaveFileName(ofn) then begin Result := True; FileName := StrPas(szFile); end; end end;