Displaying embedded web pages in Winforms

I had an application/plugin I wanted to display some license information in and also attribute my use of a public API. So, I figured a nice way to do that would be to drop a web browser control in my winform and then have an embedded resource as the content. So, I created a little webpage and set it’s Build Action to Embedded Resource. A tiny bit of css in the head section and it looked good.

But, I wanted to also display an image in there. I tried a few different ways, but eventually stumbled upon an answer on stackoverflow which suggested encoding the image as a Base64 string. So, I set to work creating a little helper method to load my embedded web page and automatically encode all images on it. I decided to go with using a placeholder to the image, like so …

%IMG("MyProgram.Images.logo.png")%

In order to find out the name of the resource, you may find running this little piece of code helpful …

var names = Assembly.GetExecutingAssembly().GetManifestResourceNames();

So, I used a little regex magic (courtesey of regexhero.net) to find those placeholders, extract the path and do the encoding for me.

    public static class EmbeddedWebPageLoader
    {
        public static string LoadWebPage(string name)
        {
            const string regexPattern = @"%IMG\(\""(?<ImagePath>[^\""]*)\""\)%";
            var assembly = Assembly.GetExecutingAssembly();
            var pageStream = assembly.GetManifestResourceStream(name);
            if (pageStream != null)
            {
                using (var webPageStreamReader = new StreamReader(pageStream))
                {
                    var pageContent = webPageStreamReader.ReadToEnd();
                    var matches = Regex.Matches(pageContent, regexPattern);
                    foreach (Match match in matches)
                    {
                        var imagePath = match.Groups["ImagePath"];
                        var extension = Path.GetExtension(imagePath.Value).Trim(".".ToCharArray());
                        var imageStream = assembly.GetManifestResourceStream(imagePath.Value);
                        if (imageStream != null)
                        {
                            var buffer = new byte[imageStream.Length];
                            imageStream.Read(buffer, 0, (int) imageStream.Length);
                            var imageBase64String = Convert.ToBase64String(buffer);
                            var imgTag = string.Format("<img src='data:image/{0};base64,{1}'/>", extension, imageBase64String);

                            pageContent = Regex.Replace(pageContent, regexPattern, imgTag);
                        }
                    }
                    return pageContent;
                }
            }
            return null;
        }
    }

It works like a dream, I can now use images inside my about box, like so …

webBrowser.DocumentText = EmbeddedWebPageLoader.LoadWebPage("MyProgram.About.html");
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s