컨텍스트 메뉴의 자동 팝업은 마우스 오른쪽 버튼 클릭에 대한 응답입니다. 같은 클릭으로 OnMouseUp
이벤트도 발생합니다. VCL 개발자는 팝업이 표시되기 전에 또는 이후에 'OnMouseUp'이벤트를 시작하도록 선택할 수 있습니다. 외관상으로는 후자가 효과적입니다. 즉, 팝업이 닫힐 때 (마우스 또는 키보드로 'Esc'를 누를 때와 같이) 이벤트가 시작됩니다.
왼쪽 버튼을 눌러 팝업을 닫으면 왼쪽 버튼을 놓아서 'OnMouseUp'이벤트를 다시 시작합니다.
몇 가지 대안이 있습니다. 하나는 새로운 클래스를 파생시키고 자신의 이벤트를 발생시키는 MouseDown
메서드를 재정의하는 것입니다. 보기;
type
TMyStringGrid = class(TStringGrid)
private
FOnRButtonUp: TMouseEvent;
protected
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
published
property OnRButtonUp: TMouseEvent read FOnRButtonUp write FOnRButtonUp;
end;
[...]
procedure TStringGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
if (Button = mbRight) and Assigned(FOnRButtonUp) then
FOnRButtonUp(Self, Button, Shift, X, Y);
inherited;
end;
또 다른 대안은 VM_RBUTTONUP
메시지를 처리 할 수 있습니다. 위와 같이 새 클래스를 파생 시키거나 그리드의 WindowProc
을 대체하여이 작업을 수행 할 수 있습니다. 이 question에 WindowProc here을 바꾸는 예가 있습니다.
또 다른 방법으로 마우스 업 이벤트 만 남겨두고 팝업 메뉴의 OnPopup
이벤트에서 처리 할 수도 있습니다. 이 이벤트는 팝업이 표시되기 전에 시작됩니다. Mouse.CursorPos
으로 마우스 좌표를 가져올 수 있습니다.
또 다른 대안은 False
에 팝업 메뉴의 AutoPopup
속성을 설정할 수 있으며, (더 나은 아직 OnContextMenu
이벤트 나)에 OnMouseUp
이벤트에 우선 몇 가지 처리를 수행 한 후 팝업을 보여줍니다. 보기;
procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Pt: TPoint;
begin
// Do processing
if Button = mbRight then begin
Pt := (Sender as TStringGrid).ClientToScreen(Point(X, Y));
PopupMenu1.Popup(Pt.X, Pt.Y);
end;
end;
"분명히 후자가 효과가 있습니다." 이것은 OnMouseUp 이벤트가 마우스 업 이벤트가 아니기 때문에 직관적 인 카운터입니다. 실제로, 그것은 "마우스 다운"이벤트입니다 !!! 당신의 완전한 답을 +1하십시오. – Ampere
@Altar> "... counter intuitive ..."- 나는 팝업 메뉴가 실제로 WM_RBUTTONUP뿐만 아니라 WM_NCRBUTTONUP과 함께 생성 된 'WM_CONTEXTMENU'에 대한 응답이라는 점을 고려하면 ' Shift + F10 '과 VK_APPS가 있으며, 예를 들어 VK_APPS를 사용하면 팝업이 표시되기 전에 OnKeyUp이 시작됩니다. –