Mam sytuacji gdzie mam TImage
i na górze nim TPanel
pokrywając je częściowo i dzielą ten sam nadrzędny:Jak przekierować zdarzenia myszy do innej kontrolki?
------------------
| Image1 |
| ------------ |
| | Panel1 | |
| ------------ |
| |
------------------
Panel1 odbiera myszy dół/MOVE/up wydarzenia i przetwarzanie go (tak robi Image1), ale w pewnej sytuacji chciałbym "przekierować" wiadomość w dół do Image1, jakby chciał zasymulować kliknięcie Image1 zamiast Panel1.
Oto co zrobiłem:
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (ssLeft in Shift) then
Beep;
end;
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
//...
end;
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('boo!');
end;
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
P: TPoint;
begin
if FRedirectToImage then begin
ReleaseCapture; // do I need to send a WM_LBUTTONUP as well to the panel?
GetCursorPos(P);
P := ScreenToClient(P);
Image1.Perform(WM_LBUTTONDOWN, MK_LBUTTON, Longint(PointToSmallPoint(P)));
Exit;
end;
// Normal handling
if (ssLeft in Shift) then begin
// ...
end;
end;
To działa zgodnie z oczekiwaniami, ale nie jestem pewien, że to właściwa droga.
Moje pytanie brzmi: czy robię to dobrze? czy istnieje lepszy lub zalecany sposób robienia tego?
Update (1): Handling WM_NCHITTEST
jako sugerowane jest ważny odpowiedź i myślałem o tym również. nawet ustawienie Panel1.Enabled
na False
przekieruje komunikaty myszy do kontrolki Image1.
jednak rozważyć tę sytuację, gdy kliknę lokalizację x
na panelu i nadal trzeba przekierować wiadomość do Image1 (!):
------------------
| Image1 |
| --------------
| | Panel1 x |
| --------------
| |
------------------
Moja metoda działa, ale WM_NCHITTEST
nie znajduje zastosowania w opisanym scenariuszu . Nadal nie otrzymałem odpowiedzi, jeśli moja metoda jest ważna, czy nie. (A może powinienem zadać kolejne pytanie z powyższym scenariuszu?)
Powiedziałbym, że najlepiej jest zrobić to na poziomie pętli wiadomości. Wdrożyć procedurę obsługi 'OnMessage' dla' TApplication'. Lub może zrobić to samo z obiektem 'TApplicationEvents'. Tam możesz zmienić uchwyt okna docelowego dla wiadomości, które Cię interesują. –
@David, nie jest widoczny w pierwszym widoku z tego pytania, ale OP naprawdę chce przekierować wiadomości. Tak, to jest droga. – TLama
@ TLama Nie mam pragnienia, aby napisać odpowiedź tutaj. Proszę, nie czuj się zahamowany, robiąc to samemu! –