Windows - abrindo um opendialog e savedialog sem usar os components do delphi

Top  Previous  Next

Question/Problem/Abstract:

 

How to display standard OpenDialog or SaveDialog? 

Answer:

 

 

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;