c# exe encapsulation in wpf not work

1

I need to encapsulate exe on my wpf application. My wpf application is very large and with many UserControls. To do this, i've start the exe from my code, then get the handle and used the "setParent" to "bind" the exe to my application, but the only effect is to show the drop down menu of the exe, but not the main page. For example: i've tried to embedded notepad, but appear only the drop down menu when I click in the area (note that not appear the main menu bar).

  var procInfo = new System.Diagnostics.ProcessStartInfo(this.exeName);
  procInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(this.exeName);

  // Start the process
  _childp = System.Diagnostics.Process.Start(procInfo);

  // Wait for process to be created and enter idle condition
  _childp.WaitForInputIdle();

  // Get the main handle
  _appWin = _childp.MainWindowHandle;

  // Get main window handle
  var helper = new WindowInteropHelper(Window.GetWindow(this.AppContainer));

  // Incapsulate
  SetWindowLongA(_appWin, -20, 0x00000040 | 0x00000008);
  SetParent(_appWin, helper.Handle);

Note that I've tried this piece of code in other c# application and work fine! I think there is a problem of redraw/update the viewport. In which way can i force this redraw of the external exe inside my application? Can you help me, even to found an alternative solution to embedded the exe? Thanks

enter image description here

I've tried the solution to run the exe in a separate tab (here), but even this solution not work.

Can I resolve this with a "SendMessage" ??? Can you suggest me a test to do?

I ask you one thing: help me!!!

c#
wpf
exe
setparent
asked on Stack Overflow Jun 10, 2016 by ste • edited May 23, 2017 by Community

2 Answers

0

The below works for me, can provide you with example project if necessary. The missing piece seems to be that either you have a z index issue OR your initial window placement in your desktop co-oridinates is such that is it outside your 'outer window'.

this will bring it the the from and make it FILL your window:

SetWindowPos(_appWin, default(IntPtr), 0, 0, (int)Application.Current.MainWindow.Width, (int)Application.Current.MainWindow.Height, SetWindowPosFlags.FrameChanged);

The default(IntPtr) is for the ZIndex and says 'bring to front'

You can then make that smaller by passing in the offsets from your containing control, ie if this.grid was what you wanted notepad to appear over:

    var desiredPos = this.grid.TranslatePoint(new Point(0, 0), Window.GetWindow(this.grid));
    SetWindowPos(_appWin, default(IntPtr), 
        (int)desiredPos.X, (int)desiredPos.Y, 
        (int)this.grid.ActualWidth, (int)this.grid.ActualHeight, SetWindowPosFlags.FrameChanged);
answered on Stack Overflow Jun 10, 2016 by tolanj
0

Using AllowsTransparency="False" instead AllowsTransparency="True" inside the WPF of the Window I've been able to solve partially the problem

Now I've embedded the external exe (for example: "notepad.exe") using this approach (WindowsFormHost approach):

System.Windows.Forms.Panel _pnlSched = new System.Windows.Forms.Panel();

System.Windows.Forms.Integration.WindowsFormsHost windowsFormsHost1 = 
              new System.Windows.Forms.Integration.WindowsFormsHost();
windowsFormsHost1.Child = _pnlSched;
_grid.Children.Add(windowsFormsHost1);
ProcessStartInfo psi = new ProcessStartInfo(@"notepad.exe");
psi.WindowStyle = ProcessWindowStyle.Normal;
Process PR = Process.Start(psi);
PR.WaitForInputIdle(); 
SetParent(PR.MainWindowHandle, _pnlSched.Handle);  

Now the new problem may be the Z-order of the user control. In fact, when another user contol move above the "notepad", it is below and not above...

enter image description here

Note that also the background of the WindowsFormHost not respect the 'z-order':

enter image description here

any suggestion is welcome

Thanks

answered on Stack Overflow Jun 23, 2016 by ste

User contributions licensed under CC BY-SA 3.0