Flickering when TPageControl has many tabs - delphi

My problem is that I have a TPageControl which contains a dynamically created number of tabs each containing a single (alClient) TMemo. When this number of tabs exceeds the width of the control and the scroll arrows appear on the tab header, all (well a large number) of my controls start to flicker a lot. This flicker only occurs when the pagecontrol is visible once you scroll out of view of the TPageControl it stops. When the pagecontrol is resized so that the scroll arrows are no longer required to see all of the tabs then the flickering stops.
I'm fairly confident that the problem is caused by the scroll arrows causing some painting to occur because when I set the TPageControl.MultiLine to true then there is no flickering. Ideally I wouldn't want to use MultiLine tabs and hope someone can provide a solution.
Information about form layout
I have a (Personal Details) form which contains a number of TSpeedButtons, TLabels, TEdits, a TImage and so on. Many of these elements are inside of a TScrollBox and are grouped into sections using TPanels. The panels are set to alTop in the scrollbox and have autosize set to true but their height never changes.
I have tried setting all controls to have DoubleBuffered set to true where possible and ParentBackground/Color = false but sadly nothing works.
I had flickering issues before adding the PageControls and using David's quick hack answer here TLabel and TGroupbox Captions Flicker on Resize I was able to improve the flickering when resizing the form. By extending TLabel and removing the background clearing from the Paint procedure, as recommended somewhere else, I was able to 99% remove the labels flickering when scrolling the ScrollBox but now I have a new flickering problem.
---EDIT---
Here is a link to a stripped down version of my form with the flickering occurring flickering example
Personnel.DetailsForm.pas
unit Personnel.DetailsForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, System.Actions,
Vcl.ActnList, Vcl.Buttons, Vcl.StdCtrls, Vcl.ComCtrls, Vcl.WinXCtrls, Vcl.Imaging.jpeg;
type
TPersonnelDetailsForm = class(TForm)
ScrollBox_Content: TScrollBox;
panel_AddressDetails: TPanel;
gpanel_Address: TGridPanel;
edit_HomeMobilePhone: TEdit;
edit_HomeTown: TEdit;
edit_HomeStreet: TEdit;
edit_HomePhone: TEdit;
lbl_HomeStreet: TLabel;
lbl_HomePhone: TLabel;
lbl_MobilePhone: TLabel;
lbl_HomeTown: TLabel;
edit_HomeState: TEdit;
edit_HomeEmail: TEdit;
edit_HomeCountry: TEdit;
edit_HomeFax: TEdit;
lbl_HomeState: TLabel;
lbl_Fax: TLabel;
lbl_Email: TLabel;
lbl_HomeCountry: TLabel;
edit_HomePostCode: TEdit;
lbl_HomePostCode: TLabel;
panel_HomeAddressTitle: TPanel;
panel_GeneralNotesDetails: TPanel;
gpanel_GeneralNotesDetails_: TGridPanel;
pageControl_GeneralNotes: TPageControl;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
PersonnelDetailsForm: TPersonnelDetailsForm;
implementation
{$R *.dfm}
uses
System.Math,
System.DateUtils,
System.Threading,
System.RegularExpressions,
System.StrUtils,
System.Contnrs,
System.UITypes,
System.Types,
Winapi.Shellapi,
Vcl.ExtDlgs;
procedure EnableComposited(WinControl: TWinControl);
var
i: Integer;
NewExStyle: DWORD;
begin
NewExStyle := GetWindowLong(WinControl.Handle, GWL_EXSTYLE) or WS_EX_COMPOSITED;
SetWindowLong(WinControl.Handle, GWL_EXSTYLE, NewExStyle);
for i := 0 to WinControl.ControlCount - 1 do
if WinControl.Controls[i] is TWinControl then
EnableComposited(TWinControl(WinControl.Controls[i]));
end;
procedure TPersonnelDetailsForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// Close the form and make sure it frees itself
Action := caFree; // Should allow it to free itself on close
self.Release; // Sends a Release message to itself as backup
end;
procedure TPersonnelDetailsForm.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint;
var Handled: Boolean);
var
LTopLeft, LTopRight, LBottomLeft, LBottomRight: Integer;
LPoint: TPoint;
begin
Handled := true;
// First you have to get the position of the control on screen
// as MousePos coordinates are based on the screen positions.
LPoint := self.ScrollBox_Content.ClientToScreen(Point(0, 0));
LTopLeft := LPoint.X;
LTopRight := LTopLeft + self.ScrollBox_Content.Width;
LBottomLeft := LPoint.Y;
LBottomRight := LBottomLeft + self.ScrollBox_Content.Width;
if (MousePos.X >= LTopLeft) and (MousePos.X <= LTopRight) and (MousePos.Y >= LBottomLeft) and (MousePos.Y <= LBottomRight) then
begin
// If the mouse is inside the scrollbox coordinates,
// scroll it by setting .VertScrollBar.Position.
self.ScrollBox_Content.VertScrollBar.Position := self.ScrollBox_Content.VertScrollBar.Position - WheelDelta;
Handled := true;
end;
if FindVCLWindow(MousePos) is TComboBox then
Handled := true;
end;
procedure TPersonnelDetailsForm.FormShow(Sender: TObject);
var
memo: TMemo;
tabsheet: TTabSheet;
ii: Integer;
begin
for ii := 0 to 7 do
begin
memo := TMemo.Create(self);
memo.Align := TAlign.alClient;
memo.ReadOnly := true;
memo.ScrollBars := TScrollStyle.ssVertical;
memo.ParentColor := false;
tabsheet := TTabSheet.Create(self);
tabsheet.InsertControl(memo);
tabsheet.PageControl := self.pageControl_GeneralNotes;
tabsheet.Caption := 'A New TabSheet ' + IntToStr(ii);
tabsheet.Tag := ii;
memo.Text := 'A New Memo ' + IntToStr(ii);
end;
EnableComposited(self);
self.ScrollBox_Content.ScrollInView(self.panel_AddressDetails);
self.Invalidate;
end;
end.
Personnel.DetailsForm.dfm
object PersonnelDetailsForm: TPersonnelDetailsForm
Left = 0
Top = 0
Caption = 'Personnel Details Form'
ClientHeight = 371
ClientWidth = 800
Color = clBtnFace
DoubleBuffered = True
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
OnMouseWheel = FormMouseWheel
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 17
object ScrollBox_Content: TScrollBox
Left = 0
Top = 0
Width = 800
Height = 371
VertScrollBar.Smooth = True
VertScrollBar.Tracking = True
Align = alClient
TabOrder = 0
object panel_AddressDetails: TPanel
Tag = 101
Left = 0
Top = 0
Width = 796
Height = 174
Align = alTop
Padding.Left = 5
Padding.Top = 5
Padding.Right = 5
Padding.Bottom = 5
ParentBackground = False
TabOrder = 0
object gpanel_Address: TGridPanel
Left = 6
Top = 30
Width = 784
Height = 138
Align = alClient
BevelOuter = bvNone
ColumnCollection = <
item
SizeStyle = ssAbsolute
Value = 105.000000000000000000
end
item
Value = 50.000762951094850000
end
item
SizeStyle = ssAbsolute
Value = 105.000000000000000000
end
item
Value = 49.999237048905160000
end>
ControlCollection = <
item
Column = 3
Control = edit_HomeMobilePhone
Row = 1
end
item
Column = 1
Control = edit_HomeTown
Row = 1
end
item
Column = 1
Control = edit_HomeStreet
Row = 0
end
item
Column = 3
Control = edit_HomePhone
Row = 0
end
item
Column = 0
Control = lbl_HomeStreet
Row = 0
end
item
Column = 2
Control = lbl_HomePhone
Row = 0
end
item
Column = 2
Control = lbl_MobilePhone
Row = 1
end
item
Column = 0
Control = lbl_HomeTown
Row = 1
end
item
Column = 1
Control = edit_HomeState
Row = 2
end
item
Column = 3
Control = edit_HomeEmail
Row = 2
end
item
Column = 1
Control = edit_HomeCountry
Row = 3
end
item
Column = 3
Control = edit_HomeFax
Row = 3
end
item
Column = 0
Control = lbl_HomeState
Row = 2
end
item
Column = 2
Control = lbl_Fax
Row = 3
end
item
Column = 2
Control = lbl_Email
Row = 2
end
item
Column = 0
Control = lbl_HomeCountry
Row = 3
end
item
Column = 1
Control = edit_HomePostCode
Row = 4
end
item
Column = 0
Control = lbl_HomePostCode
Row = 4
end>
Padding.Left = 1
Padding.Top = 1
Padding.Right = 1
Padding.Bottom = 1
RowCollection = <
item
SizeStyle = ssAbsolute
Value = 27.000000000000000000
end
item
SizeStyle = ssAbsolute
Value = 27.000000000000000000
end
item
SizeStyle = ssAbsolute
Value = 27.000000000000000000
end
item
SizeStyle = ssAbsolute
Value = 27.000000000000000000
end
item
SizeStyle = ssAbsolute
Value = 27.000000000000000000
end>
TabOrder = 0
object edit_HomeMobilePhone: TEdit
Left = 498
Top = 29
Width = 284
Height = 25
Align = alClient
BevelInner = bvNone
BevelOuter = bvNone
TabOrder = 6
Text = 'Mobile Phone'
end
object edit_HomeTown: TEdit
Left = 107
Top = 29
Width = 284
Height = 25
Align = alClient
BevelInner = bvNone
BevelOuter = bvNone
TabOrder = 1
Text = 'Home Town'
end
object edit_HomeStreet: TEdit
Left = 107
Top = 2
Width = 284
Height = 25
Align = alClient
BevelInner = bvNone
BevelOuter = bvNone
TabOrder = 0
Text = 'Home Street'
end
object edit_HomePhone: TEdit
Left = 498
Top = 2
Width = 284
Height = 25
Align = alClient
BevelInner = bvNone
BevelOuter = bvNone
TabOrder = 5
Text = 'Home Phone'
end
object lbl_HomeStreet: TLabel
Left = 2
Top = 2
Width = 103
Height = 25
Align = alClient
Alignment = taRightJustify
Caption = 'Street: '
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = [fsBold]
ParentColor = False
ParentFont = False
Transparent = True
Layout = tlCenter
ExplicitLeft = 61
ExplicitWidth = 44
ExplicitHeight = 17
end
object lbl_HomePhone: TLabel
Left = 393
Top = 2
Width = 103
Height = 25
Align = alClient
Alignment = taRightJustify
Caption = 'Home Phone: '
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = [fsBold]
ParentFont = False
Layout = tlCenter
ExplicitLeft = 408
ExplicitWidth = 88
ExplicitHeight = 17
end
object lbl_MobilePhone: TLabel
Left = 393
Top = 29
Width = 103
Height = 25
Align = alClient
Alignment = taRightJustify
Caption = 'Mobile Phone: '
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = [fsBold]
ParentFont = False
Layout = tlCenter
ExplicitLeft = 402
ExplicitWidth = 94
ExplicitHeight = 17
end
object lbl_HomeTown: TLabel
Left = 2
Top = 29
Width = 103
Height = 25
Align = alClient
Alignment = taRightJustify
Caption = 'Town: '
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = [fsBold]
ParentColor = False
ParentFont = False
Transparent = True
Layout = tlCenter
ExplicitLeft = 64
ExplicitWidth = 41
ExplicitHeight = 17
end
object edit_HomeState: TEdit
Left = 107
Top = 56
Width = 284
Height = 25
Align = alClient
BevelInner = bvNone
BevelOuter = bvNone
TabOrder = 2
Text = 'Home State'
end
object edit_HomeEmail: TEdit
Left = 498
Top = 56
Width = 284
Height = 25
Align = alClient
BevelInner = bvNone
BevelOuter = bvNone
TabOrder = 7
Text = 'Home Email'
end
object edit_HomeCountry: TEdit
Left = 107
Top = 83
Width = 284
Height = 25
Align = alClient
BevelInner = bvNone
BevelOuter = bvNone
TabOrder = 3
Text = 'Home Country'
end
object edit_HomeFax: TEdit
Left = 498
Top = 83
Width = 284
Height = 25
Align = alClient
BevelInner = bvNone
BevelOuter = bvNone
TabOrder = 8
Text = 'Home Fax'
end
object lbl_HomeState: TLabel
Left = 2
Top = 56
Width = 103
Height = 25
Align = alClient
Alignment = taRightJustify
Caption = 'State: '
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = [fsBold]
ParentColor = False
ParentFont = False
Transparent = True
Layout = tlCenter
ExplicitLeft = 66
ExplicitWidth = 39
ExplicitHeight = 17
end
object lbl_Fax: TLabel
Left = 393
Top = 83
Width = 103
Height = 25
Align = alClient
Alignment = taRightJustify
Caption = 'Fax: '
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = [fsBold]
ParentFont = False
Layout = tlCenter
ExplicitLeft = 467
ExplicitWidth = 29
ExplicitHeight = 17
end
object lbl_Email: TLabel
Left = 393
Top = 56
Width = 103
Height = 25
Align = alClient
Alignment = taRightJustify
Caption = 'Email: '
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = [fsBold]
ParentFont = False
Layout = tlCenter
ExplicitLeft = 454
ExplicitWidth = 42
ExplicitHeight = 17
end
object lbl_HomeCountry: TLabel
Left = 2
Top = 83
Width = 103
Height = 25
Align = alClient
Alignment = taRightJustify
Caption = 'Country: '
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = [fsBold]
ParentColor = False
ParentFont = False
Transparent = True
Layout = tlCenter
ExplicitLeft = 47
ExplicitWidth = 58
ExplicitHeight = 17
end
object edit_HomePostCode: TEdit
Left = 107
Top = 110
Width = 284
Height = 25
Align = alClient
BevelInner = bvNone
BevelOuter = bvNone
TabOrder = 4
Text = 'Home Post Code'
end
object lbl_HomePostCode: TLabel
Left = 2
Top = 110
Width = 103
Height = 25
Align = alClient
Alignment = taRightJustify
Caption = 'Post Code: '
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = [fsBold]
ParentColor = False
ParentFont = False
Transparent = True
Layout = tlCenter
ExplicitLeft = 35
ExplicitWidth = 70
ExplicitHeight = 17
end
end
object panel_HomeAddressTitle: TPanel
Left = 6
Top = 6
Width = 784
Height = 24
Align = alTop
Alignment = taLeftJustify
BevelOuter = bvNone
Caption = ' Home Address '
Color = clMedGray
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = [fsBold, fsUnderline]
ParentBackground = False
ParentFont = False
TabOrder = 1
end
end
object panel_GeneralNotesDetails: TPanel
Tag = 303
Left = 0
Top = 174
Width = 796
Height = 172
Align = alTop
AutoSize = True
Padding.Left = 5
Padding.Top = 5
Padding.Right = 5
Padding.Bottom = 5
ParentBackground = False
TabOrder = 1
object gpanel_GeneralNotesDetails_: TGridPanel
Left = 6
Top = 6
Width = 784
Height = 160
Align = alTop
BevelOuter = bvNone
ColumnCollection = <
item
Value = 100.000000000000000000
end>
ControlCollection = <
item
Column = 0
Control = pageControl_GeneralNotes
Row = 0
end>
Padding.Left = 1
Padding.Top = 1
Padding.Right = 1
Padding.Bottom = 1
RowCollection = <
item
SizeStyle = ssAbsolute
Value = 160.000000000000000000
end>
TabOrder = 0
object pageControl_GeneralNotes: TPageControl
Left = 2
Top = 2
Width = 780
Height = 158
Align = alClient
TabOrder = 0
end
end
end
end
end

I figured out that the problem was caused by the quick hack David answered to TLabel and TGroupbox Captions Flicker on Resize after I removed that the mad flickering when the TPageControl tab scroll buttons were visible went away. So now I'll have to look at his more in-depth solution and see if that can help with some of the flickering I was seeing before.

Related

TTitleBarPanel overlapping nested Panel when the main Form loses focus

When running a 32-bit VCL Application in Windows 10 in Delphi 11 Alexandria, initially it looks fine (except the Mainmenu is hidden):
But as soon as the window loses focus, the TTitleBarPanel OVERLAPS pnlHeader (which is a nested TPanel inside a TCard):
But I have done as the Documentation says: Put everything except the TTitleBarPanel on a client-aligned Panel.
How can this overlapping be avoided?
Here is the Unit:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.Menus,
Vcl.TitleBarCtrls, Vcl.WinXPanels;
type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
menuitemOptions: TMenuItem;
menuitemPreferences: TMenuItem;
menuitemAbout: TMenuItem;
pnlHeader: TPanel;
TitleBarPanel1: TTitleBarPanel;
CardPanel1: TCardPanel;
Card1: TCard;
Panel1: TPanel;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
end.
And here is the Form:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 294
ClientWidth = 515
Color = clSilver
CustomTitleBar.Control = TitleBarPanel1
CustomTitleBar.Enabled = True
CustomTitleBar.Height = 34
CustomTitleBar.BackgroundColor = clWhite
CustomTitleBar.ForegroundColor = 65793
CustomTitleBar.InactiveBackgroundColor = clWhite
CustomTitleBar.InactiveForegroundColor = 10066329
CustomTitleBar.ButtonForegroundColor = 65793
CustomTitleBar.ButtonBackgroundColor = clWhite
CustomTitleBar.ButtonHoverForegroundColor = 65793
CustomTitleBar.ButtonHoverBackgroundColor = 16053492
CustomTitleBar.ButtonPressedForegroundColor = 65793
CustomTitleBar.ButtonPressedBackgroundColor = 15395562
CustomTitleBar.ButtonInactiveForegroundColor = 10066329
CustomTitleBar.ButtonInactiveBackgroundColor = clWhite
DoubleBuffered = True
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
GlassFrame.Enabled = True
GlassFrame.Top = 34
Menu = MainMenu1
Position = poScreenCenter
StyleElements = [seFont, seClient]
PixelsPerInch = 96
TextHeight = 15
object TitleBarPanel1: TTitleBarPanel
Left = 0
Top = 0
Width = 515
Height = 34
CustomButtons = <>
ExplicitWidth = 608
end
object Panel1: TPanel
Left = 0
Top = 34
Width = 515
Height = 260
Align = alClient
BevelOuter = bvNone
TabOrder = 1
ExplicitTop = 33
ExplicitWidth = 608
ExplicitHeight = 296
object CardPanel1: TCardPanel
Left = 0
Top = 0
Width = 515
Height = 260
Align = alClient
ActiveCard = Card1
BevelOuter = bvNone
Caption = 'CardPanel1'
TabOrder = 0
ExplicitTop = 34
ExplicitWidth = 608
ExplicitHeight = 355
object Card1: TCard
Left = 0
Top = 0
Width = 515
Height = 260
Caption = 'Card1'
CardIndex = 0
DoubleBuffered = True
ParentDoubleBuffered = False
TabOrder = 0
ExplicitWidth = 608
ExplicitHeight = 355
object pnlHeader: TPanel
Left = 0
Top = 0
Width = 515
Height = 32
Margins.Left = 100
Margins.Top = 0
Margins.Right = 150
Margins.Bottom = 0
Align = alTop
Alignment = taLeftJustify
BevelOuter = bvNone
Color = 16443110
Font.Charset = DEFAULT_CHARSET
Font.Color = clGrayText
Font.Height = -19
Font.Name = 'Segoe UI'
Font.Style = []
ParentBackground = False
ParentFont = False
TabOrder = 0
ExplicitWidth = 608
end
end
end
end
object MainMenu1: TMainMenu
Left = 320
Top = 192
object menuitemOptions: TMenuItem
Caption = 'Options'
object menuitemPreferences: TMenuItem
Caption = 'Toggle Preferences'
ShortCut = 123
end
object menuitemAbout: TMenuItem
Caption = 'About'
ShortCut = 121
end
end
end
end

TCoolBar band resizing problem in Delphi 10.3

I put a TCoolBar component into a brand new project in Delphi 10.3. There are some bands in a row. When I resize one band, the others on its right in the same row resize too. I can decrease or increase the band size, the others on the right always grow by the difference. If I resize the form all the band gone wild. They all increase their sizes.
The error does not occure if I create a band by the band editor. It occures when I drop down some TActionToolBar into the TCoolBar.
The CoolBar AutoSize does not set. The bands or TActionToolBar has not a property like this.
The pas file:
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ToolWin, Vcl.ComCtrls,
Vcl.PlatformDefaultStyleActnCtrls, System.Actions, Vcl.ActnList, Vcl.ActnMan,
Vcl.ActnCtrls;
type
TForm2 = class(TForm)
ActionManager1: TActionManager;
CoolBar1: TCoolBar;
ActionToolBar1: TActionToolBar;
ActionToolBar2: TActionToolBar;
ActionToolBar3: TActionToolBar;
ActionToolBar4: TActionToolBar;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
end.
The dpr file:
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 405
ClientWidth = 635
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object CoolBar1: TCoolBar
Left = 0
Top = 0
Width = 635
Height = 65
Bands = <
item
Control = ActionToolBar1
ImageIndex = -1
Width = 148
end
item
Break = False
Control = ActionToolBar2
ImageIndex = -1
Width = 477
end
item
Control = ActionToolBar3
ImageIndex = -1
Width = 146
end
item
Break = False
Control = ActionToolBar4
ImageIndex = -1
Width = 479
end>
FixedSize = True
object ActionToolBar1: TActionToolBar
Left = 11
Top = 0
Width = 135
Height = 25
Caption = 'ActionToolBar1'
Color = clMenuBar
ColorMap.DisabledFontColor = 7171437
ColorMap.HighlightColor = clWhite
ColorMap.BtnSelectedFont = clBlack
ColorMap.UnusedColor = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
Spacing = 0
end
object ActionToolBar2: TActionToolBar
Left = 163
Top = 0
Width = 468
Height = 25
Caption = 'ActionToolBar2'
Color = clMenuBar
ColorMap.DisabledFontColor = 7171437
ColorMap.HighlightColor = clWhite
ColorMap.BtnSelectedFont = clBlack
ColorMap.UnusedColor = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
Spacing = 0
end
object ActionToolBar3: TActionToolBar
Left = 11
Top = 27
Width = 133
Height = 25
Caption = 'ActionToolBar3'
Color = clMenuBar
ColorMap.DisabledFontColor = 7171437
ColorMap.HighlightColor = clWhite
ColorMap.BtnSelectedFont = clBlack
ColorMap.UnusedColor = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
Spacing = 0
end
object ActionToolBar4: TActionToolBar
Left = 161
Top = 27
Width = 470
Height = 25
Caption = 'ActionToolBar4'
Color = clMenuBar
ColorMap.DisabledFontColor = 7171437
ColorMap.HighlightColor = clWhite
ColorMap.BtnSelectedFont = clBlack
ColorMap.UnusedColor = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
Spacing = 0
end
end
object ActionManager1: TActionManager
Left = 248
Top = 160
StyleName = 'Platform Default'
end
end
Is there any solution for this problem?

Cannot Change TEdit Height in Delphi

Below is the sample code of my Custom TEdit control.
type
TEdit = class(Vcl.StdCtrls.TEdit)
private
//FTextM : TEXTMETRIC;
public
constructor Create(AOwner : TComponent); override;
end;
constructor TEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
BorderStyle := bsNone;
Text := '';
Font.Name := 'Segoe UI';
Font.Size := 9;
Height := 10; //Here height change is not reflected.
end;
Here what ever the value i give in Height it is not updated in runtime. I am seriously missing very simple thing. But i am unable to figure it out on my own.
What will be the correct way to update the height of tedit control.
Update: Here is the form code i am using.
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 242
ClientWidth = 472
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Edit2: TEdit
Left = 216
Top = 184
Width = 121
Height = 21
TabOrder = 1
Text = 'Edit2'
end
object Edit3: TEdit
Left = 40
Top = 136
Width = 121
Height = 21
TabOrder = 0
Text = 'Edit3'
end
end
To be able to change the Height property of the TEdit you must first set the Autosize property to False. otherwise, at runtime the control will change its height based on the font size.

How to have an absolute row between two percentage rows when adding to a TGridPanel from code?

I am trying to create a Form with a TGridPanel from code.
It contains:
A memo at the top (which is set to 50%)
A navigator at the center (which is set to 24 pixels)
A grid at the bottom (which is set to 50%)
This is the code I wrote:
uses
Winapi.Messages, Winapi.Windows, System.Classes, System.SysUtils,
System.UITypes, System.Variants, Vcl.Controls, Vcl.DBCtrls, Vcl.DBGrids,
Vcl.Dialogs, Vcl.ExtCtrls, Vcl.Forms, Vcl.Graphics, Vcl.Grids, Vcl.StdCtrls,
Data.DB;
procedure Test;
var
View: TForm;
GridPanel: TGridPanel;
Grid: TDBGrid;
DataSource: TDataSource;
Navigator: TDBNavigator;
Memo: TMemo;
begin
View := TForm.Create(Application);
try
View.Name := 'Form2';
// SystemFont(View.Font);
View.Width := 640;
View.Height := 480;
View.Position := TPosition.poOwnerFormCenter;
GridPanel := TGridPanel.Create(View);
GridPanel.Name := 'GridPanel';
GridPanel.Caption := '';
GridPanel.BevelOuter := TBevelCut.bvNone;
GridPanel.FullRepaint := False;
GridPanel.Parent := View;
GridPanel.Align := TAlign.alClient;
GridPanel.ColumnCollection.BeginUpdate;
GridPanel.ColumnCollection.Delete(1);
GridPanel.ColumnCollection[0].Value := 100;
GridPanel.ColumnCollection.EndUpdate;
GridPanel.RowCollection.BeginUpdate;
GridPanel.RowCollection.Add;
TCellItem(GridPanel.RowCollection[0]).Value := 50;
TCellItem(GridPanel.RowCollection[0]).SizeStyle := TSizeStyle.ssPercent;
TCellItem(GridPanel.RowCollection[1]).Value := 24;
TCellItem(GridPanel.RowCollection[1]).SizeStyle := TSizeStyle.ssAbsolute;
TCellItem(GridPanel.RowCollection[2]).Value := 50;
TCellItem(GridPanel.RowCollection[2]).SizeStyle := TSizeStyle.ssPercent;
GridPanel.RowCollection.EndUpdate;
Memo := TMemo.Create(View);
Memo.Name := 'Memo';
Memo.Parent := GridPanel;
Memo.Lines.Clear;
Memo.Align := TAlign.alClient;
DataSource := TDataSource.Create(View);
Navigator := TDBNavigator.Create(View);
Navigator.Name := 'Navigator';
Navigator.DataSource := DataSource;
Navigator.Parent := GridPanel;
Navigator.Align := TAlign.alClient;
Grid := TDBGrid.Create(View);
Grid.Name := 'Grid';
Grid.Parent := GridPanel;
Grid.Align := TAlign.alClient;
Grid.DataSource := DataSource;
{
GridPanel.ControlCollection.BeginUpdate;
GridPanel.ControlCollection.AddControl(Memo, 0, 0);
GridPanel.ControlCollection.AddControl(Navigator, 0, 1);
GridPanel.ControlCollection.AddControl(Grid, 0, 2);
GridPanel.ControlCollection.EndUpdate;
}
// ShowMessage(ComponentToString(View));
View.ShowModal;
finally
View.Free;
end;
end
The result looks like this:
The Problem: There is a gap at the bottom of the form and no DB navigator to be seen!
A dump of the DFM looks fine to me:
object Form2: TForm
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 441
ClientWidth = 624
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poOwnerFormCenter
PixelsPerInch = 96
TextHeight = 13
object GridPanel: TGridPanel
Left = 0
Top = 0
Width = 624
Height = 441
Align = alClient
BevelOuter = bvNone
ColumnCollection = <
item
Value = 100.000000000000000000
end>
ControlCollection = <
item
Column = 0
Control = Memo
Row = 0
end
item
Column = 0
Control = Navigator
Row = 1
end
item
Column = 0
Control = Grid
Row = 2
end>
FullRepaint = False
RowCollection = <
item
Value = 50.000000000000000000
end
item
SizeStyle = ssAbsolute
Value = 24.000000000000000000
end
item
Value = 50.000000000000000000
end>
TabOrder = 0
object Memo: TMemo
Left = 0
Top = 0
Width = 624
Height = 208
Align = alClient
TabOrder = 0
ExplicitLeft = 219
ExplicitTop = 59
ExplicitWidth = 185
ExplicitHeight = 89
end
object Navigator: TDBNavigator
Left = 0
Top = 208
Width = 624
Height = 18
Align = alClient
TabOrder = 1
ExplicitTop = 0
ExplicitWidth = 240
ExplicitHeight = 25
end
object Grid: TDBGrid
Left = 0
Top = 208
Width = 624
Height = 209
Align = alClient
TabOrder = 2
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'Tahoma'
TitleFont.Style = []
end
end
object TDataSource
end
end
When I change the position, the Navigator is at the correct position, but I want it to be absolute.
TCellItem(GridPanel.RowCollection[1]).Value := 5;
TCellItem(GridPanel.RowCollection[1]).SizeStyle := TSizeStyle.ssPercent;
Why does TGridPanel behave so strange in this case? What can I do about it?
Change the order of setting SizeStyle and Value.
TCellItem(GridPanel.RowCollection[0]).SizeStyle := TSizeStyle.ssPercent;
TCellItem(GridPanel.RowCollection[0]).Value := 50;
TCellItem(GridPanel.RowCollection[1]).SizeStyle := TSizeStyle.ssAbsolute;
TCellItem(GridPanel.RowCollection[1]).Value := 24;
TCellItem(GridPanel.RowCollection[2]).SizeStyle := TSizeStyle.ssPercent;
TCellItem(GridPanel.RowCollection[2]).Value := 50;

How to manage constantly changing project run-time parameters in the IDE?

In my (XE2) IDE I constantly have to switch the settings for Project Options/ Debugger / Parameters because I'm testing for different client configurations, databases etc.
The Parameters dropdown list is becoming unmanageable. Since these have no descriptions either, it's even hard to figure out which ones to remove (How can I clean the Parameters field in the Run -> Parameters menu?).
Any smart ideas on managing these?
In an ideal word I would like to give them a tag/description, reorder them, delete some...
Not ideal but a workaround would be to add a redundant tag parameter as first parameter.
That way at least, when you use the dropdown list, you'll have some indication on what parameter combination you are using.
In addition to Lievens answer I'm adding an answer to my own question.
I have started using [identifier] at the beginning of the run-time parameter, and I can put in there what I want. In addition I have written a small app that lets me clean up the parameters that are stored in the registry (at HKEY_CURRENT_USER\Software\Embarcadero\BDS\9.0\History Lists\hlRunParameters).
Here is the code for that Win32 app. It will let you delete and sort the registry values. It is written in Delphi XE2. Just create a new VCL project and use this as the main form.
uCleanIDEParams.pas
unit uCleanIDEParams;
// https://stackoverflow.com/questions/27502689/how-to-manage-constantly-changing-project-run-time-parameters-in-the-ide
// All 32 bit stuff, the Delphi IDE is 32 bit too
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.CheckLst, Registry,
Vcl.ExtCtrls;
type
TFrmCleanIDEParams = class(TForm)
PnlTop: TPanel;
BtnLoad: TButton;
EdtRegKey: TEdit;
Label1: TLabel;
ChkRedundant: TCheckBox;
PnlBottom: TPanel;
GBxSelection: TGroupBox;
BtnSelectAll: TButton;
BtnSelectNone: TButton;
BtnStartWith: TButton;
ChkNot: TCheckBox;
EdtStartWith: TEdit;
BtnInvert: TButton;
Label2: TLabel;
BtnWrite: TButton;
ChkSort: TCheckBox;
PnlCenter: TPanel;
CLBParams: TCheckListBox;
procedure BtnLoadClick(Sender: TObject);
procedure BtnSelectAllClick(Sender: TObject);
procedure BtnSelectNoneClick(Sender: TObject);
procedure BtnInvertClick(Sender: TObject);
procedure BtnStartWithClick(Sender: TObject);
procedure BtnWriteClick(Sender: TObject);
private
public
end;
var
FrmCleanIDEParams: TFrmCleanIDEParams;
implementation
{$R *.dfm}
procedure TFrmCleanIDEParams.BtnInvertClick(Sender: TObject);
var i: integer;
begin
for i := 0 to CLBParams.Items.Count-1 do CLBParams.Checked[i] := not CLBParams.Checked[i];
end;
procedure TFrmCleanIDEParams.BtnLoadClick(Sender: TObject);
var
lReg : TRegistry;
lValue,
lItem,
lKey : String;
i,
lNrRegVals: Integer;
begin
lKey := Trim(EdtRegKey.Text);
if lKey = '' then Exit;
if lKey[1] = '\' then lKey := Copy(lKey,2);
lReg := TRegistry.Create(KEY_READ);
lReg.RootKey := HKEY_CURRENT_USER;
if not lReg.OpenKey(lKey,false) then
begin
MessageDlg('Key not found', mtError, mbOKCancel, 0);
Exit;
end;
if not lReg.ValueExists('Count') then
begin
MessageDlg('Value ''Count'' not found', mtError, mbOKCancel, 0);
Exit;
end;
lNrRegVals := lReg.ReadInteger('Count');
for i := 0 to lNrRegVals-1 do
begin
lValue := 'Item' + IntToStr(i);
if lReg.ValueExists(lValue) then
begin
lItem := lReg.ReadString(lValue);
if ChkRedundant.Checked then
lItem := Trim(StringReplace(lItem,' ',' ',[rfReplaceAll]));
CLBParams.Items.Add(lItem);
end;
end;
end;
procedure TFrmCleanIDEParams.BtnSelectAllClick(Sender: TObject);
var i: integer;
begin
for i := 0 to CLBParams.Items.Count-1 do CLBParams.Checked[i] := true;
end;
procedure TFrmCleanIDEParams.BtnSelectNoneClick(Sender: TObject);
var i: integer;
begin
for i := 0 to CLBParams.Items.Count-1 do CLBParams.Checked[i] := true;
end;
procedure TFrmCleanIDEParams.BtnStartWithClick(Sender: TObject);
var
i : integer;
lStart,
lItem : string;
begin
lStart := Lowercase(Trim(EdtStartWith.Text));
if lStart = '' then Exit;
for i := 0 to CLBParams.Items.Count-1 do
begin
lItem := lowercase(CLBParams.Items[i]);
if (not ChkNot.Checked) and (Pos(lStart,lItem) = 1)
or (ChkNot.Checked) and (Pos(lStart,lItem) <> 1) then
CLBParams.Checked[i] := true;
end;
end;
procedure TFrmCleanIDEParams.BtnWriteClick(Sender: TObject);
var
lReg : TRegistry;
lValue,
lKey : String;
i,
lNrToWrite,
lNrRegVals: Integer;
begin
for i := CLBParams.Items.Count-1 downto 0 do
if not CLBParams.Checked[i] then
CLBParams.Items.Delete(i);
if CLBParams.Items.Count = 0 then
begin
MessageDlg('Nothing to do', mtInformation, mbOKCancel, 0);
Exit;
end;
if ChkSort.Checked then
CLBParams.Sorted := true;
// Now writing back
lKey := Trim(EdtRegKey.Text);
if lKey = '' then Exit;
if lKey[1] = '\' then lKey := Copy(lKey,2);
lReg := TRegistry.Create(KEY_READ or KEY_WRITE);
lReg.RootKey := HKEY_CURRENT_USER;
if not lReg.OpenKey(lKey,false) then
begin
MessageDlg('Key not found', mtError, mbOKCancel, 0);
Exit;
end;
if not lReg.ValueExists('Count') then
begin
MessageDlg('Value ''Count'' not found', mtError, mbOKCancel, 0);
Exit;
end;
lNrRegVals := lReg.ReadInteger('Count');
lNrToWrite := CLBParams.Items.Count;
lReg.WriteInteger('Count',lNrToWrite);
// Write TCheckListBox items:
for i := 0 to lNrToWrite-1 do
begin
lValue := 'Item' + IntToStr(i);
lReg.WriteString(lValue,CLBParams.Items[i]);
end;
// Remove the rest:
for i := lNrToWrite to lNrRegVals-1 do
lReg.DeleteValue('Item' + IntToStr(i));
end;
end.
uCleanIDEParams.dfm
object FrmCleanIDEParams: TFrmCleanIDEParams
Left = 0
Top = 0
Caption = 'Clean Delphi IDE runtime parameters'
ClientHeight = 560
ClientWidth = 549
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
PixelsPerInch = 96
TextHeight = 13
object PnlTop: TPanel
Left = 0
Top = 0
Width = 549
Height = 58
Align = alTop
BevelOuter = bvNone
TabOrder = 0
object Label1: TLabel
Left = 19
Top = 11
Width = 308
Height = 13
Caption = 'HKEY_CURRENT_USER registry key for IDE runtime parameters:'
end
object BtnLoad: TButton
Left = 496
Top = 30
Width = 40
Height = 25
Caption = 'Load'
TabOrder = 0
OnClick = BtnLoadClick
end
object EdtRegKey: TEdit
Left = 16
Top = 32
Width = 473
Height = 21
TabOrder = 1
Text = '\Software\Embarcadero\BDS\9.0\History Lists\hlRunParameters'
end
object ChkRedundant: TCheckBox
Left = 388
Top = 10
Width = 151
Height = 17
Hint = 'Removes leading, trailing, and duplicate spaces'
Caption = 'Remove redundant spaces'
Checked = True
State = cbChecked
TabOrder = 2
end
end
object PnlBottom: TPanel
Left = 0
Top = 471
Width = 549
Height = 89
Align = alBottom
BevelOuter = bvNone
TabOrder = 1
object Label2: TLabel
Left = 74
Top = 62
Width = 287
Height = 13
Caption = 'Click button to write the selected items back to the registry:'
end
object GBxSelection: TGroupBox
Left = 16
Top = -3
Width = 520
Height = 51
Caption = ' Select '
TabOrder = 0
object BtnSelectAll: TButton
Left = 348
Top = 18
Width = 50
Height = 25
Caption = 'All'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 0
OnClick = BtnSelectAllClick
end
object BtnSelectNone: TButton
Left = 404
Top = 18
Width = 50
Height = 25
Caption = 'None'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 1
OnClick = BtnSelectNoneClick
end
object BtnStartWith: TButton
Left = 51
Top = 18
Width = 79
Height = 25
Hint = 'Selection is additive'
Caption = 'starting with:'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 2
OnClick = BtnStartWithClick
end
object ChkNot: TCheckBox
Left = 11
Top = 22
Width = 40
Height = 17
Caption = 'NOT'
TabOrder = 3
end
object EdtStartWith: TEdit
Left = 136
Top = 20
Width = 121
Height = 21
Hint = 'Case insensitive match'
ParentShowHint = False
ShowHint = True
TabOrder = 4
Text = '['
end
object BtnInvert: TButton
Left = 460
Top = 18
Width = 50
Height = 25
Caption = 'Invert'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 5
OnClick = BtnInvertClick
end
end
object BtnWrite: TButton
Left = 364
Top = 58
Width = 89
Height = 25
Hint = 'Write the selected items back to the registry'
Caption = 'Write back'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = [fsBold]
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 1
OnClick = BtnWriteClick
end
object ChkSort: TCheckBox
Left = 459
Top = 62
Width = 57
Height = 17
Caption = '(sorted)'
Checked = True
State = cbChecked
TabOrder = 2
end
end
object PnlCenter: TPanel
Left = 0
Top = 58
Width = 549
Height = 413
Align = alClient
BevelOuter = bvNone
TabOrder = 2
object CLBParams: TCheckListBox
AlignWithMargins = True
Left = 15
Top = 10
Width = 522
Height = 393
Margins.Left = 15
Margins.Top = 10
Margins.Right = 12
Margins.Bottom = 10
Align = alClient
ItemHeight = 13
TabOrder = 0
end
end
end
Notes:
Do not forget to change the version number in the key if you are using anything other than XE2. For old Delphi versions you may even have to change Embarcadero to Borland.
Do not run this app from within the IDE. When it closes, Delphi will overwrite any changes you made to that registry key, and it looks like your program does not work ;=)

Resources