代码之家  ›  专栏  ›  技术社区  ›  Edwin Yip

如何显示类似于弹出菜单的窗口?

  •  9
  • Edwin Yip  · 技术社区  · 15 年前

    1. 我不希望窗口A变得不活动,因为窗口B变成了前窗口;
    2. 我希望当窗口B聚焦时,我只需单击一下窗口a上的组合框控件(通常需要单击两次,一次用于将焦点移动到窗口a,第二次用于下拉组合框);

    我的问题清楚吗? 非常感谢。

    6 回复  |  直到 15 年前
        1
  •  8
  •   Community CDub    8 年前

    我为“1”找到的最简单的解决方案是,一旦弹出表单被激活(在WM_ACTIVATE处理程序中),就向调用表单发送WM_NCACTIVATE,以便调用表单用激活的颜色绘制其标题。要实现这一点,您必须在弹出表单中有调用表单的引用。

    对于“2”,您可以在同一个WM_ACTIVATE处理程序中释放弹出窗体,这不会消耗调用窗体的点击。

    type
      TForm2 = class(TForm)
        [..]
      private
        FOwner: TForm;
        procedure WmActivate(var Msg: TWMActivate); message WM_ACTIVATE;
      public
        constructor Create(AOwner: TComponent); override;
    
    [...]
    constructor TForm2.Create(AOwner: TComponent);
    begin
      if not (AOwner is TForm) then
        raise Exception.Create('Owner should be TForm');
      FOwner := TForm(AOwner);
      inherited;
    end;
    
    procedure TForm2.WmActivate(var Msg: TWMActivate);
    begin
      SendMessage(FOwner.Handle, WM_NCACTIVATE, Ord(Msg.Active <> WA_INACTIVE), 0);
      inherited;
      if Msg.Active = WA_INACTIVE then
        Release;
    end;
    

    并提供呼叫表单作为弹出表单的所有者;

    procedure TForm1.Button1Click(Sender: TObject);
    var
      PopForm: TForm2;
    begin
      PopForm := TForm2.Create(Self);
      [..]
    


    FWIW,我都同意 loursonwinny Ulrich TB2K SpTBXLib . 至少浏览这些资料可以暗示可能涉及到什么。
        2
  •  2
  •   Koro    15 年前

    为了防止窗口获得焦点,必须指定 WS_EX_NOACTIVATE 扩展窗口样式(Windows 2000及以上版本)或句柄 WM_MOUSEACTIVATE 返回 MA_NOACTIVATE .

        3
  •  0
  •   mghie    15 年前

    我可以用它来不失去焦点:

    SetWindowPos(Form2.Handle, HWND_TOP, 0, 0, 0, 0,
      SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE);
    

        4
  •  0
  •   FileVoyager    15 年前

    http://www.silverpointdevelopment.com/sptbxlib/index.htm

    关键似乎是容器“popuped”必须继承tpopumenu。但是处理非常复杂,您可以在代码中自己看到它。我的建议是按照程序包中的原样使用它,因为罗伯特·李做得很出色。

        6
  •  -1
  •   Edwin Yip    15 年前

    我找到了一个几乎完全符合我要求的: TAdvStickyPopupMenu