May 2004 - Posts

This is a really big article on all of the operational details of the WinForms marshalling pump (aka the plumbing for Invoke and BeginInvoke).  WinForms UI Thread Invokes: An In-Depth Review of Invoke/BeginInvoke/InvokeRequred

Abstract:
Marshalling the execution of your code onto the UI thread in the Windows Forms environment is critical to prevent cross-thread usage of UI code.  Most people don't understand how or when they'll need to use the marshalling behavior or under what circumstances it is required and when it is not.  Other users don't understand what happens when you use the marshalling behavior but it isn't needed.  In actuality it has no negative effects on stability, and instead reserves any negative side effects to performance only.

Understanding the semantics of when your callback methods will be called, in what order, and how might be very important to your application.  In addition to the default marhalling behavior, I'll be covering special considerations for enhancing the marhsalling behavior once we fully understand how it works.  We'll also cover all of the normal scenarios and uses for code execution marhsalling to make this a complete Windows Forms marshalling document.

I've talked about the pump before, but now I explain it in full gruesome detail.  Some notes are how this Awesome Windows Forms message pump trick... can actually fail and how this Got strange messages in your queue? Maybe Winforms is using it to synchronize your async code onto the UI thread... is only the tip of the iceberg (and what convinced me to write the full article).

Not everyone checks my links daily, but I added a link a couple of days ago to http://www.CorporateRebel.com.  This site is attempting to provide an alternative to the larger sites like www.guru.com or maybe www.monster.com where IT professionals can both propose contractual work and others can in turn bid on that work.  While the site is currently in its infancy (they are only about 3 days old), they have already managed to accrue some contracts and take some bids.  They've had a fairly decent sign-up rate of new professionals.  If you get a chance, check them out.  If you have small contracts for work, then post them on the site and see if you get any hits.  If you think you'll want some small contracts in the future, then sign up as a developer so you can start bidding.

Posted by Justin Rogers | 4 comment(s)
Filed under:

I think the fact that BeginInvoke/Invoke/EndInvoke just work is enough for most people.  It know it has been enough for me.  I didn't even question why it worked, though I did know it was using the message pump, just not exactly how it was using the message pump.  Well tonight I had some time so I stepped through the code as best I could and found some interesting items.

First off a control doesn't necessarily have to be the invoker for it's own events.  The invoker can be a parent control, or even the parking window for a particular control.  I've seen lots of posts on the newsgroups about parking windows and comments like “What in the hell are they”.  I've never seen a parking window launch, EVER, but others claim they show up in taksbars and all manner of other weirdness.

A control with a handle is picked so that the handle can be used to find the thread it was created on and maybe to post a message to said handle in the case we are doing an invoke across a thread boundary.  All kinds of information is saved about the call on a special object called a ThreadMethodEntry.  They have to put information about the call stack (so they can rebuild your permissions on the remote thread).  I found that pretty interesting since I had worried about the possibility of being able to circumvent the security model, but they thought of that and cut me off at the gate.  Once the TME is built they toss it into a queue.  I was thinking hard about this, why a queue, and not use some other collection where we can add, remove, and index by ordinal and put that ordinal on the message?

Well think about it for a minute.  Do you want your methods to operate in sync our out of sync?  I'd assume in some sort of synchronization.  The windows message pump isn't an immediate beast by any means and it would be possible for someone to throw events in the pump ahead of you.  So they use the queue and they synchronize access to the queue, so that all of your events happen in a particular order.

In fact, you could queue up 50 methods and thus have 50 events on the message pump.  As soon as the first message comes off the pump, all of your callbacks will execute.  I'm not sure how much I really like this, but that is the way it works.  It also means that if you queue up more operations in any of your callbacks, they'll happen without waiting for the message.  Of course you are on the thread, so why would you do that?  Well, in asynchronous operation, you'll find that you can set things, and that they get reset because various property sets initiate windows messages which in turn change your values.  You have to be so careful with ordering everything.

I won't bore you with any more of the details.  If you are interested in more depth I'm always itching to look at some extra IL.

Joel B. dropped some interesting questions for me on an very old post of mine People are confused by ApplicationContext in Windows Forms, but there really isn't any magic happening.  It seems people are also confused about the entire message pump and what it is capable of.  He asks some common questions about the pump that can be answered by delving into Win32, but he brings to light some additional questions that have their roots in the way WinForms extends the messag pump for your usage.  We'll be getting ourselves into two different hooks.  The first hook is a message filter added through the Application class.  The second hook, and the more useful hook, is going to be added by overriding Control.PreProcessMessage.

Starting with IMessageFilter you have to realize what you can do.  You can listen to events and do something, but not consume the event.  This is interesting, since you can implement all forms of debugging filters and figure out where those events are going and maybe why your application is behaving the way it is.  I often use a message filter to find out if my messages are out of order or to discover undocument things like how focus changes within my application.

You can also listen to events and consume them.  If you consume an event it doesn't continue up to the control it is destined for.  If you wanted to easily disable your form without doing a bunch of work, you could trap all messages for a while and simply throw them out.  If you wanted to limit input to only a specific control you could filter on it's handle.  Here is a small application that has a button click handler and a form handler.  I add and remove a message filter to disable the button control by limiting messages to only the form's handle.  Not very neat, but something to demonstrate what you can do.

using System;
using System.Windows.Forms;

public class OnlyAllow : IMessageFilter {
    private IntPtr redirectHandle = IntPtr.Zero;
   
    public OnlyAllow(IntPtr redirectHandle) {
        this.redirectHandle = redirectHandle;
    }
   
    public bool PreFilterMessage(ref Message m) {
        Console.WriteLine("Pre Filter is being called");
        if ( this.redirectHandle == m.HWnd ) {
            return false;
        }
       
        return true;
    }
}

public class MainForm : Form {
    private OnlyAllow oa = null;
    private Button b = new Button();
   
    public MainForm() {
        b.Click += new EventHandler(Button_Click);
        this.Controls.Add(b);
       
        this.Click += new EventHandler(Form_Click);
    }
   
    private void Button_Click(object sender, EventArgs e) {
        Console.WriteLine("Button Clicked");
        if ( oa == null ) {
            oa = new OnlyAllow(this.Handle);
        }
        Application.AddMessageFilter(oa);
    }
   
    private void Form_Click(object sender, EventArgs e) {
        Console.WriteLine("Form Clicked");
        if ( oa != null ) {
            Application.RemoveMessageFilter(oa);
        }
    }
   
    private static void Main(string[] args) {
        Application.Run(new MainForm());
    }
}

It is often misunderstood the filters are more powerful than they really are.  They aren't.  They are a specialized hook placed into the message pump that normally wouldn't exist.  Yes, libraries like MFC do have similar hooks, but you'd have to make filtering logic up yourself if you were working at the Win32 level and handling the message pump yourself.  They also aren't useful if you need to change anything about the message.  You can peek, but not touch.  Any changes you make to the message get lost.  You'd think you could change the message based on the fact the parm is ref, but you can't.  The values you change are to a copy of the message that is created behind scenes, and the values aren't copied back off.

That brings us to PreProcessMessage.  You have a bit more control with this override, however, you only get messages that are destined to your control, not a peek at all messages.  You can be promiscuous again and peek at all the of the messages, but not consume them, definitely good for debugging.  Or you can consume the events, in which case any event handlers or normal processing that would have been done won't get a chance to run.  If you have some garbage you need to throw out then you can do just that.  You can also use PreProcessMessage to trap and consume messages that you wouldn't otherwise get a chance to process.

I did say you'd get more power.  If you change the parameters in the Message structure, they will get copied to the real message this time through.  While you can't change items like HWnd or Msg, you can change WParam and LParam.  That means any rich messages can have their actions changed.  Prime candidates are definitely mouse and keyboard input.  I've used this to turn off scrolling in my listbox while I was rendering the current view (though I came up with a better approach later).

Hopefully this better explains what is available through WinForms and how you can use it.  Unfortunately I don't have a great deal of examples.  You don't often need to use message filters and pre processing unless you are debugging events.  Even the Winforms code only has a couple of classes that use it.  Namely Control, ComboBox, and AxHost.  Hopefully that tells you how much you need to do this.  At the end of the day, you can get the same effects from overriding your WndProc.  Maybe I'll talk about that some other time.

Back in the contractor lab at Microsoft we used to joke about a room made entirely out of whiteboard material.  A friend of mine told me you could get entire sheets of the stuff for cheap at Lowes or Home Depot, but I never could find the right material.  The other day I decided to take a look and sure enough, 2x4 foot sheets of whiteboard material are only $5.  A 4x6 whiteboard can cost you nearly $100 at a place like Staples, so there is definitely some savings in buying the raw material.

I only bought about 4 sheets, so the entire room being covered is a ways off.  However, I found better uses for the material than just covering your walls.  You can cut 1' square sections and use it for just about any software design you could think of.  A single sheet cuts out 8 and you can draw something, plastic wrap over the top of it, and store it for later or simply wipe it off and use it again.  Being as I'm working on my latest book, having a small portable drawing device (don't even start talking about Tablet PC's, they hold no water compared to a good old whiteboard and some markers) is coming in really handy.  I pounded out an entire chapters worth of figures in only a few hours this weekend, something that would have taken me a couple of days in Visio.  If I steady my hand a bit, I could even use the drawings inside of the chapters rather than later transferring them to Visio (I'm always quick at laying out something I've already designed, but designing something in Visio is a real pain compared to drawing it by hand).

Well, we'll see what my publisher thinks about the quality of the sketches and go from there I guess.  If nothing else, I'm happy with my $20 purchase of a nearly limitless area for mathematical equations, software design, and grocery lists (oops, how'd that get in there).

A common immutability practice is to simply protect the property setter with an immutability flag.  Take a simple class that has a single integer field for to back our property and a single boolean flag to mark it immutable.

using System;

public class SimplyImmutable {
    private int field1 = 0;
    private bool immutable = false;
   
    public SimplyImmutable() {
    }
   
    public int Field1 {
        get { return field1; }
        set {
            if ( !immutable ) {
                field1 = value;
            }
        }
    }
}

As soon as the immutable flag is set, you can no longer set the field value.  This is nice.  Time to add a few methods.  First we need a MakeImmutable method.  This will set our flag.  Normally, our application will set this before giving any other code access to the class.  Second, we'll add an IncrementField method, but we'll make a mistake, so see if you catch it.

public void MakeImmutable() {
    immutable = true;
}

public void IncrementField() {
    field1++;
}

See the mistake yet?  We accessed field1 directly, and didn't use the immutability flag.  This problem goes away if you use the property instead of the private field or if you use the immutability flag.  In this small example the problem is easy to spot.  However, in a larger class with several properties, many backing fields, and maybe 10 or more methods, you can fail to find issues early in the game.  The gem here is to use the property inside of our methods so that we don't have to write a bunch of extra code in each of them to handle immutability.

public void IncrementField() {
    Field1++;
}

What happens if you are setting the Field1 property multiple times?  You start to incur the wrath of the flag check on each set.  If this happens, then go ahead and move your immutability check into your method and then convert over to using the private field again.  Note if you do this process by first using the property and then only later converting over to use the private field and the immutability flag, you can do it on an as needed basis and ensure that you are protecting yourself.

public void IncrementField() {
    if ( !immutable ) { // Work with field multiple times, if not then just use the property instead }
}

This tip has many natural extensions into other gotchas that I'll cover later.  Think for a bit about making our fields protected so they can be accessed from derived classes, and how that might introduce resource access issues.  I'll be examining this abstraction in the next tip.

I could examine performance all day long, running tests, examining compiled assembly, whatever is necessary (fudge future improvements in the JIT, I live and work in the now) to get the best performance.  Heck, I've even been doing just that over the past couple of months.  Mainly I've been hitting areas that I find important, but I'm always curious what other people would want to have examined.  Most people don't have the time to properly review the peformance of various aspects of the framework or glean the full potential of an algorithm, but I'll help you out.

Just to get you started on some ideas I'll take just about anything that isn't enterprise/server load dependent.  I'm definitely not going to try and recreate any load scenarios since those are't generally replicatable across configurations.  What I am looking for is an algorithm that you have and you are curious if it could be faster.  Or how about the fastest way to accomplish X (not productivity speed, but code execution speed).  Make sure you check my list of performance posts before making suggestions, since I've already covered many of the common issues, and even some uncommon ones.  I haven't done very much at all with algorithms, so I'm thinking there is plenty of room there.

Posted by Justin Rogers | with no comments
Filed under: ,

In my previous article If you could pick the reason why GDI should be .NET accessible, what would it be? I talked about the new GDI namespace.  Now, while I was searching and searching for a way to do screen captures on the GDI classes, they instead added the screen capture to the actual Graphics class.  I could go into why this is such a band-aid, but I won't.  Instead I'll show you how to use it, then talk about how it is a band-aid ;-)

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

public class ScreenCap {
    private static void Main(string[] args) {
        if ( args.Length < 1 ) {
            return;
        }
       
        string fileName = args[0];
        ScreenCapture(fileName);
    }
   
    private static void ScreenCapture(string fileName) {
        Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
        Graphics gfx = Graphics.FromImage(bmp);
        gfx.CopyFromScreen(0, 0, 0, 0, bmp.Size);
        gfx.Dispose();
        bmp.Save(fileName, ImageFormat.Jpeg);
    }
}

The above code makes a screen capture.  It takes a while to load and run, which I don't find very amusing, but what the heck, I can't complain.  You can extend this with my previous article to show how you might first copy the screen, modify it, and then write it back out for a screen saver.  I'll do something along these lines soon, since I have a large amount of GDI+ filters written that would be cool to render animated over the desktop.

Now I want to talk about how much of a band-aid this is.  Any copy operation from the screen is doing a BitBlt somewhere.  A BitBlt can and should be allowed between ANY two surfaces, but they are limiting access to the copy operation to only screen surfaces, and not allowing blt's between offscreen surfaces.  Rather than give a generic method for copying from any hDC or device context, which would have been really nice, especially for DirectX + GDI interfacing, they instead give you an operation to only copy the entire screen.  I'll stop now.  Enjoy your screen capture code and watch for my upcoming screen saver section.

Posted by Justin Rogers | 1 comment(s)
Filed under: , ,

There really is no such thing as easily printing a window.  You see windows are highly oriented to the display, they have virtual regions that are only visible when scrolled, and often they are much wider than they are tall, so you get some issues with even fitting on the paper if you print the form as is straight from the screen.  That doesn't stop people from wanting the feature.  In fact, most people think it should be an easy requirement and simply demand it.  One of my friends found printing the contents of his form as an extra  question in one of his introduction to computer programming classes.  Of course he found out rather quickly how difficult it was.  You can read about that here Printing a ListBox in VB.  Of course I gave him some suggestions, but I couldn't really answer or solve his question.  That definitely disappoints me.

Why was printing left where it was?  Well, because it is hard to print.  What does a list box of three visible elements, but 20 actual elements display as in a report or printed version of the form?  How about a huge data-grid with 1000 elements, but only 10 visible?  What happens when there are nested relationships?  The answers to these are highly application dependent.  The next version of Windows Forms (Whidbey) does have some answers though.

With Whidbey there is the concept of a Renderer.  You get new classes like CheckBoxRenderer that allow you to specify the Graphics to render into.  You might say these existed already in ControlPaint, and you would be right.  The renderer classes even use ControlPaint still, but they have an extra set of code that will use a VisualStyleRenderer instead.  Will this help any in printing?  Maybe and maybe not.  It will let you get closer to the WYSIWYG approach if you want to render a form as it appears on the screen on a piece of paper.  However, they are still lacking renderers for common controls like the ListBox that people like John are having such a hard time with.

Maybe I'm wrong then.  Maybe Whidbey really doesn't help you with printing.  They certainly don't have any print adapters that adapt a visual control to a printed version of the control.  That would be pretty sweet if you ask me.  They also require you to pass in loads of arguments to the renderer.  Things like check state and rectangles for sizing that could easily be pulled off of a control instead (aka, render THIS control dummy, don't make me specify a bunch of arguments).  Maybe it is time to make a larger investment in Crystal Reports?

Posted by Justin Rogers | with no comments
Filed under: ,

I'm guessing that most people would say for screen captures.  Though there are some other reasons with playing back movies being a big one.  Custom glyphing or overwriting the Desktop would certainly be on there as well.  Which of these are possible using System.Drawing.GDI and which are not?

For the #1 reason I think most people want GDI support is capturing the screen so they can save it out.  This after all is a huge feature in many applications.  The new GDI classes let you get the DeviceContext of the desktop quite easily.  They also let you create a WindowsBitmap (HBitmap) out of a Bitmap object.  So far, so good?  I think so.  But here is where things break down.  The normal screen capture logic that you might use would CreateCompatibleDC on the desktop DC, CreateCompatibleBitmap on the desktop DC, select the compatible bitmap onto the compatible dc, and then BitBlt using the desktop DC and the compatible DC you just created.  That is a huge process, and there aren't any managed equivalent methods in the GDI namespace.  The WindowsGraphics (I'm not sure what in the hell this is supposed to be), can take a WindowsBitmap as source (just like the Graphics object takes an Image), but there is no way to create one from a DeviceContext, so we still can't get from the Desktop DC to a class that can be the source of a Draw operation.  This sucks my friend.

What does the GDI class actually buy you?  I think it is used to convert between GDI+ and the screen.  They probably get a decent performance improvement in Windows Forms by using GDI glyphs to back converted GDI+ objects.

Playing back movies or creating movies, could you do that?  I think so.  Many video libraries work with HBitmaps when rendering frames and you could at least work with them now.  If you build all of your WindowsBitmap objects over top of Bitmaps, you can save stuff, but you can't go back the other direction for some reason.  WindowsBitmap objects or HBitmap handles can't be turned back into Bitmap objects.

Maybe you just want to overwrite something.  Screen Savers do this a bunch where they munge the current desktop to create their appearance.  Normally they save the original desktop to do this, which we know we can't do.  But if they just wanted to draw on the screen they could do that right?  Yep.

WindowsGraphics drawToScreen = new WindowsGraphics(DeviceContext.FromHwnd(IntPtr.Zero));
WindowsGraphics method2 = WindowsGraphics.FromHwnd(IntPtr.Zero);

That means overwriting things does work.  This improves performance in something like an owner drawn listbox if you want to render directly to the underlying DC.  I took the time to munge something together and I more than doubled the speed of rendering thumbnailed images to an owner drawn listbox.  If I create my own *listbox* with my own hit testing, virtual scrolling, etc...  I'm able to achieve huge performance wins, especially for the scrolling scenarios.  While most of the features I wanted aren't present, maybe the GDI namespace has something to offer yet?

Posted by Justin Rogers | 5 comment(s)
Filed under: ,
More Posts « Previous page