Exploring the depths and potentials of ASP.NET RSS 2.0 or Subscribe to .BenRush by Email
 Sunday, July 15, 2007

Source: http://msdn.microsoft.com/msdnmag/issues/07/06/silverlight/default.aspx

 

1.       Introduction.

a.       Currently supports Mac OSX Safari and FireFox, Windows FireFox and IE

b.      Can be interacted with by AJAX code.

2.       Introducing Silverlight

a.       XAML is text-based and exposes it’s DOM to the browser in a scriptable manner (therefore, it is “functional”).

b.      The browser loads the XAML and creates a DOM that can be interacted with via script code, including modifications by script and event handling/processing.  You may also interact with the XAML DOM through methods (such as methods that start playing, stop playing or pause a presentation).

3.       XAML Overview

a.       XAML was first introduced as part of Windows Presentation Foundation; though the XAML used by Silverlight is a web-based subset of the full XAML supported by WPF.

b.      Silverlight XAML markup is based on the <canvas> tag; the “surface” upon which objects will be drawn.

4.       Inside the XAML

a.       There is support for pre-defined shapes, gradients, etc.

5.        Transformations, Media, and Animations

a.       XAML has built in support for transformations on objects (MatrixTransform, RotationTransform, ScaleTransform, etc).

b.      MediaElement tag controls video and audio.

c.       Animations are defined in XAML by how properties change with time.

6.       A simple silverlight application

a.       Currently silverlight.js is required to be located within the /js folder for your web application.

b.      Sys.Silverlight.createObjectEx() implements a new silverlight control.

c.       The silverlight plugin loads into a DIV tag with a unique ID.

d.      Dynamic features can be added to the Silverlight application (such as the source for a particular video) but modifying the script that controls and instantiates the objects through the ASPX page’s rendered output.

7.       Delivering XAML to the Silverlight Front-End

a.       The server can process and build the XAML as needed; the Sys.Silverlight.createObjectEx() method simply takes this markup to load and instantiate the XAML as a silverlight object.           


kick it on DotNetKicks.com
Sunday, July 15, 2007 3:48:07 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
.Net Runtime | AJAX | ASP.Net | JavaScript | MSDN Notes | WinForms and WPF
 Wednesday, April 04, 2007

Say you want to use the browser component to automate some form of web browser experience - for example, say you want to programmatically enter some value into a textbox and click a button using C# or VB.Net. To do this is actually quite simple (and, dare we say it, fun).

First, you simply add your browser component to your windows form.

Second, you register an event handler with the browser component for the DocumentCompleted event:

            this.webBrowser1.Url = new Uri("http://www.google.com");
            this.webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);

Third, you fill in the event handler with something that looks like this:

        void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (!_clicked)
            {
                _clicked = true;

                HtmlElement queryBox = this.webBrowser1.Document.All["q"];
                queryBox.SetAttribute("value", "hello world");

                HtmlElement goButton = this.webBrowser1.Document.All["btnG"];
                goButton.InvokeMember("click");
            }

            return;
        }

This will load the www.google.com homepage, fill in their submit text box and click the Search button.

In the golden days of MSHTML component reuse (before the niceness of .Net'ifying the browser DOM) you had to use a RCW (Runtime Callable Wrapper) around the MSHTML COM library. Everything is obviously implemented through IDispatch here (because you have to be able to do this stuff from VB6 or scripting environments), and so much of the invocation of methods (like click) was done by loosly picking the name for the method and building the stack frame through arrays, etc. The RCW made things a bit nicer for you (you didn't have to think about IDispatch), but you still had to think about COM.

It's been years since I've developed in COM and ATL and I'm glad I don't have to anymore.

Recommended reading:


kick it on DotNetKicks.com
Wednesday, April 04, 2007 10:55:24 AM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Programming | WinForms and WPF
 Monday, March 26, 2007

I was helping someone out on the newsgroups who wanted to draw a GIF from his ASP.Net web page; one of the requirements was that it had a transparent background. As it turns out, this little exercise is a bit more complicated than it at first seems due to - what I think - is either a bug or an anomaly in the GDI+ framework.

First - a bit of education. GIF is an indexed image format, meaning that it uses a color palette and individual pixels reference a color by indexing into the palette. One of the "colors" in the palette is a non-color or transparent; a transparent color is anything with an alpha value of 0 (ie both 0-255-255-255 and 0-128-128-128 are "invisible" where the first digit represents the value of the alpha octet).

Interestingly, the .Net runtime's GDI+ Graphics.FromImage() method DOES NOT like indexed file formats, so if you want to draw onto a GIF using the GDI+ framework, it cannot be done via this method. It's screwy; don't ask me why it is this way. Well, this guy wanted to draw text onto a GIF with a transparent background, so....how to you go about drawing text onto a GIF with a transparent background?

My first thought was modifying the palette so that all references to, say, black had an alpha transparency level of 0 - meaning invisible. What this would mean is that anything that referenced a black index into the color palette wouldn't be visible (100% alpha value). Another interesting "quirk" of the .Net runtime GDI+ framework, however, is that whenever you save the data to a stream (file, memory stream, output stream, etc) it will screw with the color palette. I didn't really try to understand what it was doing, but if you look at the color palette in a debugger window while using it, the save method just toys with it and mucks up your mods to it.

So...the only option, lock down the data, and reference each individual pixel in the image, pointing it to the entry in the GIFs color palette for a transparent color instead of black. And it worked....here is the code (implemented as a C# library that you may use freely - please be mindful that I have not tested this but for just a little bit, there may be resource leaks, etc):

public class TransparentGif
{
 public TransparentGif()
 {
 }
    public static MemoryStream DrawTransparentGif(
        String text, Color textColor, Int32 width, Int32 height)
    {
        Bitmap drawableBMP = new Bitmap(width, height);
        Graphics gdc = Graphics.FromImage(drawableBMP);
        try
        {
            gdc.FillRectangle(new SolidBrush(Color.Black), new Rectangle(0, 0, width, height));
            gdc.DrawString(text, new Font("Arial", 13), new SolidBrush(textColor), 0, 0);
            MemoryStream memStream = new MemoryStream();
            drawableBMP.Save(memStream, ImageFormat.Gif);

            memStream.Seek(0, SeekOrigin.Begin);
            System.Drawing.Image gifed = System.Drawing.Image.FromStream(memStream);

            ColorPalette cp = gifed.Palette;
            Int32 alpha = 0;
            for (Int32 c = 0; c < cp.Entries.Length; c++)
            {
                if (cp.Entries[c].A == 0)
                {
                    alpha = c;
                     break;
                }
            }

            BitmapData data = ((Bitmap)gifed).LockBits(
    new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, gifed.PixelFormat);

            Byte[] buffer = new Byte[width* height];
            Marshal.Copy(data.Scan0, buffer, 0, width* height);

            for (Int32 c = 0; c < buffer.Length; c++)
            {
                if (cp.Entries[buffer[c]].ToArgb() == Color.Black.ToArgb())
                {
                    buffer[c] = (Byte)alpha;
                }
            }

            Marshal.Copy(buffer, 0, data.Scan0, buffer.Length);

            ((Bitmap)gifed).UnlockBits(data);

            MemoryStream outStream = new MemoryStream();
            gifed.Save(outStream, ImageFormat.Gif);
            outStream.Seek(0, SeekOrigin.Begin);

            return outStream;
        }
        finally
        {
            if (gdc != null)
                gdc.Dispose();
        }
    }
}

If you comment out the actual pixel manipulation, what gets drawn to my web page is the following:

...or a GIF with a black background. If you bring back in the actual pixel manipulation part of the above code, you get this:

Total alpha transparency of the GIF....

Addendum:

For an example of using this class, see here.

Recommended reading:

kick it on DotNetKicks.com
Monday, March 26, 2007 12:19:27 PM (Central Standard Time, UTC-06:00)  #    Comments [1] - Trackback
ASP.Net | Programming | WinForms and WPF
 Saturday, March 24, 2007

The following C# code will programmatically scroll the browser window. The steps are easy.

First, add your web browser control to the form.

Second, add an event handler for the document completed event:

        private void Form1_Load(object sender, EventArgs e)
        {
            this.webBrowser1.Url = new Uri("
http://news.google.com");
            HtmlDocument doc = this.webBrowser1.Document;
            this.webBrowser1.DocumentCompleted +=
                new WebBrowserDocumentCompletedEventHandler(
                  
webBrowser1_DocumentCompleted);
        }

Third, fill in the event handler:

        void webBrowser1_DocumentCompleted(object sender, 
               
WebBrowserDocumentCompletedEventArgs e)
        {
            HtmlDocument doc = this.webBrowser1.Document;
            doc.Body.ScrollTop = 300;
            return;
        }

You can then programmatically set the body's scrolltop property to adjust the position of the body element within the scrollable area. For example, this is the page without the event handler code added:

And now with the scrolling code added:

 

Recommended reading:

kick it on DotNetKicks.com
Saturday, March 24, 2007 1:02:08 AM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Programming | WinForms and WPF

Computers Blogs - Blog Top Sites

Archive
<August 2008>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456
Blogroll
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008
Benjamin Rush
Sign In
Statistics
Total Posts: 444
This Year: 0
This Month: 0
This Week: 0
Comments: 127
Themes
Pick a theme:
All Content © 2008, Benjamin Rush
DasBlog theme 'Business' created by Christoph De Baene (delarou)