Menu

[r3189]: / trunk / Src / UFormAligner.pas  Maximize  Restore  History

Download this file

132 lines (106 with data), 3.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
{
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/
*
* Copyright (C) 2007-2013, Peter Johnson (www.delphidabbler.com).
*
* $Rev$
* $Date$
*
* Defines a classes that implement IAligner and can align a form over an owning
* control.
}
unit UFormAligner;
interface
uses
// Delphi
Forms,
// Projects
IntfAligner;
type
/// <summary>Class that can align a form over an owning control. Adopts a
/// different alignment style depending on the type of the owning control.
/// </summary>
TFormAligner = class(TInterfacedObject, IFormAligner)
public
/// <summary>Aligns the given form over its owner, or, if the owner is nil,
/// over either the active form or the application's main form.</summary>
/// <remarks>Method of IAligner.</remarks>
procedure AlignForm(const AForm: TCustomForm);
end;
type
/// <summary>Class that aligns a form centrally over its owning TWinControl.
/// </summary>
/// <remarks>Unlike TFormAligner, the form is always centralised, regardless
/// of the type of the owning control.</remarks>
TSimpleFormAligner = class(TInterfacedObject, IFormAligner)
public
/// <summary>Aligns the given form over its owner, or, if the owner is nil,
/// over either the active form or the application's main form.</summary>
/// <remarks>
/// <para>The given form's owner must either be nil or be a TWinControl
/// descendant.</para>
/// <para>Method of IAligner.</para>
/// </remarks>
procedure AlignForm(const AForm: TCustomForm);
end;
implementation
uses
// Delphi
Controls, Types,
// Project
UDlgHelper, UStructs;
{ TFormAligner }
procedure TFormAligner.AlignForm(const AForm: TCustomForm);
begin
TDlgAligner.AlignToOwner(AForm);
end;
{ TSimpleFormAligner }
procedure TSimpleFormAligner.AlignForm(const AForm: TCustomForm);
var
FormBounds: TRectEx; // bounds of AForm
Owner: TWinControl; // owner win control
WorkArea: TRectEx; // desktop work area
RelOffset: TPoint; // relative offset of AForm to its owner
OwnerAbsTopLeft: TPoint; // top left of owner control in screen co-ords
begin
Assert(Assigned(AForm), ClassName + '.AlignForm: AForm is nil');
Assert(not Assigned(AForm.Owner) or (AForm.Owner is TWinControl),
ClassName + '.AlignForm: AForm.Owner must be nil or a TWinControl');
// Get owner control
if Assigned(AForm.Owner) then
Owner := AForm.Owner as TWinControl
else if Assigned(Screen.ActiveCustomForm) then
Owner := Screen.ActiveCustomForm
else
Owner := Application.MainForm;
Assert(Assigned(Owner),
ClassName + '.AlignForm: Application has no main form.');
// Calculate aligned form position
FormBounds := TRectEx.CreateBounds(0, 0, AForm.Width, AForm.Height);
RelOffset := Point(
(Owner.Width - FormBounds.Width) div 2,
(Owner.Height - FormBounds.Height) div 2
);
if Assigned(Owner.Parent) then
OwnerAbsTopLeft := Owner.ClientToScreen(Point(0, 0))
else
OwnerAbsTopLeft := Point(Owner.Left, Owner.Top);
FormBounds.OffsetBy(
OwnerAbsTopLeft.X + RelOffset.X, OwnerAbsTopLeft.Y + RelOffset.Y
);
// Adjust for position if necesary to keep on screen
WorkArea := Screen.MonitorFromRect(FormBounds).WorkareaRect;
if FormBounds.Right > WorkArea.Right then
FormBounds.OffsetBy(WorkArea.Right - FormBounds.Right, 0);
if FormBounds.Left < WorkArea.Left then
FormBounds.OffsetBy(WorkArea.Left - FormBounds.Left, 0);
if FormBounds.Bottom > WorkArea.Bottom then
FormBounds.OffsetBy(0, WorkArea.Bottom - FormBounds.Bottom);
if FormBounds.Top < WorkArea.Top then
FormBounds.OffsetBy(0, WorkArea.Top - FormBounds.Top);
// Place the form
AForm.BoundsRect := FormBounds;
end;
end.
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.