为了账号安全,请及时绑定邮箱和手机立即绑定

单击系统托盘图标时如何防止当前窗口失去焦点

单击系统托盘图标时如何防止当前窗口失去焦点

C#
天涯尽头无女友 2022-11-22 15:35:46

我正在为 Windows 10 编写一个 C# Windows 窗体应用程序,类似于系统虚拟键盘。该应用程序位于最顶层,它不会通过覆盖 CreateParams 和 ShowWithoutActivation 来窃取焦点:


private const int WS_EX_NOACTIVATE = 0x08000000;


protected override CreateParams CreateParams

{

    get

    {

        CreateParams params = base.CreateParams;

        params.ExStyle |= WS_EX_NOACTIVATE;

        return (params);

    }

}


protected override bool ShowWithoutActivation

{

    get { return true; }

}

该应用程序可以由用户最小化到系统托盘。这不会改变焦点。但是,当应用程序从系统托盘恢复(通过单击应用程序图标)时,当前活动窗口失去焦点。


有没有办法避免这种行为并保持活动窗口(在鼠标单击之前)集中?


该应用程序被最小化并使用以下方法恢复:


this.Hide();  // minimize on close event

..

this.Show();  // restore on notify icon click event

这里有一个类似的问题,但它已经过时了:

Prevent system tray icon from stealing focus when clicked


查看完整描述

1 回答

?
子衿沉夜

TA贡献1553条经验 获得超3个赞

这是一个临时解决方案,直到有人找到合适的解决方案。它通过在应用程序的托盘图标鼠标移动事件中连续读取和保存焦点窗口来工作。这个保存的窗口将被设置为在托盘图标鼠标按下事件中聚焦:


[DllImport("user32.dll", ExactSpelling = true)]

static extern IntPtr GetForegroundWindow();


[DllImport("user32.dll")]

[return: MarshalAs(UnmanagedType.Bool)]

static extern bool SetForegroundWindow(IntPtr hWnd);


private void notifyIcon_MouseDown(object sender, MouseEventArgs e)

{

    if (lastActiveWin != IntPtr.Zero)

    {

        SetForegroundWindow(lastActiveWin);

    }

}


IntPtr lastActiveWin = IntPtr.Zero;

private void notifyIcon_MouseMove(object sender, MouseEventArgs e)

{

    lastActiveWin = GetForegroundWindow();

}


查看完整回答
反对 回复 6天前
  • 1 回答
  • 0 关注
  • 6 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信