Odeslat dotazOdeslat dotaz
 

Obecná diskuseTip: Fix WebBrowser visibilty Issue

  • 11. listopadu 2008 13:28Frankenspank Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    There is a bug in the WebBrowser WPF control where it will not show up when Window.AllowTransparency is true.

    Add the following to your window:

            protected override void OnSourceInitialized(EventArgs e)
            {
                base.OnSourceInitialized(e);
                IntPtr hWnd = new WindowInteropHelper(this).Handle;
                int hresult = Win32.SetWindowLong(hWnd, Win32.GWL_STYLE, Win32.WS_POPUP | Win32.WS_CLIPCHILDREN);

            }


    public class Win32
    {
            public const int GWL_EXSTYLE      =    (-20);
            public const int GWL_STYLE = -16;
            public const long WS_POPUP   =  0x80000000L;
            public const long WS_CLIPCHILDREN    =   0x02000000L;

            [DllImport("user32.dll" , CharSet = CharSet.Auto)]
            public static extern int SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong);

    }

Všechny reakce

  • 23. dubna 2009 5:57QuddusAli Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Obsahuje kód
    Hi Frank,
                I have added the code but i cant get it to work:

    Imports System
    Imports System.IO
    Imports System.Net
    Imports System.Windows
    Imports System.Windows.Controls
    Imports System.Windows.Data
    Imports System.Windows.Media
    Imports System.Windows.Media.Animation
    Imports System.Windows.Navigation
    
    Imports System.Runtime.InteropServices
    Imports System.Windows.Interop
    
    Partial Public Class Window1
        Public Sub New()
            MyBase.New()
    
            Me.InitializeComponent()
    
            ' Insert code required on object creation below this point.
        End Sub
    
        Private Sub NavButton_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles NavButton.Click
    
            WebBrowser.Navigate(New Uri("http://www.bl.uk/news/pdf/googlegen.pdf"))
    
    
    
        End Sub
    
        Protected Overloads Overrides Sub OnSourceInitialized(ByVal e As EventArgs)
            MyBase.OnSourceInitialized(e)
            Dim hWnd As IntPtr = New WindowInteropHelper(Me).Handle
    
            Dim hresult As Integer = Win32.SetWindowLong(hWnd, Win32.GWL_STYLE, Win32.WS_POPUP Or Win32.WS_CLIPCHILDREN)
        End Sub
    
    End Class
    
    Public Class Win32
        Public Const GWL_EXSTYLE As Integer = (-20)
        Public Const GWL_STYLE As Integer = -16
        Public Const WS_POPUP As Long = 2147483648L
        Public Const WS_CLIPCHILDREN As Long = 33554432L
    
        <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
        Public Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As Long) As Integer
        End Function
    End Class
    
    When i click the button - the browser doesnt show up.

    Can you help?
  • 27. dubna 2009 19:43Frankenspank Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Obsahuje kód
    Is the browser visible before you click the button?

    You can also check the HRESULT when you call SetWindowLong and look up the code.  If it isn't 0, then look it up in Winerror.h.  You can find it in the platform SDK, or here: http://msdn.microsoft.com/en-us/library/ms819772.aspx.

  • 28. dubna 2009 7:48QuddusAli Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    Hi. The browser isnt visible before i click the button.
  • 28. dubna 2009 18:22Frankenspank Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Obsahuje kód
    What do you get here (what is the value of hresult)?

     Dim
    
     hresult As
    
     Integer
    
     = Win32.SetWindowLong(hWnd, Win32.GWL_STYLE, Win32.WS_POPUP Or
    
     Win32.WS_CLIPCHILDREN)
  • 28. dubna 2009 18:35QuddusAli Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    114229248
  • 28. dubna 2009 21:24Frankenspank Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    Well the API failed, so you'll need to backtrack and check that everything before that is happening as it should be.
  • 28. dubna 2009 21:27QuddusAli Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    Thanks
  • 30. června 2009 5:27brental Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    I am attempting to implement this fix, but it is not working for me. I have attempted to look up the hresult code that I get back from the call to SetWindowLong in Winerror.h, but I am unable to find it.  Can anyone help in this regard? I am using the code exactly as per the original post and the hresult I am getting is 101646336.
    • Upravenýbrental 30. června 2009 5:34
    •  
  • 30. června 2009 15:52Frankenspank Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    Did you get a valid hwnd back?

    Here is why properties I have set for my window if this helps at all:

    <Setter Property="AllowsTransparency" Value="True" />
    <Setter Property="WindowStyle" Value="None" />
  • 3. července 2009 1:29brental Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Obsahuje kód

    Thanks for getting back to me on this Frankenspank

    I am a bit confused about the meaning of the hresult that is getting returned when I call SetWindowLong.  In one of the posts above you state that if the hresult is NOT 0 then look up the error code.  So, I thought that the fact that it is returning 101646336 meant that an error was occurring.  However, from reading more on the SetWindowLong method it is actually if it returns 0 that an error has occurred, and if it returns a number (such as 101646336 that I am getting) then it has succeeded (I read this here: http://msdn.microsoft.com/en-us/library/ms633591(VS.85).aspx).  So, if that is the case, then it looks like the SetWindowLong method is executing correctly.  This is further backed up by the fact that I call Marshal.GetLastWin32Error after the SetWindowLong method and dont get any error code back.

    However, this does not solve my problem as even though the SetWindowLong method is executing correctly the WebBrowser control still remains invisible.  I am fairly sure that I am getting a valid hwnd back so I will give a bit more information on the application.  Basically I have created a brand new WPF application and haven't modified anything besides the XAML of Window1 and the code behind that window.  Here is the XAML of Window1:

    <Window x:Class="WpfApplication1.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" AllowsTransparency="True" WindowStyle="None">
        <StackPanel>
            <WebBrowser Name="wbTest" Source="http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/17fc75f6-db97-43ef-8ce5-f1aecaa15f86" Height="240"></WebBrowser>
            <Button Name="btnBrowse" Click="btnBrowse_Click" Height="20"></Button>
        </StackPanel>
    </Window>
    
    And here is the code behind Window1:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    using System.Windows.Interop;
    using System.Runtime.InteropServices;
    
    namespace WpfApplication1
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
    
            protected override void OnSourceInitialized(EventArgs e)
            {
                base.OnSourceInitialized(e);
                IntPtr hWnd = new WindowInteropHelper(this).Handle;
                int hresult = Win32.SetWindowLong(hWnd, Win32.GWL_STYLE, Win32.WS_POPUP | Win32.WS_CLIPCHILDREN);
    
                int lastError = Marshal.GetLastWin32Error();
            }
    
            private void btnBrowse_Click(object sender, RoutedEventArgs e)
            {
                wbTest.Navigate(new Uri("http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/17fc75f6-db97-43ef-8ce5-f1aecaa15f86"));
            }
        }
    
        public class Win32
        {
            public const int GWL_EXSTYLE = (-20);
            public const int GWL_STYLE = (-16);
            public const long WS_POPUP = 0x80000000L;
            public const long WS_CLIPCHILDREN = 0x02000000L;
    
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern int SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong);
        }
    }
    
    

    Any other thoughts on what could be going wrong?
  • 6. července 2009 5:35Sean Yao Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Obsahuje kód

    Thanks for getting back to me on this Frankenspank

    I am a bit confused about the meaning of the hresult that is getting returned when I call SetWindowLong.  In one of the posts above you state that if the hresult is NOT 0 then look up the error code.  So, I thought that the fact that it is returning 101646336 meant that an error was occurring.  However, from reading more on the SetWindowLong method it is actually if it returns 0 that an error has occurred, and if it returns a number (such as 101646336 that I am getting) then it has succeeded (I read this here: http://msdn.microsoft.com/en-us/library/ms633591(VS.85).aspx).  So, if that is the case, then it looks like the SetWindowLong method is executing correctly.  This is further backed up by the fact that I call Marshal.GetLastWin32Error after the SetWindowLong method and dont get any error code back.

    However, this does not solve my problem as even though the SetWindowLong method is executing correctly the WebBrowser control still remains invisible.  I am fairly sure that I am getting a valid hwnd back so I will give a bit more information on the application.  Basically I have created a brand new WPF application and haven't modified anything besides the XAML of Window1 and the code behind that window.  Here is the XAML of Window1:

    <Window x:Class="WpfApplication1.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" AllowsTransparency="True" WindowStyle="None">
        <StackPanel>
            <WebBrowser Name="wbTest" Source="http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/17fc75f6-db97-43ef-8ce5-f1aecaa15f86" Height="240"></WebBrowser>
            <Button Name="btnBrowse" Click="btnBrowse_Click" Height="20"></Button>
        </StackPanel>
    </Window>
    
    And here is the code behind Window1:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    using System.Windows.Interop;
    using System.Runtime.InteropServices;
    
    namespace WpfApplication1
    {
        /// <summary>
    
        /// Interaction logic for Window1.xaml
    
        /// </summary>
    
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
    
            protected override void OnSourceInitialized(EventArgs e)
            {
                base.OnSourceInitialized(e);
                IntPtr hWnd = new WindowInteropHelper(this).Handle;
                int hresult = Win32.SetWindowLong(hWnd, Win32.GWL_STYLE, Win32.WS_POPUP | Win32.WS_CLIPCHILDREN);
    
                int lastError = Marshal.GetLastWin32Error();
            }
    
            private void btnBrowse_Click(object sender, RoutedEventArgs e)
            {
                wbTest.Navigate(new Uri("http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/17fc75f6-db97-43ef-8ce5-f1aecaa15f86"));
            }
        }
    
        public class Win32
        {
            public const int GWL_EXSTYLE = (-20);
            public const int GWL_STYLE = (-16);
            public const long WS_POPUP = 0x80000000L;
            public const long WS_CLIPCHILDREN = 0x02000000L;
    
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern int SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong);
        }
    }
    
    

    Any other thoughts on what could be going wrong?

    Anybody have suggestion on this? I encountered the same problem after the method "SetWindowLong" executed correctly.


    Sean
  • 8. července 2009 3:19brental Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     

    I managed to find another fix to this issue (outlined here http://blogs.msdn.com/changov/archive/2009/01/19/webbrowser-control-on-transparent-wpf-window.aspx) but other issues arise in this fix, so I am still looking for some advice on how to properly implement the fix outlined in this thread.