You can do this in a number of ways. One would be in the OnMouseDown event using the X and Y parameters to that event, which are the client co-ordinates in the listbox at which 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 won't affect the behaviour in any OnClick event. If you need to perform this test in OnClick then you need to obtain the mouse position and convert it to the listbox client co-ordinates before doing the same test:
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() obtains the mouse position at the time of the most recently observed mouse message (which should in this case be the message that originated the Click event). However, if your Click handler is invoked directly then the mouse position returned by GetMessagePos() is likely to have little or no relevance to the processing in the handler. If any such direct invocation might sensibly utilise the current mouse position, then this may be obtained using GetCursorPos().
GetCursorPos() is also much more straightforward to use as it obtains the mouse position in a TPoint value directly, avoiding the need to convert from TSmallPoint:
GetCursorPos(mousePos);
Either way, the fact that your handler is dependent upon mouse position in any way makes directly invoking this event handler problematic so if this is a consideration then you might wish to isolate any position independent response in the event handler into a method that can be explicitly invoked if/when required, independently of the mouse interaction with the control.