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;