代码之家  ›  专栏  ›  技术社区  ›  HX_unbanned

在OnMouseEnter中创建和销毁表单;在Delphi中保存事件

  •  -1
  • HX_unbanned  · 技术社区  · 14 年前

    对不起,如果之前已经有这样的问题,但我现在没有时间去挖掘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时,窗体被创建。至于创建,焦点从控件转到新窗体。当焦点指向新的形式时, 昂穆塞列夫 事件被激发。当事件被激发时,它应该销毁窗体,但是 只有 用户( 不是 主动控制/聚焦 )实际上是鼠标控制。

    现在所发生的是要么新的形式根本没有被破坏 两个事件都进入无限循环(*frm_prevbtn*被一次又一次地创建和销毁…)。

    最好的解决方案是什么?

    我的想法是获取新的表单rect并在鼠标位于这个rect中时进行检查。如果是,则执行“允许” 昂穆塞列夫 事件,否则解除它…它能工作吗?

    我对这些样品做了很多尝试:

    1. http://delphi.about.com/od/windowsshellapi/a/get-active-ctrl.htm
    2. http://delphi.about.com/od/delphitips2010/qt/is-some-delphi-tcontrol-under-the-mouse.htm

      • 没有运气。问题出在哪里…?

    备注:全局变量Z:字节;

    附笔。 感谢你投反对票…未来使用此网站的巨大动力…

    3 回复  |  直到 14 年前
        1
  •  1
  •   Sertac Akyuz    14 年前

    鼠标进入“graphprevbtn”,在按钮上创建一个窗体。一旦该窗体可见,由于鼠标不再位于“graphprevbtn”上,将激发“onmouseleave”。您破坏了新的窗体,现在鼠标再次出现在按钮上,因此“onmouseenter”被激发,从而产生无限循环。

    作为解决方案,您可以将表单处理代码移动到表单1的“onMouseEnter”:

    procedure TForm1.FormMouseEnter(Sender: TObject);
    begin
      if z = 112
      then begin
        GraphPrevBtn.Parent := Form1;
        [...]
    


    …“GetLastError”是什么,看起来完全不相关。如果要使用它,至少通过调用 GetLastError SetLastError 开始手术前。

        2
  •  1
  •   Remy Lebeau 463035818_is_not_an_ai    14 年前

    也许像这样的事情会帮助你:

    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; 
    
        3
  •  0
  •   himself    14 年前

    你为什么不这样做:

    1. mainform.onmouseover:创建一个辅助窗体。
    2. secondaryForm.onMouseOver:将标志_设置为_secondary。
    3. secondaryform.onmouseleave:清除标记_secondary。
    4. mainform.onmouseleave:如果没有在次要窗体上标记_,则销毁次要窗体。

    如果在mainForm.onMouseLeave之后发生secondaryForm.onMouseOver激发,这可能不起作用。好吧,想想类似的东西。另一种解决方案是启动一个计时器,该计时器将销毁第二种窗体,并在鼠标既不在主窗体上也不在第二种窗体上时禁用自身。