Tip: Fix WebBrowser visibilty Issue
- 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);
}
All Replies
- Hi Frank,
I have added the code but i cant get it to work:
When i click the button - the browser doesnt show up.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
Can you help? - 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.
- Hi. The browser isnt visible before i click the button.
- 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)
- 114229248
- Well the API failed, so you'll need to backtrack and check that everything before that is happening as it should be.
- Thanks
- 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.
- Edited bybrental Tuesday, June 30, 2009 5:34 AM
- 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" /> 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:And here is the code behind 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>
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?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:And here is the code behind 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>
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.
SeanI 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.


