как взять дескриптор окна в wpf

Я хочу открыть приложение в своем окне. мой код отлично работает в форме Windows, но в wpf он не работает. вот код с описанием

 private Process pDocked;
    private IntPtr hWndOriginalParent;
    private IntPtr hWndDocked;

    [DllImport("user32.dll")]
    static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);




    private void panel1_Resize(object sender, EventArgs e)
    {
        //Change the docked windows size to match its parent's size. 
        MoveWindow(hWndDocked, 0, 0, panel1.Width, panel1.Height, true);
    }


    private void dockIt(string utility)
    {
        if (hWndDocked != IntPtr.Zero) //don't do anything if there's already a window docked.
            return;
        //hWndParent = IntPtr.Zero;

        pDocked = Process.Start(utility);
        while (hWndDocked == IntPtr.Zero)
        {
            pDocked.WaitForInputIdle(1000); //wait for the window to be ready for input;
            pDocked.Refresh();              //update process info
            if (pDocked.HasExited)
            {
                return; //abort if the process finished before we got a handle.
            }
            hWndDocked = pDocked.MainWindowHandle;  //cache the window handle
        }
        //Windows API call to change the parent of the target window.
        //It returns the hWnd of the window's parent prior to this call.
        hWndOriginalParent = SetParent(hWndDocked, panel1.Handle);

        //Wire up the event to keep the window sized to match the control
        panel1.SizeChanged += new EventHandler(panel1_Resize);
        //Perform an initial call to set the size.
        panel1_Resize(new Object(), new EventArgs());
    }

И при нажатии кнопки я передаю блокнот в док-станцию, но он не работает, как мне заставить его работать в wpf, на любой панели (док-панель, стек-панель), но они не поддерживают изменение размера окна


person Anoop Mishra    schedule 12.02.2015    source источник
comment
после использования Windows Forms Integration он открывает утилиту, но это не видно   -  person Anoop Mishra    schedule 12.02.2015
comment
и я хочу открыть его в табуляции   -  person Anoop Mishra    schedule 12.02.2015
comment
Можете ли вы немного расширить это? Объясните свое намерение, что вы ожидаете, и что вы на самом деле наблюдаете (как в формах win, так и в wpf).   -  person Rikalous    schedule 12.02.2015
comment
Хост System.Windows.Forms.Integration.WindowsFormsHost = new System.Windows.Forms.Integration.WindowsFormsHost(); пристыковать (блокнот); host.Child = панель1; this.grid1.Children.Add (хост);   -  person Anoop Mishra    schedule 12.02.2015
comment
хорошо, это сегмент кода, который я использую, чтобы открыть его в сетке wpf   -  person Anoop Mishra    schedule 12.02.2015
comment
но я хочу вызвать dokit() в tabcontrol в wpf, и это не работает   -  person Anoop Mishra    schedule 12.02.2015
comment
чтобы получить дескриптор, вы можете использовать новый WindowInteropHelper(YOUR_WINDOW).Handle, но можете ли вы объяснить, чего вы пытаетесь достичь?   -  person igorushi    schedule 12.02.2015
comment
на самом деле я хочу открыть блокнот в tabcontrol в wpf.   -  person Anoop Mishra    schedule 12.02.2015


Ответы (1)


Вы можете разместить блокнот в своем окне WPF следующим образом: добавьте WindowsFormsHost в свое окно, установите System.Windows.Forms.Panel как дочерний элемент и используйте дескриптор панели.

public partial class MainWindow : Window
{
    [DllImport("user32.dll")]
    static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

    private Process pDocked;
    private IntPtr hWndOriginalParent;
    private IntPtr hWndDocked;
    public System.Windows.Forms.Panel pannel;

    public MainWindow()
    {
        InitializeComponent();
        pannel = new System.Windows.Forms.Panel();
        host.Child = pannel;
        dockIt("notepad.exe");
    }

    private void dockIt(string utility)
    {
        if (hWndDocked != IntPtr.Zero) //don't do anything if there's already a window docked.
            return;

        pDocked = Process.Start(utility);
        while (hWndDocked == IntPtr.Zero)
        {
            pDocked.WaitForInputIdle(1000); //wait for the window to be ready for input;
            pDocked.Refresh();              //update process info
            if (pDocked.HasExited)
            {
                return; //abort if the process finished before we got a handle.
            }
            hWndDocked = pDocked.MainWindowHandle;  //cache the window handle
        }
        //Windows API call to change the parent of the target window.
        //It returns the hWnd of the window's parent prior to this call.
        hWndOriginalParent = SetParent(hWndDocked, pannel.Handle);

        //Wire up the event to keep the window sized to match the control
        SizeChanged += window_SizeChanged;
        //Perform an initial call to set the size.
        AlignToPannel();
    }

    private void AlignToPannel()
    {
        MoveWindow(hWndDocked, 0, 0, pannel.Width, pannel.Height, true);
    }

    void window_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        AlignToPannel();
    }
}

Окно XAML:

<TabControl>
    <TabItem Header="Notepad">
        <WindowsFormsHost x:Name="host" />
    </TabItem>
</TabControl>

Но как только вы поместите свой WindowsFormsHost на вкладку, возникнет множество проблем с интеграцией WinForms/WPF. Лучший источник знаний по этой теме, который я нашел в этой статье "Устранение проблем с воздушным пространством в приложениях WPF". Удачи.

person igorushi    schedule 12.02.2015
comment
это работает нормально, но уже объясните, что это возможно для управления вкладками, или вы можете открыть его как вкладку - person Anoop Mishra; 12.02.2015