I have an app here I made for a client, but sometimes he doesn't know if an order has arrived because he plays World Of Warcraft with the volume max'd out. But he said he wants my little notification window to appear on top of his game if a new order arrives.
So, I was thinking I could just use BringToFront();
which seems to work when full-screen apps are Maximized. But, I have开发者_JS百科 noticed that while playing V8 Supercars in full screen, BringToFront();
doesn't bring the notification window on top of the game, so I figure that some games have another way of making sure they remain on top of everything else.
How can I make sure that whenever I need my form to be seen, it will always show up on top of anything else?
form.TopMost = true;
form.ShowDialog();
form.BringToFront();
Should work with all applications, full-screen exclusive games included (tested on all my games, so far, it works).
You could try setting the notification form's TopMost
property to true
...or make it modal by calling .ShowDialog
instead of .Show
.
I struggled with the same topic, especially when a "link" to a custom protocol was clicked in Outlook. (The App catched it, but always in the background...)
Even though a lot of solutions worked while debugging, for the "Live-Deployment" only the following chain of calls seems to achieve what was desired:
(Invoked, cause handling of links happens from a thread)
this.Invoke(new Action(() => {
this.Activate();
//...do stuff
this.TopMost = true;
this.BringToFront();
this.TopMost = false;
}));
Works about every time.
Here's VB code that calls windows API functions, should be relatively easy to translate (note, this is untested, found on forums, also, you may have issues with the cursor appearing).
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
Create a timer with interval 1, with the following code:
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
Code translated below (via automated tool):
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;
}
By default it will appear on top of screen but it is not model .
You can use Window.Show()
method insted of closing the window change its visibility to False when it is not required.
You might need to play with Parent Property of the child windows set it to main window
You could try setting TopLevel = true, this brings the control forward. TopMost = true prevents any other contol getting focus, which is not always what you want.
精彩评论