我正在开发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
}
}
答案 0 :(得分: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
}
答案 1 :(得分:0)
您是否尝试过这些组合?
Window.Activate();
Window.Topmost = true;
Window.Topmost = false;
Window.Focus();
这更像是一种解决方法,但是当窗口被卡在别的东西后,它帮助了我很多。
当我得到一个ShowDialog()
的链时,它也帮助了我,因为有时.NET在多个ShowDialog()