Why does the CBS_SORT combo box style sort the left square bracket so strangely?

Some time ago, Michael Kaplan asked (and answered), How the @#%&*! does CBS_SORT choose to sort it all out? One detail in his answer is that the sorting algorithm used by CBS_SORT is basically CompareString, with special treatment for the left square bracket U+005B.

Why is the left square bracket so special?

It goes back to the LB_DIR message (which is in turn used by DlgDirList, CB_DIR, DlgDirListComboBox, and related functions). If you ask for drives to be added to the list or combo box, they are added in the form [-X-], where X is the drive letter. The left square bracket is special-cased so that the drive letters sort to the top of the list.

Of course, LB_DIR and related functions and messages are pretty old-school nowadays, but the code for them is still around, so the sort function still needs to worry about them.

Comments (14)
  1. asf says:

    This sort of thing makes no sense to me, why is there no internal flag for something like this (At least by the time win32 came around, you would have enough memory to store one more bitflag)

    The way it is now, CBS_SORT is pretty much useless to everyone

    [There are only 16 bits available for class styles. CBS_SORTLINGUISTIC would consume one of the three available remaining bits. Or are you saying that a sorted combo box should behave differently depending on whether it received the CB_DIR message or not? What about the existing contents of the combo box at the time CB_DIR is sent? Should they be re-sorted? And does this mean that there’s yet another so subtle you’ll-never-find-this-until-it’s-too-late obstacle to porting your Win16 program to Win32? -Raymond]
  2. waleri says:


    No need to fix the issue at all – there is a new listview, that handles if not LVS_LIST then at least LVM_SORTITEMS…

  3. asf says:

    @Raymond: FindFirstFile and add just one item at the time with full path to CB_DIR?

    [“What a screwed-up API this is.” -Raymond]
  4. Leo Davidson says:

    If someone wants esoteric sorting, for drive letters in a particular text format or whatever, then they can sort the items themselves and tell the control not to sort, like everyone else has to.

    It’s too late to change now but making a general-purpose controls’s default sorting use an esoteric method because of one special case seems very silly to me.

  5. Anonymous Coward says:

    I agree. We can’t go back now, but when Windows 95 came out, support for CB_DIR &c. should have been terminated for 32 bit applications. Microsoft could easily have dictated that new applications should use the common dialogues. There is no good use case for dir comboboxes and lists any more, they’re hard to use, unnecessary, and invoking a common dialogue is easier and provides more features.

    The only post-Win3.1 application I’ve seen that uses things like that is VB and the VB guys decided to implement it differently, presumably for aesthetic reasons. I assume they were just there for 16-bit VB compatibility anyway, since VB supports the common dialogues as well. They should have just axed them from the toolbox when VB4 came out; there’s no sense in deliberately adding them to new, or even existing, applications.

    [You and Ulric need to work out your differences. Ulric was upset at the loss of MoveTo, something you could easily work around with a macro. Whereas your proposal of removing support for CB_DIR requires a redesign of a program’s UI. -Raymond]
  6. asf says:

    @Raymond: Yes, I’m saying CB_DIR would activate this mode (And deleting all items would deactivate it)

    @waleri: Listbox has LBS_OWNERDRAWVARIABLE and LBS_MULTICOLUMN etc

    [I guess that would cover most cases, though it messes up the case where somebody actually *wants* the left-bracket sort order (say because they are doing their own manual FindFirstFile instead of using CB_DIR, say, because they need to do additional filtering) – now they can’t get it. And of course it would be an incompatibility between Win16 and Win32 that wouldn’t be caught at compile time. -Raymond]
  7. waleri says:

    >> @waleri: Listbox has LBS_OWNERDRAWVARIABLE and LBS_MULTICOLUMN etc

    Yeah, so?

    What this has to do with sorting?

    And beside, list view has those as well.

  8. Worf says:

    Given [ is legal in a filename, could this be used to "fake" a drive?

    E.g., decided to have a bunch of files [-A-] through [-Z-] ?

  9. Paul says:

    I believe Mr Chen has imparted these words before: "Try it and see"

    I’d be intrigued as to what it would do.

  10. Anonymous Coward says:

    Yeah, it would require a slight redesign, although it would in almost all cases be replacing the call to open your own file dialogue with a call to open the common one.

    Going by the original questions and the comments, I don’t think Ulric was upset by the way. In any case, I could probably convince him that a major platform change (in this case 16- to 32-bit) requires a full code review anyway, so it isn’t that bad if it doesn’t recompile out of the box.

  11. Anonymous Coward says:

    Worf, first of all, square brackets weren’t legal in the Windows 3.1 era. I’ve looked at a file like that using Windows 1.0 Notepad, and it sees an alias short file name.

    Next, play around with this code:

    —(paste this in a form with a combobox)—

    Option Explicit

    Private Declare Function SendMessageA Lib "User32" (ByVal hWnd As Long, ByVal Msg As Long, ByVal W As Long, ByVal L As String) As Long

    Private Sub Form_Load()

    SendMessageA Combo1.hWnd, &H145, &HE036, "C:*.*"

    End Sub

    —(end – yes I know this code is ugly and I wouldn’t be caught dead doing this in a production environment)—

    You will find that if you create a file called "[-b-]" it gets sorted as if it were a folder called "-b-", id est between the b’s, after "-a-" and "abc" and before a folder called "-c-".

    Furthermore, mapped drive letters always get added to the bottom of the list, regardless of sort order. The special casing for the opening square bracket is there for folders, not for drives.

  12. 640k says:

    You will find that if you create a file called "[-b-]" it gets sorted as if it were a folder called "-b-",

    But what if you have a junction point called "[-b-]" to a drive?

  13. 640k says:

    First time I saw “CB_DIR” flag I thought: HACK.

    MS has had several opportunities to remove this hack altogether. The most obvious two are the 16->32 bit transition (a 15 year hell of pain for every windev). One of the more recent opportunities was the 32->64 bit hell.

    [That’s right, because the best way to get people to port their code to a new platform is to make it harder to do. (How’s that 64-bit port coming?) -Raymond]
  14. Anonymous Coward says:

    what if you have a junction point

    I think you’ve got enough information to figure that out. If not, try it.

    First time I saw "CB_DIR" flag I thought: HACK.

    With the benefit of hindsight, yes. You have to realise however that in the Windows 1.0 era programs did their own file open dialogue, like in DOS. And displaying file lists as simple text lists also was the norm for DOS programs, so it must have seemed sensible at the time to add a message for this commonly used functionality. Although I have to say that the dialogues in the first Notepad are hilariously bad, even for the time.

Comments are closed.