我正在使用一个表单来显示通知(它出现在屏幕的右下角),但是当我展示这个表单时,它会夺取主表单的焦点。有没有一种方法可以在不夺取焦点的情况下显示这个“通知”表单?
嗯,仅仅覆盖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;
}
}
从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已经回答了这个问题,我只是通过直接粘贴代码扩展它。有编辑权限的人可以复制它并在那里删除它,至于我,我不介意;))
这是对我有效的方法。它提供了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。
这里借鉴了(抱歉,抄袭了)这里的内容(点击 Workarounds):
来自pinvoke.net的Alex Lyman/TheSoftwareJedi答案中的示例代码将使窗口成为“最顶层”窗口,这意味着在弹出后无法将其放在普通窗口后面。考虑到Matias对他想要使用它的描述,那可能就是他想要的。但是如果您希望用户在弹出窗口后能够将其放置在其他窗口后面,请在示例中使用HWND_TOP(0)而不是HWND_TOPMOST(-1)。
这样做看起来像是一个hack,但似乎是有效的:
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
<Window
x:Class="myApplication.winNotification"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Notification Popup" Width="300" SizeToContent="Height"
WindowStyle="None" AllowsTransparency="True" Background="Transparent" ShowInTaskbar="False" Topmost="True" Focusable="False" ShowActivated="False" >
</Window>
this.Focus();
将焦点重新聚焦到主要表单上。
这个很有效。
请参阅:OpenIcon - MSDN和SetForegroundWindow - MSDN
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
static extern bool OpenIcon(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
public static void ActivateInstance()
{
IntPtr hWnd = IntPtr hWnd = Process.GetCurrentProcess().MainWindowHandle;
// Restore the program.
bool result = OpenIcon(hWnd);
// Activate the application.
result = SetForegroundWindow(hWnd);
// End the current instance of the application.
//System.Environment.Exit(0);
}
form1.Enabled = false
。 - Jader DiasWS_EX_NOACTIVATE
和WS_EX_TOOLWINDOW
的值分别为0x08000000
和0x00000080
。 - Juan