Ответ 1
Вы можете попробовать установить для формы TopMost
форму уведомления true
... или сделать ее модальной, вызвав .ShowDialog
вместо .Show
.
У меня есть приложение, которое я сделал для клиента, но иногда он не знает, поступил ли заказ, потому что он играет в World Of Warcraft с максимальной громкостью. Но он сказал, что хочет, чтобы мое маленькое окно уведомлений появилось поверх его игры, если поступит новый заказ.
Итак, я подумал, что я мог бы просто использовать BringToFront();
который, кажется, работает, когда полноэкранные приложения развернуты. Но я заметил, что во время игры V8 Supercars в полноэкранном режиме, BringToFront();
не выводит окно уведомлений поверх игры, поэтому я полагаю, что в некоторых играх есть другой способ убедиться, что они остаются поверх всего остального.
Как я могу быть уверен, что всякий раз, когда мне понадобится увидеть мою форму, она всегда будет отображаться поверх всего остального?
Вы можете попробовать установить для формы TopMost
форму уведомления true
... или сделать ее модальной, вызвав .ShowDialog
вместо .Show
.
form.TopMost = true;
form.ShowDialog();
form.BringToFront();
Должно работать со всеми приложениями, включая полноэкранные эксклюзивные игры (проверено на всех моих играх, пока оно работает).
Здесь код VB, который вызывает функции API Windows, должен быть относительно легко перевести (обратите внимание: это не проверено, найдено на форумах, также могут возникнуть проблемы с появлением курсора).
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal _ hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _ ByVal cy As Long, ByVal wFlags As Long) As Long
Const HWND_TOPMOST = -1
Const SWP_NOMOVE = &H2
Const SWP_NOSIZE = &H1
Private Sub Form_Load()
Call SetWindowPos(Form1.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Sub
Создайте таймер с интервалом 1 со следующим кодом:
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Sub Timer1_Timer()
Dim mhwnd As Long
mhwnd = GetForegroundWindow SetParent Form1.hwnd, mhwnd
End Sub
Код, переведенный ниже (через автоматический инструмент):
const long HWND_TOPMOST = -1;
const long SWP_NOMOVE = 2;
const long SWP_NOSIZE = 1;
[DllImport("user32.dll")]
private static extern long SetWindowPos(long hwnd, long hWndInsertAfter, long X, long Y, long cx, long cy, long wFlags);
private void Form_Load() {
SetWindowPos(Form1.hwnd, HWND_TOPMOST, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE));
}
[DllImport("user32.dll")]
private static extern long SetParent(long hWndChild, long hWndNewParent);
[DllImport("user32.dll")]
private static extern long GetForegroundWindow();
private void Timer1_Timer() {
long mhwnd;
mhwnd = GetForegroundWindow;
SetParent;
Form1.hwnd;
mhwnd;
}
По умолчанию он будет отображаться поверх экрана, но это не модель.
Вы можете использовать метод Window.Show()
, который при закрытии окна меняет видимость на False, когда это не требуется.
Возможно, вам придется играть с родительским свойством дочерних окон, которые были установлены в главное окно
Я боролся с той же темой, особенно когда в Outlook нажимали "ссылку" на пользовательский протокол. (Приложение ловит его, но всегда в фоновом режиме...)
Несмотря на то, что во время отладки работало много решений, для "Live-Deployment", кажется, только следующая цепочка вызовов достигает желаемого:
(Вызывается, потому что обработка ссылок происходит из потока)
this.Invoke(new Action(() => {
this.Activate();
//...do stuff
this.TopMost = true;
this.BringToFront();
this.TopMost = false;
}));
Работает примерно каждый раз.
Показать() эквивалентно для установки Visible = true. Он не меняет порядок управления Z. Если управление закрыто каким-то другим элементом управления, который находится перед Z-порядком, пользователь все равно не сможет видеть ваш контроль.
BringToFront() изменяет управление Z-порядком (выводит на передний план), но не меняет его видимость. Если управление скрыто, оно останется скрытым. Но когда вы сделаете свой контроль видимым, он появится перед всеми другими элементами управления.
То же самое с Скрыть() (делает управление невидимым, но не меняет Z-порядок) и SendToBack (не меняет видимость, но возвращает управление обратно).