views:

175

answers:

3

Hi,

I'm developing the app which has input fields and whenever user enters the controll, extra panel is being generated with the buttons.

The buttons have captions representing special symbols like degree, greek symbols.

When the button is pressed, corresponding special character should be added to the input fields TEdit existing text.

There are many input fields on the form. So on each OnEnter event of the TEdit it generates the special symbol selection panel, and OnExit event will Free the panel.

I want to somehow tell a button which TEdit he should add the symbol to, when he is pressed.

procedure TForm1.SpecSimboliai(Parent: TWinControl; Edit: TEdit);
var
    pSpec: TPanel;
    oClose: TPanelEx;
    sTekstas: TLabel;
    oButton: TPanelEx;
begin
    pSpec := TPanel.Create(Self);
    pSpec.Parent := Parent;
    pSpec.Align := alBottom;
    pSpec.Height := 38;
    pSpec.Name := 'spec';
    pSpec.Caption := '';
    pSpec.ParentBackground := false;

    sTekstas := TLabel.Create(Self);
    sTekstas.Parent := pSpec;
    sTekstas.Left := 10;
    sTekstas.Top := 12;
    sTekstas.Caption := 'Specialūs simboliai:';

    oClose := TPanelEx.Create(Self);
    oClose.Parent := pSpec;
    ...
    oClose.Top := 2;
    oClose.Anchors := [akTop,akRight];
    oClose.OnClick := UzdarytiSpec;

    oButton := TPanelEx.Create(Self);
    oButton.Parent := pSpec;
    oButton.Width := 14;
    oButton.Height := 14;
    oButton.CenterText := true;
    oButton.Caption := #$00B0;
    oButton.OnClick := AddSpecSymbol;

    ... //several other buttons
end;

This procedure is run on TEdit.OnEnter event which looks like

..InputEnter(Sender: TObject);
begin
    SpecSimboliai(TEdit(Sender).Parent,TEdit(Sender));
end;

So the panel, label, close button and the degree sign button is created in the above code.

I want to pass the Edit parameter to a button so he will know what controll he is working with, however, i have no idea how to do it as oButton.OnClick event only expects one parameter, which is Sender: TObject.

What i imagine i would want is something like this:

oButton.OnClick := AddSpecSymbol(Edit);

So it would sound like: oButton.OnClick(Sender: TObject) and AddSpecSymbol(Sender: TObject; Edit: TEdit) have same parameter Sender which they use when event occurs, but parameter Edit is the extra one which is assigned by hand already and should be used by AddSpecSymbol.

ok, i hope all of what i have written is possible to understand to you, if no, tell me and i'll try to edit.

Thank you

+4  A: 

You can introduce a field in the form which specifies the current TEdit. Set it to TEdit(Sender) when entering the field and set it to nil when leaving the field. The OnClick event can then use this field to access the proper TEdit.

Uwe Raabe
+3  A: 

One possible, but "messy" method would be to use the Tag property to save the button object cast to Integer

oButton := TPanelEx.Create(Self);
oButton.Parent := pSpec;
oButton.Width := 14;
oButton.Height := 14;
oButton.CenterText := true;
oButton.Caption := #$00B0;
oButton.Tag := Integer(Edit);
oButton.OnClick := AddSpecSymbol;

When AddSpecSymbol is called, cast the Tag back to TEdit

var
  Edit : TEdit;
begin
  Edit := TEdit((Sender as TButton).Tag);
Gerry
Thank you. I would accept both answers if i could. Both are nice and working. In your case tho, i have used this Edit := TEdit(TPanelEx(Sender).Tag)
+1  A: 

Another option would be to create a new type TSpecialSymbolPanel = class(TCustomForm). You could create the panel with the buttons and have the OnClick handling in that type. Since it's a new type it can have additional properties, one of which could be the linked TEdit. I believe this moving this code out of your main form would be considered an appropriate refactoring.

To do this add a new form to your project. Size it like your panel and place all the buttons on it.

Then you can add a private variable like: FLinkedEdit: TEdit; and a public property like: property LinkedEdit TEdit read FLinkedEdit write FLinkedEdit; In the OnClick for each button do something like: FLinkedEdit.Text := FLinkedEdit.Text + 'special character';

In you main form add this new unit to your uses clause.

Then add a private variable: FSpecialSymbolPanel: TSpecialSymbolPanel;

In the FormCreate initialize the panel something like this:

FSpecialSymbolPanel := TSpecialSymbolPanel.Create(Self); with FSpecialSymbolPanel do begin BorderIcons := []; BorderStyle := bsNone; Parent := -parent component-; Visible := False; end;

Then in the OnEnter of your edit controls you can do this:

with FSpecialSymbolPanel do begin Top := TEdit(Sender).Top; Left := TEdit(Sender).Left + TEdit(Sender).Width; Visible := True; LinkedEdit := TEdit(Sender); end

In the OnExit just hide the panel: FSpecialSymbolPanel.Visible := False;

Cheers, Tony

Tony