Всем привет! Вобщем, есть приблизительно такой код: глобально ловим мышку, опознаём координаты и если видим, что мышка находится над панелькой — посылаем 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: Рай и ад отличаются лишь поставщиком софта.
Здравствуйте, 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
Здравствуйте, 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: Рай и ад отличаются лишь поставщиком софта.
Здравствуйте, 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
ekamaloff, это буквально тот же код, который я тоже как раз написал и хотел отпостить как решение!

5 баллов!
RSDN@Home v.1.1.4
ORIGIN: Для чиво нужин Арфагрофический Славарь?
Здравствуйте, Eagle-XK, Вы писали:
EX>ekamaloff, это буквально тот же код, который я тоже как раз написал и хотел отпостить как решение!
5 баллов!
Кстати, именно это я и имел в виду под словами "есть мысль "углубить" поиски"

RSDN@Home v.1.1.4
ORIGIN: Hello Dword!