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:
bool Toolbar1::setup() {
if (!toolbarC.createWindowEx()) return false;
int resourceID = ID_TOOLBAR0;
if (!toolbarC.initializeImageList(resourceID)) return false;
std::vector<int> ids = { DwlNewFile, DwlNewProject, DwlSaveFile, DwlOpenFile, DwlCppFile,
DwlHeaderFile };
if (!toolbarC.addMaskedImages(ids, RGB(192, 192, 192))) return false;
if (!toolbarC.initialize()) return false;
DwlImageCtrl & imgCtrl = *toolbarC.imageControl();
if (!toolbarC.addButton(imgCtrl.getImagePos(DwlNewFile), fileNewC.id())) return false;
if (!toolbarC.addButton(imgCtrl.getImagePos(DwlNewProject), fileNewC.id())) return false;
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();
return true;
}
The code in the toolbar class this calls:
bool DwlToolbarCtrl::createWindowEx(DWORD style) {
swc::Rect r;
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() {
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