Delphi: frame+colorbox=bug - delphi

Delphi XE (It works fine in Delphi 2010).
Try: create a frame and a color box inside it. The color box -> set a Selected color other than black and a style = cbCustomColor (not cbCustomColors); paste the frame into the form, save a project.
Close the project. Reopen->errors as below:
I need this "custom color", who is freaking: me, a color box, a frame or whole Delphi? :)
Thanks!!!
Source code:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 202
ClientWidth = 447
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
inline Frame21: TFrame2
Left = 72
Top = -38
Width = 320
Height = 240
TabOrder = 0
ExplicitLeft = 72
ExplicitTop = -38
end
end
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Unit2;
type
TForm1 = class(TForm)
Frame21: TFrame2;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
end.
object Frame2: TFrame2
Left = 0
Top = 0
Width = 320
Height = 240
TabOrder = 0
object ColorBox1: TColorBox
Left = 72
Top = 48
Width = 145
Height = 22
Selected = clGreen
Style = [cbStandardColors, cbExtendedColors, cbSystemColors, cbCustomColor]
TabOrder = 0
end
end
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TFrame2 = class(TFrame)
ColorBox1: TColorBox;
private
{ Private declarations }
public
{ Public declarations }
end;
implementation
{$R *.dfm}
end.

This is a bug in Delphi XE. Please add this to the QC bug reporting system at Embarcadero.

Related

How to add multiple-column Items to TListBox?

In a 32-bit VCL Application in Windows 10 in Delphi 11.1 Alexandria, I am trying to add multiple-column Items to TListBox. The CHM Libraries Reference for VCL in the Vcl.StdCtrls.TCustomListBox.Items topic has the following tip:
So I created the following VCL Application test project:
DPR:
program TListBoxMultiColumn;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
PAS:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Items.Add('First Column'^I'Second Column');
ListBox1.Items.Add('1'^I'2');
ListBox1.Items.Add('4'^I'5');
end;
end.
DFM:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'TListBox MultiColumn Test'
ClientHeight = 191
ClientWidth = 368
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -15
Font.Name = 'Segoe UI'
Font.Style = []
Position = poScreenCenter
PixelsPerInch = 120
TextHeight = 20
object ListBox1: TListBox
Left = 0
Top = 0
Width = 241
Height = 191
Margins.Left = 4
Margins.Top = 4
Margins.Right = 4
Margins.Bottom = 4
Align = alLeft
Columns = 2
ItemHeight = 20
TabOrder = 0
ExplicitHeight = 413
end
object Button1: TButton
Left = 260
Top = 20
Width = 94
Height = 31
Margins.Left = 4
Margins.Top = 4
Margins.Right = 4
Margins.Bottom = 4
Caption = 'Button1'
TabOrder = 1
OnClick = Button1Click
end
end
However, the result is not what is promised in the documentation:
So how can I add multiple-column Items to a TListBox?
You must set the TabWidth property to a suitable, large enough value:
ListBox1.TabWidth := 100;
ListBox1.Items.Add('First Column'^I'Second Column');
ListBox1.Items.Add('1'^I'2');
ListBox1.Items.Add('4'^I'5');
Bonus information: You may wonder why ^I is used here. Well, since I is the 9th letter in the English alphabet, ^I is equal to #9, that is, the tabulator character.
I would write this
ListBox1.TabWidth := 100;
ListBox1.Items.Add('First Column'#9'Second Column');
ListBox1.Items.Add('1'#9'2');
ListBox1.Items.Add('4'#9'5');
Actually, the current version of the documentation states
Tip: If you have a list box with tab stops enabled (TabStop property) and you want to add data to specific columns, you can set the TabWidth property to obtain a list box in which individual lines can be displayed in columns, as long as they use tabs in their text, as shown in the snippet below (notice #9 is the tab character).
This is a better description, since it mentions the TabWidth property, uses #9 instead of ^I, and doesn't misuse the word "parameter". However, its reference to TabStop is utterly nonsense. The TabStop property is about the form's tab order.

Delphi DX 10.3 VS Delphi 6 performances

I have been using Delphi 6 for a very long time, and I recently started using version Delphi DX Rio 10.3.
Against all my expectations, it seems to me that loading items on standard controls (ComboBox, Listbox and so on) in DX RIO is significantly slower (at runtime) than in D6 (both in DEBUG and RELEASE mode, after activating all optimizations).
I tried using BeginUpdate / EndUpdate, without changing the speed difference between the environments.
I would like to ask if anyone has any suggestions for improving DX 10.3 Combobox/Listbox performances. The specific problem I'm trying to solve in my real application is to load some dozens of items in 10-20 combos/listboxes controls on my form.
I wrote a very simple test for a standard COMBO. The same program works in both D6 and DX RIO.
On my development machine (Win 10 pro) the program compiled with D6 takes about 1 second, while the program compiled with DX RIO takes about four times as much.
Many thanks in advance for your answers.
{$A+,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
cb: TComboBox;
txt_count: TLabel;
btn: TButton;
procedure btnClick(Sender: TObject);
end;
var Form1: TForm1;
implementation
{$R *.dfm}
var dt_start_timer : TDatetime;
procedure start_timer;
begin
dt_start_timer := now
end;
function delta_timer_msec : longint;
begin
result := round((now - dt_start_timer) * 24*60*60*1000)
end;
procedure execute(father : TForm;cb : TComboBox;txt : TLabel;bo_disable_update : boolean);
const
MAX = 100;
ITEMS_COUNT = 1000;
var i, j : integer;
begin
start_timer;
if bo_disable_update then cb.Items.BeginUpdate;
for i := 1 to MAX do begin
cb.Items.Clear;
for j := 1 to ITEMS_COUNT do cb.Items.Add('text-' + intToStr(j))
end;
if bo_disable_update then cb.Items.EndUpdate;
txt.Caption := intToStr(delta_timer_msec) + ' msecs'
end;
procedure TForm1.btnClick(Sender: TObject);
begin
execute(self, cb, txt_count, {disable_update}TRUE)
end;
end.
object Form1: TForm1
Left = -6
Top = 117
Width = 449
Height = 350
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object txt_count: TLabel
Left = 198
Top = 32
Width = 44
Height = 13
Caption = 'txt_count'
end
object cb: TComboBox
Left = 42
Top = 28
Width = 145
Height = 21
ItemHeight = 13
TabOrder = 0
Text = 'cb'
end
object btn: TButton
Left = 24
Top = 70
Width = 251
Height = 139
Caption = 'btn'
TabOrder = 1
OnClick = btnClick
end
end

How to correctly use TGridPanel when display PPI scaling is active?

I have written a small test VCL application with a monitor PPI of 96.
The application has a TGridPanel on it with a absolute pixel sized column.
On that column I placed a TComboBox and aligned it alClient.
Here is the DFM code:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 182
ClientWidth = 514
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object GridPanel1: TGridPanel
Left = 0
Top = 0
Width = 514
Height = 182
Align = alClient
Caption = 'GridPanel1'
ColumnCollection = <
item
Value = 100.000000000000000000
end
item
SizeStyle = ssAbsolute
Value = 150.000000000000000000
end>
ControlCollection = <
item
Column = 0
Control = Button1
Row = 0
end
item
Column = 1
Control = ComboBox1
Row = 0
end
item
Column = 0
Control = Edit1
Row = 1
end>
RowCollection = <
item
Value = 50.000000000000000000
end
item
Value = 50.000000000000000000
end>
TabOrder = 0
object Button1: TButton
Left = 1
Top = 1
Width = 362
Height = 21
Align = alTop
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object ComboBox1: TComboBox
Left = 363
Top = 1
Width = 150
Height = 21
Align = alClient
TabOrder = 1
Text = 'ComboBox1'
end
object Edit1: TEdit
Left = 1
Top = 91
Width = 362
Height = 21
Align = alTop
TabOrder = 2
Text = 'Edit1'
end
end
end
and the PAS code:
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.StdCtrls;
type
TForm1 = class(TForm)
GridPanel1: TGridPanel;
Button1: TButton;
ComboBox1: TComboBox;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
PPI: Integer;
begin
PPI := Integer.Parse(Edit1.Text);
GridPanel1.ScaleForPPI(PPI);
end;
procedure TForm1.FormShow(Sender: TObject);
begin
Edit1.Text := Screen.PixelsPerInch.ToString;
end;
end.
I then changed the custom scaling factor to 125 in Windows 10 in the advanced scaling settings.
After signing off and signing on again when I run the application again the drop down button of the combo box is not visible any more.
How do you deal with this problem?
I tried to call GridPanel1.ScaleForPPI(96) which restores the drop down button on the combo box. This kind of defeats the purpose of PPI scaling though, doesn't it?
The problem is gone in Delphi 10.3.1.
So this is a bug in at least Delphi 10.1 (and possible other older versions).

Delphi XE2 and LiveBindings between controls

Is it possible to do LiveBinding between controls, i.e. take 2 edit boxes and get the result of adding their contents together into a label. I'm sure it is, I just don't know where to start
Thanks
Have a look at the samples. SVN repository URL: https://radstudiodemos.svn.sourceforge.net/svnroot/radstudiodemos/branches/RadStudio_XE2/LiveBindings
An example:
----- Unit1.dfm -----
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 286
ClientWidth = 426
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 8
Top = 62
Width = 48
Height = 13
Caption = 'Edit1Edit2'
end
object Edit1: TEdit
Left = 8
Top = 8
Width = 121
Height = 21
TabOrder = 0
Text = 'Edit1'
OnChange = EditChange
end
object Edit2: TEdit
Left = 8
Top = 35
Width = 121
Height = 21
TabOrder = 1
Text = 'Edit2'
OnChange = EditChange
end
object BindingsList1: TBindingsList
Methods = <>
OutputConverters = <>
UseAppManager = True
Left = 20
Top = 5
object BindExpressionLabel11: TBindExpression
Category = 'Binding Expressions'
ControlComponent = Label1
SourceComponent = BindScope1
SourceExpression = 'Edit1.Text + Edit2.Text'
ControlExpression = 'Caption'
NotifyOutputs = False
Direction = dirSourceToControl
end
end
object BindScope1: TBindScope
Left = 192
Top = 16
end
end
----- Unit1.pas -----
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.Bind.EngExt, Vcl.Bind.DBEngExt,
System.Rtti, System.Bindings.Outputs, Vcl.Bind.Editors, Data.Bind.Components,
Vcl.StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
BindingsList1: TBindingsList;
BindExpressionLabel11: TBindExpression;
BindScope1: TBindScope;
procedure EditChange(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
System.Bindings.Helper;
procedure TForm1.EditChange(Sender: TObject);
begin
TBindings.Notify(Sender, 'Text');
end;
end.
How to use the IDE designer to produce the result:
put two edits (Edit1, Edit2), a label (Label1) and a TBindScope (BindScope1) on your form (Form1).
create an event handler for both edits' OnChange event (EditChange).
select Label1, expand the drop-down of LiveBindings property, select 'New Live Binding...', select TBindExpression
edit properties of the newly created BindExpressionLabel11: assign Caption to ControlExpression, BindScope1 to SourceComponent, Edit1.Text + Edit2.Text to SourceExpression
The sample project at the (Default) location of:
C:\Users\Public\Documents\RAD Studio\9.0\Samples\Delphi\LiveBinding\Components\bindexpression\fmx\BindExpressionSampleProject.dproj
does precisely that.
You don't need to TBindScope to bind components together. Say you have edit1 and edit2 on the form. If you set edit2 BindingSource to edit1 it will be link to changes to edit1

Changing the directory of Delphi OpenDialog + Drive in Win7

It seems that on Win7 changing the TOpenDialog.InitialDir doesn't work, when the new directory is on a different drive, than the current directory.
e.g.: I want to change my InitialDir from 'C:\program files\MyApp' to 'D:\test\MyAppData'
Is that a known issue, or only on my computer?
I already tried the same thing, as mentioned in the following post, but without any success:
Changing the directory of Delphi OpenDialog
EDIT:
I am using DelphiXE on Win7 32 Bit
The path/dir is correct: So, when I copy that path from code and past it into the 'File Name' field of that Dialog itself and I press ENTER, then the Dialog switches to that directory. Only, in my code it is not working.
UPDATE:
I found the problem. If the path contains some path commands like ..\ the TOpenDialog.InitialDir is not able to resolve that. Use TPath.GetFullPath(...) to make it clean.
I have tested on a Delphi XE, it runs fine... I have done this:
Put a new form:
object Form4: TForm4
Left = 0
Top = 0
Caption = 'Form4'
ClientHeight = 204
ClientWidth = 447
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 = 24
Top = 40
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object Edit1: TEdit
Left = 120
Top = 42
Width = 121
Height = 21
TabOrder = 1
Text = 'D:\'
end
object OpenDialog1: TOpenDialog
InitialDir = 'C:\'
Left = 120
Top = 72
end
end
And its source code:
unit Unit4;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm4 = class(TForm)
OpenDialog1: TOpenDialog;
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form4: TForm4;
implementation
{$R *.dfm}
procedure TForm4.Button1Click(Sender: TObject);
begin
OpenDialog1.InitialDir := edit1.text;
OpenDialog1.Execute;
end;
end.
Regards
I don't have any problem changing InitialDir, either through object inspector or runtime (Win7 with Delphi 2010). Try doublechecking if the directory you try to change to is correctly typed.

Resources