C# 嵌入qt/C的主窗口++;wpf/mvvm应用程序中的应用程序

C# 嵌入qt/C的主窗口++;wpf/mvvm应用程序中的应用程序,c#,.net,wpf,qt,winapi,C#,.net,Wpf,Qt,Winapi,我需要在wpf mvvm应用程序中嵌入一个qt/c++应用程序。此qt/C++的窗口必须集成在选项卡页面中显示的wpf页面中 页面控件如下所示: <page x:Class="Wpf_HostExe.Page1" xmlns:="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title=

我需要在wpf mvvm应用程序中嵌入一个qt/c++应用程序。此qt/C++的窗口必须集成在选项卡页面中显示的wpf页面中

页面控件如下所示:

<page x:Class="Wpf_HostExe.Page1"
    xmlns:="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Page1"
    Loaded="OnLoaded">
    <Grid>
        <Border x:Name="HostUi" Background="White"
            HorizontalAlignment="Stretch"
            VerticalAlignment="Stretch"  />
    </Grid>
</Page>
按照以下说明重新安装外部窗口:

public class ApplicationHost : HwndHost
{
    private const uint LBS_NOTIFY = 0x00000001;
    private const uint WS_BORDER = 0x00800000;
    private const int SWP_NO_ACTIVATE = 0x0010;
    private const int GWL_STYLE = -16;
    private const int WS_CAPTION = 0x00C00000;
    private const int WS_THICKFRAME = 0x00040000;
    private const uint WS_VISIBLE = 0x10000000;


    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    [DllImport("user32.dll"), SetLastError = true]
    private static extern int GetWindowLong(IntPtr hwnd, int nIndex);

    [DllImport("user32.dll")]
    private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent);

    [DllImport("user32.dll")]
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

    public IntPtr ApplicationHandle { get; set; }
    ...
    protected override HandleRef BuildWindowCore (HandleRef hwndParent)
    {
        var result = new HandleRef(this, ApplicationHandle);
        if (ApplicationHandle.ToInt32() == 0)
        {
            return result;
        }

        var oldParent = SetParent(ApplicationHandle, hwndParent.Handle);

        var styles = GetWindowLong(ApplicationHandle, GWL_STYLE);
        styles |= WS_CHILD | WS_VISIBLE | WS_BORDER | LBS_NOTIFY;
        styles &= ~WS_CAPTION;
        SetWindowLong32(ApplicationHandle, GWL_STYLE, styles);

        return result;
    }
    ...
}
我还尝试了以下版本:

    ...
    protected override HandleRef BuildWindowCore (HandleRef hwndParent)
    {
        SetParent(ApplicationHandle, hwndParent.Handle);

        int style = GetWindowLong(ApplicationHandle, GWL_STYLE);
        style = style & ~WS_CAPTION & ~WS_THICKFRAME;
        SetWindowLong(ApplicationHandle, GWL_STYLE, style);
    }
    ...
要托管的应用程序的进程开始时没有问题,但SetParent似乎不起作用,在传递方法BuildWindowCore时,无论SetParent以何种方式执行,我都会收到以下消息:

"An unhandled exception of type 'System.InvalidOperationException' occured in PresentationFramework.dll"
Additional Information : Hosted HWND must be a child window of the specified parent. "
我尝试了在stackoverflow上发现的很多东西,但是我仍然抛出了同样的InvalidOperationException,并且不知道如何修复它

你能帮帮我吗


关于,

我假定您拥有Qt应用程序的源代码。在该代码中,您必须创建一个函数,该函数将
render()。从WPF调用该函数,将图像从QImage的
data()
复制到a,并使用控件显示该图像。您还可以将鼠标和键盘的点击向相反方向移动,并具有一个功能,该功能可以合成
QEvent
s以与小部件交互。

将一个进程中的窗口作为另一个进程中窗口的子进程嵌入到另一个进程中,从本质上说,这是您无法期望成功的。它需要双方的充分合作,以及对win32的深刻理解。通过这种方式将Qt和WPF结合起来,基本上没有成功的希望。找到另一个解决方案。这里是一个重要的补充:“如果您创建了一个跨进程的父/子或所有者/所有者关系,其后果可能很难管理。如果所涉及的一个或两个窗口不知道它正在参与跨进程窗口树,则这些后果几乎无法管理。”WPF和Qt都没有为这一特技做好准备。
"An unhandled exception of type 'System.InvalidOperationException' occured in PresentationFramework.dll"
Additional Information : Hosted HWND must be a child window of the specified parent. "