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.
Although you can’t destroy it, DeleteObject still returns TRUE of course.
> 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!
Yeah, as soon as I read that my thought was “You have, of course, just given someone a terrible idea.”
Fortunately, due to the optimization that Windows uses now that terrible idea won’t work! 🙂
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.
A COLORREF is a typedef’d DWORD, so someone has probably stuffed a pointer in there at some point.