gpt4 book ai didi

c# - 通知窗口 - 防止窗口获得焦点

转载 作者:太空狗 更新时间:2023-10-29 21:41:15 25 4
gpt4 key购买 nike

我在让通知框在 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);
}

}
}

我还在 GotFocus 事件中添加了 Form.Hide() ,这样即使它确实以某种方式获得焦点,它也会简单地关闭并尽快离开用户。

此外,如果有人想知道,所有窗口样式等的常量都可以在 WINUSER.H 中找到,其在线地址为 http://www.woodmann.com/fravia/sources/WINUSER.H。如果找不到。

但是,如果有人能看到更优雅的方法,我们将不胜感激。

最佳答案

您可能正在寻找 WS_EX_NOACTIVATE 扩展窗口样式。单击时不会激活具有此样式的窗口。例如,虚拟键盘窗口就是这种风格。

要将此样式应用于窗口,请覆盖 CreateParams 函数并更改 baseParams.ExStyle。

关于c# - 通知窗口 - 防止窗口获得焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7750517/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com