当前位置:  开发笔记 > 编程语言 > 正文

在没有窃取焦点的情况下显示表单?

如何解决《在没有窃取焦点的情况下显示表单?》经验,为你挑选了7个好方法。

我正在使用表单来显示通知(它出现在屏幕的右下角),但是当我显示此表单时,它会从主表单中窃取焦点.有没有办法在不窃取焦点的情况下显示此"通知"表单?



1> Martin Plant..:

嗯,是不是简单地重写了Form.ShowWithoutActivation?

protected override bool ShowWithoutActivation
{
  get { return true; }
}

如果您不希望用户也单击此通知窗口,则可以覆盖CreateParams:

protected override CreateParams CreateParams
{
  get
  {
    CreateParams baseParams = base.CreateParams;

    const int WS_EX_NOACTIVATE = 0x08000000;
    const int WS_EX_TOOLWINDOW = 0x00000080;
    baseParams.ExStyle |= ( int )( WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW );

    return baseParams;
  }
}


并关闭TopMost.
如果您确实想要TopMost,请参阅[其他答案](http://stackoverflow.com/a/156159/33080).
ShowWithoutActivation,不敢相信我没找到它,浪费了整整一个下午!
我还需要设置`form1.Enabled = false`以防止内部控件窃取焦点
"WS_EX_NOACTIVATE"和"WS_EX_TOOLWINDOW"的值分别为"0x08000000"和"0x00000080".

2> TheSoftwareJ..:

从PInvoke.net的ShowWindow方法中偷走了:

private const int SW_SHOWNOACTIVATE = 4;
private const int HWND_TOPMOST = -1;
private const uint SWP_NOACTIVATE = 0x0010;

[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
static extern bool SetWindowPos(
     int hWnd,             // Window handle
     int hWndInsertAfter,  // Placement-order handle
     int X,                // Horizontal position
     int Y,                // Vertical position
     int cx,               // Width
     int cy,               // Height
     uint uFlags);         // Window positioning flags

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

static void ShowInactiveTopmost(Form frm)
{
     ShowWindow(frm.Handle, SW_SHOWNOACTIVATE);
     SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST,
     frm.Left, frm.Top, frm.Width, frm.Height,
     SWP_NOACTIVATE);
}

(Alex Lyman回答了这个问题,我只是通过直接粘贴代码来扩展它.拥有编辑权限的人可以在那里复制它并删除它,我所关心的所有;))


我觉得令人难以置信的是,我们仍然需要链接到外部DLL文件以与表单进行交互.我们在.NET框架版本4!是时候把它包装好了.
接受的答案是不正确的.寻找ShowWithoutActivation

3> Alex Lyman..:

如果您愿意使用Win32 P/Invoke,那么您可以使用ShowWindow方法(第一个代码示例完全符合您的要求).



4> RenniePet..:

这对我有用.它提供TopMost但没有焦点窃取.

    protected override bool ShowWithoutActivation
    {
       get { return true; }
    }

    private const int WS_EX_TOPMOST = 0x00000008;
    protected override CreateParams CreateParams
    {
       get
       {
          CreateParams createParams = base.CreateParams;
          createParams.ExStyle |= WS_EX_TOPMOST;
          return createParams;
       }
    }

请记住在Visual Studio设计器或其他地方省略设置TopMost.

这是从这里偷来的,错误的,借来的(点击解决方法):

https://connect.microsoft.com/VisualStudio/feedback/details/401311/showwithoutactivation-is-not-supported-with-topmost



5> Matthew Scha..:

这样做似乎是一个黑客,但似乎工作:

this.TopMost = true;  // as a result the form gets thrown to the front
this.TopMost = false; // but we don't actually want our form to always be on top

编辑:注意,这只会提高已经创建的表单而不会窃取焦点.



6> Micah..:

来自Alex Lyman的pinvoke.net的示例代码/ TheSoftwareJedi的答案将使窗口成为"最顶层"的窗口,这意味着在弹出窗口后你无法将其置于正常窗口之后.鉴于Matias对他想要使用它的描述,这可能是他想要的.但是如果您希望用户能够在弹出窗口后将窗口置于其他窗口之后,则只需在示例中使用HWND_TOP(0)而不是HWND_TOPMOST(-1).



7> 小智..:

在WPF中你可以像这样解决它:

在窗口中放置以下属性:



最后一个属性是你需要ShowActivated ="False"的属性.

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有