Click here to Skip to main content
15,883,852 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I have stared at this for too many hours. I am trying to get a simple toolbar working with a rebar control. The project is MDI, although I don't believe (but can't guarantee) that that isn't part of the issue. The rebar appears. But where the toolbar should be, nothing ever gets blitted except the button face color, evidently as a response to a WM_ERASEBKGND message of the rebar.

Digging into it, the fundamental problem I'm having is that even though the toolbar shows a width of > 1000, and a height of 22, a GetClipBox on the DC is showing the DC is set to 0, 0, 0, 0. This is in response to a reflected notification message, on the CDDS_PREPAINT portion. The rebar has no other children besides the toolbar (I have enumerated them and checked this condition).

The error is probably somewhere in the toolbar setup, but I can't see it. The relevant code in that part of the program is:

C#
bool Toolbar1::setup() {
   if (!toolbarC.createWindowEx()) return false;
   int resourceID = ID_TOOLBAR0; //Just for convenience, so I'll be less tempted to mistype

   //First, setup the image list.  This step loads the bitmap into the program, but doesn't
   //do anything else.
   if (!toolbarC.initializeImageList(resourceID)) return false;

   //Next, load the image into the imagelist:
   //Use the new C++11 vector initialization.  If using an older compiler, will need to
   //rewrite as outlined at http://www.cplusplus.com/reference/vector/vector/vector/
   //This brevity and clarity is one good reason to upgrade to the new standard.

   //The following constants are entered in the order of the icons in the resource:
   std::vector<int> ids = { DwlNewFile, DwlNewProject, DwlSaveFile, DwlOpenFile, DwlCppFile,
                       DwlHeaderFile };

   if (!toolbarC.addMaskedImages(ids, RGB(192, 192, 192))) return false;

   //Before adding stuff to the toolbar, we need to tell it what to expect
   if (!toolbarC.initialize()) return false;

   //Now add some buttons to the toolbar:
   DwlImageCtrl & imgCtrl = *toolbarC.imageControl();  //For '.' instead of '->' convenience
   if (!toolbarC.addButton(imgCtrl.getImagePos(DwlNewFile), fileNewC.id())) return false;
   if (!toolbarC.addButton(imgCtrl.getImagePos(DwlNewProject), fileNewC.id())) return false;

   //And do some toolbar post-image-creation toolbar setup:
   LRESULT r = (BOOL)SendMessage(toolbarC.hwnd(), TB_SETBITMAPSIZE, 0L, MAKELPARAM(16, 16));
   r = SendMessage(toolbarC.hwnd(), TB_SETBUTTONSIZE, 0L, MAKELPARAM(16+7, 16));
   r = SendMessage(toolbarC.hwnd(), TB_AUTOSIZE, 0L, 0L);

   swc::Rect tbr = toolbarC.getWindowRect();
   toolbarC.showWindow();  //Should not need this, but for testing purposes...

   return true;
   }


The code in the toolbar class this calls:

bool DwlToolbarCtrl::createWindowEx(DWORD style) {
   swc::Rect r;   //Default to 0s is OK for this situation.
   return DwlControlWin::createWindowEx(0L, TOOLBARCLASSNAME, NULL, style,
                  r, NULL, (void*)this);
   }


bool DwlToolbarCtrl::initializeImageList(uint resourceID) {
   return imageControlC.initializeFromMultiImageResource(resourceID);
   }


bool DwlToolbarCtrl::addMaskedImages(const std::vector<int> & ids,
               COLORREF transparentColor) {
   return (imageControlC.addMaskedMultiImageResource(ids, transparentColor));
   }


bool DwlToolbarCtrl::initialize() {
   //This does the actual initialization of the toolbar itself, after the pre-initialization
   //of the imagelist has taken place.  This needs to be called after the 'initializeImageList' function.

   //First, we need to setup a TB_BUTTONSTRUCTSIZE array to tell the toolbar some necessary
   //information:

   SendMessage(hwndC, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0L);
   TBADDBITMAP tbab;
   tbab.hInst = gDwlApp->hInst();
   tbab.nID = (UINT_PTR)imageControlC.resourceNum();
   int numImages = imageControlC.numImages();
   DWORD r = (int)SendMessage(hwndC, TB_ADDBITMAP, (WPARAM)numImages, (LPARAM)&tbab);
   if (r == -1) return false;
   return true;
   }

         
bool DwlToolbarCtrl::addButton(int imagePos, int callbackId) {
   if (imagePos == -1) return false;
   TBBUTTON b;
   b.iBitmap = imagePos;
   b.idCommand = callbackId;
   b.fsState = TBSTATE_ENABLED;
   b.fsStyle = TBSTYLE_BUTTON;
   b.dwData = 0;
   b.iString = 0;
   BOOL res = SendMessage(hwndC, TB_ADDBUTTONS, 1, (LPARAM)&b);
   if (res == FALSE) {
      wString str = dwl::lastSysError();
      int i=0;
      return false;
      }
   return true;
   }


No error codes are being flagged during this. In the CDDS_PREPAINT handler is where the 0-sized DC is occurring:

LRESULT DwlToolbarCtrlEx::wPrePaint(NMCUSTOMDRAW * ptr, BOOL & notify) {
   BOOL t = IsWindowVisible(hwndC);
   swc::Rect r = getWindowRect();
   SwcGdi dc(ptr->hdc);
   swc::Rect rc = ptr->rc;

   swc::Rect tt(dwl::getClipBox(dc.dcC));
   dc.FloodFill(0, 0, RGB(255,255,255));

   return CDRF_NOTIFYITEMDRAW;
   }


The 'tt' test rectangle is the perplexing 0 result. The FloodFill doesn't make anything white.

Another, probably related symptom is that CDDS_ITEMPREPAINT handler is never called for the toolbar. That is probably very significant, but I can't interpret it.

If you have any ideas, I will be very grateful. Once this is in place I'm working towards a vastly flicker-reduced docking framework based on Francisco Campos' Pretty WinAPI Class[^], if everything works out. It will become an article on CP which other frameworks can draw from if they desire. I'm tired of flickery windows resizing!

Thanks,
David
Posted

Not a solution, but thanks to the previous post I was able to obtain a major clue. Staring at the post I saw, "The project is MDI, although I don't believe (but can't guarantee) that that isn't part of the issue."

Changed it to SDI and the bar updates properly! So I'm a little fresher on the problem!
 
Share this answer
 
v2
The problem was a combination of little things that made for a nightmare debug session. Part of it was the (not-so) simple difference between 'bool' and 'BOOL' return types in other parts of the code. Still not certain I got everything, because button 'hover' doesn't stay focused properly - it quickly unfocuses when the mouse is stopped over it. But at least they no longer disappear.

Was surprised to find that 'TB_GETIDEALSIZE' resulted in the toolbar changing from horizontal to vertical. Maybe that's a sign something's still amiss.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900