I want to create a property editor because a lot of things does not supported by TValueListEditor. So I use a TStringGrid and other controls placed on it when the user enter the cells. When I place a TCheckBox for boolean values, the dynamically created TCheckBox is uncheckable. The onClick event handler does not fiered by the clicks (the grid fiered) and the caption of the TCheckBox lost its opacity. I set its parent and bring it to the front. By this time I used TEdit and TComboBox controls as well and they work fine. Somebody can help to use it in the expected way?
Here is an example to recreate the situation.
pas:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids,
StdCtrls;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
CheckBox1: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
procedure onCheckBoxClicked( sender_ : TObject );
public
{ Public declarations }
fCheckBox : TCheckBox;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.onCheckBoxClicked( sender_ : TObject );
begin
if ( TCheckBox( sender_ ).checked ) then
TCheckBox( sender_ ).caption := 'true'
else
TCheckBox( sender_ ).caption := 'false';
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fCheckBox := TCheckBox.create( NIL );
fCheckBox.Parent := stringGrid1;
fCheckBox.caption := 'Dynamic checkbox';
fCheckBox.left := 70;
fCheckBox.top := 30;
fCheckBox.onClick := onCheckBoxClicked;
fCheckBox.BringToFront;
stringgrid1.cells[1,1] := 'fgfgfgfgfgf';
stringgrid1.cells[1,2] := 'fgfgfgfgfgf';
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
fCheckBox.Free;
end;
end.
The dfm:
object Form1: TForm1
Left = 358
Top = 183
Caption = 'Form1'
ClientHeight = 601
ClientWidth = 854
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object StringGrid1: TStringGrid
Left = 120
Top = 72
Width = 320
Height = 120
TabOrder = 0
end
object CheckBox1: TCheckBox
Left = 192
Top = 128
Width = 97
Height = 17
Caption = 'Static checkbox'
TabOrder = 1
end
end
This does not work with a checkbox because the string grid intercepts processing of the WM_COMMAND message. When you click the checkbox, a WM_COMMAND notification is sent to its parent - which is the string grid. The grid, in TCustomGrid.WMCommand of 'Vcl.Grids', checks if the notification is from its inplace editor and discards the message otherwise.
You can modify the processing of the message on the grid to change the behavior. One way is to derive a new control. E.g.
type
TStringGrid = class(vcl.grids.TStringGrid)
protected
procedure WMCommand(var Message: TWMCommand); message WM_COMMAND;
end;
TForm1 = class(TForm)
StringGrid1: TStringGrid;
....
...
procedure TStringGrid.WMCommand(var Message: TWMCommand);
var
Control: TWinControl;
begin
inherited;
Control := FindControl(Message.Ctl);
if Assigned(Control) and (Control <> InplaceEditor) then
Control.Perform(Message.Msg, MakeWParam(Message.ItemID, Message.NotifyCode),
Message.Ctl);
end;
Then the OnClick will fire. You don't need BringToFront, it works among sibling controls.
Regarding opacity, it's the checkbox's default appearance. You can verify this by placing a checkbox overlapping a label on the form itself.
Related
I have never needed to do much COM, so have almost no experience with it. Nearly all of the documentation (certainly from MS) does not include Delphi examples.
In my code example, I can't see where I'm going wrong. The code was borrowed from snippets found in several locations on the web. Some were VB. I only found one thread for Free Pascal, and it was incomplete. This runs, but shows displays the same string for both name and value. I hope someone can see what I'm missing. I think the problem is with the line that reads:
PropValue := OleFolder.GetDetailsOf(OleFolderItem, i);
I don't know if I need to do something to initialize "OleFolderItem".
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ActiveX, ComObj, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
pnl1: TPanel;
btn1: TButton;
mmo1: TMemo;
OpenDialog1: TOpenDialog;
procedure btn1Click(Sender: TObject);
procedure getExtdProps(AFileName: string);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Procedure TForm1.getExtdProps(AFileName: string);
var
Shell : Variant;
OleFolder : OleVariant;
OleFolderItem: OleVariant;
PropName, PropValue: string;
i: integer;
begin
Shell := CreateOleObject('Shell.Application');
OleFolder := Shell.Namespace(ExtractFilePath(AFileName));
i := 0;
PropName := 'Not an EmptyStr'; //So the next loop will work.
while PropName <> EmptyStr do
begin
PropName := OleFolder.GetDetailsOf(null, i); {null gets the name}
PropValue := OleFolder.GetDetailsOf(OleFolderItem, i); { OleFolderItem should get the value }
if PropName <> '' then
mmo1.Lines.Add(PropName + ': ' + PropValue);
inc(i);
end;
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
GetExtdProps(OpenDialog1.FileName);
end;
end;
end.
Try this complete example :
unit GetDetailsOfDemoMain;
interface
uses
Winapi.Windows, Winapi.Messages,
System.SysUtils, System.Variants, System.Win.ComObj, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
procedure GetExtdProps(AFileName: string);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.GetExtdProps(AFileName: string);
var
Shell : Variant;
OleFolder : OleVariant;
OleFolderItem : OleVariant;
ForlderName : String;
PropName : String;
PropValue : string;
I : integer;
begin
Shell := CreateOleObject('Shell.Application');
OleFolder := Shell.Namespace(ExtractFilePath(AFileName));
OleFolderItem := OleFolder.ParseName(ExtractFileName(AFileName));
for I := 0 to 999 do begin
PropName := OleFolder.GetDetailsOf(null, i);
PropValue := OleFolder.GetDetailsOf(OleFolderItem , I);
if (PropName <> '') and (PropValue <> '') then
Memo1.Lines.Add(Format('%3d) %-30s: %s',
[I, PropName, PropValue]));
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
GetExtdProps(OpenDialog1.FileName);
end;
end.
DFM file:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 441
ClientWidth = 624
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
PixelsPerInch = 96
DesignSize = (
624
441)
TextHeight = 15
object Button1: TButton
Left = 40
Top = 32
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object Memo1: TMemo
Left = 8
Top = 72
Width = 609
Height = 361
Anchors = [akLeft, akTop, akRight, akBottom]
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Consolas'
Font.Style = []
ParentFont = False
ScrollBars = ssBoth
TabOrder = 1
end
object OpenDialog1: TOpenDialog
Left = 48
Top = 88
end
end
I've added a TPopupMenu to a TControlList, on right-click the ItemIndex isn't updated to reflect the item clicked on. Is there a way to make a right-click respond in a similar way to a left-click?
This would be nice so that the user right-clicks on a particular item, the PopupMenu is associated with that item, not the currently focused item.
You can use HotItemIndex property from OnPopupMenu event and save it to a variable. Then for the popup menu items events you can use it.
Example code:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.ControlList, Vcl.StdCtrls;
type
TForm1 = class(TForm)
ControlList1: TControlList;
PopupMenu1: TPopupMenu;
TestPopupMnu: TMenuItem;
Label1: TLabel;
Memo1: TMemo;
procedure ControlList1BeforeDrawItem(AIndex: Integer; ACanvas: TCanvas; ARect:
TRect; AState: TOwnerDrawState);
procedure ControlList1Click(Sender: TObject);
procedure TestPopupMnuClick(Sender: TObject);
procedure PopupMenu1Popup(Sender: TObject);
private
FPopupItemIndex : Integer;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ControlList1BeforeDrawItem(AIndex: Integer; ACanvas: TCanvas;
ARect: TRect; AState: TOwnerDrawState);
begin
Label1.Caption := AIndex.ToString;
end;
procedure TForm1.ControlList1Click(Sender: TObject);
begin
Memo1.Lines.Add('Clicked item ' + ControlList1.ItemIndex.ToString);
end;
procedure TForm1.TestPopupMnuClick(Sender: TObject);
begin
Memo1.Lines.Add('Test PopupMenu item ' + FPopupItemIndex.ToString);
end;
procedure TForm1.PopupMenu1Popup(Sender: TObject);
begin
FPopupItemIndex := ControlList1.HotItemIndex;
end;
end.
The form itself:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 299
ClientWidth = 635
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object ControlList1: TControlList
Left = 24
Top = 20
Width = 317
Height = 200
ItemCount = 5
ItemMargins.Left = 0
ItemMargins.Top = 0
ItemMargins.Right = 0
ItemMargins.Bottom = 0
ParentColor = False
PopupMenu = PopupMenu1
TabOrder = 0
OnBeforeDrawItem = ControlList1BeforeDrawItem
OnClick = ControlList1Click
object Label1: TLabel
Left = 92
Top = 20
Width = 31
Height = 13
Caption = 'Label1'
end
end
object Memo1: TMemo
Left = 368
Top = 24
Width = 241
Height = 201
Lines.Strings = (
'Memo1')
TabOrder = 1
end
object PopupMenu1: TPopupMenu
OnPopup = PopupMenu1Popup
Left = 436
Top = 128
object TestPopupMnu: TMenuItem
Caption = 'Test'
OnClick = TestPopupMnuClick
end
end
end
In order to handle Right Clicks you will have to make use of OnMouseDown or OnMouseUp events instead of OnClick event.
Unlike OnClick event that only detects left clicks OnMouseDown and OnMouseUp events are able to detect all mouse clicks (left, right, middle).
procedure TForm1.ControlList1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Button = mbRight then
begin
//Do what needs to be done on right click
end
else if Button = mbMiddle then
begin
//Do what needs to be done on middle click
end
end;
The HotItemIndex property can be used to detect which item has been right-clicked by using the following
procedure TListingList.clListingsMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
inherited;
if Button <> mbRight then
Exit;
if clListings.HotItemIndex <> -1 then
clListings.ItemIndex := clListings.HotItemIndex;
end;
This mostly works, but if you already have a TPopupmenu visible already, then the HotItemIndex is -1. This means that consecutive right-clicks don't popup for the correct item - but I can live with this. I think a MousePosToItemIndex or ItemIndexUnderMouse method would be required to fix this properly.
I want to test something and created a simple dynamic popup menu example. I had to realize that the popup menu appears normally but it does not call the onClick event handler. I tried to rename everything to avoid the name collisions, made the event handler virtual, public, but it did not solve the problem. I have restarted the IDE (I think this code should work fine) but it is the same. The compiler options are the new project defaults. The statically created (placed on the form) popupmenu works fine, just the dynamiically created one take a rest.
Which property of the dynamic menu should I fill up with some value? Somebody explain the reason, please!
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus;
type
TForm1 = class(TForm)
Button1: TButton;
staticPopupMenu: TPopupMenu;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
procedure addMenuItem( popupmenu_ : TPopupMenu; caption_ : string; tag_ : integer; onClick_ : TNotifyEvent );
procedure onmenuitemclick1( sender_ : TObject );
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.addMenuItem( popupmenu_ : TPopupMenu; caption_ : string; tag_ : integer; onClick_ : TNotifyEvent );
var
menuitem1 : tmenuitem;
begin
menuitem1 := tmenuitem.create( popupmenu_ );
menuitem1.caption := caption_;
menuitem1.Tag := tag_;
menuitem1.onclick := onclick_;
popupmenu_.items.add( menuitem1 );
end;
procedure TForm1.onmenuitemclick1( sender_ : TObject );
var
id : integer;
begin
id := tmenuitem( sender_ ).Tag;
showmessage( 'menuitem.onclick called! (' + intToStr( id ) + ')' );
end;
procedure TForm1.Button1Click(Sender: TObject);
var
dynamicPopupMenu : tpopupmenu;
begin
dynamicPopupMenu := tpopupmenu.create( self );
try
addMenuItem( dynamicPopupMenu, 'aaa', 1, onmenuitemclick1 );
addMenuItem( dynamicPopupMenu, 'bbb', 2, onmenuitemclick1 );
dynamicPopupMenu.popup( 500, 500 );
finally
dynamicPopupMenu.Free;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
staticPopupMenu.items.Clear;
addMenuItem( staticPopupMenu, 'aaa', 1, onmenuitemclick1 );
addMenuItem( staticPopupMenu, 'bbb', 2, onmenuitemclick1 );
staticPopupMenu.popup( 500, 500 );
end;
end.
The dfm:
object Form1: TForm1
Left = 339
Top = 270
Caption = 'Form1'
ClientHeight = 601
ClientWidth = 854
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 96
Top = 128
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 177
Top = 128
Width = 75
Height = 25
Caption = 'Button2'
TabOrder = 1
OnClick = Button2Click
end
object staticPopupMenu: TPopupMenu
Left = 280
Top = 128
end
end
Since you are creating your dynamicPopupMenu with the current TForm1 instance
as Owner, I'm not really sure you need all the rigmarole of your garbage collector,
as the TForm1 instance will destroy it anyway when it itself is destroyed.
Try this:
Set a breakpoint on TComponent.Destroy in Classes.Pas and a watch on Tag.
Change your Button1Click as shown below, disable your garbage collector,
compile, run and observe.
{code}
procedure TForm1.Button1Click(Sender: TObject);
var
dynamicPopupMenu : tpopupmenu;
AForm : TForm;
begin
AForm := TForm.Create(Nil);
dynamicPopupMenu := tpopupmenu.create(AForm);
try
dynamicPOpUpMenu.Tag := 666;
addMenuItem( dynamicPopupMenu, 'aaa', 1, onmenuitemclick1 );
addMenuItem( dynamicPopupMenu, 'bbb', 2, onmenuitemclick1 );
dynamicPopupMenu.popup( 600, 600 );
finally
AForm.Release;
end;
end;
Here's my take on the issue. A user defined message should do just fine with very little overhead. So...
Define a Windows message:
const
WM_FREE_MY_DYNAMENU = WM_USER + 0;
Move the dynamicPopupMenu variable to the form and define a handler for the message:
TForm12 = class(TForm)
...
protected
dynamicPopupMenu: TPopupMenu;
procedure FreeMyDynaMenu(var Message: TMessage); message WM_FREE_MY_DYNAMENU;
Implement it:
procedure TForm12.FreeMyDynaMenu(var Message: TMessage);
begin
dynamicPopupMenu.Free;
end;
Finally in the Button1Click replace the call to Free with posting the message:
finally
// dynamicPopupMenu.Free;
PostMessage(self.Handle, WM_FREE_MY_DYNAMENU, 0, 0);
You should also NOT assign the form as the owner when you create the menu:
dynamicPopupMenu := tpopupmenu.create( nil ); // self replaced with nil
And an even more simple alternative to the above (although not to my liking) would be to use a TTimer to delay the call to Free.
I would like to show TCustomForm descendants as dialogs so that they are positioned poOwnerFormCenter. But the same code that is positioning the form correctly when FormStyle is fsNormal does not set the correct position when FormStyle is fsMDIChild.
When the secondary form has FormStyle = fsNormal Button1 opens the modal dialog like this:
But when the secondary form has FormStyle = fsMDIChild the positioning seems to be relative to the position of the MDI Child to the MDI Parent, not the absolute postion of the MDI Child:
I'm not sure if I make any mistakes, if this is maybe a bug or normal behavior.
Following code is used to show the dialog:
procedure TForm3.Button1Click(Sender: TObject);
var
AModalForm: TForm;
begin
AModalForm := TForm.Create(Self);
try
AModalForm.Position := poOwnerFormCenter;
AModalForm.ShowModal;
finally
AModalForm.Free;
end;
end;
Project to reproduce:
dpr
program Project2;
uses
Vcl.Forms,
Unit2 in 'Unit2.pas' {Form2},
Unit3 in 'Unit3.pas' {Form3};
{$R *.res}
var
AMainForm: TForm2;
A: TApplication;
begin
A := Application;
A.Initialize;
A.MainFormOnTaskbar := True;
A.CreateForm(TForm2, AMainForm);
A.Run;
end.
Unit2
pas
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Menus;
type
TForm2 = class(TForm)
Button1: TButton;
Panel1: TPanel;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
implementation
{$R *.dfm}
uses
Unit3;
procedure TForm2.Button1Click(Sender: TObject);
var
AForm: TForm3;
begin
AForm := TForm3.Create(Self);
AForm.FormStyle := fsMDIChild;
end;
procedure TForm2.Button2Click(Sender: TObject);
var
AForm: TForm3;
begin
AForm := TForm3.Create(Self);
AForm.FormStyle := fsNormal;
end;
end.
dfm
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 356
ClientWidth = 635
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
FormStyle = fsMDIForm
OldCreateOrder = False
Visible = True
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 0
Top = 0
Width = 97
Height = 356
Align = alLeft
TabOrder = 0
object Button1: TButton
Left = 8
Top = 39
Width = 75
Height = 25
Caption = 'fsMDIChild'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 8
Top = 8
Width = 75
Height = 25
Caption = 'fsNormal'
TabOrder = 1
OnClick = Button2Click
end
end
end
Unit3
pas
unit Unit3;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm3 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
implementation
{$R *.dfm}
procedure TForm3.Button1Click(Sender: TObject);
var
AModalForm: TForm;
begin
AModalForm := TForm.Create(Self);
try
AModalForm.Position := poOwnerFormCenter;
AModalForm.ShowModal;
finally
AModalForm.Free;
end;
end;
end.
dfm
object Form3: TForm3
Left = 0
Top = 0
Caption = 'Form3'
ClientHeight = 336
ClientWidth = 635
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Visible = True
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 8
Top = 8
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
end
After trying several ideas found here on SO and also elsewhere, and all my attempts failing, I guess the safest (= working in all Delphi versions) solution is as follows.
Unit1 - Form1:TForm1 - fsMDIForm
Unit2 - Form2:TForm2 - fsMDIChild
Unit3 - AModalForm:TFom3 - ordinary form, shown modally, centered on the Form2
The essential part is simply a fallback to manually calculating and setting Left and Top properties of AModalForm so it becomes centered. It requies also setting Position property to poDesigned
// Showing the modal form centered by a fsMDIChild form
procedure TForm2.Button1Click(Sender: TObject);
var
AModalForm: TForm3;
begin
AModalForm := TForm3.Create(self);
try
AModalForm.Left := Self.ClientOrigin.X + (Self.ClientWidth-AModalForm.Width) div 2;
AModalForm.Top := Self.ClientOrigin.Y + (Self.ClientHeight-AModalForm.Height) div 2;
AModalForm.Position := poDesigned;
AModalForm.ShowModal;
// use modalresult as needed
finally
AModalForm.Free;
end;
end;
Found a glitch with VCL styles: when you update the form caption, other controls previously redrawn within the same procedure don't get repainted, and you are forced to call Repaint, losing valuable processing time to redraw.
Example: (set project options/vcl style manually)
unit Unit11;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TForm11 = class(TForm)
Button1: TButton;
Panel1: TPanel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form11: TForm11;
implementation
{$R *.dfm}
procedure TForm11.Button1Click(Sender: TObject);
begin
Panel1.Caption := 'test';
caption := 'glitch';
end;
end.
object Form11: TForm11
Left = 0
Top = 0
Caption = 'Form11'
ClientHeight = 89
ClientWidth = 352
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 8
Top = 8
Width = 121
Height = 57
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object Panel1: TPanel
Left = 135
Top = 8
Width = 185
Height = 57
Caption = 'Panel1'
TabOrder = 1
end
end
program Project10;
uses
Vcl.Forms,
Unit11 in 'Unit11.pas' {Form11},
Vcl.Themes,
Vcl.Styles;
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
TStyleManager.TrySetStyle('Cobalt XEMedia');
Application.CreateForm(TForm11, Form11);
Application.Run;
end.
Set the caption calls in the sequence.
First form.caption, then child.caption.
Once you've called the wrong sequence, then stopped working the correct sequence. That's why I use here, the "set default" button.
This proceed, as long as there is no fix for it, I can live with that.
procedure TForm11.Button1Click(Sender: TObject);
begin // wrong order
Panel1.Caption := 'test';
caption := 'glitch';
end;
procedure TForm11.Button2Click(Sender: TObject);
begin // right order
caption := 'glitch';
Panel1.Caption := 'test';
end;
procedure TForm11.Button3Click(Sender: TObject);
var
i:integer;
begin // count no refresh
for i:= 1 to 300 do begin
caption := 'glitch '+intToStr(i);
Panel1.Caption := 'test '+intToStr(i);
end;
end;
procedure TForm11.Button4Click(Sender: TObject);
var
i:integer;
begin // count with refresh
for i:= 1 to 300 do begin
caption := 'glitch '+intToStr(i);
Panel1.Caption := 'test '+intToStr(i);
Panel1.Refresh;
end;
end;
procedure TForm11.Button5Click(Sender: TObject);
begin // set default
caption := 'Form11';
Panel1.Caption := 'Panel1';
Panel1.Refresh;
end;
end.
If you found another solution. Please tell me.