【问题标题】:Bring window to front on Windows 8在 Windows 8 上将窗口置于前面
【发布时间】:2014-10-19 09:07:35
【问题描述】:

我正在开发 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
  }
}

【问题讨论】:

  • 请向我们展示您的代码。谢谢。
  • 你试过Window.Activate吗?
  • 我添加了代码。 Window.Activate 不适用于 Windows 8

标签: c# wpf windows-8


【解决方案1】:

这是一个适用于我的应用程序的解决方案。 (也许有必要用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
}

【讨论】:

    【解决方案2】:

    你尝试过这些的组合吗?

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

    这更像是一种解决方法,但是当窗口卡在其他东西后面时它对我有很大帮助。

    当我得到一系列 ShowDialog() 时,它也对我有帮助,因为有时 .NET 在涉及多个 ShowDialog() 时会出现奇怪的行为

    【讨论】:

      猜你喜欢
      • 2013-06-26
      • 2011-11-04
      • 2012-10-08
      • 2011-10-07
      • 1970-01-01
      • 2013-03-28
      • 2020-04-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多