Click here to Skip to main content
15,885,216 members
Articles / Desktop Programming / MFC
Article

MFC 7.0 Assertion Bug in CToolBar::CreateEx(...), CControlBar::SetBarStyle(...) and others

Rate me:
Please Sign up or sign in to vote.
4.11/5 (3 votes)
25 Feb 20021 min read 70.8K   28   4
This is a buggy ASSERT statement that limits the number of docking flags to one.

Introduction

I was recently going through the process of trying some code with MFC 7.0 when I stumbled on the following statement in CControlBar::SetBarStyle(...):

ASSERT((dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_TOP ||
       (dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_BOTTOM ||
       (dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_LEFT ||
       (dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_RIGHT);
Now let’s go to the MFC documentation and find out what those flags mean:
  • CBRS_ALIGN_TOP Allows the control bar to be docked to the top of the client area of a frame window.
  • CBRS_ALIGN_BOTTOM Allows the control bar to be docked to the bottom of the client area of a frame window.
  • CBRS_ALIGN_LEFT Allows the control bar to be docked to the left side of the client area of a frame window.
  • CBRS_ALIGN_RIGHT Allows the control bar to be docked to the right side of the client area of a frame window.
  • CBRS_ALIGN_ANY Allows the control bar to be docked to any side of the client area of a frame window.
On a first glance it looks like the purpose of the ASSERT statement is to make sure that at least one of the docking flag is set. But this is wrong! This statement is actually an exclusive OR - it will assert unless only one of the docking styles is set! It is clear to see why:

Let's say that we want our toolbar to be able to dock on the top and left sides of the frame window. So we need to call CControlBar::SetBarStyle(...) with the following flags:

m_ToolBar.SetBarStyle(CBRS_ALIGN_TOP | CBRS_ALIGN_LEFT);
So substituting the actual hex values from afxres.h we get:
ASSERT((0x3000 & 0xF000) == 0x2000 ||
       (0x3000 & 0xF000) == 0x8000 ||
       (0x3000 & 0xF000) == 0x1000 ||
       (0x3000 & 0xF000) == 0x4000);
This becomes:
ASSERT(0x3000 == 0x2000 ||
       0x3000 == 0x8000 ||
       0x3000 == 0x1000 ||
       0x3000 == 0x4000);
From here it is clear that this is equivalent to:
ASSERT(FALSE);
If the genuine idea if this statement is to make sure that at least one of the docking flags is set it should be replaced with:
ASSERT((dwStyle & CBRS_ALIGN_ANY) != 0);
This ASSERT statement can be found in the following functions:
  • CReBar::Create(...)
  • CControlBar::SetBarStyle(...)
  • CDockBar::Create(...)
  • CStatusBar::CreateEx(...)
  • CToolBar::CreateEx(...)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalworkaround Pin
Patrick Hoffmann12-Jun-02 2:50
Patrick Hoffmann12-Jun-02 2:50 
GeneralRe: workaround Pin
Ivor S. Sargoytchev12-Jun-02 4:59
Ivor S. Sargoytchev12-Jun-02 4:59 
GeneralRe: workaround Pin
syojisyn30-Mar-03 2:52
syojisyn30-Mar-03 2:52 
GeneralRe: workaround Pin
conan5203-Apr-03 21:57
conan5203-Apr-03 21:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.