我有一些问题得到通知框在c#中正确行为。基本上,我在屏幕的右下角显示了一个无边界的形式,它显示一条消息几秒钟然后消失。问题是,我需要它出现在其他窗口的顶部,而没有它能够窃取焦点。理想情况下,我希望它是纯粹的托管代码,虽然通过类似的例子,我怀疑这是可能的。通知窗口 - 防止窗口聚焦
在有覆盖调用Form.Show()的时候,我阻止它偷焦点时刻:
protected override bool ShowWithoutActivation // stops the window from stealing focus
{
get { return true; }
}
,然后忽略鼠标点击有:
private const int WM_MOUSEACTIVATE = 0x0021;
private const int MA_NOACTIVATEANDEAT = 0x0004;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOUSEACTIVATE)
{
m.Result = (IntPtr)MA_NOACTIVATEANDEAT;
return;
}
base.WndProc(ref m);
}
但是我发现如果我将这些与TopMost = true(我需要)一起使用,则无论如何它都会获得焦点,并且如果所有其他窗口都被最小化,它也会获得焦点。
那么,有没有什么办法可以平掉防止形式从以往获得焦点(无论是通过鼠标点击,使用Alt-Tab等),同时仍然最顶端/秒的最顶端的形式?即使只是把焦点放回到窗口,它偷走它会起作用(尽管引入了闪烁)。
任何建议将不胜感激,我真的坚持这一点。
编辑:
好了,我终于用得到这个工作:
protected override bool ShowWithoutActivation // stops the window from stealing focus
{
get { return true; }
}
// and
const int WS_EX_NOACTIVATE = 0x08000000;
const int WS_EX_TOPMOST = 0x00000008;
protected override CreateParams CreateParams
{
get
{
CreateParams param = base.CreateParams;
param.ExStyle |= WS_EX_TOPMOST; // make the form topmost
param.ExStyle |= WS_EX_NOACTIVATE; // prevent the form from being activated
return param;
}
}
// and
[DllImport("user32.dll")]
private extern static IntPtr SetActiveWindow(IntPtr handle);
private const int WM_ACTIVATE = 6;
private const int WA_INACTIVE = 0;
private const int WM_MOUSEACTIVATE = 0x0021;
private const int MA_NOACTIVATEANDEAT = 0x0004;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOUSEACTIVATE)
{
m.Result = (IntPtr)MA_NOACTIVATEANDEAT; // prevent the form from being clicked and gaining focus
return;
}
if (m.Msg == WM_ACTIVATE) // if a message gets through to activate the form somehow
{
if (((int)m.WParam & 0xFFFF) != WA_INACTIVE)
{
if (m.LParam != IntPtr.Zero)
{
SetActiveWindow(m.LParam);
}
else
{
// Could not find sender, just in-activate it.
SetActiveWindow(IntPtr.Zero);
}
}
}
我还添加了Form.Hide()来GotFocus事件,这样即使它不以某种方式获得焦点,它只是简单地关闭并尽快脱离用户的方式。
此外,如果有人想知道,所有窗口样式等的常数可以在WINUSER.H中找到,如果找不到它,可以在http://www.woodmann.com/fravia/sources/WINUSER.H上找到它。
但是,如果任何人都可以看到这样做的更优雅的方式,我们将不胜感激。
谢谢,这是完美的防止它获得焦点,它甚至不会出现在alt选项卡现在这是真棒。我仍然存在的一个小问题是TopMost = true似乎覆盖了ShowWithoutActivation,所以当调用form.Show()时它仍然获得焦点。有没有办法解决? – yebetrollin
查看Ziketo对此的回应。还记得投票赞成有帮助的人们的问题。 –