3
votes

Why does a Delphi StringGrid sometimes calls the OnClick event after an OnKeyDown?

Debugging screenshot:

enter image description here

My OnKeyDown event handler:

var
  Top: Integer;
  Bottom: Integer;
  CurrentRow: Integer;
begin
  Top := Grid.TopRow;
  Bottom := Grid.TopRow + Grid.VisibleRowCount - 1;
  if (Key = 38) then CurrentRow := Grid.Row - 1
  else if (Key = 40) then CurrentRow := Grid.Row + 1;
  
  // Disable OnClick because sometimes a 'TStringGrid.Click' is called anyway...
  // (when clicking on form top window bar and navigating)
  Grid.OnClick := nil; 
  
  if (CurrentRow < Top - 1) or (CurrentRow > Bottom + 1) then begin
     if (Key = 38) then Grid.Row := Bottom
     else if (Key = 40) then Grid.Row := Top;
  end;
  Grid.OnClick := GridClick;
end;

Edit:

It seems the 'OnClick' is not being fired when the last line is selected and pushing 'Down' or when the first line is selected and pushing 'Up'.

Way to reproduce:

Add a TStringGrid to a form and populate with a few lines. Add 'OnClick' and 'OnKeyDown' handler. No specific code needs to be added in these two handler methods. Select a row in the stringgrid on the form and press the up or down arrow on your keyboard.

Edit 2:

This isn't the solution, but to prevent the code in 'OnClick' being executed after pressing up, down, pageup or pagedown, I set a variable in 'OnKeyDown' what key was pressed and check for that variable in 'OnClick'.

Edit 3:

Updated stack trace and way to reproduce.

1
Which version of Delphi? There is nothing in TCustomGrid.KeyDown in XE3 that calls TControl.Click. And would it be too much to ask for a way to reproduce this?David Heffernan
Delphi XE3. I added a the way to reproduce this to the description.user729103
Your reproduction is incomplete. Which keys do you need to press? Describe precise steps to reproduce.David Heffernan
Why all the edits? You asked why; I told you why. You don't accept; now what question is left?NGLN
1) Being able to reproduce and verify. 2) Search for a solution (I know, not really part of the question). 3) Accept answer.user729103

1 Answers

5
votes

Well, that hard-coded key codes aren't the case making the least bit transparent, but you witness this effect when you use a direction key (up, down, left, etc...) to change the selection.

Why the OnClick event handler is called, is because TCustomGrid.OnKeyDown calls TCustomGrid.FocusCell, which calls Click.

Exactly why changing focus to another cell would establish a click I do not know, we would have to ask the developers I imagine. Perhaps to simulate the default behaviour when changing focus to another cell by clicking instead of keyboard.

Since you seem to handle direction key presses yourself, maybe you could consider to prevent this from happening at all by ignoring the key any further:

  if Key in [VK_PRIOR..VK_DOWN] then
    Key := 0;