unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, TntDialogs, TntComCtrls, TntStdCtrls, CommDlg,
  uOpenDialog, WideStrings;

type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog1: TTntOpenDialog;
    Memo1: TTntMemo;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    FileOpenDialog1: TFileOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure OpenDialog1SelectionChange(Sender: TObject);
    procedure OpenDialog1Show(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    FSelItems: array of WideString;
    FDlgWnd: HWND;
    FOldOkBtnWndProc: TFNWndProc;

    procedure ShowSelDirs;
    procedure OKBtnWindowProc(var Message: TMessage);
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  CommCtrl, ActiveX, shlobj, Dlgs,
  TntSysUtils;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //if OpenDialog1.InitialDir = '' then
//    OpenDialog1.InitialDir := ExtractFilePath(ParamStr(0));

  if Win32MajorVersion >= 6 then
    with TFileOpenDialog.Create(nil) do
      try
        Title := 'Select Directory';
        Options := [{fdoPickFolders, }{fdoPathMustExist, }fdoForceFileSystem]; // YMMV
        OkButtonLabel := 'Select';
        DefaultFolder := '';//FDir;
        FileName := '';//FDir;
        if Execute then
          ShowMessage(FileName);
      finally
        Free;
      end
  else
  if OpenDialog1.Execute then
  begin
    memo1.Lines.Text := OpenDialog1.Files.Text
  end;
end;

procedure TForm1.OpenDialog1SelectionChange(Sender: TObject);

  function ListView_GetItemTextW(hwndLV: HWND; i, iSubItem: Integer; pszText: PWideChar; cchTextMax: Integer): Integer;
  var
    Item: TLVItemW;
  begin
    Item.iSubItem := iSubItem;
    Item.cchTextMax := cchTextMax;
    Item.pszText := pszText;
    Result := SendMessage(hwndLV, LVM_GETITEMTEXTW, i, Longint(@Item));
  end;

  procedure GetSelectedList(const AListHandle: HWND);
  var
    SelCount, i, ItemIndex: Integer;
    Path: array[0..MAX_PATH] of WideChar;
    BaseDir: WideString;
  begin
    BaseDir := WideExtractFilePath(OpenDialog1.FileName);
    SelCount := ListView_GetSelectedCount(AListHandle);
    ItemIndex := -1;
    SetLength(FSelItems, SelCount);
    for i := 0 to SelCount - 1 do
    begin
      ItemIndex := ListView_GetNextItem(AListHandle, ItemIndex, LVNI_SELECTED);
      if ItemIndex <> -1 then
      begin
        Path[0] := #0;
        if ListView_GetItemTextW(AListHandle, ItemIndex, 0, @Path[0], SizeOf(Path) div 2) > 0 then
        begin
          FSelItems[i] := BaseDir + Path;
//          Memo1.Lines.Add(Path);
        end;
      end;
    end;
  end;

  procedure AnalyzeWindow(const AWnd: HWND);
  var
    Buf: array[0..255] of Char;
    ClassName: string;
    hFirst, hCurr: HWND;
  begin
    hFirst := GetWindow(AWnd, GW_CHILD);
    if hFirst = 0 then
      Exit;

    hCurr := hFirst;
    repeat
      GetClassname(hCurr, Buf, SizeOf(Buf));
      ClassName := Buf;
      if ClassName = 'SysListView32' then
      begin
        GetSelectedList(hCurr);
        Break;
      end
      else
        AnalyzeWindow(hCurr);

      hCurr := GetWindow(hCurr, GW_HWNDNEXT);
    until ((hCurr = 0) or (hCurr = hFirst));

  end;

begin
  AnalyzeWindow(GetParent(OpenDialog1.Handle));
end;

procedure TForm1.OpenDialog1Show(Sender: TObject);
begin
  FDlgWnd := GetParent(OpenDialog1.Handle);
  SendMessage(FDlgWnd, CDM_HIDECONTROL, cmb1, 0);
  SendMessage(FDlgWnd, CDM_HIDECONTROL, stc2, 0);

  SendMessage(FDlgWnd, CDM_HIDECONTROL, cmb13, 0);
  SendMessage(FDlgWnd, CDM_HIDECONTROL, stc3, 0);
  SendMessage(FDlgWnd, CDM_SETCONTROLTEXT, IDOK, LongInt(PWideChar(WideString('OK'))));

  FOldOkBtnWndProc := TFNWndProc(SetWindowLong(FDlgWnd, GWL_WNDPROC, LongInt(Classes.MakeObjectInstance(OKBtnWindowProc))));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  files: TWideStrings;
  i: Integer;
begin
  files := TWideStringList.Create;
  ShowOpenDialog('Select Folder', '', dtSingleFolder, '*', files);
  if files.Count > 0 then
  begin
    Memo1.Clear;
    for i := 0 to files.Count - 1 do
      Memo1.Lines.Add(files[i]);
  end;
  files.Free;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  files: TWideStrings;
  i: Integer;
begin
  files := TWideStringList.Create;
  ShowOpenDialog('Select File', '', dtSingleFile, '*.zip', files);
  if files.Count > 0 then
  begin
    Memo1.Clear;
    for i := 0 to files.Count - 1 do
      Memo1.Lines.Add(files[i]);
  end;
  files.Free;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  files: TWideStrings;
  i: Integer;
begin
  files := TWideStringList.Create;
  ShowOpenDialog('Select Files and Folders', '', dtAllFilesAndFolders, 'all|*.*', files);
  if files.Count > 0 then
  begin
    Memo1.Clear;
    for i := 0 to files.Count - 1 do
      Memo1.Lines.Add(files[i]);
  end;
  files.Free;
end;

procedure TForm1.OKBtnWindowProc(var Message: TMessage);
begin
  if Message.Msg = WM_COMMAND then
  begin
    if LoWord(Message.WParam) = IDOK then // Is this from OK btn
    begin
      SendMessage(GetParent(OpenDialog1.Handle), WM_CLOSE, 0, 0);
      ShowSelDirs;
      Message.Result := 0;
      Exit;
    end;
  end;

  Message.Result := CallWindowProc(FOldOkBtnWndProc, FDlgWnd, Message.Msg, Message.wParam, Message.lParam);
end;

procedure TForm1.ShowSelDirs;
var
  i: Integer;
begin
  Memo1.Lines.Clear;
  if FSelItems <> nil then
  begin
    for i := 0 to High(FSelItems) do
      Memo1.Lines.Add(ExtractFileName(FSelItems[i]));
  end;
end;

end.

