Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
rebar.c
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 134k
Category:
Windows Kernel
Development Platform:
Visual C++
- #include "ctlspriv.h"
- #include "rebar.h"
- #include "image.h"
- #ifdef DEBUG
- int ExprASSERT(int e);
- BOOL RBCheckRangePtr(PRB prb, PRBB prbb);
- BOOL RBCheckRangeInd(PRB prb, INT_PTR i);
- #else
- #define ExprASSERT(e) 0
- #define RBCheckRangePtr(prb, prbb) 0
- #define RBCheckRangeInd(prb, i) 0
- #endif
- #define RBBUSECHEVRON(prb, prbb) ((prbb->fStyle & RBBS_USECHEVRON) &&
- !((prbb)->fStyle & RBBS_FIXEDSIZE) &&
- ((UINT)(prbb)->cxIdeal > (prbb)->cxMinChild))
- #define RBSHOWTEXT(prbb) (!(prbb->fStyle&RBBS_HIDETITLE) && prbb->lpText && prbb->lpText[0])
- #define CX_CHEVRON (5 * g_cxEdge + 2)
- #define CX_OFFSET (2 * g_cxEdge)
- #define RB_GRABWIDTH 5
- #define RB_ISVERT(prb) ((prb)->ci.style & CCS_VERT)
- #define RB_ISVERTICALGRIPPER(prb) (RB_ISVERT(prb) && (prb)->ci.style & RBS_VERTICALGRIPPER)
- #define RB_GETLASTBAND(prb) ((prb)->cBands ? RBGETBAND(prb, (prb)->cBands -1) : NULL)
- #define RBISBANDSTARTOFROW(prbb) (!((prbb)->x) && !((prbb)->fStyle & RBBS_HIDDEN))
- #define RBGETBAND(prb, i) (ExprASSERT(RBCheckRangeInd(prb, i)), &(prb)->rbbList[i])
- #define RBISSTARTOFROW(prb, i) (RBISBANDSTARTOFROW( RBGETBAND((prb), (i))))
- #define RBGETFIRSTBAND(prb) (RBGETBAND(prb, 0))
- #define RBBANDTOINDEX(prb, prbb) ((int)((prbb) - (prb)->rbbList))
- #define RBBHEADERWIDTH(prbb) ((prbb)->cxMin - ((prbb)->cxMinChild + ((RBBUSECHEVRON(prb, prbb) ? CX_CHEVRON : 0))))
- #define RBISBANDVISIBLE(prbb) (!((prbb)->fStyle & RBBS_HIDDEN))
- #define RBROWATMINHEIGHT(prb, pprbb) (!RBGetRowHeightExtra(prb, pprbb, NULL))
- #define RBGETBARHEIGHT(prb) (((prb)->cBands && !(prb)->cy) ? RBRecalc(prb) : (prb)->cy)
- #define RB_ISVALIDINDEX(prb, i) ((UINT)i < (prb)->cBands)
- #define RB_ISVALIDBAND(prb, prbb) RB_ISVALIDINDEX(prb, RBBANDTOINDEX(prb, prbb))
- #define RB_ANIMSTEPS 10
- #define RB_ANIMSTEPTIME 5
- void FlipRect(LPRECT prc);
- void RBPassBreak(PRB prb, PRBB prbbSrc, PRBB prbbDest);
- int RBHitTest(PRB prb, LPRBHITTESTINFO prbht);
- BOOL RBSizeBandsToRect(PRB prb, LPRECT prc);
- BOOL RBShouldDrawGripper(PRB prb, PRBB prbb);
- void RBAutoSize(PRB prb);
- void RBSizeBandsToRowHeight(PRB prb);
- void RBSizeBandToRowHeight(PRB prb, int i, UINT uRowHeight);
- BOOL RBSetBandPos(PRB prb, PRBB prbb, int xLeft);
- BOOL RBSetBandPosAnim(PRB prb, PRBB prbb, int xLeft);
- PRBB RBGetFirstInRow(PRB prb, PRBB prbbRow);
- PRBB RBGetLastInRow(PRB prb, PRBB prbbRow, BOOL fStopAtFixed);
- PRBB RBGetPrev(PRB prb, PRBB prbb, UINT uStyleSkip);
- PRBB RBGetNext(PRB prb, PRBB prbb, UINT uStyleSkip);
- PRBB RBEnumBand(PRB prb, int i, UINT uStyleSkip);
- int RBCountBands(PRB prb, UINT uStyleSkip);
- BOOL RBMaximizeBand(PRB prb, UINT uBand, BOOL fIdeal, BOOL fAnim);
- PRBB RBGetNextVisible(PRB prb, PRBB prbb);
- PRBB RBGetPrevVisible(PRB prb, PRBB prbb);
- PRBB RBBNextVisible(PRB prb, PRBB prbb);
- BOOL RBShowBand(PRB prb, UINT uBand, BOOL fShow);
- void RBGetClientRect(PRB prb, LPRECT prc);
- int RBGetRowHeightExtra(PRB prb, PRBB *pprbb, PRBB prbbSkip);
- void RBOnBeginDrag(PRB prb, UINT uBand);
- #define RBBANDWIDTH(prb, prbb) _RBBandWidth(prb, prbb->cx)
- #ifdef DEBUG
- #undef RBBANDWIDTH
- #define RBBANDWIDTH(prb, prbb)
- ((prbb->fStyle & RBBS_HIDDEN) ? (ExprASSERT(0), -1) :
- _RBBandWidth(prb, prbb->cx))
- #endif
- #define RBBANDMINWIDTH(prb, prbb) _RBBandWidth(prb, prbb->cxMin)
- #ifdef DEBUG
- #undef RBBANDMINWIDTH
- #define RBBANDMINWIDTH(prb, prbb)
- ((prbb->fStyle & RBBS_HIDDEN) ? (ExprASSERT(0), -1) :
- _RBBandWidth(prb, prbb->cxMin))
- #endif
- //*** RBC_* -- commands
- #define RBC_QUERY 0
- #define RBC_SET 1
- #ifdef DEBUG
- int ExprASSERT(int e)
- {
- ASSERT(e);
- return 0;
- }
- #endif
- HBRUSH g_hDPFRBrush = NULL;
- __inline COLORREF RB_GetBkColor(PRB prb)
- {
- if (prb->clrBk == CLR_DEFAULT)
- return g_clrBtnFace;
- else
- return prb->clrBk;
- }
- __inline COLORREF RB_GetTextColor(PRB prb)
- {
- if (prb->clrText == CLR_DEFAULT)
- return g_clrBtnText;
- else
- return prb->clrText;
- }
- __inline COLORREF RBB_GetBkColor(PRB prb, PRBB prbb)
- {
- switch(prbb->clrBack)
- {
- case CLR_NONE:
- // CLR_NONE means "use our dad's color"
- return RB_GetBkColor(prb);
- case CLR_DEFAULT:
- return g_clrBtnFace;
- default:
- return prbb->clrBack;
- }
- }
- __inline COLORREF RBB_GetTextColor(PRB prb, PRBB prbb)
- {
- switch (prbb->clrFore)
- {
- case CLR_NONE:
- // CLR_NONE means "use our dad's color"
- return RB_GetTextColor(prb);
- case CLR_DEFAULT:
- return g_clrBtnText;
- default:
- return prbb->clrFore;
- }
- }
- //
- // Our use of CLR_DEFAULT for the band background colors is new for
- // version 5.01. Since we don't want to confuse apps by returning
- // CLR_DEFAULT when they used to see a real colorref, we convert it
- // before returning it to them. If the background color is CLR_NONE,
- // though, we need to return it without conversion (like version 4 did).
- // The *_External functions handle these cases.
- //
- __inline COLORREF RBB_GetTextColor_External(PRB prb, PRBB prbb)
- {
- if (prbb->clrFore == CLR_NONE)
- return CLR_NONE;
- else
- return RBB_GetTextColor(prb, prbb);
- }
- __inline COLORREF RBB_GetBkColor_External(PRB prb, PRBB prbb)
- {
- if (prbb->clrBack == CLR_NONE)
- return CLR_NONE;
- else
- return RBB_GetBkColor(prb, prbb);
- }
- ///
- //
- // Implement MapWindowPoints as if the hwndFrom and hwndTo aren't
- // mirrored. This is used when any of the windows (hwndFrom or hwndTo)
- // are mirrored. See below. [samera]
- //
- int TrueMapWindowPoints(HWND hwndFrom, HWND hwndTo, LPPOINT lppt, UINT cPoints)
- {
- int dx, dy;
- RECT rcFrom={0,0,0,0}, rcTo={0,0,0,0};
- if (hwndFrom) {
- GetClientRect(hwndFrom, &rcFrom);
- MapWindowPoints(hwndFrom, NULL, (LPPOINT)&rcFrom.left, 2);
- }
- if (hwndTo) {
- GetClientRect(hwndTo, &rcTo);
- MapWindowPoints(hwndTo, NULL, (LPPOINT)&rcTo.left, 2);
- }
- dx = rcFrom.left - rcTo.left;
- dy = rcFrom.top - rcTo.top;
- /*
- * Map the points
- */
- while (cPoints--) {
- lppt->x += dx;
- lppt->y += dy;
- ++lppt;
- }
- return MAKELONG(dx, dy);
- }
- ///
- //
- // Map a rect to parent should be based on the visual right edge
- // for calculating the client coordinates for a RTL mirrored windows.
- // This routine should only be used when calculating client
- // coordinates in a RTL mirrored window. [samera]
- //
- BOOL MapRectInRTLMirroredWindow( LPRECT lprc, HWND hwnd)
- {
- int iWidth = lprc->right - lprc->left;
- int iHeight = lprc->bottom- lprc->top;
- RECT rc={0,0,0,0};
- if (hwnd) {
- GetClientRect(hwnd, &rc);
- MapWindowPoints(hwnd, NULL, (LPPOINT)&rc.left, 2);
- }
- lprc->left = rc.right - lprc->right;
- lprc->top = lprc->top-rc.top;
- lprc->bottom = lprc->top + iHeight;
- lprc->right = lprc->left + iWidth;
- return TRUE;
- }
- int _RBBandWidth(PRB prb, int x)
- {
- if (prb->ci.style & RBS_BANDBORDERS)
- x += g_cxEdge;
- return x;
- }
- void RBRealize(PRB prb, HDC hdcParam, BOOL fBackground, BOOL fForceRepaint)
- {
- if (prb->hpal)
- {
- HDC hdc = hdcParam ? hdcParam : GetDC(prb->ci.hwnd);
- if (hdc)
- {
- BOOL fRepaint;
- SelectPalette(hdc, prb->hpal, fBackground);
- fRepaint = RealizePalette(hdc) || fForceRepaint;
- if (!hdcParam)
- ReleaseDC(prb->ci.hwnd, hdc);
- if (fRepaint)
- {
- InvalidateRect(prb->ci.hwnd, NULL, TRUE);
- }
- }
- }
- }
- //////////////////////////////////////////////////////////////////
- // RBSendNotify
- //
- // sends a wm_notify of code iCode and packages up all the data for you
- // for band uBand
- //
- //////////////////////////////////////////////////////////////////
- LRESULT RBSendNotify(PRB prb, UINT uBand, int iCode)
- {
- NMREBAR nm = {0};
- nm.uBand = uBand;
- if (uBand != (UINT)-1) {
- nm.dwMask = RBNM_ID | RBNM_STYLE | RBNM_LPARAM;
- nm.wID = RBGETBAND(prb, uBand)->wID;
- nm.fStyle = RBGETBAND(prb, uBand)->fStyle;
- nm.lParam = RBGETBAND(prb, uBand)->lParam;
- }
- return CCSendNotify(&prb->ci, iCode, &nm.hdr);
- }
- BOOL RBInvalidateRect(PRB prb, RECT* prc)
- {
- if (prb->fRedraw)
- {
- RECT rc;
- if (prc && RB_ISVERT(prb))
- {
- CopyRect(&rc, prc);
- FlipRect(&rc);
- prc = &rc;
- }
- prb->fRefreshPending = FALSE;
- InvalidateRect(prb->ci.hwnd, prc, TRUE);
- return TRUE;
- }
- else
- {
- prb->fRefreshPending = TRUE;
- return FALSE;
- }
- }
- LRESULT RebarDragCallback(HWND hwnd, UINT code, WPARAM wp, LPARAM lp)
- {
- PRB prb = (PRB)GetWindowPtr(hwnd, 0);
- LRESULT lres;
- switch (code)
- {
- case DPX_DRAGHIT:
- if (lp)
- {
- int iBand;
- RBHITTESTINFO rbht;
- rbht.pt.x = ((POINTL *)lp)->x;
- rbht.pt.y = ((POINTL *)lp)->y;
- MapWindowPoints(NULL, prb->ci.hwnd, &rbht.pt, 1);
- iBand = RBHitTest(prb, &rbht);
- *(DWORD*)wp = rbht.flags;
- lres = (LRESULT)(iBand != -1 ? prb->rbbList[iBand].wID : -1);
- }
- else
- lres = -1;
- break;
- case DPX_GETOBJECT:
- lres = (LRESULT)GetItemObject(&prb->ci, RBN_GETOBJECT, &IID_IDropTarget, (LPNMOBJECTNOTIFY)lp);
- break;
- default:
- lres = -1;
- break;
- }
- return lres;
- }
- // ----------------------------------------------------------------------------
- //
- // RBCanBandMove
- //
- // returns TRUE if the given band can be moved and FALSE if it cannot
- //
- // ----------------------------------------------------------------------------
- BOOL RBCanBandMove(PRB prb, PRBB prbb)
- {
- // If there is only one visible band it cannot move
- if (RBEnumBand(prb, 1, RBBS_HIDDEN) > RB_GETLASTBAND(prb))
- return FALSE;
- ASSERT(!(prbb->fStyle & RBBS_HIDDEN));
- if ((prb->ci.style & RBS_FIXEDORDER)
- && (prbb == RBEnumBand(prb, 0, RBBS_HIDDEN)))
- // the first (visible) band in fixed order rebars can't be moved
- return(FALSE);
- // fixed size bands can't be moved
- return(!(prbb->fStyle & RBBS_FIXEDSIZE));
- }
- // ----------------------------------------------------------------------------
- //
- // RBBCalcMinWidth
- //
- // calculates minimum width for the given band
- //
- // ----------------------------------------------------------------------------
- void RBBCalcMinWidth(PRB prb, PRBB prbb)
- {
- BOOL fDrawGripper = RBShouldDrawGripper(prb, prbb);
- BOOL fVertical;
- int cEdge;
- BOOL fEmpty = ((prbb->iImage == -1) && (!RBSHOWTEXT(prbb)));
- if (prbb->fStyle & RBBS_HIDDEN) {
- ASSERT(0);
- return;
- }
- // did the user specify the size explicitly?
- if (prbb->fStyle & RBBS_FIXEDHEADERSIZE)
- return;
- prbb->cxMin = prbb->cxMinChild;
- if (RBBUSECHEVRON(prb, prbb))
- prbb->cxMin += CX_CHEVRON;
- if (!fDrawGripper && fEmpty)
- return;
- fVertical = (prb->ci.style & CCS_VERT);
- if (RB_ISVERTICALGRIPPER(prb)) {
- prbb->cxMin += 4 * g_cyEdge;
- prbb->cxMin += max(prb->cyImage, prb->cyFont);
- } else {
- cEdge = fVertical ? g_cyEdge : g_cxEdge;
- prbb->cxMin += 2 * cEdge;
- if (fDrawGripper)
- {
- prbb->cxMin += RB_GRABWIDTH * (fVertical ? g_cyBorder : g_cxBorder);
- if (fEmpty)
- return;
- }
- prbb->cxMin += 2 * cEdge;
- if (prbb->iImage != -1)
- prbb->cxMin += (fVertical ? prb->cyImage : prb->cxImage);
- if (RBSHOWTEXT(prbb))
- {
- if (fVertical)
- prbb->cxMin += prb->cyFont;
- else
- prbb->cxMin += prbb->cxText;
- if (prbb->iImage != -1)
- // has both image and text -- add in edge between 'em
- prbb->cxMin += cEdge;
- }
- }
- }
- BOOL RBShouldDrawGripper(PRB prb, PRBB prbb)
- {
- if (prbb->fStyle & RBBS_NOGRIPPER)
- return FALSE;
- if ((prbb->fStyle & RBBS_GRIPPERALWAYS) || RBCanBandMove(prb, prbb))
- return TRUE;
- return FALSE;
- }
- // ----------------------------------------------------------------------------
- //
- // RBBCalcTextExtent
- //
- // computes the horizontal extent of the given band's title text in the current
- // title font for the rebar
- //
- // returns TRUE if text extent changed, FALSE otherwise
- //
- // ----------------------------------------------------------------------------
- BOOL RBBCalcTextExtent(PRB prb, PRBB prbb, HDC hdcIn)
- {
- HDC hdc = hdcIn;
- HFONT hFontOld;
- UINT cx;
- if (prbb->fStyle & RBBS_HIDDEN)
- {
- ASSERT(0); // caller should have skipped
- return FALSE;
- }
- if (!RBSHOWTEXT(prbb))
- {
- cx = 0;
- }
- else
- {
- if (!hdcIn && !(hdc = GetDC(prb->ci.hwnd)))
- return FALSE;
- hFontOld = SelectObject(hdc, prb->hFont);
- // for clients >= v5, we draw text with prefix processing (& underlines next char)
- if (prb->ci.iVersion >= 5)
- {
- RECT rc = {0,0,0,0};
- DrawText(hdc, prbb->lpText, lstrlen(prbb->lpText), &rc, DT_CALCRECT);
- cx = RECTWIDTH(rc);
- }
- else
- {
- SIZE size;
- GetTextExtentPoint(hdc, prbb->lpText, lstrlen(prbb->lpText), &size);
- cx = size.cx;
- }
- SelectObject(hdc, hFontOld);
- if (!hdcIn)
- ReleaseDC(prb->ci.hwnd, hdc);
- }
- if (prbb->cxText != cx)
- {
- prbb->cxText = cx;
- RBBCalcMinWidth(prb, prbb);
- return TRUE;
- }
- return FALSE;
- }
- // ----------------------------------------------------------------------------
- //
- // RBBGetHeight
- //
- // returns minimum height for the given band
- // TODO: make this a field in the band structure instead of always calling this
- //
- // ----------------------------------------------------------------------------
- UINT RBBGetHeight(PRB prb, PRBB prbb)
- {
- UINT cy = 0;
- BOOL fVertical = (prb->ci.style & CCS_VERT);
- UINT cyCheck, cyBorder;
- cyBorder = (fVertical ? g_cxEdge : g_cyEdge) * 2;
- if (prbb->hwndChild)
- {
- cy = prbb->cyChild;
- if (!(prbb->fStyle & RBBS_CHILDEDGE))
- // add edge to top and bottom of child window
- cy -= cyBorder;
- }
- if (RBSHOWTEXT(prbb) && !fVertical)
- {
- cyCheck = prb->cyFont;
- if (cyCheck > cy)
- cy = cyCheck;
- }
- if (prbb->iImage != -1)
- {
- cyCheck = (fVertical) ? prb->cxImage : prb->cyImage;
- if (cyCheck > cy)
- cy = cyCheck;
- }
- return(cy + cyBorder);
- }
- // ----------------------------------------------------------------------------
- //
- // RBGetRowCount
- //
- // returns the number of rows in the rebar's current configuration
- //
- // ----------------------------------------------------------------------------
- UINT RBGetRowCount(PRB prb)
- {
- UINT i;
- UINT cRows = 0;
- for (i = 0; i < prb->cBands; i++) {
- if (RBGETBAND(prb, i)->fStyle & RBBS_HIDDEN)
- continue;
- if (RBISSTARTOFROW(prb, i))
- cRows++;
- }
- return(cRows);
- }
- // ----------------------------------------------------------------------------
- //
- // RBGetLineHeight
- //
- // returns the height of the line of bands from iStart to iEnd, inclusively
- //
- // ----------------------------------------------------------------------------
- UINT RBGetLineHeight(PRB prb, UINT iStart, UINT iEnd)
- {
- UINT cy = 0;
- PRBB prbb;
- UINT cyBand;
- if (!(prb->ci.style & RBS_VARHEIGHT))
- {
- // for fixed height bars, line height is maximum height of ALL bands
- iStart = 0;
- iEnd = prb->cBands - 1;
- }
- for (prbb = prb->rbbList + iStart; iStart <= iEnd; prbb++, iStart++)
- {
- if (prbb->fStyle & RBBS_HIDDEN)
- continue;
- cyBand = RBBGetHeight(prb, prbb);
- cy = max(cy, cyBand);
- }
- return(cy);
- }
- // RBRecalcChevron: update & refresh chevron
- void RBRecalcChevron(PRB prb, PRBB prbb, BOOL fChevron)
- {
- RECT rcChevron;
- if (fChevron)
- {
- rcChevron.right = prbb->x + prbb->cx;
- rcChevron.left = rcChevron.right - CX_CHEVRON;
- rcChevron.top = prbb->y;
- rcChevron.bottom = rcChevron.top + prbb->cy;
- }
- else
- SetRect(&rcChevron, -1, -1, -1, -1);
- if (!EqualRect(&rcChevron, &prbb->rcChevron))
- {
- if (prbb->fChevron)
- RBInvalidateRect(prb, &prbb->rcChevron);
- prbb->fChevron = fChevron;
- CopyRect(&prbb->rcChevron, &rcChevron);
- if (prbb->fChevron)
- RBInvalidateRect(prb, &prbb->rcChevron);
- }
- }
- // ----------------------------------------------------------------------------
- //
- // RBResizeChildren
- //
- // resizes children to fit properly in their respective bands' bounding rects
- //
- // ----------------------------------------------------------------------------
- void RBResizeChildren(PRB prb)
- {
- int cx, cy, x, y, cxHeading;
- HDWP hdwp;
- BOOL fVertical = (prb->ci.style & CCS_VERT);
- PRBB prbb, prbbEnd;
- if (!prb->cBands || !prb->fRedraw)
- return;
- hdwp = BeginDeferWindowPos(prb->cBands);
- prbb = RBGETBAND(prb, 0);
- prbbEnd = RB_GETLASTBAND(prb);
- for ( ; prbb <= prbbEnd ; prbb++)
- {
- NMREBARCHILDSIZE nm;
- BOOL fChevron = FALSE;
- if (prbb->fStyle & RBBS_HIDDEN)
- continue;
- if (!prbb->hwndChild)
- continue;
- cxHeading = RBBHEADERWIDTH(prbb);
- x = prbb->x + cxHeading;
- cx = prbb->cx - cxHeading;
- // if we're not giving child ideal size, make space for chevron button
- if ((cx < prbb->cxIdeal) && RBBUSECHEVRON(prb, prbb))
- {
- fChevron = TRUE;
- cx -= CX_CHEVRON;
- }
- if (!(prbb->fStyle & RBBS_FIXEDSIZE)) {
- if (fVertical) {
- PRBB prbbNext = RBBNextVisible(prb, prbb);
- if (prbbNext && !RBISBANDSTARTOFROW(prbbNext))
- cx -= g_cyEdge * 2;
- } else
- cx -= CX_OFFSET;
- }
- if (cx < 0)
- cx = 0;
- y = prbb->y;
- cy = prbb->cy;
- if (prbb->cyChild && (prbb->cyChild < (UINT) cy))
- {
- y += (cy - prbb->cyChild) / 2;
- cy = prbb->cyChild;
- }
- nm.rcChild.left = x;
- nm.rcChild.top = y;
- nm.rcChild.right = x + cx;
- nm.rcChild.bottom = y + cy;
- nm.rcBand.left = prbb->x + RBBHEADERWIDTH(prbb);
- nm.rcBand.right = prbb->x + prbb->cx;
- nm.rcBand.top = prbb->y;
- nm.rcBand.bottom = prbb->y + prbb->cy;
- nm.uBand = RBBANDTOINDEX(prb, prbb);
- nm.wID = prbb->wID;
- if (fVertical) {
- FlipRect(&nm.rcChild);
- FlipRect(&nm.rcBand);
- }
- CCSendNotify(&prb->ci, RBN_CHILDSIZE, &nm.hdr);
- if (!RB_ISVALIDBAND(prb, prbb)) {
- // somebody responded to notify by nuking bands; bail
- break;
- }
- RBRecalcChevron(prb, prbb, fChevron);
- DeferWindowPos(hdwp, prbb->hwndChild, NULL, nm.rcChild.left, nm.rcChild.top,
- RECTWIDTH(nm.rcChild), RECTHEIGHT(nm.rcChild), SWP_NOZORDER);
- }
- EndDeferWindowPos(hdwp);
- //
- // The SQL 7.0 Enterprise Manager Data Transformation Services MMC Snap-In
- // (and the Visual Basic Coolbar Sample App, too) is stupid.
- // It hosts a rebar but doesn't set the WS_CLIPCHILDREN flag,
- // so when it erases its background, it wipes out the rebar. So don't
- // call UpdateWindow() here, or we will paint *first*, then SQL will
- // erase us by mistake. We have to leave our paint pending, so that
- // when SQL erases us by mistake, we will eventually get a WM_PAINT
- // message afterwards.
- //
- #if 0
- UpdateWindow(prb->ci.hwnd);
- #endif
- }
- // ----------------------------------------------------------------------------
- //
- // RBMoveBand
- //
- // moves the band from one position to another in the rebar's band array,
- // updating the rebar's iCapture field as needed
- //
- // returns TRUE or FALSE if something moved
- // ----------------------------------------------------------------------------
- BOOL RBMoveBand(PRB prb, UINT iFrom, UINT iTo)
- {
- RBB rbbMove;
- int iShift;
- BOOL fCaptureChanged = (prb->iCapture == -1);
- if (iFrom != iTo)
- {
- rbbMove = *RBGETBAND(prb, iFrom);
- if (prb->iCapture == (int) iFrom)
- {
- prb->iCapture = (int) iTo;
- fCaptureChanged = TRUE;
- }
- iShift = (iFrom > iTo) ? -1 : 1;
- while (iFrom != iTo)
- {
- if (!fCaptureChanged && (prb->iCapture == (int) (iFrom + iShift)))
- {
- prb->iCapture = (int) iFrom;
- fCaptureChanged = TRUE;
- }
- *RBGETBAND(prb, iFrom) = *RBGETBAND(prb, iFrom + iShift);
- iFrom += iShift;
- }
- *RBGETBAND(prb, iTo) = rbbMove;
- return TRUE;
- }
- return(FALSE);
- }
- // ----------------------------------------------------------------------------
- //
- // RBRecalc
- //
- // recomputes bounding rects for all bands in given rebar
- //
- // ----------------------------------------------------------------------------
- UINT RBRecalc(PRB prb)
- {
- PRBB prbb = RBGETBAND(prb, 0);
- PRBB prbbWalk;
- UINT cHidden; // # of hidden guys we've seen in current row
- UINT cxRow;
- UINT cxMin;
- UINT i;
- UINT j;
- UINT k;
- UINT iFixed = 0xFFFF;
- int cy;
- int y;
- int x;
- UINT cxBar;
- RECT rc;
- HWND hwndSize;
- BOOL fNewLine = FALSE;
- BOOL fChanged;
- BOOL fVertical = (prb->ci.style & CCS_VERT);
- BOOL fBandBorders;
- int iBarWidth;
- if (!prb->cBands)
- return(0);
- if ((prb->ci.style & CCS_NORESIZE) || (prb->ci.style & CCS_NOPARENTALIGN))
- // size based on rebar window itself
- hwndSize = prb->ci.hwnd;
- else if (!(hwndSize = prb->ci.hwndParent))
- // size based on parent window -- if no parent window, bail now
- return(0);
- if (!prb->fRecalc) {
- // defer this recalc
- prb->fRecalcPending = TRUE;
- return 0;
- } else {
- prb->fRecalcPending = FALSE;
- }
- GetClientRect(hwndSize, &rc);
- iBarWidth = (fVertical ? (rc.bottom - rc.top) : (rc.right - rc.left));
- // this can happen because we adjust the client rect, but wedon't change
- // the getminmaxinfo.
- if (iBarWidth <= 0)
- iBarWidth = 1;
- cxBar = (UINT) iBarWidth;
- fBandBorders = (prb->ci.style & RBS_BANDBORDERS);
- for (i = 0; i < prb->cBands; i++) {
- prb->rbbList[i].cx = prb->rbbList[i].cxRequest;
- }
- y = 0;
- i = 0;
- // Main Loop -- loop until all bands are calculated
- while (i < prb->cBands)
- {
- TraceMsg(TF_REBAR, "RBRecalc: outer loop i=%d", i);
- if (fBandBorders && (y > 0))
- y += g_cyEdge;
- ReLoop:
- cxRow = 0;
- cxMin = 0;
- x = 0;
- cHidden = 0;
- // Row Loop -- loop until hard line break is found or soft line break
- // is necessary
- for (j = i, prbbWalk = prbb; j < prb->cBands; j++, prbbWalk++)
- {
- TraceMsg(TF_REBAR, "RBRecalc: inner loop j=%d", j);
- if (prbbWalk->fStyle & RBBS_HIDDEN) {
- ++cHidden;
- continue;
- }
- if (j > i + cHidden)
- {
- // not the first band in the row -- check for break style
- if ((prbbWalk->fStyle & RBBS_BREAK) && !(prbbWalk->fStyle & RBBS_FIXEDSIZE))
- break;
- if (fBandBorders)
- // add in space for vertical etch on palettized display
- cxMin += g_cxEdge;
- }
- if (prbbWalk->fStyle & RBBS_FIXEDSIZE)
- {
- // remember location of branding brick
- iFixed = j;
- // if this is the first band, the next band cannot have a forced break.
- if (i + cHidden == j) {
- // if the first index in the row (i) plus the number of hidden items (cHidden) leaves us at this band,
- // then it's the first visible in this row.
- PRBB prbbNextVis = RBBNextVisible(prb, prbbWalk);
- if (prbbNextVis && (prbbNextVis->fStyle & RBBS_BREAK)) {
- // can't do this unilaterally because on startup
- // some folks (net meeting) initialize it in reverse order
- // and we whack off this break bit incorrectly
- if (prb->fRedraw && IsWindowVisible(prb->ci.hwnd))
- prbbNextVis->fStyle &= ~RBBS_BREAK;
- }
- }
- prbbWalk->cx = prbbWalk->cxMin;
- }
- if (prbbWalk->cx < prbbWalk->cxMin)
- prbbWalk->cx = prbbWalk->cxMin;
- cxMin += prbbWalk->cxMin; // update running total of min widths
- // read the assert comment below
- if (j > i + cHidden)
- {
- // not the first band in row -- check for need to autobreak
- if (cxMin > cxBar)
- // autobreak here
- break;
- if (fBandBorders)
- // add in space for vertical etch on palettized display
- cxRow += g_cxEdge;
- }
- cxRow += prbbWalk->cx; // update running total of current widths
- }
- if (!i)
- {
- // first row -- handle proper placement of branding band
- if (iFixed == 0xFFFF)
- {
- // branding band not yet found; look in the remaining bands
- k = j;
- for ( ; j < prb->cBands; j++)
- {
- if (RBGETBAND(prb, j)->fStyle & RBBS_HIDDEN)
- continue;
- if (RBGETBAND(prb, j)->fStyle & RBBS_FIXEDSIZE)
- {
- // branding band found; move to 1st row and recompute
- ASSERT(j != k);
- RBMoveBand(prb, j, k);
- goto ReLoop;
- }
- }
- // no branding band found -- reset j and continue on
- j = k;
- }
- else
- // we have a branding band; move it to
- // the rightmost position in the row
- RBMoveBand(prb, iFixed, j - 1);
- TraceMsg(TF_REBAR, "RBRecalc: after brand i=%d", i);
- }
- // variant:
- // now the current row of bands is from i to j - 1
- // n.b. i (and some following bands) might be hidden
- // assert that j != i because then the above variant won't be true
- ASSERT(j != i); // BUGBUG RBBS_HIDDEN?
- if (cxRow > cxBar)
- {
- // bands are too long -- shrink bands from right to left
- for (k = i; k < j; k++)
- {
- prbbWalk--;
- if (prbbWalk->fStyle & RBBS_HIDDEN)
- continue;
- if (prbbWalk->cx > prbbWalk->cxMin)
- {
- cxRow -= prbbWalk->cx - prbbWalk->cxMin;
- prbbWalk->cx = prbbWalk->cxMin;
- if (cxRow <= cxBar)
- {
- prbbWalk->cx += cxBar - cxRow;
- break;
- }
- }
- }
- TraceMsg(TF_REBAR, "RBRecalc: after shrink i=%d", i);
- }
- else if (cxRow < cxBar)
- {
- // bands are too short -- grow rightmost non-minimized band
- for (k = j - 1; k >= i; k--)
- {
- ASSERT(k != (UINT)-1); // catch infinite loop
- prbbWalk--;
- if ((k == i) ||
- (!(prbbWalk->fStyle & (RBBS_HIDDEN | RBBS_FIXEDSIZE)) &&
- (prbbWalk->cx > prbb->cxMin)))
- {
- // the k == i check means we've made it to the first
- // band on this row and so he has to get the cx change
- if (prbbWalk->fStyle & RBBS_HIDDEN)
- {
- ASSERT(k == i);
- prbbWalk = RBBNextVisible(prb, prbbWalk);
- if (!prbbWalk)
- break;
- }
- prbbWalk->cx += cxBar - cxRow;
- break;
- }
- }
- TraceMsg(TF_REBAR, "RBRecalc: after grow i=%d", i);
- }
- // items from index i to index j-1 (inclusive) WILL fit on one line
- cy = RBGetLineHeight(prb, i, j - 1);
- fChanged = FALSE; // set if any bands on current row changed position
- for ( ; i < j; i++, prbb++)
- {
- if (prbb->fStyle & RBBS_HIDDEN)
- continue;
- // go through row of bands, updating positions and heights,
- // invalidating as needed
- if ((prbb->y != y) || (prbb->x != x) || (prbb->cy != cy))
- {
- TraceMsg(TF_REBAR, "RBRecalc: invalidate i=%d", RBBANDTOINDEX(prb, prbb));
- fChanged = TRUE;
- rc.left = min(prbb->x, x);
- rc.top = min(prbb->y, y);
- rc.right = cxBar;
- rc.bottom = max(prbb->y + prbb->cy, y + cy);
- if (fBandBorders)
- {
- // acount for etch line that will need to move
- rc.left -= g_cxEdge;
- rc.bottom += g_cyEdge/2;
- }
- RBInvalidateRect(prb, &rc);
- }
- prbb->x = x;
- prbb->y = y;
- prbb->cy = cy;
- x += RBBANDWIDTH(prb, prbb);
- }
- // i and prbb now refer to the first band in the next row of bands
- y += cy;
- }
- prb->cy = y;
- return(y);
- }
- // ----------------------------------------------------------------------------
- //
- // RBResize
- //
- // recomputes bounding rects for all bands and then resizes rebar and children
- // based on these rects
- //
- // ----------------------------------------------------------------------------
- void RBResizeNow(PRB prb)
- {
- RECT rc;
- BOOL bMirroredWnd=(prb->ci.dwExStyle&RTL_MIRRORED_WINDOW);
- if (!prb || !prb->ci.hwndParent)
- return;
- GetWindowRect(prb->ci.hwnd, &rc);
- //
- // If this is a mirrored window, we don't won't to refect the
- // coordinates since they are coming from the screen coord
- // which they are not mirrored. [samera]
- //
- if (bMirroredWnd)
- MapRectInRTLMirroredWindow(&rc, prb->ci.hwndParent);
- else
- MapWindowPoints(HWND_DESKTOP, prb->ci.hwndParent, (LPPOINT)&rc, 2);
- RBResizeChildren(prb);
- NewSize(prb->ci.hwnd, prb->cy, prb->ci.style, rc.left, rc.top, RECTWIDTH(rc), RECTHEIGHT(rc));
- if (prb->fResizeNotify)
- CCSendNotify(&prb->ci, RBN_HEIGHTCHANGE, NULL);
- prb->fResizeNotify = FALSE;
- prb->fResizePending = FALSE;
- }
- void RBResize(PRB prb, BOOL fForceHeightChange)
- {
- UINT cy;
- StartOver:
- // lots of the code relies on having cy calculated synchronously with RBResize,
- // but we're going to delay the actual changing of the window
- cy = prb->cy;
- if (prb->fResizing)
- {
- prb->fResizeRecursed = TRUE;
- return;
- }
- prb->fResizing = TRUE;
- RBRecalc(prb);
- // true overrides always
- if (fForceHeightChange || (cy != prb->cy))
- prb->fResizeNotify = TRUE;
- if (prb->fRedraw) {
- RBResizeNow(prb);
- } else
- prb->fResizePending = TRUE;
- prb->fResizing = FALSE;
- // we do this to avoid infinite loop... RBResize can cause NewSize which causes
- // a notify in which the parent sizes us, which causes us to loop.
- // if the parent does any message pumping during the NewSize, we're in a loop
- if (prb->fResizeRecursed) {
- prb->fResizeRecursed = FALSE;
- fForceHeightChange = FALSE;
- goto StartOver;
- }
- }
- void RBSetRecalc(PRB prb, BOOL fRecalc)
- {
- prb->fRecalc = fRecalc;
- if (fRecalc) {
- if (prb->fRecalcPending)
- RBRecalc(prb);
- }
- }
- BOOL RBSetRedraw(PRB prb, BOOL fRedraw)
- {
- BOOL fOld = prb->fRedraw;
- if (prb) {
- prb->fRedraw = BOOLIFY(fRedraw);
- if (fRedraw) {
- // save off prb->fRefreshPending since this can
- // get changed by call to RBResizeNow
- BOOL fRefreshPending = prb->fRefreshPending;
- if (prb->fResizePending)
- RBResizeNow(prb);
- if (fRefreshPending)
- RBInvalidateRect(prb, NULL);
- }
- }
- return fOld;
- }
- BOOL RBAfterSetFont(PRB prb)
- {
- TEXTMETRIC tm;
- BOOL fChange = FALSE;
- UINT i;
- HFONT hOldFont;
- HDC hdc = GetDC(prb->ci.hwnd);
- if (!hdc)
- return FALSE;
- hOldFont = SelectObject(hdc, prb->hFont);
- GetTextMetrics(hdc, &tm);
- if (prb->cyFont != (UINT) tm.tmHeight)
- {
- prb->cyFont = tm.tmHeight;
- fChange = TRUE;
- }
- // adjust bands
- for (i = 0; i < prb->cBands; i++)
- {
- if (RBGETBAND(prb, i)->fStyle & RBBS_HIDDEN)
- continue;
- fChange |= RBBCalcTextExtent(prb, RBGETBAND(prb, i), hdc);
- }
- SelectObject(hdc, hOldFont);
- ReleaseDC(prb->ci.hwnd, hdc);
- if (fChange)
- {
- RBResize(prb, FALSE);
- // invalidate, o.w. title doesn't redraw 1st time after font growth
- RBInvalidateRect(prb, NULL);
- }
- return TRUE;
- }
- BOOL RBOnSetFont(PRB prb, HFONT hFont)
- {
- if (prb->fFontCreated) {
- DeleteObject(prb->hFont);
- }
- prb->hFont = hFont;
- prb->fFontCreated = FALSE;
- if (!prb->hFont)
- RBSetFont(prb, 0);
- else
- return RBAfterSetFont(prb);
- return TRUE;
- }
- // ----------------------------------------------------------------------------
- //
- // RBSetFont
- //
- // sets the rebar band title font to the current system-wide caption font
- //
- // ----------------------------------------------------------------------------
- BOOL RBSetFont(PRB prb, WPARAM wParam)
- {
- NONCLIENTMETRICS ncm;
- HFONT hOldFont;
- if ((wParam != 0) && (wParam != SPI_SETNONCLIENTMETRICS))
- return(FALSE);
- ncm.cbSize = sizeof(NONCLIENTMETRICS);
- if (!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0))
- return(FALSE);
- hOldFont = prb->hFont;
- ncm.lfCaptionFont.lfWeight = FW_NORMAL;
- if (!(prb->hFont = CreateFontIndirect(&ncm.lfCaptionFont)))
- {
- prb->hFont = hOldFont;
- return(FALSE);
- }
- prb->fFontCreated = TRUE;
- if (hOldFont)
- DeleteObject(hOldFont);
- return RBAfterSetFont(prb);
- }
- // ----------------------------------------------------------------------------
- //
- // Draws a horizontal or vertical dotted line from the given (x,y) location
- // for the given length (c). (From TReeView's TV_DrawDottedLine)
- //
- // ----------------------------------------------------------------------------
- void RBVertMungeGripperRect(PRB prb, LPRECT lprc)
- {
- if (RB_ISVERTICALGRIPPER(prb)) {
- OffsetRect(lprc, -lprc->left + lprc->top, -lprc->top + lprc->left);
- lprc->bottom -= g_cyEdge;
- } else {
- FlipRect(lprc);
- }
- }
- void RBDrawChevron(PRB prb, PRBB prbb, HDC hdc)
- {
- RECT rc;
- DWORD dwFlags = prbb->wChevState | DCHF_HORIZONTAL | DCHF_TRANSPARENT;
- CopyRect(&rc, &prbb->rcChevron);
- if (RB_ISVERT(prb))
- FlipRect(&rc);
- else
- dwFlags |= DCHF_TOPALIGN;
- DrawChevron(hdc, &rc, dwFlags);
- }
- void RBUpdateChevronState(PRB prb, PRBB prbb, WORD wControlState)
- {
- if (!prb || !prbb)
- return;
- // if no change in state, bail
- if (!(wControlState ^ prbb->wChevState))
- return;
- prbb->wChevState = wControlState;
- // if active (pushed or hottracked)
- if (!(wControlState & DCHF_INACTIVE)) {
- // then we're now the hot band
- prb->prbbHot = prbb;
- }
- // else if we were the hot band then clear
- else if (prbb == prb->prbbHot) {
- prb->prbbHot = NULL;
- }
- // clear background & repaint
- RBInvalidateRect(prb, &prbb->rcChevron);
- UpdateWindow(prb->ci.hwnd);
- }
- // ----------------------------------------------------------------------------
- //
- // RBDrawBand
- //
- // draws the title icon and title text of the given band into the given DC;
- // also the band's chevron
- //
- // ----------------------------------------------------------------------------
- void RBDrawBand(PRB prb, PRBB prbb, HDC hdc)
- {
- int xStart, yCenter;
- COLORREF clrBackSave, clrForeSave;
- int iModeSave;
- BOOL fVertical = RB_ISVERT(prb);
- BOOL fDrawHorizontal = (!fVertical || RB_ISVERTICALGRIPPER(prb));
- NMCUSTOMDRAW nmcd;
- LRESULT dwRet;
- if (prbb->fStyle & RBBS_HIDDEN) {
- ASSERT(0);
- return;
- }
- clrForeSave = SetTextColor(hdc, RBB_GetTextColor(prb, prbb));
- clrBackSave = SetBkColor(hdc, RBB_GetBkColor(prb, prbb));
- if (prbb->hbmBack)
- iModeSave = SetBkMode(hdc, TRANSPARENT);
- nmcd.hdc = hdc;
- nmcd.dwItemSpec = prbb->wID;
- nmcd.uItemState = 0;
- nmcd.lItemlParam = prbb->lParam;
- nmcd.rc.top = prbb->y;
- nmcd.rc.left = prbb->x;
- nmcd.rc.bottom = nmcd.rc.top + prbb->cy;
- nmcd.rc.right = nmcd.rc.left + RBBHEADERWIDTH(prbb);
- if (prb->ci.style & CCS_VERT)
- {
- FlipRect(&nmcd.rc);
- }
- #ifdef KEYBOARDCUES
- #if 0
- // BUGBUG: Custom draw stuff for UISTATE (stephstm)
- if (CCGetUIState(&(prb->ci), KC_TBD))
- nmcd.uItemState |= CDIS_SHOWKEYBOARDCUES;
- #endif
- #endif
- dwRet = CICustomDrawNotify(&prb->ci, CDDS_ITEMPREPAINT, &nmcd);
- if (!(dwRet & CDRF_SKIPDEFAULT))
- {
- int cy;
- if (RB_ISVERTICALGRIPPER(prb)) {
- cy = RBBHEADERWIDTH(prbb);
- yCenter = prbb->x + (cy / 2);
- } else {
- cy = prbb->cy;
- yCenter = prbb->y + (cy / 2);
- }
- xStart = prbb->x;
- if (RBShouldDrawGripper(prb, prbb))
- {
- RECT rc;
- int c;
- int dy;
- c = 3 * g_cyBorder;
- xStart += 2 * g_cxBorder;
- dy = g_cxEdge;
- SetRect(&rc, xStart, prbb->y + dy, xStart + c, prbb->y + cy - dy);
- if (fVertical)
- {
- RBVertMungeGripperRect(prb, &rc);
- if (RB_ISVERTICALGRIPPER(prb))
- xStart = rc.left;
- }
- CCDrawEdge(hdc, &rc, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE, &(prb->clrsc));
- xStart += c;
- }
- xStart += 2 * (fVertical ? g_cyEdge : g_cxEdge);
- if (prbb->iImage != -1)
- {
- UINT yStart;
- IMAGELISTDRAWPARAMS imldp = {0};
- yStart = yCenter - ((!fDrawHorizontal ? prb->cxImage : prb->cyImage) / 2);
- imldp.cbSize = sizeof(imldp);
- imldp.himl = prb->himl;
- imldp.i = prbb->iImage;
- imldp.hdcDst = hdc;
- imldp.x = (!fDrawHorizontal ? yStart : xStart);
- imldp.y = (!fDrawHorizontal ? xStart : yStart);
- imldp.rgbBk = CLR_DEFAULT;
- imldp.rgbFg = CLR_DEFAULT;
- imldp.fStyle = ILD_TRANSPARENT;
- ImageList_DrawIndirect(&imldp);
- xStart += (fDrawHorizontal ? (prb->cxImage + g_cxEdge) : (prb->cyImage + g_cyEdge));
- }
- if (RBSHOWTEXT(prbb))
- {
- HFONT hFontSave = SelectObject(hdc, prb->hFont);
- RECT rcText;
- rcText.left = fDrawHorizontal ? xStart : yCenter - (prbb->cxText / 2);
- rcText.top = fDrawHorizontal ? yCenter - (prb->cyFont / 2) : xStart;
- if (fDrawHorizontal)
- rcText.top -= 1; // fudge
- rcText.right = rcText.left + prbb->cxText;
- rcText.bottom = rcText.top + prb->cyFont;
- // for clients >= v5, we draw text with prefix processing (& underlines next char)
- if (prb->ci.iVersion >= 5)
- {
- UINT uFormat=0;
- #ifdef KEYBOARDCUES
- if (CCGetUIState(&(prb->ci)) & UISF_HIDEACCEL)
- uFormat= DT_HIDEPREFIX;
- #endif
- DrawText(hdc, prbb->lpText, lstrlen(prbb->lpText), &rcText, uFormat);
- }
- else
- TextOut(hdc, rcText.left, rcText.top, prbb->lpText, lstrlen(prbb->lpText));
- SelectObject(hdc, hFontSave);
- }
- // maybe draw chevron
- if (RBBUSECHEVRON(prb, prbb) && prbb->fChevron)
- RBDrawChevron(prb, prbb, hdc);
- }
- if (dwRet & CDRF_NOTIFYPOSTPAINT)
- CICustomDrawNotify(&prb->ci, CDDS_ITEMPOSTPAINT, &nmcd);
- if (prbb->hbmBack)
- SetBkMode(hdc, iModeSave);
- SetTextColor(hdc, clrForeSave);
- SetBkColor(hdc, clrBackSave);
- }
- // ----------------------------------------------------------------------------
- //
- // RBPaint
- //
- // processes WM_PAINT message
- //
- // ----------------------------------------------------------------------------
- void RBPaint(PRB prb, HDC hdcIn)
- {
- HDC hdc = hdcIn;
- PAINTSTRUCT ps;
- UINT i;
- NMCUSTOMDRAW nmcd;
- if (!hdcIn)
- hdc = BeginPaint(prb->ci.hwnd, &ps);
- else
- GetClientRect(prb->ci.hwnd, &ps.rcPaint);
- nmcd.hdc = hdc;
- nmcd.uItemState = 0;
- nmcd.lItemlParam = 0;
- nmcd.rc = ps.rcPaint;
- prb->ci.dwCustom = CICustomDrawNotify(&prb->ci, CDDS_PREPAINT, &nmcd);
- if (!(prb->ci.dwCustom & CDRF_SKIPDEFAULT))
- {
- for (i = 0; i < prb->cBands; i++) {
- if (RBGETBAND(prb, i)->fStyle & RBBS_HIDDEN)
- continue;
- RBDrawBand(prb, RBGETBAND(prb, i), hdc);
- }
- }
- if (prb->ci.dwCustom & CDRF_NOTIFYPOSTPAINT)
- CICustomDrawNotify(&prb->ci, CDDS_POSTPAINT, &nmcd);
- if (!hdcIn)
- EndPaint(prb->ci.hwnd, &ps);
- }
- // ----------------------------------------------------------------------------
- //
- // RBTileBlt
- //
- // Fills the given rectangle with the rebar's background bitmap, tiling if
- // necessary
- //
- // ----------------------------------------------------------------------------
- void RBTileBlt(PRB prb, PRBB prbb, UINT x, UINT y, UINT cx, UINT cy, HDC hdcDst, HDC hdcSrc)
- {
- UINT xOff = 0;
- UINT yOff = 0;
- BOOL fxTile, fyTile;
- int cxPart, cyPart;
- int iPixelOffset = 0;
- #ifndef WINNT
- // On Win98 BiDi, Bitblt has off-by-one bug in mirroring
- if(IS_DC_RTL_MIRRORED(hdcSrc))
- {
- iPixelOffset = 1;
- }
- #endif // WINNT
- if (!(prbb->fStyle & RBBS_FIXEDBMP))
- {
- if (prb->ci.style & CCS_VERT)
- {
- xOff = -prbb->y;
- yOff = -prbb->x;
- }
- else
- {
- xOff = -prbb->x;
- yOff = -prbb->y;
- }
- }
- xOff += x;
- if (xOff >= prbb->cxBmp)
- xOff %= prbb->cxBmp;
- yOff += y;
- if (yOff >= prbb->cyBmp)
- yOff %= prbb->cyBmp;
- ReCheck:
- fxTile = ((xOff + cx) > prbb->cxBmp);
- fyTile = ((yOff + cy) > prbb->cyBmp);
- if (!fxTile && !fyTile)
- {
- // no tiling needed -- blt and leave
- BitBlt(hdcDst, x , y, cx, cy, hdcSrc, xOff + iPixelOffset, yOff, SRCCOPY);
- return;
- }
- if (!fxTile)
- {
- // vertically tile
- cyPart = prbb->cyBmp - yOff;
- BitBlt(hdcDst, x, y, cx, cyPart, hdcSrc, xOff + iPixelOffset, yOff, SRCCOPY);
- y += cyPart;
- cy -= cyPart;
- yOff = 0;
- goto ReCheck;
- }
- if (!fyTile)
- {
- // horizontally tile
- cxPart = prbb->cxBmp - xOff;
- BitBlt(hdcDst, x, y, cxPart, cy, hdcSrc, xOff + iPixelOffset, yOff, SRCCOPY);
- x += cxPart;
- cx -= cxPart;
- xOff = 0;
- goto ReCheck;
- }
- // tile both ways
- cyPart = prbb->cyBmp - yOff;
- RBTileBlt(prb, prbb, x, y, cx, cyPart, hdcDst, hdcSrc);
- y += cyPart;
- cy -= cyPart;
- yOff = 0;
- goto ReCheck;
- }
- // this is using virtual coordinate space (internal always horizontal)
- int _RBHitTest(PRB prb, LPRBHITTESTINFO prbht, int x, int y)
- {
- BOOL fVert = (prb->ci.style & CCS_VERT);
- int i;
- PRBB prbb = RBGETBAND(prb, 0);
- int cx;
- RBHITTESTINFO rbht;
- if (!prbht)
- prbht = &rbht;
- for (i = 0; i < (int) prb->cBands; i++, prbb++)
- {
- if (prbb->fStyle & RBBS_HIDDEN)
- continue;
- if ((x >= prbb->x) && (y >= prbb->y) &&
- (x <= (prbb->x + prbb->cx)) && (y <= (prbb->y + prbb->cy)))
- {
- cx = RBBHEADERWIDTH(prbb);
- if (x <= (int) (prbb->x + cx))
- {
- prbht->flags = RBHT_CAPTION;
- if (RB_ISVERTICALGRIPPER(prb)) {
- if (y - prbb->y < RB_GRABWIDTH)
- prbht->flags = RBHT_GRABBER;
- } else {
- cx = RB_GRABWIDTH * (fVert ? g_cyBorder : g_cxBorder);
- if (RBShouldDrawGripper(prb, RBGETBAND(prb, i)) &&
- (x <= (int) (prbb->x + cx)))
- prbht->flags = RBHT_GRABBER;
- }
- }
- else
- {
- POINT pt;
- pt.x = x;
- pt.y = y;
- if (RBBUSECHEVRON(prb, prbb) && prbb->fChevron && PtInRect(&prbb->rcChevron, pt))
- prbht->flags = RBHT_CHEVRON;
- else
- prbht->flags = RBHT_CLIENT;
- }
- prbht->iBand = i;
- return(i);
- break;
- }
- }
- prbht->flags = RBHT_NOWHERE;
- prbht->iBand = -1;
- return(-1);
- }
- // ----------------------------------------------------------------------------
- //
- // RBHitTest
- //
- // returns the index to the band that the given point lies in, or -1 if outside
- // of all bands. Also, sets flags to indicate which part of the band the
- // point lies in.
- //
- // ----------------------------------------------------------------------------
- int RBHitTest(PRB prb, LPRBHITTESTINFO prbht)
- {
- BOOL fVert = (prb->ci.style & CCS_VERT);
- POINT pt;
- if (fVert)
- {
- pt.x = prbht->pt.y;
- pt.y = prbht->pt.x;
- }
- else
- pt = prbht->pt;
- return _RBHitTest(prb, prbht, pt.x, pt.y);
- }
- // ----------------------------------------------------------------------------
- //
- // RBEraseBkgnd
- //
- // processes WM_ERASEBKGND message by drawing band borders, if necessary, and
- // filling in the rebar bands with their background color
- //
- // ----------------------------------------------------------------------------
- BOOL RBEraseBkgnd(PRB prb, HDC hdc, int iBand)
- {
- BOOL fVertical = (prb->ci.style & CCS_VERT);
- NMCUSTOMDRAW nmcd;
- LRESULT dwItemRet;
- BOOL fBandBorders;
- RECT rcClient;
- HDC hdcMem = NULL;
- UINT i;
- PRBB prbb = RBGETBAND(prb, 0);
- nmcd.hdc = hdc;
- nmcd.uItemState = 0;
- nmcd.lItemlParam = 0;
- prb->ci.dwCustom = CICustomDrawNotify(&prb->ci, CDDS_PREERASE, &nmcd);
- if (!(prb->ci.dwCustom & CDRF_SKIPDEFAULT))
- {
- COLORREF clrBk;
- fBandBorders = (prb->ci.style & RBS_BANDBORDERS);
- GetClientRect(prb->ci.hwnd, &rcClient);
- clrBk = RB_GetBkColor(prb);
- if (clrBk != CLR_NONE) {
- FillRectClr(hdc, &rcClient, clrBk);
- }
- for (i = 0; i < prb->cBands; i++, prbb++)
- {
- if (prbb->fStyle & RBBS_HIDDEN)
- continue;
- if (fVertical)
- SetRect(&nmcd.rc, prbb->y, prbb->x, prbb->y + prbb->cy, prbb->x + prbb->cx);
- else
- SetRect(&nmcd.rc, prbb->x, prbb->y, prbb->x + prbb->cx, prbb->y + prbb->cy);
- if (fBandBorders)
- {
- if (prbb->x)
- {
- // draw etch between bands on same row
- if (fVertical)
- {
- nmcd.rc.right += g_cxEdge / 2;
- nmcd.rc.top -= g_cyEdge;
- CCDrawEdge(hdc, &nmcd.rc, EDGE_ETCHED, BF_TOP, &(prb->clrsc));
- nmcd.rc.right -= g_cxEdge / 2;
- nmcd.rc.top += g_cyEdge;
- }
- else
- {
- nmcd.rc.bottom += g_cyEdge / 2;
- nmcd.rc.left -= g_cxEdge;
- CCDrawEdge(hdc, &nmcd.rc, EDGE_ETCHED, BF_LEFT, &(prb->clrsc));
- nmcd.rc.bottom -= g_cyEdge / 2;
- nmcd.rc.left += g_cxEdge;
- }
- }
- else
- {
- // draw etch between rows
- if (fVertical)
- {
- rcClient.right = prbb->y + prbb->cy + g_cxEdge;
- CCDrawEdge(hdc, &rcClient, EDGE_ETCHED, BF_RIGHT, &(prb->clrsc));
- }
- else
- {
- rcClient.bottom = prbb->y + prbb->cy + g_cyEdge;
- CCDrawEdge(hdc, &rcClient, EDGE_ETCHED, BF_BOTTOM, &(prb->clrsc));
- }
- }
- }
- nmcd.dwItemSpec = prbb->wID;
- nmcd.uItemState = 0;
- dwItemRet = CICustomDrawNotify(&prb->ci, CDDS_ITEMPREERASE, &nmcd);
- if (!(dwItemRet & CDRF_SKIPDEFAULT))
- {
- if (prbb->hbmBack)
- {
- if (!hdcMem)
- {
- if (!(hdcMem = CreateCompatibleDC(hdc)))
- continue;
- RBRealize(prb, hdc, TRUE, FALSE);
- }
- SelectObject(hdcMem, prbb->hbmBack);
- RBTileBlt(prb, prbb, nmcd.rc.left, nmcd.rc.top, nmcd.rc.right - nmcd.rc.left,
- nmcd.rc.bottom - nmcd.rc.top, hdc, hdcMem);
- }
- else
- {
- // if the color for this band is the same as the
- // rebar's default background color, then we
- // don't need to paint this specially
- COLORREF clr = RBB_GetBkColor(prb, prbb);
- if (clr != RB_GetBkColor(prb)) {
- FillRectClr(hdc, &nmcd.rc, clr);
- }
- }
- }
- if (dwItemRet & CDRF_NOTIFYPOSTERASE)
- CICustomDrawNotify(&prb->ci, CDDS_ITEMPOSTERASE, &nmcd);
- }
- if (hdcMem)
- {
- DeleteDC(hdcMem);
- }
- }
- if (prb->ci.dwCustom & CDRF_NOTIFYPOSTERASE)
- {
- nmcd.uItemState = 0;
- nmcd.dwItemSpec = 0;
- nmcd.lItemlParam = 0;
- CICustomDrawNotify(&prb->ci, CDDS_POSTERASE, &nmcd);
- }
- return(TRUE);
- }
- // ----------------------------------------------------------------------------
- //
- // RBGetBarInfo
- //
- // retrieves the indicated values from the rebar's internal structure
- //
- // ----------------------------------------------------------------------------
- BOOL RBGetBarInfo(PRB prb, LPREBARINFO lprbi)
- {
- if (!prb || (lprbi->cbSize != sizeof(REBARINFO)))
- return(FALSE);
- if (lprbi->fMask & RBIM_IMAGELIST)
- lprbi->himl = prb->himl;
- return(TRUE);
- }
- // ----------------------------------------------------------------------------
- //
- // RBSetBarInfo
- //
- // sets the indicated values in the rebar's internal structure, recalculating
- // and refreshing as needed
- //
- // ----------------------------------------------------------------------------
- BOOL RBSetBarInfo(PRB prb, LPREBARINFO lprbi)
- {
- if (!prb || (lprbi->cbSize != sizeof(REBARINFO)))
- return(FALSE);
- if (lprbi->fMask & RBIM_IMAGELIST)
- {
- HIMAGELIST himl = prb->himl;
- UINT cxOld, cyOld;
- //todo:validate lprbi->himl
- prb->himl = lprbi->himl;
- cxOld = prb->cxImage;
- cyOld = prb->cyImage;
- ImageList_GetIconSize(prb->himl, (LPINT)&prb->cxImage, (LPINT)&prb->cyImage);
- if ((prb->cxImage != cxOld) || (prb->cyImage != cyOld))
- {
- UINT i;
- for (i = 0; i < prb->cBands; i++) {
- if (RBGETBAND(prb, i)->fStyle & RBBS_HIDDEN)
- continue;
- RBBCalcMinWidth(prb, RBGETBAND(prb, i));
- }
- RBResize(prb, FALSE);
- }
- else
- RBInvalidateRect(prb, NULL);
- lprbi->himl = himl;
- }
- return(TRUE);
- }
- // ----------------------------------------------------------------------------
- //
- // RBGetBandInfo
- //
- // retrieves the indicated values from the specified band's internal structure
- //
- // ----------------------------------------------------------------------------
- BOOL RBGetBandInfo(PRB prb, UINT uBand, LPREBARBANDINFO lprbbi)
- {
- PRBB prbb;
- if (!prb || (!RB_ISVALIDINDEX(prb, uBand)) || (lprbbi->cbSize > SIZEOF(REBARBANDINFO)))
- return(FALSE);
- prbb = RBGETBAND(prb, uBand);
- if (lprbbi->fMask & RBBIM_SIZE) {
- if (prbb->fStyle & RBBS_FIXEDSIZE)
- lprbbi->cx = prbb->cx;
- else
- lprbbi->cx = prbb->cxRequest;
- }
- if (lprbbi->fMask & RBBIM_HEADERSIZE)
- lprbbi->cxHeader = RBBHEADERWIDTH(prbb);
- if (lprbbi->fMask & RBBIM_IDEALSIZE)
- // HACKHACK: (tjgreen) Subtract the offset we added in SetBandInfo (see
- // comments there).
- lprbbi->cxIdeal = prbb->cxIdeal ? prbb->cxIdeal - CX_OFFSET : 0;
- if (lprbbi->fMask & RBBIM_STYLE)
- lprbbi->fStyle = prbb->fStyle;
- if (lprbbi->fMask & RBBIM_COLORS)
- {
- lprbbi->clrFore = RBB_GetTextColor_External(prb, prbb);
- lprbbi->clrBack = RBB_GetBkColor_External(prb, prbb);
- }
- if (lprbbi->fMask & RBBIM_TEXT)
- {
- UINT cch = prbb->lpText ? lstrlen(prbb->lpText) : 0;
- if (!lprbbi->cch || !lprbbi->lpText || (lprbbi->cch <= cch))
- lprbbi->cch = cch + 1;
- else if (prbb->lpText)
- lstrcpy(lprbbi->lpText, prbb->lpText);
- else
- // no text -- so just make it an empty string
- lprbbi->lpText[0] = 0;
- }
- if (lprbbi->fMask & RBBIM_IMAGE)
- lprbbi->iImage = prbb->iImage;
- if (lprbbi->fMask & RBBIM_CHILD)
- lprbbi->hwndChild = prbb->hwndChild;
- if (lprbbi->fMask & RBBIM_CHILDSIZE)
- {
- // HACKHACK: (tjgreen) Subtract the offset we added in SetBandInfo (see
- // comments there).
- lprbbi->cxMinChild = prbb->cxMinChild ? prbb->cxMinChild - CX_OFFSET : 0;
- lprbbi->cyMinChild = prbb->cyMinChild;
- if (prbb->fStyle & RBBS_VARIABLEHEIGHT) {
- lprbbi->cyIntegral = prbb->cyIntegral;
- lprbbi->cyMaxChild = prbb->cyMaxChild;
- lprbbi->cyChild = prbb->cyChild;
- }
- }
- if (lprbbi->fMask & RBBIM_BACKGROUND)
- lprbbi->hbmBack = prbb->hbmBack;
- if (lprbbi->fMask & RBBIM_ID)
- lprbbi->wID = prbb->wID;
- if (lprbbi->fMask & RBBIM_LPARAM)
- lprbbi->lParam = prbb->lParam;
- return(TRUE);
- }
- BOOL RBValidateBandInfo(LPREBARBANDINFO *pprbbi, LPREBARBANDINFO prbbi)
- {
- BOOL fRet = ((*pprbbi)->cbSize == sizeof(REBARBANDINFO));
- if (!fRet) {
- if ((*pprbbi)->cbSize < SIZEOF(REBARBANDINFO)) {
- hmemcpy(prbbi, (*pprbbi), (*pprbbi)->cbSize);
- (*pprbbi) = prbbi;
- prbbi->cbSize = SIZEOF(REBARBANDINFO);
- fRet = TRUE;
- }
- }
- return fRet;
- }
- // ----------------------------------------------------------------------------
- //
- // RBSetBandInfo
- //
- // sets the indicated values in the specified band's internal structure,
- // recalculating and refreshing as needed
- //
- // ----------------------------------------------------------------------------
- BOOL RBSetBandInfo(PRB prb, UINT uBand, LPREBARBANDINFO lprbbi, BOOL fAllowRecalc)
- {
- PRBB prbb;
- BOOL fRefresh = FALSE;
- BOOL fRecalc = FALSE;
- BOOL fRecalcMin = FALSE;
- BOOL fTextChanged = FALSE;
- REBARBANDINFO rbbi = {0};
- RECT rc;
- if (!prb || (!RB_ISVALIDINDEX(prb, uBand)) ||
- !RBValidateBandInfo(&lprbbi, &rbbi))
- return(FALSE);
- prbb = RBGETBAND(prb, uBand);
- if (lprbbi->fMask & RBBIM_TEXT)
- {
- if (!lprbbi->lpText || !prbb->lpText || lstrcmp(lprbbi->lpText, prbb->lpText))
- {
- if (lprbbi->lpText != prbb->lpText) {
- Str_Set(&prbb->lpText, lprbbi->lpText);
- fTextChanged = TRUE;
- }
- }
- }
- if (lprbbi->fMask & RBBIM_STYLE)
- {
- UINT fStylePrev = prbb->fStyle;
- UINT fChanged = lprbbi->fStyle ^ fStylePrev;
- prbb->fStyle = lprbbi->fStyle;
- if (fChanged)
- fRecalc = TRUE;
- if ((prbb->fStyle & RBBS_FIXEDSIZE) && !(fStylePrev & RBBS_FIXEDSIZE))
- prbb->cxMin = prbb->cx;
- else if (fChanged & RBBS_FIXEDSIZE)
- fRecalcMin = TRUE;
- if (fChanged & RBBS_GRIPPERALWAYS)
- fRecalcMin = TRUE;
- if (fChanged & RBBS_HIDDEN)
- RBShowBand(prb, uBand, !(prbb->fStyle & RBBS_HIDDEN));
- if (fChanged & RBBS_HIDETITLE)
- fTextChanged = TRUE;
- // can't have both of these
- if (prbb->fStyle & RBBS_FIXEDSIZE)
- prbb->fStyle &= ~RBBS_BREAK;
- }
- // RBBIM_TEXT does calculations that want to take some RBBIM_STYLE bits
- // into account, so delay those calculations until we grab the style bits.
- //
- if (fTextChanged && !(prbb->fStyle & RBBS_HIDDEN))
- {
- if (RBBCalcTextExtent(prb, prbb, NULL))
- fRecalc = TRUE;
- else
- fRefresh = TRUE;
- }
- if (lprbbi->fMask & RBBIM_IDEALSIZE)
- {
- // HACKHACK: (tjgreen) Add an offset to the width the caller specifies.
- // This offset gets clipped off in RBResizeChildren, so the child window is
- // rendered with the width specified by caller, and we get a little space on
- // the toolbar after the buttons. If caller specifies zero-width, though,
- // we don't want this extra space, so don't add offset.
- int cxIdeal = lprbbi->cxIdeal ? lprbbi->cxIdeal + CX_OFFSET : 0;
- if (cxIdeal != prbb->cxIdeal) {
- prbb->cxIdeal = cxIdeal;
- fRecalcMin = TRUE;
- fRecalc = TRUE;
- }
- }
- if (lprbbi->fMask & RBBIM_SIZE)
- {
- if (prbb->cxRequest != (int) lprbbi->cx)
- {
- fRecalc = TRUE;
- prbb->cxRequest = (int) lprbbi->cx;
- }
- if (prbb->fStyle & RBBS_FIXEDSIZE)
- prbb->cxMin = prbb->cxRequest;
- }
- if (lprbbi->fMask & RBBIM_HEADERSIZE)
- {
- if ((lprbbi->cxHeader == -1) ||
- !(prbb->fStyle & RBBS_FIXEDHEADERSIZE) ||
- ((UINT)prbb->cxMin != lprbbi->cxHeader + prbb->cxMinChild)) {
- if (lprbbi->cxHeader == -1) {
- prbb->fStyle &= ~RBBS_FIXEDHEADERSIZE;
- fRecalcMin = TRUE;
- } else {
- prbb->fStyle |= RBBS_FIXEDHEADERSIZE;
- prbb->cxMin = lprbbi->cxHeader + prbb->cxMinChild;
- }
- fRecalc = TRUE;
- fRefresh = TRUE;
- }
- }
- if (lprbbi->fMask & RBBIM_COLORS)
- {
- prbb->clrFore = lprbbi->clrFore;
- prbb->clrBack = lprbbi->clrBack;
- fRefresh = TRUE;
- }
- if ((lprbbi->fMask & RBBIM_IMAGE) && (prbb->iImage != lprbbi->iImage))
- {
- BOOL fToggleBmp = ((prbb->iImage == -1) || (lprbbi->iImage == -1));
- prbb->iImage = lprbbi->iImage;
- if (fToggleBmp)
- {
- fRecalc = TRUE;
- fRecalcMin = TRUE;
- }
- else
- fRefresh = TRUE;
- }
- if (lprbbi->fMask & RBBIM_CHILD &&
- lprbbi->hwndChild != prbb->hwndChild &&
- (NULL == lprbbi->hwndChild ||
- !IsChild(lprbbi->hwndChild, prb->ci.hwnd)))
- {
- if (IsWindow(prbb->hwndChild))
- ShowWindow(prbb->hwndChild, SW_HIDE);
- prbb->hwndChild = lprbbi->hwndChild;
- if (prbb->hwndChild)
- {
- SetParent(prbb->hwndChild, prb->ci.hwnd);
- ShowWindow(prbb->hwndChild, SW_SHOW);
- }
- fRecalc = TRUE;
- }
- if (lprbbi->fMask & RBBIM_CHILDSIZE)
- {
- UINT cyChildOld = prbb->cyChild;
- if (lprbbi->cyMinChild != -1)
- prbb->cyMinChild = lprbbi->cyMinChild;
- if (prbb->fStyle & RBBS_VARIABLEHEIGHT) {
- if (lprbbi->cyIntegral != -1)
- prbb->cyIntegral = lprbbi->cyIntegral;
- if (lprbbi->cyMaxChild != -1)
- prbb->cyMaxChild = lprbbi->cyMaxChild;
- if (lprbbi->cyChild != -1)
- prbb->cyChild = lprbbi->cyChild;
- if (prbb->cyChild < prbb->cyMinChild)
- prbb->cyChild = prbb->cyMinChild;
- if (prbb->cyChild > prbb->cyMaxChild)
- prbb->cyChild = prbb->cyMaxChild;
- // validate the child size. cyChild must be cyMinChild plux n*cyIntegral
- if (prbb->cyIntegral) {
- int iExtra;
- iExtra = (prbb->cyChild - prbb->cyMinChild) % prbb->cyIntegral;
- prbb->cyChild -= iExtra;
- }
- } else {
- // if we're not in variable height mode, then
- // the cyChild is the same as cyMinChild.
- // this is a little peculiar, but done this way for backcompat.
- // cyMinChild came before cyChild
- prbb->cyChild = lprbbi->cyMinChild;
- }
- if (lprbbi->cxMinChild != (UINT)-1) {
- // HACKHACK: (tjgreen) Add an offset to the width the caller specifies.
- // This offset gets clipped off in RBResizeChildren, so the child window is
- // rendered with the width specified by caller, and we get a little space on
- // the toolbar after the buttons. However, if caller specifies zero-width or
- // if the band is fixed size, we don't want this extra space, so don't add offset.
- UINT cxMinChild = lprbbi->cxMinChild;
- if ((lprbbi->cxMinChild != 0) && !(prbb->fStyle & RBBS_FIXEDSIZE))
- cxMinChild += CX_OFFSET;
- if (prbb->cxMinChild != cxMinChild) {
- int cxOldHeaderMin = RBBHEADERWIDTH(prbb);
- if (prbb->fStyle & RBBS_FIXEDSIZE)
- fRecalc = TRUE;
- prbb->cxMinChild = cxMinChild;
- if (prbb->fStyle & RBBS_FIXEDHEADERSIZE)
- prbb->cxMin = cxOldHeaderMin + prbb->cxMinChild;
- fRecalcMin = TRUE;
- }
- if (cyChildOld != prbb->cyChild) {
- // TODO: revisit optimization:
- // if (RBBGetHeight(prb, prbb) != (UINT) prbb->cy)
- fRecalc = TRUE;
- }
- }
- }
- if (lprbbi->fMask & RBBIM_BACKGROUND)
- {
- DIBSECTION dib;
- if (lprbbi->hbmBack && !GetObject(lprbbi->hbmBack, sizeof(DIBSECTION), &dib))
- return(FALSE);
- prbb->hbmBack = lprbbi->hbmBack;
- prbb->cxBmp = dib.dsBm.bmWidth;
- prbb->cyBmp = dib.dsBm.bmHeight;
- fRefresh = TRUE;
- }
- if (lprbbi->fMask & RBBIM_ID)
- prbb->wID = lprbbi->wID;
- if (lprbbi->fMask & RBBIM_LPARAM)
- prbb->lParam = lprbbi->lParam;
- if (fRecalcMin && !(prbb->fStyle & RBBS_HIDDEN))
- RBBCalcMinWidth(prb, prbb);
- if (fAllowRecalc) {
- if (fRecalc)
- RBResize(prb, FALSE);
- if (fRefresh || fRecalc)
- {
- // '|| fRecalc' so we catch add/grow of text.
- // testcase: remove title from band; add back; make sure the text
- // shows up (used to just leave old band contents there)
- SetRect(&rc, prbb->x, prbb->y, prbb->x + prbb->cx, prbb->y + prbb->cy);
- RBInvalidateRect(prb, &rc);
- }
- }
- return(TRUE);
- }
- // ----------------------------------------------------------------------------
- //
- // RBReallocBands
- //
- // reallocates the array of bands pointed to by prb->rbbList to the given
- // number of bands
- //
- // ----------------------------------------------------------------------------
- BOOL RBReallocBands(PRB prb, UINT cBands)
- {
- PRBB rbbList;
- if (!(rbbList = (PRBB) CCLocalReAlloc(prb->rbbList, sizeof(RBB) * cBands)) && cBands)
- return(FALSE);
- prb->rbbList = rbbList;
- return(TRUE);
- }
- //
- // NOTES
- // for now caller does this in two calls (query, set). eventually we
- // should be able to have it do everything up front.
- RBRecalcFirst(int nCmd, PRB prb, PRBB prbbDelHide)
- {
- switch (nCmd) {
- case RBC_QUERY:
- {
- BOOL fRecalcFirst;
- // if we're nuking the 1st visible guy,
- // and there are visible guys after us,
- // then we need to recompute stuff
- //
- // for a testcase, start w/:
- // row1: 'standard buttons' + 'brand'
- // row2: 'address' + 'links'
- // now hide 'standard buttons', you should end up w/:
- // row1: 'address' + 'links' + 'brand'
- // if there's a bug, you'll end up w/ (since the break isn't recomputed):
- // row1: 'brand'
- // row2: 'address' + 'links'
- // fRecalcFirst = (!uBand && prb->cBands);
- // if brbbDelHide is the first non-hidden band, and there are other non-hidden bands after it, fRecalcFirst = TRUE;
- fRecalcFirst = (RBEnumBand(prb, 0, RBBS_HIDDEN) == prbbDelHide) &&
- (RBGetNextVisible(prb, prbbDelHide) <= RB_GETLASTBAND(prb));