Hosting Windows Forms controls in native windows, window class="Static" - winforms

I need to provide a Windows Forms control to a native application (Visual Studio).
So I create a control and provide its handle.
Then, when I check the native window using Spy++, I see that my control is wrapped in additional 'control' with window class = "Static" and title "This is a static!". I have several problems with it:
Resize events sent to my control by a hosting window have to be re-sent to the "Static" so it also gets resized (otherwise my control get partially hidden within the static's size).
The static does not have WS_EX_CONTROLPARENT, which causes KB149501 to appear (in short, whole application hangs on lost focus).
If I apply WS_EX_CONTROLPARENT, listbox within the static stops redrawing.
I think I have been doing something wrong, but I am not sure what. Google does not help, since static is a C# keyword as well so it occurs quite often in WinForms results.

I mostly solved the redrawing problem using DoubleBuffered=True, so probably this is it.
I still think I am doing something wrong, but at least it works now.

Related

A window with no taskbar icon, no appearance in Alt-Tab and *without* using the ToolWindow extended style

I have a problem that appears to be new to Windows 10.
I want to create a form that is visible to the user, but with no task bar icon and that does not appear in Alt+Tab.
This is perfectly doable if one is happy to sacrifice the normal styling of a window by following the accepted solutions here for either WPF or Windows Forms.
The general advice for both WPF and Windows Forms is:
Set ShowInTaskbar to false
Enable the ToolWindow styling (either through setting the border style in WinForms or the WindowStyle in WPF)
However, this has a new, practical problem in Windows 10 when using Virtual Desktops: the moment you do the above, the WPF or WinForms window will appear in every virtual desktop. See my example application with a red background:
This affects both the Task View switching screen and the actual desktop itself. No matter where you go, the form is there!
Is there any way to show a form - or even just a bitmap - on Windows without anything appearing in the taskbar, without anything appearing in Alt+Tab and without duplicating the window on every virtual desktop?
I have spent two days researching every possible option, trying every example online, reading MSDN documentation on window styles etc. but all resort to the same method, either through P/Invoke calls or directly, but either way the result is the same.

Custom Window Bar

I'm not sure that's the right way to say it, but what I want is to for my wpf main window to have it's own bar that will behave like a taskbar, and any children windows that will be open from the main one will be placed in that bar in a similar way like the taskbar works in windows - a rectangle showing the window name for example, on click it opens you the window, if you click minimize it will minimize it to the bar, and with some option, to get it out of the main window and move it to the real windows taskbar, with another option for putting it back in. The problem is I don't know if this is even possible, and I don't know the name of such an element, so if anyone can give me any tips I'll be really thankful.
I worked on an application years ago (.NET 3.0: first WPF release!) that did exactly that. We ran into a lot of issues getting it to work, but we were pretty successful in the end. One thing we didn't support was moving it to the Windows taskbar.
The best option would be to set an attached property on each Window. This would register a Window with your custom taskbar, so if you wanted to move the Window out of your custom bar, you'd set the property to false. Setting the property to true would add it to the collection of application windows, as well as register event handlers to track the state of the Window.
One of the major pain points for us was getting the Window animations correct. If you're not running in XP, this probably less of an issue, as the animations in Vista (or is it 7?) and above aren't really showing where a Window is going on minimize. In the end, we had to do a lot of low level Win32 (p/Invoke) work for this.
Take a look at AvalonDock and WPF MDI:
http://avalondock.codeplex.com/
http://wpfmdi.codeplex.com/

How to avoid visual artifacts when hosting WPF user controls within a WinForms MDI app?

When hosting WPF user controls within a WinForms MDI app there is a drawing issue when you have multiple forms that overlap each other that causes very distinct visual artifacts. These artifacts are mostly visible after dragging one child form over another one that also hosts WPF content or by allowing the edges of the child form to be clipped by the main MDI parent when dragging it around. After the drag and drop of the child form is completed the artifacts stay around generally but I've found that setting focus to a different application's window and then refocusing back on to my application window that it is redrawn and all is good again until the child forms are moved once again. Please see the image below which demonstrates the problem.
Those at Microsoft insist that the WinForms MDI is already a sufficient solution for MDI and doesn't need reinventing in WPF although I find it hard to believe they tried creating a WPF app this way because of the obvious shortcomings.
UPDATE: A few extra notes that I left out is that if I create these Forms without setting the MdiParent they are created as regular forms and this issue doesn't happen. This issue seems unique to the WinForms MDI scenario. Also I've currently running on Windows 7 Enterprise and I'm aware the results may be quite different on Windows XP but I haven't been able to test this.
UPDATE: I've found a few other related resources on this issue that I thought I should share.
elementHost repaint problem in MDI
application
elementHost repaint problem in MDI application on Tech Archive
It appears that another workaround is to revert to software rendering as opposed to taking advantage of hardware acceleration. This was the suggestion by Marco Zhou on the MSDN Forums.
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
this.Loaded += delegate
{
var source = PresentationSource.FromVisual(this);
var hwndTarget = source.CompositionTarget as HwndTarget;
if (hwndTarget != null)
{
hwndTarget.RenderMode = RenderMode.SoftwareOnly;
}
};
}
}
I've tested this and this solution seems to work very well and so far is the only solution that I've found for solving this problem within a FoxPro interop scenario which is very similar to the WinForms one I posted about originally. For now I'm planning to use my original Refresh on the MDI Parent solution for my WinForms project but then for my other native interop applications such as when my WPF controls are hosted in Visual FoxPro I'll use this solution. That is unless of course if a more elegant solution is discovered for either of the cases.
Also it's important to note that from what I'm aware software rendering is the only option on XP systems and normally Visual FoxPro nore WinForms normally take advantage of the same type of hardware acceleration that native WPF apps do on Vista OS and up. So using this option may not be as bad as it sounds when you do have to deal with interop. Currently I'm not aware of any related side effects when using this solution but if there are any those would have to be taken into serious consideration.
Well, I may have found a solution although it feels like a bit of a hack. It appears that if you call the Refresh method on the MDI parent whenver a child MDI Form is moved that the noted artifacts go away. Visually things appear a bit jittery when dragging a window but it seems much more acceptable than the example I showed in my original post.
private void Form1_Move(object sender, EventArgs e)
{
this.ParentForm.Refresh();
System.Diagnostics.Debug.WriteLine(string.Format("Form Moved to: ({0},{1})", this.Left, this.Top));
}
I've tried many combinations in the same vein such as refreshing just the child window that was being moved by calling methods such as Update(), Invalidate(), Refresh() and also I've tried these same methods on the MDI parent as well as Dispatcher.Invoke(DispatcherPriority.Render, ...) and InvalidateVisual() on my hosted WPF control but none of those other methods worked accept for calling Refresh() specifically on the MDI parent.
I realize that this probably isn't the optimal solution since I'm forcing the whole main application window to refresh every time a child window moves a few pixels but as for right now it's the only reasonable solution that I found that works. If anybody else has any alternative solutions or any improvements upon this I will gladly accept your answer instead.
Check video drivers and try disabling hardware acceleration. Most artifacts are caused by bad drivers, failing video card, or insufficient time to complete the refresh.
First troubleshooting step: Update video drivers. Obvious, I know.
I had similar issue, checking my video card settings (NVidia Control Panel) showed global setting set very high causing a longer refresh interval which may be aborted if taking too long. Setting my settings back to defaults resolved most of the issue. But I also run hashing programs which use the GPU intensely so this is likely the cause of my remaing artifact issue which is very seldom now and mostly shows its ugly face in Visual Studio.
Another troubleshooting step I ran across is to disable hardware acceleration for WPF, this can be done in 'HKEY_CURRENT_USER/SOFTWARE/Microsoft/Avalon.Graphics', or maybe an application can do it BUT this is only for troubleshooting; never set these within an application because it will disable for ALL WPF applications. I do not have this registry setting nor did I add it so I am not sure of the success with it, but many say this resolved their issue. Also note some applications have this option available, try disabling it if available.
Another troubleshooting step is to make sure the video card is a proper tier level for rendering. Any card that supports DX9 or greater should be sufficient, but other factors are involved (as is my case) so just because it is on the list does not mean it is adequate for your purpose.
Finally, you can use the Visual Profiler (part of Windows SDK), and other tools, to help determine what is going on more precisely with WPF lacking performance in relation to graphics ability.
Rendering Tier level notes and WPF Performance information --> http://msdn.microsoft.com/en-us/library/vstudio/ms742196(v=vs.90).aspx
Hope this helps someone.
--Ryan Strassburg
Your usercontrol or window loaded event ;
this.WindowState = System.Windows.WindowState.Minimized;
this.WindowState = System.Windows.WindowState.Normal;
it may seem bad solution. no need to hit your head against the wall.
A Turkish proverb says: the best code is the code is running :)

Morae Screen Text search not capturing screen text in WPF app

When I try to use Morae Manager 3.0 to run a Screen Text search on a recording of our prototype (coded in WPF, .NET version 3.5 SP1), the only things that come up are the window titles. We are using Windows XP.
Even when I search for something that is editable, like text typed into a text box, it does not come up.
Screen text for things outside the prototype (e.g. desktop icons) still comes up perfectly.
I contacted TechSmith support on two separate occassions and both times the reply I got was it must be an issue with our technology, since the screen text search does work for other things, and that the support people are not developers and thus do not know what might be causing this.
Does anyone know:
what precisely might be causing this -- e.g. does WPF's rendering engine bypass some sort of Windows layer where Morae looks for text (please forgive me for any errors in terminology)
if there is anything I can tweak in the prototype to fix it
how I can get through to someone at TechSmith who knows the answers to 1. and 2.
P.S. Morae is a wonderful product and we've usually had great support from TechSmith. We are only having problems with this one little thing, and one can hardly blame Morae for not being compatible with something as new as WPF.
I have no idea what Morae is or how it works, but one big difference between WPF and for example WinForms is the following, copied from here:
When you create a WPF Window, WPF
creates a top-level HWND, and uses an
HwndSource to put the Window and its
WPF content inside the HWND. The rest
of your WPF content in the application
shares that singular HWND.
If Morae depends on HWNDs to find texts on the screen, this could explain why it can not find the text box. In contrast, i believe in WinForms every control (button, textbox) has its own HWND.

How to run Google Earth Inside a WPF Control

I’m trying to run Google earth inside WPF but I don’t know how. Basically I have managed to run Google Earth in a Windows Form Control inside a Windows Form, everything was OK.
Trying to do the same thing in WPF, well, give strange result a small Google Earth screen placed anywhere in the form an not inside the User Control I have created, and there is now way to make this Google Earth Control grow, or shrink, when I grow or shrink the WPF Form.
Any help would be appreciated, I really mean any!
If you have a Windows Forms control that already works exactly as you want, you could always use WindowsFormsHost to put that control on your WPF form. That might be the easiest thing to do... or is that what you're already doing that isn't working?
I also wrote an application that placed Google Earth inside a WinForms WebBrowserControl that was based on the more-or-less official example hosted by Google. It worked fine. I struggled to recreate the same application inside a WPF WebBrowserControl. My experience confirms what appears to be the general consensus that the WPF WebBrowserControl is harder to use because it provides less control. (e.g. With the WinForms WebBrowserControl you can use the properties to remove the scroll bar and eliminate the IE security question on startup, but with WPF WebBrowserControl you have to use kludges inside to HTML file loaded to get the same effect.) If you are following the Google GE plugin WinForms example, you have to move the JavaScript callback functions into a separate class because of WPF window cant be a parent of the .Net-COM interop between JavaScript and C#. Maybe the other artifacts you described are due to how you resolved this latter limitation. Before finding this solution, I was tempted to put the WinForms WebBrowser control inside the WPF window, but others have posted of unpleasing side-effects of doing this.

Resources