git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@38 05c56307-c608-d34a-929d-697000501d7a
1994 lines
58 KiB
ObjectPascal
1994 lines
58 KiB
ObjectPascal
{*******************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressBars components }
|
|
{ }
|
|
{ Copyright (c) 1998-2009 Developer Express Inc. }
|
|
{ ALL RIGHTS RESERVED }
|
|
{ }
|
|
{ The entire contents of this file is protected by U.S. and }
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
|
{ the code contained in this file is strictly prohibited and may }
|
|
{ result in severe civil and criminal penalties and will be }
|
|
{ prosecuted to the maximum extent possible under the law. }
|
|
{ }
|
|
{ RESTRICTIONS }
|
|
{ }
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSBARS AND ALL ACCOMPANYING VCL }
|
|
{ CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
|
|
{ }
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
|
{ }
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
|
{ ADDITIONAL RESTRICTIONS. }
|
|
{ }
|
|
{*******************************************************************}
|
|
|
|
unit dxRibbonForm;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
|
|
Dialogs, StdCtrls, ExtCtrls, ImgList, cxClasses, cxGraphics, cxControls,
|
|
dxRibbonSkins, dxRibbonFormCaptionHelper, cxDWMApi;
|
|
|
|
type
|
|
|
|
{ TdxCustomRibbonForm }
|
|
|
|
TdxCustomRibbonForm = class(TForm)
|
|
private
|
|
FAdjustLayoutForNonClientDrawing: Boolean;
|
|
FAutoScroll: Boolean;
|
|
FCaption: TCaption;
|
|
FCornerRegions: array[0..3] of HRGN;
|
|
FData: TdxRibbonFormData;
|
|
FDisableAero: Boolean;
|
|
FExtendFrameAtTopHeight: Integer;
|
|
FFakeClientHandle: HWND;
|
|
FZoomedBoundsOffsets: TRect;
|
|
FIsActive: Boolean;
|
|
FSizingBorders: TSize;
|
|
FSizingLoop: Boolean;
|
|
FDelayedActivate: Boolean;
|
|
FNeedCallActivate: Boolean;
|
|
FRedrawCount: Integer;
|
|
FUseSkin: Boolean;
|
|
FUseSkinColor: Boolean;
|
|
FVisibleChanging: Boolean;
|
|
FDefClientProc: TFarProc;
|
|
FNewClientInstance: TFarProc;
|
|
FOldClientProc: TFarProc;
|
|
FPrevActiveControl: TWinControl;
|
|
{$IFDEF DELPHI10}
|
|
FRibbonAlwaysOnTop: Boolean;
|
|
{$ENDIF}
|
|
FRibbonNonClientHelper: TdxRibbonFormCaptionHelper;
|
|
procedure AfterResize(AIsRibbonVisible: Boolean; ARibbonHeight: Integer; AIsZoomed: Boolean);
|
|
procedure BeforeResize(out AIsRibbonVisible: Boolean; out ARibbonHeight: Integer);
|
|
procedure CalculateCornerRegions;
|
|
procedure CalculateZoomedOffsets;
|
|
procedure CheckExtendFrame(AZoomed: Boolean);
|
|
procedure CheckResizingNCHitTest(var AHitTest: Integer; const P: TPoint);
|
|
procedure CorrectZoomedBounds(var R: TRect);
|
|
procedure CreateCornerRegions;
|
|
procedure DestroyCornerRegions;
|
|
procedure ExcludeRibbonPaintArea(DC: HDC);
|
|
procedure ForceUpdateWindowSize;
|
|
procedure FullRedrawWithChildren;
|
|
function GetCurrentBordersWidth: TRect;
|
|
function GetBackgroundColor: TColor;
|
|
function GetBorderStyle: TFormBorderStyle;
|
|
function GetUseSkin: Boolean;
|
|
procedure InvalidateFrame(AWnd: HWND; AUpdate: Boolean = False);
|
|
function IsNeedCorrectForAutoHideTaskBar: Boolean;
|
|
function IsNormalWindowState: Boolean;
|
|
function IsRibbonVisible: Boolean;
|
|
procedure NewClientWndProc(var Message: TMessage);
|
|
procedure ResetSystemMenu;
|
|
procedure SetAutoScroll(const Value: Boolean);
|
|
procedure SetBorderStyle(const Value: TFormBorderStyle);
|
|
procedure SetDisableAero(const Value: Boolean);
|
|
procedure SetPrevActiveControl(AValue: TWinControl);
|
|
procedure SetRegion(ARegion: HRGN; ARedraw: Boolean = False);
|
|
{$IFDEF DELPHI10}
|
|
procedure SetRibbonAlwaysOnTop(const Value: Boolean);
|
|
{$ENDIF}
|
|
procedure SetRibbonNonClientHelper(const Value: TdxRibbonFormCaptionHelper);
|
|
procedure SetUseSkinColor(const Value: Boolean);
|
|
procedure ShowSystemMenu(AFromMouse: Boolean);
|
|
procedure ResetGlassFrame;
|
|
procedure UpdateGlassFrame;
|
|
procedure UpdateSystemMenu;
|
|
//messages
|
|
procedure CMActionUpdate(var Message: TMessage); message CM_ACTIONUPDATE;
|
|
procedure CMActivate(var Message: TCMActivate); message CM_ACTIVATE;
|
|
procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
|
|
procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;
|
|
procedure CMVisibleChanged(var Message: TMessage); message CM_VISIBLECHANGED;
|
|
procedure WMCaptureChanged(var Message: TMessage); message WM_CAPTURECHANGED;
|
|
procedure WMDisplayChange(var Message: TMessage); message WM_DISPLAYCHANGE;
|
|
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
|
|
procedure WMInitMenu(var Message: TWMInitMenu); message WM_INITMENU;
|
|
procedure WMNCActivate(var Message: TWMNCActivate); message WM_NCACTIVATE;
|
|
procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
|
|
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
|
|
procedure WMNCPaint(var Message: TMessage); message WM_NCPAINT;
|
|
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
|
|
procedure WMShowWindow(var Message: TMessage); message WM_SHOWWINDOW;
|
|
procedure WMSize(var Message: TWMSize); message WM_SIZE;
|
|
procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
|
|
procedure WMCancelMode(var Message: TWMCancelMode); message WM_CANCELMODE;
|
|
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
|
|
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
|
|
procedure WMNCRButtonUp(var Message: TWMNCRButtonUp); message WM_NCRBUTTONUP;
|
|
procedure WMRButtonDown(var Message: TWMRButtonDown); message WM_RBUTTONDOWN;
|
|
procedure WMRButtonUp(var Message: TWMRButtonUp); message WM_RBUTTONUP;
|
|
procedure WMWindowPosChanged(var Message: TWMWindowPosChanged); message WM_WINDOWPOSCHANGED;
|
|
//vista support
|
|
procedure WMDWMCompositionChanged(var Message: TMessage); message WM_DWMCOMPOSITIONCHANGED;
|
|
//caption
|
|
procedure WMGetText(var Message: TWMGetText); message WM_GETTEXT;
|
|
procedure WMGetTextLength(var Message: TWMGetTextLength); message WM_GETTEXTLENGTH;
|
|
procedure WMSetText(var Message: TWMSetText); message WM_SETTEXT;
|
|
protected
|
|
procedure AdjustClientRect(var Rect: TRect); override;
|
|
procedure AdjustLayout; virtual;
|
|
procedure AdjustSize; override;
|
|
{$IFDEF DELPHI10}
|
|
procedure AlignControls(AControl: TControl; var Rect: TRect); override;
|
|
{$ENDIF}
|
|
procedure CallDWMWindowProc(var Message);
|
|
function CanAdjustLayout: Boolean; virtual;
|
|
procedure CaptionChanged;
|
|
procedure CreateWnd; override;
|
|
procedure DestroyWindowHandle; override;
|
|
procedure DoCreate; override;
|
|
procedure DrawNonClientArea(ADrawCaption: Boolean; AUpdateRegion: HRGN = 1);
|
|
procedure ExtendFrameIntoClientAreaAtTop(AHeight: Integer);
|
|
function GetFormBorderIcons: TBorderIcons; virtual;
|
|
function HandleWithHelper(ADown: Boolean; AButton: TMouseButton): Boolean; virtual;
|
|
procedure InitializeNewForm; {$IFDEF DELPHI12} override; {$ENDIF}
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure ModifySystemMenu(ASysMenu: THandle); virtual;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
procedure Resize; override;
|
|
procedure ShiftControlsVertically(ADelta: Integer); virtual;
|
|
procedure UpdateNonClientArea;
|
|
procedure UpdateWindowRegion(AIsMaximized: Boolean);
|
|
procedure UpdateWindowStates;
|
|
procedure WndProc(var Message: TMessage); override;
|
|
|
|
property DisableAero: Boolean read FDisableAero write SetDisableAero default False;
|
|
property UseSkin: Boolean read GetUseSkin;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
|
|
destructor Destroy; override;
|
|
procedure FullUpdate;
|
|
function GetCaptionHeightDelta(AHasQuickAccessToolbar: Boolean): Integer; virtual;
|
|
procedure Invalidate; override;
|
|
function IsUseAeroNCPaint: Boolean;
|
|
procedure ResetWindowRegion;
|
|
procedure SetRedraw(ARedraw: Boolean);
|
|
|
|
property PrevActiveControl: TWinControl read FPrevActiveControl write SetPrevActiveControl;
|
|
{$IFDEF DELPHI10}
|
|
property RibbonAlwaysOnTop: Boolean read FRibbonAlwaysOnTop write SetRibbonAlwaysOnTop;
|
|
{$ENDIF}
|
|
property RibbonNonClientHelper: TdxRibbonFormCaptionHelper
|
|
read FRibbonNonClientHelper write SetRibbonNonClientHelper;
|
|
property IsActive: Boolean read FIsActive;
|
|
published
|
|
property AdjustLayoutForNonClientDrawing: Boolean
|
|
read FAdjustLayoutForNonClientDrawing write FAdjustLayoutForNonClientDrawing default True;
|
|
property AutoScroll: Boolean read FAutoScroll write SetAutoScroll default False;
|
|
property BorderStyle: TFormBorderStyle read GetBorderStyle write SetBorderStyle default bsSizeable;
|
|
property KeyPreview default True;
|
|
property UseSkinColor: Boolean read FUseSkinColor write SetUseSkinColor default True;
|
|
end;
|
|
|
|
{ TdxRibbonForm }
|
|
|
|
TdxRibbonForm = class(TdxCustomRibbonForm);
|
|
|
|
procedure SetWindowTextWithoutRedraw(AWnd: HWND; const AText: string);
|
|
|
|
implementation
|
|
|
|
uses
|
|
Types, dxBar, cxGeometry, Math, dxOffice11, dxUxTheme, MultiMon, ShellAPI,
|
|
dxRibbon, dxStatusBar, dxCore;
|
|
|
|
const
|
|
{$IFNDEF DELPHI7}
|
|
WM_NCMOUSELEAVE = $02A2;
|
|
{$ENDIF}
|
|
WM_NCUAHDRAWCAPTION = $00AE;
|
|
WM_NCUAHDRAWFRAME = $00AF;
|
|
WM_SYNCPAINT = $0088;
|
|
WM_SYSMENU = $313;
|
|
|
|
dxGlassMaximizedNonClientHeight = 4;
|
|
dxFullRedrawFlags = RDW_INVALIDATE or RDW_ERASE or RDW_FRAME or RDW_ALLCHILDREN;
|
|
|
|
function SetWindowInvisibleStyle(AWnd: HWND): Cardinal;
|
|
begin
|
|
Result := GetWindowLong(AWnd, GWL_STYLE);
|
|
SetWindowLong(AWnd, GWL_STYLE, Result and not WS_VISIBLE);
|
|
end;
|
|
|
|
procedure RestoreWindowStyles(AWnd: HWND; AStyles: Cardinal);
|
|
begin
|
|
SetWindowLong(AWnd, GWL_STYLE, AStyles);
|
|
end;
|
|
|
|
procedure SetWindowTextWithoutRedraw(AWnd: HWND; const AText: string);
|
|
var
|
|
AStyles: Cardinal;
|
|
begin
|
|
AStyles := SetWindowInvisibleStyle(AWnd);
|
|
DefWindowProc(AWnd, WM_SETTEXT, 0, LongInt(PChar(AText)));
|
|
RestoreWindowStyles(AWnd, AStyles);
|
|
end;
|
|
|
|
function GetAnimation: Boolean;
|
|
var
|
|
AInfo: TAnimationInfo;
|
|
begin
|
|
AInfo.cbSize := SizeOf(TAnimationInfo);
|
|
if SystemParametersInfo(SPI_GETANIMATION, SizeOf(AInfo), @AInfo, 0) then
|
|
Result := AInfo.iMinAnimate <> 0
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
procedure SetAnimation(AValue: Boolean);
|
|
var
|
|
AInfo: TAnimationInfo;
|
|
begin
|
|
AInfo.cbSize := SizeOf(TAnimationInfo);
|
|
BOOL(AInfo.iMinAnimate) := AValue;
|
|
SystemParametersInfo(SPI_SETANIMATION, SizeOf(AInfo), @AInfo, 0);
|
|
end;
|
|
|
|
{ TdxCustomRibbonForm }
|
|
|
|
constructor TdxCustomRibbonForm.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner); //CBUILDER workaround
|
|
end;
|
|
|
|
constructor TdxCustomRibbonForm.CreateNew(AOwner: TComponent; Dummy: Integer = 0);
|
|
begin
|
|
inherited CreateNew(AOwner, Dummy);
|
|
{$IFNDEF DELPHI12}
|
|
InitializeNewForm;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
destructor TdxCustomRibbonForm.Destroy;
|
|
begin
|
|
DestroyCornerRegions;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.FullUpdate;
|
|
begin
|
|
UpdateGlassFrame;
|
|
if HandleAllocated then
|
|
begin
|
|
UpdateSystemMenu;
|
|
SetWindowPos(Handle, 0, 0, 0, Width, Height, SWP_FRAMECHANGED or SWP_NOMOVE or
|
|
SWP_NOZORDER or SWP_NOACTIVATE);
|
|
FullRedrawWithChildren;
|
|
end;
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.GetCaptionHeightDelta(
|
|
AHasQuickAccessToolbar: Boolean): Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.Invalidate;
|
|
begin
|
|
if HandleAllocated and not IsIconic(Handle) then
|
|
CheckExtendFrame(IsZoomed(Handle));
|
|
inherited Invalidate;
|
|
if ClientHandle <> 0 then
|
|
InvalidateRect(ClientHandle, nil, True);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CreateWnd;
|
|
var
|
|
ClientCreateStruct: TClientCreateStruct;
|
|
begin
|
|
FExtendFrameAtTopHeight := -1;
|
|
inherited CreateWnd;
|
|
if not (csDesigning in ComponentState) and (FormStyle = fsMDIForm) then
|
|
begin
|
|
with ClientCreateStruct do
|
|
begin
|
|
idFirstChild := $FF00; //check
|
|
hWindowMenu := 0;
|
|
end;
|
|
FFakeClientHandle := Windows.CreateWindowEx(WS_EX_CLIENTEDGE, 'MDICLIENT',
|
|
nil, WS_CHILD or WS_VISIBLE or WS_GROUP or WS_TABSTOP or
|
|
WS_CLIPCHILDREN or WS_CLIPSIBLINGS or
|
|
MDIS_ALLCHILDSTYLES, 0, 0, ClientWidth, ClientHeight, Handle, 0,
|
|
HInstance, @ClientCreateStruct);
|
|
SetWindowPos(FFakeClientHandle, 0, -20, -20, 10, 10, SWP_NOACTIVATE or SWP_NOZORDER);
|
|
FOldClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
|
|
FDefClientProc := Pointer(GetWindowLong(FFakeClientHandle, GWL_WNDPROC));
|
|
FNewClientInstance := Classes.MakeObjectInstance(NewClientWndProc);
|
|
SetWindowLong(ClientHandle, GWL_WNDPROC, Longint(FNewClientInstance));
|
|
if ClientHandle <> 0 then
|
|
begin
|
|
SetWindowLong(ClientHandle, GWL_EXSTYLE,
|
|
GetWindowLong(ClientHandle, GWL_EXSTYLE) and not WS_EX_CLIENTEDGE);
|
|
InvalidateFrame(ClientHandle);
|
|
end;
|
|
end;
|
|
UpdateSystemMenu;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.DestroyWindowHandle;
|
|
begin
|
|
inherited DestroyWindowHandle;
|
|
if csDestroying in ComponentState then
|
|
RibbonNonClientHelper := nil;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.DoCreate;
|
|
begin
|
|
inherited DoCreate;
|
|
if UseSkin then
|
|
AdjustLayout;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.AdjustClientRect(var Rect: TRect);
|
|
begin
|
|
inherited;
|
|
if UseSkin and IsUseAeroNCPaint and IsZoomed(Handle) then
|
|
Inc(Rect.Top, dxGlassMaximizedNonClientHeight);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.AdjustLayout;
|
|
var
|
|
ALoadedHeight, AHeight, ADelta: Integer;
|
|
begin
|
|
if not CanAdjustLayout then Exit;
|
|
RibbonNonClientHelper.GetDesignInfo(ALoadedHeight, AHeight);
|
|
ADelta := AHeight - ALoadedHeight;
|
|
if WindowState <> wsMaximized then
|
|
ClientHeight := ClientHeight + ADelta - (GetSystemMetrics(SM_CYCAPTION) + GetDefaultWindowBordersWidth(Handle).Top);
|
|
ShiftControlsVertically(ADelta);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.AdjustSize;
|
|
{$IFDEF DELPHI11}
|
|
var
|
|
AFlags: Cardinal;
|
|
{$ENDIF}
|
|
begin
|
|
{$IFDEF DELPHI11}
|
|
if not (csLoading in ComponentState) and HandleAllocated then
|
|
begin
|
|
AFlags := SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOZORDER;
|
|
if IsZoomed(Handle) then
|
|
AFlags := AFlags or SWP_NOSIZE;
|
|
SetWindowPos(Handle, 0, 0, 0, Width, Height, AFlags);
|
|
RequestAlign;
|
|
end;
|
|
{$ELSE}
|
|
inherited AdjustSize;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
{$IFDEF DELPHI10}
|
|
type
|
|
TControlAccess = class(TControl);
|
|
|
|
procedure TdxCustomRibbonForm.AlignControls(AControl: TControl; var Rect: TRect);
|
|
|
|
function AlignWork: Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := True;
|
|
for I := ControlCount - 1 downto 0 do
|
|
if (Controls[I].Align <> alNone) or
|
|
(Controls[I].Anchors <> [akLeft, akTop]) then Exit;
|
|
Result := False;
|
|
end;
|
|
|
|
procedure UpdateTopmostControlBounds;
|
|
var
|
|
I: Integer;
|
|
AControl: TControl;
|
|
begin
|
|
for I := ControlCount - 1 downto 0 do
|
|
begin
|
|
AControl := Controls[I];
|
|
if RibbonNonClientHelper.IsTopmostControl(AControl) then
|
|
begin
|
|
TControlAccess(AControl).UpdateBoundsRect(cxRectSetTop(AControl.BoundsRect, -1));
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if FRibbonAlwaysOnTop and UseSkin and AlignWork then
|
|
UpdateTopmostControlBounds;
|
|
inherited AlignControls(AControl, Rect);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TdxCustomRibbonForm.CallDWMWindowProc(var Message);
|
|
begin
|
|
DwmDefWindowProc(Handle, TMessage(Message).Msg, TMessage(Message).WParam,
|
|
TMessage(Message).LParam, Integer(@TMessage(Message).Result));
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.CanAdjustLayout: Boolean;
|
|
begin
|
|
Result := AdjustLayoutForNonClientDrawing and
|
|
([csDesigning, csDestroying, csReading, csLoading] * ComponentState = []);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CaptionChanged;
|
|
begin
|
|
UpdateWindowStates;
|
|
RibbonNonClientHelper.CaptionChanged;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.NewClientWndProc(var Message: TMessage);
|
|
|
|
procedure Default;
|
|
begin
|
|
with Message do
|
|
Result := CallWindowProc(FDefClientProc, ClientHandle, Msg, wParam, lParam);
|
|
end;
|
|
|
|
procedure OldDefault;
|
|
begin
|
|
with Message do
|
|
Result := CallWindowProc(FOldClientProc, ClientHandle, Msg, wParam, lParam);
|
|
end;
|
|
|
|
function MaximizedChildren: Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to MDIChildCount - 1 do
|
|
if MDIChildren[I].WindowState = wsMaximized then
|
|
begin
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
Result := False;
|
|
end;
|
|
|
|
var
|
|
DC: HDC;
|
|
PS: TPaintStruct;
|
|
R: TRect;
|
|
// F: TForm;
|
|
AColor: TColor;
|
|
begin
|
|
if not UseSkin then
|
|
begin
|
|
with Message do
|
|
case Msg of
|
|
WM_NCHITTEST, WM_PAINT, WM_ERASEBKGND:
|
|
OldDefault;
|
|
WM_NCCALCSIZE:;
|
|
WM_NCPAINT:;
|
|
else
|
|
Default;
|
|
end;
|
|
Exit;
|
|
end;
|
|
with Message do
|
|
case Msg of
|
|
WM_KEYDOWN:
|
|
begin
|
|
KeyDown(WParamLo, KeyDataToShiftState(LParam));
|
|
if WParamLo = 0 then Exit;
|
|
Default;
|
|
end;
|
|
WM_NCHITTEST:
|
|
begin
|
|
Default;
|
|
if Result = HTCLIENT then Result := HTTRANSPARENT;
|
|
end;
|
|
WM_ERASEBKGND:
|
|
begin
|
|
AColor := GetBackgroundColor;
|
|
FillRectByColor(TWMEraseBkGnd(Message).DC, ClientRect, AColor);
|
|
// Erase the background at the location of an MDI client window
|
|
if (FormStyle = fsMDIForm) and (ClientHandle <> 0) then
|
|
begin
|
|
Windows.GetClientRect(ClientHandle, R);
|
|
FillRectByColor(TWMEraseBkGnd(Message).DC, R, AColor);
|
|
end;
|
|
Result := 1;
|
|
end;
|
|
WM_NCCALCSIZE:;
|
|
WM_NCPAINT:;
|
|
WM_MDIREFRESHMENU:
|
|
Result := 0;
|
|
WM_NCACTIVATE:
|
|
Message.Result := 1;
|
|
{
|
|
$3F://!
|
|
begin
|
|
Default;
|
|
F := ActiveMDIChild;
|
|
if (F <> nil) and MaximizedChildren then
|
|
begin
|
|
//correct maximized bounds
|
|
GetWindowRect(ClientHandle, R);
|
|
R.Right := R.Right - R.Left + (F.Width - F.ClientWidth);
|
|
R.Bottom := R.Bottom - R.Top + (F.Height - F.ClientHeight);
|
|
if (F is TdxCustomRibbonForm) and TdxCustomRibbonForm(F).UseSkin then
|
|
Inc(R.Bottom, TdxCustomRibbonForm(F).RibbonNonClientHelper.GetWindowCaptionHeight);
|
|
SetWindowPos(F.Handle, 0, 0, 0, R.Right, R.Bottom,
|
|
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOZORDER);
|
|
end;
|
|
end;
|
|
}
|
|
WM_PAINT:
|
|
begin
|
|
DC := TWMPaint(Message).DC;
|
|
if DC = 0 then
|
|
TWMPaint(Message).DC := BeginPaint(ClientHandle, PS);
|
|
try
|
|
if DC = 0 then
|
|
begin
|
|
R := cxGetWindowRect(ClientHandle);
|
|
R.TopLeft := ScreenToClient(R.TopLeft);
|
|
MoveWindowOrg(TWMPaint(Message).DC, -R.Left, -R.Top);
|
|
end;
|
|
PaintHandler(TWMPaint(Message));
|
|
finally
|
|
if DC = 0 then
|
|
EndPaint(ClientHandle, PS);
|
|
end;
|
|
end;
|
|
else
|
|
Default;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.DrawNonClientArea(ADrawCaption: Boolean; AUpdateRegion: HRGN = 1);
|
|
var
|
|
DC: HDC;
|
|
AFlags: Integer;
|
|
ARgn: HRGN;
|
|
AZoomed: Boolean;
|
|
begin
|
|
if IsUseAeroNCPaint then Exit;
|
|
UpdateWindowStates;
|
|
AFlags := DCX_CACHE or DCX_CLIPSIBLINGS or DCX_WINDOW or DCX_VALIDATE;
|
|
if AUpdateRegion <> 1 then
|
|
begin
|
|
ARgn := CreateRectRgnIndirect(cxEmptyRect);
|
|
CombineRgn(ARgn, AUpdateRegion, 0, RGN_COPY);
|
|
DC := GetDCEx(Handle, ARgn, AFlags or DCX_INTERSECTRGN);
|
|
end
|
|
else
|
|
DC := GetDCEx(Handle, 0, AFlags);
|
|
BarCanvas.BeginPaint(DC);
|
|
BarCanvas.Canvas.Lock;
|
|
try
|
|
if IsIconic(Handle) then
|
|
RibbonNonClientHelper.DrawWindowCaption(BarCanvas, Caption)
|
|
else
|
|
begin
|
|
AZoomed := IsZoomed(Handle);
|
|
if not AZoomed then
|
|
RibbonNonClientHelper.DrawWindowBorders(BarCanvas);
|
|
if ADrawCaption then
|
|
RibbonNonClientHelper.DrawWindowCaption(nil, Caption);
|
|
end;
|
|
finally
|
|
BarCanvas.Canvas.Unlock;
|
|
BarCanvas.EndPaint;
|
|
ReleaseDC(Handle, DC);
|
|
end;
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.HandleWithHelper(ADown: Boolean;
|
|
AButton: TMouseButton): Boolean;
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
Result := UseSkin;
|
|
if Result then
|
|
begin
|
|
P := GetMouseCursorPos;
|
|
if RibbonNonClientHelper.IsInCaptionArea(P.X, P.Y) then
|
|
begin
|
|
if ADown then
|
|
Result := RibbonNonClientHelper.MouseDown(P, AButton)
|
|
else
|
|
Result := RibbonNonClientHelper.MouseUp(P, AButton);
|
|
end
|
|
else
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.InitializeNewForm;
|
|
begin
|
|
{$IFDEF DELPHI12}
|
|
inherited InitializeNewForm;
|
|
{$ENDIF}
|
|
FAutoScroll := False;
|
|
FUseSkinColor := True;
|
|
FAdjustLayoutForNonClientDrawing := True;
|
|
AutoScroll := False;
|
|
KeyPreview := True;
|
|
CreateCornerRegions;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.KeyDown(var Key: Word; Shift: TShiftState);
|
|
var
|
|
I: Integer;
|
|
AIntf: IdxFormKeyPreviewListener;
|
|
AForm: TForm;
|
|
begin
|
|
inherited KeyDown(Key, Shift);
|
|
if KeyPreview then
|
|
begin
|
|
if FormStyle = fsMDIChild then
|
|
AForm := Application.MainForm
|
|
else
|
|
AForm := Self;
|
|
for I := 0 to AForm.ControlCount - 1 do
|
|
if Supports(TObject(AForm.Controls[I]), IdxFormKeyPreviewListener, AIntf) then
|
|
begin
|
|
AIntf.FormKeyDown(Key, Shift);
|
|
AIntf := nil;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.ModifySystemMenu(ASysMenu: THandle);
|
|
|
|
procedure UpdateMenuItems(AEnabledItems, ADisabledItems: array of Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to High(AEnabledItems) do
|
|
begin
|
|
if ((AEnabledItems[I] = SC_MINIMIZE) and not (biMinimize in BorderIcons)) or
|
|
((AEnabledItems[I] = SC_MAXIMIZE) and not (biMaximize in BorderIcons)) then
|
|
EnableMenuItem(ASysMenu, AEnabledItems[I], MF_BYCOMMAND or MF_GRAYED)
|
|
else
|
|
EnableMenuItem(ASysMenu, AEnabledItems[I], MF_BYCOMMAND);
|
|
end;
|
|
for I := 0 to High(ADisabledItems) do
|
|
EnableMenuItem(ASysMenu, ADisabledItems[I], MF_BYCOMMAND or MF_GRAYED);
|
|
end;
|
|
|
|
var
|
|
AStyles: Cardinal;
|
|
begin
|
|
if (BorderStyle <> bsNone) and (biSystemMenu in BorderIcons) and (FormStyle <> fsMDIChild) then
|
|
begin
|
|
AStyles := SetWindowInvisibleStyle(Handle);
|
|
if BorderStyle = bsDialog then
|
|
begin
|
|
DeleteMenu(ASysMenu, SC_TASKLIST, MF_BYCOMMAND);
|
|
DeleteMenu(ASysMenu, 7, MF_BYPOSITION);
|
|
DeleteMenu(ASysMenu, 5, MF_BYPOSITION);
|
|
DeleteMenu(ASysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
|
|
DeleteMenu(ASysMenu, SC_MINIMIZE, MF_BYCOMMAND);
|
|
DeleteMenu(ASysMenu, SC_SIZE, MF_BYCOMMAND);
|
|
DeleteMenu(ASysMenu, SC_RESTORE, MF_BYCOMMAND);
|
|
end
|
|
else
|
|
case WindowState of
|
|
wsNormal:
|
|
UpdateMenuItems([SC_MOVE, SC_SIZE, SC_MINIMIZE, SC_MAXIMIZE], [SC_RESTORE]);
|
|
wsMaximized:
|
|
UpdateMenuItems([SC_MINIMIZE, SC_RESTORE], [SC_MOVE, SC_SIZE, SC_MAXIMIZE]);
|
|
wsMinimized:
|
|
UpdateMenuItems([SC_MAXIMIZE, SC_RESTORE], [SC_MOVE, SC_SIZE, SC_MINIMIZE]);
|
|
end;
|
|
SetMenuDefaultItem(ASysMenu, SC_CLOSE, MF_BYCOMMAND);
|
|
RestoreWindowStyles(Handle, AStyles);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.Notification(AComponent: TComponent;
|
|
Operation: TOperation);
|
|
begin
|
|
if (Operation = opRemove) and (AComponent = FPrevActiveControl) then
|
|
FPrevActiveControl := nil;
|
|
inherited Notification(AComponent, Operation);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.Resize;
|
|
begin
|
|
if AlignDisabled then Exit;
|
|
inherited Resize;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.ShiftControlsVertically(ADelta: Integer);
|
|
var
|
|
I: Integer;
|
|
R: TRect;
|
|
begin
|
|
if ADelta = 0 then Exit;
|
|
DisableAlign;
|
|
try
|
|
for I := 0 to ControlCount - 1 do
|
|
with Controls[I] do
|
|
if Align in [alNone, alCustom] then
|
|
begin
|
|
if akBottom in Anchors then
|
|
begin
|
|
if akTop in Anchors then
|
|
begin
|
|
R := BoundsRect;
|
|
Inc(R.Top, ADelta);
|
|
BoundsRect := R;
|
|
end;
|
|
end
|
|
else
|
|
Top := Top + ADelta;
|
|
end;
|
|
finally
|
|
EnableAlign;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.UpdateNonClientArea;
|
|
begin
|
|
UpdateWindowStates;
|
|
if UseSkin and IsWindowVisible(Handle) then
|
|
begin
|
|
DrawNonClientArea(False);
|
|
RibbonNonClientHelper.UpdateNonClientArea;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.UpdateWindowRegion(AIsMaximized: Boolean);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if IsUseAeroNCPaint then Exit;
|
|
if AIsMaximized then
|
|
begin
|
|
//clip borders
|
|
R := cxGetWindowRect(Handle);
|
|
OffsetRect(R, -R.Left, -R.Top);
|
|
with GetDefaultWindowBordersWidth(Handle) do
|
|
R := cxRectInflate(R, -Left, -Top, -Right, -Bottom);
|
|
SetRegion(CreateRectRgnIndirect(R), True);
|
|
end
|
|
else
|
|
begin
|
|
SetRegion(RibbonNonClientHelper.GetWindowRegion, True);
|
|
CalculateCornerRegions;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.UpdateWindowStates;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if UseSkin and not (csDestroying in ComponentState) then
|
|
begin
|
|
FillChar(FData, SizeOf(TdxRibbonFormData), 0);
|
|
if HandleAllocated then
|
|
begin
|
|
FData.Handle := Handle;
|
|
R := cxGetWindowRect(Self);
|
|
OffsetRect(R, -R.Left, -R.Top);
|
|
FData.Bounds := R;
|
|
if IsIconic(Handle) then
|
|
FData.State := wsMinimized
|
|
else if IsZoomed(Handle) then
|
|
FData.State := wsMaximized
|
|
else
|
|
FData.State := wsNormal;
|
|
end;
|
|
FData.Active := FIsActive;
|
|
FData.Border := BorderStyle;
|
|
FData.Style := FormStyle;
|
|
FData.DontUseAero := DisableAero or (ParentWindow <> 0);
|
|
RibbonNonClientHelper.CheckWindowStates(FData);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.AfterResize(AIsRibbonVisible: Boolean;
|
|
ARibbonHeight: Integer; AIsZoomed: Boolean);
|
|
|
|
procedure CheckGlassFrame;
|
|
begin
|
|
if IsUseAeroNCPaint then
|
|
begin
|
|
if AIsZoomed then
|
|
SetRegion(0);
|
|
CheckExtendFrame(AIsZoomed);
|
|
end;
|
|
end;
|
|
|
|
var
|
|
ARibbonHandle: THandle;
|
|
begin
|
|
if AIsRibbonVisible then
|
|
begin
|
|
ARibbonHandle := RibbonNonClientHelper.Control.Handle;
|
|
if IsWindowVisible(ARibbonHandle) then
|
|
begin
|
|
SendMessage(ARibbonHandle, WM_SETREDRAW, 0, 0);
|
|
CheckGlassFrame;
|
|
EnableAlign;
|
|
if ARibbonHeight <> RibbonNonClientHelper.Control.Height then
|
|
begin
|
|
UpdateWindow(Handle);
|
|
//ensure redraw after restoring minimized ribbon for MDI form
|
|
if FormStyle = fsMDIForm then
|
|
RedrawWindow(ClientHandle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN);
|
|
end;
|
|
SendMessage(ARibbonHandle, WM_SETREDRAW, 1, 0);
|
|
RedrawWindow(ARibbonHandle, nil, 0, dxFullRedrawFlags or RDW_UPDATENOW);
|
|
end
|
|
else
|
|
begin
|
|
EnableAlign;
|
|
CheckGlassFrame;
|
|
end;
|
|
Resize;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.BeforeResize(out AIsRibbonVisible: Boolean;
|
|
out ARibbonHeight: Integer);
|
|
begin
|
|
AIsRibbonVisible := IsRibbonVisible;
|
|
if AIsRibbonVisible then
|
|
begin
|
|
ARibbonHeight := RibbonNonClientHelper.Control.Height;
|
|
DisableAlign;
|
|
end
|
|
else
|
|
ARibbonHeight := -1;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CalculateCornerRegions;
|
|
|
|
procedure CalculateRegion(ACornerRgn: HRGN; DX, DY: Integer; const ACornerRect: TRect);
|
|
var
|
|
R1, R2: HRGN;
|
|
begin
|
|
R1 := CreateRectRgnIndirect(cxEmptyRect);
|
|
GetWindowRgn(Handle, ACornerRgn);
|
|
GetWindowRgn(Handle, R1);
|
|
OffsetRgn(R1, DX, DY);
|
|
CombineRgn(ACornerRgn, ACornerRgn, R1, RGN_DIFF);
|
|
R2 := CreateRectRgnIndirect(ACornerRect);
|
|
CombineRgn(ACornerRgn, ACornerRgn, R2, RGN_AND);
|
|
DeleteObject(R1);
|
|
DeleteObject(R2);
|
|
end;
|
|
|
|
var
|
|
H: Integer;
|
|
begin
|
|
H := GetSystemMetrics(SM_CYCAPTION);
|
|
CalculateRegion(FCornerRegions[0], FSizingBorders.cx, FSizingBorders.cy,
|
|
cxRect(0, 0, H, H));
|
|
CalculateRegion(FCornerRegions[1], -FSizingBorders.cx, FSizingBorders.cy,
|
|
cxRect(Width - H, 0, Width, H));
|
|
CalculateRegion(FCornerRegions[2], -FSizingBorders.cx, -FSizingBorders.cy,
|
|
cxRect(Width - H, Height - H, Width, Height));
|
|
CalculateRegion(FCornerRegions[3], FSizingBorders.cx, -FSizingBorders.cy,
|
|
cxRect(0, Height - H, H, Height));
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CalculateZoomedOffsets;
|
|
var
|
|
ABData: TAppBarData;
|
|
begin
|
|
FZoomedBoundsOffsets := cxEmptyRect;
|
|
if IsNeedCorrectForAutoHideTaskBar then
|
|
begin
|
|
FillChar(ABData, sizeof(ABData), 0);
|
|
ABData.cbSize := sizeof(ABData);
|
|
ABData.hWnd := Handle;
|
|
SHAppBarMessage(ABM_GETTASKBARPOS, ABData);
|
|
if ABData.uEdge = ABE_LEFT then
|
|
FZoomedBoundsOffsets.Left := 1
|
|
else if (ABData.uEdge = ABE_TOP) and not IsUseAeroNCPaint then
|
|
FZoomedBoundsOffsets.Top := 1
|
|
else if ABData.uEdge = ABE_RIGHT then
|
|
FZoomedBoundsOffsets.Right := 1 + Ord(IsUseAeroNCPaint)
|
|
else if ABData.uEdge = ABE_BOTTOM then
|
|
FZoomedBoundsOffsets.Bottom := 1;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CheckExtendFrame(AZoomed: Boolean);
|
|
var
|
|
ANonClientHeight: Integer;
|
|
begin
|
|
if UseSkin and HandleAllocated and IsUseAeroNCPaint then
|
|
begin
|
|
ANonClientHeight := RibbonNonClientHelper.GetWindowCaptionHeight;
|
|
//prevent client area rendering beyond the screen if maximized
|
|
if AZoomed and (ANonClientHeight > 0) then
|
|
Inc(ANonClientHeight, dxGlassMaximizedNonClientHeight);
|
|
ExtendFrameIntoClientAreaAtTop(ANonClientHeight);
|
|
end;
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.GetUseSkin: Boolean;
|
|
begin
|
|
Result := FUseSkin and Assigned(FRibbonNonClientHelper) and
|
|
FRibbonNonClientHelper.Control.Visible;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.InvalidateFrame(AWnd: HWND; AUpdate: Boolean = False);
|
|
begin
|
|
SetWindowPos(AWnd, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or
|
|
SWP_NOZORDER or SWP_NOACTIVATE or SWP_DRAWFRAME);
|
|
if AUpdate then
|
|
UpdateWindow(AWnd);
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.IsNeedCorrectForAutoHideTaskBar: Boolean;
|
|
var
|
|
ABData : TAppBarData;
|
|
begin
|
|
FillChar(ABData, sizeof(ABData), 0);
|
|
ABData.cbSize := sizeof(ABData);
|
|
Result := ((SHAppBarMessage(ABM_GETSTATE, ABData) and ABS_AUTOHIDE) > 0) and
|
|
(MonitorFromWindow(FindWindow('Shell_TrayWnd', nil), MONITOR_DEFAULTTONEAREST) = Monitor.Handle);
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.IsNormalWindowState: Boolean;
|
|
begin
|
|
Result := not (IsIconic(Handle) or IsZoomed(Handle));
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.IsRibbonVisible: Boolean;
|
|
begin
|
|
Result := UseSkin and RibbonNonClientHelper.Control.HandleAllocated;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.ResetSystemMenu;
|
|
begin
|
|
if UseSkin and HandleAllocated then
|
|
GetSystemMenu(Handle, True);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.ResetWindowRegion;
|
|
begin
|
|
if not HandleAllocated then Exit;
|
|
SetRegion(0);
|
|
if IsCompositionEnabled then
|
|
begin
|
|
FExtendFrameAtTopHeight := -1;
|
|
Application.ProcessMessages; //it needs for vista after change window's region
|
|
if not UseSkin then
|
|
ExtendFrameIntoClientAreaAtTop(0)
|
|
else
|
|
begin
|
|
CheckExtendFrame(WindowState = wsMaximized);
|
|
UpdateNonClientArea;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.SetRedraw(ARedraw: Boolean);
|
|
begin
|
|
if not (HandleAllocated and Visible) then Exit;
|
|
if not ARedraw then
|
|
begin
|
|
Inc(FRedrawCount);
|
|
if FRedrawCount = 1 then
|
|
SendMessage(Handle, WM_SETREDRAW, 0, 0);
|
|
end
|
|
else
|
|
begin
|
|
Dec(FRedrawCount);
|
|
if FRedrawCount = 0 then
|
|
begin
|
|
SendMessage(Handle, WM_SETREDRAW, 1, 0);
|
|
FullRedrawWithChildren;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.SetAutoScroll(const Value: Boolean);
|
|
begin
|
|
//don't change
|
|
inherited AutoScroll := False;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.SetBorderStyle(const Value: TFormBorderStyle);
|
|
begin
|
|
if Value <> BorderStyle then
|
|
begin
|
|
inherited BorderStyle := Value;
|
|
ResetWindowRegion;
|
|
ForceUpdateWindowSize;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.SetDisableAero(const Value: Boolean);
|
|
begin
|
|
if FDisableAero <> Value then
|
|
begin
|
|
FDisableAero := Value;
|
|
ResetGlassFrame;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.SetPrevActiveControl(AValue: TWinControl);
|
|
begin
|
|
if (AValue <> FPrevActiveControl) then
|
|
begin
|
|
if Assigned(FPrevActiveControl) then
|
|
FPrevActiveControl.RemoveFreeNotification(Self);
|
|
FPrevActiveControl := AValue;
|
|
if Assigned(FPrevActiveControl) then
|
|
FPrevActiveControl.FreeNotification(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.SetRegion(ARegion: HRGN; ARedraw: Boolean = False);
|
|
begin
|
|
if not HandleAllocated then Exit;
|
|
SetWindowRgn(Handle, ARegion, ARedraw and IsWindowVisible(Handle));
|
|
end;
|
|
|
|
{$IFDEF DELPHI10}
|
|
procedure TdxCustomRibbonForm.SetRibbonAlwaysOnTop(const Value: Boolean);
|
|
begin
|
|
if FRibbonAlwaysOnTop <> Value then
|
|
begin
|
|
FRibbonAlwaysOnTop := Value;
|
|
Realign;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TdxCustomRibbonForm.SetRibbonNonClientHelper(const Value: TdxRibbonFormCaptionHelper);
|
|
begin
|
|
if FRibbonNonClientHelper <> Value then
|
|
begin
|
|
FRibbonNonClientHelper := Value;
|
|
FUseSkin := (Value <> nil) and (FRibbonNonClientHelper <> nil);
|
|
FExtendFrameAtTopHeight := -1;
|
|
if csDestroying in ComponentState then
|
|
FUseSkin := False
|
|
else
|
|
begin
|
|
UpdateWindowStates;
|
|
if HandleAllocated then
|
|
begin
|
|
if dxWMSetSkinnedMessage > 0 then
|
|
SendMessage(Handle, dxWMSetSkinnedMessage, Integer(UseSkin), 0);
|
|
ResetWindowRegion;
|
|
UpdateSystemMenu;
|
|
end;
|
|
if UseSkin then
|
|
RibbonNonClientHelper.CaptionChanged
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.SetUseSkinColor(const Value: Boolean);
|
|
begin
|
|
if FUseSkinColor <> Value then
|
|
begin
|
|
FUseSkinColor := Value;
|
|
if HandleAllocated then
|
|
InvalidateRect(Handle, nil, True);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.ShowSystemMenu(AFromMouse: Boolean);
|
|
var
|
|
P: TPoint;
|
|
R: TRect;
|
|
begin
|
|
if AFromMouse then
|
|
P := GetMouseCursorPos
|
|
else
|
|
begin
|
|
R := RibbonNonClientHelper.GetWindowSystemMenuBounds;
|
|
P.X := R.Left;
|
|
P.Y := R.Bottom;
|
|
P := ClientToScreen(P);
|
|
end;
|
|
RibbonNonClientHelper.ShowSystemMenu(P);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.ResetGlassFrame;
|
|
begin
|
|
UpdateWindowStates;
|
|
if UseSkin and HandleAllocated and IsWindowVisible(Handle) then
|
|
begin
|
|
SetRedraw(False);
|
|
try
|
|
ResetWindowRegion;
|
|
ForceUpdateWindowSize;
|
|
finally
|
|
SetRedraw(True);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.UpdateGlassFrame;
|
|
begin
|
|
UpdateWindowStates;
|
|
if UseSkin and HandleAllocated and UseAeroNCPaint(FData) and IsWindowVisible(Handle) then
|
|
begin
|
|
ResetWindowRegion;
|
|
if UseAeroNCPaint(FData) then
|
|
begin
|
|
FExtendFrameAtTopHeight := -1;
|
|
CheckExtendFrame(FData.State = wsMaximized);
|
|
RibbonNonClientHelper.CaptionChanged;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.UpdateSystemMenu;
|
|
begin
|
|
if UseSkin then
|
|
begin
|
|
RibbonNonClientHelper.InitWindowBorderIcons(GetFormBorderIcons);
|
|
ResetSystemMenu;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CMActionUpdate(var Message: TMessage);
|
|
|
|
function UpdateControlAction(AControl: TControl): Boolean;
|
|
begin
|
|
Result := (AControl <> nil) and
|
|
AControl.UpdateAction(TBasicAction(Message.LParam));
|
|
end;
|
|
|
|
function ProcessChildren(AContainer: TWinControl): Boolean;
|
|
var
|
|
I: Integer;
|
|
AControl: TControl;
|
|
begin
|
|
if AContainer.Showing then
|
|
for I := 0 to AContainer.ControlCount - 1 do
|
|
begin
|
|
AControl := AContainer.Controls[I];
|
|
if AControl.Visible and UpdateControlAction(AControl) or
|
|
(AControl is TWinControl) and ProcessChildren(TWinControl(AControl)) then
|
|
begin
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
end;
|
|
Result := False;
|
|
end;
|
|
|
|
begin
|
|
if (csDesigning in ComponentState) or not Showing then Exit;
|
|
if PrevActiveControl is TWinControl then
|
|
begin
|
|
UpdateControlAction(PrevActiveControl);
|
|
Message.Result := 1;
|
|
end
|
|
else
|
|
if UpdateControlAction(ActiveControl) or UpdateControlAction(Self) or ProcessChildren(Self) then
|
|
Message.Result := 1;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CMActivate(var Message: TCMActivate);
|
|
begin
|
|
FNeedCallActivate := True;
|
|
if not FDelayedActivate then
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CMColorChanged(var Message: TMessage);
|
|
begin
|
|
if UseSkin then
|
|
begin
|
|
if (FormStyle = fsMDIForm) and (ClientHandle <> 0) then
|
|
Windows.InvalidateRect(ClientHandle, nil, True);
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CMShowingChanged(var Message: TMessage);
|
|
|
|
function GetNonClientParts: TList;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := TList.Create;
|
|
for I := 0 to ControlCount - 1 do
|
|
if Controls[I].Visible and Supports(TObject(Controls[I]), IdxRibbonFormNonClientPart) then
|
|
Result.Add(Controls[I]);
|
|
end;
|
|
|
|
procedure HideRibbonControls(AList: TList);
|
|
var
|
|
I: Integer;
|
|
AControl: TWinControl;
|
|
begin
|
|
for I := 0 to AList.Count - 1 do
|
|
begin
|
|
AControl := TWinControl(AList[I]);
|
|
if AControl.HandleAllocated then
|
|
ShowWindow(AControl.Handle, SW_HIDE);
|
|
end;
|
|
end;
|
|
|
|
procedure ShowRibbonControls(AList: TList);
|
|
var
|
|
I: Integer;
|
|
AControl: TWinControl;
|
|
begin
|
|
for I := 0 to AList.Count - 1 do
|
|
begin
|
|
AControl := TWinControl(AList[I]);
|
|
if AControl.HandleAllocated then
|
|
begin
|
|
ShowWindow(AControl.Handle, SW_SHOWNA);
|
|
UpdateWindow(AControl.Handle);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
ANonClientParts: TList;
|
|
ANeedHideRibbonControls: Boolean;
|
|
begin
|
|
ANeedHideRibbonControls := Visible and FVisibleChanging;
|
|
FDelayedActivate := ANeedHideRibbonControls;
|
|
FNeedCallActivate := False;
|
|
ANonClientParts := GetNonClientParts;
|
|
try
|
|
if ANeedHideRibbonControls then
|
|
HideRibbonControls(ANonClientParts);
|
|
inherited;
|
|
finally
|
|
UpdateGlassFrame;
|
|
if ANeedHideRibbonControls then
|
|
ShowRibbonControls(ANonClientParts);
|
|
FreeAndNil(ANonClientParts);
|
|
FDelayedActivate := False;
|
|
if FNeedCallActivate then Perform(CM_ACTIVATE, 0, 0);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CMVisibleChanged(var Message: TMessage);
|
|
var
|
|
Animation: Boolean;
|
|
begin
|
|
FVisibleChanging := True;
|
|
try
|
|
if UseSkin and Visible and HandleAllocated and (FormStyle = fsMDIChild) then
|
|
begin
|
|
Animation := GetAnimation;
|
|
if Animation then SetAnimation(False);
|
|
inherited;
|
|
if Animation then SetAnimation(True);
|
|
end
|
|
else
|
|
inherited;
|
|
finally
|
|
FVisibleChanging := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMCancelMode(var Message: TWMCancelMode);
|
|
begin
|
|
if UseSkin then
|
|
RibbonNonClientHelper.CancelMode;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMCaptureChanged(var Message: TMessage);
|
|
begin
|
|
if UseSkin and (THandle(Message.LParam) <> Handle) then
|
|
begin
|
|
FSizingLoop := False;
|
|
RibbonNonClientHelper.CancelMode;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMDisplayChange(var Message: TMessage);
|
|
var
|
|
AWindowPlacement: TWindowPlacement;
|
|
AWindowRect, ANormalRect: TRect;
|
|
begin
|
|
if Useskin and (WindowState = wsMaximized) then
|
|
begin
|
|
AWindowPlacement.Length := SizeOf(AWindowPlacement);
|
|
GetWindowPlacement(Handle, @AWindowPlacement);
|
|
GetWindowRect(Handle, AWindowRect);
|
|
ANormalRect := AWindowPlacement.rcNormalPosition;
|
|
AWindowPlacement.rcNormalPosition := AWindowRect;
|
|
SetWindowPlacement(Handle, @AWindowPlacement);
|
|
WindowState := wsNormal;
|
|
inherited;
|
|
WindowState := wsMaximized;
|
|
AWindowPlacement.rcNormalPosition := ANormalRect;
|
|
SetWindowPlacement(Handle, @AWindowPlacement);
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMEraseBkgnd(var Message: TWMEraseBkgnd);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if UseSkin and (IsUseAeroNCPaint or not DoubleBuffered or (TMessage(Message).wParam = TMessage(Message).lParam)) then
|
|
begin
|
|
R := ClientRect;
|
|
//reduce flickering
|
|
if IsUseAeroNCPaint then
|
|
Inc(R.Top, FExtendFrameAtTopHeight);
|
|
if not cxRectIsEmpty(R) then
|
|
FillRectByColor(Message.DC, R, GetBackgroundColor);
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMInitMenu(var Message: TWMInitMenu);
|
|
begin
|
|
Message.Menu := GetSystemMenu(Handle, False);
|
|
inherited;
|
|
ModifySystemMenu(Message.Menu);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMLButtonDown(var Message: TWMLButtonDown);
|
|
begin
|
|
if HandleWithHelper(True, mbLeft) then
|
|
UpdateNonClientArea
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMLButtonUp(var Message: TWMLButtonUp);
|
|
begin
|
|
if UseSkin then
|
|
begin
|
|
if HandleWithHelper(False, mbLeft) then
|
|
Message.Result := 0
|
|
else
|
|
begin
|
|
RibbonNonClientHelper.CancelMode;
|
|
inherited;
|
|
end;
|
|
end
|
|
else inherited
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMRButtonDown(var Message: TWMRButtonDown);
|
|
begin
|
|
if HandleWithHelper(True, mbRight) then
|
|
Message.Result := 0
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMRButtonUp(var Message: TWMRButtonUp);
|
|
begin
|
|
if HandleWithHelper(False, mbRight) then
|
|
Message.Result := 0
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMNCRButtonUp(var Message: TWMNCRButtonUp);
|
|
begin
|
|
if HandleWithHelper(False, mbRight) then
|
|
Message.Result := 0
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMNCActivate(var Message: TWMNCActivate);
|
|
var
|
|
AStyles: Cardinal;
|
|
begin
|
|
FIsActive := Message.Active;
|
|
if UseSkin then
|
|
begin
|
|
UpdateWindowStates;
|
|
if (FormStyle = fsMDIChild) or IsUseAeroNCPaint then // AB15017 only on XP
|
|
begin // Aero required to call a default method
|
|
AStyles := SetWindowInvisibleStyle(Handle);
|
|
Message.Result := DefWindowProc(Handle, WM_NCACTIVATE, TMessage(Message).WParam, 0);
|
|
RestoreWindowStyles(Handle, AStyles);
|
|
end
|
|
else
|
|
Message.Result := 1; //B20794
|
|
if not (csDestroying in ComponentState) then
|
|
begin
|
|
if not FIsActive then
|
|
RibbonNonClientHelper.CancelMode;
|
|
UpdateNonClientArea
|
|
end;
|
|
if (FormStyle = fsMDIForm) and (ActiveMDIChild <> nil) then
|
|
ActiveMDIChild.Perform(WM_NCACTIVATE, Ord(IsActive), 0);
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMNCCalcSize(var Message: TWMNCCalcSize);
|
|
var
|
|
R, SaveR0: TRect;
|
|
T: Integer;
|
|
AIsZoomed: Boolean;
|
|
begin
|
|
if not (UseSkin and Visible and not IsIconic(Handle) and not (csReading in ComponentState)) then
|
|
inherited
|
|
else
|
|
begin
|
|
if Message.CalcValidRects then
|
|
begin
|
|
AIsZoomed := IsZoomed(Handle);
|
|
if IsUseAeroNCPaint then
|
|
begin
|
|
T := Message.CalcSize_Params^.rgrc[0].Top;
|
|
inherited;
|
|
SaveR0 := Message.CalcSize_Params^.rgrc[0];
|
|
SaveR0.Top := T;
|
|
end
|
|
else
|
|
begin
|
|
R := GetCurrentBordersWidth;
|
|
SaveR0 := Message.CalcSize_Params^.rgrc[0];
|
|
with Message.CalcSize_Params^.rgrc[0] do
|
|
begin
|
|
Inc(SaveR0.Top, R.Top);
|
|
Dec(SaveR0.Bottom, R.Bottom);
|
|
Inc(SaveR0.Left, R.Left);
|
|
Dec(SaveR0.Right, R.Right);
|
|
end;
|
|
end;
|
|
if AIsZoomed then
|
|
begin
|
|
if FormStyle = fsMDIChild then
|
|
Inc(SaveR0.Top, GetDefaultWindowNCSize(Handle).Top - RibbonNonClientHelper.GetWindowCaptionHeight)
|
|
else
|
|
begin
|
|
CalculateZoomedOffsets; //check for Taskbar autohide
|
|
CorrectZoomedBounds(SaveR0);
|
|
end;
|
|
end;
|
|
Message.CalcSize_Params^.rgrc[0] := SaveR0;
|
|
end
|
|
else
|
|
inherited;
|
|
Message.Result := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMNCHitTest(var Message: TWMNCHitTest);
|
|
var
|
|
R: TRect;
|
|
P: TPoint;
|
|
begin
|
|
if UseSkin then
|
|
begin
|
|
Message.Result := HTNOWHERE;
|
|
if IsUseAeroNCPaint then
|
|
begin
|
|
CallDWMWindowProc(Message);
|
|
if Message.Result = HTNOWHERE then
|
|
inherited;
|
|
if not ((Message.Result = HTCAPTION) or (Message.Result = HTCLIENT)) then
|
|
Exit;
|
|
Message.Result := HTNOWHERE;
|
|
end;
|
|
R := cxGetWindowRect(Handle);
|
|
P := cxPoint(Message.XPos - R.Left, Message.YPos - R.Top);
|
|
if (BorderStyle in [bsSizeable, bsSizeToolWin]) then
|
|
CheckResizingNCHitTest(Message.Result, P);
|
|
if (Message.Result = HTNOWHERE) and RibbonNonClientHelper.IsInCaptionArea(Message.XPos, Message.YPos) then
|
|
RibbonNonClientHelper.GetWindowCaptionHitTest(Message);
|
|
if Message.Result = HTNOWHERE then
|
|
Message.Result := HTCLIENT;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMShowWindow(var Message: TMessage);
|
|
begin
|
|
inherited;
|
|
if WordBool(Message.WParam) and UseSkin and IsNormalWindowState then
|
|
begin
|
|
//for a showing MDIChild on vista without DWM
|
|
//make sure for WM_SIZE & WM_NCCALCSIZE
|
|
SetWindowPos(Handle, 0, 0, 0, Width, Height, SWP_NOZORDER or SWP_NOACTIVATE or
|
|
SWP_NOMOVE or SWP_FRAMECHANGED);
|
|
|
|
RibbonNonClientHelper.InitWindowBorderIcons(GetFormBorderIcons);
|
|
CaptionChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMNCPaint(var Message: TMessage);
|
|
begin
|
|
if UseSkin then
|
|
begin
|
|
if IsUseAeroNCPaint then
|
|
inherited;
|
|
DrawNonClientArea(False, Message.WParam);
|
|
Message.Result := 0;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMPaint(var Message: TWMPaint);
|
|
begin
|
|
if UseSkin then
|
|
begin
|
|
UpdateWindowStates;
|
|
if IsUseAeroNCPaint then
|
|
ExcludeRibbonPaintArea(Message.DC);
|
|
inherited;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMSize(var Message: TWMSize);
|
|
var
|
|
AIsRibbonVisible: Boolean;
|
|
ARibbonHeight: Integer;
|
|
begin
|
|
if UseSkin and not (csReading in ComponentState) then
|
|
begin
|
|
UpdateWindowStates;
|
|
BeforeResize(AIsRibbonVisible, ARibbonHeight);
|
|
try
|
|
RibbonNonClientHelper.Resize;
|
|
inherited;
|
|
FSizingBorders.cx := GetSystemMetrics(SM_CXSIZEFRAME);
|
|
FSizingBorders.cy := GetSystemMetrics(SM_CYSIZEFRAME);
|
|
UpdateWindowRegion(Message.SizeType = SIZE_MAXIMIZED);
|
|
finally
|
|
AfterResize(AIsRibbonVisible, ARibbonHeight, Message.SizeType = SIZE_MAXIMIZED);
|
|
end;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMSysCommand(var Message: TWMSysCommand);
|
|
var
|
|
ACommand: Word;
|
|
Animation: Boolean;
|
|
begin
|
|
if UseSkin then
|
|
begin
|
|
ACommand := Message.CmdType and $FFF0;
|
|
if (ACommand = SC_KEYMENU) and (Message.Key = $20) then
|
|
begin
|
|
ShowSystemMenu(False);
|
|
Message.Result := 0;
|
|
end
|
|
else
|
|
begin
|
|
if (FormStyle = fsMDIChild) and ((ACommand = SC_MAXIMIZE) or
|
|
(ACommand = SC_MINIMIZE) or (ACommand = SC_RESTORE))then
|
|
begin
|
|
Animation := GetAnimation;
|
|
if Animation then SetAnimation(False);
|
|
inherited;
|
|
if Animation then SetAnimation(True);
|
|
end
|
|
else
|
|
inherited;
|
|
case ACommand of
|
|
SC_MAXIMIZE, SC_RESTORE:
|
|
UpdateNonClientArea;
|
|
else
|
|
UpdateWindowStates;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMWindowPosChanged(var Message: TWMWindowPosChanged);
|
|
begin
|
|
UpdateWindowStates;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMDWMCompositionChanged(var Message: TMessage);
|
|
begin
|
|
inherited;
|
|
if UseSkin then
|
|
begin
|
|
ResetGlassFrame;
|
|
Message.Result := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WndProc(var Message: TMessage);
|
|
begin
|
|
if not UseSkin then
|
|
inherited WndProc(Message)
|
|
else
|
|
with Message do
|
|
begin
|
|
case Msg of
|
|
WM_SYSMENU:
|
|
begin
|
|
if IsWindowEnabled(Handle) then //B136020
|
|
ShowSystemMenu(True);
|
|
Result := 0;
|
|
end;
|
|
WM_ENTERSIZEMOVE:
|
|
begin
|
|
FSizingLoop := True;
|
|
inherited WndProc(Message);
|
|
end;
|
|
WM_EXITSIZEMOVE:
|
|
begin
|
|
FSizingLoop := False;
|
|
inherited WndProc(Message);
|
|
UpdateNonClientArea;
|
|
end;
|
|
WM_NCUAHDRAWCAPTION,
|
|
WM_NCUAHDRAWFRAME:
|
|
begin
|
|
if IsUseAeroNCPaint then
|
|
CallDWMWindowProc(Message);
|
|
DrawNonClientArea(True);
|
|
Message.Result := 0;
|
|
end;
|
|
WM_QUERYOPEN, WM_EXITMENULOOP: //WM_MENUCHAR
|
|
begin
|
|
ResetSystemMenu;
|
|
inherited WndProc(Message);
|
|
end;
|
|
WM_MOUSEACTIVATE, WM_SYNCPAINT:
|
|
begin
|
|
inherited WndProc(Message);
|
|
DrawNonClientArea(True);
|
|
end;
|
|
WM_NCLBUTTONDOWN:
|
|
begin
|
|
if not IsUseAeroNCPaint then
|
|
UpdateWindow(Handle);
|
|
inherited WndProc(Message);
|
|
if IsIconic(Handle) then
|
|
begin
|
|
DrawNonClientArea(True);
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
WM_NCMOUSELEAVE:
|
|
begin
|
|
if IsUseAeroNCPaint then
|
|
CallDWMWindowProc(Message)
|
|
else
|
|
inherited;
|
|
end;
|
|
WM_LBUTTONDOWN:
|
|
begin
|
|
//dmAutomatic suppress a dispatching
|
|
if (DragMode = dmAutomatic) and not IsUseAeroNCPaint then
|
|
if HandleWithHelper(True, mbLeft) then
|
|
Exit;
|
|
inherited;
|
|
end;
|
|
else
|
|
if (dxWMGetSkinnedMessage <> 0) and (Msg = dxWMGetSkinnedMessage) then
|
|
begin
|
|
Result := Ord(UseSkin);
|
|
Exit;
|
|
end;
|
|
inherited;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.IsUseAeroNCPaint: Boolean;
|
|
begin
|
|
Result := UseAeroNCPaint(FData);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CheckResizingNCHitTest(var AHitTest: Integer; const P: TPoint);
|
|
const
|
|
CornerHitTests: array[0..3] of DWORD = (HTTOPLEFT, HTTOPRIGHT, HTBOTTOMRIGHT, HTBOTTOMLEFT);
|
|
var
|
|
I: Integer;
|
|
R, RW: TRect;
|
|
begin
|
|
if not IsNormalWindowState then Exit;
|
|
for I := 0 to 3 do
|
|
if PtInRegion(FCornerRegions[I], P.X, P.Y) then
|
|
begin
|
|
AHitTest := CornerHitTests[I];
|
|
Break;
|
|
end;
|
|
if AHitTest = HTNOWHERE then
|
|
begin
|
|
RW := cxGetWindowRect(Handle);
|
|
OffsetRect(RW, -RW.Left, -RW.Top);
|
|
R := RW;
|
|
R.Bottom := R.Top + FSizingBorders.cy;
|
|
if cxRectPtIn(R, P) then
|
|
AHitTest := HTTOP
|
|
else
|
|
if not IsUseAeroNCPaint then
|
|
begin
|
|
R := RW;
|
|
R.Left := R.Right - FSizingBorders.cx;
|
|
if cxRectPtIn(R, P) then
|
|
AHitTest := HTRIGHT
|
|
else
|
|
begin
|
|
R := RW;
|
|
R.Top := R.Bottom - FSizingBorders.cy;
|
|
if cxRectPtIn(R, P) then
|
|
AHitTest := HTBOTTOM
|
|
else
|
|
begin
|
|
R := RW;
|
|
R.Right := R.Left + FSizingBorders.cx;
|
|
if cxRectPtIn(R, P) then
|
|
AHitTest := HTLEFT;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CreateCornerRegions;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to 3 do
|
|
FCornerRegions[I] := CreateRectRgnIndirect(cxEmptyRect);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.DestroyCornerRegions;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to 3 do
|
|
DeleteObject(FCornerRegions[I]);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.ExcludeRibbonPaintArea(DC: HDC);
|
|
var
|
|
R, CR: HRGN;
|
|
ARibbonRect: TRect;
|
|
begin
|
|
if FExtendFrameAtTopHeight = 0 then Exit;
|
|
R := GetClipRegion(DC);
|
|
ARibbonRect := cxRect(0, 0, ClientWidth, FExtendFrameAtTopHeight);
|
|
CR := CreateRectRgnIndirect(ARibbonRect);
|
|
SelectClipRgn(DC, CR);
|
|
FillRect(DC, ARibbonRect, GetStockObject(BLACK_BRUSH));
|
|
CombineRgn(R, R, CR, RGN_DIFF);
|
|
SelectClipRgn(DC, R);
|
|
DeleteObject(R);
|
|
DeleteObject(CR);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.ForceUpdateWindowSize;
|
|
begin
|
|
if UseSkin and HandleAllocated then
|
|
begin
|
|
if not UseAeroNCPaint(FData) and IsNormalWindowState then
|
|
begin
|
|
SetRegion(RibbonNonClientHelper.GetWindowRegion, True);
|
|
CalculateCornerRegions;
|
|
end;
|
|
RibbonNonClientHelper.CaptionChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.FullRedrawWithChildren;
|
|
begin
|
|
WinControlFullInvalidate(Self, True, True);
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.ExtendFrameIntoClientAreaAtTop(AHeight: Integer);
|
|
var
|
|
M: TdxMargins;
|
|
DC: HDC;
|
|
R: TRect;
|
|
begin
|
|
if HandleAllocated and (FExtendFrameAtTopHeight <> AHeight) then
|
|
begin
|
|
if AHeight > FExtendFrameAtTopHeight then
|
|
begin
|
|
R := cxRect(0, FExtendFrameAtTopHeight, Width, AHeight);
|
|
if not FVisibleChanging then
|
|
Inc(R.Left, 100);
|
|
if not cxRectIsEmpty(R) then
|
|
begin
|
|
DC := GetWindowDC(Handle);
|
|
FillRect(DC, R, GetStockObject(BLACK_BRUSH));
|
|
ReleaseDC(Handle, DC);
|
|
end;
|
|
end;
|
|
FExtendFrameAtTopHeight := AHeight;
|
|
M.cxLeftWidth := 0;
|
|
M.cxRightWidth := 0;
|
|
M.cyBottomHeight := 0;
|
|
M.cyTopHeight := AHeight;
|
|
DwmExtendFrameIntoClientArea(Handle, @M);
|
|
if IsWindowVisible(Handle) then
|
|
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_UPDATENOW);
|
|
end;
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.GetFormBorderIcons: TBorderIcons;
|
|
var
|
|
ABorderStyle: TFormBorderStyle;
|
|
begin
|
|
ABorderStyle := BorderStyle;
|
|
if (FormStyle = fsMDIChild) and (ABorderStyle in [bsNone, bsDialog]) then
|
|
ABorderStyle := bsSizeable;
|
|
Result := BorderIcons;
|
|
case ABorderStyle of
|
|
bsNone: Result := [];
|
|
bsDialog: Result := (Result * [biSystemMenu, biHelp]) - [biMaximize];
|
|
bsToolWindow,
|
|
bsSizeToolWin: Result := Result * [biSystemMenu];
|
|
end;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.CorrectZoomedBounds(var R: TRect);
|
|
begin
|
|
Inc(R.Left, FZoomedBoundsOffsets.Left);
|
|
Inc(R.Top, FZoomedBoundsOffsets.Top);
|
|
Dec(R.Right, FZoomedBoundsOffsets.Right);
|
|
Dec(R.Bottom, FZoomedBoundsOffsets.Bottom);
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.GetCurrentBordersWidth: TRect;
|
|
begin
|
|
if IsZoomed(Handle) then
|
|
begin
|
|
Result := GetDefaultWindowBordersWidth(Handle);
|
|
if FormStyle = fsMDIChild then
|
|
Result.Top := 0;
|
|
end
|
|
else
|
|
Result := RibbonNonClientHelper.GetWindowBordersWidth;
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.GetBorderStyle: TFormBorderStyle;
|
|
begin
|
|
Result := inherited BorderStyle;
|
|
end;
|
|
|
|
function TdxCustomRibbonForm.GetBackgroundColor: TColor;
|
|
begin
|
|
if UseSkin and UseSkinColor then
|
|
Result := RibbonNonClientHelper.GetWindowColor
|
|
else
|
|
Result := Color;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMGetText(var Message: TWMGetText);
|
|
var
|
|
L: Integer;
|
|
begin
|
|
if (csLoading in ComponentState) or UseSkin then
|
|
begin
|
|
L := Length(FCaption) + 1; //include the terminating null character
|
|
if Message.TextMax < L then
|
|
L := Message.TextMax;
|
|
if L > 1 then
|
|
Move(Pointer(FCaption)^, Pointer(Message.Text)^, L * SizeOf(Char));
|
|
Message.Result := L - 1;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMGetTextLength(var Message: TWMGetTextLength);
|
|
begin
|
|
if (csLoading in ComponentState) or UseSkin then
|
|
Message.Result := Length(FCaption)
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxCustomRibbonForm.WMSetText(var Message: TWMSetText);
|
|
|
|
function IsMaximizedChildForRibbonForm: Boolean;
|
|
var
|
|
AForm: TdxCustomRibbonForm;
|
|
begin
|
|
Result := False;
|
|
if (FormStyle = fsMDIChild) and IsZoomed(Handle) and
|
|
(Application.MainForm is TdxCustomRibbonForm) then
|
|
begin
|
|
AForm := TdxCustomRibbonForm(Application.MainForm);
|
|
Result := AForm.UseSkin;
|
|
end;
|
|
end;
|
|
|
|
procedure UpdateMDIForm;
|
|
begin
|
|
if IsMaximizedChildForRibbonForm then
|
|
TdxCustomRibbonForm(Application.MainForm).CaptionChanged;
|
|
end;
|
|
|
|
begin
|
|
if (csLoading in ComponentState) or UseSkin then
|
|
begin
|
|
FCaption := Message.Text;
|
|
if UseSkin then
|
|
begin
|
|
CaptionChanged;
|
|
UpdateMDIForm;
|
|
Perform(CM_TEXTCHANGED, 0, 0);
|
|
if GetWindowLong(Handle, GWL_EXSTYLE) and WS_EX_APPWINDOW = WS_EX_APPWINDOW then
|
|
SetWindowTextWithoutRedraw(Handle, RibbonNonClientHelper.GetTaskBarCaption);
|
|
end
|
|
else
|
|
begin
|
|
inherited;
|
|
UpdateMDIForm;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if not IsThemeActive and IsMaximizedChildForRibbonForm then
|
|
begin
|
|
Perform(CM_TEXTCHANGED, 0, 0);
|
|
SetWindowTextWithoutRedraw(Handle, Message.Text);
|
|
end
|
|
else
|
|
inherited;
|
|
UpdateMDIForm;
|
|
end;
|
|
end;
|
|
|
|
initialization
|
|
if Win32MajorVersion >= 6 then
|
|
BufferedPaintInit;
|
|
|
|
finalization
|
|
if Win32MajorVersion >= 6 then
|
|
BufferedPaintUnInit;
|
|
|
|
end.
|
|
|
|
|