Launch WPF executable and set parent? - wpf

I have a WPF executable and I want another program to launch it and set this launching program as the parent windows of my WPF executable (The main purpose is that when the launching program is closed the WPF executable is also shut down). I thought I could make it like this: I pass the Hwnd as one command line parameter (as integer-string), and I can call the SetParent or whatever function inside my WPF executable code to specify the parent. However, I can't make it work. Can anybody tell me how to do that, or any other way to do that? Thanks!

You can't. Window handles are per-process.
Besides, you wouldn't want to. It's problematic enough to have a parent window in another thread -- that causes the message queues of the two threads to become attached, i.e., they effetively share the same message queue from then on. So now if either thread locks up, or does some lengthy processing, both threads are frozen. (And there's no way to later detach the message queues, as far as I'm aware.) Imagine trying to extend this cross-process.
If you must start some new code and use an existing window as a parent, you can't go cross-process. You would have to load the WPF code into your process and call a method in it, passing your parent window as a parameter. The simplest way to load that code into your process would be to change your WPF application to a class library (.dll), and either add a reference to that .dll, or load it dynamically using Reflection.

As #Joe White said you cannot achieve this straightaway ... I think I can "guess" what you are getting at ....
You probably have a WinForm MDI parent (its exe already) and you want to launch another WPF window (another exe) as its child. Am I correct?
Hmmmm then you would have to create a new WinForm child window with WinFormWPFHostApp in it and then refer the WPF assemblies to this project and try to host the Content of the MainWindow from that other WPF application.
refer this article...

Related

How can i retrieve a textbox control's name property from another application's window

I am writing a program that overlay's a toolbar onto another applications window. I am able to iterate through the MDI child windows and even access all the controls via PInvoke. The one thing I am trying to figure out is how to get the controls actual Name property.
I am able to see the name of the field using Hawkeye but I cannot figure out how it is getting the control name.
One thought is that it may be injecting something into the target application and running something like Control.FromHandle but I am not 100% sure.
Thanks for any help.
Unfortunately, the Name property of a control is a property of the .Net object that creates the window not of the control window itself. There is no way to get this value using the window handle - PInvoke or otherwise - from outside of the process.
You would need to do some variation on what Hawkeye appears to do. Attach to the process, examine the object hierarchy and/or inject code dynamically using the CLR Debugging API.

Silverlight Open Child Window counter

I have a silverlight application which uses a child window as a processing dialog. The child window open can be called from more that one event.
What I would like to do is to add a counter to the Child Window Show() that increments by one on each call. That way, I should then be able to only call the Close() if the counter is at zero. This would allow for all the completed events to run and call a Close() and decrement the value by one with each call.
To be honest I'm not sure where to start with this one but any help or guidance would be great.
Thanks
Its not 100% clear what you are trying to accomplish, but a good way to retrieve all your opened childwindow objects is the following method :
VisualTreeHelper.GetOpenPopups()
Note that this is available since Silverlight version 4.0 only
Good luck.

Changing window procedure for console window

I want to make console window with a functional tray icon. I figured out that most probably it is necessary to replace initial console's window procedure so I will be able to control all messages including notify area events. But SetWindowLong() function returns 0, and GetLastError() tells that access is denied.
hwndFound = GetConsoleWindow();
SetWindowLong(hwndFound, GWL_WNDPROC, (long)WndProc);
What could it be, or maybe there is some other way to control tray icon manipulations?
If all you want to do is create a notification icon for a console application, there's nothing that says your Shell_NotifyIcon call has to point to the console window. Create an invisible dummy window with your own window class and procedure instead. Note that you'll probably have to do this from a secondary thread in order to run its message loop. (The console window is special, as it's hosted outside your process by conhost.exe/csrss.exe.)
No, you just need a window. Best thing is to startup a thread so you can pump a message loop and receive the icon notifications. Create a little hidden window that you can use for the Shell_NotifyIcon() call.
Which version of Windows are you using? I know that prior to Vista, console windows are treated specially, and can't be manipulated in many of the standard ways. This article by Raymond Chen might shed some further light.

Creating a WPF element in another Thread

I'm able to run 2 or more WPF windows on different thread.
The problem is that now my application in splitted in many windows.
What I really want is have a main window containg a grid in which every cell contains an element managed by a different thread.
Is it possible to create a UIElement/Component managed by a thread that is not the one which manage the parent/ containing window?
or
Is it possible to encapsulate a window that runs on a different thread in some frame/UIElement?
Thanks
Is it possible to use a MediaElement to project a window into a Panel?
"What I really want is have a main window containg a grid in which every cell contains an element managed by a different thread."
One way to go about this would be to create your elements normally in the cell. Create a regular class ViewModel that doesn't touch the UI but runs on it's own thread. This class is the brains behind what you're actually trying to DO with in your cells, not what you're trying to SHOW in your cells. This ViewModel class should implement INotifyPropertyChanged when it's data is has been updated. In your MainWindow.cs file you can set your cell elements' DataContext to these ViewModels. Lastly, in your XAML you can Bind things you're trying to show with the Properties in your ViewModel.
I know I breezed over a lot of details, but it's a starting point. Lots of help to be had around here if you need any.
It's not possible in WPF and even if it was it would have been a bad idea:
It's not possible in WPF because WPF element can only be used by the thread that created them, if you add a child element from another thread they wouldn't be able to communicate.
In pure Win32 it is possible - but it joins the two threads message queues so the threads are no longer independent (so even if you find a hack that makes it work with WPF it still doesn't help you)
Any thread that has UI and performs a long running task can hung the entire system - so it's impotent to never perform any long running task in a UI thread - instead run the long task in a background thread
because you have to keep the UI thread responsive -> it should never be busy for a noticeable length of time -> it can handle all your windows because it's not too busy.

WPF Canvas: Children.Add() hanging on background thread?

...or...
"What evil in the depths of WPF have I awoken?"
I'm creating a Canvas on a background thread and rendering it to a bitmap. I've had this working in production code for over a year now without problems. I do the following:
create a Canvas object
create a new NameScope object
assign that NameScope to the Canvas
draw whatever I want on the Canvas
call canvas.Measure() with the Canvas's size
call canvas.Arrage() with the Canvas's available rect
call canvas.UpdateLayout()
render the Canvas
In the draw step, I have always just called canvas.Children.Add() to put UIElements onto the Canvas. This has always worked.
Now, for some inexplicable reason, in one specific case in the application I'm working on, the call to canvas.Children.Add() hangs indefinetely, blocking my background thread. I can't think of anything I'm doing differently between the code that has been working for over a year, and this one specific case.
Can anyone suggest possible reasons why a call to canvas.Children.Add() would hang like this?
Edit: The background thread is an STA thread (the background thread processing model was put in place because I couldn't process images using WPF on a MTA thread), so the thread apartment model shouldn't be the culprit.
Edit #2: While I understand why people are suggesting I try Dispatcher.BeginInvoke() from my background thread, I don't like that option for two reasons:
I want my background thread processing to be synchronous on that thread. My background thread has a queue that other threads submit image jobs to, and my background thread processes each job as it gets to them. Using Dispatcher.BeginInvoke() adds another layer of complexity that I'd rather avoid.
I've never needed to until now. Doing this background processing synchronously on my background thread has just plain worked. I'm trying to determine what could possibly be different about this bizarre edge case that causes this code to not work. If I can't get it to work, I'll end up rewriting this processing code without WPF, which I'd also rather avoid.
What apartment model are you using for your background thread?
I believe WPF needs to run on the STA thread. When you spawn the background thread, try settings it's apartment to STA.
Update:
If the STA thread is not the problem, then I would try breaking your canvas drawing up into chunks. Basically if you do a:
Dispatcher.BeginInvoke(...)
from your thread, the provided delegate gets pushed onto the back of the dispatcher queue, allowing other queued tasks to execute.
Update 2:
You could also try debugging into the source code for the Canvas object using the .NET framework reference sources. You can enable this by turning on "enable .net framework source stepping" in the debugging options under Tools->Options.
Try calling Dispatcher.Run() in the background thread.

Resources