Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Monitor Key Press 1

Status
Not open for further replies.

dik

Technical User
Jul 18, 2001
217
0
16
MD
More a general question:

I have a form with an TEdit attached. I want to determine the Text value of the TEdit when an <Enter> key is pressed. The value returned will either be an integer or 'T' or 'F'. I don't have the code for this... it's in a prelim stage. I want to access the information from a procedure or function that may or may not reside in the form unit.

The generated procedure is of the form:
procedure TMain_ScreenF.AnswerEKeyPress(Sender: TObject; var Key: Char);

and I'll be testing it for (27 = ord(key)) and if (13 = ord(key)) as well as T/F; the number is generally an integer.

Is there a better way to do this? I'd like to have the coding in a separate procedure or function that could access the keys pressed.

Any suggestions?

Dik
 
 http://files.engineering.com/getfile.aspx?folder=96673707-e938-412d-8eca-b6754dfaa208&file=Test03.zip
You mention that you want to determine the value of an Edit field when <Enter> is pressed. Did you mean when <Enter> is pressed while that Edit control has focus, or did you mean when the user presses <Enter> no matter which component has focus? Depending on the answer, you would have to impement different solutions.
 
I'm lookikng at recording the value in the TEdit.Text when the <Enter> key is pressed. The TEdit has the focus.

Also found the GetKeyState funcion using it with VK_Return and am trying that approach.

Dik
 
I'm trying to do something like:

Code:
function GetAnswer(): string;
{  Function monitors Main_ScreenF for keystorkes.  When a <Enter> key or an
   <Esc> key is pressed, the function checks the input to see if it is a
   valid entry and returns the value input in the AnswerT.Text.

   Parameters:

   Returns:   String variable from AnswerE.Text
}
var
  TmpStr: string;

begin
  Main_ScreenF.AnswerE.SetFocus;

  while NOT EnterKeyPressed do
  begin
    Result := Main_ScreenF.AnswerE.Text
  end;
end; // procedure


function EnterKeyPressed: Boolean;
begin
  Result := GetKeyState(VK_Return) < 0;
end;

The above does not seem to recognise the <Enter> key

Dik
 
Best approach to limit and check the contents of an Edit control would be with OnKeyPress or OnKeyDown and or OnKeyUp and possibly even OnChange, but that doesn't need the ENTER key to be pressed, these are triggered for every key pressed (and in the case of OnKeyUp when the key is released). If you want to only check the content when the ENTER key is pressed, then you'd need to use OnFormKeyDown, but to get that to work, you also need to set the Form's KeyPreview property to TRUE.
 
That was the approach I'd used in my original posting, but I need to access the information from another procedure without using a global variable to store it temporarily. I was thinking that there had to be a more simple manner of doing that.

Dik

Code:
procedure TMainF.AnswerEKeyPress(Sender: TObject; var Key: Char);
var
  ButtonSelected: integer;
  TxtValue, TxtTest: integer;                               // submitted answer
  IntAns: integer;                                 // submitted answer: integer
//  StrAns: string;                                   // submitted answer: string
  TmpStr: string;
//  Right, Wrong: integer;                       // correct and incorrect answers

begin
  if (27 = ord(key)) then                               // <Escape> key pressed
  begin
    buttonSelected := MessageDlg('Are you sure you want to exit?', mtConfirmation, [mbYes, mbNo], 0);

    if buttonSelected = mrYes then
    begin
      application.Terminate;                          // PROVIDE PROPER CLOSURE
    end;
  end // if <Esc> key pressed
  else if (13 = ord(key)) then                           // <Enter> key pressed
  begin
    val(answerE.Text, TxtValue, TxtTest);                  // test for a number

    if TxtTest = 0 then                                   // answer is a number
    begin
      ShowMessage('Answer is:  ' + answerE.Text);
      IntAns := StrToInt(answerE.Text);
      application.Terminate
    end
    else                                              // answer is not a number
    begin
      TmpStr := AnsiUpperCase(Trim(AnswerE.Text));

      if (TmpStr = 'F') or (TmpStr = 'T') then        // True or False Selected
      begin
        ShowMessage('Answer is ' + TmpStr);
      end
      else
      begin
        answerE.Text := '';
        ShowMessage('Answer is NOT a Number and zeroed');
      end;
    end;
  end; // if <Enter> key pressed
end; // procedure

Is it possible to write a function that accesses the information from the Edit.Text control from a procedure or function, monitoring the keys from the keypress action? I need the Edit box to only accept 0-9 and f, F, t, and T.

Dik
 
Is it possible to write a function that accesses the information from the Edit.Text control from a procedure or function, monitoring the keys from the keypress action? I need the Edit box to only accept 0-9 and f, F, t, and T

Yes, all this is possible, I'll try to put together something for you later, but first, which version of Delphi are you using?
 
10.1... used to have a registered copy of Delphi 5. The 10.1 was a promotional 'freeby', I had it for about 6 months before I decided to try it out. I am trying to port a program I wrote in BASIC 7.2 about 30 years ago to Windows... and have been away from programming for a long time. Just got the hang of how to set up functions, procedures and variables. I'm trying another tack to see if I can get the keys to register correctly... key down is much better than key up or key press... more features.

Dik
 
Since there are two forms (at least that what I've understood) here is the code to two different forms.

Form1 talks to Form2 via a windows message, and form2 calls a PUBLIC function defined in Form1 to get the contents of the Edit Control
Code:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, [b]Unit2[/b];
  [b]//make sure you add reference to FORM2 form HERE for main form.[/b]

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    function GetEdit1Content: String;[b]//add this line manually then hold Shift-Control-C and[/b] 
	                                 [b]//Delphi will add the function stub for you to fill in[/b]
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
   Form2.Show;
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if not (CharInSet(Key, ['t','T','f','F','0'..'9', #13, #9, #8])) then
    Key := #0; [b]//clear the key to null if it isn't one of your acceptable values (added backspace #8, tab #9 and Enter #13 as acceptable)[/b]
  if Key = #13 then [b]//sends the message only if Enter is clicked while Edit1 has focus.[/b]
    SendMessage(Form2.Handle, WM_ENTERKEY_HIT, 0, 0);
end;

function TForm1.GetEdit1Content: String;
begin
   Result := Edit1.Text;[b]//this is public function callable from your other forms[/b]
end;

end.

Code:
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

[b]const
  WM_ENTERKEY_HIT = WM_USER + 1;[/b]
[b]//add the message constant[/b]
type
  TForm2 = class(TForm)
    Memo1: TMemo;
  private
    { Private declarations }
  public
    [b]procedure WMENTERKEYHIT(var Msg: TMessage); message WM_ENTERKEY_HIT;//add this click Shift-Control-C, Delphi creates stub proc[/b]
  end;

var
  Form2: TForm2;

implementation

[b]Uses Unit1;//make sure you add reference to FORM1's unit AFTER implementation section (you need to also add 'Uses' not just the unit name[/b]

{$R *.dfm}

{ TForm2 }

procedure TForm2.WMENTERKEYHIT(var Msg: TMessage);
begin
  Memo1.Text := Form1.GetEdit1Content;
end;

end.
 
Thanks so much... I'll take a look at them tonight. Looking at starting the program from formshow with the initial problem and then doing everything from the edit.keydown... maybe another solution.

Dik
 
i used to do similar things a while ago

the content ( string ) of an Edit field was checked by specific routines, so to verify if the content verifies a mask

this could occur :
... on EditExit
... on general request, like when verifing each input field of a record, before adding the entity to the record
... on Enter

so build masks : i have some that detects if a content ( string ) is number, real number, number in range, alpanumeric chars, etc

after that, call those routines as you like

kindly !

 
Thanks... majlumbo has also been incredibly helpful... with a little tinkering the source he provided is very helpful.

Yup... just a matter of becoming more familiar with the program again... Something like:

if (Key in [8, 13, 27, 48..57, 96..105, 70, 84]) then
begin

thanks again, Dik
 
Majlumbo:

I'm having a bit of a problem; it's intermittent. Sometimes it transfers the text to form2 and sometimes not. Can you take a peek at this. The exe file has been removed... my computer is pretty secure.

Dik
 
 http://files.engineering.com/getfile.aspx?folder=feab8eb6-4a52-4aff-a59c-2ff0be152305&file=Win_Message.zip
more than likely you didn't catch my comment when I provided this code,
sends the message only if Enter is clicked while Edit1 has focus.

if you want it to send the message ANY TIME the enter key is pressed, then you don't want to use Edit1's OnKeypress, you would use the FORM's OnKeyPress but then you would need to set the FORM's KeyPreview to True.

Code:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if NOT (CharInSet(Key, ['t', 'T', 'f', 'F', '0'..'9', #8, #9, #13])) then
  begin
    Key := #0;
  end;
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then
  begin
    SendMessage(Form2.Handle, WM_ENTERKEY_HIT, 0, 0);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  KeyPreview := True;
end;

Now anytime the ENTER key is clicked, it'll send the message.
 
Thanks... that would explain the intermittent actions... If the form has focus, then, do all objects on the form notify the form that an activity has occurred or is the form notified that an activity has occurred only if it has happened over the form alone?

Dik
 
The event is now associated with the entire form, so if the enter key is clicked while that form has focus, it will kick off the event handler. If you want it to happen no matter which form has focus, that is a bit trickier.
 
Thanks... you've been an immense help.

Dik
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top