WPF Stream Live Video - c#

I'm working on an WinForms replacement app in WPF 4.5.
The current WinForms app streams video from a C++ component. The C# WinForms control has this code:
public void StartVideoStream(int iCamera)
{
if (InvokeRequired)
{
delStartVideoStream del = new delStartVideoStream(StartVideoStream);
Invoke(del, new object[] { iCamera });
}
else
{
if (!VideoPlaying)
{
int iSuccess = ClientComm.StartVideoStream(iCamera, ucVideoPlayer.Handle,
(ClientComm.streaming_protocols)Properties.Settings.Default.VideoStreamProtocol,
Properties.Settings.Default.VideoStreamFrameRate);
if (iSuccess != 0)
{
Debug.WriteLine("[ucVideo] Could not play video.");
}
}
else
{
ClientComm.SelectVideoStream(iCamera);
}
VideoPlaying = true;
}
}
You can see that it passes its handle to the COM component which writes the video directly to it.
The problem is that in WPF controls do not have handles. How can I do this I WPF?
Thank you.

The only way I've seen this done is to host a WinForms control inside the WPF control using a HwndHost (https://msdn.microsoft.com/en-us/library/system.windows.interop.hwndhost%28v=vs.110%29.aspx). Unfortunately this lands you right back in WinForms territory.
HwndHost is a little involved to cover in a sensible answer, but there's a reasonable tutorial here: http://blogs.msdn.com/b/ivo_manolov/archive/2007/10/07/5354351.aspx
You should be able to get some useful pointers from the Vlc.DotNet library (https://github.com/ZeBobo5/Vlc.DotNet), which does something similar. Based on playing around with that, if you pass the handle of the WPF application window to a COM component the video is likely to overlay the entire window. If, on the other hand, you talk to the COM component from a WinForms component inside the WPF component, you can use the handle of the WinForms component and keep the rest of your window clear of obstruction.

Related

C# WPF Frame->UserControl->Usercontrol Loaded event doesn't fire

I'm new into WPF and have a problem I can't seem to find a solution for.
I'm writing a G19 (Keyboard) applet. This Keyboard has a 320x240 display attached, which you can access with C#.
I'm using WPF for this, because I don't need to do any GDI drawing anymore and use the normal controls instead.
So. It works as I wish. Everything draws properly except one UserControl. I have downloaded this control -> http://marqueedriproll.codeplex.com/
In the designer, the control works, the Loaded event get's fired and the animation is good.
When I run my application, I just see the label and the text. The animation does not work, and the Loaded event does not fire anymore.
Any help is appreciated.
The main function is my wrapper. The wrapper is already a Usercontrol and displays plugins which are switchable. This wrapper has the Frame Control(Wrapper1). I replace the content of this frame every time I switch the plugin.
public void SetPlugin(IPlugin plugin)
{
if (this.MainPlugin != null)
{
this.MainPlugin.OnHide();
((UserControl)this.MainPlugin).Visibility = System.Windows.Visibility.Hidden;
}
this.MainPlugin = plugin;
((UserControl)this.MainPlugin).Visibility = System.Windows.Visibility.Visible;
this.MainPlugin.OnShow();
this.Wrapper1.Content = this.MainPlugin;
}
I think it's the right approach to handle a plugin system that way. The plugin get's drawed on my keyboard.
What I don't understand is why the usercontrol only works in the designer view and not in the running application.
The basic code of the scrolling label is so:
public MarqueeText()
{
this.Loaded += new RoutedEventHandler(MarqueeText_Loaded);
InitializeComponent();
canMain.Height = this.Height;
canMain.Width = this.Width;
}
void MarqueeText_Loaded(object sender, RoutedEventArgs e)
{
StartMarqueeing(_marqueeType);
}
I don't see a reason why it doesn't work. Actually Ive always found a way to fix a problem but this time I see nothing.
Thanks in advance. Your help is really required today.
Have a great saturday! :)
I am guessing you are rendering to a bitmap target, rather than onscreen. If you are using RenderTargetBitmap, you have a couple of responsibilities. You need to set both a presentation source, and make sure you run events on the dispatcher.
Normally, App.xaml or Application.Run does this for you, but if you are not using a Window, you are on your own.
See this related question for details.

Java Swing Windows "always on top" in WPF app

for some reasons, we have an application built with WPF 4, but in some cases we have to show a windows built using java swing. The problem is, you can set some Window as parent of some dialog or other windows, but always in the same technology.
But when we launch another window that is not built using WPF is very easy to that window to be hidden behind WPF app, and is not easy way to put in front WPF.
Is there any way to put that Java windows "on top" of WPF app?
Window#toFront() and Window#setAlwaysOnTop() can help.
If you need to set window always on top, use setAlwaysOnTop() method.
If you want window to get focus, toFront() or setAutoRequestFocus() may help.
Try this:
import javax.swing.JFrame;
public class NewClass1 {
public static void main(String[] args) {
JFrame frame = new JFrame("On Top");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(100, 100);
frame.setVisible(true);
frame.toFront();
}
}
See Window methods:
toFront()
setAlwaysOnTop(boolean)

hosting WPF inside Windows Form giving issues - C#

I've created a .DLL in WPF. To use it in existing Windows Forms application I use ElementHost.
ElementHost eleHOst = new ElementHost();
UserWarps userWarps = new UserWarps();
eleHOst.Child = userWarps;
eleHOst.Dock = DockStyle.Fill;
UserWarps is in WPF .DLL which has been add-referenced. Now the file does lot of 3D manipulations. I'm also using Petzold.Media3D for 3D lines for wireframe modelling. Everything's working fine except that WireLines of Petzold.Media3D is not drawing any lines. If I reference the DLL from other WPF applications everything's fine, but hosting the UserControl of wpf in windows forms eliminates the lines/wireframes. Rest everything is perfect - MeshGeometry3D, Models, Visuals, functionalities etc.
Please suggest the way forward. could any alternative to ElementHost work? If it does then what is it?
Adding answer originally added by OP in question as I don't want this question to
be closed just because of that.
Petzold has mentioned here that hosting wpf in Windows forms causes the Wire frames to disappear. He also posts a work around which is very simple and worked perfectly:
NOTE: For reasons discussed in paragraph 5, these Wire classes will
not work when
you're hosting 3D in Windows Forms, or when you're trying to print a 3D scene. To make it work, try replacing the static
OnRendering method in WireBase with the following:
static void OnRendering(object sender, EventArgs args)
{
foreach (WireBaseAndUltimateParent wirebaseAndParent in listWireBases)
{
WireBase wirebase = wirebaseAndParent.wirebase;
wirebase.OnRendering();
}
}

WPF OpenFileDialog with Win32 parent window; window is not regaining focus when closed

I have a c++ windows app calling into a c++/cli library, which is calling into a managed library. The managed library is calling OpenFileDialog.Show with a WPF window parent which is owned by the Win32 window. I haven't found a better way to do this, and all the resources I've read here and searching google and social.msdn recommend doing what I'm doing.
The dialog opens just fine, but when I hit the cancel button, for instance, the app loses focus completely. I'm not sure why it's happening, but I can't seem to make it stop. I've tried a number of different things to no avail.
If I just launch the OpenFileDialog without creating a WPF Window, I don't see the problem.
If I don't set the owner of the WPF Window, I don't see the problem. If I call OpenFileDialog.Show and don't pass the parent, but still create the WPF Window and set its owner, I still see the problem.
I am able to hack it to set the parent app window to foreground after it loses focus, but I would like to not have to.
I have uploaded a small example solution for my scenario that illustrates the problem:
http://dl.dropbox.com/u/26054523/MixedExample.zip
Any help would be appreciated.
Have you tried inverting the hosting scenario? Right now it sounds like you're going unmanaged->bridge->managed->WPF->Winforms. Maybe you could go ...managed->WinForms->WPF using ElementHost http://msdn.microsoft.com/en-us/library/ms742215.aspx
In that way, the WPF window would just be a child control of the WinForms app and that might work out better for focus switches. WinForms controls are not really meant to work directly with WPF apps so well, two different UI threading setups are being used as you've noted.
I know that this is an old post but I think that this is a common problem and I have a good answer. If you have a Win32 window parent window called ParentWindow and a WPF child window called WPFChild you can do this:
using System.Windows.Interop;
void OpenWindow()
{
WPFChildWindow WPFChild = new WPFChildWindow();
WindowInteropHelper helper = new WindowInteropHelper(WPFChild)
{
Owner = new NativeWindowWrapper(ParentWindow.Hwnd).Handle
};
bool? ret = _stepsForm.ShowDialog();
}
This will cause the child window to remain on top of the parent and function as a dialog. Keep in mind that the WPF window does not return a DialogResult but rather a nullable bool.
NativeWindow wrapper is a simple class that takes casts an int as an IntPtr. It's actually from a .net Excel ref edit project located here: How to code a .NET RefEdit ControlT

C# Application loaded without focus still steals it on the first injected mouse event

I have two applications, the first is a full directX application written in c++, the second application is written in c# and renders flash videos, avi's, pdf's etc using ActiveX COM objects. The first application then captures the content of this c# app, and renders it into the 3d environment as a texture. This all works as intended, and I have code in the directX app to allow me to send key and mouse events to the c# app via SendMessage and PostMessage.
My problem lies with initial startup. I have the c# app set to start up without activation, using:
protected override bool ShowWithoutActivation
{
get { return true; }
}
which is the equivalent of SW_SHOWNOACTIVATE in the CreateProcess call. The application launches fine, and renders fine on the c++ app's texture. However, the very first mouse click forces the c# application to steal focus, and thus drops my directx context. Does anybody know why this happens, or if there's any way around it?
If I launch the c# app and dont ever click on it, the c++ app when launched still runs as intended, its only when launching it through code:
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESIZE;
si.wShowWindow = SW_SHOWNORMAL;
si.dwXSize = 400;
si.dwYSize = 400;
if(!::CreateProcess(program, arguments, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
return false;
}
else
{
// use EnumWindows to conforim the app is open and get its HANDLE
}
Cheers in advance for any help,
Wayne
you an also try to make the main c# form hidden by setting its properties as WindowState=Minimized
and ShowInTaskbar=false.
then at a certain moment, if you want, you can change the above properties to bring the application form to front.
In this case, the application will be running doing all its jobs but it will not be visible. you can then capture its active region without making it visible on the screen.
Sending key presses doesn't sound like the proper way to do communication between two programs. Could you set up some sort of COM interface between the two programs? Here's a Microsoft page on Interprocess Communication with some other techniques too.

Categories

Resources