Podgląd plików w GetOpenFileName

0

Jak zrobić podgląd nietypowych plików podczas otwierania?
Coś jak w Paint Shop... powiedzmy, gdzie po wybraniu pliku jest rysowany obrazek niżej,
nie te kafelki, ikony, miniaturki, ale tak zwyczajnie i jeden plik podglądam.

0

Tu przykładowy komponent: http://www.torry.net/samples/samples/comp/cstdlgs.zip Zamiast kontrolek TComboBox, TEdit i TCheckBox można do okna dialogowego wstawić TPicture lub TPaintBox, co pozwoli wyświetlać miniaturowy podgląd treści pliku graficznego wybranego w oknie dialogu. Trzeba tylko przeprojektować szablon zawarty w pliku "res" (Template).

0

Oczywiście można rzeźbić i tak. Chociaż rozwiązanie, które podał poprzednik jest ciekawe. Ale żeby zrobić to na poziomie bardziej zbliżonym do WinAPI trzeba by trochę pokombinować z kodem. A czy nie możesz po prostu posłużyć się TOpenPictureDialog?

Bo pod Lazarusem też on jest. I w porównaniu do na przykład Delphi 7 - ma obsługe znacznie większej ilości formatów plików graficznych. A jeśli już koniecznie potrzebujesz coś pod czystym WinAPI, to ja używam w Delphi 7 takiego kodu:

unit opensavedlg;

interface

uses
  Windows;

function OpenSaveFileDialog(ParentHandle : THandle; const DefExt, Filter,
  InitialDir, Title : string; var FileName : string; IsOpenDialog : boolean) : boolean;

implementation

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';

function StrLCopy(Dest : PChar; const Source : PChar; MaxLen : Cardinal) : PChar; assembler;
asm
        PUSH    EDI
        PUSH    ESI
        PUSH    EBX
        MOV     ESI,EAX
        MOV     EDI,EDX
        MOV     EBX,ECX
        XOR     AL,AL
        TEST    ECX,ECX
        JZ      @@1
        REPNE   SCASB
        JNE     @@1
        INC     ECX
@@1:    SUB     EBX,ECX
        MOV     EDI,ESI
        MOV     ESI,EDX
        MOV     EDX,EDI
        MOV     ECX,EBX
        SHR     ECX,2
        REP     MOVSD
        MOV     ECX,EBX
        AND     ECX,3
        REP     MOVSB
        STOSB
        MOV     EAX,EDX
        POP     EBX
        POP     ESI
        POP     EDI
end;

function StrPCopy(Dest : PChar; const Source : string) : PChar;
begin
  Result := StrLCopy(Dest, PChar(Source), Length(Source));
end;

function StrPas(const Str : PChar) : string;
begin
  Result := Str;
end;

function OpenSaveFileDialog(ParentHandle : THandle; const DefExt, Filter,
  InitialDir, Title : string; var FileName : string; IsOpenDialog : boolean) : boolean;
const
  OFN_READONLY = $00000001;
  OFN_OVERWRITEPROMPT = $00000002;
  OFN_HIDEREADONLY = $00000004;
  OFN_NOCHANGEDIR = $00000008;
  OFN_SHOWHELP = $00000010;
  OFN_ENABLEHOOK = $00000020;
  OFN_ENABLETEMPLATE = $00000040;
  OFN_ENABLETEMPLATEHANDLE = $00000080;
  OFN_NOVALIDATE = $00000100;
  OFN_ALLOWMULTISELECT = $00000200;
  OFN_EXTENSIONDIFFERENT = $00000400;
  OFN_PATHMUSTEXIST = $00000800;
  OFN_FILEMUSTEXIST = $00001000;
  OFN_CREATEPROMPT = $00002000;
  OFN_SHAREAWARE = $00004000;
  OFN_NOREADONLYRETURN = $00008000;
  OFN_NOTESTFILECREATE = $00010000;
  OFN_NONETWORKBUTTON = $00020000;
  OFN_NOLONGNAMES = $00040000;
  OFN_EXPLORER = $00080000;
  OFN_NODEREFERENCELINKS = $00100000;
  OFN_LONGNAMES = $00200000;
  OFN_ENABLEINCLUDENOTIFY = $00400000;
  OFN_ENABLESIZING = $00800000;
  OFN_DONTADDTORECENT = $02000000;
  OFN_FORCESHOWHIDDEN = $10000000;

  function CharReplace(const Source : string; OldChar, NewChar : Char) : string;
  var
    I : integer;
  begin
    Result := Source;
    for I := 1 to Length(Result) do
    begin
      if Result[I] = OldChar then
      begin
        Result[I] := NewChar
      end;
    end;
  end;

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
    OFN.Flags := OFN_HIDEREADONLY + OFN_DONTADDTORECENT + OFN_PATHMUSTEXIST + OFN_FILEMUSTEXIST;
    if GetOpenFileName(OFN) then
    begin
      Result := True;
      FileName := StrPas(SzFile);
    end;
  end
  else
  begin
    OFN.Flags := OFN_HIDEREADONLY + OFN_DONTADDTORECENT + OFN_OVERWRITEPROMPT;
    if GetSaveFileName(OFN) then
    begin
      Result := True;
      FileName := StrPas(SzFile);
    end;
  end
end;

end.

Można to opakować w klasę, no i można ustawić w strukturze lpTemplateName przy dodatkowej Flags zawierającej też OFN_ENABLETEMPLATE. Więcej informacji na MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx i do tej pory nie musiałem eksperymentować z własnym Template w tych dialogach. Także spróbuj samodzielnie pokombinować. Ewentualnie łącząć kod od poprzednika i dostosowując mój pod WinAPI. Możesz też spróbować przeanalizować kod komponentu TOpenPictureDialog z LCL.

0
olesio napisał(a):

Oczywiście można rzeźbić i tak. Chociaż rozwiązanie, które podał poprzednik jest ciekawe. Ale żeby zrobić to na poziomie bardziej zbliżonym do WinAPI trzeba by trochę pokombinować z kodem. A czy nie możesz po prostu posłużyć się TOpenPictureDialog?

Nie da rady, bowiem chodzi mi o podgląd zupełnie innych plików,
specyficznych dla aplikacji, która produkuje... coś tam, typu DTP i w hurtowych ilościach,
dlatego taki podgląd byłby użyteczny.
...

Kod sprawdzę, dzięki.

Tak z marszu - nie widzę tam fagi nowego stylu EXPLORER:

OFN.Flags := OFN_HIDEREADONLY + OFN_DONTADDTORECENT + OFN_OVERWRITEPROMPT;

czy to przypadkiem nie otworzy mi okna w tym starym stylu tylko...
o czym mowa w dokumentacji:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms646839%28v=vs.85%29.aspx
i tam pod opisem lpfnHook jest OFNHookProcOldStyle, albo OFNHookProc z OFN_EXPLORER.

0

Sprawdź moje downloadery w WinAPI. Korzystają z tego modułu i na Windowsach od XP wzwyż na pewno wyświetlają ok dialogi. Żeby mieć dialogi w starym stylu to trzeba by kompilować pod Delphi 3 zdaje się. Przynajmniej tak zauważyłem. Wtedy mamy takie dialogi ubogie i brzydkie jak pod Windows 95/98. Chociaż akurat tej flagi Explorer nigdy nie używałem. Posprawdzaj sam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1