Creating custom button in Delphi with different actions [closed] - delphi

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am creating a custom component, a button-switch like this :
In my "form activate" function, I wrote a for loop in which I call 3 times the button function with a different position parameter like : SwitchButton(30); where 30 is the top position.
What I want to do is assign at these 3 buttons different actions, here some code.
Code for button creation :
procedure TFMain.SwitchButton(posPulsante: Integer);
var
i: Integer;
posDescrizionePulsante: Integer;
strDescrizione: String;
begin
posDescrizionePulsante := 32;
lastPressed := 1;
Pulsante := TPanel.Create(FMain);
BordoPulsante := TShape.Create(self);
LevaPulsante := TPanel.Create(self);
DescrizionePulsante := TLabel.Create(self);
//Proprietà Descrizione
with DescrizionePulsante do
begin
Parent := PComandi;
Top := posDescrizionePulsante;
Left := 100;
Caption := 'Visualizza finestra utenti';
Font.Name := 'Tahoma';
Font.Size := 12;
Font.Style := [fsBold];
Font.Color := clWhite;
end;
//Proprietà Pulsante
with Pulsante do
begin
Parent := PComandi;
ParentColor := false;
ParentBackground := false;
BevelOuter := bvNone;
Color := clWhite;
Width := 57;
Height := 25;
Top := posPulsante;
Left := 20;
Visible := true;
end;
//Proprietà Bordo
with BordoPulsante do
begin
Parent := Pulsante;
Align := alClient;
Brush.Style := bsClear;
Brush.Color := RGB(122,136,201);
Pen.Color := clWhite;
Pen.Style := psSolid;
Pen.Width := 3;
end;
//Proprietà Leva
with LevaPulsante do
begin
Parent := Pulsante;
ParentBackground := false;
ParentColor := false;
BevelOuter := bvNone;
Color := clWhite;
Cursor := crHandPoint;
Width := 23;
Height := 13;
Top := 6;
Left := 28;
LevaPulsante.OnClick := SwitchState;
end;
end;
Code for creating Button object :
procedure TFMain.FormActivate(Sender: TObject);
var
i: Integer;
posPulsante: Integer;
begin
posPulsante := 30;
for i := 1 to 3 do
begin
SwitchButton(posPulsante);
posPulsante := posPulsante + 50;
end;
end;
Would be nice to have some : if SwitchButton 1 is clicked then do something. if SwitchButton 2 is clicked then do something else.

I think this is an acceptable use of the Tag property. You can specify some number, for example the index of the for loop, in each of the panels:
procedure TFMain.FormActivate(Sender: TObject);
var
i: Integer;
posPulsante: Integer;
begin
posPulsante := 30;
for i := 1 to 3 do
begin
SwitchButton(posPulsante, i {For example, add the tag as extra parameter});
posPulsante := posPulsante + 50;
end;
end;
And then set that tag in the button, here using the added parameter indexPulsante.
procedure TFMain.SwitchButton(posPulsante: Integer; indexPulsante: Integer);
var
i: Integer;
posDescrizionePulsante: Integer;
strDescrizione: String;
begin
...
LevaPulsante.Tag := indexPulsante;
end;
And then, in the event handler (which I think you called SwitchState), you'll have the Sender, which is the control that was clicked (the panel, in your case).
procedure TFMain.SwitchState(Sender: TObject);
begin
case (Sender as TComponent).Tag of
1: ShowMessage('You clicked the first. Do something.')
2: ShowMessage('Do something else.')
else
ShowMessage('You clicked another button than 1 or 2');
end;
end;
NB: Tag is introduced in TComponent and therefore also available in TPanel. In the code above I only typecast to TComponent, because it doesn't matter that it's a panel to get the tag, but if you want to use other properties, a more specific cast may be needed. I like to keep the cast generic, to make it easier to make changes like switching to another type than TPanel, for instance when you actually gonna make a component out of this (inherited from TCustomControl?), or use a third party component.

Related

Simulate Align position in Delphi Custom Panel

I'm building a custom panel in Delphi XE5 and I'm having a hard time simulating a new "Gravity" property where I can combine two coordinates (like Right + Bottom) and the effect is similar to "Align" however, it does not resize the object, direction. The main problem I encountered is to simulate this behavior. My initial intention was to create a panel in memory with the same "Parent" in my custom panel and then align to the position defined in "Gravity" overwriting the "SetBounds" method. It's working, but a bit precarious, especially in "Design Time". Could someone suggest me how to more effectively simulate this alignment using VCL?
function TZPanel.GetPosition: TCustomPanel;
var
sid: TZSide;
anch: TAnchors;
panTest: TPanel;
function getGravity(al: TAlign): TRect;
var
panGravity: TPanel;
I: Integer;
begin
try
//Self.Visible := False;
panGravity:= TPanel.Create(Self);
panGravity.BevelInner := panTest.BevelInner;
panGravity.BevelOuter := panTest.BevelOuter;
panGravity.BevelWidth := panTest.BevelWidth;
panGravity.BorderWidth := panTest.BorderWidth;
panGravity.ParentBackground := True;
panGravity.SetBounds(panTest.Left, panTest.Top, panTest.Width, panTest.Height);
panGravity.Parent:= Self.Parent;
panGravity.Align := al;
Result:= panGravity.BoundsRect;
finally
panGravity.Destroy;
Self.Visible := True;
end;
end;
begin
panTest := TPanel.Create(Self);
panTest.Align := Align;
panTest.Anchors := Anchors;
panTest.BevelInner := BevelInner;
panTest.BevelOuter := BevelOuter;
panTest.BevelWidth := BevelWidth;
panTest.BorderWidth := BorderWidth;
panTest.SetBounds(Left, Top, Width, Height);
if (FGravity = []) then
begin
//
end
else
begin
panTest.Align := alCustom;
anch := [];
for sid in FGravity do
begin
case sid of
sTop:
begin
panTest.Top := getGravity(alTop).Top;
anch := anch + [akTop];
end;
sRight:
begin
panTest.Left := getGravity(alRight).Left;
anch := anch + [akRight];
end;
sBottom:
begin
panTest.Top := getGravity(alBottom).Top;
anch := anch + [akBottom];
end;
sLeft:
begin
panTest.Left := getGravity(alLeft).Left;
anch := anch + [akLeft];
end;
end;
end;
panTest.Anchors := anch;
end;
Result := panTest;
end;

Change THeader font size in FMX TStringGrid

I've searched this question and found this.
so, I wrote a OnApplyStyleLookup event handler like this:
procedure TForm1.StringGrid1ApplyStyleLookup(Sender: TObject);
var
Header: THeader;
I: Integer;
begin
Header := THeader((Sender as TStringGrid).FindStyleResource('header'));
if Assigned(Header) then
begin
for I := 0 to Header.Count - 1 do
with Header.Items[I].Font do
begin
Header.Items[I].TextSettings.HorzAlign := TTextAlign.Center;
Size := 100;
Style := [TFontStyle.fsBold];
// SetSettings('Arial', 100, [TFontStyle.fsBold]);
end;
Header.Height := 48;
end;
// TStringGrid(Sender).Realign;
end;
text align is changed, but font size and style are not applied.
I'm using XE7.
For apply changed text style, you must set StyledSettings property for changed object.
So, final code looks like this (i dont like with operator)
procedure TForm1.StringGrid1ApplyStyleLookup(Sender: TObject);
var
Header: THeader;
HeaderItem: THeaderItem;
I: Integer;
begin
Header := THeader((Sender as TStringGrid).FindStyleResource('header'));
if Assigned(Header) then
begin
for I := 0 to Header.Count - 1 do
begin
HeaderItem := Header.Items[I];
HeaderItem.Font.Size := 100;
HeaderItem.Font.Style := [TFontStyle.fsBold];
HeaderItem.TextSettings.HorzAlign := TTextAlign.Center;
// new code line:
HeaderItem.StyledSettings := HeaderItem.StyledSettings - [TStyledSetting.Size, TStyledSetting.Style];
end;
Header.Height := 48;
end;
end;

Delphi XE6 firemonkey component alignment problems when added at runtime

i wanto dynamic add 5 TLable in my iOS app.
like this
Procedure Form1.FormCreate(Sender: TObject)
var
I: Integer;
begin
for I := 1 to 5 do
begin
with TLabel.Create(Self) do
begin
Parent := self;
Align := TAlignLayout.Top;
Height := 50;
Text := IntToStr(I);
end;
end;
end;
i think the order is 12345, but I get 15432.
What can I do to get the desired results?
You must give a chance to the aligning algorithm to do what you want.
procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
begin
for I := 1 to 5 do
begin
with TLabel.Create(Self) do
begin
Parent := self;
Align := TAlignLayout.alTop;
Height := 50;
Position.Y := I*Height; //add this line
Text := IntToStr(I);
end;
end;
end;

Delphi 7 - how to use Inputbox

I am programming a program where you have to enter a password into a InputBox to gain access to the programs min features . But I have a problem if you click on cancel on the inputbox my program gives a error message . So i wanted to know if any one know how I can get that right because with the Messagedlg I know you use IF . But how can I get it right with a InputBox ?
InputBox() returns a blank string if the dialog is canceled, eg:
var
Pass: String;
Pass := InputBox('Password needed', 'Enter the password:');
if Pass <> '' then
begin
// use Pass as needed...
end;
Alternatively, use InputQuery() instead, which returns a Boolean to indicate whether the dialog was canceled or not, eg:
var
Pass: String;
if InputQuery('Password needed', 'Enter the password:', Pass) then
begin
// use Pass as needed...
end;
Many times it is better to have a custom InputQuery
function InputValor(const aCaption: String; APrompt: string; var aValor:
String): Boolean;
var
vForm : TForm;
vLabel : TLabel;
vBtnOk : TBitBtn;
vValor : TEdit;
vBtnCancel : TBitBtn;
begin
Result := False;
vForm := TForm.Create(Application);
vLabel := TLabel.Create(vForm);
vValor := TEdit.Create(vForm);
vBtnOk := TBitBtn.Create(vForm);
vBtnCancel := TBitBtn.Create(vForm);
with vForm do
begin
Name := 'frmValor';
Position := poScreenCenter;
BorderIcons := [biSystemMenu];
BorderStyle := bsDialog;
Caption := aCaption;
ClientHeight := 150;
ClientWidth := 515;
Color := clBtnFace;
OldCreateOrder := False;
Font.Charset := DEFAULT_CHARSET;
Font.Color := clWindowText;
Font.Height := -11;
Font.Name := 'Tahoma';
Font.Style := [];
OldCreateOrder := False;
PixelsPerInch := 96;
Left := 0;
Top := 0;
end;
with vLabel do
begin
Name := 'vLabel';
Parent := vForm;
AutoSize := False;
Left := 18;
Top := 15;
Width := 484;
Height := 41;
Caption := APrompt;
WordWrap := True;
end;
with vValor do
begin
Name := 'vValorEdit';
Parent := vForm;
Left := 18;
Top := 62;
Width := 484;
Height := 21;
Text := '';
end;
with vBtnOk do
begin
Name := 'vBtnOk';
Parent := vForm;
Caption := 'Aceptar';
Left := 335;
Top := 103;
Width := 75;
Height := 25;
TabOrder := 1;
ModalResult := mrOk;
end;
with vBtnCancel do
begin
Name := 'vBtnCancel';
Parent := vForm;
Caption := 'Cancelar';
Left := 427;
Top := 103;
Width := 75;
Height := 25;
TabOrder := 2;
ModalResult := mrCancel;
end;
vForm.ShowModal;
if (vForm.ModalResult = mrOk) and (vValor.Text <> '') then
begin
Result := True;
aValor := vValor.Text;
end else
begin
Result := False;
aValor := '';
end;
FreeAndNil(vForm);
end;
Use in the same way as the Official:
var
vTest : String;
begin
if (InputValor('Title', 'Label text', vTest) = True) then
ShowMessage(vTest);
end;

Delphi 7 edit component creation

I have a problem according to run-time creation of edit components in Delphi 7.
So when I create TEdit components after the program ran for "some" time it perfectly works.
However, when I create TEdit elements at the Forms OnCreate event, they have a wrong height.
Furthermore the (almost) simultaneously created Shapes have the right height.
Edit:
procedure TTPLVisorForm.CreateZeichen(ZShape : TShape; ZEdit : TEdit; VLeft : integer);
begin
with ZShape do
begin
Width := 50;
Height := 50;
Left := VLeft;
Top := 25;
Shape := stRectangle;
Parent := self.Band;
SendToBack();
end;
with ZEdit do
begin
Text := '#';
Left := VLeft+1;
Top := 26;
Parent := self.Band;
Font.Height := 48;
Width := 48;
Height := 48;
SendToBack;
end;
end;
Getting called by:
procedure TZeichen.Anzeigen(Form : TObject; Left : integer);
begin
self.Form := Form;
self.ZShape := TShape.Create(TTPLVisorForm(self.Form).Band);
self.ZEdit := TEdit.Create(TTPLVisorForm(self.Form).Band);
TTPLVisorForm(Form).CreateZeichen(self.ZShape, self.ZEdit, Left);
end;
Getting called by:
procedure TMagnetband.ErweitereRechts;
var
Zeichen : TZeichenKette;
begin
Zeichen := TZeichenKette.Create;
self.LetztesZeichen.Naechstes := TZeichenKette(Zeichen);
Zeichen.Vorheriges := self.LetztesZeichen;
Zeichen.Zeichen.Anzeigen(self.Form,
self.LetztesZeichen.Zeichen.ZShape.Left +
self.LetztesZeichen.Zeichen.ZShape.Width +
self.Padding);
self.LetztesZeichen := Zeichen;
self.Laenge := self.Laenge+1;
end;
Getting again called by:
procedure TTuringmaschine.ZeichenAnfuegen;
begin
self.Magnetband.ErweitereRechts;
end;
Getting called by:
procedure TTuringmaschine.PanelResize(Sender: TObject);
begin
while self.Magnetband.GetRechtsMax < self.Panel.Width do
self.ZeichenAnfuegen;
end;
Finally gets called by:
Constructor TTuringmaschine.Create(Form : TObject);
var
Breite : integer;
begin
self.Zustand := 0;
self.Form := TTPLVisorForm(Form);
self.Panel := TTPLVisorForm(self.Form).Band;
self.Magnetband := TMagnetband.Create(self.Form);
TTPLVisorForm(Form).Band.OnResize := self.PanelResize;
self.PanelResize(Nil);
//self.CreateMagnetkopf;
end;
And the Constructor is either called at the OnCreate event or on another event.
There's a margin around the text in TEdit control, so if you set the Font.Height to 48, the height of the control won't be exactly 48 if the control has the AutoSize property set to True. I would personally decrease height of the font, and for being sure turn the AutoSize off. Your CreateZeichen method would then look like this:
procedure TTPLVisorForm.CreateZeichen(ZShape: TShape; ZEdit: TEdit;
VLeft: Integer);
begin
with ZShape do
begin
Width := 50;
Height := 50;
Left := VLeft;
Top := 25;
Shape := stRectangle;
Parent := Self.Band;
SendToBack;
end;
with ZEdit do
begin
AutoSize := False;
Text := '#';
Left := VLeft + 1;
Top := 26;
Parent := Self.Band;
Font.Height := 40;
Width := 48;
Height := 48;
SendToBack;
end;
end;

Resources