Показать форму без кражи фокуса? - PullRequest
133 голосов
/ 01 октября 2008

Я использую форму для показа уведомлений (она появляется в правом нижнем углу экрана), но когда я показываю эту форму, она крадет фокус у основной формы. Есть ли способ показать эту форму "уведомления" без кражи фокуса?

Ответы [ 17 ]

2 голосов
/ 19 мая 2009

Это хорошо работает.

См .: 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);    
}
2 голосов
/ 07 марта 2013

Вы можете обрабатывать это только одной логикой, хотя я должен признать, что приведенные выше рекомендации, в которых вы используете метод BringToFront без фактического кражи фокуса, являются самыми элегантными.

Во всяком случае, я столкнулся с этим и решил, используя свойство DateTime, чтобы запретить дальнейшие вызовы BringToFront, если вызовы были сделаны уже недавно.

Предположим, что базовый класс 'Core' обрабатывает, например, три формы: Form1, 2 и 3. Каждой форме требуется свойство DateTime и событие Activate, которое вызывает Core, чтобы вывести окна на передний план:

internal static DateTime LastBringToFrontTime { get; set; }

private void Form1_Activated(object sender, EventArgs e)
{
    var eventTime = DateTime.Now;
    if ((eventTime - LastBringToFrontTime).TotalMilliseconds > 500)
        Core.BringAllToFront(this);
    LastBringToFrontTime = eventTime;
}

А затем создайте работу в Базовом классе:

internal static void BringAllToFront(Form inForm)
{
    Form1.BringToFront();
    Form2.BringToFront();
    Form3.BringToFront();
    inForm.Focus();
}

Если вы хотите восстановить свернутое окно в исходное состояние (не развернуто), отметьте:

inForm.WindowState = FormWindowState.Normal;

Опять же, я знаю, что это всего лишь патч для решения проблемы отсутствия BringToFrontWithoutFocus. Подразумевается, если вы хотите избежать DLL-файла.

1 голос
/ 03 июня 2015

Я не знаю, считается ли это некропостингом, но это то, что я сделал, поскольку не смог заставить его работать с методами user32 "ShowWindow" и "SetWindowPos". И нет, переопределение «ShowWithoutActivation» не работает в этом случае, так как новое окно должно быть всегда сверху. Во всяком случае, я создал вспомогательный метод, который принимает форму в качестве параметра; при вызове он показывает форму, выводит ее на передний план и делает ее TopMost, не крадя фокус текущего окна (очевидно, это так, но пользователь не заметит).

    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    static extern IntPtr SetForegroundWindow(IntPtr hWnd);

    public static void ShowTopmostNoFocus(Form f)
    {
        IntPtr activeWin = GetForegroundWindow();

        f.Show();
        f.BringToFront();
        f.TopMost = true;

        if (activeWin.ToInt32() > 0)
        {
            SetForegroundWindow(activeWin);
        }
    }
0 голосов
/ 11 марта 2016

Мне нужно было сделать это с моим окном TopMost. Я реализовал метод PInvoke выше, но обнаружил, что мое событие Load не вызывается, как Talha выше. Я наконец преуспел. Может быть, это кому-нибудь поможет. Вот мое решение:

        form.Visible = false;
        form.TopMost = false;
        ShowWindow(form.Handle, ShowNoActivate);
        SetWindowPos(form.Handle, HWND_TOPMOST,
            form.Left, form.Top, form.Width, form.Height,
            NoActivate);
        form.Visible = true;    //So that Load event happens
0 голосов
/ 01 октября 2008

При создании новой формы с использованием

Form f = new Form();
f.ShowDialog();

он крадет фокус, потому что ваш код не может продолжать выполняться в главной форме, пока эта форма не будет закрыта.

Исключением является использование потоков для создания новой формы, а затем Form.Show (). Убедитесь, что поток является глобально видимым, потому что если вы объявите его внутри функции, как только ваша функция выйдет, ваш поток закончится и форма исчезнет.

0 голосов
/ 09 декабря 2012

Разобрался: window.WindowState = WindowState.Minimized;.

0 голосов
/ 24 сентября 2009

Я знаю, это может звучать глупо, но это сработало:

this.TopMost = true;
this.TopMost = false;
this.TopMost = true;
this.SendToBack();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...