Link to home
Start Free TrialLog in
Avatar of selas
selas

asked on

how to simulate key press on button click?

My form have 11 labelededits and 10 buttons from 0..9
i will use touchscreen monitor and i want to simulate keybord clicks
i want to make key 1 press if button1 clicked ... make key 0 press if button 10 pressed
How can i do so?
Avatar of kretzschmar
kretzschmar
Flag of Germany image

you could use the keybd_event-api
or thw wm_keydoen/wm_keyup-messages

it depends, if you want to send the key to a control (then messages)
or not (keybd_event will apply the key to the focused control)

explain a bit more

meikl ;-)
Avatar of Evarest
Evarest

Possible solution

procedure TForm1.Button1Click(Sender: TObject);
begin
 SelectedLabeledEdit.Text :=SelectedLabeledEdit.Text + inttostr(TButton(Sender).Tag);
end;

Just give each edit the appropriate Tag ranging 0..9
And add this to each OnEnter event of each edit:

procedure TForm1.Edit1Enter(Sender: TObject);
begin
 SelectedLabeledEdit :=TEdit(Sender);
end;

with SelectedLabeledEdit:

private
property SelectedLabeledEdit: TEdit read fSelectedLabeledEdit write fSelectedLabeledEdit;

I've included the unit for 1 button and 1 edit:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Edit1Enter(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    fSelectedLabeledEdit: TEdit;
  public
    { Public declarations }
    property SelectedLabeledEdit: TEdit read fSelectedLabeledEdit write fSelectedLabeledEdit;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 fSelectedLabeledEdit :=nil;
end;

procedure TForm1.Edit1Enter(Sender: TObject);
begin
 SelectedLabeledEdit :=TEdit(Sender);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 if SelectedLabeledEdit = nil then exit;
 SelectedLabeledEdit.Text :=SelectedLabeledEdit.Text + inttostr(TButton(Sender).Tag);
end;

end.

Set the SelectedLabeledEdit to nil when the form is created...

Kind regards,
Evarest
ASKER CERTIFIED SOLUTION
Avatar of Evarest
Evarest

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of selas

ASKER

if i use Keybd_event(VK_NUMPAD1, 0, 0, 0 );
nothing heppens...
That's why I simply use the code above. It's only 6 lines of code (the DPR you don't need to code, it's all the comps on your form)...

Each comp has a Tag and by using this you can add that tag as a character to the selected edit.

Kind regards,
Evarest
use SendMessage. SendMessage has format:

SendMessage(Button1.Handle, WM_KEYDOWN, VK_RETURN, 0);

this simulate Enter key pressed on Button1.
well, you must also release the key like

      keybd_event(VK_NUMPAD1, 0, 0, 0);  //press key
      keybd_event(VK_NUMPAD1, 0,KEYEVENTF_KEYUP,0); //release key

or also

      keybd_event(ord('1'), 0, 0, 0);
      keybd_event(ord('1'), 0,KEYEVENTF_KEYUP,0);

but as i said this event is sent to the focused control,
and as you click on a button, the button will be the focused control

explain a bit more about, where shall the key displayed

maybe, i'm on a wrong track and evarest knows what you want to archive      

meikl ;-)
Avatar of selas

ASKER

yes on button1 click nothing typed in selected labelededit and button focused...
how to solve this?
Personally I'm at a loss :-) As selas posted in his question, his question was to be able to use a touchscreen to input values in an edit. He used 10 buttons which each have a number ranging from 0-9. If a button is touched the value is inserted in the selected Edit.

This all can be achived with the code above. However, as selas doesn't seem to use or try out that code, I'm not sure whether it's of any use or not... Please let me know what you really want, so i might be able to be of some help :-)

Kind regards,
Evarest
>yes on button1 click nothing typed in selected labelededit
in this case use the wm_keydown/wm_keyup-messages
-> see ivanov's sample and use the labelededit-handle instead

or, if it is in the same app, you can go with evarest's suggestion

meikl ;-)
Doesn't a touchscreen come with a driver that translates touches to mouseclicks?
meikl one  is the best one method...

just set your buttons tag from 48 (for 0) to 57 (for 9) then in the buttonclick (the same for all buttons) this:

procedure TForm1.Button1Click(Sender: TObject);
begin
keybd_event(TButton(Sender).tag, 0, 0, 0);
keybd_event(TButton(Sender).tag, 0,KEYEVENTF_KEYUP,0);

end;
or better agai using sendmessage to send directly to the selected edit

procedure TForm1.Button2Click(Sender: TObject);
begin
SendMessage(edit1.handle, WM_KEYDOWN, TButton(Sender).tag, 0);
SendMessage(edit1.handle, WM_CHAR, TButton(Sender).tag, 0);
SendMessage(edit1.handle, WM_KEYUP, TButton(Sender).tag, 0);
end;
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
just to append to the suggestion above, by using the keybd_event
(just stealing f68's code above)

procedure TForm1.Button1Click(Sender: TObject);
var control : Tcomponent
begin
  control := findcomponent('Edit'+inttostr(TButton(Sender).tag-47));
  if (assigned(control)) and (control is TEdit) then
  begin
    TEdit(control).SetFocus;  //shift the focus to the control, which should receive the key
    Application.ProcessMessages; //maybe not needed
    keybd_event(TButton(Sender).tag, 0, 0, 0);
    keybd_event(TButton(Sender).tag, 0,KEYEVENTF_KEYUP,0);
  end;
end;

just from head

meikl ;-)
download my example from:
page:        http://www.geocities.com/esoftbg/
  link:        Q_21122981.zip
Hello, I asked: Doesn't a touchscreen come with a driver that translates touches to mouseclicks?

Well, does it?
And why do I ask? I just wonder why you would translate mouse messages into key messages so you could then handle the key events. Why not just handle the mouse events?

And one tip. On the MouseDown event you can send the OnKeyDown event and on the MouseUp event you just send the OnKeyUp event. Thus you can even handle repeating keypresses if you really want to simulate them. But I do think it's a bit silly...
Workshop_Alex: "Thus you can even handle repeating keypresses if you really want to simulate them"

that's why i can't understand the problem any more...
Well, in my opinion....
-->Doesn't a touchscreen come with a driver that translates touches to mouseclicks?
Yes it does. I guess that here he's creating a sort of cash register using a numerical keypad on touchscreen.
So a touch on the screen is treated like a mouse click and it's ok. What he wants is a keybord event to write the values on some edit fields as if he's typing directly on keyboard numerical keypad....That's my guess of course, and i could be completely wrong, but if it's so the way could be that one suggested here by most of us using kb_event or sendmessage...
Also consider that the use of a touchscreen is intended for skip keyboards and mouses, so the link to an event of these become obsolete....

That's just my opinion of course :)

F68 ;-)
What I think he wants is some onscreen keyboard that sends keypresses to whatever control that has focus on that moment. Thus, there's an edit-control and key messages must be sent to it. His onscreen keyboard should make this possible.
The problem, I think, is that whenever a button is clicked, the focus changes to this button. Thus any keypress event <i>will be send to this button!</i> (I know html doesn't work but it's for emphatism) This is why nothing happens on the Keybd_event() method. The keys are sent to the button and from there they're just ignored.

What he actually needs, I think, is a way to put the focus back to the original control and send the keyboard events to that control! (And this control could be an external application even.) I could be wrong, though. But I think selas wants the keypresses to be sent to the control that had the focus right before the button got focus...
From the initial question "My form have 11 labelededits and 10 buttons from 0..9".

This line indicates that both the edits as the buttons are located _on the same_ form. Thus, no need for "complicated" KeyPress Events,  or messages from any kind, as you simply can write code like you normally do. When the user clicks a button, here touches one, the code behind it will execute and do whatever you want it to do. I really don't see the use for such keybd_event(TButton(Sender).tag, 0, 0, 0);...

Just use
procedure TForm1.Button1Click(Sender: TObject);
begin
 SelectedLabeledEdit.Text :=SelectedLabeledEdit.Text + inttostr(TButton(Sender).Tag);
end;
And all will work just fine, no need to worry about focussed or not, as that focussing is done in the onEnter of each Edit.

Evarest
--> as that focussing is done in the onEnter of each Edit.
SO you mean that before you need to find wich is the selected...
Something like
var SelectedLabeledEdit: TLabeledEdit;

procedure TForm1.LabeledEdit1Enter(Sender: TObject);
begin
   SelectedLabeledEdit := TLabeledEdit(Sender);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
 If assigned(SelectedLabeledEdit) then
 SelectedLabeledEdit.Text :=SelectedLabeledEdit.Text + inttostr(TButton(Sender).Tag);
end;

Yes Evarest, if this is the scenario your idea could be easly applied...

F68 ;-)
About my last comment: this thread is becoming a bit long, as i've just posted an already full coded example by Evarest (forgotten and misreaded it). Sorry Evarest, i'll keep more attention re-reading threads before to post comments in the future :)

F68 ;-)
Notting to worry about, let's maybe now wait for selas to better specify what he needs (if there still is any need for it...)

Evarest
> My form have 11 labelededits and 10 buttons from 0..9
> ....
> i want to make key 1 press if button1 clicked ... make key 0 press if button 10 pressed

I think the problem is:
  - when a TButton is pressed the focused TLabeledEdit loses the focus: this is the reason that the simulated key press on button click does not apper into the just-losed focus TLabeledEdit;
 - So my solution is based on using TSpeedButtons instead of TButtons. As is known TSpeedButton never gets the focus, so LabeledEdit1 gets the simulated key-presses until it is focused .... After the user clicks on another LabeledEditX and then clicks a lots of times on SpeedButtons this way LabeledEditX gets the simulated key-presses until it is focused.

Download my solution from:
page:        http://www.geocities.com/esoftbg/
  link:        Q_21122981.zip
and you will see it works perfect !
Indeed, the buttons will loose focus. But in my example above I used TButtons and that still worked, as i remember the last focused TEdit.
Of course, that's inheritely the same as your example...

Evarest
Evarest,
Your example is not a universal one, because you make obligatory next digit to be added after all already existing digits into the TLabeledEdit. This is unnatural behaviour of the TLabeledEdit;
But it is possible in my example to click somewhere between existing characters into the TLabeledEdit ant on the next clicks on TSpeedButtons the new simulated key-presses will be inserted where is the cursor placed: this is the natural behaviour !
Something more, I can select some symbols into a TLabeledEdit and when I press a SpeedButton, it will replace selected symbols with a digit: the natural behaviour again ....
esoftbg, I'm sorry, but personally I don't know about the TLabeledEdit. I don't use it in any of my projects...

If indeed this can be done with your code, then i gladly accept that. However, you can modify my code too, to accomplish what you're saying...

Kind regards,
Evarest
Btw, it's a touchscreen, and i don't think the person's fingers will be able to accurately set the mouse cursor on a selpos :-) Better just to do a TEdit.SelectAll and replace the entire text...
Hi Evarest,

TLabeledEdit appears at the Additional tab of the Delphi 7 components palette .... (TLabeledEdit or TEdit) It does not matter about the context of this question ....

I have not been say anything about your solution before your try to explain that:

> Of course, that's inheritely the same as your example...

I just wanted to say that it is not true ;-)) Just my solution (simple and elegant) is different ....

I don't like to change your code, you may do that better ;-))

Best Regards,
Emil