Мышь над компонентом, или нет?
От: Eagle-XK Украина http://esoft.pp.ua
Дата: 19.07.06 09:09
Оценка:
Всем привет! Вобщем, есть приблизительно такой код: глобально ловим мышку, опознаём координаты и если видим, что мышка находится над панелькой — посылаем beep.
Как ни странно, работает... но с огрехами: если форма с панелькой скрыта другой формой, оно всё равно будет работать, хотя мне это как раз и не нужно... Проблемма в том, как узнать, находится ли мышка реально над компонентом (отлов WM_MOUSEMOVE не канает — на панельке могут лежать ещё компоненты, да и не работает WM_MOUSEMOVE если на каком-то компоненте уже стоит SetCaptureControl) или она реально прикрыта другим окном/компонентой. Помогите, плиз, советом, а то у меня что-то совсем башка не варит... %)

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure TmrTimer(Sender: TObject);
    procedure PnlCaptureMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  end;

var
  Form1: TForm1;
  Pnl, PnlCapture: TPanel;
  Tmr: TTimer;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Pnl := TPanel.Create(Self);
  Pnl.Parent := Self;

  PnlCapture := TPanel.Create(Self);
  PnlCapture.Parent := Self;
  PnlCapture.OnMouseMove := PnlCaptureMouseMove;
  PnlCapture.Left := 200;

  Tmr := TTimer.Create(Self);
  Tmr.Enabled := True;
  Tmr.Interval := 100;
  Tmr.OnTimer := TmrTimer;
end;

procedure TForm1.PnlCaptureMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
 P:TPoint;
begin
 if not ((x>=0) and (y>=0) and (x<PnlCapture.width) and (y<PnlCapture.height)) then
 begin
  if GetCaptureControl=PnlCapture then ReleaseCapture;
 end
 else
  if not (GetCaptureControl=PnlCapture) then SetCaptureControl(PnlCapture);
end;

procedure TForm1.TmrTimer(Sender: TObject);
var
  CurPos: TPoint;
begin
  GetCursorPos(CurPos);
  CurPos := Pnl.ScreenToClient(CurPos);
  if ((CurPos.X >= 0) and (CurPos.X <= Pnl.Width)) and ((CurPos.Y >= 0) and (CurPos.Y <= Pnl.Height)) then
    Beep;
end;

end.


RSDN@Home v.1.1.4
ORIGIN: Рай и ад отличаются лишь поставщиком софта.
Re: Мышь над компонентом, или нет?
От: ekamaloff Великобритания  
Дата: 19.07.06 09:24
Оценка:
Здравствуйте, Eagle-XK, Вы писали:

А если так:

EX>
EX>procedure TForm1.TmrTimer(Sender: TObject);
EX>begin
EX>  if WindowFromPoint(Mouse.CursorPos) = Pnl.Handle then
EX>    Beep;
EX>end;
EX>
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[2]: Мышь над компонентом, или нет?
От: Eagle-XK Украина http://esoft.pp.ua
Дата: 19.07.06 09:34
Оценка:
Здравствуйте, ekamaloff, Вы писали:

E>Здравствуйте, Eagle-XK, Вы писали:


E>А если так:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure TmrTimer(Sender: TObject);
    procedure PnlCaptureMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  end;

var
  Form1: TForm1;
  Pnl, PnlCapture: TPanel;
  M: TMemo;
  Tmr: TTimer;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Pnl := TPanel.Create(Self);
  Pnl.Parent := Self;

  M := TMemo.Create(Pnl);
  M.Parent := Pnl;
  M.Align := alClient;

  PnlCapture := TPanel.Create(Self);
  PnlCapture.Parent := Self;
  PnlCapture.OnMouseMove := PnlCaptureMouseMove;
  PnlCapture.Left := 200;

  Tmr := TTimer.Create(Self);
  Tmr.Enabled := True;
  Tmr.Interval := 100;
  Tmr.OnTimer := TmrTimer;
end;

procedure TForm1.PnlCaptureMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
 P:TPoint;
begin
 if not ((x>=0) and (y>=0) and (x<PnlCapture.width) and (y<PnlCapture.height)) then
 begin
  if GetCaptureControl=PnlCapture then ReleaseCapture;
 end
 else
  if not (GetCaptureControl=PnlCapture) then SetCaptureControl(PnlCapture);
end;

procedure TForm1.TmrTimer(Sender: TObject);
var
  CurPos: TPoint;
begin
  GetCursorPos(CurPos);
  CurPos := Pnl.ScreenToClient(CurPos);
  if WindowFromPoint(Mouse.CursorPos) = Pnl.Handle then
//  if ((CurPos.X >= 0) and (CurPos.X <= Pnl.Width)) and ((CurPos.Y >= 0) and (CurPos.Y <= Pnl.Height)) then
    Beep;
end;

end.


Проверь сам... Я уже искал в этом направлении... Сейчас есть мысль "углубить" поиски


RSDN@Home v.1.1.4
ORIGIN: Рай и ад отличаются лишь поставщиком софта.
Re[3]: Мышь над компонентом, или нет?
От: ekamaloff Великобритания  
Дата: 19.07.06 09:59
Оценка: 1 (1) +1
Здравствуйте, Eagle-XK, Вы писали:

EX>Проверь сам...


Я не заметил, что панелька у тебя закрыта другим контролом. Тогда может подойдет нечто такое:

procedure TForm1.TmrTimer(Sender: TObject);
var
    Control: TWinControl;
begin
    Control := FindControl(WindowFromPoint(Mouse.CursorPos));
    while Assigned(Control) and (Control <> Pnl) do
        Control := Control.Parent;
    if Control = Pnl then
        Beep;
end;
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[4]: Мышь над компонентом, или нет?
От: Eagle-XK Украина http://esoft.pp.ua
Дата: 19.07.06 10:40
Оценка:
ekamaloff, это буквально тот же код, который я тоже как раз написал и хотел отпостить как решение! 5 баллов!


RSDN@Home v.1.1.4
ORIGIN: Для чиво нужин Арфагрофический Славарь?
Re[5]: Мышь над компонентом, или нет?
От: Eagle-XK Украина http://esoft.pp.ua
Дата: 19.07.06 10:41
Оценка:
Здравствуйте, Eagle-XK, Вы писали:

EX>ekamaloff, это буквально тот же код, который я тоже как раз написал и хотел отпостить как решение! 5 баллов!

Кстати, именно это я и имел в виду под словами "есть мысль "углубить" поиски"


RSDN@Home v.1.1.4
ORIGIN: Hello Dword!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.