If vertical strips are better, why do toolbars use horizontal strips?


If vertical strips are better, why do toolbars use horizontal strips?

An early version of the toolbar control first made its appearance in Windows 3.0, and in those days, screen resolutions were low and toolbar buttons were small. Horizontal or vertical didn’t really matter. Ten bitmaps, each 16 × 16, at 4-bit color, comes out to one kilobyte, much less than even a single 4KB page. (And what’s this paging nonsense anyway? We’re talking 16-bit Windows here!)

When this code was ported to 32-bit Windows for Windows 95, the existing bitmap format was preserved in order to retain compatibility with the 16-bit clients of the toolbar control. Windows 95 included both the 16-bit and 32-bit versions of the common controls library, and they both built out of the same sources, with a little #ifdef WIN32 action here and there to deal with the places where 16/32 source code compatibility didn’t quite cover everything. The early prototypes of the Windows 95 shell were written in this mixed 16/32 model, so that the same program could be compiled either as a 16-bit program or a 32-bit program. The 16-bit version was used in the earlier builds because the 32-bit kernel, GDI, and USER were all being developed in parallel. The 16-bit version went out in the builds, and the 32-bit version was used by the development team as a proving ground for Windows 95’s 32-bit computing environment. When the 32-bit environment was declared “good enough to self-host”, the switch was thrown, and the 32-bit shell went into the builds instead of the 16-bit shell.

All this is a long way of saying that source code compatibility between 16-bit code and 32-bit code was very important, not only within the Windows 95 shell team, but throughout the Windows 95 product, so that teams could port their 16-bit components to 32-bit in a gradual and evolutionary manner. If you were to introduce gratuitous subtle differences (like the orientation of bitmap strips in toolbars), you wouldn’t make many friends. They would port their program to 32-bit Windows and the toolbars would all come out funny. “But it works fine when I compile it as 16-bit. Must be a bug in Windows 95. I’ll wait for the next build and try again.”

With the introduction of version 4.70 of the common controls, the internal structure of the toolbars changed, and the bitmaps came to be stored as imagelists rather than as raw bitmaps. Imagelists store their images in a vertical strip, so once again all is well with the world.

“Why not add a TB_ADDVERTICALBITMAP message?”

Well, for one thing, you’re looking for inefficiency at the wrong level. All that happens with the bitmap is that it gets stuffed into an imagelist. Nobody actually draws out of it, so there’s no point in optimize it for drawing.

And for another thing, you’re looking for inefficiency at the wrong level. If this even shows up on your performance traces, it means that you’re spending your time loading images into toolbars. Isn’t that a bigger cause for concern, that you’re spending so much of your time setting up toolbars? Shouldn’t you be spending your time doing productive work?

(Imagelists? Use your imagination.)

Comments (12)
  1. Adrian says:

    The term "self-host" seems to be unique to Microsoft.  Can you give a definition for those of us on the outside and the recently-initiated?

  2. HitScan says:

    Adrian: Self-host is more commonly used with a compiler. i.e. a C compiler that is complete enough that it can compile it’s own C source code.

    I’m not 100% certain what they meant by Explorer self-“hosting”, but it basically meant that it was working well enough in 32-bit mode that they could leave behind the 16-bit helper code.

    [To self-host an operating system means to use that operating system to develop itself. -Raymond]
  3. AC says:

    We’ve always used the term "self-host" as "being good enough to have on your primary machine". Perhaps they mean that it’s good enough to use as their operating system on their primary machine at that point.

  4. benkaras says:

    There is a level of inefficiency that you are forgetting about:  The artist.  

    An artist wants to draw all the artwork and just hand it off to the development team.  But now they must ask, "Is this for an imagelist or a toolbar?"  Then the artist heads back to the office and arranges the images vertically or horizontally as appropriate.  A simple flag would cut this step out of the development process.

  5. Southpaw says:

    Interesting how there is no mention of how Vertical tool bars went with the OS2 License. The MS contract with IBM is the real reason MS couldn’t use vertical tool bars in Windows.

  6. Mike Dimmick says:

    Southpaw: nice conspiracy theory, but Raymond is talking about the bitmaps which contain the button-face images, and whether they’re like a compact camera filmstrip (horizontal), or a movie filmstrip (vertical). You can orient the resulting toolbar either way.

    benkaras: it’s not exactly hard to write a program that converts from one to the other – I did it myself when Raymond published the original articles. There was no appreciable difference in performance between the two approaches, in my scenario, so to avoid the code churn, I backed out the change. Might be worth another look now I know that BitBlt recolours monochrome bitmaps when blitting to a colour DC.

  7. db48x says:

    Actually, the best solution in a situation like that is for the artist to produce one image for each button, and have the build process assemble them into a combined image. Doing that lets you change the format of the combined image if you need to. Still, in general the largest benefit comes from combining the images, and there’s essentially no performance difference between different ways of combining those images. (Animations show the difference better than toolbars)

    Also, scripting languages like perl or python are quite a bit better than they used to be, so  today it’s a lot easier to whip up a little script do do that sort of thing than it used to be.

  8. Starfish says:

    Not much imagination is needed anymore – as there’s no compelling reason to change the initial orientation (it barely matters performance-wise), it seems obvious to keep the format already in use and save many developers from headaches.

    *dons ‘dunce’ cap

  9. Jonathan says:

    To Selfhost – To use your under-development product for production uses.

  10. Yuhong Bao says:

    "Windows 95 included both the 16-bit and 32-bit versions of the common controls library, and they both built out of the same sources, with a little #ifdef WIN32 action here and there to deal with the places where 16/32 source code compatibility didn’t quite cover everything."

    So that is why the 16-bit version of the common control library were updated to support the new common controls in Windows 95, yet this fact were undocumented!

    You should blog more about the early builds of Windows 95, such as builds 58 and 73. I wonder what version of Visual C++ was these builds built with. WinSock support, Win32 support, Shell namespace, and so on… Does this web page recall any memories of these builds?

    http://toastytech.com/guis/c73.html

  11. Yuhong Bao says:

    "Windows 95 included both the 16-bit and 32-bit versions of the common controls library, and they both built out of the same sources, with a little #ifdef WIN32 action here and there to deal with the places where 16/32 source code compatibility didn’t quite cover everything."

    So that is why the 16-bit version of the common control library were updated to support the new common controls in Windows 95, yet this fact were undocumented!

    You should blog more about the early builds of Windows 95, such as builds 58 and 73. I wonder what version of Visual C++ was these builds built with. WinSock support, Win32 support, Shell namespace, and so on… And perticularly about why the networking support in these builds were the same as WFW 3.11’s networking support. Does this web page recall any memories of these builds?

    http://toastytech.com/guis/c73.html

  12. Carlos says:

    Reading this, I wondered why you didn’t prototype the Windows 95 shell on Windows NT; this would have saved maintaining a 16-bit version.  But it’s clear from the previous comment that early Windows 95 development must have predated the first release of Windows NT in early 1993, although it seems that betas of NT might have been available?

    I second Yuhong Bao’s suggestion: a post on the history of Windows 95 development with the dates of key milestones and how it related to NT development (if at all) would be interesting.

Comments are closed.