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.
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).
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.
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.
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.