2012-10-19 7 views
8

Utworzono program przykładowy Firemonkey (Delphi XE2), który zawiera TButton i TSavedialog z dwoma różnymi filtrami. (Komponent TSaveDialog obsługuje platformę Win32/Win64 i OS X).FireMonkey/Rad Studio XE2: Jak wyświetlić filtr SaveDialog na OS X?

Działa poprawnie na Win32/Win64, ale nie wiem, dlaczego nie wyświetla filtrów Savedialog na OS X (VirtualBox/OS X 10,7.x).

Jak mogę uruchomić go na OS X?

procedure TForm1.Button_SaveClick(Sender: TObject); 
begin 
    SaveDialog.Filter:='Format_1 (*.fmt1)|*.fmt1|Format_2 (*.fmt2)|*.fmt2'; 

    If Savedialog.Execute Then ShowMessage(SaveDialog.FileName+#13+'Selected filterindex: '+Inttostr(SaveDialog.FilterIndex)); 
end; 

Odpowiedz

3

Okno dialogowe zapisu nie jest zbudowane w Delphi, ale wywołuje macierzyste okno dialogowe MAC OSX (NSSavePanel). To nie ma filtra, który można wybrać przez użytkownika.

Po uruchomieniu okna dialogowego zapisywania, Delphi przekazuje filtr jako tablicę do NSSavePanel.SetAllowedFileTypes, który określa, jakich rozszerzeń dialog OSX pozwala użytkownikowi określić - ale nie ma listy do wybrania.

Aby zezwolić użytkownikowi na wybór z listy, należy utworzyć własne okno dialogowe wyboru rodzaju pliku, a następnie wybrać i zapisać zapisany zapis jako domyślny typ pliku i jedyny element filtru.

Alternatywa utworzenia zupełnie nowego okna dialogowego fileSave nie jest łatwa, ponieważ komponent drzewa Firemonkey wydaje się nalegać na rozwinięcie wszystkich jego węzłów, a zatem wykonuje kompletny trawers wszystkich plików na dysku twardym. W każdym przypadku użytkownicy MAC będą zaznajomieni ze standardowym dialogiem.

+0

David, dziękuję za bardzo przydatne informacje, ale nie byłem zbyt szczęśliwy, kiedy przeczytałem twoją odpowiedź. –

+0

Mam przeglądarkę/konwerter plików MS Windows 3D (geometria) (http://web.t-online.hu/karpo), która obsługuje 615 różnych formatów plików (292 dla zachowania!) I przenoszę ten program pod FireMonkey, aby pobrać pliki wykonywalne Win32/Win64 i OS X. Myślę, że użyję prostego ComboBox do wyboru formatu (i drugiego ComboBox do wyboru z ulubionych formatów) i SaveDialog do wyboru nazwy pliku. –

1

Miałem ten sam problem z TOpendialog w MAC OSX: filtr nie działa, ale w Windows oni robią. Teraz rozwiązałem problem, być może możesz użyć kodu do obejścia problemu. Te pliki, które NIE są wyświetlane w systemie Windows, są wyłączone w systemie MAC OSX, nie można ich wybrać.

uses 
    Macapi.Foundation, Macapi.ObjectiveC, Macapi.AppKit; 


{$IFDEF MACOS} 

    function AllocFilterStr(const S: string; var Filter: NSArray): Boolean; 
    var 
    input, pattern: string; 
    FileTypes: array of string; 
    outcome, aux: TArray<string>; 
    i, j: Integer; 
    FileTypesNS: array of Pointer; 
    NStr: NSString; 
    LocObj: ILocalObject; 
    begin 
    // First, split the string by using '|' as a separator 
    Result := false; 
    input := S; 
    pattern := '\|'; 

    outcome := TRegEx.Split(input, pattern); 
    pattern := '\*\.'; 
    SetLength(FileTypes, 0); 

    for i := 0 to length(outcome) - 1 do 
    begin 
     if Odd(i) then 
     if outcome[i] <> '*.*' then 
      if AnsiLeftStr(outcome[i], 2) = '*.' then 
      begin 
      aux := TRegEx.Split(outcome[i], pattern); 
      for j := 0 to length(aux) - 1 do 
      begin 
       aux[j] := Trim(aux[j]); 
       if aux[j] <> '' then 
       begin 
       if AnsiEndsStr(';', aux[j]) then 
        aux[j] := AnsiLeftStr(aux[j], length(aux[j]) - 1); 
       SetLength(FileTypes, length(FileTypes) + 1); 
       FileTypes[length(FileTypes) - 1] := aux[j]; 
       end; 
      end; 
      end; 
    end; 

    // create the NSArray from the FileTypes array 
    SetLength(FileTypesNS, length(FileTypes)); 
    for i := 0 to length(FileTypes) - 1 do 
    begin 
     NStr := NSSTR(FileTypes[i]); 
     if Supports(NStr, ILocalObject, LocObj) then 
     FileTypesNS[i] := LocObj.GetObjectID; 
    end; 
    if length(FileTypes) > 0 then begin 
     Filter := TNSArray.Wrap(TNSArray.OCClass.arrayWithObjects(@FileTypesNS[0], length(FileTypes))); 
     result := true; 
    end; 
    end; 

function CFToDelphiString(const CFStr: CFStringRef): string; 
var 
    Range: CFRange; 
begin 
    Range.location := 0; 
    Range.length := CFStringGetLength(CFStr); 
    SetLength(Result, Range.length); 
    if Range.length = 0 then Exit; 
    CFStringGetCharacters(CFStr, Range, PWideChar(Result)); 
end; 

function NSToDelphiString(const NSStr: NSString): string; inline; 
begin 
    Result := CFToDelphiString((NSStr as ILocalObject).GetObjectID); 
end; 


    {$ENDIF} 


procedure TMainform.LoadClick(Sender: TObject); 
{$IFDEF MACOS} 
var 
    Filter: NSArray; 
    LOpenDir: NSOpenPanel; 
    {$ENDIF} 
begin 

    {$IFDEF MSWINDOWS} 
    Opendialog1.Filter:= '*.fcb|*.fcb'; 
    if Opendialog1.execute then 
    begin 
    case Opendialog1.Filterindex of 
     1: LoadPlaylist(Opendialog1.filename, false, false); 
     2: LoadPlaylist(Opendialog1.filename, false, true); 
    end; 
    end; 
    {$ENDIF} 

{$IFDEF MACOS} 
    LOpenDir := TNSOpenPanel.Wrap(TNSOpenPanel.OCClass.openPanel); 
    if AllocFilterStr('*.fcb|*.fcb', Filter) then 
    if LOpenDir.runModalForTypes(Filter)=1 then 
    LoadPlaylist(NSToDelphiString(LOpenDir.filename), false, false); 
    {$ENDIF} 
end;