Domanda

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.

È stato utile?

Soluzione

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top