The TVS_CHECKBOXES style is quirky, which is a polite way of saying that it is crazy


A customer was having trouble with tree view checkboxes.

We have a tree view control in a dialog box. It is defined like this:

CONTROL "", IDC_TREEVIEW, WC_TREEVIEW,
    TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT |
    TVS_DISABLEDRAGDROP | TBS_SHOWSELALWAYS |
    TVS_CHECKBOXES | WS_BORDER | WS_HSCROLL | WS_TABSTOP,
    65, 22, 259, 182

As you can see, the TVS_CHECK­BOXES style is set in the dialog template. When the dialog is created, but before it is shown, we have code that populates the tree. At that time, we want to set the checked state of some of the nodes by using the Tree­View_Set­Check­State macro. If we call Tree­View_Get­Check­State immediately after setting the checked state, it reports the checked state correctly. However, once the tree view finishes rendering, all of the check boxes are cleared.

Curiously, if we hide the dialog box, then set the check boxes, and then show the dialog box, then the check boxes are not reset.

Why can't we check the tree view items immediately upon adding them, but before the dialog is shown for the first time? And more importantly, is there a workaround?

The tree view control's handling of the TVS_CHECK­BOXES style is quirky.

"Quirky" is a polite word for "crazy".

The documentation for the TVS_CHECK­BOXES style says

If you want to use this style, you must set the TVS_CHECK­BOXES style with Set­Window­Long after you create the treeview control, and before you populate the tree. Otherwise, the checkboxes might appear unchecked, depending on timing issues.

Sorry.

Tree view check boxes were poorly-designed. But we're stuck with them.

The customer confirmed that removing the TVS_CHECK­BOXES style from the dialog template and instead applying the style at run time fixes the problem.

The TVS_CHECK­BOXES style is quirky because it was bolted on rather than designed in. We'll spend the next several days exploring its quirks and trying to come up with a set of best practices for its use.

Comments (6)
  1. Pierre B. says:

    Wow. I’m reading this post as saying that some programs rely on the fact that they set the flag statically, check some items while creating the tree and *requiresr* that those checks be cleared when first showing up? (So that would explain why it can’t be fixed.)

    Otherwise, the only other explanation I can see is that the checks use data that used to be left uninitialized and contained random bits.

    1. Antonio Rodríguez says:

      You never know. The customer submitting the question probably is calling Tree­View_Get­Check­State for debugging. But after reading TheDailyWTF for a few years, I wouldn’t be surprised if somebody used the checked boxes as a temporary storage.

    2. When you’re dealing with code that is over 20 years old with untold thousands of apps using it, you can never be too careful. People rely on the weirdest things, often by accident. Sometimes they work around an issue in such a way that fixing the issue breaks the workaround.

      1. Martin Bonner says:

        … and presumably tree-view checkboxes aren’t used enough to justify implementing TVS_CHECKBOXES_DONE_RIGHT.

        1. It’s harder than that, because you need to know the right time to create the checkboxes. Create them too soon, and you create them before people have finished customizing them. (And you end up creating the wrong kind of check boxes.) We’ll learn how complicated this is over the next few weeks.

          1. Tanveer Badar says:

            Weeks you say? How long is this series going to be? Too may quirks.

Comments are closed.

Skip to main content