lazarus/lcl/interfaces/win32/win32wsextdlgs.pp

216 lines
6.5 KiB
ObjectPascal

{ $Id$}
{
*****************************************************************************
* Win32WSExtDlgs.pp *
* ----------------- *
* *
* *
*****************************************************************************
*****************************************************************************
This file is part of the Lazarus Component Library (LCL)
See the file COPYING.modifiedLGPL.txt, included in this distribution,
for details about the license.
*****************************************************************************
}
unit Win32WSExtDlgs;
{$mode objfpc}{$H+}
{$I win32defines.inc}
interface
uses
////////////////////////////////////////////////////
// I M P O R T A N T
////////////////////////////////////////////////////
// To get as little as posible circles,
// uncomment only when needed for registration
////////////////////////////////////////////////////
Windows,
////////////////////////////////////////////////////
WSExtDlgs, WSLCLClasses, Win32WSDialogs, Win32WSControls, Win32Int, Win32Proc,
Types, Controls, Dialogs, ExtDlgs, LCLType, Graphics, Themes, Win32Extra, ShlObj;
type
{ TWin32WSPreviewFileControl }
TWin32WSPreviewFileControl = class(TWSPreviewFileControl)
published
class function CreateHandle(const AWinControl: TWinControl;
const AParams: TCreateParams): HWND; override;
end;
{ TWin32WSPreviewFileDialog }
TWin32WSPreviewFileDialog = class(TWSPreviewFileDialog)
published
end;
{ TWin32WSOpenPictureDialog }
TWin32WSOpenPictureDialog = class(TWin32WSOpenDialog)
published
class function CreateHandle(const ACommonDialog: TCommonDialog): THandle; override;
end;
{ TWin32WSSavePictureDialog }
TWin32WSSavePictureDialog = class(TWin32WSSaveDialog)
published
class function CreateHandle(const ACommonDialog: TCommonDialog): THandle; override;
end;
{ TWin32WSCalculatorDialog }
TWin32WSCalculatorDialog = class(TWSCalculatorDialog)
published
end;
{ TWin32WSCalculatorForm }
TWin32WSCalculatorForm = class(TWSCalculatorForm)
published
end;
{ TWin32WSCalendarDialogForm }
TWin32WSCalendarDialogForm = class(TWSCalendarDialogForm)
published
end;
{ TWin32WSCalendarDialog }
TWin32WSCalendarDialog = class(TWSCalendarDialog)
published
end;
implementation
{$R *.res}
function OpenPictureDialogCallBack(hWnd: Handle; uMsg: UINT; wParam: WPARAM;
lParam: LPARAM): UINT_PTR; stdcall;
var
OpenFileName: Windows.POPENFILENAME;
DialogRec: POpenFileDialogRec;
AControl: TPreviewFileControl;
stc32Handle: Handle;
ARect: TRect = (Left: 0; Top: 0; Right: 0; Bottom: 0);
ADialogRect: TRect = (Left: 0; Top: 0; Right: 0; Bottom: 0);
begin
Result := OpenFileDialogCallBack(hWnd, uMsg, wParam, lparam);
if uMsg = WM_INITDIALOG then
begin
OpenFileName := Windows.POPENFILENAME(lParam);
// Our dialog template contains a special control with ID stc32 which
// tells it how our template will be positioned. We need to place our
// control at the end of tempate
stc32Handle := GetDlgItem(hWnd, 1119);
if stc32Handle <> 0 then
begin
DialogRec := POpenFileDialogRec(OpenFileName^.lCustData);
AControl := TPreviewFileDialog(DialogRec^.Dialog).PreviewFileControl;
// attach our child to the template window
AControl.ParentWindow := hWnd;
GetWindowRect(stc32Handle, ARect);
ScreenToClient(hWnd, ARect.TopLeft);
ScreenToClient(hWnd, ARect.BottomRight);
GetClientRect(hWnd, ADialogRect);
with ARect do
begin
Left := Right;
Top := 30; // do not know how to get relative coord
Right := ADialogRect.Right - 4;
Bottom := ADialogRect.Bottom;
end;
AControl.BoundsRect := ARect;
AControl.Color := clBtnFace;
end;
end;
end;
procedure AddPreviewControl(const ACommonDialog: TCommonDialog; OFN: LPOPENFILENAME);
const
ResName: WideString = 'LAZ_PIC_DIALOG_TEMPLATE';
begin
if (TPreviewFileDialog(ACommonDialog).PreviewFileControl <> nil) and
not (ofOldStyleDialog in TPreviewFileDialog(ACommonDialog).Options) then
with OFN^ do
begin
lpTemplateName := AllocMem(Length(ResName) * 2 + 2);
Move(PChar(ResName)^, lpTemplateName^, Length(ResName) * 2);
Flags := Flags or OFN_ENABLETEMPLATE;
lpfnHook := LPOFNHOOKPROC(@OpenPictureDialogCallBack);
end;
end;
{ TWin32WSOpenPictureDialog }
class function TWin32WSOpenPictureDialog.CreateHandle(const ACommonDialog: TCommonDialog): THandle;
var
Dialog: IFileOpenDialog;
fos: FILEOPENDIALOGOPTIONS;
begin
Result := inherited CreateHandle(ACommonDialog);
if (Result = 0) or (Result = INVALID_HANDLE_VALUE) then
Exit;
if CanUseVistaDialogs(TOpenDialog(ACommonDialog)) and not IsXPStyleFallBack(TOpenDialog(ACommonDialog)) then
begin
Dialog := IFileOpenDialog(Result);
if Succeeded(Dialog.GetOptions(@fos)) then
begin
fos := fos or FOS_FORCEPREVIEWPANEON;
Dialog.SetOptions(fos);
end;
end
else
AddPreviewControl(ACommonDialog, LPOPENFILENAME(Result));
end;
{ TWin32WSPreviewFileControl }
class function TWin32WSPreviewFileControl.CreateHandle(
const AWinControl: TWinControl; const AParams: TCreateParams): HWND;
var
Params: TCreateWindowExParams;
begin
// general initialization of Params
PrepareCreateWindow(AWinControl, AParams, Params);
// customization of Params
with Params do
begin
pClassName := @ClsName[0];
SubClassWndProc := nil;
end;
// create window
FinishCreateWindow(AWinControl, Params, false);
Result := Params.Window;
end;
{ TWin32WSSavePictureDialog }
class function TWin32WSSavePictureDialog.CreateHandle(
const ACommonDialog: TCommonDialog): THandle;
var
Dialog: IFileSaveDialog;
fos: FILEOPENDIALOGOPTIONS;
begin
Result := inherited CreateHandle(ACommonDialog);
if (Result = 0) or (Result = INVALID_HANDLE_VALUE) then
Exit;
// According to https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/ne-shobjidl_core-_fileopendialogoptions
// FOS_FORCEPREVIEWPANEON has no effect on a save dialog.
// So don't bother in that case
if (not CanUseVistaDialogs(TOpenDialog(ACommonDialog))) or IsXPStyleFallBack(TOpenDialog(ACommonDialog)) then
AddPreviewControl(ACommonDialog, LPOPENFILENAME(Result));
end;
end.