簡體   English   中英

在Windows 8上將窗口移到最前面

[英]Bring window to front on Windows 8

我正在開發wpf應用程序,我想將主窗口置於最前面。 從文件夾啟動應用程序時,在Windows XP和Windows 7上一切正常。在第8窗口中,應用程序保留在后台。 我嘗試重寫OnLoadCompleted方法並調用win32 api方法https://stackoverflow.com/a/7559766/2250152,但它在Windows 8上不起作用。

protected override void OnStartup(StartupEventArgs e)
{
  base.OnStartup(e);
  ShowSplashScreen();
}
private void ShowSplashScreen()
{
  Thread newWindowThread = new Thread(ThreadStartingPoint);
  newWindowThread.SetApartmentState(ApartmentState.STA);
  newWindowThread.IsBackground = true;
  newWindowThread.Start();
}
private void ThreadStartingPoint()
{
  SplashScreen splashScreen = new SplashScreen();
  splashScreen.Closed += splashScreen_Closed;
  splashScreen.ShowDialog();
}
void splashScreen_Closed(object sender, EventArgs e)
{
  Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
  {
    Current.MainWindow.Activate(); // or win 32 api method SetForegroundWindow
  }
}

這是適用於我的應用程序的解決方案。 (也許有必要使用Dispatcher.CurrentDispatcher.BeginInvoke來調用它)

public static void ShowAndActivate(this Window window)
{
  if (window == null) {
    return;
  }
  var hwnd = new WindowInteropHelper(window).Handle;
  ActivateWindowHandle(hwnd);
}

/// <summary>
/// Activates and sets focus to the Window Object
/// </summary>
public static void ActivateWindowHandle(IntPtr hWnd)
{
  var threadId1 = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
  var threadId2 = GetWindowThreadProcessId(hWnd, IntPtr.Zero);

  if (threadId1 != threadId2) {
    AttachThreadInput(threadId1, threadId2, 1);
    SetForegroundWindow(hWnd);
    AttachThreadInput(threadId1, threadId2, 0);
  } else {
    SetForegroundWindow(hWnd);
  }

  if (IsIconic(hWnd)) {
    ShowWindowAsync(hWnd, ShowWindowCommands.Restore);
  } else {
    ShowWindowAsync(hWnd, ShowWindowCommands.Show);
  }
}

[DllImport("user32.dll")]
public static extern bool IsIconic(IntPtr hWnd);

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
public static extern IntPtr AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, int fAttach);

[DllImport("user32.dll")]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, ShowWindowCommands cmdShow);

[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hWnd);

public enum ShowWindowCommands : int
{
  /// <summary>
  /// Hides the window and activates another window.
  /// </summary>
  Hide = 0,
  /// <summary>
  /// Activates and displays a window. If the window is minimized or 
  /// maximized, the system restores it to its original size and position.
  /// An application should specify this flag when displaying the window 
  /// for the first time.
  /// </summary>
  Normal = 1,
  /// <summary>
  /// Activates the window and displays it as a minimized window.
  /// </summary>
  ShowMinimized = 2,
  /// <summary>
  /// Maximizes the specified window.
  /// </summary>
  Maximize = 3, // is this the right value?
  /// <summary>
  /// Activates the window and displays it as a maximized window.
  /// </summary>       
  ShowMaximized = 3,
  /// <summary>
  /// Displays a window in its most recent size and position. This value 
  /// is similar to <see cref="Win32.ShowWindowCommand.Normal"/>, except 
  /// the window is not activated.
  /// </summary>
  ShowNoActivate = 4,
  /// <summary>
  /// Activates the window and displays it in its current size and position. 
  /// </summary>
  Show = 5,
  /// <summary>
  /// Minimizes the specified window and activates the next top-level 
  /// window in the Z order.
  /// </summary>
  Minimize = 6,
  /// <summary>
  /// Displays the window as a minimized window. This value is similar to
  /// <see cref="Win32.ShowWindowCommand.ShowMinimized"/>, except the 
  /// window is not activated.
  /// </summary>
  ShowMinNoActive = 7,
  /// <summary>
  /// Displays the window in its current size and position. This value is 
  /// similar to <see cref="Win32.ShowWindowCommand.Show"/>, except the 
  /// window is not activated.
  /// </summary>
  ShowNA = 8,
  /// <summary>
  /// Activates and displays the window. If the window is minimized or 
  /// maximized, the system restores it to its original size and position. 
  /// An application should specify this flag when restoring a minimized window.
  /// </summary>
  Restore = 9,
  /// <summary>
  /// Sets the show state based on the SW_* value specified in the 
  /// STARTUPINFO structure passed to the CreateProcess function by the 
  /// program that started the application.
  /// </summary>
  ShowDefault = 10,
  /// <summary>
  ///  <b>Windows 2000/XP:</b> Minimizes a window, even if the thread 
  /// that owns the window is not responding. This flag should only be 
  /// used when minimizing windows from a different thread.
  /// </summary>
  ForceMinimize = 11
}

您是否嘗試過這些方法的組合?

Window.Activate();
Window.Topmost = true;
Window.Topmost = false; 
Window.Focus();         

這是一種解決方法,但是當窗口卡在其他物體后面時,它對我有很大幫助。

當我得到ShowDialog()時,它也對我有幫助,因為有時.NET在涉及多個ShowDialog()時會出現怪異的行為

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM