很抱歉,如果之前已经提出过这样的问题,但我现在没有时间去挖掘stackoverflow数据库......
所以,我有这段代码:
procedure TForm1.GraphPrevBtnMouseEnter(Sender: TObject);
var frm_PrevBtn : TForm;
begin
GraphPrevBtn.Width := 75;
if z = 0 then begin
frm_PrevBtn := TForm.Create(nil);
with frm_PrevBtn do begin
Name := 'frm_PrevBtn';
BorderStyle := bsNone;
Position := poDesigned;
Top := Form1.Top + GraphprevBtn.Top + (form1.Height - Form1.ClientHeight) - 3;
Left := Form1.Left + GraphprevBtn.Left + 3;
Width := GraphprevBtn.Width; Height := GraphprevBtn.Height; transparentColor := True; TransparentColorValue := clbtnFace;
Show;
end;
GraphPrevBtn.Parent := frm_PrevBtn;
if GetLastError = 0 then z := frm_prevBtn.GetHashCode;
end;
end;
procedure TForm1.GraphPrevBtnMouseLeave(Sender: TObject);
var frm_PrevBtn_H : THandle;
begin
// if form is created then- if mouse is under button then- if z = formshashcode ( form is on creatin stage )
if not (FindVCLWindow(Mouse.CursorPos) = GraphPrevBtn) and ((FindControl(FindWindow('TForm','frm_PrevBtn')) as TForm).Visible = True) and (GraphPrevBtn.Parent = FindControl(FindWindow('TForm','frm_PrevBtn')) as TForm) then begin // if mouse is not under graphprevBtn
ShowMessage(FindVCLWindow(Mouse.CursorPos).Name); //
if z = 112 // then if form is created
then begin
GraphPrevBtn.Parent := Form1;
GraphPrevBtn.bringtoFront;
GraphPrevBtn.Top := 29; GraphPrevBtn.Left := 226;
(FindControl(FindWindow('TForm','frm_PrevBtn')) as TForm).Free;
if GetLastError = 0 then z := 0;
end;
end;
end;
所以,我希望如下: 当我使用鼠标输入此GraphPrevBtn时,将创建表单。至于创造,焦点从控制到新形式。由于重点是新表单,因此会触发 OnMouseLeave 事件。当事件被触发时,它应该破坏表单,但仅在用户(不 主动控件/焦点)实际上通过鼠标控制。< / p>
现在发生的事情是,任何新表单都不会被破坏 或 两个事件都会无限循环(* frm_PrevBtn *会被一次又一次地创建和销毁。 ..)。
什么是最好的解决方案?
我的想法是获取新的表格rect并检查鼠标是否在此矩形内。如果是,则执行allow OnMouseLeave 事件,否则取消它......它会起作用吗?
我尽量尝试这些样本:
http://delphi.about.com/od/delphitips2010/qt/is-some-delphi-tcontrol-under-the-mouse.htm
备注:global var z:byte;
P.S。 感谢负面投票......将来使用此网站的动力很大......
答案 0 :(得分:1)
鼠标进入'GraphPrevBtn',您在按钮上创建一个表单。一旦这个表单变得可见,因为鼠标不再是'GraphPrevBtn','OnMouseLeave'被触发。你破坏了新的表单,现在鼠标再次出现在按钮上,因此'OnMouseEnter'被触发,因此无限循环。
作为解决方案,您可以将表单处理代码移动到Form1的“OnMouseEnter”:
procedure TForm1.FormMouseEnter(Sender: TObject);
begin
if z = 112
then begin
GraphPrevBtn.Parent := Form1;
[...]
..和'GetLastError'有什么关系,看起来完全无关紧要。如果你打算使用它,至少在开始操作之前调用GetLastError
或SetLastError
将最后一个错误设置为'0'。
答案 1 :(得分:1)
也许更像这样的东西可以帮到你:
var
frm_PrevBtn : TForm = nil;
procedure TForm1.GraphPrevBtnMouseEnter(Sender: TObject);
var
P: TPoint;
begin
GraphPrevBtn.Width := 75;
if frm_PrevBtn = nil then begin
P := GraphPrevBtn.ClientOrigin;
frm_PrevBtn := TForm.Create(nil);
with frm_PrevBtn do begin
BorderStyle := bsNone;
Position := poDesigned;
SetBounds(P.X, P.Y, GraphPrevBtn.Width, GraphPrevBtn.Height);
TransparentColor := True;
TransparentColorValue := clBtnFace;
GraphPrevBtn.Parent := frm_PrevBtn;
GraphPrevBtn.Top := 0;
GraphPrevBtn.Left := 0;
Show;
end;
end;
end;
procedure TForm1.GraphPrevBtnMouseLeave(Sender: TObject);
begin
if (FindVCLWindow(Mouse.CursorPos) <> GraphPrevBtn) and (frm_PrevBtn <> nil) then begin
GraphPrevBtn.Parent := Self;
GraphPrevBtn.BringToFront;
GraphPrevBtn.Top := 29;
GraphPrevBtn.Left := 226;
FreeAndNil(frm_PrevBtn);
end;
end;
答案 2 :(得分:0)
你为什么不这样做:
如果在MainForm.OnMouseLeave之后触发SecondaryForm.OnMouseOver,则可能无效。好吧,想想类似的东西。另一种解决方案是启动一个计时器,如果鼠标既不在Main也不在SecondaryForm上,它会销毁SecondaryForm并自行禁用。