WPF 응용 프로그램을 데스크탑 전면으로 가져 오려면 어떻게해야합니까? 지금까지 나는 시도했다 :
SwitchToThisWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle, true);
SetWindowPos(new WindowInteropHelper(Application.Current.MainWindow).Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
SetForegroundWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle);
어느 것도 작업을 수행하지 않습니다 ( Marshal.GetLastWin32Error()
이러한 작업이 성공적으로 완료되었다고 말하고 각 정의에 대한 P / Invoke 속성에 있음 SetLastError=true
).
새 빈 WPF 응용 프로그램을 만들고 SwitchToThisWindow
타이머를 사용하여 호출 하면 예상대로 정확하게 작동하므로 원래 사례에서 왜 작동하지 않는지 잘 모르겠습니다.
편집 : 나는 글로벌 핫키와 함께 이것을하고 있습니다.
답변
myWindow.Activate();
창을 전경으로 가져 와서 활성화합니다.
내가 오해하지 않고 항상 맨 위의 동작을 원하지 않는 한 트릭을 수행해야합니다. 이 경우에는 다음을 원합니다.
myWindow.TopMost = true;
답변
창을 맨 위로 가져 오는 솔루션을 찾았지만 일반 창처럼 작동합니다.
if (!Window.IsVisible)
{
Window.Show();
}
if (Window.WindowState == WindowState.Minimized)
{
Window.WindowState = WindowState.Normal;
}
Window.Activate();
Window.Topmost = true; // important
Window.Topmost = false; // important
Window.Focus(); // important
답변
창을 처음로드 할 때 맨 앞에 있어야하는 경우 다음을 사용해야합니다.
private void Window_ContentRendered(object sender, EventArgs e)
{
this.Topmost = false;
}
private void Window_Initialized(object sender, EventArgs e)
{
this.Topmost = true;
}
답변
이것을 빠른 복사-붙여 넣기 방법으로 만들기 –
이 클래스의 DoOnProcess
메소드를 사용 하여 프로세스의 메인 윈도우를 포 그라운드로 옮기십시오 (그러나 다른 윈도우에서 포커스를 훔치지는 않습니다)
public class MoveToForeground
{
[DllImportAttribute("User32.dll")]
private static extern int FindWindow(String ClassName, String WindowName);
const int SWP_NOMOVE = 0x0002;
const int SWP_NOSIZE = 0x0001;
const int SWP_SHOWWINDOW = 0x0040;
const int SWP_NOACTIVATE = 0x0010;
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);
public static void DoOnProcess(string processName)
{
var allProcs = Process.GetProcessesByName(processName);
if (allProcs.Length > 0)
{
Process proc = allProcs[0];
int hWnd = FindWindow(null, proc.MainWindowTitle.ToString());
// Change behavior by settings the wFlags params. See http://msdn.microsoft.com/en-us/library/ms633545(VS.85).aspx
SetWindowPos(new IntPtr(hWnd), 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
}
}
}
HTH
답변
나는이 질문이 다소 오래되었다는 것을 알고 있지만이 정확한 시나리오를 보았고 구현 한 솔루션을 공유하고 싶었습니다.
이 페이지의 의견에서 언급했듯이 제안 된 여러 솔루션은 XP에서 작동하지 않으므로 시나리오에서 지원해야합니다. @Matthew Xavier의 의견에 동의하지만 일반적으로 이것이 나쁜 UX 관행이라는 사실에 동의하지만, 전적으로 그럴듯한 UX 인 경우가 있습니다.
WPF 창을 맨 위로 가져 오는 솔루션은 실제로 글로벌 핫키를 제공하는 데 사용하는 동일한 코드로 제공되었습니다. Joseph Cooney의 블로그 기사 에는 원래 코드가 포함 된 코드 샘플에 대한 링크 가 포함되어 있습니다.
코드를 약간 정리하고 수정했으며 System.Windows.Window에 대한 확장 메서드로 구현했습니다. XP 32 비트 및 Win7 64 비트에서 이것을 테스트했으며 둘 다 올바르게 작동합니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Interop;
using System.Runtime.InteropServices;
namespace System.Windows
{
public static class SystemWindows
{
#region Constants
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_SHOWWINDOW = 0x0040;
#endregion
/// <summary>
/// Activate a window from anywhere by attaching to the foreground window
/// </summary>
public static void GlobalActivate(this Window w)
{
//Get the process ID for this window's thread
var interopHelper = new WindowInteropHelper(w);
var thisWindowThreadId = GetWindowThreadProcessId(interopHelper.Handle, IntPtr.Zero);
//Get the process ID for the foreground window's thread
var currentForegroundWindow = GetForegroundWindow();
var currentForegroundWindowThreadId = GetWindowThreadProcessId(currentForegroundWindow, IntPtr.Zero);
//Attach this window's thread to the current window's thread
AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);
//Set the window position
SetWindowPos(interopHelper.Handle, new IntPtr(0), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
//Detach this window's thread from the current window's thread
AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);
//Show and activate the window
if (w.WindowState == WindowState.Minimized) w.WindowState = WindowState.Normal;
w.Show();
w.Activate();
}
#region Imports
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
[DllImport("user32.dll")]
private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
#endregion
}
}
이 코드가이 문제를 겪는 다른 사람들에게 도움이되기를 바랍니다.
답변
사용자가 다른 응용 프로그램과 상호 작용하는 경우 사용자의 응용 프로그램을 맨 앞으로 가져올 수 없습니다. 일반적으로 프로세스는 해당 프로세스가 이미 포 그라운드 프로세스 인 경우에만 포 그라운드 창을 설정할 것으로 예상 할 수 있습니다. (Microsoft는 SetForegroundWindow () MSDN 항목 의 제한 사항을 설명합니다 .) 그 이유는 다음과 같습니다.
- 사용자는 포 그라운드를 “소유”합니다. 예를 들어, 사용자가 입력하는 동안 다른 프로그램이 포 그라운드를 훔 쳤을 때 최소한 워크 플로우를 방해하고 한 응용 프로그램의 키 입력이 변경 사항을 알 때까지 위반자가 잘못 해석하여 의도하지 않은 결과를 초래할 수 있습니다. .
- 두 프로그램 각각이 해당 창의 창이 전경인지 확인하고 그렇지 않은 경우이를 전경으로 설정하려고 시도한다고 상상해보십시오. 두 번째 프로그램이 실행 되 자마자 모든 작업 스위치에서 포 그라운드가 두 개 사이에서 바운스됨에 따라 컴퓨터가 쓸모 없게됩니다.
답변
나는 이것이 답이 늦다는 것을 알고 있습니다.
if (!WindowName.IsVisible)
{
WindowName.Show();
WindowName.Activate();
}