我有一个高大的列表框,其中包含可变数量的项目.它并不总是满满的.我知道当用户没有通过此代码选择项目时: if ( lstbox.ItemIndex = -1 ) then ShowMessage('here'); 但是当我选择一个Item然后单击
if ( lstbox.ItemIndex = -1 ) then ShowMessage('here');
但是当我选择一个Item然后单击列表框的’whitespace’时,这不起作用.我该如何发现这种情况?
您可以通过多种方式执行此操作.一个是在OnMouseDown事件中使用该事件的X和Y参数,它们是用户单击的列表框中的客户端坐标: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;
但这不会影响任何OnClick事件中的行为.如果您需要在OnClick中执行此测试,则需要获取鼠标位置并在执行相同测试之前将其转换为列表框客户端坐标:
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;
注意:GetMessagePos()获取最近观察到的鼠标消息时的鼠标位置(在这种情况下应该是发起Click事件的消息).但是,如果直接调用Click处理程序,则GetMessagePos()返回的鼠标位置可能与处理程序中的处理几乎没有关系.如果任何这样的直接调用可能合理地利用当前鼠标位置,那么这可以使用GetCursorPos()获得.
GetCursorPos()也可以直接使用,因为它直接获取TPoint值中的鼠标位置,避免了从TSmallPoint转换的需要:
GetCursorPos(mousePos);
无论哪种方式,您的处理程序以任何方式依赖于鼠标位置的事实使得直接调用此事件处理程序有问题,因此如果这是一个考虑因素,那么您可能希望将事件处理程序中的任何位置无关响应隔离到可以明确的方法中如果/在需要时调用,与鼠标与控件的交互无关.