Detect whitespace clicks in a list

I have a tall list with a variable number of items. It will not always be full. I know when the user is not selecting an item by this code:

if ( lstbox.ItemIndex = -1 ) then
  ShowMessage('here');

      

But it doesn't work when I select an item and then press "space" in the list. How to define such a situation?

+3


source to share


1 answer


You can do this in several ways. One would be in the OnMouseDown event , using the X and Y parameters for that event, which are client coordinates in the list where the user clicked:

procedure TMyForm.ListBox1MouseDown(Sender: TObject;
                                    Button: TMouseButton;
                                    Shift: TShiftState;
                                    X,  Y: Integer);
begin
  if TListbox(Sender).ItemAtPos(Point(X, Y), TRUE) <> -1 then
    // item was clicked
  else
    // 'whitespace' was clicked
end;

      

But this will not affect the behavior on any OnClick event . If you need to execute this test in OnClick , you need to get the mouse position and convert it to client list coordinates before running the same tests:

procedure TMyForm.ListBox1Click(Sender: TObject);
var
  msgMousePos: TSmallPoint;
  mousePos: TPoint;
begin
  // Obtain screen co-ords of mouse at time of originating message
  //
  // Note that GetMessagePos returns a TSmallPoint which we need to convert to a TPoint
  //  in order to make further use of it

  msgMousePos := TSmallPoint(GetMessagePos);  

  mousePos := SmallPointToPoint(msgMousePos);
  mousePos := TListbox(Sender).ScreenToClient(mousePos);

  if TListbox(Sender).ItemAtPos(mousePos, TRUE) <> -1 then
    // item clicked
  else
    // 'whitespace' clicked
end;

      



NOTE. GetMessagePos () gets the mouse position at the time of the last observed mouse message (which in this case should be the message that raised the Click event ). However, if your Click handler is called directly, then the mouse position returned by GetMessagePos () is likely to be negligible or irrelevant for handling in the handler. If any such direct call can reasonably use the current mouse position, then this can be obtained using GetCursorPos () .

GetCursorPos () is also much easier to use as it gets the mouse position in TPoint , avoiding the need to convert from TSmallPoint

GetCursorPos(mousePos);

      

In any case, the fact that your handler depends on the position of the mouse in some way causes a direct call to that event handler, so if that is a consideration, then you can cast any position-independent response in the event handler into a method that can be explicitly called if / if required, regardless of mouse interaction with the control.

+6


source







All Articles