Quantcast
Channel: Windows Presentation Foundation (WPF) forum
Viewing all articles
Browse latest Browse all 18858

How to automatically put the focus on a WPF WebBrowser object in design mode

$
0
0
Hi, I'm trying to write a simple HTML editor. As a test project, the application is very simple. It hosts a single WebBrowser control in a grid.

 
<Window x:Class="WebBrowser.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300" 
        Loaded="Window_Loaded" Activated="Window_Activated">  
    <Grid> 
        <WebBrowser Name="WB" IsVisibleChanged="WB_IsVisibleChanged"/>  
    </Grid> 
</Window> 
 


I'd like the web browser object to have focus at all times: When the application starts and also whenever the application becomes active (by switching from another app). So I put event handlers at various locations: on Loaded, on Activated and on VisibilityChanged.

        private void Window_Loaded(object sender, RoutedEventArgs e)  
        {  
            WB.NavigateToString("<HTML>Hello</HTML>");  
 
            IHTMLDocument2 doc2 = (IHTMLDocument2) WB.Document;  
            doc2.designMode = "On";  
 
            SetFocus();  
        }  
 

Loaded is also when I switch the control to design mode.

Then 

        private void Window_Activated(object sender, EventArgs e)  
        {  
            SetFocus();  
        }  
 
        private void WB_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)  
        {  
            if (WB.IsVisible)  
            {  
                SetFocus();  
            }  
        }  
 
 

First, I tried to implement SetFocus() as a call to WB.SetFocus(), but I got an System.ExecutionEngineException.
Instead, I call focus() on the browser.

        private void SetFocus()  
        {  
            // This throws System.ExecutionEngineException  
            // WB.Focus();  
 
            IHTMLDocument4 doc4 = (IHTMLDocument4)WB.Document;  
            if (doc4 != null)  
            {  
                doc4.focus();  
                Debug.Print("focus {0}", doc4.hasFocus());  
            }  
        }  
 

It doesn't work. The focus is not on the editor as startup. I can click on the main window and write things, but the focus is lost when I go to another window and come back.

With SPY++, I noticed that on window activation, the SetFocus() function transfers the focus to the web browser but then it is taken back by the WPF main window.

Then I added a hook to intercept any WM_FOCUS message. It's brutal and I'd rather not do this even.

        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)  
        {  
            const int WM_SETFOCUS = 0x0007;  
 
            switch (msg)  
            {  
                case WM_SETFOCUS:  
                    SetFocus();  
                    handled = true;  
                    break;  
            }  
 
            return IntPtr.Zero;  
        }  
 

and added 

            HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);  
            source.AddHook(WndProc);  
 


to Window_Loaded.

Now the focus is given to the web browser control when I switch from another app, but not at startup.

It seems like it is because SetFocus() is called before the web browser is fully materialized. SetFocus() is called but hasFocus remains false. At startup, the Debugger Output shows

focus False

When I switch from another app, I see

focus True

I tried putting several SetFocus() calls at different places during the setup but I can't make it to work.

Do you have a recommendation?

Thanks,
--h



Viewing all articles
Browse latest Browse all 18858

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>