简体   繁体   English

C# 中的 BringToFront()

[英]BringToFront() in C#

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.但他说他希望我的小通知 window 在新订单到达时出现在他的游戏顶部。

So, I was thinking I could just use BringToFront();所以,我想我可以只使用BringToFront(); which seems to work when full-screen apps are Maximized.这似乎在全屏应用程序最大化时起作用。 But, I have noticed that while playing V8 Supercars in full screen, BringToFront();但是,我注意到在全屏播放 V8 Supercars 时, 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.不会将通知 window 置于游戏之上,因此我认为某些游戏有另一种方式来确保它们始终位于其他所有内容之上。

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 .您可以尝试将通知表单的TopMost属性设置为true ...或通过调用.ShowDialog而不是.Show使其成为模态。

I struggled with the same topic, especially when a "link" to a custom protocol was clicked in Outlook.我在同一个话题上苦苦挣扎,尤其是在 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).这是调用windows API函数的VB代码,应该相对容易翻译(注意,这是未经测试的,在论坛上找到的,另外,您可能对出现的Z1791A97A8403730EE0760489A2有问题)。

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:使用以下代码创建一个间隔为 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

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.默认情况下,它将出现在屏幕顶部,但不是 model。

You can use Window.Show() method insted of closing the window change its visibility to False when it is not required.您可以使用Window.Show()方法关闭 window 在不需要时将其可见性更改为 False。 You might need to play with Parent Property of the child windows set it to main window您可能需要使用子 windows 的父属性将其设置为主 window

You could try setting TopLevel = true, this brings the control forward.您可以尝试设置 TopLevel = true,这会使控制向前。 TopMost = true prevents any other contol getting focus, which is not always what you want. TopMost = true 可防止任何其他控件获得焦点,这并不总是您想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM