Search Unity

Solved: Running Unity App inside WPF control of WPF App (I already see it but it is always top-left)

Discussion in 'Windows' started by LR-Developer, Aug 15, 2019.

  1. LR-Developer

    LR-Developer

    Joined:
    May 5, 2017
    Posts:
    109
    Hello,

    I created a simple WPF which has some grids with different controls on it.
    The Control showing Unity should be in the middle column.

    I found a sample somewhere with Unity app running in some Windows form and I tried to integrate from it.

    Now I can see my Unity app inside my WPF App, but it is starts with the whole Windows size instead of the sub-Control size, and it does never resize when I resize the wpf window and always stays in the top-left Corner with it's original starting size…

    upload_2019-8-15_13-9-27.png

    The dark Grey one is the Unity app, it should be in the middle column…

    In the MainWindow.xaml.cs, taken from the forms sample mostly:

    Code (CSharp):
    1.         [DllImport("User32.dll")]
    2.         static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
    3.  
    4.         internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
    5.         [DllImport("user32.dll")]
    6.         internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
    7.  
    8.         [DllImport("user32.dll")]
    9.         static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
    10.  
    11.         private Process process;
    12.         private IntPtr unityHWND = IntPtr.Zero;
    13.  
    14.         private const int WM_ACTIVATE = 0x0006;
    15.         private readonly IntPtr WA_ACTIVE = new IntPtr(1);
    16.         private readonly IntPtr WA_INACTIVE = new IntPtr(0);
    In the Window_Loaded Event:

    Code (CSharp):
    1.             HwndSource source = PresentationSource.FromVisual(UnityPanel) as HwndSource;
    2.             IntPtr unityHandle = source.Handle;
    3.  
    4.             //Start embedded Unity Application
    5.             process = new Process();
    6.             process.StartInfo.FileName = "SimGfx.exe";
    7.             process.StartInfo.Arguments = "-parentHWND " + unityHandle.ToInt32() + " " + Environment.CommandLine;
    8.             process.StartInfo.UseShellExecute = false;
    9.             process.StartInfo.CreateNoWindow = true;
    10.             //process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
    11.  
    12.             process.Start();
    13.  
    14.             process.WaitForInputIdle();
    15.             EnumChildWindows(unityHandle, WindowEnum, IntPtr.Zero);        
    Works Pretty well so far, but when the app starts and Shows it's window, Unity app is stretched over the whole window instead of being a part in the middle.

    In the forms sample resize was working this way, but I get no reaction here (and no exception, just Nothing happens):

    Code (CSharp):
    1.         private void ResizeUnityPanel()
    2.         {
    3.             try
    4.             {
    5.                 //MoveWindow(unityHWND, 200, 100, Convert.ToInt32(UnityPanel.ActualWidth), Convert.ToInt32(UnityPanel.ActualHeight), true);
    6.                 MoveWindow(unityHWND, 200, 100, 300, 200, true);
    7.                 ActivateUnityWindow();
    8.             }
    9.             catch { }
    10.  
    11.         private int WindowEnum(IntPtr hwnd, IntPtr lparam)
    12.         {
    13.             unityHWND = hwnd;
    14.             ActivateUnityWindow();
    15.             return 0;
    16.         }
    17.         }
    Why does the Unity part not resize or move and Always stay in left top corner now?

    What am I doing wrong or what am I missing?

    In the XAML part in the MainWindow, the Unity Panel is a part of a grid and Looks like this:

    Code (CSharp):
    1. <WindowsFormsHost Name="UnityPanel" Grid.Row="0" MinHeight="200" />
    WindowsFormsHost tself is just and empty XAML Control from UserControl or from Window…

    Thanks a lot! Help would be great!
     
  2. LR-Developer

    LR-Developer

    Joined:
    May 5, 2017
    Posts:
    109
    Found a solution myself, by making the XAML container a ContentPresenter, it now seems to work pretty well...
     
  3. sommmen

    sommmen

    Joined:
    Jan 7, 2016
    Posts:
    9
    Hi man!

    I kinda have the same issue. Could you be able to share your solution with me? i've been looking for a good solution for 2 weeks now (not fulltime ofcourse but still ;)).

    I use the same sample but whenever i resize my control the whole unity window dissapears.
     
  4. LR-Developer

    LR-Developer

    Joined:
    May 5, 2017
    Posts:
    109
    Use a XAML contentpresenter. Get the handle with

    HwndSource source = (HwndSource)HwndSource.FromVisual(UnityPanel);
    unityHandle = source.Handle;

    and use the above code, make sure the first resizing done by MoveWindow is delayed unitil the process has started.
    Should work perfect. I am currently working on the inter proccess communication and having Problems with those...
     
  5. pilleryann

    pilleryann

    Joined:
    Sep 12, 2013
    Posts:
    1
    Hello !

    I have the same problem to display the Unity application in a WPF.
    I don't know enough about WPF and I don't really know what a "Contentpersenter" is.
    Do you have an example code of how to use it?
     
  6. sommmen

    sommmen

    Joined:
    Jan 7, 2016
    Posts:
    9
    Simple TCP client and server should be easy - my company actually uses a simple json file with one-way communication lol. It works and is running in production although i obviously would not recommend this.