Хммм, недостаточно ли просто переопределения Form.ShowWithoutActivation?
protected override bool ShowWithoutActivation
{
get { return true; }
}
И если вы не хотите, чтобы пользователь щелкнул это окно уведомления, вы можете переопределить CreateParams:
protected override CreateParams CreateParams
{
get
{
CreateParams baseParams = base.CreateParams;
const int WS_EX_NOACTIVATE = 0x08000000;
const int WS_EX_TOOLWINDOW = 0x00000080;
baseParams.ExStyle |= ( int )( WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW );
return baseParams;
}
}
form1.Enabled = false
чтобы внутренние элементы управления не отвлекали вниманиеWS_EX_NOACTIVATE
иWS_EX_TOOLWINDOW
равны0x08000000
и0x00000080
соответственно.Похищенный из Pinvoke.net «s ShowWindow методы:
private const int SW_SHOWNOACTIVATE = 4; private const int HWND_TOPMOST = -1; private const uint SWP_NOACTIVATE = 0x0010; [DllImport("user32.dll", EntryPoint = "SetWindowPos")] static extern bool SetWindowPos( int hWnd, // Window handle int hWndInsertAfter, // Placement-order handle int X, // Horizontal position int Y, // Vertical position int cx, // Width int cy, // Height uint uFlags); // Window positioning flags [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); static void ShowInactiveTopmost(Form frm) { ShowWindow(frm.Handle, SW_SHOWNOACTIVATE); SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST, frm.Left, frm.Top, frm.Width, frm.Height, SWP_NOACTIVATE); }
(Алекс Лайман ответил на это, я просто расширяю его, напрямую вставляя код. Кто-то с правами редактирования может скопировать его туда и удалить, мне все равно;))
источник
Если вы хотите использовать Win32 P / Invoke , вы можете использовать метод ShowWindow (первый пример кода делает именно то, что вы хотите).
источник
Это то, что у меня сработало. Он обеспечивает TopMost, но без перехвата внимания.
protected override bool ShowWithoutActivation { get { return true; } } private const int WS_EX_TOPMOST = 0x00000008; protected override CreateParams CreateParams { get { CreateParams createParams = base.CreateParams; createParams.ExStyle |= WS_EX_TOPMOST; return createParams; } }
Не забудьте опустить установку TopMost в конструкторе Visual Studio или где-либо еще.
Это украдено, ошибочно, позаимствовано отсюда (нажмите на обходные пути):
https://connect.microsoft.com/VisualStudio/feedback/details/401311/showwithoutactivation-is-not-supported-with-topmost
источник
Это похоже на взлом, но похоже, что это работает:
this.TopMost = true; // as a result the form gets thrown to the front this.TopMost = false; // but we don't actually want our form to always be on top
Изменить: обратите внимание, это просто вызывает уже созданную форму без кражи фокуса.
источник
Пример кода с сайта pinvoke.net в ответах Alex Lyman / TheSoftwareJedi сделает окно «самым верхним» окном, что означает, что вы не можете поместить его за обычными окнами после его появления. Учитывая описание Матиаса того, для чего он хочет использовать это, это может быть то, что он хочет. Но если вы хотите, чтобы пользователь мог помещать ваше окно позади других окон после того, как вы его открыли, просто используйте HWND_TOP (0) вместо HWND_TOPMOST (-1) в примере.
источник
В WPF это можно решить так:
В окошке укажите эти атрибуты:
<Window x:Class="myApplication.winNotification" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Notification Popup" Width="300" SizeToContent="Height" WindowStyle="None" AllowsTransparency="True" Background="Transparent" ShowInTaskbar="False" Topmost="True" Focusable="False" ShowActivated="False" > </Window>
Последний атрибут - это тот, который вам нужен ShowActivated = "False".
источник
У меня есть что-то похожее, и я просто показываю форму уведомления, а затем делаю
this.Focus();
чтобы снова сфокусироваться на главной форме.
источник
Создайте и запустите форму уведомления в отдельном потоке и сбросьте фокус обратно на основную форму после открытия формы. Попросите форму уведомления предоставить событие OnFormOpened, которое запускается из
Form.Shown
события. Что-то вроде этого:private void StartNotfication() { Thread th = new Thread(new ThreadStart(delegate { NotificationForm frm = new NotificationForm(); frm.OnFormOpen += NotificationOpened; frm.ShowDialog(); })); th.Name = "NotificationForm"; th.Start(); } private void NotificationOpened() { this.Focus(); // Put focus back on the original calling Form }
Вы также можете сохранить дескриптор объекта NotifcationForm, чтобы его можно было программно закрыть с помощью основной формы Form (
frm.Close()
).Некоторые детали отсутствуют, но, надеюсь, это поможет вам двигаться в правильном направлении.
источник
Вы можете подумать, какое уведомление вы хотите отображать.
Если абсолютно необходимо сообщить пользователю о каком-либо событии, рекомендуется использовать Messagebox.Show из-за его характера для блокировки любых других событий в главном окне, пока пользователь не подтвердит это. Однако помните о всплывающей слепоте.
Если это менее критично, вы можете использовать альтернативный способ отображения уведомлений, например панель инструментов в нижней части окна. Вы писали, что вы показываете уведомления в правом нижнем углу экрана - стандартный способ сделать это - использовать всплывающую подсказку с комбинацией значка на панели задач .
источник
Это хорошо работает.
См .: 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); }
источник
Вы также можете справиться с этим только с помощью логики, хотя я должен признать, что приведенные выше предложения, в которых вы заканчиваете методом 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; }
А затем создайте работу в Core Class:
internal static void BringAllToFront(Form inForm) { Form1.BringToFront(); Form2.BringToFront(); Form3.BringToFront(); inForm.Focus(); }
Кстати, если вы хотите восстановить свернутое окно в исходное состояние (не развернуто), используйте:
Опять же, я знаю, что это просто исправление из-за отсутствия BringToFrontWithoutFocus. Это означает, что вы хотите избежать использования файла DLL.
источник
Я не знаю, считается ли это некро-публикацией, но это то, что я сделал, так как я не мог заставить его работать с методами 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); } }
источник
Я знаю, это может показаться глупым, но это сработало:
this.TopMost = true; this.TopMost = false; this.TopMost = true; this.SendToBack();
источник
Мне нужно было сделать это с моим окном 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
источник
Когда вы создаете новую форму, используя
Form f = new Form(); f.ShowDialog();
он крадет фокус, потому что ваш код не может продолжать выполнение в основной форме, пока эта форма не будет закрыта.
Исключением является использование потоков для создания новой формы, а затем Form.Show (). Однако убедитесь, что поток виден глобально, потому что, если вы объявите его в функции, как только ваша функция завершится, ваш поток завершится, и форма исчезнет.
источник
Фигурное это:
window.WindowState = WindowState.Minimized;
.источник