Is there a difference between creating a null pen with Create­Pen and just using the stock null pen?

Raymond Chen

Raymond

A null pen draws nothing. It’s a pen with no ink.

To get a null pen, you can use the stock null pen by calling Get­Stock­Object(NULL_PEN), or you can create your own null pen from scratch by calling Create­Pen(PS_NULL, something, something).

Is there a difference? Why would you choose one over the other?

All null pens are functionally equivalent. They all do nothing. The difference is in the rules for handling them.

The stock null pen is always available, and you don’t need to destroy it. (Indeed, you can’t destroy it.) On the other hand, if you create your own custom null pen, then it’s on you to destroy it.

Now I get to talk about implementation details: Remember that implementation details are not contractual and may change at any time.

Starting in the Windows NT series, the Create­Pen function (and its moral equivalents such as Create­Pen­Indirect) checks whether you’re creating a null pen. If so, then it just gives you the stock null pen instead of creating a custom one.

The contract is still the same: Pens created with Create­Pen still need to be destroyed (eventually) with Delete­Object. (But everything works out because your attempt to destroy the stock null pen is simply ignored.)

Aside from checking the numeric value of the handle and comparing it to the numeric value of the stock null pen, there’s another way to detect that your null pen has been optimized out: See if your custom width and color are still there!

HPEN hpen = CreatePen(PS_NULL, 42, RGB(12,34,56));
LOGPEN lpen;
GetObject(hpen, sizeof(lpen), &lpen);
if (lpen.lopnWidth == 42)
{
  // CreatePen gave me a custom pen!
}

Fortunately, we didn’t find any apps that secretly passed information by hiding it inside the the width and color of null pens.

6 comments

Comments are closed. Login to edit/delete your existing comments

  • Baptiste Candellier
    Baptiste Candellier

    > Fortunately, we didn’t find any apps that secretly passed information by hiding it inside the the width and color of null pens.

    Hold my beer!

    • Avatar
      Alex Martin

      A COLORREF is a typedef’d DWORD, so someone has probably stuffed a pointer in there at some point.

    • Avatar
      Ron ParkerMicrosoft employee

      I’m probably misremembering this, but I want to say that GetObject is a relatively new API, so the kind of people who would have smuggled information in this way on Win 3.x where every bit mattered may not have been able to do so.

    • Avatar
      Chris Crowther

      Yeah, as soon as I read that my thought was “You have, of course, just given someone a terrible idea.”

      • Avatar
        Erik Fjeldstrom

        Fortunately, due to the optimization that Windows uses now that terrible idea won’t work! 🙂

  • Avatar
    Neil Rashbrook

    Although you can’t destroy it, DeleteObject still returns TRUE of course.