Home > .net 3.5, c#, Visual Studio 2008, Windows Vista, Workplace > Flash and Proxy Support on .NET WebBrowser Controls – Part II

Flash and Proxy Support on .NET WebBrowser Controls – Part II

January 4, 2008

Yesterday, I created a quick Windows Forms application that used an “EnhancedWebBrowser” control to render Flash content and accept proxy server settings on the fly.  As promised, I separated out the control from the project and placed the responsibility for controlling proxy settings back onto the browser control.

If you haven’t read Part I, please do so; it’ll provide the “storyline” for the project. 🙂

Download the Source Code: .NET 3.5

The source code download includes three projects: the EnhancedWebBrowser forms control, Pandora’s Proxy, my “example” project for using Pandora Music Service and the EnhancedWebBrowser, and the setup project for Pandora’s Proxy—since it’s a Windows Forms app.

Note: This project is for demonstration purposes only and does not represent functionality of Pandora or the Music Genome Project.

Extracting the EnhancedWebBrowser (EWB) Control

The “FlashWebBrowser” control name is a bit obsolete now that it does more than that (with proxy support)… a good test of how important object naming can be.  I’m sure, down the road, I may regret EnhancedWebBrowser, but for demo purposes, it works. 🙂

Our override of WndProc from yesterday is about the only change that remains of our EWB control—to pull off proxy support in the custom control, we’ll need a public property, another override, and some major changes to our RefreshIESettings method.

Let’s start with our public property.  Since we’re developing in .NET 3.5, we’ll use one of the more useful features: automatic properties.

[Description(“Gets or sets the proxy server and port for this instance of the WebBrowser control.  Should be in the format of server:port.”)]

public string ProxyServer { get; set; }

That’s easy enough.

Our next step is to set the proxy server settings on the WebBrowser control.  Yesterday, we called this as part of the Load method—which simply applied the settings prior to the WebBrowser.Navigate call.  Since we’re baking this functionality INTO the WebBrowser, we have a bit more control now and can inject the logic directly into Navigate.  This is done by overriding the OnNavigating method.

protected override void OnNavigating(WebBrowserNavigatingEventArgs e)

{

SetProxyServer(ProxyServer);

       base.OnNavigating(e);

}

The new method (well, renamed method) for setting our proxy settings is SetProxyServer.  I could refactor out everything and simply get back to the basics of SetInternetSettings or something, but I’ll leave that as a TODO at this point.

public void SetProxyServer(string proxyServerAddress)

{

const int INTERNET_OPTION_PROXY = 38;

       const int INTERNET_OPEN_TYPE_PROXY = 3;

       const int INTERNET_OPEN_TYPE_DIRECT = 1;

 

INTERNET_PROXY_INFO struct_IPI;

In the first few lines, you’ll notice a new constant, INTERNET_OPEN_TYPE_DIRECT.  Our old method could set the proxy, but couldn’t “unset” or disable it.  This constant allows us the option to disable the proxy settings if so desired.  We’ll use this later on.

// Filling in structure

if (proxyServerAddress == “”)

{

       // Clear any proxy settings and go “direct” to the Internet.

struct_IPI.dwAccessType = INTERNET_OPEN_TYPE_DIRECT;

       struct_IPI.proxy = IntPtr.Zero;

       struct_IPI.proxyBypass = IntPtr.Zero;

}

else

      

       // Assign the specified proxy server and port to

// access the Internet. This supports only

// anonymous proxy servers; support for authentication

// coming in the future.

       struct_IPI.dwAccessType = INTERNET_OPEN_TYPE_PROXY;

       struct_IPI.proxy = Marshal.StringToHGlobalAnsi(proxyServerAddress);

       struct_IPI.proxyBypass = Marshal.StringToHGlobalAnsi(“local”);

}

 

 

Following our constants, we have our logic that toggles the proxy settings on and off.  I kept the comments in the code to clarify what is occuring.

 

// Allocating memory

IntPtr intptrStruct =

Marshal.AllocCoTaskMem(Marshal.SizeOf(struct_IPI));

 

// Converting structure to IntPtr

Marshal.StructureToPtr(struct_IPI, intptrStruct, true);

 

bool iReturn = InternetSetOption(IntPtr.Zero,

INTERNET_OPTION_PROXY,

intptrStruct,

Marshal.SizeOf(struct_IPI));

}

The remaining code (above) remains the same, as does our output.  A quick way to verify is to set a breakpoint at the iReturn—if iReturn is true, then the settings were applied successfully; false then an error occured.

 

That’s it!  That pulls the EWB control out of our project and into a library of its own and adds the proxy support directly into the object.

 

Using the EnhancedWebBrowser

 

After adding a reference to our new library and a quick using statement, we’re ready to start using our EWB.  The only line of code that we need to change is our private variable—the FlashWebBrowser should be EnhancedWebBrowser.

 

private EnhancedWebBrowser enhancedBrowser = new EnhancedWebBrowser();

At this point, you have two options: you can manually assign the EWB control a proxy server with:

 

enhancedBrowser.ProxyServer = “myproxy.server:81”;

or, what I did with the Pandora’s Proxy application, place the proxy settings in the User Settings—allowing the user to control the proxy setting.  Since .NET 2.0, user and application settings are easier than ever!

 

enhancedBrowser.ProxyServer = Properties.Settings.Default.ProxyServer;

 

Project settings are managed through the project’s properties > Settings tab.  For more information on the Settings capabilities within .NET, read this article on MSDN.  Unfortunately, the article still targets .NET 2.0; however, I haven’t seen a difference with VS2008 and .NET 3.5.

 

To couple with the ability to manage our proxy setting in user settings, I built up a quick Options form—a text box, button, and a label that saves the user input back into the user settings.  That form is also included in the project, but not required—as I mentioned, you could simply hardcode the setting in, it just depends on usage.

 

What I’ve Learned…

 

Without going into too much boring detail, I’d like to point out that my last “real” forms-based development was VB6–-and that was for prototyping in a theory class for my associate’s degree.  Before that, I did some forms work in VB3.  Yeah, 3.0.  Remember Windows 3.11?  Good times.

 

Since then, I’ve been a web guy.  I love the “reach” of web applications and, with things like AJAX and Flash, the UI capabilities of the web are AMAZING.  The proof is that this entire venture (of encapsulating Pandora in a window of it’s own) speaks volumes to that—years ago, we were trying to run desktop applications in our web browser!

 

But, this project has been fun and no learning ever goes to waste.  I have a better appreciation for some of the “freebies” that we get in the web (we design forms, but the fact that they exist and their show/hide state is the browser’s responsibility), but liked having the design-time control for placement and that, inspite of resolutions and fonts, I copied the app to my XP laptop and it worked like a champ.

 

All in all, a cool venture and learning experience in the Windows Forms arena—giving me another option to look at (more seriously) when designing applications that may not NEED to be web tools. 🙂

kick it on DotNetKicks.com

  1. January 25, 2008 at 5:23 pm

    Good scoop!

  2. a ossoble
    December 7, 2008 at 6:10 pm

    I’ve found a much easier way to use a proxy.

    proxy = new WebProxy(ProxyAddress, Port);
    proxy.Credentials = new NetworkCredential(Username, Password);

    Use that to create a proxy; then use


    webBrowser1.Navigate(proxy.GetProxy(Url));

    This method is much easier to use and requires such little effort it’s amazing.
    All that interop is not really needed. Microsoft made something easy for once.

  3. March 4, 2009 at 1:16 am

    I’m a little befuddled by the above suggestion by “a ossoble”. The suggested method is merely going to navigate to the proxy address ITSELF. Proxy.GetProxy() method only returns the Uri of the proxy, if the proxy will be used for the request, ie if the Url is not on the bypass list. It’s all there in the documentation.

  4. May 21, 2009 at 7:33 pm

    Nice blog post, a good read, i’ll be bookmarking this.

  1. May 21, 2008 at 10:25 pm
Comments are closed.