Komunikat WM_MOUSEMOVE - Co robię źle?

Odpowiedz Nowy wątek
2013-11-01 09:15

Rejestracja: 7 lat temu

Ostatnio: 1 dzień temu

0

Poniżej prezentuję fragment kodu który ma za zadanie pokazywać gdzie jest obecnie kursor (Oczywiście w obszarze naszej aplikacji). Wszystko było by ok gdyby nie fakt że jak na formie postawię np. Panel to w momencie przejeżdżania kursorem przez ten komponent zdarzenie MouseProc się nie wykonuje. Pytanie dlaczego czy użyłem złego komunikatu?

type
  TForm1 = class(TForm)
    label1 : TLabel;
    panel1 : TPanels;
  private
    procedure MouseProc(var Msg: TMessage); message WM_MOUSEMOVE;
  public
  end;

var
  Form1: Tform1;

procedure Tform1.MouseProc(var Msg: TMessage); 
begin
  label1.caption := inttostr(Msg.LParamLo)+'  '+inttostr(Msg.LParamHi);
end;

Pozostało 580 znaków

2013-11-01 10:18

Rejestracja: 14 lat temu

Ostatnio: 54 sekundy temu

Lokalizacja: Gorlice

Panel tak samo jak Form dziedziczy po TWinControl więc posiada uchwyt czyli jest oknem (choć potomnym) i komunikaty dotyczące jego są kierowane do niego (przecież myszka jest nad panelem) a nie do okna Form.
Chcąc to poprawić trzeba by pobierać współrzędne kursora w kolejce komunikatów całej aplikacji a nie Form1 czyli:

//...
  private
    procedure AppMsgProc(var Msg: tagMsg; var Handled: Boolean);
//...\
implementation

{$R *.dfm}

procedure TForm1.AppMsgProc(var Msg: tagMsg; var Handled: Boolean);
begin
  if Msg.message = WM_MOUSEMOVE then
    Label1.caption:= IntToStr(LoWord(Msg.lParam)) + '  ' + IntToStr(HiWord(Msg.lParam));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage:= AppMsgProc;
end;

Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
edytowany 1x, ostatnio: kAzek, 2013-11-01 10:18
Kolega widocznie sam doszedł jak to zrobić, ale ponieważ Twoje jest podane w wątku, to chyba uczciwie będzie go oznaczyć jako "rozwiązanie z ptaszkiem" ;) - madmike 2013-11-01 10:23

Pozostało 580 znaków

2013-11-01 10:21

Rejestracja: 7 lat temu

Ostatnio: 1 dzień temu

0

Właśnie też tak zacząłem to robić. Byłeś szybszy ,wielkie dzięki

edytowany 1x, ostatnio: Rafał D, 2013-11-01 10:22

Pozostało 580 znaków

2013-11-01 10:37

Rejestracja: 14 lat temu

Ostatnio: 54 sekundy temu

Lokalizacja: Gorlice

2

A to tak jak być to dla potomnych jeszcze napiszę że w sposób opisany wyżej zawsze pokazuje współrzędne względem lewego górnego rogu kontrolki nad którą znajduje się kursor. Chcąc uzyskać względem całej Formy trzeba przeliczyć:

procedure TForm1.AppMsgProc(var Msg: tagMsg; var Handled: Boolean);
var
  p: TPoint;
begin
  if Msg.message = WM_MOUSEMOVE then
  begin
    p.X:= LoWord(Msg.lParam);
    p.Y:= HiWord(Msg.lParam);
    Windows.ClientToScreen(Msg.hwnd, p);
    Windows.ScreenToClient(Handle, p);
    Label1.Caption:= IntToStr(p.X) + '  ' + IntToStr(p.Y);
  end;
end;

W przykładzie funkcją ClientToScreen zmieniam współrzędne względem kontrolki na współrzędne względem ekranu (pierwszym parametrem jest uchwyt okna nad którym znajduje się kursor) później funkcją ScreenToClient zmieniam te współrzędne na współrzędne względem Form (pierwszym parametrem jest uchwyt Form) . Oczywiście zamiast się bawić w ClientToScreen mogłem od razu pobrać współrzędne funkcją GetCursorPos ale przykład ma pokazanie jak te współrzędne przeliczyć.


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
edytowany 1x, ostatnio: kAzek, 2013-11-01 10:39

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0