I'm trying to enter characters into an edit box by way of the user clicking buttons on a Delphi form. Button1, for example, adds to the contents of the edit box the character '1'; Button2 adds the character '2', etc.
Here is the relevant code in the event handler for each button - to take Button1 adding 1 as an example:
Edit1.text := Edit1.Text + '1';
The problem is that clicking on some buttons ensures the a number appears in the edit box while clicking on others does not, ie no number appears.
Can anyone explain what I'm doing wrong, and explain what the problem is? I'm new to all this.
Add this event handler to your form:
procedure TForm1.NumberButtonClick(Sender: TObject);
begin
Edit1.Text := Edit1.Text + (Sender as TButton).Caption;
end;
Using the Object Inspector's Events tab, set the OnClick handler of all the buttons on the panel to the above event handler.
This works perfectly in Delphi 10.1 Berlin and Delphi 2007. If it doesn't work for you, then you have something else happening and will need to post enough code for us to use to reproduce the problem.
Related
There are two tedit
One is enabled for the user, and the other disabled.
The moment user types anything in the tedit, the same thing gets typed in the disabled tedit, while the user is typing.
I don't want to use any buttons for this.
How to implement this in Delphi?
You can use the OnChange event of your first TEdit and set text of the second edit to the text of the first. This should look like
procedure TForm1.Edit1Change(Sender: TObject);
begin
Edit2.Text := Edit1.Text;
end;
I created a TTabControl with two TTabItems. On each TTabItem there is one (or more) TImageViewers and several TEdits. When I click on the TImageViewer, a modal screen pops up, I set some values, and I want to report those values to the user through the TEdits. So on returning from the Modal screen,
I execute
editn.text := whateveritis;
I then say
editn.repaint;
Nothing happens. I say TTabItem.repaint. Nothing happens. I click the other TTabIem and then come back to the first TabItem and, voila, the Edit control contains the right information. So my editn.text := whateveritis must be working (that's the only write to the TEdit), but I can't get the blinkin' control to show the result without going off-tab. How do I get it to redisplay as soon as I change the content? Do I need to write an OnChange routine that is one line, self.repaint? Seems ugly, and I'd hope there's a more global approach. Suggestions?
In light of initial comments, let me give more details. Setup: In main screen, drop in tabcontrol, and in tabcontrol drop in 2 tabitems. In tabitem1, drop in a timageviewer and 4 tedits (plus other stuff, probably irrelevant). Image gets dropped into the imageviewer (and displays correctly). The onclick event activates the following (ellipsis cuts out irrelevant code):
procedure TSCKMain.ImageViewer1Click(Sender: TObject);
var
lochold, scrollhold : tpoint;
backfromwavform : tmodalresult;
begin
lochold.X := mouseloccallback.x;
lochold.Y := mouseloccallback.y;
scrollhold.X := round(imageviewer1.ViewportPosition.X);
scrollhold.Y := round(imageviewer1.ViewportPosition.Y);
…
repeat backfromwavform := Wavform.Showmodal until backfromwavform<>mrnone;
case backfromwavform of
mrOK : begin {blue end}
Specsingle.BlueEnd.X := lochold.X;
Specsingle.BlueEnd.y := lochold.y;
edit13.Text := inttostr(Specsingle.BlueEnd.X);
Edit14.Text := inttostr(Specsingle.BlueEnd.y);
PublicWindowFlag := 'RePlot';
end;
mrContinue : begin {red end}
Specsingle.RedEnd.X := lochold.X;
Specsingle.RedEnd.y := lochold.y;
edit15.Text := inttostr(Specsingle.RedEnd.X);
Edit16.Text := inttostr(Specsingle.RedEnd.y);
PublicWindowFlag := 'RePlot';
end;
…
end;
if PublicWindowFlag<>'Cancel' then
if PublicWindowFlag='RePlot' then
begin
specsingle.RegenImage;
end
else
showmessage('Single image semaphore error. Debug.');
Imageviewer1.scrollto(scrollhold.X-Imageviewer1.viewportposition.X, scrollhold.y-Imageviewer1.ViewportPosition.Y);
end;
The modal screen sends back either mrContinue or mrOK correctly, and the appropriate case executes. However, edit13, edit14, edit15, and edit16 do not change their content. However, if I click over to Tabitem2 and back to Tabitem1, they DO repaint and DO contain the correct characters, which they could only have gotten from the above code. Conclusion: somehow, the edits aren’t repainting independently, but it’s not clear why.
Got it. The canvas for the imageviewer, the canvas for the bitmap in the imageviewer, and the canvas for the parent form are all in play. One must be sure that the canvas is the right one. As soon as scenes got untangled between imageviewer.bitmap and everything else, the edits worked as one would expect.
I am trying to put a combobox on a toolbar in Delphi 2010. The App is a MDI text editor. If I place a combobox on the toolbar and run the app, when I click the combobox, it opens up a new child window and doesn't drop down for a selection. I have tried putting the toolbar and combobox in both a controlbar and a coolbar, both with the same results. In fairness, I have not recreated the toolbar, just moved it to the other controls.
Has anyone seen this before and how do I get around it?
I just tried it again with the same results. Here is the code for the combobox1.
procedure TMainForm.ComboBox1Change(Sender: TObject);
begin
exec_sql(combobox1.Text);
end;
There is no on click for the toolbar and no button currently opens a new child.
The exec_sql looks like this:
procedure TMainForm.exec_sql(MachName:string);
var
sql_str: string;
parm_str: string;
begin
mach.Free;
parm_str := MachName;
sql_str := 'Select * from machines where MACHINE_NAME = :parm_str';
with adoquery1 do
begin
close;
sql.Text := sql_str;
with Parameters.ParamByName('parm_str') do
begin
DataType := ftString;
Value := parm_str;
end;
open;
mach := TMachineData.get_record_data(ADOQuery1);
end;
ShowMessage('Current Machine Is ' + mach.MACHINE_NAME);
end;
I am unable to reproduce your problem. Here are the steps I took to try and do so:
File->New->Other->Delphi Projects->MDI Application
Created a new folder when prompted for the project
Delphi shows a new MDI parent, with a toolbar, some toolbuttons, menu, etc.
Dropped a new TComboBox on the toolbar
Added 'Item 1', 'Item 2', and 'Item 3' to the combobox via the Object Inspector
Ran the application, and clicked the dropdown button on the combobox.
Picked any item from the combobox; it behaved as expected.
Picked a different item from the combobox. It behaved as expected.
Therefore, the problem is not with placing a TComboBox on a TToolBar, and has to be elsewhere in your code, in a location not included in your question.
You'll need to use the debugger, set some breakpoints in various locations, and take a look at the call stack window to see how you got where you're at in the code. You can then set a new breakpoint in one of those earlier calls, repeat the process, and keep doing so until you trace back to the point that's causing your problem.
I just tested debugging in this fashion. I created a FormCreate event in the default CHILDWIN unit, added Dialogs to the implementation uses clause, and added a call to MessageDlg('New child created', mtInformation, [mbOK], 0); in that FormCreate event. I set a breakpoint there, and ran the app, and then clicked on the New toolbar button. When the breakpoint was triggered, the call stack window looked like this (I've highlighted the place that caused the new child window to be created - the line below it is relevant as well):
The problem was the combobox was firing the Form1.OnActivate event which created a new mdi child. OnActivate was set to ActionFirstChildExecute. I was creating a new blank child when the app opened. This had the described undesired effect. I removed the OnActivate and moved the ActionFirstChildExecute to OnShow. The app and combobox then worked as expected. There was nothing in the ActionFirstChildExecute to cause the behavior as shown in the code below. The problem was clicking the combobox fired the Form1.OnActivate event calling the code below.
procedure TMainForm.ActionFirstChildExecute(Sender: TObject);
var
ChildForm: TMDIChild;
begin
Inc (Counter);
ChildForm := TMDIChild.Create (Self);
ChildForm.Caption := ('NONAME' + IntToStr(MDIChildCount));
ChildForm.Show;
(ActiveMDIChild as TMDIChild).FormCreate(Application);
if ParamStr(1) <>'' then open_mru_item(ParamStr(1));
end;
I have a really simple problem, but I don't find a nice way how I should solve this:
I have a TEdit field. When I enter this Edit-Field, I want to show an Panel.
When I click on the panel, the panel should hide.
When I leave the edit field, the panel also should hide, but I can't use the onExit event of the editField, because this would hide the panel before I can click it.
I'm experimenting for a while to solve this, but can't find an elegant way...
Any Ideas? thanks!
Well, that is a tricky one. Have you considered hiding the panel with the onEnter event for every control except the panel and the edit field?
In other words, the panel will not hide itself when you exit the edit field and enter the panel but it will hide itself once it has performed its work.
Exiting the edit field and entering any field other than the panel will also cause the panel to hide.
None of that is driven by the edit field onExit, more by the other fields as you enter them. It's convoluted but it may just work. See the table below for conditions and their associated actions:
onExit onEnter panelAction
------- ------- -----------
panel nothing nothing hide panel
edit field nothing show panel nothing
all others nothing hide panel nothing
You can use ActiveControl property of the Form at OnClick event of Panel and OnExit event of the EditField
actually you can use the onExit because the panel is not focuseable, so your edit is still focused when you click on the panel (tested with d7).
it's either this or i didn't understand well what you need. if the latest is the case, try rephrasing like gabr suggested earlier ;)
cheers,
G
i test your problem. check it out.
procedure TForm1.Edit1Enter(Sender: TObject);
begin
Panel1.Visible := true;
end;
procedure TForm1.Edit1MouseLeave(Sender: TObject);
begin
Panel1.Hide;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.TabStop := False;
Panel1.Visible := False;
end;
procedure TForm1.Panel1Click(Sender: TObject);
begin
(Sender as TPanel).Visible := false;
end;
I'm still on D2007 and have need to create a unicode enabled virtual keyboard. So I'm using TMS's unicode buttons to simulate the keys, but what I want to avoid is having to assign
mmo.Lines.Text := mmo.Lines.Text + Button1.Caption;
~50 times. There just has to be a better way to send one character at a time to the memo. Is there a way to use the Tag property in the Object Inspector and assign a value from there, or how?
How would you do this?
Assign the same OnClick event handler to all your buttons. Instead of referring to each button by name, as you did above with Button1, use the Sender parameter. That's what it's there for. It tells you which control's event was triggered to cause the handler to run.
Sender has the static type TObject. When one of your buttons is clicked, Sender will have the run-time type TButton, or whatever actual class you're using. To get your code to compile , you'll need to type-cast. For example:
procedure TKeyboardForm.ButtonClick(Sender: TObject);
begin
mmo.Lines.Text := mmo.Lines.Text + (Sender as TButton).Caption;
end;
A speedbutton of some kind may be a better choice for the buttons, since they don't grab focus. Then the blinking cursor would remain in the memo.
You may get the same result by tweeking the properties of the button you use. I don't know the tms-button, but you can try to set tabstop to false.
I'm getting maybe a little old and I live out in the country so I'm probably just behind the times. I don't know if "snarg" means "I'm still not getting it" or maybe "Sorry, I found my error." On the chance that it means the latter, it seems like this suggestion from Rob Kennedy was right on the money:
procedure TKeyboardForm.ButtonClick(Sender: TObject);
begin
mmo.Lines.Text := mmo.Lines.Text + (Sender as TButton).Caption;
end;
If you put a break point right on the line inside the event handler and evaluate TButton(Sender).Caption, doesn't it show you the caption of the button you pressed? I see that you are iterating through all the buttons now. If all you want is the caption, it seems like that code should solve it.
Jack