Get component text based on component name - delphi

So I creat some TEdit components like this
var
lb : TLabel;
topLabel, i: Integer;
dbedit : TEdit;
begin
inherited;
topLabel := 40;
i := 0;
lb := TLabel.Create(nil);
lb.Parent := GroupBox2;
lb.Left := 245;
lb.Top := 20;
lb.Caption := 'ASD';
with DataModule.myStoredProc do begin
Close;
ParamByName('#Param1').AsInteger := 1;
ExecProc;
Open;
SetLength(nrPozitiiDinctionar,RecordCount);
First;
while not Eof do begin
lb := TLabel.Create(nil);
lb.Parent := GroupBox2;
lb.Left := 7;
lb.Top := topLabel ;
lb.Caption := FieldByName('X').AsString;
dbedit := TEdit.Create(nil);
dbedit.Name := 'Edit'+IntToStr(FieldByName('Poz').AsInteger);
dbedit.Text := '';
dbedit.Parent := GroupBox2;
dbedit.Height := 21;
dbedit.Width := 40;
dbedit.Left := 240;
dbedit.Top := lb.Top-3 ;
topLabel := topLabel + 30;
nrPozitiiDinctionar[i] := FieldByName('Poz').AsInteger;
i := i + 1;
Next;
end;
end;
end;
Then after the user add his input I run a function with this code
var
IDPoz, I : Integer;
dbedit : TEdit;
pctj,nume : string;
begin
for I := Low(nrPozitiiDinctionar) to High(nrPozitiiDinctionar) do
begin
nume := 'Edit'+IntToStr(nrPozitiiDinctionar[i]);
pctj := TEdit(FindComponent('Edit'+IntToStr(nrPozitiiDinctionar[i]))).Text;
with DateCOFurnizori.spCOFCmzFurnizoriEvaluarePozitii_Edit do begin
ParamByName('#IDEvaluare').AsInteger := StrToInt(Edit1.Text);
ParamByName('#IDPozitie').AsInteger := IDPoz;
ParamByName('#DictionarID').AsInteger := 9103;
ParamByName('#DictionarPozitiiID').AsInteger := nrPozitiiDinctionar[i];
ParamByName('#Punctaj').AsFloat := 1 ;//StrToFloat(pctj) ;
ParamByName('#DataEvaluare').AsDateTime := Now;
ExecProc;
IDPoz := IDPoz + 1;
end;
end;
This is only a portion of the code but this should relate to my problem.
When I use the debugger there is no value in pctj, what am I doing wrong? I try to get the value of the TEdits based on their names. What am I doing wrong with the FindComponent function?

You are not assigning an Owner to the TEdit controls, so that is why FindComponent() cannot find them. Either assign Self as the Owner (since you are calling Self.FindComponent()), or else store the TEdit pointers in a TList or TObjectList that you can loop through when needed.

Related

change width SysIPAddress32

I'm trying implement IP edit. This my code:
unit Main;
interface
uses
System.SysUtils, System.Classes,
Winapi.Windows, Winapi.Messages, Winapi.CommCtrl,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.StdCtrls, Vcl.ComCtrls;
type
TIpEdit = class(TWinControl)
strict protected
procedure CreateParams(var Params: TCreateParams); override;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
procedure WMSetFont(var Message: TWMSetFont); message WM_SETFONT;
end;
TMainForm = class(TForm)
Btn1: TButton;
procedure FormCreate(Sender: TObject);
procedure Btn1Click(Sender: TObject);
private
FIpEdit: TIpEdit;
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
{ TIPEdit }
procedure TIPEdit.CreateParams(var Params: TCreateParams);
begin
InitCommonControl(ICC_INTERNET_CLASSES);
inherited CreateParams(Params);
CreateSubClass(Params, WC_IPADDRESS);
Params.Style := Params.Style or WS_TABSTOP or WS_CHILD;
end;
procedure TIPEdit.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
inherited;
Message.Result := Message.Result or DLGC_WANTARROWS;
end;
procedure TIPEdit.WMSetFont(var Message: TWMSetFont);
var
LF: LOGFONT;
begin
if GetObject(Message.Font, SizeOf(LF), #LF) <> 0 then
begin
Message.Font := CreateFontIndirect(LF);
inherited;
end;
end;
{ TMainForm }
procedure TMainForm.Btn1Click(Sender: TObject);
begin
FIpEdit.Width := FIpEdit.Width + 100;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
FIpEdit := TIpEdit.Create(Self);
FIpEdit.Parent := Self;
FIpEdit.SetBounds(10, 10, 120, 21);
end;
end.
Before Btn1.Click
After Btn1.Click
As a result: Control change own width but not change width internal edits.
I try fix by two ways
Use RecreateWnd. This works, but IMHO its ugly solution.
Fix internal edits width manualy. This works, but it is difficult to
implement, due to the internal work of the control
Maybe I missed something and there is a simpler solution?
Edit:
I tested the RecreateWnd, but it can not be used when using DevExpress layout control. It seems that layout control uses the direct call of the API bypassing the SetBounds method. In this case RecreateWnd can not be using.
The final conclusion is:
RecreateWnd is simple solution with some ristrictions
RepeatUntil answer more difficult, but always working
The control does not provide a mechanism to update its layout after it has been created. Yes you could hack at the internal edit controls, but that is dangerous. You'd be relying on undocumented implementation detail that is subject to change.
In summary, I would say that recreating the window is the best solution available.
You can use TPanel with child TEdit controls to create your own IP Edit, That will give you more control of their property.
This how its look at run time:
I wrote this time ago, its not completed work but may give an idea of what i mean.
unit IPEdit;
interface
uses
System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Forms,
Vcl.Graphics, System.UITypes;
type
TExitType = (etNone, etNext);
type
TIPEdit = class(TCustomPanel)
private
FPart1 : TEdit;
FPart2 : TEdit;
FPart3 : TEdit;
FPart4 : TEdit;
FSplitter1 : TPanel;
FSplitter2 : TPanel;
FSplitter3 : TPanel;
FRiseErr : Boolean;
FErrMsg : string;
FExitType : TExitType;
FBevelInner : TPanelBevel;
FLeadingzero: Boolean;
procedure SetExitType(Value : TExitType);
procedure SetBevelInner(Value: TPanelBevel);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
protected
procedure EditOnKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure EditOnChange(Sender: TObject);
procedure OnPanelResize(Sender: TObject);
procedure EditOnExit(Sender: TObject);
published
property ShowError: Boolean read FRiseErr write FRiseErr default False;
property Leadingzero: Boolean read FLeadingzero write FLeadingzero default False;
property ErrorText: string read FErrMsg write FErrMsg;
property ExitType: TExitType read FExitType write SetExitType default etNext;
property BevelInner: TPanelBevel read FBevelInner write SetBevelInner default bvNone;
end;
implementation
const
Msg_Err_Value_Exceeded = 'Value cannot be greater than 255';
SplitterWidth = 5;
{ TIPEdit }
constructor TIPEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if AOwner is TWinControl then
Parent := TWinControl(AOwner);
{ Main Panle Style }
ParentBackground := False;
BevelKind := bkFlat;
BevelOuter := bvNone;
Color := clWindow;
Height := 25;
Width := 165;
Caption := '';
/////////////////////////////
{ Set Handlers}
OnResize := OnPanelResize;
{ Create child controls }
FPart1 := TEdit.Create(Self);
FPart1.Name := 'IPEditPart1';
FPart1.Visible := False;
FSplitter1 := TPanel.Create(Self);
FSplitter1.Name := 'IPSplitter1';
FSplitter1.Visible:= False;
FPart2 := TEdit.Create(Self);
FPart2.Name := 'IPEditPart2';
FPart2.Visible := False;
FSplitter2 := TPanel.Create(Self);
FSplitter2.Name := 'IPSplitter2';
FSplitter2.Visible:= False;
FPart3 := TEdit.Create(Self);
FPart3.Name := 'IPEditPart3';
FPart3.Visible := False;
FSplitter3 := TPanel.Create(Self);
FSplitter3.Name := 'IPSplitter3';
FSplitter3.Visible:= False;
FPart4 := TEdit.Create(Self);
FPart4.Name := 'IPEditPart4';
FPart4.Visible := False;
FPart1.Align := alLeft;
FSplitter1.Align := alLeft;
FPart2.Align := alLeft;
FSplitter2.Align := alLeft;
FPart3.Align := alLeft;
FSplitter3.Align := alLeft;
FPart4.Align := alLeft;
/////////////////////////////
{ Set Child Style }
// This order is very important //
FPart1.Parent := TWinControl(Self);
FSplitter1.Parent := TWinControl(Self);
FPart2.Parent := TWinControl(Self);
FSplitter2.Parent := TWinControl(Self);
FPart3.Parent := TWinControl(Self);
FSplitter3.Parent := TWinControl(Self);
FPart4.Parent := TWinControl(Self);
FPart1.Visible := True;
FSplitter1.Visible := True;
FPart2.Visible := True;
FSplitter2.Visible := True;
FPart3.Visible := True;
FSplitter3.Visible := True;
FPart4.Visible := True;
//////////////////////////////////
FPart1.Alignment := taCenter;
FPart2.Alignment := taCenter;
FPart3.Alignment := taCenter;
FPart4.Alignment := taCenter;
FPart1.Margins.Left := 0;
FPart2.Margins.Left := 0;
FPart3.Margins.Left := 0;
FPart4.Margins.Left := 0;
FSplitter1.Margins.Left := 0;
FSplitter2.Margins.Left := 0;
FSplitter3.Margins.Left := 0;
FPart1.Margins.Right := 0;
FPart2.Margins.Right := 0;
FPart3.Margins.Right := 0;
FPart4.Margins.Right := 0;
FSplitter1.Margins.Right := 0;
FSplitter2.Margins.Right := 0;
FSplitter3.Margins.Right := 0;
FPart1.AlignWithMargins := True;
FSplitter1.AlignWithMargins := True;
FPart2.AlignWithMargins := True;
FSplitter2.AlignWithMargins := True;
FPart3.AlignWithMargins := True;
FSplitter3.AlignWithMargins := True;
FPart4.AlignWithMargins := True;
FPart1.AutoSize := False;
FPart2.AutoSize := False;
FPart3.AutoSize := False;
FPart4.AutoSize := False;
FPart1.BorderStyle := bsNone;
FPart2.BorderStyle := bsNone;
FPart3.BorderStyle := bsNone;
FPart4.BorderStyle := bsNone;
FPart1.NumbersOnly := True;
FPart2.NumbersOnly := True;
FPart3.NumbersOnly := True;
FPart4.NumbersOnly := True;
FPart1.MaxLength := 3;
FPart2.MaxLength := 3;
FPart3.MaxLength := 3;
FPart4.MaxLength := 3;
FPart1.Width := 36;
FPart2.Width := 36;
FPart3.Width := 36;
FPart4.Width := 36;
FSplitter1.Alignment := taCenter;
FSplitter2.Alignment := taCenter;
FSplitter3.Alignment := taCenter;
FSplitter1.Caption := '.';
FSplitter2.Caption := '.';
FSplitter3.Caption := '.';
FSplitter1.BevelOuter := bvNone;
FSplitter2.BevelOuter := bvNone;
FSplitter3.BevelOuter := bvNone;
FSplitter1.Color := clWindow;
FSplitter2.Color := clWindow;
FSplitter3.Color := clWindow;
FSplitter1.ParentBackground := False;
FSplitter2.ParentBackground := False;
FSplitter3.ParentBackground := False;
FSplitter1.TabStop := False;
FSplitter2.TabStop := False;
FSplitter3.TabStop := False;
FSplitter1.Width := SplitterWidth;
FSplitter2.Width := SplitterWidth;
FSplitter3.Width := SplitterWidth;
FSplitter1.Font.Style := FSplitter1.Font.Style + [fsBold];
FSplitter2.Font.Style := FSplitter2.Font.Style + [fsBold];
FSplitter3.Font.Style := FSplitter3.Font.Style + [fsBold];
//////////////////////////////
{Set Child handlers}
FPart1.OnChange := EditOnChange;
FPart2.OnChange := EditOnChange;
FPart3.OnChange := EditOnChange;
FPart4.OnChange := EditOnChange;
FPart1.OnKeyDown := EditOnKeyDown;
FPart2.OnKeyDown := EditOnKeyDown;
FPart3.OnKeyDown := EditOnKeyDown;
FPart4.OnKeyDown := EditOnKeyDown;
FPart1.OnExit := EditOnExit;
FPart2.OnExit := EditOnExit;
FPart3.OnExit := EditOnExit;
FPart4.OnExit := EditOnExit;
{Set Child control tab order for the handlers work}
FPart1.TabOrder := 0;
FPart2.TabOrder := 1;
FPart3.TabOrder := 2;
FPart4.TabOrder := 3;
FPart1.Text := '1';
FPart2.Text := '2';
FPart3.Text := '3';
FPart4.Text := '4';
FExitType := etNext;
FErrMsg := Msg_Err_Value_Exceeded;
end;
destructor TIPEdit.Destroy;
begin
FPart1.Free;
FPart2.Free;
FPart3.Free;
FPart4.Free;
FSplitter1.Free;
FSplitter2.Free;
FSplitter3.Free;
inherited;
end;
procedure TIPEdit.EditOnChange(Sender: TObject);
var
iValue : Integer;
bValGrater : Boolean;
I: Integer;
begin
if NOT (Sender is TEdit) then Exit;
bValGrater := False;
if TryStrToInt(TEdit(Sender).Text, iValue) then begin
if (iValue > 255) then begin
iValue := 255;
bValGrater := True;
TEdit(Sender).Text := iValue.ToString;
if (FRiseErr and bValGrater) then
raise Exception.Create(FErrMsg);
end;
end;
if Length(TEdit(Sender).Text) = 3 then begin
case FExitType of
etNone: ;
etNext: FindNextControl(TEdit(Sender), True, False, False).SetFocus;
end;
end;
end;
procedure TIPEdit.EditOnKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
const
vkReturn = $0D;
begin
if not (Sender is TEdit) then Exit;
if Key = vkReturn then
FindNextControl(TEdit(Sender), True, False, False).SetFocus;
end;
procedure TIPEdit.OnPanelResize(Sender: TObject);
const
EditCount = 4;
SplitterCount = 3;
var
EditWidth : Integer;
FSplitterWidth : Integer;
EditMargin : Integer;
begin
EditWidth := Trunc(((Width) / EditCount) - (SplitterCount * (SplitterWidth)));
FPart1.Width := EditWidth;
FPart2.Width := EditWidth;
FPart3.Width := EditWidth;
FPart4.Width := EditWidth;
FSplitterWidth := Trunc(( (Width) - ( EditWidth * EditCount) ) / SplitterCount);
FSplitter1.Width := FSplitterWidth;
FSplitter2.Width := FSplitterWidth;
FSplitter3.Width := FSplitterWidth;
{Center edits text vertically == this is a temporary workaround}
FPart1.Margins.Top := 0;
FPart2.Margins.Top := 0;
FPart3.Margins.Top := 0;
FPart4.Margins.Top := 0;
EditMargin := Round( ((Height / 5)));
FPart1.Margins.Top := EditMargin;
FPart2.Margins.Top := EditMargin;
FPart3.Margins.Top := EditMargin;
FPart4.Margins.Top := EditMargin;
FSplitter1.Margins.Top := EditMargin + SplitterWidth; { the +lblWidth to make it lower than the edits}
FSplitter2.Margins.Top := EditMargin + SplitterWidth;
FSplitter3.Margins.Top := EditMargin + SplitterWidth;
end;
procedure TIPEdit.SetBevelInner(Value: TPanelBevel);
begin
TPanel(Self).BevelInner := Value;
end;
procedure TIPEdit.SetExitType(Value: TExitType);
begin
FExitType := Value;
end;
procedure TIPEdit.EditOnExit(Sender: TObject);
var
I: Integer;
begin
if not (Sender IS TEdit) then Exit;
if FLeadingzero then begin
if Length(TEdit(Sender).Text) >= 1 then
for I := Length(TEdit(Sender).Text) to 2 do begin
TEdit(Sender).Text := '0' + TEdit(Sender).Text;
end;
end;
end;
end.

Draw TPanel and TSplitter at runtime results in wrong component order

If I create multiple TPanel and TSplitter components at runtime into a TScrollBox, the order of the components is wrong. If I call drawInput() 3 times, the scrollbox contains 3 panels followed by 3 splitters instead of 1 panel followed by 1 splitter (repeated).
How can I force the correct order?
Here is a screenshot
function drawInput(owner: TWinControl): TWinControl;
var
panel: TPanel;
edit: TEdit;
splitter: TSplitter;
begin
panel := TPanel.Create(owner);
panel.Parent := owner;
panel.Align := alTop;
panel.AlignWithMargins := True;
panel.BorderWidth := 0;
panel.Color := clRed;
panel.BorderStyle := bsNone;
panel.ParentBackground := False;
panel.Ctl3D := False;
edit := TEdit.Create(panel);
edit.Parent := panel;
edit.Align := alTop;
edit.AlignWithMargins := True;
edit.Text := 'foo';
edit.Margins.Left := 5;
edit.Margins.top := 5;
edit.Margins.Bottom := 5;
edit.Margins.Right := 5;
splitter := TSplitter.Create(owner);
splitter.Parent := owner;
splitter.Align := alTop;
splitter.Beveled := True;
splitter.Height := 3;
end;
EDIT:
Here is how I call this function:
procedure TForm2.Button1Click(Sender: TObject);
var
form: TForm;
sb: TScrollBox;
begin
form := TForm.Create(Application);
sb := TScrollBox.Create(form);
sb.Parent := form;
sb.Align := alClient;
sb.Color := clBlack;
drawInput(sb);
drawInput(sb);
drawInput(sb);
drawInput(sb);
form.Width := 300;
form.Height := 700;
form.ShowModal;
end;
Position your panel + splitter then set the alignment
You can position you panel below all other components by aligning it to the client
function drawInput(owner: TWinControl): TWinControl;
var
panel: TPanel;
edit: TEdit;
splitter: TSplitter;
begin
panel := TPanel.Create(owner);
panel.Parent := owner;
///
panel.Align := alclient;
///
panel.Align := alTop;
panel.AlignWithMargins := True;
panel.BorderWidth := 0;
panel.Color := clRed;
panel.BorderStyle := bsNone;
panel.ParentBackground := False;
panel.Ctl3D := False;
splitter := TSplitter.Create(owner);
splitter.Parent := owner;
//
splitter.top := panel.top+panel.height;
//
splitter.Align := alTop;
splitter.Beveled := True;
splitter.Height := 3;
end;
Delphi's alignment logic can be hard at times. But the following works. Note the line splitter.Top := -1;
function drawInput(owner: TWinControl): TWinControl;
var
panel: TPanel;
edit: TEdit;
splitter: TSplitter;
begin
splitter := TSplitter.Create(owner);
splitter.Parent := owner;
splitter.Align := alTop;
splitter.Beveled := True;
splitter.Height := 3;
splitter.Top := -1;
panel := TPanel.Create(owner);
panel.Parent := owner;
panel.Align := alTop;
panel.AlignWithMargins := True;
panel.BorderWidth := 0;
panel.Color := clRed;
panel.BorderStyle := bsNone;
panel.ParentBackground := False;
panel.Ctl3D := False;
edit := TEdit.Create(panel);
edit.Parent := panel;
edit.Align := alTop;
edit.AlignWithMargins := True;
edit.Text := 'foo';
edit.Margins.Left := 5;
edit.Margins.top := 5;
edit.Margins.Bottom := 5;
edit.Margins.Right := 5;
end;
Here's the code that works for me on XE5. I still have to solve my problem but at least I fixed yours :)
procedure drawInput(owner: TWinControl; var t: integer);
var
panel: TPanel;
edit: TEdit;
splitter: TSplitter;
begin
panel := TPanel.Create(owner);
panel.Parent := owner;
panel.Align := alTop;
panel.AlignWithMargins := True;
panel.BorderWidth := 0;
panel.Color := clRed;
panel.BorderStyle := bsNone;
panel.ParentBackground := False;
panel.Ctl3D := False;
panel.Top := t;
t := panel.Top + panel.Height + 1;
edit := TEdit.Create(panel);
edit.Parent := panel;
edit.Align := alTop;
edit.AlignWithMargins := True;
edit.Text := 'foo';
edit.Margins.Left := 5;
edit.Margins.top := 5;
edit.Margins.Bottom := 5;
edit.Margins.Right := 5;
splitter := TSplitter.Create(owner);
splitter.Parent := owner;
splitter.Align := alTop;
splitter.Beveled := True;
splitter.Height := 3;
splitter.Top := t;
t := splitter.Top + splitter.Height + 1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
form: TForm;
sb: TScrollBox;
t: integer;
begin
form := TForm.Create(Application);
sb := TScrollBox.Create(form);
sb.Parent := form;
sb.Align := alClient;
sb.Color := clBlack;
t := 0;
drawInput(sb, t);
drawInput(sb, t);
drawInput(sb, t);
drawInput(sb, t);
form.Width := 300;
form.Height := 700;
form.ShowModal;
end;
In one of my applications, I have a function that creates a TImage and follows it with a TSplitter with the parent and containing control being a TScrollbox (sbScroller). The function is either called by the end user (tied to a TButton OnClick event) when they select an image or when the program starts it loads a previously loaded set of images each divided by a TSplitter.
It works when run alone by itself (creating one TImage + TSplitter pairing) or when run in a continuous loop to create multiple pairings. The key element in getting it to work seems to the positioning of the TSplitter.Top property as the previous answer says:
procedure AddImage(AFilename: string);
var
Image: TImage;
begin
Image := TImage.Create(sbScroller);
with Image do
begin
Image.Parent := sbScroller;
Left := 0;
Top := 0;
Width := 150;
Height := 150;
Constraints.MinHeight := 128;
Align := alTop;
Anchors := [akLeft, akTop, akRight];
Proportional := True;
Stretch := True;
Visible := True;
end;
if sbScroller.ControlCount > 0 then
with TSplitter.Create(sbScroller) do
begin
Parent := sbScroller;
Top := Image.Top;
Align := alTop;
Color := clGray;
end;
end;

Creating a new btnClick procedure for a dynamic button

I'm having trouble creating a new procedure for a dynamic button. When the button is clicked, it supposed to send items to a RichEdit.
I have declared all my objects and my procedures.
Here's my code:
type
TfrmSale = class(TForm)
redOutput: TRichEdit;
btnBuy: TButton;
procedure btnBuyClick(Sender: TObject);
private
pnlSale : TPanel;
edtQuantity : TEdit;
rgpOptions : TRadioGroup;
btnSelect : TButton;
procedure btnSelectCick(Sender: TObject);
public
{ Public declarations }
end;
var
frmSale: TfrmSale;
implementation
{$R *.dfm}
procedure TfrmSale.btnBuyClick(Sender: TObject);
begin
pnlSale := TPanel.Create(frmSale);
pnlSale.Parent := frmSale;
pnlSale.Left := 10;
pnlSale.Top := 10;
pnlSale.Width := 350;
pnlSale.Height := 250;
pnlSale.Visible := True;
edtQuantity := TEdit.Create(pnlSale);
edtQuantity.Parent := pnlSale;
edtQuantity.Left := 50;
edtQuantity.Top := 60;
edtQuantity.Width := 80;
edtQuantity.Height := 20;
edtQuantity.Text := 'Quantity';
edtQuantity.Visible := True;
rgpOptions := TRadioGroup.Create(pnlSale);
rgpOptions.Parent := pnlSale;
rgpOptions.Left := 30;
rgpOptions.Top := 100;
rgpOptions.Width := 300;
rgpOptions.Height := 140;
rgpOptions.Visible := True;
rgpOptions.Caption := 'Options';
rgpOptions.Items.Add('Screws 12mm');
rgpOptions.Items.Add('Canned Peaches 250g');
rgpOptions.Items.Add('Tomatoes');
rgpOptions.Items.Add('Spaghetti 500g');
rgpOptions.Items.Add('Twin Flex 5m');
rgpOptions.Items.Add('Clear Glue 250ml');
btnSelect := TButton.Create(frmSale);
btnSelect.Parent := frmSale;
btnSelect.Left := 130;
btnSelect.Top := 260;
btnSelect.Width := 80;
btnSelect.Height := 40;
btnSelect.Caption := 'Select';
end;
procedure TfrmSale.btnSelectClick(Sender: TObject);
case rgpOptions.ItemIndex of
1 := redOutput.Lines.Add('Screws 12mm');
2 := redOutput.Lines.Add('Canned Peaches 250g');
3 := redOutput.Lines.Add('Refil Blue Pen');
4 := redOutput.Lines.Add('Tomatoes');
5 := redOutput.Lines.Add('Spaghetti 500g');
6 := redOutput.Lines.Add('Twin Flex 5m');
7 := redOutput.Lines.Add('Clear Glue 250ml');
end
Please can someone help me make a OnClick procedure.
AS TLama said. If you're going to create your buttons in code,you need to also assign the OnClick handler in code.
type
TfrmSale = class(TForm)
redOutput: TRichEdit;
btnBuy: TButton;
procedure btnBuyClick(Sender: TObject); <<--- link made in designer
private VVVVV-- from here on it's
pnlSale : TPanel; your responsibility
edtQuantity : TEdit;
rgpOptions : TRadioGroup;
btnSelect : TButton;
procedure btnSelectCick(Sender: TObject); <<-- link must be made in code
public
{ Public declarations }
end;
var
frmSale: TfrmSale;
implementation
{$R *.dfm}
procedure TfrmSale.btnBuyClick(Sender: TOBject);
begin
pnlSale := TPanel.Create(frmSale);
pnlSale.Parent := frmSale;
pnlSale.Left := 10;
pnlSale.Top := 10;
pnlSale.Width := 350;
pnlSale.Height := 250;
pnlSale.Visible := True;
edtQuantity := TEdit.Create(pnlSale);
edtQuantity.Parent := pnlSale;
edtQuantity.Left := 50;
edtQuantity.Top := 60;
edtQuantity.Width := 80;
edtQuantity.Height := 20;
edtQuantity.Text := 'Quantity';
edtQuantity.Visible := True;
rgpOptions := TRadioGroup.Create(pnlSale);
rgpOptions.Parent := pnlSale;
rgpOptions.Left := 30;
rgpOptions.Top := 100;
rgpOptions.Width := 300;
rgpOptions.Height := 140;
rgpOptions.Visible := True;
rgpOptions.Caption := 'Options';
rgpOptions.Items.Add('Screws 12mm');
rgpOptions.Items.Add('Canned Peaches 250g');
rgpOptions.Items.Add('Tomatoes');
rgpOptions.Items.Add('Spaghetti 500g');
rgpOptions.Items.Add('Twin Flex 5m');
rgpOptions.Items.Add('Clear Glue 250ml');
btnSelect := TButton.Create(frmSale);
btnSelect.OnClick:= btnSelectCick; <<-- Assign the button handler
btnSelect.Parent := frmSale;
btnSelect.Left := 130;
btnSelect.Top := 260;
btnSelect.Width := 80;
btnSelect.Height := 40;
btnSelect.Caption := 'Select';
end;
procedure TfrmSale.btnSelectClick(Sender: TOBject);
begin
redOutput.Lines.Add(rgpOptions.Lines[rgpOptions.ItemIndex]); <<-- DRY
end;
Note that I've tweaked btnSelectClick so that it reuses the data you've stored into rgpOptions previously.
See also: http://en.wikipedia.org/wiki/Don%27t_repeat_yourself

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;

How to show dialog box with two buttons ( Continue / Close ) in Delphi

I want to create a warning dialog box which asks the users if the information typed during signup was correct, and asks him wether he want to continue or close that dialog and correct his information.
var
td: TTaskDialog;
tb: TTaskDialogBaseButtonItem;
begin
td := TTaskDialog.Create(nil);
try
td.Caption := 'Warning';
td.Text := 'Continue or Close?';
td.MainIcon := tdiWarning;
td.CommonButtons := [];
tb := td.Buttons.Add;
tb.Caption := 'Continue';
tb.ModalResult := 100;
tb := td.Buttons.Add;
tb.Caption := 'Close';
tb.ModalResult := 101;
td.Execute;
if td.ModalResult = 100 then
ShowMessage('Continue')
else if td.ModalResult = 101 then
ShowMessage('Close');
finally
td.Free;
end;
end;
Note: This will only work on Windows Vista or later.
if delphi then
if mrYes=MessageDlg('Continue?',mtwarning,[mbYes, mbNo],0) then
begin
//do somthing
end
else
exit; //go out
var
AMsgDialog: TForm;
abutton: TButton;
bbutton: TButton;
begin
AMsgDialog := CreateMessageDialog('This is a test message.', mtWarning,[]);
abutton := TButton.Create(AMsgDialog);
bbutton := TButton.Create(AMsgDialog);
with AMsgDialog do
try
Caption := 'Dialog Title' ;
Height := 140;
AMsgDialog.Width := 260 ;
with abutton do
begin
Parent := AMsgDialog;
Caption := 'Continue';
Top := 67;
Left := 60;
// OnClick :tnotyfievent ;
end;
with bbutton do
begin
Parent := AMsgDialog;
Caption := 'Close';
Top := 67;
Left := 140;
//OnClick :tnotyfievent ;
end;
ShowModal ;
finally
abutton.Free;
bbutton.Free;
Free;
end;
Based on this:
procedure HookResourceString(rs: PResStringRec; newStr: PChar);
var
oldprotect: DWORD;
begin
VirtualProtect(rs, SizeOf(rs^), PAGE_EXECUTE_READWRITE, #oldProtect);
rs^.Identifier := Integer(newStr);
VirtualProtect(rs, SizeOf(rs^), oldProtect, #oldProtect);
end;
const
SContinue = 'Continue';
SClose = 'Close';
procedure TForm1.Button1Click(Sender: TObject);
begin
HookResourceString(#SMsgDlgOK, SContinue);
HookResourceString(#SMsgDlgCancel, SClose);
if MessageDlg('My Message', mtConfirmation, [mbOK, mbCancel], 0) = mrOK then
begin
// OK...
end;
end;

Resources