mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
2339 lines
73 KiB
ObjectPascal
2339 lines
73 KiB
ObjectPascal
// **************************************************************************************************
|
|
//
|
|
// Unit Vcl.Styles.NC
|
|
// unit for the VCL Styles Utils
|
|
// https://github.com/RRUZ/vcl-styles-utils/
|
|
//
|
|
// The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
|
|
// you may not use this file except in compliance with the License. You may obtain a copy of the
|
|
// License at http://www.mozilla.org/MPL/
|
|
//
|
|
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
|
|
// ANY KIND, either express or implied. See the License for the specific language governing rights
|
|
// and limitations under the License.
|
|
//
|
|
// The Original Code is Vcl.Styles.NC.pas.
|
|
//
|
|
// The Initial Developer of the Original Code is Rodrigo Ruz V.
|
|
// Portions created by Rodrigo Ruz V. are Copyright (C) 2014-2021 Rodrigo Ruz V.
|
|
// All Rights Reserved.
|
|
//
|
|
// **************************************************************************************************
|
|
|
|
unit Vcl.Styles.NC;
|
|
|
|
interface
|
|
|
|
{$IF RTLVersion>=24}
|
|
{$LEGACYIFEND ON}
|
|
{$IFEND}
|
|
|
|
uses
|
|
System.Classes,
|
|
System.Generics.Collections,
|
|
System.Types,
|
|
Winapi.Windows,
|
|
Winapi.Messages,
|
|
Vcl.ImgList,
|
|
System.UITypes,
|
|
Vcl.Graphics,
|
|
Vcl.Themes,
|
|
Vcl.Styles,
|
|
Vcl.Controls,
|
|
Vcl.Menus,
|
|
Vcl.StdCtrls,
|
|
Vcl.GraphUtil,
|
|
Vcl.Forms,
|
|
Vcl.Styles.Utils.Misc;
|
|
|
|
type
|
|
TNCControl = class;
|
|
// TListNCButtons = TObjectList<TNCButton>;
|
|
TNCControls = class;
|
|
|
|
TListNCControls = class(TCollection)
|
|
private
|
|
FOwner: TNCControls;
|
|
function GetItem(Index: Integer): TNCControl;
|
|
procedure SetItem(Index: Integer; Value: TNCControl);
|
|
function Add: TNCControl;
|
|
protected
|
|
function GetOwner: TPersistent; override;
|
|
public
|
|
constructor Create(AOwner: TPersistent);
|
|
destructor Destroy; override;
|
|
function AddEx<T: TCollectionItem>: T;
|
|
function Insert(Index: Integer): TNCControl;
|
|
property Items[Index: Integer]: TNCControl read GetItem write SetItem; default;
|
|
end;
|
|
|
|
TNCControls = class(TComponent)
|
|
private
|
|
FControls: TListNCControls;
|
|
FStyleServices: TCustomStyleServices;
|
|
FVisible: Boolean;
|
|
FForm: TCustomForm;
|
|
FShowSystemMenu: Boolean;
|
|
FFormBorderSize: TRect;
|
|
FImages: TCustomImageList;
|
|
FShowCaption: Boolean;
|
|
FLastPoint: TPoint;
|
|
FActiveTabControlIndex, FHotControlIndex, FPressedControlIndex, FControlUpIndex: Integer;
|
|
function GetStyleServices: TCustomStyleServices;
|
|
procedure SetStyleServices(const Value: TCustomStyleServices);
|
|
procedure SetVisible(const Value: Boolean);
|
|
function GetControl(Index: Integer): TNCControl;
|
|
function GetCount: Integer;
|
|
procedure SetImages(const Value: TCustomImageList);
|
|
procedure SetShowSystemMenu(const Value: Boolean);
|
|
procedure SetShowCaption(const Value: Boolean);
|
|
function GetActiveTabButtonIndex: Integer;
|
|
procedure SetActiveTabButtonIndex(const Value: Integer);
|
|
property FormBorderSize: TRect read FFormBorderSize write FFormBorderSize;
|
|
property Form: TCustomForm read FForm;
|
|
protected
|
|
function GetNCControlIndex(P: TPoint): Integer;
|
|
function PointInNCControl(P: TPoint): Boolean;
|
|
property LastPoint: TPoint read FLastPoint;
|
|
public
|
|
property Controls: TListNCControls read FControls;
|
|
property ControlsList[index: Integer]: TNCControl read GetControl; default;
|
|
property ControlsCount: Integer read GetCount;
|
|
property StyleServices: TCustomStyleServices read GetStyleServices write SetStyleServices;
|
|
procedure Invalidate;
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
published
|
|
property ActiveTabButtonIndex: Integer read GetActiveTabButtonIndex write SetActiveTabButtonIndex;
|
|
property LNCControl: TListNCControls read FControls;
|
|
property Visible: Boolean read FVisible write SetVisible default True;
|
|
property Images: TCustomImageList read FImages write SetImages;
|
|
property ShowSystemMenu: Boolean read FShowSystemMenu write SetShowSystemMenu default True;
|
|
property ShowCaption: Boolean read FShowCaption write SetShowCaption default True;
|
|
end;
|
|
|
|
TNCControl = class(TCollectionItem)
|
|
private
|
|
FFont: TFont;
|
|
FEnabled: Boolean;
|
|
FWidth: Integer;
|
|
FVisible: Boolean;
|
|
FTop: Integer;
|
|
FHeight: Integer;
|
|
FLeft: Integer;
|
|
FNCControls: TNCControls;
|
|
FCaption: string;
|
|
FHint: string;
|
|
FShowHint: Boolean;
|
|
FName: TComponentName;
|
|
FTag: NativeInt;
|
|
FCaptionAligmentFlags: Cardinal;
|
|
function GetEnabled: Boolean;
|
|
procedure SetEnabled(const Value: Boolean);
|
|
function GetBoundsRect: TRect;
|
|
procedure SetBoundsRect(const Value: TRect);
|
|
procedure SetHeight(const Value: Integer);
|
|
procedure SetLeft(const Value: Integer);
|
|
procedure SetTop(const Value: Integer);
|
|
procedure SetWidth(const Value: Integer);
|
|
procedure SetVisible(const Value: Boolean);
|
|
procedure SetFont(const Value: TFont);
|
|
procedure SetShowHint(const Value: Boolean);
|
|
procedure SetName(const Value: TComponentName);
|
|
procedure DrawControl(ACanvas: TCanvas; AMouseInControl, Pressed: Boolean); virtual;
|
|
protected
|
|
procedure Handle_WMNCLButtonDown(var Message: TWMNCHitMessage); virtual;
|
|
procedure Handle_WMNCLButtonUp(var Message: TWMNCHitMessage); virtual;
|
|
procedure Handle_WMNCMouseMove(var Message: TWMNCHitMessage); virtual;
|
|
published
|
|
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); virtual;
|
|
property Left: Integer read FLeft write SetLeft;
|
|
property Top: Integer read FTop write SetTop;
|
|
property Width: Integer read FWidth write SetWidth;
|
|
property Height: Integer read FHeight write SetHeight;
|
|
property Font: TFont read FFont write SetFont;
|
|
property Enabled: Boolean read GetEnabled write SetEnabled default True;
|
|
property Visible: Boolean read FVisible write SetVisible default True;
|
|
property Hint: string read FHint write FHint;
|
|
property ShowHint: Boolean read FShowHint write SetShowHint;
|
|
property Name: TComponentName read FName write SetName stored False;
|
|
property Tag: NativeInt read FTag write FTag default 0;
|
|
property CaptionAligmentFlags: Cardinal read FCaptionAligmentFlags write FCaptionAligmentFlags;
|
|
property Caption: string read FCaption write FCaption;
|
|
function GetAs<T>: T;
|
|
public
|
|
constructor Create(Collection: TCollection); override;
|
|
destructor Destroy; override;
|
|
property NCControls: TNCControls read FNCControls;
|
|
property BoundsRect: TRect read GetBoundsRect write SetBoundsRect;
|
|
end;
|
|
|
|
TNCButton = class(TNCControl)
|
|
public type
|
|
TNCButtonStyle = (nsPushButton, nsTranparent, nsSplitButton, nsSplitTrans, nsAlpha, nsGradient, nsTab, nsEdge, nsFrame);
|
|
TNCImageStyle = (isNormal, isGray, isGrayHot);
|
|
private
|
|
FDropDown: Boolean;
|
|
FStyle: TNCButtonStyle;
|
|
FImageAlignment: TImageAlignment;
|
|
FPressedImageIndex: TImageIndex;
|
|
FDropDownMenu: TPopupMenu;
|
|
FOnDropDownClick: TNotifyEvent;
|
|
FDisabledImageIndex: TImageIndex;
|
|
FImageMargins: TImageMargins;
|
|
FImageIndex: TImageIndex;
|
|
FHotImageIndex: TImageIndex;
|
|
FImageStyle: TNCImageStyle;
|
|
FOnClick: TNotifyEvent;
|
|
FHintWindow: THintWindow;
|
|
FAlphaColor: TColor;
|
|
FAlphaHotColor: TColor;
|
|
FFontColor: TColor;
|
|
FHotFontColor: TColor;
|
|
FStartColor: TColor;
|
|
FEndColor: TColor;
|
|
FDirection: TGradientDirection;
|
|
FDefaultFontAwesomeSize: Integer;
|
|
FUseFontAwesome: Boolean;
|
|
FAwesomeHotFontColor: TColor;
|
|
FAwesomeFontColor: TColor;
|
|
FOnClose: TNotifyEvent;
|
|
procedure DrawControl(ACanvas: TCanvas; AMouseInControl, Pressed: Boolean); override;
|
|
procedure SetStyle(const Value: TNCButtonStyle);
|
|
procedure SetDisabledImageIndex(const Value: TImageIndex);
|
|
procedure SetDropDownMenu(const Value: TPopupMenu);
|
|
procedure SetHotImageIndex(const Value: TImageIndex);
|
|
procedure SetImageAlignment(const Value: TImageAlignment);
|
|
procedure SetImageIndex(const Value: TImageIndex);
|
|
procedure SetImageMargins(const Value: TImageMargins);
|
|
procedure SetPressedImageIndex(const Value: TImageIndex);
|
|
procedure DrawControlText(Canvas: TCanvas; Details: TThemedElementDetails; const S: string; var R: TRect;
|
|
Flags: Cardinal; AColor: TColor = clNone);
|
|
procedure SetImageStyle(const Value: TNCImageStyle);
|
|
procedure ShowHintWindow(X, Y: Integer);
|
|
procedure HideHintWindow;
|
|
function GetTabIndex: Integer;
|
|
procedure SetUseFontAwesome(const Value: Boolean);
|
|
protected
|
|
procedure Handle_WMNCLButtonDown(var Message: TWMNCHitMessage); override;
|
|
procedure Handle_WMNCLButtonUp(var Message: TWMNCHitMessage); override;
|
|
procedure Handle_WMNCMouseMove(var Message: TWMNCHitMessage); override;
|
|
public
|
|
constructor Create(Collection: TCollection); override;
|
|
destructor Destroy; override;
|
|
property TabIndex: Integer read GetTabIndex;
|
|
published
|
|
property Style: TNCButtonStyle read FStyle write SetStyle;
|
|
property ImageStyle: TNCImageStyle read FImageStyle write SetImageStyle;
|
|
property DisabledImageIndex: TImageIndex read FDisabledImageIndex write SetDisabledImageIndex;
|
|
property DropDownMenu: TPopupMenu read FDropDownMenu write SetDropDownMenu;
|
|
property HotImageIndex: TImageIndex read FHotImageIndex write SetHotImageIndex;
|
|
property ImageAlignment: TImageAlignment read FImageAlignment write SetImageAlignment;
|
|
property ImageIndex: TImageIndex read FImageIndex write SetImageIndex;
|
|
property ImageMargins: TImageMargins read FImageMargins write SetImageMargins;
|
|
property PressedImageIndex: TImageIndex read FPressedImageIndex write SetPressedImageIndex;
|
|
|
|
property AlphaColor: TColor read FAlphaColor write FAlphaColor;
|
|
property AlphaHotColor: TColor read FAlphaHotColor write FAlphaHotColor;
|
|
property FontColor: TColor read FFontColor write FFontColor;
|
|
property HotFontColor: TColor read FHotFontColor write FHotFontColor;
|
|
|
|
property StartColor: TColor read FStartColor write FStartColor;
|
|
property EndColor: TColor read FEndColor write FEndColor;
|
|
property Direction: TGradientDirection read FDirection write FDirection;
|
|
|
|
property UseFontAwesome: Boolean read FUseFontAwesome write SetUseFontAwesome;
|
|
property DefaultFontAwesomeSize: Integer read FDefaultFontAwesomeSize write FDefaultFontAwesomeSize;
|
|
property AwesomeFontColor: TColor read FAwesomeFontColor write FAwesomeFontColor;
|
|
property AwesomeHotFontColor: TColor read FAwesomeHotFontColor write FAwesomeHotFontColor;
|
|
property OnDropDownClick: TNotifyEvent read FOnDropDownClick write FOnDropDownClick;
|
|
property OnClick: TNotifyEvent read FOnClick write FOnClick;
|
|
property OnClose: TNotifyEvent read FOnClose write FOnClose;
|
|
end;
|
|
|
|
TFormStyleNCControls = class(TFormStyleHook)
|
|
strict private
|
|
FNCControls: TNCControls;
|
|
private
|
|
function GetNCControls: TNCControls;
|
|
protected
|
|
procedure WMNCMouseMove(var Message: TWMNCHitMessage); message WM_NCMOUSEMOVE;
|
|
procedure WMNCLButtonDown(var Message: TWMNCHitMessage); message WM_NCLBUTTONDOWN;
|
|
procedure WMNCLButtonUp(var Message: TWMNCHitMessage); message WM_NCLBUTTONUP;
|
|
procedure WMNCLButtonDblClk(var Message: TWMNCHitMessage); message WM_NCLBUTTONDBLCLK;
|
|
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
|
|
procedure PaintNCControls(Canvas: TCanvas; ARect: TRect);
|
|
procedure PaintNC(Canvas: TCanvas); override;
|
|
strict protected
|
|
procedure MouseLeave; override;
|
|
procedure MouseEnter; override;
|
|
procedure Restore; override;
|
|
procedure Maximize; override;
|
|
procedure Minimize; override;
|
|
public
|
|
property NCControls: TNCControls read GetNCControls;
|
|
constructor Create(AControl: TWinControl); override;
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
TFormStyleNCSettings = class
|
|
private
|
|
class var FUseThinBorder: Boolean;
|
|
public
|
|
class property UseThinBorder: Boolean read FUseThinBorder write FUseThinBorder;
|
|
end;
|
|
|
|
{
|
|
TODO
|
|
Add more buttons styles (colors, gradient, glow, link)
|
|
Add hot effects (glow, menu sel)
|
|
Add support for TAction
|
|
}
|
|
|
|
implementation
|
|
|
|
uses
|
|
DDetours,
|
|
Winapi.CommCtrl,
|
|
System.SysUtils,
|
|
System.Rtti,
|
|
Winapi.UxTheme,
|
|
Vcl.Styles.Utils.Graphics,
|
|
Vcl.Styles.FontAwesome,
|
|
Vcl.Styles.FormStyleHooks;
|
|
|
|
type
|
|
THintWindowClass = class(THintWindow);
|
|
TCustomFormClass = class(TCustomForm);
|
|
TFormStyleHookClass = class(TFormStyleHook);
|
|
TStyleHookList = TList<TStyleHookClass>;
|
|
|
|
TStyleHookDictionary = TDictionary<TClass, TStyleHookList>;
|
|
|
|
TCustomStyleEngineHelper = Class Helper for TCustomStyleEngine
|
|
public
|
|
class function GetRegisteredStyleHooks: TStyleHookDictionary;
|
|
end;
|
|
|
|
var
|
|
Trampoline_TFormStyleHook_GetBorderSize: function(Self: TFormStyleHook): TRect;
|
|
Trampoline_TFormStyleHook_GetRegion: function(Self: TFormStyleHook): HRgn;
|
|
|
|
class function TCustomStyleEngineHelper.GetRegisteredStyleHooks: TStyleHookDictionary;
|
|
begin
|
|
with Self do
|
|
Result := FRegisteredStyleHooks;
|
|
end;
|
|
|
|
function IsStyleHookRegistered(ControlClass: TClass; StyleHookClass: TStyleHookClass): Boolean;
|
|
var
|
|
List: TStyleHookList;
|
|
begin
|
|
Result := False;
|
|
if TCustomStyleEngine.GetRegisteredStyleHooks.ContainsKey(ControlClass) then
|
|
begin
|
|
List := TCustomStyleEngine.GetRegisteredStyleHooks[ControlClass];
|
|
Result := List.IndexOf(StyleHookClass) <> -1;
|
|
end;
|
|
end;
|
|
|
|
function GetRegisteredStylesHooks(ControlClass: TClass): TStyleHookList;
|
|
begin
|
|
Result := nil;
|
|
if TCustomStyleEngine.GetRegisteredStyleHooks.ContainsKey(ControlClass) then
|
|
Result := TCustomStyleEngine.GetRegisteredStyleHooks[ControlClass];
|
|
end;
|
|
|
|
{ TNCControls }
|
|
|
|
constructor TNCControls.Create(AOwner: TComponent);
|
|
begin
|
|
if not(AOwner is TCustomForm) then
|
|
Raise EAbort.Create('TNCControls only must be created in forms');
|
|
inherited Create(AOwner);
|
|
FForm := TCustomForm(AOwner);
|
|
FControls := TListNCControls.Create(Self);
|
|
|
|
FHotControlIndex := -1;
|
|
FControlUpIndex := -1;
|
|
FPressedControlIndex := -1;
|
|
|
|
FStyleServices := nil;
|
|
FImages := nil;
|
|
FVisible := True;
|
|
FShowCaption := True;
|
|
FShowSystemMenu := True;
|
|
if not IsStyleHookRegistered(AOwner.ClassType, TFormStyleNCControls) then
|
|
TStyleManager.Engine.RegisterStyleHook(AOwner.ClassType, TFormStyleNCControls);
|
|
FForm.Perform(CM_RECREATEWND, 0, 0);
|
|
FActiveTabControlIndex := 0;
|
|
end;
|
|
|
|
destructor TNCControls.Destroy;
|
|
begin
|
|
FControls.Free;
|
|
inherited;
|
|
end;
|
|
|
|
function TNCControls.GetActiveTabButtonIndex: Integer;
|
|
begin
|
|
Result := FActiveTabControlIndex;
|
|
end;
|
|
|
|
function TNCControls.GetControl(Index: Integer): TNCControl;
|
|
begin
|
|
Result := FControls[Index];
|
|
end;
|
|
|
|
function TNCControls.GetCount: Integer;
|
|
begin
|
|
Result := FControls.Count;
|
|
end;
|
|
|
|
function TNCControls.GetStyleServices: TCustomStyleServices;
|
|
begin
|
|
Result := FStyleServices;
|
|
if (Result = nil) then
|
|
Result := Vcl.Themes.StyleServices;
|
|
end;
|
|
|
|
procedure TNCControls.Invalidate;
|
|
begin
|
|
if FForm.HandleAllocated then
|
|
SendMessage(FForm.Handle, WM_NCPAINT, 0, 0);
|
|
end;
|
|
|
|
procedure TNCControls.SetActiveTabButtonIndex(const Value: Integer);
|
|
|
|
// Refactor This -> TNCButton can't be called from here
|
|
function GetMaxTabIndex: Integer;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := -1;
|
|
For i := 0 to (FControls.Count - 1) do
|
|
if (FControls[i] is TNCButton) and (FControls[i].GetAs<TNCButton>.Style = nsTab) then
|
|
Inc(Result);
|
|
end;
|
|
|
|
var
|
|
lmax: Integer;
|
|
begin
|
|
lmax := GetMaxTabIndex;
|
|
if (Value <> FActiveTabControlIndex) and (Value >= 0) and (lmax >= 0) and (Value <= lmax) then
|
|
begin
|
|
FActiveTabControlIndex := Value;
|
|
Invalidate;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TNCControls.SetImages(const Value: TCustomImageList);
|
|
begin
|
|
FImages := Value;
|
|
end;
|
|
|
|
procedure TNCControls.SetShowCaption(const Value: Boolean);
|
|
begin
|
|
if Value <> FShowCaption then
|
|
begin
|
|
FShowCaption := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TNCControls.SetShowSystemMenu(const Value: Boolean);
|
|
begin
|
|
if Value <> FShowSystemMenu then
|
|
begin
|
|
FShowSystemMenu := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TNCControls.SetStyleServices(const Value: TCustomStyleServices);
|
|
begin
|
|
if Value <> FStyleServices then
|
|
begin
|
|
FStyleServices := Value;
|
|
if IsWindowVisible(TCustomFormClass(FForm).Handle) then
|
|
PostMessage(TCustomFormClass(FForm).Handle, CM_CUSTOMSTYLECHANGED, 0, 0)
|
|
else
|
|
SendMessage(TCustomFormClass(FForm).Handle, CM_CUSTOMSTYLECHANGED, 0, 0);
|
|
end;
|
|
end;
|
|
|
|
procedure TNCControls.SetVisible(const Value: Boolean);
|
|
begin
|
|
if Value <> FVisible then
|
|
begin
|
|
FVisible := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
function TNCControls.GetNCControlIndex(P: TPoint): Integer;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := -1;
|
|
for i := 0 to FControls.Count - 1 do
|
|
if FControls[i].Visible and PtInRect(FControls[i].BoundsRect, P) then
|
|
Exit(i);
|
|
end;
|
|
|
|
function TNCControls.PointInNCControl(P: TPoint): Boolean;
|
|
begin
|
|
Result := GetNCControlIndex(P) >= 0;
|
|
end;
|
|
|
|
{ TNCButton }
|
|
|
|
constructor TNCButton.Create(Collection: TCollection);
|
|
begin
|
|
inherited Create(Collection);
|
|
FDropDown := False;
|
|
FImageMargins := TImageMargins.Create;
|
|
FDisabledImageIndex := -1;
|
|
FPressedImageIndex := -1;
|
|
FImageIndex := -1;
|
|
FUseFontAwesome := False;
|
|
FDefaultFontAwesomeSize := 16; // 16
|
|
FHotImageIndex := -1;
|
|
FImageAlignment := iaLeft;
|
|
FStyle := nsPushButton;
|
|
FImageStyle := isNormal;
|
|
FDropDownMenu := nil;
|
|
FOnDropDownClick := nil;
|
|
FOnClick := nil;
|
|
FOnClose := nil;
|
|
FHintWindow := THintWindow.Create(nil);
|
|
FAlphaColor := FNCControls.StyleServices.GetSystemColor(clBtnFace);
|
|
FDirection := TGradientDirection.gdHorizontal;
|
|
|
|
FFontColor := StyleServices.GetSystemColor(clBtnText);
|
|
FHotFontColor := StyleServices.GetSystemColor(clHighlight);
|
|
|
|
FAwesomeFontColor := StyleServices.GetSystemColor(clBtnText);
|
|
FAwesomeHotFontColor := StyleServices.GetSystemColor(clHighlight);
|
|
end;
|
|
|
|
destructor TNCButton.Destroy;
|
|
begin
|
|
FreeAndNil(FHintWindow);
|
|
FreeAndNil(FImageMargins);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TNCButton.DrawControlText(Canvas: TCanvas; Details: TThemedElementDetails; const S: string; var R: TRect;
|
|
Flags: Cardinal; AColor: TColor = clNone);
|
|
var
|
|
ThemeTextColor: TColor;
|
|
TextFormat: TTextFormatFlags;
|
|
LStyleServices: TCustomStyleServices;
|
|
begin
|
|
Canvas.Font := Font;
|
|
LStyleServices := NCControls.StyleServices;
|
|
TextFormat := TTextFormatFlags(Flags);
|
|
if LStyleServices.GetElementColor(Details, ecTextColor, ThemeTextColor) then
|
|
begin
|
|
if AColor <> clNone then
|
|
Canvas.Font.Color := AColor
|
|
else
|
|
Canvas.Font.Color := ThemeTextColor;
|
|
LStyleServices.DrawText(Canvas.Handle, Details, S, R, TextFormat, Canvas.Font.Color);
|
|
end
|
|
else
|
|
begin
|
|
Canvas.Refresh;
|
|
LStyleServices.DrawText(Canvas.Handle, Details, S, R, TextFormat);
|
|
end;
|
|
end;
|
|
|
|
function TNCButton.GetTabIndex: Integer;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := -1;
|
|
for i := 0 to NCControls.ControlsCount - 1 do
|
|
if NCControls.LNCControl[i] is TNCButton then
|
|
begin
|
|
if NCControls.LNCControl[i].GetAs<TNCButton>.Style = nsTab then
|
|
Inc(Result);
|
|
|
|
if NCControls[i] = Self then
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
procedure DoDrawGrayImage(hdcDst: HDC; himl: HIMAGELIST; ImageIndex, X, Y: Integer);
|
|
var
|
|
pimldp: TImageListDrawParams;
|
|
begin
|
|
FillChar(pimldp, SizeOf(pimldp), #0);
|
|
pimldp.fState := ILS_SATURATE;
|
|
pimldp.cbSize := SizeOf(pimldp);
|
|
pimldp.hdcDst := hdcDst;
|
|
pimldp.himl := himl;
|
|
pimldp.i := ImageIndex;
|
|
pimldp.X := X;
|
|
pimldp.Y := Y;
|
|
ImageList_DrawIndirect(@pimldp);
|
|
end;
|
|
|
|
procedure FrameRect(ACanvas: TCanvas; const R: TRect; Color1, Color2: TColor);
|
|
begin
|
|
with ACanvas do
|
|
begin
|
|
Pen.Color := Color1;
|
|
PolyLine([Point(R.Left, R.Bottom), Point(R.Left, R.Top), Point(R.Right, R.Top)]);
|
|
Pen.Color := Color2;
|
|
PolyLine([Point(R.Right, R.Top), Point(R.Right, R.Bottom), Point(R.Left, R.Bottom)]);
|
|
end;
|
|
end;
|
|
|
|
procedure TNCButton.Handle_WMNCLButtonDown(var Message: TWMNCHitMessage);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
// process click on buttton with the nstab style
|
|
if (FNCControls.FPressedControlIndex >= 0) and (FNCControls[FNCControls.FPressedControlIndex] is TNCButton) and
|
|
(FNCControls[FNCControls.FPressedControlIndex].GetAs<TNCButton>.Style = nsTab) then
|
|
begin
|
|
FNCControls.FActiveTabControlIndex := -1;
|
|
For i := 0 to FNCControls.FPressedControlIndex do
|
|
if (FNCControls[i] is TNCButton) and (FNCControls[i].GetAs<TNCButton>.Style = nsTab) then
|
|
Inc(FNCControls.FActiveTabControlIndex);
|
|
end;
|
|
end;
|
|
|
|
procedure TNCButton.Handle_WMNCLButtonUp(var Message: TWMNCHitMessage);
|
|
var
|
|
LNCButtton: TNCButton;
|
|
LRect: TRect;
|
|
P: TPoint;
|
|
i, X, Y: Integer;
|
|
begin
|
|
i := FNCControls.FControlUpIndex;
|
|
|
|
if ((Message.HitTest = HTTOP) or (Message.HitTest = HTCAPTION)) and (i >= 0) and
|
|
(NCControls.LNCControl[i] is TNCButton) then
|
|
begin
|
|
LRect := Rect(0, 0, 0, 0);
|
|
if (NCControls <> nil) then
|
|
begin
|
|
LRect := NCControls.LNCControl[i].BoundsRect;
|
|
LRect.Left := LRect.Right - 15;
|
|
end;
|
|
|
|
P := NCControls.LastPoint;
|
|
|
|
LNCButtton := NCControls.LNCControl[i].GetAs<TNCButton>;
|
|
|
|
if (LNCButtton.Enabled) and Assigned(LNCButtton.FOnDropDownClick) and
|
|
(LNCButtton.Style in [nsSplitButton, nsSplitTrans]) and PtInRect(LRect, P) then
|
|
LNCButtton.FOnDropDownClick(LNCButtton)
|
|
else if (LNCButtton.Enabled) and Assigned(LNCButtton.FDropDownMenu) and PtInRect(LRect, P) then
|
|
begin
|
|
X := NCControls.Form.Left + LNCButtton.BoundsRect.Left;
|
|
if NCControls.Form.BiDiMode = TBiDiMode.bdRightToLeft then
|
|
Inc(X, 250);
|
|
|
|
Y := NCControls.Form.Top + LNCButtton.BoundsRect.Bottom;
|
|
// OutputDebugString(PChar(Format('Popup X %d Y %d', [X, Y])));
|
|
|
|
LNCButtton.FDropDownMenu.Popup(X, Y);
|
|
// if LNCButtton.FDropDownMenu.BiDiMode = bdLeftToRight then
|
|
// LNCButtton.FDropDownMenu.Popup(X, Y)
|
|
// else
|
|
// begin
|
|
// LPoint := Point(X, Y);
|
|
// TrackPopupMenu(LNCButtton.FDropDownMenu.Handle, TPM_RIGHTALIGN or TPM_TOPALIGN, LPoint.X, LPoint.Y, 0, PopupList.Window, nil);
|
|
// end;
|
|
end
|
|
else if (LNCButtton.Style = nsTab) and Assigned(LNCButtton.FOnClose) and PtInRect(LRect, P) then
|
|
begin
|
|
if LNCButtton.ShowHint then
|
|
LNCButtton.HideHintWindow();
|
|
|
|
if not IsIconic(TCustomFormClass(NCControls.Form).Handle) then
|
|
LNCButtton.FOnClose(LNCButtton);
|
|
end
|
|
else if (LNCButtton.Enabled) and Assigned(LNCButtton.FOnClick) then
|
|
begin
|
|
if LNCButtton.ShowHint then
|
|
LNCButtton.HideHintWindow();
|
|
|
|
if not IsIconic(TCustomFormClass(NCControls.Form).Handle) then
|
|
LNCButtton.FOnClick(LNCButtton);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TNCButton.Handle_WMNCMouseMove(var Message: TWMNCHitMessage);
|
|
var
|
|
P: TPoint;
|
|
i: Integer;
|
|
begin
|
|
P := NCControls.LastPoint;
|
|
|
|
if ((Message.HitTest = HTTOP) or (Message.HitTest = HTCAPTION) or (not NCControls.ShowSystemMenu and
|
|
(Message.HitTest = HTSYSMENU))) and NCControls.PointInNCControl(P) then
|
|
begin
|
|
|
|
if NCControls.FHotControlIndex <> NCControls.GetNCControlIndex(P) then
|
|
begin
|
|
NCControls.FHotControlIndex := NCControls.GetNCControlIndex(P);
|
|
|
|
for i := 0 to NCControls.ControlsCount - 1 do
|
|
if (NCControls.FHotControlIndex <> i) and NCControls.LNCControl[i].ShowHint and
|
|
(NCControls.LNCControl[i] is TNCButton) then
|
|
NCControls.LNCControl[i].GetAs<TNCButton>.HideHintWindow();
|
|
|
|
if not IsIconic(TCustomFormClass(NCControls.Form).Handle) then
|
|
if NCControls.LNCControl[NCControls.FHotControlIndex].ShowHint and
|
|
(NCControls.LNCControl[NCControls.FHotControlIndex] is TNCButton) then
|
|
NCControls.LNCControl[NCControls.FHotControlIndex].GetAs<TNCButton>.ShowHintWindow(Message.XCursor,
|
|
Message.YCursor);
|
|
|
|
NCControls.Invalidate();
|
|
end;
|
|
end
|
|
else
|
|
// if NCControls.FHotControlIndex <> -1 then
|
|
begin
|
|
for i := 0 to NCControls.ControlsCount - 1 do
|
|
if NCControls.LNCControl[i].ShowHint and (NCControls.LNCControl[i] is TNCButton) then
|
|
NCControls.LNCControl[i].GetAs<TNCButton>.HideHintWindow();
|
|
|
|
NCControls.FHotControlIndex := -1;
|
|
NCControls.Invalidate();
|
|
// OutputDebugString(PChar('Ping '+FormatDateTime('hh:nn:ss.zzz', Now)));
|
|
end;
|
|
end;
|
|
|
|
procedure TNCButton.DrawControl(ACanvas: TCanvas; AMouseInControl, Pressed: Boolean);
|
|
var
|
|
Details, Details2: TThemedElementDetails;
|
|
ButtonRect, DrawRect, LRect, LRectAwesome: TRect;
|
|
IW, IH, IX, IY: Integer;
|
|
SaveIndex: Integer;
|
|
X, Y, i, LImgIndex: Integer;
|
|
BCaption: String;
|
|
LStyleServices: TCustomStyleServices;
|
|
LColor, LColor1, LColor2, ThemeTextColor: TColor;
|
|
FButtonState: TThemedWindow;
|
|
|
|
function GetBorderSize: TRect;
|
|
var
|
|
Size: TSize;
|
|
Details: TThemedElementDetails;
|
|
Detail: TThemedWindow;
|
|
begin
|
|
Result := Rect(0, 0, 0, 0);
|
|
if NCControls.Form.BorderStyle = bsNone then
|
|
Exit;
|
|
|
|
if not LStyleServices.Available then
|
|
Exit;
|
|
{ caption height }
|
|
if (NCControls.Form.BorderStyle <> bsToolWindow) and (NCControls.Form.BorderStyle <> bsSizeToolWin) then
|
|
Detail := twCaptionActive
|
|
else
|
|
Detail := twSmallCaptionActive;
|
|
Details := LStyleServices.GetElementDetails(Detail);
|
|
LStyleServices.GetElementSize(0, Details, esActual, Size);
|
|
Result.Top := Size.cy;
|
|
{ left border width }
|
|
if (NCControls.Form.BorderStyle <> bsToolWindow) and (NCControls.Form.BorderStyle <> bsSizeToolWin) then
|
|
Detail := twFrameLeftActive
|
|
else
|
|
Detail := twSmallFrameLeftActive;
|
|
Details := LStyleServices.GetElementDetails(Detail);
|
|
LStyleServices.GetElementSize(0, Details, esActual, Size);
|
|
Result.Left := Size.cx;
|
|
{ right border width }
|
|
if (NCControls.Form.BorderStyle <> bsToolWindow) and (NCControls.Form.BorderStyle <> bsSizeToolWin) then
|
|
Detail := twFrameRightActive
|
|
else
|
|
Detail := twSmallFrameRightActive;
|
|
Details := LStyleServices.GetElementDetails(Detail);
|
|
LStyleServices.GetElementSize(0, Details, esActual, Size);
|
|
Result.Right := Size.cx;
|
|
{ bottom border height }
|
|
if (FNCControls.Form.BorderStyle <> bsToolWindow) and (NCControls.Form.BorderStyle <> bsSizeToolWin) then
|
|
Detail := twFrameBottomActive
|
|
else
|
|
Detail := twSmallFrameBottomActive;
|
|
Details := LStyleServices.GetElementDetails(Detail);
|
|
LStyleServices.GetElementSize(0, Details, esActual, Size);
|
|
Result.Bottom := Size.cy;
|
|
end;
|
|
|
|
function GetTopOffset: Integer;
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
P.X := NCControls.Form.Left + NCControls.Form.Width div 2;
|
|
P.Y := NCControls.Form.Top + NCControls.Form.Height div 2;
|
|
Result := Screen.MonitorFromPoint(P).WorkareaRect.Top;
|
|
if NCControls.Form.Top < Result then
|
|
Result := Result - NCControls.Form.Top
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure CorrectRightButtonRect(var AButtonRect: TRect);
|
|
var
|
|
TopOffset, RightOffset: Integer;
|
|
BS: TRect;
|
|
begin
|
|
if (NCControls.Form.WindowState = wsMaximized) and (TCustomFormClass(NCControls.Form).FormStyle <> fsMDIChild) and
|
|
(ButtonRect.Width > 0) then
|
|
begin
|
|
BS := GetBorderSize;
|
|
TopOffset := GetTopOffset;
|
|
RightOffset := -BS.Right;
|
|
if ButtonRect.Top < TopOffset then
|
|
begin
|
|
TopOffset := TopOffset - ButtonRect.Top;
|
|
OffsetRect(ButtonRect, RightOffset, TopOffset);
|
|
TopOffset := ButtonRect.Bottom - BS.Top;
|
|
if TopOffset > 0 then
|
|
OffsetRect(ButtonRect, 0, -TopOffset);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure CorrectLeftButtonRect(var AButtonRect: TRect);
|
|
var
|
|
TopOffset, LeftOffset: Integer;
|
|
BS: TRect;
|
|
begin
|
|
if (NCControls.Form.WindowState = wsMaximized) and (TCustomFormClass(NCControls.Form).FormStyle <> fsMDIChild) and
|
|
(ButtonRect.Width > 0) then
|
|
begin
|
|
BS := GetBorderSize;
|
|
TopOffset := GetTopOffset;
|
|
LeftOffset := BS.Left;
|
|
if ButtonRect.Top < TopOffset then
|
|
begin
|
|
TopOffset := TopOffset - ButtonRect.Top;
|
|
OffsetRect(ButtonRect, LeftOffset, TopOffset);
|
|
TopOffset := ButtonRect.Bottom - BS.Top;
|
|
if TopOffset > 0 then
|
|
OffsetRect(ButtonRect, 0, -TopOffset);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function GetButtonCloseRect(Index: Integer): TRect;
|
|
var
|
|
Details: TThemedElementDetails;
|
|
R, ButtonR: TRect;
|
|
begin
|
|
R := BoundsRect;
|
|
if R.Left < 0 then
|
|
Exit;
|
|
|
|
if Index = TabIndex then
|
|
InflateRect(R, 0, 2);
|
|
|
|
Result := R;
|
|
Details := LStyleServices.GetElementDetails(twSmallCloseButtonNormal);
|
|
if not LStyleServices.GetElementContentRect(0, Details, Result, ButtonR) then
|
|
ButtonR := Rect(0, 0, 0, 0);
|
|
|
|
Result.Left := Result.Right - (ButtonR.Width) - 3;
|
|
Result.Width := ButtonR.Width;
|
|
Result.Top := Result.Top + 3;
|
|
end;
|
|
|
|
begin
|
|
|
|
LStyleServices := NCControls.StyleServices;
|
|
BCaption := FCaption;
|
|
LImgIndex := FImageIndex;
|
|
if not Enabled then
|
|
begin
|
|
Details := LStyleServices.GetElementDetails(tbPushButtonDisabled);
|
|
if DisabledImageIndex <> -1 then
|
|
LImgIndex := FDisabledImageIndex;
|
|
end
|
|
else if Pressed then
|
|
begin
|
|
Details := LStyleServices.GetElementDetails(tbPushButtonPressed);
|
|
if PressedImageIndex <> -1 then
|
|
LImgIndex := FPressedImageIndex;
|
|
end
|
|
else if AMouseInControl then
|
|
begin
|
|
Details := LStyleServices.GetElementDetails(tbPushButtonHot);
|
|
if HotImageIndex <> -1 then
|
|
LImgIndex := FHotImageIndex;
|
|
end
|
|
else if Enabled then
|
|
Details := LStyleServices.GetElementDetails(tbPushButtonNormal);
|
|
|
|
DrawRect := BoundsRect; // ClientRect;
|
|
|
|
if FStyle = nsTab then
|
|
if (NCControls.Form.WindowState = wsMaximized) and (TCustomFormClass(NCControls.Form).FormStyle <> fsMDIChild) then
|
|
else
|
|
DrawRect.Height := NCControls.FormBorderSize.Top - DrawRect.Top;
|
|
|
|
if FStyle = nsAlpha then
|
|
begin
|
|
LColor := ACanvas.Pen.Color;
|
|
try
|
|
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23}
|
|
if not StyleServices.HasElementFixedPosition(Details) then
|
|
{$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
DrawRect := ButtonRect;
|
|
|
|
ACanvas.Pen.Color := clNone;
|
|
|
|
if (AMouseInControl) and (FAlphaHotColor <> clNone) then
|
|
begin
|
|
LRect := DrawRect;
|
|
InflateRect(LRect, -1, -1);
|
|
AlphaBlendFillCanvas(ACanvas.Handle, FAlphaHotColor, LRect, 96);
|
|
ACanvas.Pen.Color := FAlphaHotColor;
|
|
end
|
|
else if FAlphaColor <> clNone then
|
|
begin
|
|
LRect := DrawRect;
|
|
InflateRect(LRect, -1, -1);
|
|
AlphaBlendFillCanvas(ACanvas.Handle, FAlphaColor, LRect, 96);
|
|
ACanvas.Pen.Color := FAlphaColor;
|
|
end;
|
|
|
|
if ACanvas.Pen.Color <> clNone then
|
|
begin
|
|
LRect := DrawRect;
|
|
ACanvas.Brush.Style := bsSolid;
|
|
ACanvas.Rectangle(LRect.Left, LRect.Top, LRect.Left + LRect.Width, LRect.Top + LRect.Height);
|
|
end;
|
|
finally
|
|
ACanvas.Pen.Color := LColor;
|
|
end;
|
|
end
|
|
else if FStyle = nsGradient then
|
|
begin
|
|
LColor := ACanvas.Pen.Color;
|
|
try
|
|
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
DrawRect := ButtonRect;
|
|
|
|
if AMouseInControl then
|
|
GradientFillCanvas(ACanvas, FEndColor, FStartColor, DrawRect, FDirection)
|
|
else
|
|
GradientFillCanvas(ACanvas, FStartColor, FEndColor, DrawRect, FDirection);
|
|
|
|
if AMouseInControl then
|
|
ACanvas.Pen.Color := FEndColor
|
|
else
|
|
ACanvas.Pen.Color := FStartColor;
|
|
|
|
ACanvas.Brush.Style := bsClear;
|
|
|
|
LRect := DrawRect;
|
|
ACanvas.Rectangle(LRect.Left, LRect.Top, LRect.Left + LRect.Width, LRect.Top + LRect.Height);
|
|
finally
|
|
ACanvas.Pen.Color := LColor;
|
|
end;
|
|
end
|
|
else if FStyle = nsTab then
|
|
begin
|
|
// if AMouseInControl then
|
|
// Details := LStyleServices.GetElementDetails(ttTabItemHot)
|
|
// else
|
|
if Pressed or (NCControls.FActiveTabControlIndex = TabIndex) then
|
|
Details := LStyleServices.GetElementDetails(ttTabItemSelected)
|
|
else if not Enabled then
|
|
Details := LStyleServices.GetElementDetails(ttTabItemDisabled)
|
|
else
|
|
Details := LStyleServices.GetElementDetails(ttTabItemNormal);
|
|
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
DrawRect := ButtonRect;
|
|
|
|
LStyleServices.DrawElement(ACanvas.Handle, Details, DrawRect);
|
|
|
|
if @FOnClose <> nil then
|
|
begin
|
|
if AMouseInControl then
|
|
FButtonState := twSmallCloseButtonHot
|
|
else if Index = TabIndex then
|
|
FButtonState := twSmallCloseButtonNormal
|
|
else
|
|
FButtonState := twSmallCloseButtonDisabled;
|
|
|
|
Details2 := LStyleServices.GetElementDetails(FButtonState);
|
|
LRect := GetButtonCloseRect(Index);
|
|
if LRect.Bottom - LRect.Top > 0 then
|
|
LStyleServices.DrawElement(ACanvas.Handle, Details2, LRect);
|
|
end;
|
|
end
|
|
else if FStyle = nsEdge then
|
|
begin
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
DrawRect := ButtonRect;
|
|
|
|
LStyleServices.DrawElement(ACanvas.Handle, LStyleServices.GetElementDetails(tbGroupBoxNormal), DrawRect);
|
|
end
|
|
else if FStyle = nsFrame then
|
|
begin
|
|
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
DrawRect := ButtonRect;
|
|
|
|
LColor1 := LStyleServices.GetSystemColor(clBtnShadow);
|
|
LColor2 := LStyleServices.GetSystemColor(clBtnHighlight);
|
|
|
|
LColor := LColor1;
|
|
LColor1 := LColor2;
|
|
with DrawRect do
|
|
FrameRect(ACanvas, Rect(Left + 1, Top + 1, Left + Width - 1, Top + Height - 1), LColor1, LColor2);
|
|
|
|
LColor2 := LColor;
|
|
LColor1 := LColor;
|
|
with DrawRect do
|
|
FrameRect(ACanvas, Rect(Left + 0, Top + 0, Left + Width - 2, Top + Height - 2), LColor1, LColor2);
|
|
|
|
end
|
|
else if Enabled and (FStyle in [ { nsTranparent, } nsSplitTrans]) and AMouseInControl then
|
|
begin
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
DrawRect := ButtonRect;
|
|
|
|
Details := LStyleServices.GetElementDetails(tmMenuBarItemHot);
|
|
LStyleServices.DrawElement(ACanvas.Handle, Details, DrawRect);
|
|
end
|
|
else if (FStyle <> nsTranparent) and (FStyle <> nsSplitTrans) then
|
|
begin
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
DrawRect := ButtonRect;
|
|
|
|
LStyleServices.DrawElement(ACanvas.Handle, Details, DrawRect);
|
|
end;
|
|
|
|
if FUseFontAwesome and (LImgIndex >= 0) then
|
|
begin
|
|
|
|
IW := FDefaultFontAwesomeSize;
|
|
IH := FDefaultFontAwesomeSize;
|
|
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
|
|
DrawRect := ButtonRect;
|
|
|
|
if FStyle = nsSplitButton then
|
|
IX := DrawRect.Left + ((DrawRect.Width - 15) - IW) div 2
|
|
else
|
|
IX := DrawRect.Left + (DrawRect.Width - IW) div 2;
|
|
|
|
IY := DrawRect.Top + (DrawRect.Height - IH) div 2;
|
|
|
|
case FImageAlignment of
|
|
iaLeft:
|
|
begin
|
|
IX := DrawRect.Left + 2;
|
|
Inc(IX, ImageMargins.Left);
|
|
Inc(IY, ImageMargins.Top);
|
|
Dec(IY, ImageMargins.Bottom);
|
|
Inc(DrawRect.Left, { IX + } IW + ImageMargins.Right);
|
|
end;
|
|
|
|
iaRight:
|
|
begin
|
|
IX := DrawRect.Right - IW - 2;
|
|
Dec(IX, ImageMargins.Right);
|
|
Dec(IX, ImageMargins.Left);
|
|
Inc(IY, ImageMargins.Top);
|
|
Dec(IY, ImageMargins.Bottom);
|
|
DrawRect.Right := IX;
|
|
end;
|
|
|
|
iaTop:
|
|
begin
|
|
IX := { DrawRect.Left + } ( { DrawRect.Width - } IW) div 2;
|
|
Inc(IX, ImageMargins.Left);
|
|
Dec(IX, ImageMargins.Right);
|
|
IY := DrawRect.Top + 2;
|
|
Inc(IY, ImageMargins.Top);
|
|
Inc(DrawRect.Top, IY + IH + ImageMargins.Bottom);
|
|
end;
|
|
|
|
iaBottom:
|
|
begin
|
|
IX := { DrawRect.Left + } ( { DrawRect.Width - } IW) div 2;
|
|
Inc(IX, ImageMargins.Left);
|
|
Dec(IX, ImageMargins.Right);
|
|
IY := DrawRect.Bottom - IH - 2;
|
|
Dec(IY, ImageMargins.Bottom);
|
|
Dec(IY, ImageMargins.Top);
|
|
DrawRect.Bottom := IY;
|
|
end;
|
|
end;
|
|
|
|
// if AMouseInControl then
|
|
// Dec(IY);
|
|
LRectAwesome := Rect(IX, IY, IX + IW + 2, IY + IH + 2);
|
|
end
|
|
else if (LImgIndex >= 0) and (NCControls.FImages <> nil) and (NCControls.FImages.Handle <> 0) and
|
|
ImageList_GetIconSize(NCControls.FImages.Handle, IW, IH) then
|
|
begin
|
|
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
|
|
DrawRect := ButtonRect;
|
|
|
|
IX := DrawRect.Left + (DrawRect.Width - IW) div 2;
|
|
IY := DrawRect.Top + (DrawRect.Height - IH) div 2;
|
|
|
|
case FImageAlignment of
|
|
iaLeft:
|
|
begin
|
|
IX := DrawRect.Left + 2;
|
|
Inc(IX, ImageMargins.Left);
|
|
Inc(IY, ImageMargins.Top);
|
|
Dec(IY, ImageMargins.Bottom);
|
|
Inc(DrawRect.Left, { IX + } IW + ImageMargins.Right);
|
|
end;
|
|
|
|
iaRight:
|
|
begin
|
|
IX := DrawRect.Right - IW - 2;
|
|
Dec(IX, ImageMargins.Right);
|
|
Dec(IX, ImageMargins.Left);
|
|
Inc(IY, ImageMargins.Top);
|
|
Dec(IY, ImageMargins.Bottom);
|
|
DrawRect.Right := IX;
|
|
end;
|
|
|
|
iaTop:
|
|
begin
|
|
IX := { DrawRect.Left + } ( { DrawRect.Width - } IW) div 2;
|
|
Inc(IX, ImageMargins.Left);
|
|
Dec(IX, ImageMargins.Right);
|
|
IY := DrawRect.Top + 2;
|
|
Inc(IY, ImageMargins.Top);
|
|
Inc(DrawRect.Top, IY + IH + ImageMargins.Bottom);
|
|
end;
|
|
|
|
iaBottom:
|
|
begin
|
|
IX := { DrawRect.Left + } ( { DrawRect.Width - } IW) div 2;
|
|
Inc(IX, ImageMargins.Left);
|
|
Dec(IX, ImageMargins.Right);
|
|
IY := DrawRect.Bottom - IH - 2;
|
|
Dec(IY, ImageMargins.Bottom);
|
|
Dec(IY, ImageMargins.Top);
|
|
DrawRect.Bottom := IY;
|
|
end;
|
|
end;
|
|
|
|
// if AMouseInControl then
|
|
// Dec(IY);
|
|
if Enabled and ((FImageStyle = isNormal) or ((FImageStyle = isGrayHot) and AMouseInControl)) then
|
|
ImageList_Draw(NCControls.FImages.Handle, LImgIndex, ACanvas.Handle, IX, IY, ILD_NORMAL)
|
|
else
|
|
DoDrawGrayImage(ACanvas.Handle, NCControls.FImages.Handle, LImgIndex, IX, IY);
|
|
end;
|
|
|
|
if (FStyle in [nsSplitButton, nsSplitTrans]) then
|
|
begin
|
|
LRect := DrawRect;
|
|
Dec(DrawRect.Right, 15);
|
|
|
|
if AMouseInControl then
|
|
ThemeTextColor := FHotFontColor
|
|
else
|
|
ThemeTextColor := FFontColor;
|
|
|
|
if Length(BCaption) > 0 then
|
|
begin
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
DrawRect := ButtonRect;
|
|
|
|
DrawControlText(ACanvas, Details, BCaption, DrawRect, DT_VCENTER or DT_CENTER, ThemeTextColor);
|
|
end;
|
|
|
|
if FUseFontAwesome and (FImageIndex >= 0) then
|
|
begin
|
|
if AMouseInControl then
|
|
ThemeTextColor := FAwesomeHotFontColor
|
|
else
|
|
ThemeTextColor := FAwesomeFontColor;
|
|
|
|
FontAwesome.DrawChar(ACanvas.Handle, LImgIndex, LRectAwesome, FDefaultFontAwesomeSize, ThemeTextColor, 0,
|
|
FImageAlignment);
|
|
end;
|
|
|
|
if FDropDown then
|
|
begin
|
|
Details := LStyleServices.GetElementDetails(tbPushButtonPressed);
|
|
SaveIndex := SaveDC(ACanvas.Handle);
|
|
try
|
|
IntersectClipRect(ACanvas.Handle, Width - 15, 0, Width, Height);
|
|
DrawRect := Rect(Width - 30, 0, Width, Height);
|
|
|
|
ButtonRect := DrawRect;
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
DrawRect := ButtonRect;
|
|
|
|
LStyleServices.DrawElement(ACanvas.Handle, Details, DrawRect);
|
|
finally
|
|
RestoreDC(ACanvas.Handle, SaveIndex);
|
|
end;
|
|
end;
|
|
|
|
with ACanvas do
|
|
begin
|
|
|
|
LColor := Pen.Color;
|
|
// draw split line
|
|
if FStyle <> nsSplitTrans then
|
|
begin
|
|
Pen.Color := LStyleServices.GetSystemColor(clBtnShadow);
|
|
MoveTo(LRect.Right - 15, LRect.Top + 3);
|
|
LineTo(LRect.Right - 15, LRect.Bottom - 3);
|
|
if Enabled then
|
|
Pen.Color := LStyleServices.GetSystemColor(clBtnHighlight)
|
|
else
|
|
Pen.Color := Font.Color;
|
|
MoveTo(LRect.Right - 14, LRect.Top + 3);
|
|
LineTo(LRect.Right - 14, LRect.Bottom - 3);
|
|
end;
|
|
|
|
|
|
// draw arrow
|
|
|
|
if (FStyle = nsSplitTrans) and (not AMouseInControl) then
|
|
Pen.Color := FFontColor
|
|
else
|
|
Pen.Color := FHotFontColor;
|
|
|
|
X := LRect.Right - 8;
|
|
Y := LRect.Top + (Height div 2) + 1;
|
|
for i := 3 downto 0 do
|
|
begin
|
|
MoveTo(X - i, Y - i);
|
|
LineTo(X + i + 1, Y - i);
|
|
end;
|
|
|
|
Pen.Color := LColor;
|
|
end;
|
|
|
|
end
|
|
else
|
|
begin
|
|
if AMouseInControl then
|
|
ThemeTextColor := FHotFontColor
|
|
else
|
|
ThemeTextColor := FFontColor;
|
|
|
|
// ButtonRect := DrawRect;
|
|
// if not StyleServices.HasElementFixedPosition(Details) then
|
|
// CorrectLeftButtonRect(ButtonRect);
|
|
// DrawRect := ButtonRect;
|
|
|
|
if (FCaptionAligmentFlags and DT_CENTER) <> DT_CENTER then
|
|
DrawRect.Left := DrawRect.Left + 5;
|
|
|
|
DrawControlText(ACanvas, Details, BCaption, DrawRect, FCaptionAligmentFlags, ThemeTextColor);
|
|
|
|
if FUseFontAwesome and (FImageIndex >= 0) then
|
|
begin
|
|
if AMouseInControl then
|
|
ThemeTextColor := FAwesomeHotFontColor
|
|
else
|
|
ThemeTextColor := FAwesomeFontColor;
|
|
|
|
// InflateRect(LRectAwesome, 2, 2);
|
|
FontAwesome.DrawChar(ACanvas.Handle, LImgIndex, LRectAwesome, FDefaultFontAwesomeSize, ThemeTextColor, 0,
|
|
FImageAlignment);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TNCButton.SetDisabledImageIndex(const Value: TImageIndex);
|
|
begin
|
|
FDisabledImageIndex := Value;
|
|
end;
|
|
|
|
procedure TNCButton.SetDropDownMenu(const Value: TPopupMenu);
|
|
begin
|
|
FDropDownMenu := Value;
|
|
end;
|
|
|
|
procedure TNCButton.SetHotImageIndex(const Value: TImageIndex);
|
|
begin
|
|
FHotImageIndex := Value;
|
|
end;
|
|
|
|
procedure TNCButton.SetImageAlignment(const Value: TImageAlignment);
|
|
begin
|
|
FImageAlignment := Value;
|
|
end;
|
|
|
|
procedure TNCButton.SetImageIndex(const Value: TImageIndex);
|
|
begin
|
|
FImageIndex := Value;
|
|
end;
|
|
|
|
procedure TNCButton.SetImageMargins(const Value: TImageMargins);
|
|
begin
|
|
FImageMargins := Value;
|
|
end;
|
|
|
|
procedure TNCButton.SetImageStyle(const Value: TNCImageStyle);
|
|
begin
|
|
FImageStyle := Value;
|
|
end;
|
|
|
|
procedure TNCButton.SetPressedImageIndex(const Value: TImageIndex);
|
|
begin
|
|
FPressedImageIndex := Value;
|
|
end;
|
|
|
|
procedure TNCButton.SetStyle(const Value: TNCButtonStyle);
|
|
begin
|
|
FStyle := Value;
|
|
end;
|
|
|
|
procedure TNCButton.SetUseFontAwesome(const Value: Boolean);
|
|
begin
|
|
FUseFontAwesome := Value;
|
|
end;
|
|
|
|
procedure TNCButton.ShowHintWindow(X, Y: Integer);
|
|
begin
|
|
if (THintWindowClass(FHintWindow).WindowHandle = 0) then
|
|
begin
|
|
FHintWindow.Visible := False;
|
|
FHintWindow.Color := NCControls.StyleServices.GetSystemColor(clInfoBk);
|
|
FHintWindow.Font.Color := NCControls.StyleServices.GetSystemColor(clInfoText);
|
|
FHintWindow.Caption := Hint;
|
|
FHintWindow.ParentWindow := Application.Handle;
|
|
FHintWindow.Left := NCControls.FForm.Left + BoundsRect.Left;
|
|
FHintWindow.Top := NCControls.FForm.Top + BoundsRect.Bottom + 5;
|
|
FHintWindow.Show;
|
|
end;
|
|
end;
|
|
|
|
procedure TNCButton.HideHintWindow;
|
|
begin
|
|
if THintWindowClass(FHintWindow).WindowHandle <> 0 then
|
|
FHintWindow.ReleaseHandle;
|
|
end;
|
|
|
|
{ TFormStyleNCControls }
|
|
constructor TFormStyleNCControls.Create(AControl: TWinControl);
|
|
begin
|
|
inherited;
|
|
FNCControls := nil;
|
|
end;
|
|
|
|
destructor TFormStyleNCControls.Destroy;
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
function TFormStyleNCControls.GetNCControls: TNCControls;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := FNCControls;
|
|
if Result = nil then
|
|
for i := 0 to Form.ComponentCount - 1 do
|
|
if Form.Components[i] is TNCControls then
|
|
begin
|
|
FNCControls := TNCControls(Form.Components[i]);
|
|
Exit(FNCControls);
|
|
end;
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.Maximize;
|
|
begin
|
|
if Handle <> 0 then
|
|
begin
|
|
FNCControls.FPressedControlIndex := -1;
|
|
FNCControls.FHotControlIndex := -1;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.Minimize;
|
|
begin
|
|
if Handle <> 0 then
|
|
begin
|
|
FNCControls.FPressedControlIndex := -1;
|
|
FNCControls.FHotControlIndex := -1;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.MouseEnter;
|
|
begin
|
|
inherited;
|
|
FNCControls.FPressedControlIndex := -1;
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.MouseLeave;
|
|
begin
|
|
inherited;
|
|
if FNCControls.FHotControlIndex <> -1 then
|
|
begin
|
|
FNCControls.FHotControlIndex := -1;
|
|
FNCControls.FPressedControlIndex := -1;
|
|
if Form.BorderStyle <> bsNone then
|
|
InvalidateNC;
|
|
end;
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.Restore;
|
|
begin
|
|
FNCControls.FPressedControlIndex := -1;
|
|
FNCControls.FHotControlIndex := -1;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.PaintNCControls(Canvas: TCanvas; ARect: TRect);
|
|
var
|
|
LCurrent: Integer;
|
|
LNCControl: TNCControl;
|
|
begin
|
|
if (NCControls <> nil) and (NCControls.ControlsCount > 0) and (NCControls.Visible)
|
|
{ and (NCControls.Form.Visible) } and (NCControls.FControls.UpdateCount = 0) then
|
|
for LCurrent := 0 to NCControls.ControlsCount - 1 do
|
|
begin
|
|
LNCControl := NCControls.Controls[LCurrent];
|
|
if LNCControl.Visible and (LNCControl.BoundsRect.Right <= ARect.Right) then
|
|
LNCControl.DrawControl(Canvas, FNCControls.FHotControlIndex = LCurrent,
|
|
FNCControls.FPressedControlIndex = LCurrent);
|
|
end
|
|
else;
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.WMNCHitTest(var Message: TWMNCHitTest);
|
|
var
|
|
P: TPoint;
|
|
LHitTest: Integer;
|
|
begin
|
|
if (NCControls <> nil) and (NCControls.Visible) then
|
|
begin
|
|
{$IF CompilerVersion>23}
|
|
if (TStyleManager.FormBorderStyle = fbsCurrentStyle) and (seBorder in Form.StyleElements) then
|
|
{$IFEND}
|
|
begin
|
|
P := _NormalizePoint(Point(Message.XPos, Message.YPos));
|
|
LHitTest := _GetHitTest(P);
|
|
if (LHitTest <> HTSYSMENU) or ((LHitTest = HTSYSMENU) and NCControls.ShowSystemMenu) then
|
|
begin
|
|
Message.Result := LHitTest;
|
|
Handled := True;
|
|
end
|
|
else
|
|
begin
|
|
Message.Result := WM_NULL;
|
|
Handled := True;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
// Avoid maximize or restore on DblClk
|
|
|
|
procedure TFormStyleNCControls.WMNCLButtonDblClk(var Message: TWMNCHitMessage);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
if (NCControls <> nil) and (NCControls.Visible) then
|
|
begin
|
|
P := _NormalizePoint(Point(Message.XCursor, Message.YCursor));
|
|
if ((Message.HitTest = HTTOP) or (Message.HitTest = HTCAPTION)) and NCControls.PointInNCControl(P) then
|
|
begin
|
|
Message.Result := 0;
|
|
Message.Msg := WM_NULL;
|
|
Handled := True;
|
|
Exit;
|
|
end;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.WMNCLButtonDown(var Message: TWMNCHitMessage);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
inherited;
|
|
{$IF CompilerVersion>23}
|
|
if not((TStyleManager.FormBorderStyle = fbsCurrentStyle) and (seBorder in Form.StyleElements)) then
|
|
begin
|
|
Handled := False;
|
|
Exit;
|
|
end;
|
|
{$IFEND}
|
|
if (NCControls <> nil) and (NCControls.Visible) then
|
|
begin
|
|
P := _NormalizePoint(Point(Message.XCursor, Message.YCursor));
|
|
if ((Message.HitTest = HTTOP) or (Message.HitTest = HTCAPTION)) and FNCControls.PointInNCControl(P) then
|
|
begin
|
|
FNCControls.FPressedControlIndex := FNCControls.GetNCControlIndex(P);
|
|
|
|
if (FNCControls.FPressedControlIndex >= 0) then
|
|
FNCControls[FNCControls.FPressedControlIndex].Handle_WMNCLButtonDown(Message);
|
|
|
|
InvalidateNC;
|
|
Message.Result := 0;
|
|
Message.Msg := WM_NULL;
|
|
Handled := True;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.WMNCLButtonUp(var Message: TWMNCHitMessage);
|
|
var
|
|
OldIndex: Integer;
|
|
P: TPoint;
|
|
LNCControl: TNCControl;
|
|
begin
|
|
inherited;
|
|
|
|
if (NCControls <> nil) and (NCControls.Visible) then
|
|
begin
|
|
{$IF CompilerVersion>23}
|
|
if not((TStyleManager.FormBorderStyle = fbsCurrentStyle) and (seBorder in Form.StyleElements)) then
|
|
begin
|
|
Handled := False;
|
|
Exit;
|
|
end;
|
|
{$IFEND}
|
|
OldIndex := FNCControls.FPressedControlIndex;
|
|
|
|
if FNCControls.FPressedControlIndex <> -1 then
|
|
begin
|
|
FNCControls.FPressedControlIndex := -1;
|
|
InvalidateNC;
|
|
end;
|
|
|
|
if OldIndex = FNCControls.FHotControlIndex then
|
|
begin
|
|
P := _NormalizePoint(Point(Message.XCursor, Message.YCursor));
|
|
NCControls.FLastPoint := P;
|
|
NCControls.FControlUpIndex := NCControls.GetNCControlIndex(P);
|
|
if NCControls.FControlUpIndex > -1 then
|
|
begin
|
|
LNCControl := NCControls.Controls[NCControls.FControlUpIndex];
|
|
LNCControl.Handle_WMNCLButtonUp(Message);
|
|
end;
|
|
end;
|
|
|
|
Message.Result := 0;
|
|
Message.Msg := WM_NULL;
|
|
Handled := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.WMNCMouseMove(var Message: TWMNCHitMessage);
|
|
var
|
|
i: Integer;
|
|
LNCControl: TNCControl;
|
|
begin
|
|
inherited;
|
|
if (NCControls <> nil) and (NCControls.Visible) then
|
|
begin
|
|
NCControls.FLastPoint := _NormalizePoint(Point(Message.XCursor, Message.YCursor));
|
|
// OutputDebugString(PChar(Format('Message.HitTest %d XCursor %d YCursor %d P.X %d P.Y %d',[Message.HitTest, Message.XCursor, Message.YCursor, P.X, P.Y])));
|
|
|
|
{$IF CompilerVersion>23}
|
|
if not((TStyleManager.FormBorderStyle = fbsCurrentStyle) and (seBorder in Form.StyleElements)) then
|
|
begin
|
|
Handled := False;
|
|
Exit;
|
|
end;
|
|
{$IFEND}
|
|
i := NCControls.GetNCControlIndex(NCControls.LastPoint);
|
|
if (i >= 0) then
|
|
begin
|
|
LNCControl := NCControls[i];
|
|
LNCControl.Handle_WMNCMouseMove(Message);
|
|
end
|
|
else
|
|
// notify to the controls the mouse leave.
|
|
if NCControls.ControlsCount > 0 then
|
|
begin
|
|
LNCControl := NCControls[0];
|
|
LNCControl.Handle_WMNCMouseMove(Message);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
procedure TFormStyleNCControls.PaintNC(Canvas: TCanvas);
|
|
var
|
|
Details, CaptionDetails, IconDetails: TThemedElementDetails;
|
|
Detail: TThemedWindow;
|
|
R, R1, R2, DrawRect, ButtonRect, TextRect: TRect;
|
|
CaptionBuffer: TBitmap;
|
|
FButtonState: TThemedWindow;
|
|
TextFormat: TTextFormat;
|
|
LText: string;
|
|
LStyleServices: TCustomStyleServices;
|
|
TextTopOffset: Integer;
|
|
|
|
function GetTopOffset: Integer;
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
P.X := Form.Left + Form.Width div 2;
|
|
P.Y := Form.Top + Form.Height div 2;
|
|
Result := Screen.MonitorFromPoint(P).WorkareaRect.Top;
|
|
if Form.Top < Result then
|
|
Result := Result - Form.Top
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure CorrectRightButtonRect(var AButtonRect: TRect);
|
|
var
|
|
TopOffset, RightOffset: Integer;
|
|
BS: TRect;
|
|
begin
|
|
if (Form.WindowState = wsMaximized) and (TCustomFormClass(Form).FormStyle <> fsMDIChild) and (ButtonRect.Width > 0)
|
|
then
|
|
begin
|
|
BS := _GetBorderSize;
|
|
TopOffset := GetTopOffset;
|
|
RightOffset := -BS.Right;
|
|
if ButtonRect.Top < TopOffset then
|
|
begin
|
|
TopOffset := TopOffset - ButtonRect.Top;
|
|
OffsetRect(ButtonRect, RightOffset, TopOffset);
|
|
TopOffset := ButtonRect.Bottom - BS.Top;
|
|
if TopOffset > 0 then
|
|
OffsetRect(ButtonRect, 0, -TopOffset);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure CorrectLeftButtonRect(var AButtonRect: TRect);
|
|
var
|
|
TopOffset, LeftOffset: Integer;
|
|
BS: TRect;
|
|
begin
|
|
if (Form.WindowState = wsMaximized) and (TCustomFormClass(Form).FormStyle <> fsMDIChild) and (ButtonRect.Width > 0)
|
|
then
|
|
begin
|
|
BS := _GetBorderSize;
|
|
TopOffset := GetTopOffset;
|
|
LeftOffset := BS.Left;
|
|
if ButtonRect.Top < TopOffset then
|
|
begin
|
|
TopOffset := TopOffset - ButtonRect.Top;
|
|
OffsetRect(ButtonRect, LeftOffset, TopOffset);
|
|
TopOffset := ButtonRect.Bottom - BS.Top;
|
|
if TopOffset > 0 then
|
|
OffsetRect(ButtonRect, 0, -TopOffset);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if Form.BorderStyle = bsNone then
|
|
begin
|
|
MainMenuBarHookPaint(Canvas);
|
|
Exit;
|
|
end;
|
|
|
|
if NCControls <> nil then
|
|
LStyleServices := NCControls.StyleServices
|
|
else
|
|
LStyleServices := StyleServices;
|
|
|
|
_FCloseButtonRect := Rect(0, 0, 0, 0);
|
|
_FMaxButtonRect := Rect(0, 0, 0, 0);
|
|
_FMinButtonRect := Rect(0, 0, 0, 0);
|
|
_FHelpButtonRect := Rect(0, 0, 0, 0);
|
|
_FSysMenuButtonRect := Rect(0, 0, 0, 0);
|
|
_FCaptionRect := Rect(0, 0, 0, 0);
|
|
|
|
if not LStyleServices.Available then
|
|
Exit;
|
|
R := _GetBorderSize;
|
|
if (NCControls <> nil) then
|
|
NCControls.FormBorderSize := R;
|
|
|
|
if (Form.BorderStyle <> bsToolWindow) and (Form.BorderStyle <> bsSizeToolWin) then
|
|
begin
|
|
if _FFormActive then
|
|
Detail := twCaptionActive
|
|
else
|
|
Detail := twCaptionInActive
|
|
end
|
|
else
|
|
begin
|
|
if _FFormActive then
|
|
Detail := twSmallCaptionActive
|
|
else
|
|
Detail := twSmallCaptionInActive
|
|
end;
|
|
|
|
CaptionBuffer := TBitmap.Create;
|
|
try
|
|
CaptionBuffer.SetSize(_FWidth, R.Top);
|
|
// caption
|
|
DrawRect := Rect(0, 0, CaptionBuffer.Width, CaptionBuffer.Height);
|
|
Details := LStyleServices.GetElementDetails(Detail);
|
|
LStyleServices.DrawElement(CaptionBuffer.Canvas.Handle, Details, DrawRect);
|
|
TextRect := DrawRect;
|
|
CaptionDetails := Details;
|
|
TextTopOffset := 3;
|
|
|
|
// icon
|
|
if ((NCControls <> nil) and NCControls.ShowSystemMenu) and (biSystemMenu in TCustomFormClass(Form).BorderIcons) and
|
|
(Form.BorderStyle <> bsDialog) and (Form.BorderStyle <> bsToolWindow) and (Form.BorderStyle <> bsSizeToolWin) then
|
|
begin
|
|
IconDetails := LStyleServices.GetElementDetails(twSysButtonNormal);
|
|
if not LStyleServices.GetElementContentRect(0, IconDetails, DrawRect, ButtonRect) then
|
|
ButtonRect := Rect(0, 0, 0, 0);
|
|
|
|
R1 := ButtonRect;
|
|
|
|
{$IF CompilerVersion > 23}
|
|
if not StyleServices.HasElementFixedPosition(Details) then
|
|
begin
|
|
{$IFEND}
|
|
CorrectLeftButtonRect(ButtonRect);
|
|
TextTopOffset := Abs(R1.Top - ButtonRect.Top);
|
|
if TextTopOffset > R.Top then
|
|
TextTopOffset := 3;
|
|
{$IF CompilerVersion > 23}
|
|
end
|
|
else
|
|
TextTopOffset := 0;
|
|
{$IFEND}
|
|
R1 := Rect(0, 0, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
|
|
RectVCenter(R1, ButtonRect);
|
|
if ButtonRect.Width > 0 then
|
|
DrawIconEx(CaptionBuffer.Canvas.Handle, R1.Left, R1.Top, _GetIconFast.Handle, 0, 0, 0, 0, DI_NORMAL);
|
|
Inc(TextRect.Left, ButtonRect.Width + 5);
|
|
_FSysMenuButtonRect := ButtonRect;
|
|
end
|
|
else
|
|
Inc(TextRect.Left, R.Left);
|
|
|
|
// buttons
|
|
if (biSystemMenu in TCustomFormClass(Form).BorderIcons) then
|
|
begin
|
|
if (Form.BorderStyle <> bsToolWindow) and (Form.BorderStyle <> bsSizeToolWin) then
|
|
begin
|
|
if (_FPressedButton = HTCLOSE) and (_FHotButton = HTCLOSE) then
|
|
FButtonState := twCloseButtonPushed
|
|
else if _FHotButton = HTCLOSE then
|
|
FButtonState := twCloseButtonHot
|
|
else if _FFormActive then
|
|
FButtonState := twCloseButtonNormal
|
|
else
|
|
FButtonState := twCloseButtonDisabled;
|
|
end
|
|
else
|
|
begin
|
|
if (_FPressedButton = HTCLOSE) and (_FHotButton = HTCLOSE) then
|
|
FButtonState := twSmallCloseButtonPushed
|
|
else if _FHotButton = HTCLOSE then
|
|
FButtonState := twSmallCloseButtonHot
|
|
else if _FFormActive then
|
|
FButtonState := twSmallCloseButtonNormal
|
|
else
|
|
FButtonState := twSmallCloseButtonDisabled;
|
|
end;
|
|
|
|
Details := LStyleServices.GetElementDetails(FButtonState);
|
|
if not LStyleServices.GetElementContentRect(0, Details, DrawRect, ButtonRect) then
|
|
ButtonRect := Rect(0, 0, 0, 0);
|
|
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectRightButtonRect(ButtonRect);
|
|
|
|
LStyleServices.DrawElement(CaptionBuffer.Canvas.Handle, Details, ButtonRect);
|
|
|
|
if ButtonRect.Left > 0 then
|
|
TextRect.Right := ButtonRect.Left;
|
|
_FCloseButtonRect := ButtonRect;
|
|
end;
|
|
|
|
if (biMaximize in TCustomFormClass(Form).BorderIcons) and (biSystemMenu in TCustomFormClass(Form).BorderIcons) and
|
|
(Form.BorderStyle <> bsDialog) and (Form.BorderStyle <> bsToolWindow) and (Form.BorderStyle <> bsSizeToolWin) then
|
|
begin
|
|
if Form.WindowState = wsMaximized then
|
|
begin
|
|
|
|
if (_FPressedButton = HTMAXBUTTON) and (_FHotButton = HTMAXBUTTON) then
|
|
FButtonState := twRestoreButtonPushed
|
|
else if _FHotButton = HTMAXBUTTON then
|
|
FButtonState := twRestoreButtonHot
|
|
else if _FFormActive then
|
|
FButtonState := twRestoreButtonNormal
|
|
else
|
|
FButtonState := twRestoreButtonDisabled;
|
|
end
|
|
else
|
|
begin
|
|
if (_FPressedButton = HTMAXBUTTON) and (_FHotButton = HTMAXBUTTON) then
|
|
FButtonState := twMaxButtonPushed
|
|
else if _FHotButton = HTMAXBUTTON then
|
|
FButtonState := twMaxButtonHot
|
|
else if _FFormActive then
|
|
FButtonState := twMaxButtonNormal
|
|
else
|
|
FButtonState := twMaxButtonDisabled;
|
|
end;
|
|
|
|
Details := LStyleServices.GetElementDetails(FButtonState);
|
|
|
|
if not LStyleServices.GetElementContentRect(0, Details, DrawRect, ButtonRect) then
|
|
ButtonRect := Rect(0, 0, 0, 0);
|
|
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectRightButtonRect(ButtonRect);
|
|
|
|
if ButtonRect.Width > 0 then
|
|
LStyleServices.DrawElement(CaptionBuffer.Canvas.Handle, Details, ButtonRect);
|
|
|
|
if ButtonRect.Left > 0 then
|
|
TextRect.Right := ButtonRect.Left;
|
|
_FMaxButtonRect := ButtonRect;
|
|
end;
|
|
|
|
if (biMinimize in TCustomFormClass(Form).BorderIcons) and (biSystemMenu in TCustomFormClass(Form).BorderIcons) and
|
|
(Form.BorderStyle <> bsDialog) and (Form.BorderStyle <> bsToolWindow) and (Form.BorderStyle <> bsSizeToolWin) then
|
|
begin
|
|
if (_FPressedButton = HTMINBUTTON) and (_FHotButton = HTMINBUTTON) then
|
|
FButtonState := twMinButtonPushed
|
|
else if _FHotButton = HTMINBUTTON then
|
|
FButtonState := twMinButtonHot
|
|
else if _FFormActive then
|
|
FButtonState := twMinButtonNormal
|
|
else
|
|
FButtonState := twMinButtonDisabled;
|
|
|
|
Details := LStyleServices.GetElementDetails(FButtonState);
|
|
|
|
if not LStyleServices.GetElementContentRect(0, Details, DrawRect, ButtonRect) then
|
|
ButtonRect := Rect(0, 0, 0, 0);
|
|
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectRightButtonRect(ButtonRect);
|
|
|
|
if ButtonRect.Width > 0 then
|
|
LStyleServices.DrawElement(CaptionBuffer.Canvas.Handle, Details, ButtonRect);
|
|
|
|
if ButtonRect.Left > 0 then
|
|
TextRect.Right := ButtonRect.Left;
|
|
_FMinButtonRect := ButtonRect;
|
|
end;
|
|
|
|
if (biHelp in TCustomFormClass(Form).BorderIcons) and (biSystemMenu in TCustomFormClass(Form).BorderIcons) and
|
|
((not(biMaximize in TCustomFormClass(Form).BorderIcons) and not(biMinimize in TCustomFormClass(Form).BorderIcons))
|
|
or (Form.BorderStyle = bsDialog)) then
|
|
begin
|
|
if (_FPressedButton = HTHELP) and (_FHotButton = HTHELP) then
|
|
FButtonState := twHelpButtonPushed
|
|
else if _FHotButton = HTHELP then
|
|
FButtonState := twHelpButtonHot
|
|
else if _FFormActive then
|
|
FButtonState := twHelpButtonNormal
|
|
else
|
|
FButtonState := twHelpButtonDisabled;
|
|
|
|
Details := LStyleServices.GetElementDetails(FButtonState);
|
|
|
|
if not LStyleServices.GetElementContentRect(0, Details, DrawRect, ButtonRect) then
|
|
ButtonRect := Rect(0, 0, 0, 0);
|
|
|
|
{$IF CompilerVersion > 23} if not StyleServices.HasElementFixedPosition(Details) then {$IFEND}
|
|
CorrectRightButtonRect(ButtonRect);
|
|
|
|
if ButtonRect.Width > 0 then
|
|
LStyleServices.DrawElement(CaptionBuffer.Canvas.Handle, Details, ButtonRect);
|
|
|
|
if ButtonRect.Left > 0 then
|
|
TextRect.Right := ButtonRect.Left;
|
|
_FHelpButtonRect := ButtonRect;
|
|
end;
|
|
|
|
R2 := TextRect;
|
|
|
|
if (NCControls <> nil) and (NCControls.ControlsCount > 0) and (NCControls.Visible) then
|
|
Inc(TextRect.Left, NCControls.Controls[NCControls.ControlsCount - 1].BoundsRect.Right - NCControls.Controls[0]
|
|
.BoundsRect.Left + 10);
|
|
|
|
// text
|
|
if (NCControls <> nil) and (IsIconic(TCustomFormClass(Form).Handle) or (NCControls.ShowCaption)) then
|
|
begin
|
|
|
|
TextFormat := [tfLeft, tfSingleLine, tfVerticalCenter];
|
|
if Control.UseRightToLeftReading then
|
|
Include(TextFormat, tfRtlReading);
|
|
|
|
LText := Text;
|
|
if (TCustomFormClass(Form).WindowState = wsMaximized) and (TCustomFormClass(Form).FormStyle <> fsMDIChild) and
|
|
(TextTopOffset <> 0) and (biSystemMenu in TCustomFormClass(Form).BorderIcons) then
|
|
begin
|
|
Inc(TextRect.Left, R.Left);
|
|
MoveWindowOrg(CaptionBuffer.Canvas.Handle, 0, TextTopOffset);
|
|
LStyleServices.DrawText(CaptionBuffer.Canvas.Handle, CaptionDetails, LText, TextRect, TextFormat);
|
|
MoveWindowOrg(CaptionBuffer.Canvas.Handle, 0, -TextTopOffset);
|
|
end
|
|
else
|
|
LStyleServices.DrawText(CaptionBuffer.Canvas.Handle, CaptionDetails, LText, TextRect, TextFormat);
|
|
end;
|
|
|
|
if (NCControls <> nil) and (NCControls.ControlsCount > 0) and (NCControls.Visible) then
|
|
Dec(TextRect.Left, NCControls.Controls[NCControls.ControlsCount - 1].BoundsRect.Right - NCControls.Controls[0]
|
|
.BoundsRect.Left + 10);
|
|
|
|
_FCaptionRect := TextRect;
|
|
|
|
if not IsIconic(TCustomFormClass(Form).Handle) then
|
|
PaintNCControls(CaptionBuffer.Canvas, R2);
|
|
|
|
// caption
|
|
Canvas.Draw(0, 0, CaptionBuffer);
|
|
finally
|
|
CaptionBuffer.Free;
|
|
end;
|
|
|
|
// menubar
|
|
MainMenuBarHookPaint(Canvas);
|
|
|
|
// left
|
|
if (Form.BorderStyle <> bsToolWindow) and (Form.BorderStyle <> bsSizeToolWin) then
|
|
begin
|
|
if _FFormActive then
|
|
Detail := twFrameLeftActive
|
|
else
|
|
Detail := twFrameLeftInActive
|
|
end
|
|
else
|
|
begin
|
|
if _FFormActive then
|
|
Detail := twSmallFrameLeftActive
|
|
else
|
|
Detail := twSmallFrameLeftInActive
|
|
end;
|
|
|
|
DrawRect := Rect(0, R.Top, R.Left, _FHeight - R.Bottom);
|
|
Details := LStyleServices.GetElementDetails(Detail);
|
|
|
|
if DrawRect.Bottom - DrawRect.Top > 0 then
|
|
LStyleServices.DrawElement(Canvas.Handle, Details, DrawRect);
|
|
|
|
// right
|
|
if (Form.BorderStyle <> bsToolWindow) and (Form.BorderStyle <> bsSizeToolWin) then
|
|
begin
|
|
if _FFormActive then
|
|
Detail := twFrameRightActive
|
|
else
|
|
Detail := twFrameRightInActive
|
|
end
|
|
else
|
|
begin
|
|
if _FFormActive then
|
|
Detail := twSmallFrameRightActive
|
|
else
|
|
Detail := twSmallFrameRightInActive
|
|
end;
|
|
|
|
DrawRect := Rect(_FWidth - R.Right, R.Top, _FWidth, _FHeight - R.Bottom);
|
|
Details := LStyleServices.GetElementDetails(Detail);
|
|
|
|
if DrawRect.Bottom - DrawRect.Top > 0 then
|
|
LStyleServices.DrawElement(Canvas.Handle, Details, DrawRect);
|
|
|
|
// Bottom
|
|
if (Form.BorderStyle <> bsToolWindow) and (Form.BorderStyle <> bsSizeToolWin) then
|
|
begin
|
|
if _FFormActive then
|
|
Detail := twFrameBottomActive
|
|
else
|
|
Detail := twFrameBottomInActive
|
|
end
|
|
else
|
|
begin
|
|
if _FFormActive then
|
|
Detail := twSmallFrameBottomActive
|
|
else
|
|
Detail := twSmallFrameBottomInActive
|
|
end;
|
|
|
|
DrawRect := Rect(0, _FHeight - R.Bottom, _FWidth, _FHeight);
|
|
Details := LStyleServices.GetElementDetails(Detail);
|
|
|
|
if DrawRect.Bottom - DrawRect.Top > 0 then
|
|
LStyleServices.DrawElement(Canvas.Handle, Details, DrawRect);
|
|
end;
|
|
|
|
// This custom GetBorderSize method is necessary to allow to the NC controls use a custom Style in the title and border area.
|
|
function Detour_TFormStyleHook_GetBorderSize(Self: TFormStyleHook): TRect;
|
|
var
|
|
Size: TSize;
|
|
Details: TThemedElementDetails;
|
|
Detail: TThemedWindow;
|
|
LStylesServices: TCustomStyleServices;
|
|
LForm: TCustomForm;
|
|
begin
|
|
if not(ExecutingInMainThread) then
|
|
Exit(Trampoline_TFormStyleHook_GetBorderSize(Self));
|
|
|
|
if (Self is TFormStyleNCControls) and (TFormStyleNCControls(Self).NCControls <> nil) then
|
|
begin
|
|
LStylesServices := TFormStyleNCControls(Self).NCControls.StyleServices;
|
|
LForm := TFormStyleHookClass(Self)._Form;
|
|
Result := Rect(0, 0, 0, 0);
|
|
if LForm.BorderStyle = bsNone then
|
|
Exit;
|
|
|
|
if not LStylesServices.Available then
|
|
Exit;
|
|
{ caption height }
|
|
if (LForm.BorderStyle <> bsToolWindow) and (LForm.BorderStyle <> bsSizeToolWin) then
|
|
Detail := twCaptionActive
|
|
else
|
|
Detail := twSmallCaptionActive;
|
|
Details := LStylesServices.GetElementDetails(Detail);
|
|
LStylesServices.GetElementSize(0, Details, esActual, Size);
|
|
Result.Top := Size.cy;
|
|
{ left border width }
|
|
if (LForm.BorderStyle <> bsToolWindow) and (LForm.BorderStyle <> bsSizeToolWin) then
|
|
Detail := twFrameLeftActive
|
|
else
|
|
Detail := twSmallFrameLeftActive;
|
|
Details := LStylesServices.GetElementDetails(Detail);
|
|
LStylesServices.GetElementSize(0, Details, esActual, Size);
|
|
Result.Left := Size.cx;
|
|
{ right border width }
|
|
if (LForm.BorderStyle <> bsToolWindow) and (LForm.BorderStyle <> bsSizeToolWin) then
|
|
Detail := twFrameRightActive
|
|
else
|
|
Detail := twSmallFrameRightActive;
|
|
Details := LStylesServices.GetElementDetails(Detail);
|
|
LStylesServices.GetElementSize(0, Details, esActual, Size);
|
|
Result.Right := Size.cx;
|
|
{ bottom border height }
|
|
if (LForm.BorderStyle <> bsToolWindow) and (LForm.BorderStyle <> bsSizeToolWin) then
|
|
Detail := twFrameBottomActive
|
|
else
|
|
Detail := twSmallFrameBottomActive;
|
|
Details := LStylesServices.GetElementDetails(Detail);
|
|
LStylesServices.GetElementSize(0, Details, esActual, Size);
|
|
Result.Bottom := Size.cy;
|
|
|
|
// //Result.Top := Result.Top + 5;
|
|
// Result.Left := 0;
|
|
// Result.Right := 0;
|
|
// Result.Bottom := 0;
|
|
if TFormStyleNCSettings.UseThinBorder then
|
|
begin
|
|
// Don't use 0, because the native resize feature is lost if the border is 0.
|
|
Result.Left := 1;
|
|
Result.Right := 1;
|
|
Result.Bottom := 1;
|
|
end;
|
|
end
|
|
else
|
|
Exit(Trampoline_TFormStyleHook_GetBorderSize(Self));
|
|
end;
|
|
|
|
// This custom GetRegion method is necessary to allow to the NC controls use a custom Style in the title and border area.
|
|
function Detour_TFormStyleHook_GetRegion(Self: TFormStyleHook): HRgn;
|
|
var
|
|
R: TRect;
|
|
Details: TThemedElementDetails;
|
|
Detail: TThemedWindow;
|
|
LStylesServices: TCustomStyleServices;
|
|
LForm: TCustomForm;
|
|
begin
|
|
if not(ExecutingInMainThread) then
|
|
Exit(Trampoline_TFormStyleHook_GetRegion(Self));
|
|
|
|
if (Self is TFormStyleNCControls) and (TFormStyleNCControls(Self).NCControls <> nil) then
|
|
begin
|
|
LStylesServices := TFormStyleNCControls(Self).NCControls.StyleServices;
|
|
LForm := TFormStyleHookClass(Self)._Form;
|
|
Result := 0;
|
|
if not LStylesServices.Available then
|
|
Exit;
|
|
|
|
R := Rect(0, 0, TFormStyleHookClass(Self)._FWidth, TFormStyleHookClass(Self)._FHeight);
|
|
if (LForm.BorderStyle <> bsToolWindow) and (LForm.BorderStyle <> bsSizeToolWin) then
|
|
Detail := twCaptionActive
|
|
else
|
|
Detail := twSmallCaptionActive;
|
|
Details := LStylesServices.GetElementDetails(Detail);
|
|
LStylesServices.GetElementRegion(Details, R, Result);
|
|
end
|
|
else
|
|
Exit(Trampoline_TFormStyleHook_GetRegion(Self));
|
|
end;
|
|
|
|
{ TListNCButtons }
|
|
function TListNCControls.Add: TNCControl;
|
|
begin
|
|
Result := TNCControl(inherited Add);
|
|
end;
|
|
|
|
function RttiMethodInvokeEx(const MethodName: string; RttiType: TRttiType; Instance: TValue;
|
|
const Args: array of TValue): TValue;
|
|
var
|
|
Found: Boolean;
|
|
LMethod: TRttiMethod;
|
|
LIndex: Integer;
|
|
LParams: TArray<TRttiParameter>;
|
|
begin
|
|
Result := nil;
|
|
LMethod := nil;
|
|
Found := False;
|
|
for LMethod in RttiType.GetMethods do
|
|
if SameText(LMethod.Name, MethodName) then
|
|
begin
|
|
LParams := LMethod.GetParameters;
|
|
if Length(Args) = Length(LParams) then
|
|
begin
|
|
Found := True;
|
|
for LIndex := 0 to Length(LParams) - 1 do
|
|
if LParams[LIndex].ParamType.Handle <> Args[LIndex].TypeInfo then
|
|
begin
|
|
Found := False;
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
if Found then
|
|
Break;
|
|
end;
|
|
|
|
if (LMethod <> nil) and Found then
|
|
Result := LMethod.Invoke(Instance, Args)
|
|
else
|
|
raise Exception.CreateFmt('method %s not found', [MethodName]);
|
|
end;
|
|
|
|
function TListNCControls.AddEx<T>: T;
|
|
var
|
|
LRttiContext: TRttiContext;
|
|
LRttiType: TRttiType;
|
|
LRttiInstanceType: TRttiInstanceType;
|
|
LValue: TValue;
|
|
begin
|
|
LRttiContext := TRttiContext.Create;
|
|
LRttiType := LRttiContext.GetType(TypeInfo(T));
|
|
if (LRttiType <> nil) then
|
|
begin
|
|
LRttiInstanceType := LRttiType.AsInstance;
|
|
LValue := LRttiInstanceType.GetMethod('Create').Invoke(LRttiInstanceType.MetaclassType, [Self]);
|
|
// LValue := RttiMethodInvokeEx('Create', LRttiInstanceType, LRttiInstanceType.MetaclassType, [Self]);
|
|
end;
|
|
|
|
Result := LValue.AsType<T>;
|
|
end;
|
|
|
|
constructor TListNCControls.Create(AOwner: TPersistent);
|
|
begin
|
|
FOwner := TNCControls(AOwner);
|
|
inherited Create(TNCControl);
|
|
end;
|
|
|
|
destructor TListNCControls.Destroy;
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
function TListNCControls.GetItem(Index: Integer): TNCControl;
|
|
begin
|
|
Result := TNCControl(inherited GetItem(Index));
|
|
end;
|
|
|
|
function TListNCControls.GetOwner: TPersistent;
|
|
begin
|
|
Result := FOwner;
|
|
end;
|
|
|
|
function TListNCControls.Insert(Index: Integer): TNCControl;
|
|
begin
|
|
Result := TNCControl(inherited Insert(Index));
|
|
end;
|
|
|
|
procedure TListNCControls.SetItem(Index: Integer; Value: TNCControl);
|
|
begin
|
|
inherited SetItem(Index, Value);
|
|
end;
|
|
|
|
{ TNCControl }
|
|
|
|
constructor TNCControl.Create(Collection: TCollection);
|
|
begin
|
|
inherited Create(Collection);
|
|
FNCControls := TNCControls(Collection.Owner);
|
|
FEnabled := True;
|
|
FVisible := True;
|
|
FFont := TFont.Create;
|
|
FWidth := 80;
|
|
FTop := 5;
|
|
FCaptionAligmentFlags := DT_VCENTER or DT_CENTER or DT_WORDBREAK;
|
|
end;
|
|
|
|
destructor TNCControl.Destroy;
|
|
begin
|
|
FFont.Free;
|
|
inherited;
|
|
end;
|
|
|
|
function TNCControl.GetAs<T>: T;
|
|
var
|
|
LValue: TValue;
|
|
begin
|
|
LValue := TValue.From(Self);
|
|
Result := LValue.AsType<T>;
|
|
end;
|
|
|
|
function TNCControl.GetBoundsRect: TRect;
|
|
begin
|
|
Result.Left := Left;
|
|
Result.Top := Top;
|
|
Result.Right := Left + Width;
|
|
Result.Bottom := Top + Height;
|
|
end;
|
|
|
|
function TNCControl.GetEnabled: Boolean;
|
|
begin
|
|
Result := FEnabled;
|
|
end;
|
|
|
|
procedure TNCControl.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
|
|
begin
|
|
FLeft := ALeft;
|
|
FTop := ATop;
|
|
FWidth := AWidth;
|
|
FHeight := AHeight;
|
|
end;
|
|
|
|
procedure TNCControl.SetBoundsRect(const Value: TRect);
|
|
begin
|
|
with Value do
|
|
SetBounds(Left, Top, Right - Left, Bottom - Top);
|
|
end;
|
|
|
|
procedure TNCControl.SetEnabled(const Value: Boolean);
|
|
begin
|
|
if Value <> FEnabled then
|
|
FEnabled := Value;
|
|
end;
|
|
|
|
procedure TNCControl.SetFont(const Value: TFont);
|
|
begin
|
|
FFont := Value;
|
|
end;
|
|
|
|
procedure TNCControl.SetHeight(const Value: Integer);
|
|
begin
|
|
FHeight := Value;
|
|
end;
|
|
|
|
procedure TNCControl.SetLeft(const Value: Integer);
|
|
begin
|
|
FLeft := Value;
|
|
end;
|
|
|
|
procedure TNCControl.SetName(const Value: TComponentName);
|
|
begin
|
|
FName := Value;
|
|
|
|
end;
|
|
|
|
procedure TNCControl.SetShowHint(const Value: Boolean);
|
|
begin
|
|
FShowHint := Value;
|
|
end;
|
|
|
|
procedure TNCControl.SetTop(const Value: Integer);
|
|
begin
|
|
FTop := Value;
|
|
end;
|
|
|
|
procedure TNCControl.SetVisible(const Value: Boolean);
|
|
begin
|
|
if FVisible <> Value then
|
|
FVisible := Value;
|
|
// TODO: Add parent notification
|
|
end;
|
|
|
|
procedure TNCControl.SetWidth(const Value: Integer);
|
|
begin
|
|
FWidth := Value;
|
|
end;
|
|
|
|
procedure TNCControl.DrawControl(ACanvas: TCanvas; AMouseInControl, Pressed: Boolean);
|
|
begin
|
|
end;
|
|
|
|
procedure TNCControl.Handle_WMNCLButtonDown(var Message: TWMNCHitMessage);
|
|
begin
|
|
end;
|
|
|
|
procedure TNCControl.Handle_WMNCLButtonUp(var Message: TWMNCHitMessage);
|
|
begin
|
|
end;
|
|
|
|
procedure TNCControl.Handle_WMNCMouseMove(var Message: TWMNCHitMessage);
|
|
begin
|
|
end;
|
|
|
|
initialization
|
|
|
|
TFormStyleNCSettings.UseThinBorder := False;
|
|
{$IFDEF CPUX86}
|
|
Trampoline_TFormStyleHook_GetBorderSize := InterceptCreate(TFormStyleHookClass(nil)._GetBorderSizeAddr,
|
|
@Detour_TFormStyleHook_GetBorderSize);
|
|
{$ENDIF}
|
|
Trampoline_TFormStyleHook_GetRegion := InterceptCreate(TFormStyleHookClass(nil)._GetRegionAddr,
|
|
@Detour_TFormStyleHook_GetRegion);
|
|
|
|
finalization
|
|
|
|
{$IFDEF CPUX86}
|
|
InterceptRemove(@Trampoline_TFormStyleHook_GetBorderSize);
|
|
{$ENDIF}
|
|
InterceptRemove(@Trampoline_TFormStyleHook_GetRegion);
|
|
|
|
end.
|