Как предотвратить потерю фокуса текущим окном при нажатии на значок в системном трее - PullRequest
0 голосов
/ 03 апреля 2019

Я пишу приложение C # Windows Forms для Windows 10, аналогичное системной виртуальной клавиатуре. Приложение самое верхнее, и оно не отвлекает внимание, переопределяя 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

Здесь был похожий вопрос, но он довольно устарел:
Предотвращение кражи значка в системном трее при нажатии

1 Ответ

0 голосов
/ 03 апреля 2019

Вот временное решение, пока кто-то не найдет подходящее.Он работает, постоянно читая и сохраняя окно в фокусе внутри события перемещения мыши на значке в трее приложения.Это сохраненное окно будет сфокусировано на событии мыши внизу иконки в трее:

[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();
}
...