2014-09-22 6 views
3

가변 개수의 항목이있는 큰 목록 상자가 있습니다. 항상 가득 차는 것은 아닙니다. 사용자가이 코드에 의해 항목을 선택하지 않을 때 나는 알고있다 :"공백"을 목록 상자에서 클릭하십시오.

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

을하지만이 항목을 선택하면이 작동하지 않습니다와 나는이 목록 상자의 '공백'을 클릭합니다. 그런 상황을 어떻게 감지 할 수 있습니까?

+0

저는 최근에 XE5에서이 것을 보았습니다. 내가 TListboxes에서 동작이 상대적으로 최근에 변경된 것이라면 궁금합니다. 왜냐하면 항목이 선택되었는지 여부에 관계없이 공백을 클릭하면 .ItemIndex의 값이 -1이된다는 것을 맹세했기 때문입니다. 항목이 이미 선택되어 있으면 클릭을 무시합니다. –

답변

6

여러 가지 방법으로이 작업을 수행 할 수 있습니다.

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; 

그러나이 원 ': 하나는 사용자가 클릭하는 목록 상자의 클라이언트 좌표입니다 해당 이벤트에 XY 매개 변수를 사용하여 하면 onMouseDown 이벤트에있을 것입니다 어떤 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() 얻 당신이 의 OnClick에서이 테스트를 수행해야하는 경우에 당신은 마우스 위치를 획득하고 동일한 테스트를 수행하기 전에 목록 상자의 클라이언트 좌표로 변환 할 필요가 가장 최근에 관찰 된 마우스 메시지 (이 경우에는 을 클릭 한 메시지 여야합니다. 이벤트 발생시 마우스 위치). 그러나 클릭 처리기가 직접 호출 된 경우 GetMessagePos()에 의해 반환 된 마우스 위치는 처리기에서의 처리와 거의 관련이 없습니다. 이러한 직접 호출이 현재의 마우스 위치를 현명하게 이용하는 경우는, GetCursorPos()를 사용해 취득 할 수 있습니다. 에서 TSmallPoint 변환 할 필요 피할 수는 또한 직접 TPoint 값에서 마우스 위치를 취득로 사용하는 것이 훨씬 더 간단합니다()

GetCursorPos :

GetCursorPos(mousePos); 

어느 쪽이든을, 귀하의 핸들러가 어떤 식 으로든 마우스 위치에 의존한다는 사실은이 이벤트 핸들러를 직접 호출 할 수 없으므로 이것이 고려 사항이라면 이벤트 핸들러에서 위치 독립적 응답을 명시 적으로 호출 할 수있는 메소드로 분리 할 수 ​​있습니다. 필요할 때마다 컨트롤과의 마우스 상호 작용을 기다리고 있습니다.

+0

또한 글로벌 마우스의 CursorPos가 있습니다. –

+0

GetCursorPos 대신 GetMessagePos 여야합니다. GetKeyState 및 GetAsyncKeyState와 동일합니다. 하지만 마우스 이벤트가 아닌 다른 이유로 OnClick 발사 가능성을 명심하십시오. –

+0

OnClick 이벤트가 직접 호출되지 않는 한, 메시지 루프에서 관찰 된 마우스 위치가 잠재적으로 엄청나게 정확합니다. 여기서 GetCursorPos()는 약간 떨어져있을 가능성이 매우 큽니다. GetMessagePos()는 메시지에 직접 응답을 구현할 때 적합하지만 VCL 이벤트 핸들러에서는 확실하지 않습니다. – Deltics

관련 문제