BringToFront() в С#

У меня есть приложение, которое я сделал для клиента, но иногда он не знает, поступил ли заказ, потому что он играет в World Of Warcraft с максимальной громкостью. Но он сказал, что хочет, чтобы мое маленькое окно уведомлений появилось поверх его игры, если поступит новый заказ.

Итак, я подумал, что я мог бы просто использовать BringToFront(); который, кажется, работает, когда полноэкранные приложения развернуты. Но я заметил, что во время игры V8 Supercars в полноэкранном режиме, BringToFront(); не выводит окно уведомлений поверх игры, поэтому я полагаю, что в некоторых играх есть другой способ убедиться, что они остаются поверх всего остального.

Как я могу быть уверен, что всякий раз, когда мне понадобится увидеть мою форму, она всегда будет отображаться поверх всего остального?

Ответ 1

Вы можете попробовать установить для формы TopMost форму уведомления true... или сделать ее модальной, вызвав .ShowDialog вместо .Show.

Ответ 2

form.TopMost = true;
form.ShowDialog();
form.BringToFront();

Должно работать со всеми приложениями, включая полноэкранные эксклюзивные игры (проверено на всех моих играх, пока оно работает).

Ответ 3

Здесь код 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;
}

Ответ 4

По умолчанию он будет отображаться поверх экрана, но это не модель.

Вы можете использовать метод Window.Show(), который при закрытии окна меняет видимость на False, когда это не требуется. Возможно, вам придется играть с родительским свойством дочерних окон, которые были установлены в главное окно

Ответ 5

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

Несмотря на то, что во время отладки работало много решений, для "Live-Deployment", кажется, только следующая цепочка вызовов достигает желаемого:

(Вызывается, потому что обработка ссылок происходит из потока)

this.Invoke(new Action(() => {
  this.Activate();
  //...do stuff
  this.TopMost = true;
  this.BringToFront();
  this.TopMost = false;                              
}));

Работает примерно каждый раз.

Ответ 6

Показать() эквивалентно для установки Visible = true. Он не меняет порядок управления Z. Если управление закрыто каким-то другим элементом управления, который находится перед Z-порядком, пользователь все равно не сможет видеть ваш контроль.

BringToFront() изменяет управление Z-порядком (выводит на передний план), но не меняет его видимость. Если управление скрыто, оно останется скрытым. Но когда вы сделаете свой контроль видимым, он появится перед всеми другими элементами управления.

То же самое с Скрыть() (делает управление невидимым, но не меняет Z-порядок) и SendToBack (не меняет видимость, но возвращает управление обратно).

введите описание изображения здесь

введите описание изображения здесь