📄 dxribbonformcaptionhelper.pas
字号:
procedure TdxRibbonFormCaptionHelper.InitWindowBorderIcons(
const AIcons: TBorderIcons);
begin
FBorderIcons := AIcons;
FHotBorderIcon := tbiNone;
FPressedBorderIcon := tbiNone;
Calculate;
end;
function TdxRibbonFormCaptionHelper.IsInCaptionArea(X, Y: Integer): Boolean;
var
P: TPoint;
begin
Result := (FFormCaptionRegions[rfrWindow] <> 0) and Valid;
if Result then
begin
if FormData.State = wsMinimized then
Result := True
else
begin
P := Control.ScreenToClient(cxPoint(X, Y));
Result := PtInRegion(FFormCaptionRegions[rfrNCHitTest], P.X, P.Y)
end;
end;
end;
procedure TdxRibbonFormCaptionHelper.Resize;
begin
Calculate;
IRibbonFormNonClientDraw.RibbonFormResized;
end;
function TdxRibbonFormCaptionHelper.GetApplicationButtonRegion: HRGN;
begin
if (FormData.Handle <> 0) and (FormData.State <> wsMinimized) then
Result := IRibbonFormNonClientDraw.GetRibbonApplicationButtonRegion
else
Result := 0;
end;
procedure TdxRibbonFormCaptionHelper.BufferedDrawCaption(ADestCanvas: TcxCanvas;
const ACaption: TCaption);
var
R1, R2: HRGN;
begin
ADestCanvas.SaveDC;
try
FBitmap.cxCanvas.FillRect(cxRect(0, 0, FBitmap.Width, FBitmap.Height), clBlack);
IRibbonFormNonClientDraw.DrawRibbonFormCaption(FBitmap.cxCanvas,
FFormCaptionDrawBounds, ACaption, FormData);
DrawBorderIcons(FBitmap.cxCanvas);
if FormData.State <> wsMinimized then
begin
R1 := GetClipRegion(ADestCanvas.Handle);
R2 := GetFormCaptionRegionsForDC(ADestCanvas.Handle, rfrClient);
CombineRgn(R2, R2, R1, RGN_AND);
SelectClipRgn(ADestCanvas.Handle, R2);
DeleteObject(R1);
DeleteObject(R2);
end;
BitBlt(ADestCanvas.Handle, 0, 0, Control.Width, Control.Height,
FBitmap.cxCanvas.Handle, 0, 0, SRCCOPY);
finally
ADestCanvas.RestoreDC;
end;
end;
procedure TdxRibbonFormCaptionHelper.DrawWindowBorders(ACanvas: TcxCanvas);
begin
IRibbonFormNonClientDraw.DrawRibbonFormBorders(ACanvas, FormData, GetWindowBordersWidth);
end;
procedure TdxRibbonFormCaptionHelper.DrawWindowCaption(ACanvas: TcxCanvas;
const ACaption: TCaption);
var
ASaveIndex: Integer;
begin
if Valid then
begin
if FIsClientDrawing or UseAeroNCPaint(FormData) then
begin
ASaveIndex := SaveDC(Control.Canvas.Handle);
SelectClipRgn(Control.Canvas.Handle, FFormCaptionRegions[rfrClient]);
IRibbonFormNonClientDraw.DrawRibbonFormCaption(Control.Canvas,
FFormCaptionDrawBounds, ACaption, FormData);
DrawBorderIcons(Control.Canvas);
RestoreDC(Control.Canvas.Handle, ASaveIndex);
ExcludeCaptionRgn(Control.Canvas.Handle);
end
else
if FormData.State = wsMinimized then
BufferedDrawCaption(ACanvas, ACaption)
else
begin
BufferedDrawCaption(Control.ActiveCanvas, ACaption);
ExcludeCaptionRgn(Control.ActiveCanvas.Handle);
end;
end;
end;
procedure TdxRibbonFormCaptionHelper.GetDesignInfo(out ALoadedHeight, ACurrentHeight: Integer);
begin
ALoadedHeight := IRibbonFormNonClientDraw.GetRibbonLoadedHeight;
ACurrentHeight := Control.Height;
end;
procedure TdxRibbonFormCaptionHelper.CalculateBorderIcons;
var
R: TRect;
I, AIcon: TBorderIcon;
H: Integer;
AIconSize: TSize;
begin
if UseAeroNCPaint(FormData) then
begin
if FormData.Handle <> 0 then
DwmGetWindowAttribute(FormData.Handle, DWMWA_CAPTION_BUTTON_BOUNDS, @FBorderIconsArea, SizeOf(R));
Exit;
end;
if (FormData.Handle <> 0) and not (FormData.Border in [bsToolWindow, bsSizeToolWin]) then
AIconSize := cxSize(GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE))
else
AIconSize := cxSize(GetSystemMetrics(SM_CXSMSIZE), GetSystemMetrics(SM_CYSMSIZE));
H := GetWindowCaptionHeight - AIconSize.cy;
R := GetClientRect;
R.Top := H - (H div 2);
R.Bottom := R.Top + AIconSize.cy;
R.Left := R.Right - AIconSize.cx;
if (FormData.Handle <> 0) and (FormData.State = wsMinimized) then
Dec(R.Bottom);
FBorderIconsArea := R;
for I := Low(TBorderIcon) to High(TBorderIcon) do
begin
AIcon := BorderIconOrder[I];
if AIcon in FBorderIcons then
begin
FBorderIconBounds[AIcon] := R;
FBorderIconsArea.Left := R.Left;
OffsetRect(R, -AIconSize.cx, 0);
end
else
FBorderIconBounds[AIcon] := cxEmptyRect;
end;
end;
procedure TdxRibbonFormCaptionHelper.CalculateFormCaption;
begin
DestroyCaptionRegions;
FFormCaptionRegions[rfrWindow] := GetWindowCaptionRegion;
FFormCaptionRegions[rfrClient] := GetClientCaptionRegion;
FFormCaptionRegions[rfrNCHitTest] := GetNCHitTestRegion;
FFormCaptionDrawBounds := GetFormCaptionDrawBounds;
if Abs(cxRectWidth(FFormCaptionDrawBounds)) > 10000 then
begin
FFormCaptionDrawBounds.Left := 0;
FFormCaptionDrawBounds := GetFormCaptionDrawBounds;
end;
{$IFDEF DELPHI10}
FBitmap.SetSize(cxRectWidth(FFormCaptionDrawBounds), GetWindowCaptionHeight);
{$ELSE}
FBitmap.Width := cxRectWidth(FFormCaptionDrawBounds);
FBitmap.Height := GetWindowCaptionHeight;
{$ENDIF}
end;
function TdxRibbonFormCaptionHelper.CanProcessFormCaptionHitTest(X, Y: Integer): Boolean;
var
P: TPoint;
begin
Result := (FFormCaptionRegions[rfrNCHitTest] <> 0) and (GetCapture = 0);
if Result then
begin
P := Control.ScreenToClient(Point(X, Y));
Result := PtInRegion(FFormCaptionRegions[rfrNCHitTest], P.X, P.Y);
end;
end;
procedure TdxRibbonFormCaptionHelper.CalculateSysMenuIconBounds;
var
AHasSysMenu: Boolean;
R: TRect;
H: Integer;
begin
FSysMenuBounds := cxEmptyRect;
FSysMenuIconBounds := cxEmptyRect;
AHasSysMenu := TestWinStyle(WS_SYSMENU) and (FormData.Border in [bsSingle, bsSizeable]);
if AHasSysMenu then
begin
if UseAeroNCPaint(FormData) then
begin
H := GetSystemMetrics(SM_CYCAPTION);
if H < 24 then Exit;
H := (H - 3) and $FE;
R := GetDefaultWindowBordersWidth(FormData.Handle);
FSysMenuBounds := cxRectBounds(0, R.Top, H, H);
FSysMenuIconBounds := FSysMenuBounds;
end
else
begin
R := GetDefaultWindowBordersWidth(FormData.Handle);
FSysMenuBounds := cxRect(0, R.Top, GetSystemMetrics(SM_CYSIZE) + 2, GetWindowCaptionHeight - 2);
H := GetSystemMetrics(SM_CYSMICON);
FSysMenuIconBounds := cxRectBounds(0, R.Top, H, H);
OffsetRect(FSysMenuIconBounds, 0, (cxRectHeight(FSysMenuBounds) - H) div 2);
if FormData.State = wsMinimized then
OffsetRect(FSysMenuIconBounds, 4, 2);
end;
end;
end;
procedure TdxRibbonFormCaptionHelper.CalculateTextBounds;
begin
FTextBounds := GetClientRect;
Inc(FTextBounds.Top);
FTextBounds.Left := FSysMenuIconBounds.Right;
FTextBounds.Bottom := GetWindowCaptionHeight;
if FBorderIcons <> [] then
FTextBounds.Right := FBorderIconsArea.Left;
end;
procedure TdxRibbonFormCaptionHelper.DrawBorderIcons(ACanvas: TcxCanvas);
var
I: TBorderIcon;
R: TRect;
begin
if UseAeroNCPaint(FormData) then Exit;
for I := Low(TBorderIcon) to High(TBorderIcon) do
begin
if I in FBorderIcons then
begin
R := FBorderIconBounds[I];
DrawWindowBorderIcon(ACanvas, R, I, GetBorderIconState(I));
end;
end;
end;
procedure TdxRibbonFormCaptionHelper.ExcludeCaptionRgn(DC: HDC);
var
R1, R2: HRGN;
begin
if FFormCaptionRegions[rfrClient] = 0 then Exit;
R1 := GetClipRegion(DC);
R2 := GetFormCaptionRegionsForDC(DC, rfrClient);
CombineRgn(R1, R1, R2, RGN_DIFF);
SelectClipRgn(DC, R1);
DeleteObject(R1);
DeleteObject(R2);
end;
function TdxRibbonFormCaptionHelper.GetBorderIconState(
AIcon: TBorderIcon): TdxBorderIconState;
begin
if not FormData.Active then
begin
if BorderIconsMap[AIcon] = FHotBorderIcon then
Result := bisHotInactive
else
Result := bisInactive;
end
else
begin
if FPressedBorderIcon <> tbiNone then
begin
if (BorderIconsMap[AIcon] = FPressedBorderIcon) and (FPressedBorderIcon = FHotBorderIcon) then
Result := bisPressed
else
Result := bisNormal;
end
else if BorderIconsMap[AIcon] = FHotBorderIcon then
Result := bisHot
else
Result := bisNormal;
end;
end;
function TdxRibbonFormCaptionHelper.GetButtonFromPos(
const P: TPoint): TBorderIcon;
var
I, AIcon: TBorderIcon;
begin
Result := biSystemMenu;
for I := Low(BorderIconOrder) to High(BorderIconOrder) do
begin
AIcon := BorderIconOrder[I];
if (AIcon in FBorderIcons) and cxRectPtIn(FBorderIconBounds[AIcon], P) then
begin
Result := AIcon;
Exit;
end;
end;
end;
function TdxRibbonFormCaptionHelper.GetClientRect: TRect;
var
R: TRect;
begin
if FormData.Handle > 0 then
begin
if FormData.State = wsMinimized then
begin
Result := FormData.Bounds;
R := GetWindowBordersWidth;
Dec(Result.Right, R.Left);
end
else
if not Windows.GetClientRect(FormData.Handle, Result) then
Result := cxNullRect;
end
else
Result := Control.ClientRect;
end;
function TdxRibbonFormCaptionHelper.GetDrawIconFromBorderIcon(
AIcon: TBorderIcon): TdxBorderDrawIcon;
begin
case AIcon of
biMinimize:
begin
if FormData.State = wsMinimized then
Result := bdiRestore
else
Result := bdiMinimize;
end;
biMaximize:
begin
if FormData.State = wsMaximized then
Result := bdiRestore
else
Result := bdiMaximize;
end;
biSystemMenu:
Result := bdiClose;
else
Result := bdiHelp;
end;
end;
function TdxRibbonFormCaptionHelper.GetForm: TCustomForm;
begin
if Control.Owner is TCustomForm then
Result := TCustomForm(Control.Owner)
else
Result := nil;
end;
function TdxRibbonFormCaptionHelper.GetFormCaptionRegionsForDC(DC: HDC;
ARegionKind: TdxRibbonFormRegion): HRGN;
var
AWindowOrg, AViewportOrg: TPoint;
begin
Result := 0;
if FFormCaptionRegions[ARegionKind] = 0 then Exit;
Result := CreateRectRgnIndirect(cxEmptyRect);
CombineRgn(Result, FFormCaptionRegions[ARegionKind], 0, RGN_COPY);
GetWindowOrgEx(DC, AWindowOrg);
GetViewportOrgEx(DC, AViewportOrg);
OffsetRgn(Result, AViewportOrg.X - AWindowOrg.X, AViewportOrg.Y - AWindowOrg.Y);
end;
function TdxRibbonFormCaptionHelper.GetHandle: THandle;
begin
Result := FOwner.Handle;
end;
function TdxRibbonFormCaptionHelper.GetIsValid: Boolean;
begin
Result := FOwner.HandleAllocated and
(FOwner.ComponentState * [{csDestroying,} csLoading] = []);
end;
function TdxRibbonFormCaptionHelper.IsBorderIconMouseEvent(const P: TPoint;
out CP: TPoint; ACheckComposition: Boolean = True): Boolean;
begin
CP := Control.ScreenToClient(P);
Result := not (ACheckComposition and UseAeroNCPaint(FormData)) and
cxRectPtIn(FBorderIconsArea, CP);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -