sourcetip

WPF 창을 표시하지 않고 로드하는 방법

fileupload 2023. 4. 18. 23:16
반응형

WPF 창을 표시하지 않고 로드하는 방법

PInvoking으로 창을 표시하는 글로벌 단축키를 만듭니다.RegisterHotKey()하지만 그러기 위해서는 저 창문의 창문이HWND이는 창이 로드될 때까지 존재하지 않습니다. 즉, 처음 표시됩니다.하지만 단축키를 설정하기 전에 창을 보여주고 싶지는 않아요.이 파일을 작성하기 위한HWND사용자가 볼 수 없는 창으로요?

타겟이 되는 경우.NET 4.0 새로운 기능을 이용할 수 있습니다.EnsureHandle에서 사용 가능한 방법WindowInteropHelper:

public void InitHwnd()
{
    var helper = new WindowInteropHelper(this);
    helper.EnsureHandle();
}

(Thomas Levesque가 이 을 지적해 주셔서 감사합니다.)

의 이전 버전을 대상으로 하는 경우.NET Framework에서 가장 쉬운 방법은 HWND로 이동하는 창을 보여주면서 창이 보이지 않고 포커스를 가로채지 않도록 몇 가지 속성을 설정하는 것입니다.

var window = new Window() //make sure the window is invisible
{
    Width = 0,
    Height = 0,
    WindowStyle = WindowStyle.None,
    ShowInTaskbar = false,
    ShowActivated = false
};
window.Show();

실제 창을 표시하려면 내용, 크기를 설정하고 유형을 일반 창으로 다시 변경할 수 있습니다.

창을 이른바 메시지 전용 창으로 변경할 수도 있습니다.이 창 유형은 그래픽 요소를 지원하지 않으므로 표시되지 않습니다.기본적으로 전화는 다음과 같습니다.

    SetParent(hwnd, (IntPtr)HWND_MESSAGE);

항상 숨겨지는 전용 메시지창을 만들거나 실제 GUI 창을 사용하여 표시할 때 일반 창으로 되돌립니다.자세한 예는 아래 코드를 참조하십시오.

    [DllImport("user32.dll")]
    static extern IntPtr SetParent(IntPtr hwnd, IntPtr hwndNewParent);

    private const int HWND_MESSAGE = -3;

    private IntPtr hwnd;
    private IntPtr oldParent;

    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);
        HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;

        if (hwndSource != null)
        {
            hwnd = hwndSource.Handle;
            oldParent = SetParent(hwnd, (IntPtr)HWND_MESSAGE);
            Visibility = Visibility.Hidden;
        }
    }

    private void OpenWindowMenuItem_Click(object sender, RoutedEventArgs e)
    {
        SetParent(hwnd, oldParent);
        Show();
        Activate();
    }

가로 세로, 세로 세로, 세로 세로, 세로 세로, 세로 세로, 세로 세로, 세로 세로, 세로 세로 세로, 세로 세로, 세로 세로, 세로 세로, 세로 세로, 세로 세로, 세로 세로, 세로 세로 세로, 세로 세로 세로, 세로 세로 세로, 세로 세로 세로, 세로 세로 세로, 세로, 세로 세로 세로 세로, 세로 세로, 세로 세로, 세로 세로, 세로 세로, 세로, 세로, 세로, 세로, 세로, 세로, 세로, 세로, 세로, 세로, 세로,그래서 저는 이 대안을 제공하고 있습니다.

이것은 지저분한 해킹이지만 효과가 있을 것이고 불투명도를 바꾸는 단점도 없다.

  • 을 설정하다WindowStartupLocation로.Manual
  • 을 설정하다Top그리고.Left화면 밖의 어딘가에 대한 속성
  • 세트ShowInTaskbar사용자가 새 창이 있다는 것을 깨닫지 못하도록 거짓으로 하다
  • Show그리고.Hide창문

이것으로 HWND를 취득할 수 있습니다.

EDIT: 다른 옵션, 아마도 더 나은 옵션: setShowInTaskBar거짓으로WindowState로.Minimized표시: 전혀 표시되지 않습니다.

저는 이미 그 질문에 대한 답변을 올렸지만, 더 나은 해결책을 찾았습니다.

실제로 창을 표시하지 않고 HWND가 작성되어 있는지 확인해야 하는 경우 다음을 수행할 수 있습니다.

    public void InitHwnd()
    {
        var helper = new WindowInteropHelper(this);
        helper.EnsureHandle();
    }

EnsureHandle질문이 게시되었을 때 메서드를 사용할 수 없었습니다.을 사용하다 4. NET 4.0)

HWND를 얻기 위해 창을 표시해야 하지만 표시하지 않으려면 Window Opacity를 0으로 설정하십시오.이것에 의해, 히트 테스트도 행해지지 않게 됩니다.그런 다음 윈도우에서 Opacity를 표시할 때 Opacity를 100으로 변경하는 공개 방법을 사용할 수 있습니다.

WPF에 대해서는 전혀 모릅니다만, WM_HOTKEY 메시지를 수신하기 위해서 다른 수단(PInvoke 등)을 사용하여 메시지 전용 을 작성할 수 있습니까?[네(Yes)]의 경우 WM_HOTEKEY를 수신하면 거기에서 WPF 창을 실행할 수 있습니다.

할 때 은 '창문'의WindowState(서양속담, 친구속담)이 기능을 실제로 활용할 수 있습니다.

public void InitializeWindow(Window window) {
    window.Top = Int32.MinValue;
    window.Left = Int32.MinValue;

    window.Width = 0;
    window.Height = 0;

    window.ShowActivated = false;
    window.ShowInTaskbar = false;
    window.Opacity = 0;

    window.StateChanged += OnBackgroundStateChanged;

    window.WindowStyle = WindowStyle.None;
}

public void ShowWindow(Window window) {
    window.Show();
    window.WindowState = WindowState.Maximized;
}

protected bool isStateChangeFirst = true;
protected void OnBackgroundStateChanged(object sender, EventArgs e) {
    if (isStateChangeFirst) {
        isStateChangeFirst = false;

        window.Top = 300;
        window.Left = 200;

        window.Width = 760;
        window.Height = 400;

        window.WindowState = WindowState.Normal;

        window.ShowInTaskbar = true;
        window.Opacity = 1;
        window.Activate();
    }
}

그걸로 충분합니다.또한 핸들 등의 조작이 필요하지 않으며, 무엇보다 창에 대한 커스텀 클래스가 필요하지 않습니다.이것은 동적으로 로드되는 XAML에 매우 적합합니다.또한 풀스크린 앱을 만드는 경우에도 매우 적합합니다.상태를 정상으로 되돌리거나 적절한 폭과 높이를 설정할 필요도 없습니다.그냥 따라해

protected bool isStateChangeFirst = true;
protected void OnBackgroundStateChanged(object sender, EventArgs e) {
    if (isStateChangeFirst) {
        isStateChangeFirst = false;

        window.ShowInTaskbar = true;
        window.Opacity = 1;
        window.Activate();
    }
}

그리고 넌 끝났어.

또한 윈도우가 로드될 때 마지막으로 상태 변경이 수행된다고 가정하는 것이 틀리더라도 다른 이벤트로 변경할 수 있습니다.그것은 그다지 중요하지 않습니다.

WindowInterop도우미 클래스에서 WPF 창의 HWND를 얻을 수 있어야 합니다.

MyWindow win = new MyWindow();
WindowInteropHelper helper = new WindowInteropHelper(win);

IntPtr hwnd = helper.Handle;

MSDN 매뉴얼

불투명도를 0으로 설정하는 것과 유사한 맥락의 또 다른 옵션은 크기를 0으로 설정하고 화면을 끌 위치를 설정하는 것입니다.이 경우 AllowsTransparency = True가 필요하지 않습니다.

또한 한 번 보여주면 숨길 수 있고 hwnd를 얻을 수 있습니다.

창의 크기를 0 x 0 px로 설정하고 Show In Task Bar를 false로 하여 표시하고 필요에 따라 크기를 조정합니다.

눈에 보이지 않는 창을 확장 Show이치노

public static class WindowHelper
{
    public static void ShowInvisible(this Window window)
    {
        // saving original settings
        bool needToShowInTaskbar = window.ShowInTaskbar;
        WindowState initialWindowState = window.WindowState;

        // making window invisible
        window.ShowInTaskbar = false;
        window.WindowState = WindowState.Minimized;

        // showing and hiding window
        window.Show();
        window.Hide();

        // restoring original settings
        window.ShowInTaskbar = needToShowInTaskbar;
        window.WindowState = initialWindowState;
    }
}

숨김 모드에서 Wpf 창 시작:

WpfWindow w = new WpfWindow() { Visibility = Visibility.Hidden };

Visible 모드에서 Wpf 창 시작:

WpfWindow w = new WpfWindow();
w.Show();

언급URL : https://stackoverflow.com/questions/1399037/loading-a-wpf-window-without-showing-it

반응형