Creating new MDI Window in hosting application - c#

I have an interesting case to solve:
I have a native (winapi) application, which uses MDI. This application allows me to extend itself with a simple scripting language. The scripts are launched on different thread than UI thread (although I can get the UI thread ID with appropriate functions). The scripting language also allow me to launch any c++ code (through LoadLibrary).
What I would like to achieve is to create a new window inside this application, which could host WPF and "attach it" as a MDI child window to MDI client (mdi area). Also, I would like this window to properly "talk" to MDI area, for example update list of windows in mdi menu.
So far, my first guess was to just create a WinForms window, host WPF inside, and then try to make it mdi child window by setting MDI client as it's parent (because my hosting application is not written in c#, I only have a handle, so I did this with User32.SetParent() P/Invoke). This worked almost well, after I attached my script thread to GUI thread, but I had few problems with it: the MDI menu with active windows did not update, the window did not interact correctly (it stayed on stop when it shouldn't etc.).
Then, I tried to set flags (style, exStyles) with SetWindowLongPtr. It changed my window's behavior a bit, but that was still not it.
Now I'm considering using CreateMDIWindow function, or doing it by SendMessage, according to docs sending message should create a window, even if I send it from different thread. The problem is, that this way would give me a native handle only, and I could not find (yet) any way of hosting WinForms / WPF inside it.
I'm curious if anyone tried to do something similar and had any results with it? Which way would be the best - trying to create a WinForms window and add it to MDI client, or create a native window and try to host WinForms in it (any particular way of doing that)?
Most answers for this question I have found are dealing with situation where hosting application is managed, so you can just set .MDIParent property, which won't work in this case I'm afraid.

Related

C# Embedd A Non-Winforms Application into a Winform Application

I want to embedd an application (Hikvision iVMS-4200) into my winform .net application. The application appears to use custom rendering for its GUI, and a loading screen appears before the main window is launched.
In more detail, I want the window of this app to be confined within the window area of my application in a locked position (user can't move the embedded window), and display other things in the same parent window (for example a picture).
I have tried solutions such as this. It worked perfectly, but only with notepad. This solution doesn't work with the application I want (the process is opened successfuly but it is in a completely independant window).
My guess is that the app (again, Hikvision iVMS-4200) uses OpenGL for a custom GUI or another type of non-native GUI library. As a though, shouldn't any application on windows have atleast a single main window? could I access and edit its position and parenting properties? Any solution would be highly appreciated.

Close all WPF windows from winforms application

I host a WPF application in my winforms application via the ElementHost control. I've implemented a logic which listens to unhandled exceptions on WPF side. If an exception is catched, the ElementHost control should be disposed and all related WPF windows should be closed.
This works quite fine, if there is only one WPF window. Since that WPF application can open up more sub windows (which are undocked windows) those windows are not closed when I dispose the ElementHost control.
Is there an easy way to close that WPF window and all child windows from winforms side?
I have tried Application.OpenForms but the sub WPF windows do not show up (makes sense somehow ;-)).
One remark: I do own the WPF code so I could implement something on the WPF side, but I really would like to stick on the win forms side.
Also I would like to consider situations where the WPF window code might be "stuck" and is not able to react and close it self. That's why I'd like to kill the windows from "outside"
So I made up my mind and followed cdkMoose recommendation to let this be handled by the WPF part. It's probably a good idea to let the clean up be done by the one who has the knowledge about what has to be done. Thanks though!

Set Owner of wpf window by window of other application, is it possible?

I would like to make an application by wpf which could overlay a specific windows application.
It means, when I run my application and specify Notepad as target application. At that time, anytime Notepad application got focus, my application will take over the focus & prevent user handle directly Notepad.
It is quite simple in case of 2 windows in same application ( we can set owner of child window & showdialog)
So, I wonder that if it is possible to get the handle of window of other application to set owner for our application.
Thanks for any comments or discussion!
In the general sense, yes - it's possible. But you will have to use Platform APIs in order to obtain the handle of Windows that are not in your process.
Here's a list of Window-related Functions in the Win32 Platform API
You may then by able to make your WPF window appear on top of the other window. But just know that depending on your end goal this might not be the best way to achieve your desired results!

Repainting problem with MDI child created by SetParent API

I have a legacy app written in C that consists of a main window and several mdi children opened from menu options. To allow new mdi children to be written in C# I have created a C++ COM interop layer that is called by the C code and in turn calls the C# code. I then use the SetParent API to set the C main window as the new parent of any C# window opened. This seems to work - the C# window behaves like an MDI child of the main window. BUT, the child window does not paint properly and only gets worse if you move other windows over it or move it to the edges of the main window - it gets painted with parts of the other windows or leaves bits of itself lying around as it moves. In addition the screen doesn't respond very well eg you cannot tab from one textbox to another.
Please don't question the architecture of my solution (believe me, this is the only way), but if you've ever seen a problem like this with a child created by SetParent I'd love to hear if you managed to fix it.
Try these things:
Add Application.DoEvents inside a processing loop that is normally running when things go bad.
Try refreshing the MDI forms from within the main form's paint event.
I don't totally understand how SetParent() works; that being said, here's some more things to consider:
In the MSDN community content of the SetParent documentation, Chango V. from Microsoft added that you: "need to call SetWindowPos(SWP_FRAMECHANGED) when changing between null and non-null parent."
Also, are you sure you are actually running the .NET Form message loop? Did you call Application.Run(yourManagedForm), or are you running your own message loop in the C code? If you're running your own message loop, you may need to forward messages to the WndProc method on your managed form after filtering it through PreProcessMessage. You would need to expose an interface to these as they are protected. I don't know how valid this is, though.

Hosting WPF/Surface application within WPF/Surface application

I am trying to create a parent WPF/surface application which will host multiple WPF/surface applications. I am looking for some pointers of how to implement such functionality. Was reading http://msdn.microsoft.com/en-us/library/ms742522.aspx but it talks about hosting Win32 content in WPF and vice versa.
My idea is to have something similar to MDI forms where you have a main form and you can instantiate multiple child forms.
In my case, these would be different applications which will be launched using a config file and loaded within the main application.
Also, since is there a way to ensure that the main window's process memory is not hogged by the child process initiated.
Edit:
The host application will launch different applications based on what user selects. One can say its like an application launcher which are build on WPF/Surface touch SDK. Now once the application is launched the launcher goes in the background(except showing small button to bring it forward again at some point later) and when the user ends the current application launcher comes back again in foreground. The only interaction i feel which is necessary is knowing the launched application is terminated or invoking applications in a limited screen area. If someone has seen the Microsoft surface application launcher, even when the application is launched there are corner buttons which bring the app launcher to foreground.
I would first look at using Microsoft Prism, specifically the Modularity namespace.
Except for the "different applications" part, it sounds like a classic case for MVVM. Are these "different applications" actually separate applications, or could they simply be separate projects within the same application? That may simplify the choice of presentation.
I suppose you could still have a View called "Host" that presents a different app.
Of course, WPF doesn't have the concept of MDI, but you can open multiple, non-modal windows.
It really depends on what you mean by "hosting". Does the main window need to somehow handle and/or interact with the other applications, or is it just a launching pad for other applications?
I followed this approach to solve this problem. The launcher was not hosting the application within itself but would launch a new application and hide itself.
Steps I followed:
The main launcher application will run in Kiosk mode i.e always on top/no option to close by capturing the close event/No instance shown in taskbar/no title bar/killing the explorer.exe/hiding the taskbar.
The launcher populates a horizontal listbox (data templated for UI) which lets occupied main center area of screen and can be scrolled either ways.
When user selected an item on listbox, click/tap event a separate process is launched with launcher window's visibility set to hidden and a small button(basically a window with just a button inside and size set to height/width of button) created on the either corner of the screen with always on top option.
The functionality of button is to minimize the current working application and set visibility of launcher back to visible and setting the focus to this window.
Since the process is launched by launcher, i trap the close event for the launched window to know user ended the application and then again pop up the launcher back.

Categories

Resources