The Missing .NET #1: Cue Banners in Windows Forms (EM_SETCUEBANNER, Text Prompt)

The .NET framework is huge, but not so huge that it does everything for everyone; there are things that they in Redmond miss or don’t do for whatever reason but is still generally applicable to many developers. So, dear reader, I present to you a new, hopefully weekly, series of posts on stuff I find missing in .NET, typically where even the Google fails to find the answer.


One of the subtle UI improvements we’ve seen over the past few windows versions, and on the web, is the cue banner, or text prompt. They are hardly groundbreaking — putting them in your app probably won’t win you awards, but they do serve to make your applications that much more polished and usable.

They are used increasingly more often now that Vista has come out, which solved a few problems that I’ll address later. You can see them used in the popular browsers IE 7 and Firefox in the search boxes, denoting the search engine of choice for the user in a subtle grey tone. Click inside those textboxes, however, and the text disappears. That’s all a cue banner is, that grey text, informing the user what exactly she is supposed to use the text control for.

Cue banners work great in places where a formatted string is required, say an email address or a URL or a phone number. Instead of cluttering up the window with tons of labels, explaining examples or ranges of valid values, you can put those in a cue banner. It makes the UI a tad more elegant and self-explanatory.

Firefox and IE 7 Search boxes displaying a cue banner of the default search engine.These aren’t exactly missing on the web though. Search for ‘cue banner’ in your favourite search engine and you’ll find all kinds of examples, but none of them cover everything, or in a way that seems satisfactory to me. An example of an inherited textbox for Winforms can be found at this Channel 9 post. Daniel Moth has a version that works for the .NET Compact Framework as well as the main framework and decided to eschew the OS support and do it completely in managed code. He’s braver than I; I’d prefer to have MS do all that work and then use it.

[ad]

The Code

Download the code I’ve covered in this article.

OK, so now we know what a cue banner is, how do we include them in our apps?

The first thing to remember is that this is all done in Win32 which requires P/Invoke. All we’re doing is sending a Win32 message on the window handle of the control. That’s pretty straightforward boilerplate code that you can find on pinvoke.net. The one thing you may have to search for is the value of the msg parameter, EM_SETCUEBANNER, but I got you covered.

private const int EM_SETCUEBANNER = 0x1501;
private const int EM_GETCUEBANNER = 0x1502;

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SendMessage(IntPtr hWnd, int msg,
int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);

You can certainly do what buddy did on Channel 9: inherit from TextBox, add the required property, call the P/Invoke method and call it a day but then you’d be missing something important. Cue banners can be placed on edit controls, not just textboxes. The unfortunate thing about WinForms is that it’s essentially a facade over Win32. It does a very good job, make no mistake, but if you push it in the wrong place you end up exposing what’s underneath. And what’s underneath is Win32 which identifies all controls with its corresponding HWND. As a consequence, Windows Forms has a pretty flat hierarchy (cf. with WPF which was designed when OO was the prevailing wisdom; a very deep hierarch). Therefore, if you want to display a cue banner in a ComboBox or a RichTextBox, which the OS allows, then you’d have to subclass ComboBox and RichTextBox. Well, that’s just not scalable or portable. You’d always have to import your own controls and use those in your projects. I’ve found that most custom controls suck when used in the designer, so who wants to use them?

Besides, all the info that’s required to make cue banners work is already there in the control! So let’s use it instead. It’s not ideal, but I prefer to keep it all in a static class. We only need to use the Handle property which Control owns and we should also parameterize the actual cue banner text so we write the following method to set cue banners:

public static void SetCueText(Control control, string text)
{
   SendMessage(control.Handle, EM_SETCUEBANNER, 0, text);
}

Easy or what? So now drop a text box on a form. Call SetCueText in the form constructor for the text box and you’re set. Now drop a ComboBox and do the same for it. Hit F5 and prepare to bask in the glo… Hey! Why isn’t the cue banner set in the ComboBox? This is where other articles completely fall down on this stuff. You see, the ComboBox is actually made up of three controls: a text box and a list box and a button; think of it as a really old and ubiquitous UserControl. ComboBox.Handle is the handle for the combined control, not the text control, so we’ll need a way to get its handle. For that, we need more P/Invoke:

[DllImport("user32.dll")]
private static extern bool GetComboBoxInfo(IntPtr hwnd, ref COMBOBOXINFO pcbi);

[StructLayout(LayoutKind.Sequential)]
private struct COMBOBOXINFO
{
   public int cbSize;
   public RECT rcItem;
   public RECT rcButton;
   public IntPtr stateButton;
   public IntPtr hwndCombo;
   public IntPtr hwndItem;
   public IntPtr hwndList;
}

[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
   public int left;
   public int top;
   public int right;
   public int bottom;
}

OK, now we’re ready to add some more logic to the SetCueText method above:

public static void SetCueText(Control control, string text)
{
   if (control is ComboBox)
   {
      COMBOBOXINFO info = GetComboBoxInfo(control);
      SendMessage(info.hwndItem, EM_SETCUEBANNER, 0, text);
   }
   else
    {
        SendMessage(control.Handle, EM_SETCUEBANNER, 0, text);
    }
}

private static COMBOBOXINFO GetComboBoxInfo(Control control)
{
   COMBOBOXINFO info = new COMBOBOXINFO();
   //a combobox is made up of three controls, a button, a list and textbox;
    //we want the textbox
    info.cbSize = Marshal.SizeOf(info);
    GetComboBoxInfo(control.Handle, ref info);
   return info;
}

Hit F5 on your test app again, and voila: cue banner on ComboBox!

Notes

This only works on Windows XP and Vista.

On Windows XP, this conflicts with the East Asian Language packs, so if you have them installed, cue banners won’t work. Vista fixes this.

On Windows Vista, they’ve added a use for wParam parameter in the SendMessage() call. If you set it to TRUE, then the cue banner text will remain when the control gets focus.

I’ve found no use for the corresponding GetCueText, but if you want it, make sure you use a StringBuilder as the last parameter in SendMessage(), which requires another declaration of SendMessage.

Important: If you’ve done everything above and you still don’t see the wonderful cue banner text, check to see that before you call Application.Run(), you call Application.EnableVisualStyles(). That has to be called else cue banner won’t show up no matter what OS your are using.

Exercises

A few exercises for the reader:

  • SetCueText() is an ideal candidate for an extension method, if you’re allowed to use .NET 3.5. It’ll make the code just a little more readable. I’ll let you figure out how to do that.
  • There is a way you can have this on the designer. Just provide a component that implements IExtenderProvider to be dropped on the design surface.

The 4 things you require for successful dieting

I recently wrote about my ongoing success with the Cheat-To-Lose Diet. I’ve been thinking a lot lately about why this time is successful and the others weren’t. The diet is effective and pretty easy to follow, but I think I’m successful on it for other reasons; those reasons are why I don’t think I’ll be regressing to my former heavy self. So here they are, the four things you need to be successful at dieting, no matter the diet.

Motivation to change

This is the most important aspect of transforming your body. There are thousands and thousands of articles, books, videos, and products of all other sorts all focused on how to lose weight, how to diet, how to exercise available everywhere you turn. So why does everyone obsess over losing weight? Why hasn’t everyone just done it already?

You have to be ready to change the way you do things, maybe everything: eating, drinking, sleeping, cooking, exercising, working, even socializing. Without that willingness, all the good intentions and all the advice won’t work on you.It could be anything to give you that little spark of motivation, it doesn’t matter what it is; for me, it was pictures of myself. You can’t hide from the lens of a camera; it sees everything, including your fat face and two chins — well, my fat face and my two chins. 🙂

Once I decided enough was enough, it’s time for a change, then dieting didn’t look so daunting; I was willing to try something new. I knew that whatever I had to go through to lose the weight was worth doing. From what I’ve read of others’ transformations, they had that same motivation. Think of it this way: everything you’ve ever done has gotten you exactly where you are. Are you happy with that?

Self-awareness

This comes part and parcel with the first one. You need the motivation to start changing, and a little introspection to keep changing. Succeeding at diet is a challenge, and a transformative one: you won’t be the same person when you finish. The habits that got you where you are and the habits that will get you where you’re going have to be at the forefront of your mind. Modifying behaviour, if you’ve never done it before, requires a concerted effort.

How do you feel about food? What do you do when you’re hungry? Are you surprised by your hunger? My colleagues often go ’til 2pm before they realize they’re hungry, then eat less desirable food. Can you handle eating the same thing for long stretches or does every meal need to be an adventure? These are some of the questions that you have to know the answer to before any diet you go on will work.

Fostering self-awareness can be difficult when you have a lot going on. In the first few weeks, concentrating on the details of dieting will go a long way to success. If you’ve decided to do this with someone else, obsess over it in the first few weeks with each other. Talk to one another; try different strategies out, see how you feel after each one, and find the ones that’ll work for you. By yourself? Talk to yourself then. I’ll be talking about the habits that have helped me in future posts.

A specific, challenging goal

You want to lose weight? How much? Don’t know? Find out!If you’re interested in “losing weight”, or “toning up”, or “getting ripped”, you’re not going to get very far. How do you know when you made it? You need something specific to measure progress against. You also want a challenge; something that will take some effort to achieve. Don’t pick 5 pounds or 10 pounds, that’s too easy, and you can’t really see the difference. Go big: even if you don’t quite make it, you’ll still achieve a lot. Don’t sell yourself short.

It doesn’t have to be a number of pounds to lose (in fact, that’s not the best indicator, which is another blog post); it could be a body fat percentage, a waist measurement, or a pair of pants that you haven’t fit in for years, as long as you can measure your progress toward that goal and it’s challenging. Once you make it to the goal, make another goal! Why stop?

Confidence in the kitchen

This is the one that I was lacking the other few times I tried to lose weight. You often hear the complaint: “I really don’t like diet food. I’d totally diet if I didn’t have to eat boring chicken breasts.” You don’t. You just need to learn how to cook. Whether you feel the need to count calories or not; whether you’re on a low carb diet or low fat diet really doesn’t matter if you’re more comfortable heating a dinner from a box in the microwave than putting a pan on the stove and actually cooking. Do you think Stouffer’s really has your back with that low-fat Tuscan Pesto Chicken in Fettuccini Sauce? It’s loaded with sugar, corn and soy food products that you have no hope of ever pronouncing correctly. Think that’s good for you? It’s cheaper and healthier to cook your own, and it really doesn’t take that long after a couple weeks of practice.

Once you start mastering a few dishes, you’ll want to try more and more cooking methods, different ingredients; you’ll start planning your meals, food at chain restaurants won’t taste that good and neither will that microwave dinner. You’ll want to invite people over to share in the meals, and, let’s be honest, show off a little. And all the while, the fat is coming off your body because you are in charge of what goes in your body.


These four things aren’t the only things you’re going to need, but based on my experience, they’re the fundamental foundation for a successful physique transformation. If you work on these four things, you’re well on your way to the new you.

Tags: ,,,

Subtext to WordPress: Converting blog engines

I think my mom is my only constant reader, but if you used to read jasonkemp.ca when I was writing it more frequently than the last year and a half, you’ll notice a few changes in appearance that only scratch the surface of the changes that I’ve made.

I moved hosts; I moved OSes; and I moved blog engines. I decided to move to WordPress on LAMP from Subtext on IIS. And I’m really happy with the move, too, which is rare, if Google is any indication; everyone else is moving the other way. There was only one, Aaron Lerch, who went in my direction and he wrote an import plug in, which I didn’t use because it required all these extra downloads. [Um, re-reading Aaron’s post, I see now that his BlogML Import plugin is probably the way to go if you’re in this situation. There’s only one extra download.]

To make matters worse, I had a version of Subtext that must’ve been a development version because the BlogML export didn’t work at all. So I had to use all my hacking skills to read directly from the database with the current Subtext source (Thank goodness it was open source!). I’ll spare you the details of that export; it wasn’t perfect or pretty but I got my posts, comments, and categories, which was close enough for what I wanted. So I had a BlogML XML file and I needed to convert to a WordPress export file, which is just some gussied up RSS. In the intervening years since I stopped blogging and now, .NET 3.5 was released, so I thought this was the perfect time to play with LINQ and the new XML APIs.

LINQ is seriously cool. Working with XML is seriously not, no matter what API you have. Those were the two conclusions I came up with. The new XML APIs are pretty sweet, though. They’re the closest I can come to writing code that handles XML the way I think about XML. But that’s not what I’m writing this post about.

The conversion got me about 90% there, but there were a couple things that I needed to fix: mapping old urls to the new ones because your urls are probably the most important thing about people reaching your website and handling image paths; both of which are handled with mod_rewrite and the htaccess file. Until IIS 7, I don’t think Windows had anything as cool as that and even with IIS 7, it may not, certainly not as simple as a text file.

Using this helpful article, I generated all the rewrite rules from the BlogML export file, since it had all the old post urls. I only had roughly one hundred articles so I just hard-coded everyone of them. They all take the form of

RewriteRule ^rss.aspx http://www.jasonkemp.ca/blog/feed [r=301,nc]

I didn’t want to mess with mod_rewrite too much, because regular expressions require a quiet room and lots of testing, so I kept it pretty simple. What the above says is if my web server receives a request for rss.aspx, then permanently redirect to http://www.jasonkemp.ca/blog/feed, that’s what the r=301 means. The ‘nc’ means case doesn’t matter. Spaces matter here! Notice there are no spaces in the the square brackets. It won’t work otherwise.

The last thing I had to do to convert was images. My images were in two spots: the root folder and in an ‘images’ folder. So my posts have those paths in them. Rather than go through all my posts and changing the paths, I added another rewrite rule:

RewriteRule ^(images/)?(.+)\.(gif|jpg)$ blog/img/$2.$3 [nc]

That’s about as fancy as I get in mod_rewrite. What this says is any jpg or gif file either in the root or in the path images/, then redirect to blog/img/ with the same name and extension. So if I had an image in a post with the path images/1.jpg, then mod_rewrite will convert that to blog/img/1.jpg.

Converting this took a few weeks of off and on development. Changing blog engines is anything but trivial right now. If anyone is curious about the code, just ask.

Technorati Tags: ,,,

Review: The Cheat to Lose Diet by Joel Marion

The Cheat to Lose Diet: Cheat BIG with the Foods You Love, Lose Fat Faster Than Ever Before, and Enjoy Keeping It Off!

If you’ve been struggling to lose fat for a year, say, and someone came up to you and said you could drink a 2L bottle of pop a week, ice cream, cookies, and pizza (my favourite; also note the “and”) and still lose up to 2.5 lbs a week*, would you believe them? I wouldn’t. How many offers do you see on TV and the internets that promise insane losses in insanely short time periods? C’mon! I know better, move on, we don’t want any.

But this is different.

So far, on this diet, I’ve lost 31 pounds in 19 weeks for an average of 1.6 lbs/week. I started on Thanksgiving (the Canadian one, naturally, so beginning of October). My performance in the gym hasn’t waned nor has my size in the right places, which leads me to believe that I haven’t lost much muscle. And, once a week, I can eat whatever I want for a whole day.

It’s a remarkable diet; it works by manipulating the hormone leptin, a hormone at its peak when the body has all the energy it needs, when calories are abundant. Leptin levels decline quickly in the absence of calories, as much as 50% in a week. Therefore, every week, during the core phase of the diet, you get a cheat day where there are few limits on what to eat, to keep leptin at its peak. I’m simplifying of course, the book has far more detail about the how and why, but it is a very simple diet and exercise routine that takes very little time to master if you’re prepared to diet.

Joel writes in a clear, conversational tone throughout the book, making it easy to grasp the ideas and zip through the book, so you can get started pretty quickly after the book arrives. The book is very well researched and has a detailed reference section highlighting all the studies that Joel Marion read if you want to follow up. One thing he does not do, thankfully, is force you to count calories. Instead, he encourages you go by sight which is refreshing, if you, like me, hate counting calories.

One more note about the exercise portion: I made the mistake of assuming I knew better than Joel when it came to exercise. I thought that whatever he recommended couldn’t possibly be better than the weight workouts I’d come up with or follow. When I wasn’t quite getting the 2lbs/week that the diet promises, I figured I’d just have to keep going with weight workouts but push just a little harder. In truth, I didn’t even read the exercise part! What a giant mistake! It wasn’t until my girlfriend pointed out that she does it every week did I listen; she was losing more bulk than I was. So I started on 1 Jan 08 with the exercise routine outlined in the book and I’ve lost 12 pounds since then for a much better average.

I’m someone who loves to eat with a sweet tooth. If this works for me, then it can work for anybody. If you’ve tried to lose weight, but failed, then I can’t recommend this diet highly enough. I saw results after the first week. Do yourself a favour and try this out.

A Fast Equals() – Remember to Always Measure

For years, I thought I had the one, true answer to Equals() from seeing something in some MSDN article a long, long time ago – like 2002 or 2003. Or maybe it was on Brad’s or Krystof’s blog and freaked out because I wasn’t doing it. Whatever the case, I’d make sure to point out the “proper” way to do Equals() to my colleagues. And I always made sure that I’d do it the same way for all my types that needed Equals overridden. Then I decided to measure it.

So, what did I think the best way to do Equals was? Consider this type:

    class MyClass
    {
        public int NumberValue;
        public string StringValue;
    }

If I were to write Equals the way I used to, I would write it the following way:

        public override bool Equals(object obj)
        {
            if (obj == null || obj.GetType() != GetType())
                return false;
            if (ReferenceEquals(obj, this))
                return true;
            MyClass other = (MyClass) obj;
            return other.NumberValue == this.NumberValue &&
                   other.StringValue == this.StringValue;
        }

Note that the above implementation suffices the conditions for a robust Equals. The important part of Equals() is that it covers all the following cases:

  • it returns false if obj is null;
  • it returns false if obj is not the same type as this;
  • it returns true if the references are the same;
  • it doesn’t throw Exceptions; and
  • it doesn’t allocate memory.

The actual evaluation of equality is per class and changes for every class. In the example above, the equality evaluation is the return statement comparing the string and the int of both MyClass instances. The above list of conditions is boilerplate and should be met for every Equals method you write.

So what’s the problem? My Equals method does everything in that list just fine. Right?

Two of the conditions are trivial to meet: the check for null and check for reference equality. The hard one to meet, perhaps because are there so many ways of doing it, is checking for the right type. In my method above, I check the type by comparing GetType() of both obj and this. If they aren’t equal, I return false. That turns out to be 5 times slower than the other two ways of doing it: the is and as operator.

The .NET Design Guidelines recommend you use the as operator to check the type rather than the is operator because it does the type check and assignment all at once. So let’s re-write the Equals method to use the as operator:

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, this))
                return true;
            MyClass other = obj as MyClass;
            if (other != null)
              return other.NumberValue == this.NumberValue &&
                     other.StringValue == this.StringValue;
            return false;
        }

This method meets all the conditions of a good Equals, but has the advantage of being pretty fast, faster than the first way I did it anyway. Since the gurus in Redmond recommend the as operator, you’d think that it’s the fastest: wrong! Check it:

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, this))
                return true;
            if (obj is MyClass)
            {
                MyClass other = (MyClass) obj;
                return other.NumberValue == this.NumberValue &&
                       other.StringValue == this.StringValue;
            }
            return false;
        }

Equals with the is operator and then casting is actually the fastest of them all (by about 10% when compared to the as operator). All three methods meet the conditions of a good Equals method, but the least intuitive one – to me at least – has the advantage of being the fastest. And it’s cheap speed, too: you get it just by implementing Equals the same way everytime for every type. You generally want Equals to be pretty fast because it will show up a lot in loops and operations on collections.

My point? Always measure – don’t assume you’re doing things right. It’s good to go back and think about the fundamentals once in a while.