Problem when using return key to move to TDBGrid from TEdit

Viewed 108

In a search form I have two components, a TEdit and and TDBGrid. The user enters text into the TEditand in the TEdit.OnChange event I search for matching items in a table using a query. These are displayed in a TDGrid. The event only triggers when the user has entered more than three characters in the TEdit.Textto cut down the overhead.

The problem occurs when the search has returned all possible records and the user wants to select one of the records displayed in the TDBGrid. While I told the users to use the Tab key (or the mouse) to switch from the TEdit to the TDBGrid, they use the return key to do this in another application and are insisting that they should be able to do the same thing in the application I'm altering/adding to. I can understand this, but the problem is that if I use

if (key = VK_RETURN) then key := VK_TAB;

in the TEdit.OnKeyUp event, the original value of the last key pressed in the TEdit is "remembered" as VK_RETURN and is passed to the TDBGrid's OnKeyUp event. Since I have other actions triggered in that event, I get undesired things happening as soon the the TDBGrid gains focus because they also want to select the correct row in the grid by pressing the return key again.

Therefore what I want to do is to "cancel" the key value passed to the TDBGrid from the TEdit. I tried using if (Sender = TEdit) then Key := VK_CANCEL; in the DGBrid's OnKeyUp event but I get a compiler "Incompatible types" error and I can't find anything to tell me how I should use it in this situation.

Is this possible? Or am I going about this the wrong way?

Thanks in advance!

2 Answers

I believe the following approach satisfies your needs and I suspect it to be the shortest such approach:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then
    Key := #0;
end;

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if Key = VK_RETURN then
  begin
    PostMessage(Handle, WM_NEXTDLGCTL, 0, 0);
    Key := 0;
  end;
end;

This will make Enter, in Edit1, move focus to the next control. This is accomplished by posting the form a WM_NEXTDLGCTL message. The OnKeyPress handler is needed to suppress the "invalid input" message beep.

For bonus points, do

PostMessage(Handle, WM_NEXTDLGCTL, Ord(ssShift in Shift), 0);

instead to have Shift+Enter correspond to Shift+Tab.

I'm not quite sure I like this entire idea, though. I think I prefer to have Enter act on key down instead. The target control shoudn't care about this key up message.

Just to add to Andreas answer, I have used the same approach. There are 3 events you can play around with, onkeydown, onkeypress, onkeyup. At some point you will probably have to assign the key to null to avoid the "beep". The other thing to watch out for are unintended side effects, like moving 2 fields instead of one as has happened to me in the past.

Related