Docksite WindowActivated and WindowDeactivated Events (WindowsFormsHost)

Docking/MDI for WPF Forum

Posted 7 years ago by P. Chwoika - Inosoft GmbH
Version: 12.2.0573
Platform: .NET 4.0
Environment: Windows 7 (64-bit)
Avatar

Hi,

we are using your DockSite and have subscribed to the WindowActivated and WindowDeactivated Events.

As long as we don't use the WindowsFormsHost to show Winforms content, everything is fine and the events are fired.

Our scenario is as follows: We have a floating ToolWindow (with WPF content) and a DockingWindow (with hosted Windows Forms content) in the TabbedMDIContainer. If we now change the active window by clicking directly into the WindowsFormsHost and in the Toolwindow the WindowActivated/Deactivated events are no longer fired.

I have a sample project which shows the problematic behavior. Is it possible for me to attach it to this thread?

Thanks for your help.

Comments (17)

Answer - Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi,

Unfortuantely WindowsFormsHost controls don't always properly report focus to containing WPF controls.  And our product relies on knowing where focus is for activating docking windows. 

So in this kind of scenario, when you detect that focus moves into a WindowsFormsHost, you should check to see if the containing docking window is active.  If not, call its Activate(false) method.


Actipro Software Support

Posted 7 years ago by P. Chwoika - Inosoft GmbH
Avatar

Hello again!

I tried the same scenario with the WindowsFormsHost using another DockingManager (AvalonDock). All events are fired fine, there are no problems with the WindowsFormsHost!

Is there any chance you can implement what the guys from AvalonDock implemented to make this work?

Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello, can you e-mail our support address with a new simple sample project that shows it working there?  Then we can debug through and see what is happening.  Please rename the .zip file extension so it doesn't get spam blocked.


Actipro Software Support

Posted 7 years ago by P. Chwoika - Inosoft GmbH
Avatar

The example is very small, I can post it right here:

 

<Window x:Class="AvalonDockApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:avalonDock="http://avalondock.codeplex.com"
        xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        Title="MainWindow" Height="434" Width="684">
    <Grid>
        <avalonDock:DockingManager x:Name="dockingManager">
            <avalonDock:LayoutRoot>
                <avalonDock:LayoutPanel Orientation="Horizontal">
                    <avalonDock:LayoutDocumentPane>
                        <avalonDock:LayoutDocument Title="Document 1">
                            <WindowsFormsHost>
                                <wf:TextBox BackColor="Red" Text="TextBox is in WindowsFormsHost" />
                            </WindowsFormsHost>
                        </avalonDock:LayoutDocument>
                    </avalonDock:LayoutDocumentPane>
                    <avalonDock:LayoutAnchorablePane DockWidth="150">
                        <avalonDock:LayoutAnchorable Title="Sample Tool Pane">
                            <TextBox/>
                        </avalonDock:LayoutAnchorable>
                        <avalonDock:LayoutAnchorable x:Name="toolWindow" Title="Another Sample Tool Pane">
                            <!--<TextBox/>-->
                            <WindowsFormsHost>
                                <wf:TextBox BackColor="Red" Text="TextBox is in WindowsFormsHost" />
                            </WindowsFormsHost>
                        </avalonDock:LayoutAnchorable>
                    </avalonDock:LayoutAnchorablePane>
                </avalonDock:LayoutPanel>
                <avalonDock:LayoutRoot.LeftSide>
                    <avalonDock:LayoutAnchorSide>
                        <avalonDock:LayoutAnchorGroup>
                            <avalonDock:LayoutAnchorable Title="Autohidden Content">
                                <TextBox/>
                            </avalonDock:LayoutAnchorable>
                        </avalonDock:LayoutAnchorGroup>
                    </avalonDock:LayoutAnchorSide>
                </avalonDock:LayoutRoot.LeftSide>
            </avalonDock:LayoutRoot>
        </avalonDock:DockingManager>
    </Grid>
</Window>

 And the code-behind with the event that is always fired:

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.toolWindow.IsActiveChanged += toolWindow_IsActiveChanged;
        }

        void toolWindow_IsActiveChanged(object sender, EventArgs e)
        {
            Debug.WriteLine("toolwindow is active: " + this.toolWindow.IsActive);
        }

      
    }

 

I was also interested in what the guys from AvalonDock are doing to get all the events even with the WindowsFormsHost.

The solution can be found in the source file WindowHookHandler.cs and in the extern method "SetWindowsHookEx" from user32.dll.

[Modified 7 years ago]

Posted 7 years ago by P. Chwoika - Inosoft GmbH
Avatar

Hi,

any news on this topic from your side? Since this thing is quite urgent for us and we own the Blue License of the WPFStudio, I implemented a quick bugfix for your DockingManger. Now there are no more problems with the WindowFormsHost and the DockSite Events are fired all the time :)

My quick fix looks for HwndHost objects in the Docksite when they are registered (RegisterDockingWindow). Then it uses the MessageHook event to get the specific focus/activated events:

IntPtr host_MessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == (int)WM.SETFOCUS || msg == (int)WM.ACTIVATE || msg == (int)WM.MOUSEACTIVATE)
{

In this event handler I can easily set the active Window (which is the parent of the HwndHost) and everything works fine.

 

Even though this now works we can only see this as a temporary fix for the problem. We actually do not want to build the ActiproSoftware.Docking.Wpf.dll ourselves. It would be really great if you could include the fix I implemented quickly in the next maintenance release!

Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello, I'm sorry but we've been tied up trying to finish the 2013.1 version and haven't had a chance to look at their implementation as of yet.  If you want us to possibly get it in for the next release, it would help if you e-mail over the updates you did to our product.  That way we can get an idea for the concept of what needs to be done.  It would also help if you could make a new simple sample project that shows it working once the changes are made, and we will use it to test.  Please rename the .zip file extension you send so it doesn't get spam blocked.   Thanks!


Actipro Software Support

Posted 7 years ago by P. Chwoika - Inosoft GmbH
Avatar

Hello!

I just mailed the changed source files and a sample project to your support address.

Hope this helps :)

Posted 5 years ago by Reed Copsey
Avatar

Are there plans to implement this, or a similar fix?

 

We're running into the exact same issue, and it's incredibly difficult to work around, especially as we don't have source/can't rebuild the core libs...

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Reed,

Have you tried adding docking:InteropFocusTracking.IsEnabled="True" on your WindowsFormsHost?  That is something we added in recent versions that helps in general with issues in this area.


Actipro Software Support

Posted 5 years ago by Reed Copsey
Avatar

Thanks!  I didn't realize that was in.


So, I added that, and it almost works correctly now.  Clicking in one of the HwndHost based documents does immediately raise WindowActivated on the DockSite, but it's not actually "selecting" (visually) the appropriate docking window.  A 2nd mouse click seems to cause the window to become selected visually.

So - from a functionality standpoint, the attached property seems to solve the issue, but there's a visual disconnect still.  I've tried hooking into WindowActivated and putting a call into Window.Activate(true) and Window.Activate(false) - neither seems to have any effect.

What's odd is that, in the Window.Activated event, the DockSite shows the correct active window, but visually, it's still "disabled".  A second mouse click in the HwndHost "activates" it correctly.

-Reed

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Reed,

If you would like us to look into it further, please put together a simple sample that shows the issue and email that to our support address.  Reference this thread in your email and rename the .zip file extension so it doesn't get spam blocked.  Then we'll have a look at that and see what's going on.  Thanks!


Actipro Software Support

Posted 5 years ago by Reed Copsey
Avatar

I just submitted a full reproduction as a ticket (29F-1B88FD37-0401) - Hopefully that will suffice.

 

Let me know if you have any questions reproducing - it should be very self-explanatory.

 

-Reed

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Reed,

Thanks for the sample.  Most of our active tab highlighting is based on where focus is.  The WPF WebBrowser you are using in the sample is notoriously bad for tracking focus, and remarkably even worse than interoping the WinForms WebBrowser!  We spent a long time on all this in the past when enhancing the InteropFocusTracking class.  To sum up, we were never able to find any tricks to properly catch focus changes in relation to the WPF WebBrowser because the Windows messages it publishes don't make sense.  Back then, we were able to get our InteropFocusTracking class to properly handle the WinForms WebBrowser though.

So this sort of code will work fine:

<WindowsFormsHost docking:InteropFocusTracking.IsEnabled="True">
	<winforms:WebBrowser x:Name="browser1" />
</WindowsFormsHost>

I would recommend you switch over to that to avoid any problems.


Actipro Software Support

Posted 5 years ago by Reed Copsey
Avatar

So - the problem is I'm actually using a custom HwndHost (that contains OpenGL rendering).  The WPF Webbrowser was just a good reproduction as it shows the same behaivor.

 

The thing I don't understand is you're obviously already catching it correctly, even with the WPF Webbrowser, as the WindowActivated event does fire immediately.  It's only the visual that lags behind.  See the repro - the events happen and show up in the text box - so you're catching it internally now.

 

On a side node - I had found that, for the most part, WM_PARENTNOTIFY messages seem to be a very good place to catch this - everything that should gain focus sends a WM_PARENTNOTIFY message, as far as I can tell....

 

-Reed

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

HI Reed,

We did another long debugging session with this and found that our existing InteropFocusTracking code is already handling the scenario great.  We track several Windows API messages that come to the HwndHost to know when to refresh the UI (the tab highlights).  One of them is WM_MOUSEACTIVATE.  The problem is that if we call our UI refresh code immediately in that message handler, core WPF hasn't fully updated its own focus tracking info yet, so things can get off with certain interop controls.  That's why clicking a second time would get the highlights to show, since by that time, WPF's focus tracking had caught up.

We changed code to delay the logic that runs when WM_MOUSEACTIVATE occurs.  The good news is that seems to resolve the issue in your sample.  Now clicking on either WebBrowser highlights the related tab immediately.  This update will be in the next version.


Actipro Software Support

Posted 5 years ago by Reed Copsey
Avatar

Glad to hear you managed to improve this.  Thanks!

 

What is the estimated time frame for the next build?  We'd like to plan so we can determine our proper response to our customers.

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Reed,

We hope to have it out in the next several weeks (mid September).


Actipro Software Support

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.