2040 lines
52 KiB
ObjectPascal
2040 lines
52 KiB
ObjectPascal
|
{***************************************************}
|
||
|
{ }
|
||
|
{ FastReport VCL }
|
||
|
{ Tool controls }
|
||
|
{ }
|
||
|
{ Copyright (c) 1998-2021 }
|
||
|
{ by Fast Reports Inc. }
|
||
|
{ }
|
||
|
{ }
|
||
|
{ Flat ComboBox, FontComboBox v1.2 }
|
||
|
{ For Delphi 2,3,4,5. Freeware. }
|
||
|
{ }
|
||
|
{ Copyright (c) 1999 by: }
|
||
|
{ Dmitry Statilko (dima_misc@hotbox.ru) }
|
||
|
{ - Main idea and realisation of Flat ComboBox }
|
||
|
{ inherited from TCustomComboBox }
|
||
|
{ }
|
||
|
{ Vladislav Necheporenko (vlad_n@ua.fm) }
|
||
|
{ - Help in bug fixes }
|
||
|
{ - Adaptation to work on Delphi 2 }
|
||
|
{ - MRU list in FontComboBox that stored values }
|
||
|
{ in regitry }
|
||
|
{ - Font preview box in FontComboBox }
|
||
|
{ - New look style, like in Office XP }
|
||
|
{ }
|
||
|
{***************************************************}
|
||
|
|
||
|
unit frxCtrls;
|
||
|
|
||
|
interface
|
||
|
|
||
|
{$I frx.inc}
|
||
|
|
||
|
uses
|
||
|
{$IFNDEF NONWINFPC}Windows, CommCtrl, Registry, ActiveX,{$ENDIF}
|
||
|
{$IFDEF FPC}LCLType, LMessages, LCLIntf, LazHelper, LazarusPackageIntf,{$ENDIF}
|
||
|
Messages, Types, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
||
|
StdCtrls, ExtCtrls, Buttons, IniFiles, frxDPIAwareInt, frxDPIAwareBaseControls, frxClass
|
||
|
{$IFDEF Delphi6}
|
||
|
, Variants
|
||
|
{$ENDIF};
|
||
|
|
||
|
type
|
||
|
{$IFDEF DELPHI16}
|
||
|
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
|
||
|
{$ENDIF}
|
||
|
TfrxCustomFilterEdit = class(TfrxDPIAwareBasePanel)
|
||
|
private
|
||
|
FFrameIsActive: Boolean;
|
||
|
FClearBtnActive: Boolean;
|
||
|
FEdit: TEdit;
|
||
|
FBitmapActive: TBitmap;
|
||
|
FBitmapUnactive: TBitmap;
|
||
|
FOnFilterChanged: TNotifyEvent;
|
||
|
FFilterColor: TColor;
|
||
|
procedure DoFocus(Sender: TObject);
|
||
|
procedure DoLostFocus(Sender: TObject);
|
||
|
procedure DoTextChange(Sender: TObject);
|
||
|
procedure UpdateSize;
|
||
|
procedure SetFilterColor(const Value: TColor);
|
||
|
protected
|
||
|
{$IFNDEF Linux}
|
||
|
procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
|
||
|
{$ENDIF}
|
||
|
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
|
||
|
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
|
||
|
procedure WMSize(var Message: TWMSize); message WM_SIZE;
|
||
|
procedure PaintBorder;
|
||
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
|
||
|
X, Y: Integer); override;
|
||
|
public
|
||
|
procedure Paint; override;
|
||
|
constructor Create(AOwner: TComponent); override;
|
||
|
destructor Destroy; override;
|
||
|
property FilterColor: TColor read FFilterColor write SetFilterColor;
|
||
|
property BitmapActive: TBitmap read FBitmapActive;
|
||
|
property BitmapUnactive: TBitmap read FBitmapUnactive;
|
||
|
property EditControl: TEdit read FEdit;
|
||
|
property OnFilterChanged: TNotifyEvent read FOnFilterChanged write FOnFilterChanged;
|
||
|
end;
|
||
|
|
||
|
{$IFDEF DELPHI16}
|
||
|
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
|
||
|
{$ENDIF}
|
||
|
TfrxFilterEdit = class(TfrxCustomFilterEdit)
|
||
|
published
|
||
|
property Align;
|
||
|
property Alignment;
|
||
|
property Anchors;
|
||
|
property AutoSize;
|
||
|
property BitmapActive;
|
||
|
property BitmapUnactive;
|
||
|
property Constraints;
|
||
|
property UseDockManager default True;
|
||
|
property DockSite;
|
||
|
property DoubleBuffered;
|
||
|
property DragCursor;
|
||
|
property DragKind;
|
||
|
property DragMode;
|
||
|
property Enabled;
|
||
|
property EditControl;
|
||
|
property FullRepaint;
|
||
|
property ParentBiDiMode;
|
||
|
property ParentShowHint;
|
||
|
property PopupMenu;
|
||
|
property ShowHint;
|
||
|
property TabOrder;
|
||
|
property TabStop;
|
||
|
property Visible;
|
||
|
property OnClick;
|
||
|
property OnConstrainedResize;
|
||
|
property OnContextPopup;
|
||
|
property OnDockDrop;
|
||
|
property OnDockOver;
|
||
|
property OnDblClick;
|
||
|
property OnDragDrop;
|
||
|
property OnDragOver;
|
||
|
property OnEndDock;
|
||
|
property OnEndDrag;
|
||
|
property OnEnter;
|
||
|
property OnExit;
|
||
|
property OnGetSiteInfo;
|
||
|
property OnMouseDown;
|
||
|
property OnMouseMove;
|
||
|
property OnMouseUp;
|
||
|
property OnResize;
|
||
|
property OnStartDock;
|
||
|
property OnStartDrag;
|
||
|
property OnUnDock;
|
||
|
end;
|
||
|
|
||
|
{$IFDEF DELPHI16}
|
||
|
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
|
||
|
{$ENDIF}
|
||
|
TfrxCustomComboBox = class(TCustomComboBox)
|
||
|
private
|
||
|
FButtonWidth: Integer;
|
||
|
msMouseInControl: Boolean;
|
||
|
FListInstance: Pointer;
|
||
|
FDefListProc: Pointer;
|
||
|
FSolidBorder: Boolean;
|
||
|
FReadOnly: Boolean;
|
||
|
FEditOffset: Integer;
|
||
|
FListWidth: Integer;
|
||
|
FCurrentPPI: Integer;
|
||
|
{$IFDEF FPC}
|
||
|
procedure SelectAllWhenClicked(Sender: TObject);
|
||
|
protected
|
||
|
procedure DoPPIChanged(aNewPPI: Integer); virtual;
|
||
|
{$ELSE}
|
||
|
FChildHandle: HWND;
|
||
|
FListHandle: HWND;
|
||
|
FUpDropdown: Boolean;
|
||
|
procedure ListWndProc(var Message: TMessage);
|
||
|
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
|
||
|
procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
|
||
|
procedure WMDpiChanged(var Message: TMessage); message FRX_WM_DPICHANGED_AFTERPARENT;
|
||
|
procedure PaintButton(ButtonStyle: Integer);
|
||
|
procedure PaintBorder(DC: HDC; const SolidBorder: Boolean);
|
||
|
procedure PaintDisabled;
|
||
|
function GetSolidBorder: Boolean;
|
||
|
function GetListHeight: Integer;
|
||
|
protected
|
||
|
procedure ComboWndProc(var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer); override;
|
||
|
procedure WndProc(var Message: TMessage); override;
|
||
|
procedure CreateWnd; override;
|
||
|
procedure DrawImage(DC: HDC; Index: Integer; R: TRect); dynamic;
|
||
|
procedure DoPPIChanged(aNewPPI: Integer); virtual;
|
||
|
private
|
||
|
{$ENDIF}
|
||
|
procedure CMEnabledChanged(var Msg: TMessage); message CM_ENABLEDCHANGED;
|
||
|
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
|
||
|
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
|
||
|
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
|
||
|
procedure SetReadOnly(Value: Boolean);
|
||
|
procedure SetListWidth(const Value: Integer);
|
||
|
protected
|
||
|
{$IFDEF FPC}
|
||
|
OnlyMask: Boolean;
|
||
|
{$ENDIF}
|
||
|
procedure CreateParams(var Params: TCreateParams); override;
|
||
|
procedure KeyPress(var Key: Char); override;
|
||
|
function GetScale: Single;
|
||
|
property ListWidth: Integer read FListWidth write SetListWidth;
|
||
|
property ReadOnly: Boolean read FReadOnly write SetReadOnly default False;
|
||
|
property SolidBorder: Boolean read FSolidBorder;
|
||
|
public
|
||
|
constructor Create(AOwner: TComponent); override;
|
||
|
destructor Destroy; override;
|
||
|
{$IFNDEF FPC}
|
||
|
procedure Resize; override;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
{$IFDEF DELPHI16}
|
||
|
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
|
||
|
{$ENDIF}
|
||
|
TfrxComboBox = class(TfrxCustomComboBox)
|
||
|
published
|
||
|
property Color;
|
||
|
property DragMode;
|
||
|
property DragCursor;
|
||
|
property DropDownCount;
|
||
|
property Enabled;
|
||
|
property Font;
|
||
|
property ItemHeight;
|
||
|
property Items;
|
||
|
property ListWidth;
|
||
|
property MaxLength;
|
||
|
property ParentColor;
|
||
|
property ParentFont;
|
||
|
property ParentShowHint;
|
||
|
property PopupMenu;
|
||
|
property ShowHint;
|
||
|
property Sorted;
|
||
|
property TabOrder;
|
||
|
property TabStop;
|
||
|
property Text;
|
||
|
property ReadOnly;
|
||
|
property Visible;
|
||
|
property ItemIndex;
|
||
|
property OnChange;
|
||
|
property OnClick;
|
||
|
property OnDblClick;
|
||
|
property OnDragDrop;
|
||
|
property OnDragOver;
|
||
|
property OnDrawItem;
|
||
|
property OnDropDown;
|
||
|
property OnEndDrag;
|
||
|
property OnEnter;
|
||
|
property OnExit;
|
||
|
property OnKeyDown;
|
||
|
property OnKeyPress;
|
||
|
property OnKeyUp;
|
||
|
property OnStartDrag;
|
||
|
{$IFDEF Delphi4}
|
||
|
property Anchors;
|
||
|
property BiDiMode;
|
||
|
property Constraints;
|
||
|
property DragKind;
|
||
|
property ParentBiDiMode;
|
||
|
property OnEndDock;
|
||
|
property OnStartDock;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
{$IFDEF DELPHI16}
|
||
|
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
|
||
|
{$ENDIF}
|
||
|
TfrxFontPreview = class(TWinControl)
|
||
|
private
|
||
|
FPanel: TPanel;
|
||
|
protected
|
||
|
procedure CreateParams(var Params: TCreateParams); override;
|
||
|
public
|
||
|
constructor Create(AOwner: TComponent); override;
|
||
|
destructor Destroy; override;
|
||
|
procedure SetDefaultFontSize(aNewPPI: Integer);
|
||
|
end;
|
||
|
|
||
|
{$IFDEF DELPHI16}
|
||
|
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
|
||
|
{$ENDIF}
|
||
|
TfrxFontComboBox = class(TfrxCustomComboBox)
|
||
|
private
|
||
|
{$IFNDEF FPC}
|
||
|
frFontViewForm: TfrxFontPreview;
|
||
|
{$ENDIF}
|
||
|
FRegKey: String;
|
||
|
FTrueTypeBMP: TBitmap;
|
||
|
FDeviceBMP: TBitmap;
|
||
|
FOnClick: TNotifyEvent;
|
||
|
FUpdate: Boolean;
|
||
|
FShowMRU: Boolean;
|
||
|
Numused: Integer;
|
||
|
FIni: TCustomIniFile;
|
||
|
{$IFNDEF FPC}
|
||
|
procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
|
||
|
{$ENDIF}
|
||
|
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
|
||
|
procedure CMFontChange(var Message: TMessage); message CM_FONTCHANGE;
|
||
|
procedure SetRegKey(Value: String);
|
||
|
protected
|
||
|
procedure Loaded; override;
|
||
|
procedure Init;
|
||
|
procedure Reset;
|
||
|
procedure Click; override;
|
||
|
procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override;
|
||
|
procedure DrawImage(DC: HDC; Index: Integer; R: TRect); {$IFNDEF FPC} override; {$ENDIF}
|
||
|
procedure DoPPIChanged(aNewPPI: Integer); override;
|
||
|
public
|
||
|
constructor Create(AOwner: TComponent); override;
|
||
|
destructor Destroy; override;
|
||
|
procedure PopulateList; virtual;
|
||
|
property IniFile: TCustomIniFile read FIni write FIni;
|
||
|
published
|
||
|
property ShowMRU: Boolean read FShowMRU write FShowMRU default True;
|
||
|
property MRURegKey: String read FRegKey write SetRegKey;
|
||
|
property Text;
|
||
|
property Color;
|
||
|
property DragMode;
|
||
|
property DragCursor;
|
||
|
property DropDownCount;
|
||
|
property Enabled;
|
||
|
property Font;
|
||
|
{$IFDEF Delphi4}
|
||
|
property Anchors;
|
||
|
property BiDiMode;
|
||
|
property Constraints;
|
||
|
property DragKind;
|
||
|
property ParentBiDiMode;
|
||
|
{$ENDIF}
|
||
|
property ItemHeight;
|
||
|
property ParentColor;
|
||
|
property ParentFont;
|
||
|
property ParentShowHint;
|
||
|
property PopupMenu;
|
||
|
property ShowHint;
|
||
|
property TabOrder;
|
||
|
property TabStop;
|
||
|
property Visible;
|
||
|
property OnChange;
|
||
|
property OnClick: TNotifyEvent read FOnClick write FOnClick;
|
||
|
property OnDblClick;
|
||
|
property OnDragDrop;
|
||
|
property OnDragOver;
|
||
|
property OnDropDown;
|
||
|
property OnEndDrag;
|
||
|
property OnEnter;
|
||
|
property OnExit;
|
||
|
property OnKeyDown;
|
||
|
property OnKeyPress;
|
||
|
property OnKeyUp;
|
||
|
property OnStartDrag;
|
||
|
{$IFDEF Delphi4}
|
||
|
property OnEndDock;
|
||
|
property OnStartDock;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
{$IFDEF DELPHI16}
|
||
|
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
|
||
|
{$ENDIF}
|
||
|
TfrxComboEdit = class(TComboBox)
|
||
|
private
|
||
|
FPanel: TWinControl;
|
||
|
FButton: TSpeedButton;
|
||
|
FButtonEnabled: Boolean;
|
||
|
FOnButtonClick: TNotifyEvent;
|
||
|
{$IFDEF FPC}
|
||
|
{$IFNDEF NONWINFPC}
|
||
|
function GetEditHandle: HWND;
|
||
|
{$ENDIF}
|
||
|
{$ENDIF}
|
||
|
function GetGlyph: TBitmap;
|
||
|
procedure SetGlyph(Value: TBitmap);
|
||
|
function GetButtonHint: String;
|
||
|
procedure SetButtonHint(Value: String);
|
||
|
procedure SetButtonEnabled(Value: Boolean);
|
||
|
procedure ButtonClick(Sender: TObject);
|
||
|
procedure WMSize(var Message: TWMSize); message WM_SIZE;
|
||
|
procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
|
||
|
procedure SetPos;
|
||
|
public
|
||
|
constructor Create(AOwner: TComponent); override;
|
||
|
procedure CreateWnd; override;
|
||
|
procedure KeyPress(var Key: Char); override;
|
||
|
{$IFDEF FPC}
|
||
|
{$IFNDEF NONWINFPC}
|
||
|
property EditHandle: HWND read GetEditHandle;
|
||
|
{$ENDIF}
|
||
|
{$ENDIF}
|
||
|
published
|
||
|
property Glyph: TBitmap read GetGlyph write SetGlyph;
|
||
|
property ButtonEnabled: Boolean read FButtonEnabled write SetButtonEnabled default True;
|
||
|
property ButtonHint: String read GetButtonHint write SetButtonHint;
|
||
|
property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
|
||
|
end;
|
||
|
|
||
|
TfrxScrollMaxChangeEvent = procedure(Sender: TObject; Orientation: TfrxScrollerOrientation; Value: Integer) of Object;
|
||
|
TfrxScrollPosChangeEvent = procedure(Sender: TObject; Orientation: TfrxScrollerOrientation; var Value: Integer) of Object;
|
||
|
|
||
|
TfrxScrollWin = class(TCustomControl)
|
||
|
private
|
||
|
FBorderStyle: TBorderStyle;
|
||
|
FHorzPage: Integer;
|
||
|
FHorzPosition: Integer;
|
||
|
FHorzRange: Integer;
|
||
|
FLargeChange: Integer;
|
||
|
FSmallChange: Integer;
|
||
|
FVertPage: Integer;
|
||
|
FVertPosition: Integer;
|
||
|
FVertRange: Integer;
|
||
|
FHideScrolls: Boolean;
|
||
|
FOnScrollMaxChange: TfrxScrollMaxChangeEvent;
|
||
|
FOnScrollPosChange: TfrxScrollPosChangeEvent;
|
||
|
procedure SetHideScrolls(b: Boolean);
|
||
|
function GetLongPosition(DefValue: Integer; Code: Word): Integer;
|
||
|
procedure SetHorzPosition(Value: Integer);
|
||
|
procedure SetHorzRange(Value: Integer);
|
||
|
procedure SetPosition(Value: Integer; Code: Word);
|
||
|
procedure SetVertPosition(Value: Integer);
|
||
|
procedure SetVertRange(Value: Integer);
|
||
|
procedure UpdateScrollBar(Max, Page, Pos: Integer; Code: Word);
|
||
|
procedure WMEraseBackground(var Message: TMessage); message WM_ERASEBKGND;
|
||
|
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
|
||
|
procedure WMHScroll(var Message: TWMHScroll); message WM_HSCROLL;
|
||
|
procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
|
||
|
procedure SetHorzPage(const Value: Integer);
|
||
|
procedure SetVertPage(const Value: Integer);
|
||
|
procedure SetBorderStyle(const Value: TBorderStyle);
|
||
|
protected
|
||
|
FfrCurrentPPI: Integer;
|
||
|
procedure CreateParams(var Params: TCreateParams); override;
|
||
|
procedure OnHScrollChange(Sender: TObject); virtual;
|
||
|
procedure OnVScrollChange(Sender: TObject); virtual;
|
||
|
procedure WMDpiChanged(var Message: TMessage); message FRX_WM_DPICHANGED_AFTERPARENT;
|
||
|
procedure DoPPIChanged(aNewPPI: Integer); virtual;
|
||
|
function GetScale: Single;
|
||
|
public
|
||
|
constructor Create(AOwner: TComponent); override;
|
||
|
procedure Paint; override;
|
||
|
function GetScaledFontSize: Integer;
|
||
|
procedure SetScaledFontSize(Value: Integer);
|
||
|
{$IFNDEF FPC}
|
||
|
property BevelKind;
|
||
|
{$ENDIF}
|
||
|
property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle;
|
||
|
property HorzPage: Integer read FHorzPage write SetHorzPage;
|
||
|
property HorzPosition: Integer read FHorzPosition write SetHorzPosition;
|
||
|
property HorzRange: Integer read FHorzRange write SetHorzRange;
|
||
|
property LargeChange: Integer read FLargeChange write FLargeChange;
|
||
|
property SmallChange: Integer read FSmallChange write FSmallChange;
|
||
|
property VertPage: Integer read FVertPage write SetVertPage;
|
||
|
property VertPosition: Integer read FVertPosition write SetVertPosition;
|
||
|
property VertRange: Integer read FVertRange write SetVertRange;
|
||
|
property HideScrolls: Boolean read FHideScrolls write SetHideScrolls;
|
||
|
property OnScrollMaxChange: TfrxScrollMaxChangeEvent read FOnScrollMaxChange write FOnScrollMaxChange;
|
||
|
property OnScrollPosChange: TfrxScrollPosChangeEvent read FOnScrollPosChange write FOnScrollPosChange;
|
||
|
end;
|
||
|
|
||
|
function frxBlend(C1, C2: TColor; W1: Integer): TColor;
|
||
|
{$IFDEF FPC}
|
||
|
// procedure Register;
|
||
|
{$ENDIF}
|
||
|
|
||
|
implementation
|
||
|
|
||
|
{$R *.res}
|
||
|
{$IFDEF Delphi6}
|
||
|
{$WARN SYMBOL_DEPRECATED OFF}
|
||
|
{$ENDIF}
|
||
|
|
||
|
uses frxPrinter, frxUtils;
|
||
|
|
||
|
const
|
||
|
fr01cm = 3.77953;
|
||
|
fr01in = 96 / 10;
|
||
|
|
||
|
type
|
||
|
THackScrollBar = class(TScrollBar);
|
||
|
|
||
|
|
||
|
{ Additional functions }
|
||
|
|
||
|
function Min(val1, val2: Word): Word;
|
||
|
begin
|
||
|
Result := val1;
|
||
|
if val1 > val2 then
|
||
|
Result := val2;
|
||
|
end;
|
||
|
|
||
|
function GetFontMetrics(Font: TFont): TTextMetric;
|
||
|
var
|
||
|
DC: HDC;
|
||
|
SaveFont: HFont;
|
||
|
begin
|
||
|
DC := GetDC(0);
|
||
|
SaveFont := SelectObject(DC, Font.Handle);
|
||
|
GetTextMetrics(DC, Result);
|
||
|
SelectObject(DC, SaveFont);
|
||
|
ReleaseDC(0, DC);
|
||
|
end;
|
||
|
|
||
|
function GetFontHeight(Font: TFont): Integer;
|
||
|
begin
|
||
|
Result := GetFontMetrics(Font).tmHeight;
|
||
|
end;
|
||
|
|
||
|
function frxBlend(C1, C2: TColor; W1: Integer): TColor;
|
||
|
var
|
||
|
W2, A1, A2, D, F, G: Integer;
|
||
|
begin
|
||
|
if C1 < 0 then C1 := GetSysColor(C1 and $FF);
|
||
|
if C2 < 0 then C2 := GetSysColor(C2 and $FF);
|
||
|
|
||
|
if W1 >= 100 then D := 1000
|
||
|
else D := 100;
|
||
|
|
||
|
W2 := D - W1;
|
||
|
F := D div 2;
|
||
|
|
||
|
A2 := C2 shr 16 * W2;
|
||
|
A1 := C1 shr 16 * W1;
|
||
|
G := (A1 + A2 + F) div D and $FF;
|
||
|
Result := G shl 16;
|
||
|
|
||
|
A2 := (C2 shr 8 and $FF) * W2;
|
||
|
A1 := (C1 shr 8 and $FF) * W1;
|
||
|
G := (A1 + A2 + F) div D and $FF;
|
||
|
Result := Result or G shl 8;
|
||
|
|
||
|
A2 := (C2 and $FF) * W2;
|
||
|
A1 := (C1 and $FF) * W1;
|
||
|
G := (A1 + A2 + F) div D and $FF;
|
||
|
Result := Result or G;
|
||
|
end;
|
||
|
|
||
|
{ TfrxCustomFilterEdit }
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.CMMouseEnter(var Message: TMessage);
|
||
|
begin
|
||
|
inherited;
|
||
|
FFrameIsActive := True;
|
||
|
{$IFDEF FPC}
|
||
|
{$note FIXME TfrxCustomComboBox.CMMouseEnter}
|
||
|
{$ELSE}
|
||
|
if Enabled then
|
||
|
begin
|
||
|
PaintBorder;
|
||
|
Invalidate;
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.CMMouseLeave(var Message: TMessage);
|
||
|
begin
|
||
|
inherited;
|
||
|
FFrameIsActive := False;
|
||
|
{$IFDEF FPC}
|
||
|
{$note FIXME TfrxCustomComboBox.CMMouseLeave}
|
||
|
{$ELSE}
|
||
|
if Enabled and not FEdit.Focused then
|
||
|
begin
|
||
|
PaintBorder;
|
||
|
Invalidate;
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
constructor TfrxCustomFilterEdit.Create(AOwner: TComponent);
|
||
|
begin
|
||
|
inherited;
|
||
|
{$IFNDEF FPC}
|
||
|
BevelKind := bkNone;
|
||
|
{$ENDIF}
|
||
|
BevelInner := bvNone;
|
||
|
BevelOuter := bvNone;
|
||
|
BorderStyle := bsSingle;
|
||
|
BorderWidth := 1;
|
||
|
FEdit := TEdit.Create(nil);
|
||
|
FEdit.Parent := Self;
|
||
|
FEdit.BorderStyle := bsNone;
|
||
|
FEdit.OnEnter := DoFocus;
|
||
|
FEdit.OnExit := DoLostFocus;
|
||
|
FEdit.OnChange := DoTextChange;
|
||
|
Color := clWindow;
|
||
|
FilterColor := clWindow;
|
||
|
FBitmapActive := TBitmap.Create;
|
||
|
FBitmapUnactive := TBitmap.Create;
|
||
|
end;
|
||
|
|
||
|
destructor TfrxCustomFilterEdit.Destroy;
|
||
|
begin
|
||
|
FreeAndNil(FBitmapActive);
|
||
|
FreeAndNil(FBitmapUnactive);
|
||
|
FreeAndNil(FEdit);
|
||
|
inherited;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.DoFocus(Sender: TObject);
|
||
|
begin
|
||
|
FFrameIsActive := True;
|
||
|
PaintBorder;
|
||
|
Invalidate;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.DoLostFocus(Sender: TObject);
|
||
|
begin
|
||
|
FFrameIsActive := False;
|
||
|
PaintBorder;
|
||
|
Invalidate;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.DoTextChange(Sender: TObject);
|
||
|
var
|
||
|
bTextIsEmpty: Boolean;
|
||
|
begin
|
||
|
bTextIsEmpty := FEdit.Text <> '';
|
||
|
if bTextIsEmpty <> FClearBtnActive then
|
||
|
begin
|
||
|
FClearBtnActive := bTextIsEmpty;
|
||
|
UpdateSize;
|
||
|
Invalidate;
|
||
|
end;
|
||
|
if Assigned(FOnFilterChanged) then
|
||
|
FOnFilterChanged(Sender);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
||
|
X, Y: Integer);
|
||
|
begin
|
||
|
inherited;
|
||
|
if (X > 1) and (X < Height) then
|
||
|
FEdit.Clear;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.Paint;
|
||
|
var
|
||
|
aRect: TRect;
|
||
|
btnWidth, Offset: Integer;
|
||
|
LG: {$IFDEF FPC}TLogBrush{$ELSE}LOGBRUSH{$ENDIF};
|
||
|
hP: HPEN;
|
||
|
OldPen: HGDIOBJ;
|
||
|
SerchIcon: TBitmap;
|
||
|
begin
|
||
|
inherited;
|
||
|
aRect := GetClientRect;
|
||
|
Canvas.Brush.Style := bsSolid;
|
||
|
Canvas.Brush.Color := FFilterColor;
|
||
|
Offset := Round(4 * GetScale);
|
||
|
Canvas.FillRect(aRect);
|
||
|
btnWidth := ((aRect.Bottom - aRect.Top) - Offset * 2) div 2 * 2;
|
||
|
|
||
|
LG.lbStyle := BS_SOLID;
|
||
|
LG.lbColor := 0;// black;
|
||
|
LG.lbHatch := 0;
|
||
|
|
||
|
hP := ExtCreatePen(PS_GEOMETRIC or PS_ENDCAP_ROUND, Round(GetScale),
|
||
|
LG, 0, nil);
|
||
|
try
|
||
|
OldPen := SelectObject(Canvas.Handle, hP);
|
||
|
Canvas.MoveTo(Offset, Offset);
|
||
|
Canvas.LineTo(btnWidth + Offset, btnWidth + Offset);
|
||
|
Canvas.MoveTo(Offset, btnWidth + Offset);
|
||
|
Canvas.LineTo(btnWidth + Offset, Offset);
|
||
|
Canvas.Brush.Color := clBlack;
|
||
|
SelectObject(Canvas.Handle, OldPen);
|
||
|
finally
|
||
|
DeleteObject(hP);
|
||
|
end;
|
||
|
Offset := 0;
|
||
|
btnWidth := ((aRect.Bottom - aRect.Top) - Offset * 2) div 2 * 2;
|
||
|
if FFrameIsActive then
|
||
|
SerchIcon := FBitmapActive
|
||
|
else
|
||
|
SerchIcon := FBitmapUnactive;
|
||
|
Canvas.StretchDraw(Rect((aRect.Right - aRect.Left - btnWidth + 1), 1, (aRect.Right - aRect.Left - btnWidth + 1) + btnWidth, btnWidth), SerchIcon);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.PaintBorder;
|
||
|
var
|
||
|
R: TRect;
|
||
|
DC: HDC;
|
||
|
begin
|
||
|
DC := GetWindowDC(Handle);
|
||
|
try
|
||
|
GetWindowRect(Handle, R);
|
||
|
OffsetRect(R, -R.Left, -R.Top);
|
||
|
InflateRect(R, 0, 0);
|
||
|
if FFrameIsActive then
|
||
|
FrameRect(DC, R, GetSysColorBrush(COLOR_HIGHLIGHT))
|
||
|
else
|
||
|
FrameRect(DC, R, GetSysColorBrush(COLOR_WINDOW));
|
||
|
finally
|
||
|
ReleaseDC(Handle, DC);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.SetFilterColor(const Value: TColor);
|
||
|
begin
|
||
|
FFilterColor := Value;
|
||
|
Color := Value;
|
||
|
EditControl.Color := Color;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.UpdateSize;
|
||
|
var
|
||
|
nOffset: Integer;
|
||
|
begin
|
||
|
nOffset := Round(2 * GetScale);
|
||
|
FClearBtnActive := FEdit.Text <> '';
|
||
|
if FClearBtnActive then
|
||
|
FEdit.SetBounds(Height, nOffset, Width - Height * 2, Height - 1)
|
||
|
else
|
||
|
FEdit.SetBounds(1, nOffset, Width - Height, Height - 1);
|
||
|
end;
|
||
|
|
||
|
{$IFNDEF Linux}
|
||
|
procedure TfrxCustomFilterEdit.WMNCPaint(var Message: TWMNCPaint);
|
||
|
var
|
||
|
R: TRect;
|
||
|
DC: HDC;
|
||
|
begin
|
||
|
DC := GetWindowDC(Handle);
|
||
|
try
|
||
|
GetWindowRect(Handle, R);
|
||
|
OffsetRect(R, -R.Left, -R.Top);
|
||
|
InflateRect(R, 0, 0);
|
||
|
FillRect(DC, R, GetSysColorBrush(Color))
|
||
|
finally
|
||
|
ReleaseDC(Handle, DC);
|
||
|
end;
|
||
|
PaintBorder;
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
|
||
|
procedure TfrxCustomFilterEdit.WMSize(var Message: TWMSize);
|
||
|
begin
|
||
|
inherited;
|
||
|
UpdateSize;
|
||
|
end;
|
||
|
|
||
|
{ TfrxCustomComboBox }
|
||
|
|
||
|
constructor TfrxCustomComboBox.Create(AOwner: TComponent);
|
||
|
begin
|
||
|
inherited Create(AOwner);
|
||
|
{$IFDEF FPC}
|
||
|
FListInstance := nil;
|
||
|
OnClick := SelectAllWhenClicked;
|
||
|
{$IFDEF FPC}
|
||
|
OnlyMask := False;
|
||
|
{$ENDIF}
|
||
|
{$ELSE}
|
||
|
FListInstance := MakeObjectInstance(ListWndProc);
|
||
|
{$ENDIF}
|
||
|
FDefListProc := nil;
|
||
|
ItemHeight := GetFontHeight(Font);
|
||
|
Width := 100;
|
||
|
FEditOffset := 0;
|
||
|
FCurrentPPI := Screen.PixelsPerInch;
|
||
|
FButtonWidth := Round(11 * FCurrentPPI / frx_DefaultPPI);
|
||
|
end;
|
||
|
|
||
|
destructor TfrxCustomComboBox.Destroy;
|
||
|
begin
|
||
|
inherited Destroy;
|
||
|
{$IFNDEF FPC}
|
||
|
FreeObjectInstance(FListInstance);
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
|
||
|
procedure TfrxCustomComboBox.DoPPIChanged(aNewPPI: Integer);
|
||
|
begin
|
||
|
FButtonWidth := MulDiv(11, aNewPPI, FCurrentPPI);
|
||
|
FListWidth := MulDiv(FListWidth, aNewPPI, FCurrentPPI);
|
||
|
end;
|
||
|
|
||
|
|
||
|
procedure TfrxCustomComboBox.SetListWidth(const Value: Integer);
|
||
|
begin
|
||
|
FListWidth := MulDiv(Value, FCurrentPPI, frx_DefaultPPI);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.SetReadOnly(Value: Boolean);
|
||
|
begin
|
||
|
if FReadOnly <> Value then
|
||
|
begin
|
||
|
FReadOnly := Value;
|
||
|
{$IFDEF FPC}
|
||
|
inherited ReadOnly := Value;
|
||
|
{$ELSE}
|
||
|
if HandleAllocated then
|
||
|
SendMessage(EditHandle, EM_SETREADONLY, Ord(Value), 0);
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.CreateParams(var Params: TCreateParams);
|
||
|
begin
|
||
|
inherited CreateParams(Params);
|
||
|
{$IFNDEF FPC}
|
||
|
with Params do
|
||
|
Style := (Style and not CBS_DROPDOWNLIST) or CBS_OWNERDRAWFIXED or CBS_DROPDOWN;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
function TfrxCustomComboBox.GetScale: Single;
|
||
|
begin
|
||
|
Result := FCurrentPPI / frx_DefaultPPI;
|
||
|
end;
|
||
|
|
||
|
{$IFNDEF FPC}
|
||
|
procedure TfrxCustomComboBox.CreateWnd;
|
||
|
begin
|
||
|
inherited;
|
||
|
SendMessage(EditHandle, EM_SETREADONLY, Ord(FReadOnly), 0);
|
||
|
// Desiding, which of the handles is DropDown list handle...
|
||
|
if FChildHandle <> EditHandle then
|
||
|
FListHandle := FChildHandle;
|
||
|
//.. and superclassing it
|
||
|
FDefListProc := Pointer(GetWindowLong(FListHandle, GWL_WNDPROC));
|
||
|
SetWindowLong(FListHandle, GWL_WNDPROC, frxInteger(FListInstance));
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.ListWndProc(var Message: TMessage);
|
||
|
var
|
||
|
p: TPoint;
|
||
|
|
||
|
procedure CallDefaultProc;
|
||
|
begin
|
||
|
with Message do
|
||
|
Result := CallWindowProc(FDefListProc, FListHandle, Msg, WParam, LParam);
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
case Message.Msg of
|
||
|
LB_SETTOPINDEX:
|
||
|
begin
|
||
|
if ItemIndex > DropDownCount then
|
||
|
CallDefaultProc;
|
||
|
end;
|
||
|
WM_WINDOWPOSCHANGING:
|
||
|
with TWMWindowPosMsg(Message).WindowPos^ do
|
||
|
begin
|
||
|
// calculating the size of the drop down list
|
||
|
if FListWidth <> 0 then
|
||
|
cx := FListWidth else
|
||
|
cx := Width;
|
||
|
cy := GetListHeight;
|
||
|
p.x := cx;
|
||
|
p.y := cy + GetFontHeight(Font) + 6;
|
||
|
p := ClientToScreen(p);
|
||
|
FUpDropdown := False;
|
||
|
if p.y > Screen.Height then //if DropDownList showing below
|
||
|
begin
|
||
|
FUpDropdown := True;
|
||
|
end;
|
||
|
end;
|
||
|
else
|
||
|
CallDefaultProc;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.WndProc(var Message: TMessage);
|
||
|
begin
|
||
|
case Message.Msg of
|
||
|
WM_SETTEXT:
|
||
|
Invalidate;
|
||
|
WM_PARENTNOTIFY:
|
||
|
if LoWord(Message.wParam)=WM_CREATE then begin
|
||
|
if FDefListProc <> nil then
|
||
|
begin
|
||
|
// This check is necessary to be sure that combo is created, not
|
||
|
// RECREATED (somehow CM_RECREATEWND does not work)
|
||
|
SetWindowLong(FListHandle, GWL_WNDPROC, frxInteger(FDefListProc));
|
||
|
FDefListProc := nil;
|
||
|
FChildHandle := Message.lParam;
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
// WM_Create is the only event I found where I can get the ListBox handle.
|
||
|
// The fact that combo box usually creates more then 1 handle complicates the
|
||
|
// things, so I have to have the FChildHandle to resolve it later (in CreateWnd).
|
||
|
if FChildHandle = 0 then
|
||
|
FChildHandle := Message.lParam
|
||
|
else
|
||
|
FListHandle := Message.lParam;
|
||
|
end;
|
||
|
end;
|
||
|
WM_WINDOWPOSCHANGING:
|
||
|
{$IFDEF FPC}
|
||
|
{$warning MoveWindow can't be used here - we have resize loop and crash.}
|
||
|
{$ELSE}
|
||
|
MoveWindow(EditHandle, 3+FEditOffset, 3, Width-FButtonWidth-8-FEditOffset,
|
||
|
Height-6, True);
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
inherited;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.WMDpiChanged(var Message: TMessage);
|
||
|
var
|
||
|
NewPPI: Integer;
|
||
|
begin
|
||
|
Inherited;
|
||
|
NewPPI := frxGetDpiForWindow(Handle);
|
||
|
if NewPPI = FCurrentPPI then Exit;
|
||
|
DoPPIChanged(NewPPI);
|
||
|
FCurrentPPI := NewPPI;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.WMPaint(var Message: TWMPaint);
|
||
|
var
|
||
|
PS, PSE: TPaintStruct;
|
||
|
begin
|
||
|
BeginPaint(Handle,PS);
|
||
|
try
|
||
|
if Enabled then
|
||
|
begin
|
||
|
DrawImage(PS.HDC, ItemIndex ,Rect(3, 3, FEditOffset + 3, Height - 3));
|
||
|
if GetSolidBorder then
|
||
|
begin
|
||
|
PaintBorder(PS.HDC, True);
|
||
|
if DroppedDown then
|
||
|
PaintButton(2)
|
||
|
else
|
||
|
PaintButton(1);
|
||
|
end else
|
||
|
begin
|
||
|
PaintBorder(PS.HDC, False);
|
||
|
PaintButton(0);
|
||
|
end;
|
||
|
end else
|
||
|
begin
|
||
|
{$IFNDEF FPC}
|
||
|
BeginPaint(EditHandle, PSE);
|
||
|
try
|
||
|
PaintDisabled;
|
||
|
finally
|
||
|
EndPaint(EditHandle, PSE);
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
finally
|
||
|
EndPaint(Handle,PS);
|
||
|
end;
|
||
|
Message.Result := 0;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.DrawImage(DC: HDC; Index: Integer; R: TRect);
|
||
|
begin
|
||
|
if FEditOffset > 0 then
|
||
|
FillRect(DC, R, GetSysColorBrush(COLOR_WINDOW));
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.ComboWndProc(var Message: TMessage; ComboWnd: HWnd;
|
||
|
ComboProc: Pointer);
|
||
|
var
|
||
|
DC: HDC;
|
||
|
begin
|
||
|
inherited;
|
||
|
if (ComboWnd = EditHandle) then
|
||
|
case Message.Msg of
|
||
|
WM_SETFOCUS:
|
||
|
begin
|
||
|
DC:=GetWindowDC(Handle);
|
||
|
PaintBorder(DC,True);
|
||
|
PaintButton(1);
|
||
|
ReleaseDC(Handle,DC);
|
||
|
end;
|
||
|
WM_KILLFOCUS:
|
||
|
begin
|
||
|
DC:=GetWindowDC(Handle);
|
||
|
PaintBorder(DC,False);
|
||
|
PaintButton(0);
|
||
|
ReleaseDC(Handle,DC);
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.CNCommand(var Message: TWMCommand);
|
||
|
begin
|
||
|
inherited;
|
||
|
if (Message.NotifyCode in [CBN_CLOSEUP]) then
|
||
|
PaintButton(1);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.PaintBorder(DC: HDC; const SolidBorder: Boolean);
|
||
|
var
|
||
|
R: TRect;
|
||
|
begin
|
||
|
GetWindowRect(Handle, R);
|
||
|
OffsetRect(R, -R.Left, -R.Top);
|
||
|
if SolidBorder then
|
||
|
FrameRect(DC, R, GetSysColorBrush(COLOR_HIGHLIGHT))
|
||
|
else
|
||
|
FrameRect(DC, R, GetSysColorBrush(COLOR_BTNFACE));
|
||
|
InflateRect(R, -1, -1);
|
||
|
FrameRect(DC, R, GetSysColorBrush(COLOR_WINDOW));
|
||
|
InflateRect(R, -1, -1);
|
||
|
R.Right:=R.Right - FButtonWidth - 2;
|
||
|
FrameRect(DC, R, GetSysColorBrush(COLOR_WINDOW));
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.PaintButton(ButtonStyle: Integer);
|
||
|
var
|
||
|
R: TRect;
|
||
|
DC: HDC;
|
||
|
|
||
|
procedure FillButton(DC: HDC; R: TRect; Color: TColor);
|
||
|
var
|
||
|
Brush, SaveBrush: HBRUSH;
|
||
|
begin
|
||
|
Brush := CreateSolidBrush(ColorToRGB(Color));
|
||
|
SaveBrush := SelectObject(DC, Brush);
|
||
|
FillRect(DC, R, Brush);
|
||
|
SelectObject(DC, SaveBrush);
|
||
|
DeleteObject(Brush);
|
||
|
end;
|
||
|
|
||
|
procedure PaintButtonLine(DC: HDC; Color: TColor);
|
||
|
var
|
||
|
Pen, SavePen: HPEN;
|
||
|
R: TRect;
|
||
|
begin
|
||
|
GetWindowRect(Handle, R);
|
||
|
OffsetRect (R, -R.Left, -R.Top);
|
||
|
InflateRect(R, -FButtonWidth - 4, -1);
|
||
|
Pen := CreatePen(PS_SOLID, 1, ColorToRGB(Color));
|
||
|
SavePen := SelectObject(DC, Pen);
|
||
|
MoveToEx(DC, R.Right, R.Top, nil);
|
||
|
LineTo(DC, R.Right, R.Bottom);
|
||
|
SelectObject(DC, SavePen);
|
||
|
DeleteObject(Pen);
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
DC := GetWindowDC(Handle);
|
||
|
//X := Trunc(FButtonWidth / 2) + Width - FButtonWidth - 4;
|
||
|
//Y := Trunc((Height - 4) / 2) + 1;
|
||
|
|
||
|
SetRect(R, Width - FButtonWidth - 3, 1, Width - 1, Height - 1);
|
||
|
if ButtonStyle = 0 then //No 3D border
|
||
|
begin
|
||
|
FillButton(DC, R, clBtnFace);
|
||
|
FrameRect(DC, R, GetSysColorBrush(COLOR_WINDOW));
|
||
|
PaintButtonLine(DC, clWindow);
|
||
|
frxDrawArrow(Canvas, R, clBtnText);
|
||
|
end;
|
||
|
if ButtonStyle = 1 then //3D up border
|
||
|
begin
|
||
|
FillButton(DC, R, frxBlend(clHighlight, clWindow, 30));
|
||
|
PaintButtonLine(DC, clHighlight);
|
||
|
frxDrawArrow(Canvas, R, clBtnText);
|
||
|
end;
|
||
|
if ButtonStyle = 2 then //3D down border
|
||
|
begin
|
||
|
FillButton(DC, R, frxBlend(clHighlight, clWindow, 50));
|
||
|
PaintButtonLine(DC, clHighlight);
|
||
|
frxDrawArrow(Canvas, R, clCaptionText);
|
||
|
end;
|
||
|
ReleaseDC(Handle, DC);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.PaintDisabled;
|
||
|
var
|
||
|
R: TRect;
|
||
|
Brush, SaveBrush: HBRUSH;
|
||
|
DC: HDC;
|
||
|
BtnShadowBrush: HBRUSH;
|
||
|
begin
|
||
|
BtnShadowBrush := GetSysColorBrush(COLOR_BTNSHADOW);
|
||
|
DC := GetWindowDC(Handle);
|
||
|
Brush := CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
|
||
|
SaveBrush := SelectObject(DC, Brush);
|
||
|
FillRect(DC, ClientRect, Brush);
|
||
|
SelectObject(DC, SaveBrush);
|
||
|
DeleteObject(Brush);
|
||
|
GetWindowRect(Handle, R);
|
||
|
OffsetRect(R, -R.Left, -R.Top);
|
||
|
FrameRect(DC, R, BtnShadowBrush);
|
||
|
SetRect(R, Width - FButtonWidth - 3, 1, Width - 1, Height - 1);
|
||
|
frxDrawArrow(Canvas, R, clGrayText);
|
||
|
ReleaseDC(Handle,DC);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.Resize;
|
||
|
var
|
||
|
m: TMessage;
|
||
|
begin
|
||
|
inherited;
|
||
|
m.Msg := FRX_WM_DPICHANGED_AFTERPARENT;
|
||
|
WMDpiChanged(m);
|
||
|
end;
|
||
|
|
||
|
function TfrxCustomComboBox.GetSolidBorder: Boolean;
|
||
|
begin
|
||
|
Result := ((csDesigning in ComponentState)) or
|
||
|
(DroppedDown or (GetFocus = {$IFDEF FPC}Handle{$ELSE}EditHandle{$ENDIF}) or msMouseInControl);
|
||
|
end;
|
||
|
|
||
|
function TfrxCustomComboBox.GetListHeight: Integer;
|
||
|
begin
|
||
|
Result := ItemHeight * Min(DropDownCount, Items.Count) + 2;
|
||
|
if (DropDownCount <= 0) or (Items.Count = 0) then
|
||
|
Result := ItemHeight + 2;
|
||
|
end;
|
||
|
{$ELSE}
|
||
|
procedure TfrxCustomComboBox.SelectAllWhenClicked(Sender: TObject);
|
||
|
begin
|
||
|
SelectAll;
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
procedure TfrxCustomComboBox.CMEnabledChanged(var Msg: TMessage);
|
||
|
begin
|
||
|
inherited;
|
||
|
Invalidate;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.CMMouseEnter(var Message: TMessage);
|
||
|
var
|
||
|
DC: HDC;
|
||
|
begin
|
||
|
inherited;
|
||
|
msMouseInControl := True;
|
||
|
{$IFDEF FPC}
|
||
|
{$note FIXME TfrxCustomComboBox.CMMouseEnter}
|
||
|
{$ELSE}
|
||
|
if Enabled and not (GetFocus = EditHandle) and not DroppedDown then
|
||
|
begin
|
||
|
DC:=GetWindowDC(Handle);
|
||
|
PaintBorder(DC, True);
|
||
|
PaintButton(1);
|
||
|
ReleaseDC(Handle, DC);
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.CMMouseLeave(var Message: TMessage);
|
||
|
var
|
||
|
DC: HDC;
|
||
|
begin
|
||
|
inherited;
|
||
|
msMouseInControl := False;
|
||
|
{$IFDEF FPC}
|
||
|
{$note FIXME TfrxCustomComboBox.CMMouseLeave}
|
||
|
{$ELSE}
|
||
|
if Enabled and not (GetFocus = EditHandle) and not DroppedDown then
|
||
|
begin
|
||
|
DC:=GetWindowDC(Handle);
|
||
|
PaintBorder(DC, False);
|
||
|
PaintButton(0);
|
||
|
ReleaseDC(Handle, DC);
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.KeyPress(var Key: Char);
|
||
|
var
|
||
|
sPos: Integer;
|
||
|
{$IFDEF FPC}
|
||
|
Mask: boolean;
|
||
|
i: Integer;
|
||
|
Bufstr: String;
|
||
|
{$ELSE}
|
||
|
sLen: Integer;
|
||
|
{$ENDIF}
|
||
|
begin
|
||
|
inherited KeyPress(Key);
|
||
|
{$IFDEF FPC}
|
||
|
if(Key=#8) then exit;
|
||
|
Bufstr := AnsiUpperCase(Text);
|
||
|
Delete(Bufstr, SelStart+1, SelLength);
|
||
|
Bufstr := Bufstr + AnsiUpperCase(Key);
|
||
|
Mask := false;
|
||
|
for i:= 0 to Items.Count-1 do
|
||
|
if(Pos(Bufstr, AnsiUpperCase(Items[i]))=1) then
|
||
|
begin
|
||
|
sPos := Bufstr.Length;
|
||
|
ItemIndex:=i;
|
||
|
Click();
|
||
|
SelStart := sPos;
|
||
|
SelLength := Length(Text)-sPos;
|
||
|
Mask := True;
|
||
|
break;
|
||
|
end;
|
||
|
if (Mask) or (OnlyMask) then
|
||
|
Key := #0;
|
||
|
{$ELSE}
|
||
|
if (ItemIndex >= 0) and (ItemIndex < Items.Count) then
|
||
|
begin
|
||
|
sPos := SelStart;
|
||
|
sLen := SelLength;
|
||
|
Text := Items[ItemIndex];
|
||
|
SelStart := sPos;
|
||
|
SelLength := sLen;
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxCustomComboBox.CMFontChanged(var Message: TMessage);
|
||
|
begin
|
||
|
inherited;
|
||
|
ItemHeight := GetFontHeight(Font);
|
||
|
{$IFNDEF FPC}
|
||
|
RecreateWnd;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
{ TfrxFontComboBox }
|
||
|
|
||
|
function CreateBitmap(ResName: PChar): TBitmap;
|
||
|
begin
|
||
|
Result := TBitmap.Create;
|
||
|
Result.Handle := LoadBitmap(HInstance, ResName);
|
||
|
if Result.Handle = 0 then
|
||
|
begin
|
||
|
Result.Free;
|
||
|
Result := nil;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function EnumFontsProc(var LogFont: TLogFont; var TextMetric: TTextMetric;
|
||
|
FontType: Integer; Data: Pointer): Integer; stdcall;
|
||
|
begin
|
||
|
if (TStrings(Data).IndexOf(LogFont.lfFaceName) < 0) then
|
||
|
TStrings(Data).AddObject(LogFont.lfFaceName, TObject(FontType));
|
||
|
Result := 1;
|
||
|
end;
|
||
|
|
||
|
constructor TfrxFontComboBox.Create(AOwner: TComponent);
|
||
|
begin
|
||
|
inherited Create(AOwner);
|
||
|
{$IFNDEF FPC}
|
||
|
if not (csDesigning in ComponentState) then
|
||
|
frFontViewForm := TfrxFontPreview.Create(Self);
|
||
|
{$ENDIF}
|
||
|
Width := 150;
|
||
|
DoPPIChanged(Screen.PixelsPerInch);
|
||
|
FShowMRU := True;
|
||
|
Numused := -1;
|
||
|
MRURegKey := '';
|
||
|
FIni := nil;
|
||
|
end;
|
||
|
|
||
|
destructor TfrxFontComboBox.Destroy;
|
||
|
begin
|
||
|
FTrueTypeBMP.Free;
|
||
|
FDeviceBMP.Free;
|
||
|
if FIni <> nil then
|
||
|
Fini.Free;
|
||
|
{$IFNDEF FPC}
|
||
|
if not (csDesigning in ComponentState) then
|
||
|
frFontViewForm.Destroy;
|
||
|
{$ENDIF}
|
||
|
inherited Destroy;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontComboBox.DoPPIChanged(aNewPPI: Integer);
|
||
|
begin
|
||
|
inherited;
|
||
|
FreeAndNil(FTrueTypeBMP);
|
||
|
FreeAndNil(FDeviceBMP);
|
||
|
FTrueTypeBMP := CreateBitmap('FRXTRUETYPE_FNT');
|
||
|
FDeviceBMP := CreateBitmap('FRXDEVICE_FNT');
|
||
|
ScaleBitmap(FTrueTypeBMP, aNewPPI);
|
||
|
ScaleBitmap(FDeviceBMP, aNewPPI);
|
||
|
DropDownCount := 12;
|
||
|
{$IFNDEF FPC}
|
||
|
FEditOffset := FTrueTypeBMP.Width;
|
||
|
FReadOnly := True;
|
||
|
{$ELSE}
|
||
|
OnlyMask := True;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontComboBox.Loaded;
|
||
|
begin
|
||
|
inherited Loaded;
|
||
|
if csDesigning in ComponentState then exit;
|
||
|
FUpdate := True;
|
||
|
try
|
||
|
PopulateList;
|
||
|
if Items.IndexOf(Text) = -1 then
|
||
|
ItemIndex:=0;
|
||
|
finally
|
||
|
FUpdate := False;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontComboBox.SetRegKey(Value: String);
|
||
|
begin
|
||
|
if Value = '' then
|
||
|
FRegKey := '\Software\Fast Reports\MRUFont' else
|
||
|
FRegKey := Value;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontComboBox.PopulateList;
|
||
|
var
|
||
|
LFont: TLogFont;
|
||
|
DC: HDC;
|
||
|
// {$IFNDEF NONWINFPC}
|
||
|
// Reg: TRegistry;
|
||
|
// {$ENDIF}
|
||
|
s: String;
|
||
|
i: Integer;
|
||
|
str: TStringList;
|
||
|
begin
|
||
|
Sorted:=True;
|
||
|
Items.BeginUpdate;
|
||
|
str := TStringList.Create;
|
||
|
str.Sorted := True;
|
||
|
try
|
||
|
Clear;
|
||
|
DC := GetDC(0);
|
||
|
try
|
||
|
FillChar(LFont, sizeof(LFont), 0);
|
||
|
LFont.lfCharset := DEFAULT_CHARSET;
|
||
|
{$IFDEF FPC}
|
||
|
EnumFontFamiliesEx(DC, @LFont, FontEnumExProc(@EnumFontsProc), PtrUInt(str), 0);
|
||
|
{$ELSE}
|
||
|
EnumFontFamiliesEx(DC, LFont, @EnumFontsProc, frxInteger(str), 0);
|
||
|
{$ENDIF}
|
||
|
finally
|
||
|
ReleaseDC(0, DC);
|
||
|
end;
|
||
|
if frxPrinters.HasPhysicalPrinters then
|
||
|
try
|
||
|
FillChar(LFont, sizeof(LFont), 0);
|
||
|
LFont.lfCharset := DEFAULT_CHARSET;
|
||
|
if frxPrinters.Printer <> nil then
|
||
|
begin
|
||
|
|
||
|
{$IFDEF NONWINFPC}
|
||
|
DC := GetDC(0);
|
||
|
try
|
||
|
EnumFontFamiliesEx(DC, @LFont, FontEnumExProc(@EnumFontsProc), PtrUInt(str), 0);
|
||
|
finally
|
||
|
ReleaseDC(0, DC);
|
||
|
end;
|
||
|
{$ELSE}
|
||
|
EnumFontFamiliesEx(frxPrinters.Printer.Canvas.Handle,
|
||
|
{$IFDEF FPC}@LFont{$ELSE}LFont{$ENDIF}, @EnumFontsProc, frxInteger(str), 0);
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
except;
|
||
|
end;
|
||
|
finally
|
||
|
Items.Assign(str);
|
||
|
Items.EndUpdate;
|
||
|
end;
|
||
|
str.Free;
|
||
|
Sorted := False;
|
||
|
// {$IFNDEF NONWINFPC}
|
||
|
if (FShowMRU) and (FIni <> nil) then
|
||
|
begin
|
||
|
NumUsed := -1;
|
||
|
Items.BeginUpdate;
|
||
|
//Reg:=TRegistry.Create;
|
||
|
try
|
||
|
//Reg.OpenKey(FRegKey, True);
|
||
|
for i := 4 downto 0 do
|
||
|
begin
|
||
|
s := Fini.ReadString('MRUFont', 'Font' + IntToStr(i), '');
|
||
|
if (s <> '') and (Items.IndexOf(s) <> -1) then
|
||
|
begin
|
||
|
Items.InsertObject(0, s, TObject(Fini.ReadInteger('MRUFont', 'FontType' + IntToStr(i), 0)));
|
||
|
Inc(Numused);
|
||
|
end else
|
||
|
begin
|
||
|
Fini.WriteString('MRUFont', 'Font' + IntToStr(i), '');
|
||
|
Fini.WriteInteger('MRUFont', 'FontType' + IntToStr(i), 0);
|
||
|
end;
|
||
|
end;
|
||
|
finally
|
||
|
Items.EndUpdate;
|
||
|
end;
|
||
|
end;
|
||
|
//{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontComboBox.DrawImage(DC: HDC; Index: Integer; R: TRect);
|
||
|
var
|
||
|
C: TCanvas;
|
||
|
Bitmap: TBitmap;
|
||
|
begin
|
||
|
inherited;
|
||
|
Index := Items.IndexOf(Text);
|
||
|
if Index = -1 then exit;
|
||
|
C := TCanvas.Create;
|
||
|
C.Handle := DC;
|
||
|
if (Integer(Items.Objects[Index]) and TRUETYPE_FONTTYPE) <> 0 then
|
||
|
Bitmap := FTrueTypeBMP
|
||
|
else if (Integer(Items.Objects[Index]) and DEVICE_FONTTYPE) <> 0 then
|
||
|
Bitmap := FDeviceBMP
|
||
|
else
|
||
|
Bitmap := nil;
|
||
|
if Bitmap <> nil then
|
||
|
begin
|
||
|
C.Brush.Color := clWindow;
|
||
|
C.BrushCopy(Bounds(R.Left, (R.Top + R.Bottom - Bitmap.Height)
|
||
|
div 2, Bitmap.Width, Bitmap.Height), Bitmap, Bounds(0, 0, Bitmap.Width,
|
||
|
Bitmap.Height), Bitmap.TransparentColor);
|
||
|
end;
|
||
|
C.Free;
|
||
|
end;
|
||
|
|
||
|
|
||
|
procedure TfrxFontComboBox.DrawItem(Index: Integer; Rect: TRect;
|
||
|
State: TOwnerDrawState);
|
||
|
var
|
||
|
Bitmap: TBitmap;
|
||
|
BmpWidth: Integer;
|
||
|
Text: array[0..255] of Char;
|
||
|
{$IFNDEF FPC}
|
||
|
tWidth: Integer;
|
||
|
{$ENDIF}
|
||
|
begin
|
||
|
{$IFNDEF FPC}
|
||
|
if odSelected in State then
|
||
|
begin
|
||
|
frFontViewForm.SetDefaultFontSize(FCurrentPPI);
|
||
|
frFontViewForm.FPanel.Caption := Self.Items[index];
|
||
|
frFontViewForm.FPanel.Font.Name := Self.Items[index];
|
||
|
{ use one of the Icon's bitmaps to calculate size of text }
|
||
|
{ we do not use it to output any text, so it shouldn't impact draw }
|
||
|
FTrueTypeBMP.Canvas.Font.Assign(frFontViewForm.FPanel.Font);
|
||
|
tWidth := FTrueTypeBMP.Canvas.TextWidth(frFontViewForm.FPanel.Caption);
|
||
|
if tWidth > frFontViewForm.Width then
|
||
|
frFontViewForm.FPanel.Font.Height := Round(frFontViewForm.FPanel.Font.Height / (tWidth / frFontViewForm.Width));
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
with Canvas do
|
||
|
begin
|
||
|
BmpWidth := 15;
|
||
|
FillRect(Rect);
|
||
|
if (Integer(Items.Objects[Index]) and TRUETYPE_FONTTYPE) <> 0 then
|
||
|
Bitmap := FTrueTypeBMP
|
||
|
else if (Integer(Items.Objects[Index]) and DEVICE_FONTTYPE) <> 0 then
|
||
|
Bitmap := FDeviceBMP
|
||
|
else
|
||
|
Bitmap := nil;
|
||
|
|
||
|
if Bitmap <> nil then
|
||
|
begin
|
||
|
BmpWidth := Bitmap.Width;
|
||
|
BrushCopy(Bounds(Rect.Left+1 , (Rect.Top + Rect.Bottom - Bitmap.Height)
|
||
|
div 2, Bitmap.Width, Bitmap.Height), Bitmap, Bounds(0, 0, Bitmap.Width,
|
||
|
Bitmap.Height), Bitmap.TransparentColor);
|
||
|
end;
|
||
|
StrPCopy(Text, Items[Index]);
|
||
|
Rect.Left := Rect.Left + BmpWidth + 2;
|
||
|
DrawText(Canvas.Handle, Text, StrLen(Text), Rect,
|
||
|
{$IFDEF Delphi4}
|
||
|
DrawTextBiDiModeFlags(DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX));
|
||
|
{$ELSE}
|
||
|
DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX);
|
||
|
{$ENDIF}
|
||
|
if (Index = Numused) then
|
||
|
begin
|
||
|
Pen.Color := clBtnShadow;
|
||
|
MoveTo(0,Rect.Bottom - 2);
|
||
|
LineTo(width, Rect.Bottom - 2);
|
||
|
end;
|
||
|
if (Index = Numused + 1) and (Numused <> -1) then
|
||
|
begin
|
||
|
Pen.Color := clBtnShadow;
|
||
|
MoveTo(0, Rect.Top);
|
||
|
LineTo(width, Rect.Top);
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontComboBox.CMFontChanged(var Message: TMessage);
|
||
|
begin
|
||
|
inherited;
|
||
|
Init;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontComboBox.CMFontChange(var Message: TMessage);
|
||
|
begin
|
||
|
inherited;
|
||
|
Reset;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontComboBox.Init;
|
||
|
begin
|
||
|
if GetFontHeight(Font) > FTrueTypeBMP.Height then
|
||
|
ItemHeight := GetFontHeight(Font)
|
||
|
else
|
||
|
ItemHeight := FTrueTypeBMP.Height + 1;
|
||
|
{$IFNDEF NONWINFPC}
|
||
|
{$IFDEF FPC}
|
||
|
// if HandleAllocated then
|
||
|
// RecreateWnd(Self);
|
||
|
{$ELSE}
|
||
|
RecreateWnd;
|
||
|
{$ENDIF}
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontComboBox.Click;
|
||
|
begin
|
||
|
inherited Click;
|
||
|
if not (csReading in ComponentState) then
|
||
|
if not FUpdate and Assigned(FOnClick) then FOnClick(Self);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontComboBox.Reset;
|
||
|
begin
|
||
|
if csDesigning in ComponentState then exit;
|
||
|
FUpdate := True;
|
||
|
try
|
||
|
PopulateList;
|
||
|
if Items.IndexOf(Text) = -1 then
|
||
|
ItemIndex := 0;
|
||
|
finally
|
||
|
FUpdate := False;
|
||
|
end;
|
||
|
end;
|
||
|
{$IFNDEF FPC}
|
||
|
procedure TfrxFontComboBox.CNCommand(var Message: TWMCommand);
|
||
|
var
|
||
|
pnt:TPoint;
|
||
|
ind, i, sWidth:integer;
|
||
|
m: TMonitor;
|
||
|
//{$IFNDEF NONWINFPC}
|
||
|
//Reg: TRegistry;
|
||
|
//{$ENDIF}
|
||
|
begin
|
||
|
inherited;
|
||
|
if (Message.NotifyCode in [CBN_CLOSEUP]) then
|
||
|
begin
|
||
|
frFontViewForm.Visible := False;
|
||
|
ind := itemindex;
|
||
|
if (ItemIndex = -1) or (ItemIndex = 0) then exit;
|
||
|
if FShowMRU then
|
||
|
begin
|
||
|
Items.BeginUpdate;
|
||
|
if Items.IndexOf(Items[ind]) <= Numused then
|
||
|
begin
|
||
|
Items.Move(Items.IndexOf(Items[ind]), 0);
|
||
|
ItemIndex := 0;
|
||
|
end else
|
||
|
begin
|
||
|
Items.InsertObject(0, Items[ItemIndex], Items.Objects[ItemIndex]);
|
||
|
Itemindex := 0;
|
||
|
if Numused < 4 then
|
||
|
Inc(Numused)
|
||
|
else
|
||
|
Items.Delete(5);
|
||
|
end;
|
||
|
Items.EndUpdate;
|
||
|
// {$IFNDEF NONWINFPC}
|
||
|
//Reg := TRegistry.Create;
|
||
|
if (FIni <> nil) then
|
||
|
begin
|
||
|
//Reg.OpenKey(FRegKey,True);
|
||
|
for i := 0 to 4 do
|
||
|
if i <= Numused then
|
||
|
begin
|
||
|
FIni.WriteString('MRUFont', 'Font' + IntToStr(i), Items[i]);
|
||
|
FIni.WriteInteger('MRUFont', 'FontType' + IntToStr(i), Integer(Items.Objects[i]));
|
||
|
end else
|
||
|
begin
|
||
|
FIni.WriteString('MRUFont', 'Font' + IntToStr(i), '');
|
||
|
Fini.WriteInteger('MRUFont', 'FontType' + IntToStr(i), 0);
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
if (Message.NotifyCode in [CBN_DROPDOWN]) then
|
||
|
begin
|
||
|
{$IFDEF NONWINFPC}
|
||
|
{$note TfrxFontComboBox.CNCommand fix LB_SETCURSEL}
|
||
|
{$ELSE}
|
||
|
if ItemIndex < 5 then
|
||
|
PostMessage(FListHandle, LB_SETCURSEL, 0, 0);
|
||
|
{$ENDIF}
|
||
|
pnt.x := Self.Left + Self.Width;
|
||
|
pnt.y := Self.Top + Self.Height;
|
||
|
pnt := Parent.ClientToScreen(pnt);
|
||
|
frFontViewForm.Top := pnt.y;
|
||
|
frFontViewForm.Left := pnt.x + 1;
|
||
|
m := Screen.MonitorFromWindow(Self.Handle, mdNearest);
|
||
|
if Assigned(m) then
|
||
|
sWidth := m.WorkareaRect.Right
|
||
|
else
|
||
|
sWidth := Screen.Width;
|
||
|
|
||
|
if frFontViewForm.Left + frFontViewForm.Width > sWidth then
|
||
|
begin
|
||
|
pnt.x := Self.Left;
|
||
|
pnt := Parent.ClientToScreen(pnt);
|
||
|
frFontViewForm.Left := pnt.x - frFontViewForm.Width - 1;
|
||
|
end;
|
||
|
if FUpDropdown then
|
||
|
begin
|
||
|
pnt.y := Self.Top;
|
||
|
pnt := Parent.ClientToScreen(pnt);
|
||
|
frFontViewForm.Top := pnt.y - frFontViewForm.Height;
|
||
|
end;
|
||
|
frFontViewForm.Visible := True;
|
||
|
end;
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
|
||
|
|
||
|
{ TfrxFontPreview }
|
||
|
|
||
|
constructor TfrxFontPreview.Create(AOwner: TComponent);
|
||
|
begin
|
||
|
inherited Create(AOwner);
|
||
|
Width := 200;
|
||
|
Height := 50;
|
||
|
Visible := False;
|
||
|
Parent := AOwner as TWinControl;
|
||
|
|
||
|
FPanel := TPanel.Create(Self);
|
||
|
with FPanel do
|
||
|
begin
|
||
|
Parent := Self;
|
||
|
Color := clWindow;
|
||
|
{$IFNDEF FPC}
|
||
|
Ctl3D := False;
|
||
|
ParentCtl3D := False;
|
||
|
{$ENDIF}
|
||
|
BorderStyle := bsSingle;
|
||
|
BevelInner := bvNone;
|
||
|
BevelOuter := bvNone;
|
||
|
Font.Color := clWindowText;
|
||
|
Font.Size := 18;
|
||
|
Align := alClient;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
destructor TfrxFontPreview.Destroy;
|
||
|
begin
|
||
|
FPanel.Free;
|
||
|
FPanel := nil;
|
||
|
inherited Destroy;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontPreview.SetDefaultFontSize(aNewPPI: Integer);
|
||
|
begin
|
||
|
FPanel.Font.Size := 18;
|
||
|
FPanel.Font.Height := MulDiv(FPanel.Font.Height, aNewPPI, frx_DefaultPPI);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxFontPreview.CreateParams(var Params: TCreateParams);
|
||
|
begin
|
||
|
inherited CreateParams( Params);
|
||
|
with Params do begin
|
||
|
Style := WS_POPUP or WS_CLIPCHILDREN;
|
||
|
ExStyle := WS_EX_TOOLWINDOW;
|
||
|
{$IFNDEF NONWINFPC}
|
||
|
WindowClass.Style := WindowClass.Style or CS_SAVEBITS;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
|
||
|
{ TfrxComboEdit }
|
||
|
|
||
|
constructor TfrxComboEdit.Create(AOwner: TComponent);
|
||
|
begin
|
||
|
inherited Create(AOwner);
|
||
|
Style := csSimple;
|
||
|
Height := 21;
|
||
|
FPanel := TPanel.Create(Self);
|
||
|
FPanel.Parent := Self;
|
||
|
FPanel.SetBounds(Width - Height + 2, 2, Height - 4, Height - 4);
|
||
|
FButton := TSpeedButton.Create(Self);
|
||
|
FButton.Parent := FPanel;
|
||
|
FButton.SetBounds(0, 0, FPanel.Width, FPanel.Height);
|
||
|
FButton.OnClick := ButtonClick;
|
||
|
FButtonEnabled := True;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxComboEdit.SetPos;
|
||
|
begin
|
||
|
{$IFDEF NONWINFPC}
|
||
|
{$note FIXME TfrxComboEdit.SetPos}
|
||
|
{$ELSE}
|
||
|
SetWindowPos(EditHandle, 0, 0, 0, Width - Height - 4, ItemHeight,
|
||
|
SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE)
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxComboEdit.CreateWnd;
|
||
|
begin
|
||
|
inherited CreateWnd;
|
||
|
SetPos;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxComboEdit.WMSize(var Message: TWMSize);
|
||
|
begin
|
||
|
inherited;
|
||
|
FPanel.SetBounds(Width - Height + 2, 2, Height - 4, Height - 4);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxComboEdit.CMEnabledChanged(var Message: TMessage);
|
||
|
begin
|
||
|
inherited;
|
||
|
FButton.Enabled := Enabled;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxComboEdit.KeyPress(var Key: Char);
|
||
|
begin
|
||
|
if (Key = Char(vk_Return)) or (Key = Char(vk_Escape)) then
|
||
|
GetParentForm(Self).Perform(CM_DIALOGKEY, Byte(Key), 0);
|
||
|
inherited KeyPress(Key);
|
||
|
end;
|
||
|
|
||
|
function TfrxComboEdit.GetGlyph: TBitmap;
|
||
|
begin
|
||
|
Result := FButton.Glyph;
|
||
|
end;
|
||
|
|
||
|
{$IFDEF FPC}
|
||
|
{$IFNDEF NONWINFPC}
|
||
|
function TfrxComboEdit.GetEditHandle: HWND;
|
||
|
begin
|
||
|
Result := LazHelper.GetComboEditHandle(Handle);
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
{$ENDIF}
|
||
|
|
||
|
procedure TfrxComboEdit.SetGlyph(Value: TBitmap);
|
||
|
begin
|
||
|
FButton.Glyph := Value;
|
||
|
end;
|
||
|
|
||
|
function TfrxComboEdit.GetButtonHint: String;
|
||
|
begin
|
||
|
Result := FButton.Hint;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxComboEdit.SetButtonHint(Value: String);
|
||
|
begin
|
||
|
FButton.Hint := Value;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxComboEdit.SetButtonEnabled(Value: Boolean);
|
||
|
begin
|
||
|
FButtonEnabled := Value;
|
||
|
FButton.Enabled := Value;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxComboEdit.ButtonClick(Sender: TObject);
|
||
|
begin
|
||
|
SetFocus;
|
||
|
if Assigned(FOnButtonClick) then
|
||
|
FOnButtonClick(Self);
|
||
|
end;
|
||
|
|
||
|
|
||
|
{ TfrxScrollWin }
|
||
|
|
||
|
constructor TfrxScrollWin.Create(AOwner: TComponent);
|
||
|
begin
|
||
|
inherited;
|
||
|
FSmallChange := 1;
|
||
|
FLargeChange := 10;
|
||
|
FHorzPage := 0;
|
||
|
FVertPage := 0;
|
||
|
FHideScrolls := False;
|
||
|
{$IFDEF Delphi7}
|
||
|
ControlStyle := ControlStyle + [csNeedsBorderPaint];
|
||
|
{$ENDIF}
|
||
|
FfrCurrentPPI := Screen.PixelsPerInch;
|
||
|
{$IFDEF DELPHI24}
|
||
|
FCurrentPPI := FfrCurrentPPI;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.CreateParams(var Params: TCreateParams);
|
||
|
const
|
||
|
BorderStyles: array[TBorderStyle] of DWORD = (0, WS_BORDER);
|
||
|
begin
|
||
|
inherited;
|
||
|
with Params do
|
||
|
begin
|
||
|
Style := Style or WS_CLIPCHILDREN or BorderStyles[FBorderStyle];
|
||
|
if (not HideScrolls) then
|
||
|
Style := Style or WS_HSCROLL or WS_VSCROLL;
|
||
|
if {$IFNDEF FPC}Ctl3D and {$ENDIF} NewStyleControls and (FBorderStyle = bsSingle) then
|
||
|
begin
|
||
|
Style := Style and not WS_BORDER;
|
||
|
ExStyle := ExStyle or WS_EX_CLIENTEDGE;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.DoPPIChanged(aNewPPI: Integer);
|
||
|
begin
|
||
|
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.SetBorderStyle(const Value: TBorderStyle);
|
||
|
begin
|
||
|
FBorderStyle := Value;
|
||
|
{$IFNDEF NONWINFPC}
|
||
|
{$IFDEF FPC}
|
||
|
// if HandleAllocated then
|
||
|
// RecreateWnd(Self);
|
||
|
{$ELSE}
|
||
|
RecreateWnd;
|
||
|
{$ENDIF}
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.WMDpiChanged(var Message: TMessage);
|
||
|
var
|
||
|
NewPPI: Integer;
|
||
|
begin
|
||
|
Inherited;
|
||
|
NewPPI := frxGetDpiForWindow(Handle);
|
||
|
if NewPPI = FfrCurrentPPI then Exit;
|
||
|
DoPPIChanged(NewPPI);
|
||
|
FfrCurrentPPI := NewPPI;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.WMEraseBackground(var Message: TMessage);
|
||
|
begin
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.WMGetDlgCode(var Message: TWMGetDlgCode);
|
||
|
begin
|
||
|
Message.Result := DLGC_WANTARROWS or DLGC_WANTTAB or DLGC_WANTALLKEYS;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.SetHideScrolls(b: Boolean);
|
||
|
begin
|
||
|
if (FHideScrolls <> b) then
|
||
|
begin
|
||
|
ShowScrollBar(Self.Handle, SB_BOTH, not b);
|
||
|
ShowScrollBar(Self.Handle, SB_HORZ, not b);
|
||
|
ShowScrollBar(Self.Handle, SB_VERT, not b);
|
||
|
FHideScrolls := b;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function TfrxScrollWin.GetLongPosition(DefValue: Integer; Code: Word): Integer;
|
||
|
var
|
||
|
{$IFNDEF NONWINFPC}
|
||
|
ScrollInfo: Windows.TScrollInfo;
|
||
|
{$ELSE}
|
||
|
ScrollInfo: TScrollInfo;
|
||
|
{$ENDIF}
|
||
|
begin
|
||
|
{$IFDEF FPC}
|
||
|
FillChar(ScrollInfo, SizeOf(ScrollInfo), #0);
|
||
|
{$ENDIF}
|
||
|
ScrollInfo.cbSize := SizeOf(TScrollInfo);
|
||
|
ScrollInfo.fMask := SIF_TRACKPOS;
|
||
|
Result := DefValue;
|
||
|
{$IFDEF NONWINFPC}
|
||
|
if LCLIntf.GetScrollInfo(Handle, Code, ScrollInfo) then
|
||
|
{$ELSE}
|
||
|
if FlatSB_GetScrollInfo(Handle, Code, Windows.TScrollInfo(ScrollInfo)) then
|
||
|
{$ENDIF}
|
||
|
Result := ScrollInfo.nTrackPos;
|
||
|
end;
|
||
|
|
||
|
function TfrxScrollWin.GetScale: Single;
|
||
|
begin
|
||
|
Result := FfrCurrentPPI / frx_DefaultPPI;
|
||
|
end;
|
||
|
|
||
|
function TfrxScrollWin.GetScaledFontSize: Integer;
|
||
|
var
|
||
|
f: TFont;
|
||
|
begin
|
||
|
{ used to scale back font before saving }
|
||
|
f := TFont.Create;
|
||
|
try
|
||
|
f.Assign(Font);
|
||
|
f.Height := MulDiv(f.Height, Font.PixelsPerInch, FfrCurrentPPI);
|
||
|
Result := f.Size;
|
||
|
finally
|
||
|
f.Free;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.SetHorzPage(const Value: Integer);
|
||
|
begin
|
||
|
FHorzPage := Value;
|
||
|
HorzRange := HorzRange;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.SetHorzPosition(Value: Integer);
|
||
|
begin
|
||
|
if Assigned(FOnScrollPosChange) then
|
||
|
FOnScrollPosChange(Self, frsHorizontal, Value);
|
||
|
if Value > FHorzRange - FHorzPage then
|
||
|
Value := FHorzRange - FHorzPage;
|
||
|
if Value < 0 then
|
||
|
Value := 0;
|
||
|
if Value <> FHorzPosition then
|
||
|
begin
|
||
|
FHorzPosition := Value;
|
||
|
SetPosition(Value, SB_HORZ);
|
||
|
OnHScrollChange(Self);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.SetHorzRange(Value: Integer);
|
||
|
begin
|
||
|
if Assigned(FOnScrollMaxChange) and (Value - FHorzPage >= 0) then
|
||
|
FOnScrollMaxChange(Self, frsHorizontal, Value - FHorzPage);
|
||
|
FHorzRange := Value;
|
||
|
UpdateScrollBar(Value, HorzPage, HorzPosition, SB_HORZ);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.SetVertPage(const Value: Integer);
|
||
|
begin
|
||
|
FVertPage := Value;
|
||
|
VertRange := VertRange;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.SetVertPosition(Value: Integer);
|
||
|
begin
|
||
|
if Assigned(FOnScrollPosChange) then
|
||
|
FOnScrollPosChange(Self, frsVertical, Value);
|
||
|
if Value > FVertRange - FVertPage then
|
||
|
Value := FVertRange - FVertPage;
|
||
|
if Value < 0 then
|
||
|
Value := 0;
|
||
|
if Value <> FVertPosition then
|
||
|
begin
|
||
|
FVertPosition := Value;
|
||
|
SetPosition(Value, SB_VERT);
|
||
|
OnVScrollChange(Self);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.SetVertRange(Value: Integer);
|
||
|
begin
|
||
|
if Assigned(FOnScrollMaxChange) and (Value - FVertPage>=0) then
|
||
|
FOnScrollMaxChange(Self, frsVertical, Value - FVertPage);
|
||
|
FVertRange := Value;
|
||
|
UpdateScrollBar(Value, VertPage, VertPosition, SB_VERT);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.SetPosition(Value: Integer; Code: Word);
|
||
|
begin
|
||
|
{$IFDEF NONWINFPC}
|
||
|
LCLIntf.SetScrollPos(Handle, Code, Value, True);
|
||
|
{$ELSE}
|
||
|
FlatSB_SetScrollPos(Handle, Code, Value, True);
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.SetScaledFontSize(Value: Integer);
|
||
|
var
|
||
|
f: TFont;
|
||
|
begin
|
||
|
{ used to scale back font before saving }
|
||
|
f := TFont.Create;
|
||
|
try
|
||
|
f.Assign(Font);
|
||
|
f.Size := Value;
|
||
|
Font.Height := MulDiv(f.Height, FfrCurrentPPI, Font.PixelsPerInch);
|
||
|
finally
|
||
|
f.Free;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.UpdateScrollBar(Max, Page, Pos: Integer; Code: Word);
|
||
|
var
|
||
|
ScrollInfo:{$IFNDEF NONWINFPC}Windows.{$ENDIF}TScrollInfo;
|
||
|
begin
|
||
|
if HideScrolls then
|
||
|
Exit;
|
||
|
{$IFDEF FPC}
|
||
|
FillChar(ScrollInfo, SizeOf(ScrollInfo), #0);
|
||
|
{$ENDIF}
|
||
|
ScrollInfo.cbSize := SizeOf(ScrollInfo);
|
||
|
ScrollInfo.fMask := SIF_ALL;
|
||
|
ScrollInfo.nMin := 0;
|
||
|
if Max < Page then
|
||
|
Max := 0;
|
||
|
ScrollInfo.nMax := Max;
|
||
|
ScrollInfo.nPage := Page;
|
||
|
ScrollInfo.nPos := Pos;
|
||
|
ScrollInfo.nTrackPos := Pos;
|
||
|
{$IFDEF NONWINFPC}
|
||
|
LCLIntf.setScrollInfo(Handle, Code, ScrollInfo, True);
|
||
|
{$ELSE}
|
||
|
FlatSB_SetScrollInfo(Handle, Code, Windows.TScrollInfo(ScrollInfo), True);
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.Paint;
|
||
|
begin
|
||
|
with Canvas do
|
||
|
begin
|
||
|
Brush.Color := Color;
|
||
|
FillRect(Rect(0, 0, ClientWidth, ClientHeight));
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.WMHScroll(var Message: TWMHScroll);
|
||
|
begin
|
||
|
case Message.ScrollCode of
|
||
|
SB_LINEUP: HorzPosition := HorzPosition - FSmallChange;
|
||
|
SB_LINEDOWN: HorzPosition := HorzPosition + FSmallChange;
|
||
|
SB_PAGEUP: HorzPosition := HorzPosition - FLargeChange;
|
||
|
SB_PAGEDOWN: HorzPosition := HorzPosition + FLargeChange;
|
||
|
SB_THUMBPOSITION, SB_THUMBTRACK:
|
||
|
HorzPosition := GetLongPosition(Message.Pos, SB_HORZ);
|
||
|
SB_TOP: HorzPosition := 0;
|
||
|
SB_BOTTOM: HorzPosition := HorzRange;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.WMVScroll(var Message: TWMVScroll);
|
||
|
begin
|
||
|
case Message.ScrollCode of
|
||
|
SB_LINEUP: VertPosition := VertPosition - FSmallChange;
|
||
|
SB_LINEDOWN: VertPosition := VertPosition + FSmallChange;
|
||
|
SB_PAGEUP: VertPosition := VertPosition - FLargeChange;
|
||
|
SB_PAGEDOWN: VertPosition := VertPosition + FLargeChange;
|
||
|
SB_THUMBPOSITION, SB_THUMBTRACK:
|
||
|
VertPosition := GetLongPosition(Message.Pos, SB_VERT);
|
||
|
SB_TOP: VertPosition := 0;
|
||
|
SB_BOTTOM: VertPosition := VertRange;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.OnHScrollChange(Sender: TObject);
|
||
|
begin
|
||
|
end;
|
||
|
|
||
|
procedure TfrxScrollWin.OnVScrollChange(Sender: TObject);
|
||
|
begin
|
||
|
end;
|
||
|
|
||
|
|
||
|
{$IFDEF FPC}
|
||
|
{procedure RegisterUnitfrxCtrls;
|
||
|
begin
|
||
|
RegisterComponents('Fast Report 6',[TfrxComboBox,
|
||
|
TfrxFontComboBox, TfrxComboEdit,
|
||
|
TfrxScrollWin
|
||
|
]);
|
||
|
end;
|
||
|
|
||
|
procedure Register;
|
||
|
begin
|
||
|
RegisterUnit('frxCtrls',@RegisterUnitfrxCtrls);
|
||
|
end;}
|
||
|
{$ENDIF}
|
||
|
|
||
|
end.
|