1c2c66affSColin Finck /*
2c2c66affSColin Finck * Rebar control
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 1998, 1999 Eric Kohl
5c2c66affSColin Finck * Copyright 2007, 2008 Mikolaj Zalewski
6c2c66affSColin Finck *
7c2c66affSColin Finck * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck * License as published by the Free Software Foundation; either
10c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck *
12c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15c2c66affSColin Finck * Lesser General Public License for more details.
16c2c66affSColin Finck *
17c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck *
21c2c66affSColin Finck * NOTES
22c2c66affSColin Finck *
23c2c66affSColin Finck * This code was audited for completeness against the documented features
24c2c66affSColin Finck * of Comctl32.dll version 6.0 on Oct. 19, 2004, by Robert Shearman.
25c2c66affSColin Finck *
26c2c66affSColin Finck * Unless otherwise noted, we believe this code to be complete, as per
27c2c66affSColin Finck * the specification mentioned above.
28c2c66affSColin Finck * If you discover missing features or bugs please note them below.
29c2c66affSColin Finck *
30c2c66affSColin Finck * TODO
31c2c66affSColin Finck * Styles:
32c2c66affSColin Finck * - RBS_DBLCLKTOGGLE
33c2c66affSColin Finck * - RBS_FIXEDORDER
34c2c66affSColin Finck * - RBS_REGISTERDROP
35c2c66affSColin Finck * - RBS_TOOLTIPS
36c2c66affSColin Finck * Messages:
37c2c66affSColin Finck * - RB_BEGINDRAG
38c2c66affSColin Finck * - RB_DRAGMOVE
39c2c66affSColin Finck * - RB_ENDDRAG
40c2c66affSColin Finck * - RB_GETBANDMARGINS
41c2c66affSColin Finck * - RB_GETCOLORSCHEME
42c2c66affSColin Finck * - RB_GETDROPTARGET
43c2c66affSColin Finck * - RB_GETPALETTE
44c2c66affSColin Finck * - RB_SETCOLORSCHEME
45c2c66affSColin Finck * - RB_SETPALETTE
46c2c66affSColin Finck * - RB_SETTOOLTIPS
47c2c66affSColin Finck * - WM_CHARTOITEM
48c2c66affSColin Finck * - WM_LBUTTONDBLCLK
49c2c66affSColin Finck * - WM_PALETTECHANGED
50c2c66affSColin Finck * - WM_QUERYNEWPALETTE
51c2c66affSColin Finck * - WM_RBUTTONDOWN
52c2c66affSColin Finck * - WM_RBUTTONUP
53c2c66affSColin Finck * - WM_VKEYTOITEM
54c2c66affSColin Finck * - WM_WININICHANGE
55c2c66affSColin Finck * Notifications:
56c2c66affSColin Finck * - NM_HCHITTEST
57c2c66affSColin Finck * - NM_RELEASEDCAPTURE
58c2c66affSColin Finck * - RBN_AUTOBREAK
59c2c66affSColin Finck * - RBN_GETOBJECT
60c2c66affSColin Finck * - RBN_MINMAX
61c2c66affSColin Finck * Band styles:
62c2c66affSColin Finck * - RBBS_FIXEDBMP
63c2c66affSColin Finck * Native uses (on each draw!!) SM_CYBORDER (or SM_CXBORDER for CCS_VERT)
64c2c66affSColin Finck * to set the size of the separator width (the value SEP_WIDTH_SIZE
65c2c66affSColin Finck * in here). Should be fixed!!
66c2c66affSColin Finck */
67c2c66affSColin Finck
68c2c66affSColin Finck /*
69c2c66affSColin Finck * Testing: set to 1 to make background brush *always* green
70c2c66affSColin Finck */
71c2c66affSColin Finck #define GLATESTING 0
72c2c66affSColin Finck
73c2c66affSColin Finck /*
74c2c66affSColin Finck * 3. REBAR_MoveChildWindows should have a loop because more than
75c2c66affSColin Finck * one pass (together with the RBN_CHILDSIZEs) is made on
76c2c66affSColin Finck * at least RB_INSERTBAND
77c2c66affSColin Finck */
78c2c66affSColin Finck
79b3fb8555SGiannis Adamopoulos #include <assert.h>
80b3fb8555SGiannis Adamopoulos #include <stdarg.h>
81b3fb8555SGiannis Adamopoulos #include <stdlib.h>
82b3fb8555SGiannis Adamopoulos #include <string.h>
83b3fb8555SGiannis Adamopoulos
84b3fb8555SGiannis Adamopoulos #include "windef.h"
85b3fb8555SGiannis Adamopoulos #include "winbase.h"
86b3fb8555SGiannis Adamopoulos #include "wingdi.h"
87b3fb8555SGiannis Adamopoulos #include "winuser.h"
88b3fb8555SGiannis Adamopoulos #include "winnls.h"
89b3fb8555SGiannis Adamopoulos #include "commctrl.h"
90c2c66affSColin Finck #include "comctl32.h"
91b3fb8555SGiannis Adamopoulos #include "uxtheme.h"
92b3fb8555SGiannis Adamopoulos #include "vssym32.h"
93b3fb8555SGiannis Adamopoulos #include "wine/debug.h"
94c2c66affSColin Finck
95c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(rebar);
96c2c66affSColin Finck
97c2c66affSColin Finck typedef struct
98c2c66affSColin Finck {
99c2c66affSColin Finck UINT fStyle;
100c2c66affSColin Finck UINT fMask;
101c2c66affSColin Finck COLORREF clrFore;
102c2c66affSColin Finck COLORREF clrBack;
103c2c66affSColin Finck INT iImage;
104c2c66affSColin Finck HWND hwndChild;
105c2c66affSColin Finck UINT cxMinChild; /* valid if _CHILDSIZE */
106c2c66affSColin Finck UINT cyMinChild; /* valid if _CHILDSIZE */
107c2c66affSColin Finck UINT cx; /* valid if _SIZE */
108c2c66affSColin Finck HBITMAP hbmBack;
109c2c66affSColin Finck UINT wID;
110c2c66affSColin Finck UINT cyChild; /* valid if _CHILDSIZE */
111c2c66affSColin Finck UINT cyMaxChild; /* valid if _CHILDSIZE */
112c2c66affSColin Finck UINT cyIntegral; /* valid if _CHILDSIZE */
113c2c66affSColin Finck UINT cxIdeal;
114c2c66affSColin Finck LPARAM lParam;
115c2c66affSColin Finck UINT cxHeader;
116c2c66affSColin Finck
117c2c66affSColin Finck INT cxEffective; /* current cx for band */
118c2c66affSColin Finck UINT cyHeader; /* the height of the header */
119c2c66affSColin Finck UINT cxMinBand; /* minimum cx for band */
120c2c66affSColin Finck UINT cyMinBand; /* minimum cy for band */
121c2c66affSColin Finck
122c2c66affSColin Finck UINT cyRowSoFar; /* for RBS_VARHEIGHT - the height of the row if it would break on this band (set by _Layout) */
123c2c66affSColin Finck INT iRow; /* zero-based index of the row this band assigned to */
124c2c66affSColin Finck UINT fStatus; /* status flags, reset only by _Validate */
125c2c66affSColin Finck UINT fDraw; /* drawing flags, reset only by _Layout */
126c2c66affSColin Finck UINT uCDret; /* last return from NM_CUSTOMDRAW */
127c2c66affSColin Finck RECT rcBand; /* calculated band rectangle - coordinates swapped for CCS_VERT */
128c2c66affSColin Finck RECT rcGripper; /* calculated gripper rectangle */
129c2c66affSColin Finck RECT rcCapImage; /* calculated caption image rectangle */
130c2c66affSColin Finck RECT rcCapText; /* calculated caption text rectangle */
131c2c66affSColin Finck RECT rcChild; /* calculated child rectangle */
132c2c66affSColin Finck RECT rcChevron; /* calculated chevron rectangle */
133c2c66affSColin Finck
134c2c66affSColin Finck LPWSTR lpText;
135c2c66affSColin Finck HWND hwndPrevParent;
136c2c66affSColin Finck } REBAR_BAND;
137c2c66affSColin Finck
138c2c66affSColin Finck /* has a value of: 0, CCS_TOP, CCS_NOMOVEY, CCS_BOTTOM */
139c2c66affSColin Finck #define CCS_LAYOUT_MASK 0x3
140c2c66affSColin Finck
141c2c66affSColin Finck /* fStatus flags */
142c2c66affSColin Finck #define HAS_GRIPPER 0x00000001
143c2c66affSColin Finck #define HAS_IMAGE 0x00000002
144c2c66affSColin Finck #define HAS_TEXT 0x00000004
145c2c66affSColin Finck
146c2c66affSColin Finck /* fDraw flags */
147c2c66affSColin Finck #define DRAW_GRIPPER 0x00000001
148c2c66affSColin Finck #define DRAW_IMAGE 0x00000002
149c2c66affSColin Finck #define DRAW_TEXT 0x00000004
150c2c66affSColin Finck #define DRAW_CHEVRONHOT 0x00000040
151c2c66affSColin Finck #define DRAW_CHEVRONPUSHED 0x00000080
152c2c66affSColin Finck #define NTF_INVALIDATE 0x01000000
153c2c66affSColin Finck
154c2c66affSColin Finck typedef struct
155c2c66affSColin Finck {
156c2c66affSColin Finck COLORREF clrBk; /* background color */
157c2c66affSColin Finck COLORREF clrText; /* text color */
158c2c66affSColin Finck COLORREF clrBtnText; /* system color for BTNTEXT */
159c2c66affSColin Finck COLORREF clrBtnFace; /* system color for BTNFACE */
160c2c66affSColin Finck HIMAGELIST himl; /* handle to imagelist */
161c2c66affSColin Finck UINT uNumBands; /* # of bands in rebar (first=0, last=uNumBands-1 */
162c2c66affSColin Finck UINT uNumRows; /* # of rows of bands (first=1, last=uNumRows */
163c2c66affSColin Finck HWND hwndSelf; /* handle of REBAR window itself */
164c2c66affSColin Finck HWND hwndToolTip; /* handle to the tool tip control */
165c2c66affSColin Finck HWND hwndNotify; /* notification window (parent) */
166c2c66affSColin Finck HFONT hDefaultFont;
167c2c66affSColin Finck HFONT hFont; /* handle to the rebar's font */
168c2c66affSColin Finck SIZE imageSize; /* image size (image list) */
169c2c66affSColin Finck DWORD dwStyle; /* window style */
170c2c66affSColin Finck DWORD orgStyle; /* original style (dwStyle may change) */
171c2c66affSColin Finck SIZE calcSize; /* calculated rebar size - coordinates swapped for CCS_VERT */
172c2c66affSColin Finck BOOL bUnicode; /* TRUE if parent wants notify in W format */
173c2c66affSColin Finck BOOL DoRedraw; /* TRUE to actually draw bands */
174c2c66affSColin Finck UINT fStatus; /* Status flags (see below) */
175c2c66affSColin Finck HCURSOR hcurArrow; /* handle to the arrow cursor */
176c2c66affSColin Finck HCURSOR hcurHorz; /* handle to the EW cursor */
177c2c66affSColin Finck HCURSOR hcurVert; /* handle to the NS cursor */
178c2c66affSColin Finck HCURSOR hcurDrag; /* handle to the drag cursor */
179c2c66affSColin Finck INT iVersion; /* version number */
180c2c66affSColin Finck POINT dragStart; /* x,y of button down */
181c2c66affSColin Finck POINT dragNow; /* x,y of this MouseMove */
182c2c66affSColin Finck INT iOldBand; /* last band that had the mouse cursor over it */
183c2c66affSColin Finck INT ihitoffset; /* offset of hotspot from gripper.left */
184c2c66affSColin Finck INT ichevronhotBand; /* last band that had a hot chevron */
185c2c66affSColin Finck INT iGrabbedBand;/* band number of band whose gripper was grabbed */
186c2c66affSColin Finck
187c2c66affSColin Finck HDPA bands; /* pointer to the array of rebar bands */
188c2c66affSColin Finck } REBAR_INFO;
189c2c66affSColin Finck
190c2c66affSColin Finck /* fStatus flags */
191c2c66affSColin Finck #define BEGIN_DRAG_ISSUED 0x00000001
192c2c66affSColin Finck #define SELF_RESIZE 0x00000002
193c2c66affSColin Finck #define BAND_NEEDS_REDRAW 0x00000020
194c2c66affSColin Finck
195c2c66affSColin Finck /* used by Windows to mark that the header size has been set by the user and shouldn't be changed */
196c2c66affSColin Finck #define RBBS_UNDOC_FIXEDHEADER 0x40000000
197c2c66affSColin Finck
198c2c66affSColin Finck /* ---- REBAR layout constants. Mostly determined by ---- */
199c2c66affSColin Finck /* ---- experiment on WIN 98. ---- */
200c2c66affSColin Finck
201c2c66affSColin Finck /* Width (or height) of separators between bands (either horz. or */
202c2c66affSColin Finck /* vert.). True only if RBS_BANDBORDERS is set */
203c2c66affSColin Finck #define SEP_WIDTH_SIZE 2
204c2c66affSColin Finck #define SEP_WIDTH ((infoPtr->dwStyle & RBS_BANDBORDERS) ? SEP_WIDTH_SIZE : 0)
205c2c66affSColin Finck
206c2c66affSColin Finck /* Blank (background color) space between Gripper (if present) */
207c2c66affSColin Finck /* and next item (image, text, or window). Always present */
208c2c66affSColin Finck #define REBAR_ALWAYS_SPACE 4
209c2c66affSColin Finck
210c2c66affSColin Finck /* Blank (background color) space after Image (if present). */
211c2c66affSColin Finck #define REBAR_POST_IMAGE 2
212c2c66affSColin Finck
213c2c66affSColin Finck /* Blank (background color) space after Text (if present). */
214c2c66affSColin Finck #define REBAR_POST_TEXT 4
215c2c66affSColin Finck
216c2c66affSColin Finck /* Height of vertical gripper in a CCS_VERT rebar. */
217c2c66affSColin Finck #define GRIPPER_HEIGHT 16
218c2c66affSColin Finck
219c2c66affSColin Finck /* Blank (background color) space before Gripper (if present). */
220c2c66affSColin Finck #define REBAR_PRE_GRIPPER 2
221c2c66affSColin Finck
222c2c66affSColin Finck /* Width (of normal vertical gripper) or height (of horz. gripper) */
223c2c66affSColin Finck /* if present. */
224c2c66affSColin Finck #define GRIPPER_WIDTH 3
225c2c66affSColin Finck
226c2c66affSColin Finck /* Width of the chevron button if present */
227c2c66affSColin Finck #define CHEVRON_WIDTH 10
228c2c66affSColin Finck
229c2c66affSColin Finck /* the gap between the child and the next band */
230c2c66affSColin Finck #define REBAR_POST_CHILD 4
231c2c66affSColin Finck
232c2c66affSColin Finck /* Height of divider for Rebar if not disabled (CCS_NODIVIDER) */
233c2c66affSColin Finck /* either top or bottom */
234c2c66affSColin Finck #define REBAR_DIVIDER 2
235c2c66affSColin Finck
236c2c66affSColin Finck /* height of a rebar without a child */
237c2c66affSColin Finck #define REBAR_NO_CHILD_HEIGHT 4
238c2c66affSColin Finck
239c2c66affSColin Finck /* minimum vertical height of a normal bar */
240c2c66affSColin Finck /* or minimum width of a CCS_VERT bar - from experiment on Win2k */
241c2c66affSColin Finck #define REBAR_MINSIZE 23
242c2c66affSColin Finck
243c2c66affSColin Finck /* This is the increment that is used over the band height */
244c2c66affSColin Finck #define REBARSPACE(a) ((a->fStyle & RBBS_CHILDEDGE) ? 2*REBAR_DIVIDER : 0)
245c2c66affSColin Finck
246c2c66affSColin Finck /* ---- End of REBAR layout constants. ---- */
247c2c66affSColin Finck
248c2c66affSColin Finck #define RB_GETBANDINFO_OLD (WM_USER+5) /* obsoleted after IE3, but we have to support it anyway */
249c2c66affSColin Finck
250c2c66affSColin Finck /* The following define determines if a given band is hidden */
251c2c66affSColin Finck #define HIDDENBAND(a) (((a)->fStyle & RBBS_HIDDEN) || \
252c2c66affSColin Finck ((infoPtr->dwStyle & CCS_VERT) && \
253c2c66affSColin Finck ((a)->fStyle & RBBS_NOVERT)))
254c2c66affSColin Finck
255c2c66affSColin Finck #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)GetWindowLongPtrW (hwnd, 0))
256c2c66affSColin Finck
257c2c66affSColin Finck static LRESULT REBAR_NotifyFormat(REBAR_INFO *infoPtr, LPARAM lParam);
258c2c66affSColin Finck static void REBAR_AutoSize(REBAR_INFO *infoPtr, BOOL needsLayout);
259c2c66affSColin Finck
260c2c66affSColin Finck /* no index check here */
REBAR_GetBand(const REBAR_INFO * infoPtr,INT i)261c2c66affSColin Finck static inline REBAR_BAND* REBAR_GetBand(const REBAR_INFO *infoPtr, INT i)
262c2c66affSColin Finck {
263c2c66affSColin Finck assert(i >= 0 && i < infoPtr->uNumBands);
264c2c66affSColin Finck return DPA_GetPtr(infoPtr->bands, i);
265c2c66affSColin Finck }
266c2c66affSColin Finck
267c2c66affSColin Finck /* "constant values" retrieved when DLL was initialized */
268c2c66affSColin Finck /* FIXME we do this when the classes are registered. */
269c2c66affSColin Finck static UINT mindragx = 0;
270c2c66affSColin Finck static UINT mindragy = 0;
271c2c66affSColin Finck
272c2c66affSColin Finck static const char * const band_stylename[] = {
273c2c66affSColin Finck "RBBS_BREAK", /* 0001 */
274c2c66affSColin Finck "RBBS_FIXEDSIZE", /* 0002 */
275c2c66affSColin Finck "RBBS_CHILDEDGE", /* 0004 */
276c2c66affSColin Finck "RBBS_HIDDEN", /* 0008 */
277c2c66affSColin Finck "RBBS_NOVERT", /* 0010 */
278c2c66affSColin Finck "RBBS_FIXEDBMP", /* 0020 */
279c2c66affSColin Finck "RBBS_VARIABLEHEIGHT", /* 0040 */
280c2c66affSColin Finck "RBBS_GRIPPERALWAYS", /* 0080 */
281c2c66affSColin Finck "RBBS_NOGRIPPER", /* 0100 */
2820707475fSJustin Miller "RBBS_USECHEVRON", /* 0200 */
2830707475fSJustin Miller "RBBS_HIDETITLE", /* 0400 */
2840707475fSJustin Miller "RBBS_TOPALIGN", /* 0800 */
285c2c66affSColin Finck NULL };
286c2c66affSColin Finck
287c2c66affSColin Finck static const char * const band_maskname[] = {
288c2c66affSColin Finck "RBBIM_STYLE", /* 0x00000001 */
289c2c66affSColin Finck "RBBIM_COLORS", /* 0x00000002 */
290c2c66affSColin Finck "RBBIM_TEXT", /* 0x00000004 */
291c2c66affSColin Finck "RBBIM_IMAGE", /* 0x00000008 */
292c2c66affSColin Finck "RBBIM_CHILD", /* 0x00000010 */
293c2c66affSColin Finck "RBBIM_CHILDSIZE", /* 0x00000020 */
294c2c66affSColin Finck "RBBIM_SIZE", /* 0x00000040 */
295c2c66affSColin Finck "RBBIM_BACKGROUND", /* 0x00000080 */
296c2c66affSColin Finck "RBBIM_ID", /* 0x00000100 */
297c2c66affSColin Finck "RBBIM_IDEALSIZE", /* 0x00000200 */
298c2c66affSColin Finck "RBBIM_LPARAM", /* 0x00000400 */
299c2c66affSColin Finck "RBBIM_HEADERSIZE", /* 0x00000800 */
3000707475fSJustin Miller "RBBIM_CHEVRONLOCATION", /* 0x00001000 */
3010707475fSJustin Miller "RBBIM_CHEVRONSTATE", /* 0x00002000 */
302c2c66affSColin Finck NULL };
303c2c66affSColin Finck
304c2c66affSColin Finck
305c2c66affSColin Finck static const WCHAR themeClass[] = { 'R','e','b','a','r',0 };
306c2c66affSColin Finck
307c2c66affSColin Finck static CHAR *
REBAR_FmtStyle(char * buffer,UINT style)3080707475fSJustin Miller REBAR_FmtStyle(char *buffer, UINT style)
309c2c66affSColin Finck {
310c2c66affSColin Finck INT i = 0;
311c2c66affSColin Finck
3120707475fSJustin Miller *buffer = 0;
313c2c66affSColin Finck while (band_stylename[i]) {
314c2c66affSColin Finck if (style & (1<<i)) {
3150707475fSJustin Miller if (*buffer) strcat(buffer, " | ");
3160707475fSJustin Miller strcat(buffer, band_stylename[i]);
317c2c66affSColin Finck }
318c2c66affSColin Finck i++;
319c2c66affSColin Finck }
3200707475fSJustin Miller return buffer;
321c2c66affSColin Finck }
322c2c66affSColin Finck
323c2c66affSColin Finck
324c2c66affSColin Finck static CHAR *
REBAR_FmtMask(char * buffer,UINT mask)3250707475fSJustin Miller REBAR_FmtMask(char *buffer, UINT mask)
326c2c66affSColin Finck {
327c2c66affSColin Finck INT i = 0;
328c2c66affSColin Finck
3290707475fSJustin Miller *buffer = 0;
330c2c66affSColin Finck while (band_maskname[i]) {
331c2c66affSColin Finck if (mask & (1<<i)) {
3320707475fSJustin Miller if (*buffer) strcat(buffer, " | ");
3330707475fSJustin Miller strcat(buffer, band_maskname[i]);
334c2c66affSColin Finck }
335c2c66affSColin Finck i++;
336c2c66affSColin Finck }
3370707475fSJustin Miller return buffer;
338c2c66affSColin Finck }
339c2c66affSColin Finck
340c2c66affSColin Finck
341c2c66affSColin Finck static VOID
REBAR_DumpBandInfo(const REBARBANDINFOW * pB)342c2c66affSColin Finck REBAR_DumpBandInfo(const REBARBANDINFOW *pB)
343c2c66affSColin Finck {
3440707475fSJustin Miller char buff[300];
3450707475fSJustin Miller
346c2c66affSColin Finck if( !TRACE_ON(rebar) ) return;
347c2c66affSColin Finck TRACE("band info: ");
348c2c66affSColin Finck if (pB->fMask & RBBIM_ID)
349c2c66affSColin Finck TRACE("ID=%u, ", pB->wID);
350c2c66affSColin Finck TRACE("size=%u, child=%p", pB->cbSize, pB->hwndChild);
351c2c66affSColin Finck if (pB->fMask & RBBIM_COLORS)
352c2c66affSColin Finck TRACE(", clrF=0x%06x, clrB=0x%06x", pB->clrFore, pB->clrBack);
353c2c66affSColin Finck TRACE("\n");
354c2c66affSColin Finck
3550707475fSJustin Miller TRACE("band info: mask=0x%08x (%s)\n", pB->fMask, REBAR_FmtMask(buff, pB->fMask));
356c2c66affSColin Finck if (pB->fMask & RBBIM_STYLE)
3570707475fSJustin Miller TRACE("band info: style=0x%08x (%s)\n", pB->fStyle, REBAR_FmtStyle(buff, pB->fStyle));
358c2c66affSColin Finck if (pB->fMask & (RBBIM_SIZE | RBBIM_IDEALSIZE | RBBIM_HEADERSIZE | RBBIM_LPARAM )) {
359c2c66affSColin Finck TRACE("band info:");
360c2c66affSColin Finck if (pB->fMask & RBBIM_SIZE)
361c2c66affSColin Finck TRACE(" cx=%u", pB->cx);
362c2c66affSColin Finck if (pB->fMask & RBBIM_IDEALSIZE)
363c2c66affSColin Finck TRACE(" xIdeal=%u", pB->cxIdeal);
364c2c66affSColin Finck if (pB->fMask & RBBIM_HEADERSIZE)
365c2c66affSColin Finck TRACE(" xHeader=%u", pB->cxHeader);
366c2c66affSColin Finck if (pB->fMask & RBBIM_LPARAM)
367c2c66affSColin Finck TRACE(" lParam=0x%08lx", pB->lParam);
368c2c66affSColin Finck TRACE("\n");
369c2c66affSColin Finck }
370c2c66affSColin Finck if (pB->fMask & RBBIM_CHILDSIZE)
371c2c66affSColin Finck TRACE("band info: xMin=%u, yMin=%u, yChild=%u, yMax=%u, yIntgl=%u\n",
372c2c66affSColin Finck pB->cxMinChild,
373c2c66affSColin Finck pB->cyMinChild, pB->cyChild, pB->cyMaxChild, pB->cyIntegral);
374c2c66affSColin Finck }
375c2c66affSColin Finck
376c2c66affSColin Finck static VOID
REBAR_DumpBand(const REBAR_INFO * iP)377c2c66affSColin Finck REBAR_DumpBand (const REBAR_INFO *iP)
378c2c66affSColin Finck {
3790707475fSJustin Miller char buff[300];
380c2c66affSColin Finck REBAR_BAND *pB;
381c2c66affSColin Finck UINT i;
382c2c66affSColin Finck
383c2c66affSColin Finck if(! TRACE_ON(rebar) ) return;
384c2c66affSColin Finck
385c2c66affSColin Finck TRACE("hwnd=%p: color=%08x/%08x, bands=%u, rows=%u, cSize=%d,%d\n",
386c2c66affSColin Finck iP->hwndSelf, iP->clrText, iP->clrBk, iP->uNumBands, iP->uNumRows,
387c2c66affSColin Finck iP->calcSize.cx, iP->calcSize.cy);
388c2c66affSColin Finck TRACE("hwnd=%p: flags=%08x, dragStart=%d,%d, dragNow=%d,%d, iGrabbedBand=%d\n",
389c2c66affSColin Finck iP->hwndSelf, iP->fStatus, iP->dragStart.x, iP->dragStart.y,
390c2c66affSColin Finck iP->dragNow.x, iP->dragNow.y,
391c2c66affSColin Finck iP->iGrabbedBand);
392c2c66affSColin Finck TRACE("hwnd=%p: style=%08x, notify in Unicode=%s, redraw=%s\n",
393c2c66affSColin Finck iP->hwndSelf, iP->dwStyle, (iP->bUnicode)?"TRUE":"FALSE",
394c2c66affSColin Finck (iP->DoRedraw)?"TRUE":"FALSE");
395c2c66affSColin Finck for (i = 0; i < iP->uNumBands; i++) {
396c2c66affSColin Finck pB = REBAR_GetBand(iP, i);
397c2c66affSColin Finck TRACE("band # %u:", i);
398c2c66affSColin Finck if (pB->fMask & RBBIM_ID)
399c2c66affSColin Finck TRACE(" ID=%u", pB->wID);
400c2c66affSColin Finck if (pB->fMask & RBBIM_CHILD)
401c2c66affSColin Finck TRACE(" child=%p", pB->hwndChild);
402c2c66affSColin Finck if (pB->fMask & RBBIM_COLORS)
403c2c66affSColin Finck TRACE(" clrF=0x%06x clrB=0x%06x", pB->clrFore, pB->clrBack);
404c2c66affSColin Finck TRACE("\n");
4050707475fSJustin Miller TRACE("band # %u: mask=0x%08x (%s)\n", i, pB->fMask, REBAR_FmtMask(buff, pB->fMask));
406c2c66affSColin Finck if (pB->fMask & RBBIM_STYLE)
4070707475fSJustin Miller TRACE("band # %u: style=0x%08x (%s)\n", i, pB->fStyle, REBAR_FmtStyle(buff, pB->fStyle));
408c2c66affSColin Finck TRACE("band # %u: xHeader=%u",
409c2c66affSColin Finck i, pB->cxHeader);
410c2c66affSColin Finck if (pB->fMask & (RBBIM_SIZE | RBBIM_IDEALSIZE | RBBIM_LPARAM )) {
411c2c66affSColin Finck if (pB->fMask & RBBIM_SIZE)
412c2c66affSColin Finck TRACE(" cx=%u", pB->cx);
413c2c66affSColin Finck if (pB->fMask & RBBIM_IDEALSIZE)
414c2c66affSColin Finck TRACE(" xIdeal=%u", pB->cxIdeal);
415c2c66affSColin Finck if (pB->fMask & RBBIM_LPARAM)
416c2c66affSColin Finck TRACE(" lParam=0x%08lx", pB->lParam);
417c2c66affSColin Finck }
418c2c66affSColin Finck TRACE("\n");
419c2c66affSColin Finck if (RBBIM_CHILDSIZE)
420c2c66affSColin Finck TRACE("band # %u: xMin=%u, yMin=%u, yChild=%u, yMax=%u, yIntgl=%u\n",
421c2c66affSColin Finck i, pB->cxMinChild, pB->cyMinChild, pB->cyChild, pB->cyMaxChild, pB->cyIntegral);
422c2c66affSColin Finck if (pB->fMask & RBBIM_TEXT)
423c2c66affSColin Finck TRACE("band # %u: text=%s\n",
424c2c66affSColin Finck i, (pB->lpText) ? debugstr_w(pB->lpText) : "(null)");
425c2c66affSColin Finck TRACE("band # %u: cxMinBand=%u, cxEffective=%u, cyMinBand=%u\n",
426c2c66affSColin Finck i, pB->cxMinBand, pB->cxEffective, pB->cyMinBand);
427c2c66affSColin Finck TRACE("band # %u: fStatus=%08x, fDraw=%08x, Band=(%s), Grip=(%s)\n",
428c2c66affSColin Finck i, pB->fStatus, pB->fDraw, wine_dbgstr_rect(&pB->rcBand),
429c2c66affSColin Finck wine_dbgstr_rect(&pB->rcGripper));
430c2c66affSColin Finck TRACE("band # %u: Img=(%s), Txt=(%s), Child=(%s)\n",
431c2c66affSColin Finck i, wine_dbgstr_rect(&pB->rcCapImage),
432c2c66affSColin Finck wine_dbgstr_rect(&pB->rcCapText), wine_dbgstr_rect(&pB->rcChild));
433c2c66affSColin Finck }
434c2c66affSColin Finck
435c2c66affSColin Finck }
436c2c66affSColin Finck
437c2c66affSColin Finck /* dest can be equal to src */
translate_rect(const REBAR_INFO * infoPtr,RECT * dest,const RECT * src)438c2c66affSColin Finck static void translate_rect(const REBAR_INFO *infoPtr, RECT *dest, const RECT *src)
439c2c66affSColin Finck {
440c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT) {
441c2c66affSColin Finck int tmp;
442c2c66affSColin Finck tmp = src->left;
443c2c66affSColin Finck dest->left = src->top;
444c2c66affSColin Finck dest->top = tmp;
445c2c66affSColin Finck
446c2c66affSColin Finck tmp = src->right;
447c2c66affSColin Finck dest->right = src->bottom;
448c2c66affSColin Finck dest->bottom = tmp;
449c2c66affSColin Finck } else {
450c2c66affSColin Finck *dest = *src;
451c2c66affSColin Finck }
452c2c66affSColin Finck }
453c2c66affSColin Finck
get_rect_cx(const REBAR_INFO * infoPtr,const RECT * lpRect)454c2c66affSColin Finck static int get_rect_cx(const REBAR_INFO *infoPtr, const RECT *lpRect)
455c2c66affSColin Finck {
456c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT)
457c2c66affSColin Finck return lpRect->bottom - lpRect->top;
458c2c66affSColin Finck return lpRect->right - lpRect->left;
459c2c66affSColin Finck }
460c2c66affSColin Finck
get_rect_cy(const REBAR_INFO * infoPtr,const RECT * lpRect)461c2c66affSColin Finck static int get_rect_cy(const REBAR_INFO *infoPtr, const RECT *lpRect)
462c2c66affSColin Finck {
463c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT)
464c2c66affSColin Finck return lpRect->right - lpRect->left;
465c2c66affSColin Finck return lpRect->bottom - lpRect->top;
466c2c66affSColin Finck }
467c2c66affSColin Finck
round_child_height(const REBAR_BAND * lpBand,int cyHeight)468c2c66affSColin Finck static int round_child_height(const REBAR_BAND *lpBand, int cyHeight)
469c2c66affSColin Finck {
470c2c66affSColin Finck int cy = 0;
471c2c66affSColin Finck if (lpBand->cyIntegral == 0)
472c2c66affSColin Finck return cyHeight;
473c2c66affSColin Finck cy = max(cyHeight - (int)lpBand->cyMinChild, 0);
474c2c66affSColin Finck cy = lpBand->cyMinChild + (cy/lpBand->cyIntegral) * lpBand->cyIntegral;
475c2c66affSColin Finck cy = min(cy, lpBand->cyMaxChild);
476c2c66affSColin Finck return cy;
477c2c66affSColin Finck }
478c2c66affSColin Finck
update_min_band_height(const REBAR_INFO * infoPtr,REBAR_BAND * lpBand)479c2c66affSColin Finck static void update_min_band_height(const REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
480c2c66affSColin Finck {
481c2c66affSColin Finck lpBand->cyMinBand = max(lpBand->cyHeader,
482c2c66affSColin Finck (lpBand->hwndChild ? lpBand->cyChild + REBARSPACE(lpBand) : REBAR_NO_CHILD_HEIGHT));
483c2c66affSColin Finck }
484c2c66affSColin Finck
485c2c66affSColin Finck static void
REBAR_DrawChevron(HDC hdc,INT left,INT top,INT colorRef)486c2c66affSColin Finck REBAR_DrawChevron (HDC hdc, INT left, INT top, INT colorRef)
487c2c66affSColin Finck {
488c2c66affSColin Finck INT x, y;
489c2c66affSColin Finck HPEN hPen, hOldPen;
490c2c66affSColin Finck
491c2c66affSColin Finck if (!(hPen = CreatePen( PS_SOLID, 1, GetSysColor( colorRef )))) return;
492c2c66affSColin Finck hOldPen = SelectObject ( hdc, hPen );
493c2c66affSColin Finck x = left + 2;
494c2c66affSColin Finck y = top;
495c2c66affSColin Finck MoveToEx (hdc, x, y, NULL);
496c2c66affSColin Finck LineTo (hdc, x+5, y++); x++;
497c2c66affSColin Finck MoveToEx (hdc, x, y, NULL);
498c2c66affSColin Finck LineTo (hdc, x+3, y++); x++;
499c2c66affSColin Finck MoveToEx (hdc, x, y, NULL);
500c2c66affSColin Finck LineTo (hdc, x+1, y);
501c2c66affSColin Finck SelectObject( hdc, hOldPen );
502c2c66affSColin Finck DeleteObject( hPen );
503c2c66affSColin Finck }
504c2c66affSColin Finck
505c2c66affSColin Finck static HWND
REBAR_GetNotifyParent(const REBAR_INFO * infoPtr)506c2c66affSColin Finck REBAR_GetNotifyParent (const REBAR_INFO *infoPtr)
507c2c66affSColin Finck {
508c2c66affSColin Finck HWND parent, owner;
509c2c66affSColin Finck
510c2c66affSColin Finck parent = infoPtr->hwndNotify;
511c2c66affSColin Finck if (!parent) {
512c2c66affSColin Finck parent = GetParent (infoPtr->hwndSelf);
513c2c66affSColin Finck owner = GetWindow (infoPtr->hwndSelf, GW_OWNER);
514c2c66affSColin Finck if (owner) parent = owner;
515c2c66affSColin Finck }
516c2c66affSColin Finck return parent;
517c2c66affSColin Finck }
518c2c66affSColin Finck
519c2c66affSColin Finck
520c2c66affSColin Finck static INT
REBAR_Notify(NMHDR * nmhdr,const REBAR_INFO * infoPtr,UINT code)521c2c66affSColin Finck REBAR_Notify (NMHDR *nmhdr, const REBAR_INFO *infoPtr, UINT code)
522c2c66affSColin Finck {
523c2c66affSColin Finck HWND parent;
524c2c66affSColin Finck
525c2c66affSColin Finck parent = REBAR_GetNotifyParent (infoPtr);
526c2c66affSColin Finck nmhdr->idFrom = GetDlgCtrlID (infoPtr->hwndSelf);
527c2c66affSColin Finck nmhdr->hwndFrom = infoPtr->hwndSelf;
528c2c66affSColin Finck nmhdr->code = code;
529c2c66affSColin Finck
530c2c66affSColin Finck TRACE("window %p, code=%08x, via %s\n", parent, code, (infoPtr->bUnicode)?"Unicode":"ANSI");
531c2c66affSColin Finck
532c2c66affSColin Finck return SendMessageW(parent, WM_NOTIFY, nmhdr->idFrom, (LPARAM)nmhdr);
533c2c66affSColin Finck }
534c2c66affSColin Finck
535c2c66affSColin Finck static INT
REBAR_Notify_NMREBAR(const REBAR_INFO * infoPtr,UINT uBand,UINT code)536c2c66affSColin Finck REBAR_Notify_NMREBAR (const REBAR_INFO *infoPtr, UINT uBand, UINT code)
537c2c66affSColin Finck {
538c2c66affSColin Finck NMREBAR notify_rebar;
539c2c66affSColin Finck
540c2c66affSColin Finck notify_rebar.dwMask = 0;
541c2c66affSColin Finck if (uBand != -1) {
542c2c66affSColin Finck REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, uBand);
543c2c66affSColin Finck
544c2c66affSColin Finck if (lpBand->fMask & RBBIM_ID) {
545c2c66affSColin Finck notify_rebar.dwMask |= RBNM_ID;
546c2c66affSColin Finck notify_rebar.wID = lpBand->wID;
547c2c66affSColin Finck }
548c2c66affSColin Finck if (lpBand->fMask & RBBIM_LPARAM) {
549c2c66affSColin Finck notify_rebar.dwMask |= RBNM_LPARAM;
550c2c66affSColin Finck notify_rebar.lParam = lpBand->lParam;
551c2c66affSColin Finck }
552c2c66affSColin Finck if (lpBand->fMask & RBBIM_STYLE) {
553c2c66affSColin Finck notify_rebar.dwMask |= RBNM_STYLE;
554c2c66affSColin Finck notify_rebar.fStyle = lpBand->fStyle;
555c2c66affSColin Finck }
556c2c66affSColin Finck }
557c2c66affSColin Finck notify_rebar.uBand = uBand;
558c2c66affSColin Finck return REBAR_Notify ((NMHDR *)¬ify_rebar, infoPtr, code);
559c2c66affSColin Finck }
560c2c66affSColin Finck
561c2c66affSColin Finck static VOID
REBAR_DrawBand(HDC hdc,const REBAR_INFO * infoPtr,REBAR_BAND * lpBand)562c2c66affSColin Finck REBAR_DrawBand (HDC hdc, const REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
563c2c66affSColin Finck {
564c2c66affSColin Finck HFONT hOldFont = 0;
565c2c66affSColin Finck INT oldBkMode = 0;
566c2c66affSColin Finck NMCUSTOMDRAW nmcd;
567c2c66affSColin Finck HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
568c2c66affSColin Finck RECT rcBand;
569c2c66affSColin Finck
570c2c66affSColin Finck translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
571c2c66affSColin Finck
572c2c66affSColin Finck if (lpBand->fDraw & DRAW_TEXT) {
573c2c66affSColin Finck hOldFont = SelectObject (hdc, infoPtr->hFont);
574c2c66affSColin Finck oldBkMode = SetBkMode (hdc, TRANSPARENT);
575c2c66affSColin Finck }
576c2c66affSColin Finck
577c2c66affSColin Finck /* should test for CDRF_NOTIFYITEMDRAW here */
578c2c66affSColin Finck nmcd.dwDrawStage = CDDS_ITEMPREPAINT;
579c2c66affSColin Finck nmcd.hdc = hdc;
580c2c66affSColin Finck nmcd.rc = rcBand;
581c2c66affSColin Finck nmcd.rc.right = lpBand->rcCapText.right;
582c2c66affSColin Finck nmcd.rc.bottom = lpBand->rcCapText.bottom;
583c2c66affSColin Finck nmcd.dwItemSpec = lpBand->wID;
584c2c66affSColin Finck nmcd.uItemState = 0;
585c2c66affSColin Finck nmcd.lItemlParam = lpBand->lParam;
586c2c66affSColin Finck lpBand->uCDret = REBAR_Notify ((NMHDR *)&nmcd, infoPtr, NM_CUSTOMDRAW);
587c2c66affSColin Finck if (lpBand->uCDret == CDRF_SKIPDEFAULT) {
588c2c66affSColin Finck if (oldBkMode != TRANSPARENT)
589c2c66affSColin Finck SetBkMode (hdc, oldBkMode);
590c2c66affSColin Finck SelectObject (hdc, hOldFont);
591c2c66affSColin Finck return;
592c2c66affSColin Finck }
593c2c66affSColin Finck
594c2c66affSColin Finck /* draw gripper */
595c2c66affSColin Finck if (lpBand->fDraw & DRAW_GRIPPER)
596c2c66affSColin Finck {
597c2c66affSColin Finck if (theme)
598c2c66affSColin Finck {
599c2c66affSColin Finck RECT rcGripper = lpBand->rcGripper;
600c2c66affSColin Finck int partId = (infoPtr->dwStyle & CCS_VERT) ? RP_GRIPPERVERT : RP_GRIPPER;
601c2c66affSColin Finck GetThemeBackgroundExtent (theme, hdc, partId, 0, &rcGripper, &rcGripper);
602c2c66affSColin Finck OffsetRect (&rcGripper, lpBand->rcGripper.left - rcGripper.left,
603c2c66affSColin Finck lpBand->rcGripper.top - rcGripper.top);
604c2c66affSColin Finck DrawThemeBackground (theme, hdc, partId, 0, &rcGripper, NULL);
605c2c66affSColin Finck }
606c2c66affSColin Finck else
607c2c66affSColin Finck DrawEdge (hdc, &lpBand->rcGripper, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
608c2c66affSColin Finck }
609c2c66affSColin Finck
610c2c66affSColin Finck /* draw caption image */
611c2c66affSColin Finck if (lpBand->fDraw & DRAW_IMAGE) {
612c2c66affSColin Finck POINT pt;
613c2c66affSColin Finck
614c2c66affSColin Finck /* center image */
615c2c66affSColin Finck pt.y = (lpBand->rcCapImage.bottom + lpBand->rcCapImage.top - infoPtr->imageSize.cy)/2;
616c2c66affSColin Finck pt.x = (lpBand->rcCapImage.right + lpBand->rcCapImage.left - infoPtr->imageSize.cx)/2;
617c2c66affSColin Finck
618c2c66affSColin Finck ImageList_Draw (infoPtr->himl, lpBand->iImage, hdc,
619c2c66affSColin Finck pt.x, pt.y,
620c2c66affSColin Finck ILD_TRANSPARENT);
621c2c66affSColin Finck }
622c2c66affSColin Finck
623c2c66affSColin Finck /* draw caption text */
624c2c66affSColin Finck if (lpBand->fDraw & DRAW_TEXT) {
625c2c66affSColin Finck /* need to handle CDRF_NEWFONT here */
626c2c66affSColin Finck INT oldBkMode = SetBkMode (hdc, TRANSPARENT);
627c2c66affSColin Finck COLORREF oldcolor = CLR_NONE;
628c2c66affSColin Finck COLORREF new;
629c2c66affSColin Finck if (lpBand->clrFore != CLR_NONE) {
630c2c66affSColin Finck new = (lpBand->clrFore == CLR_DEFAULT) ? infoPtr->clrBtnText :
631c2c66affSColin Finck lpBand->clrFore;
632c2c66affSColin Finck oldcolor = SetTextColor (hdc, new);
633c2c66affSColin Finck }
63492732f1bSGiannis Adamopoulos
635edd99e8cSAmine Khaldi #ifdef __REACTOS__
63692732f1bSGiannis Adamopoulos if (!theme)
63792732f1bSGiannis Adamopoulos {
63892732f1bSGiannis Adamopoulos DrawTextW (hdc, lpBand->lpText, -1, &lpBand->rcCapText, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
63992732f1bSGiannis Adamopoulos }
64092732f1bSGiannis Adamopoulos else
64192732f1bSGiannis Adamopoulos {
64292732f1bSGiannis Adamopoulos DrawThemeText(theme, hdc, 0, 0, lpBand->lpText, -1, DT_CENTER | DT_VCENTER | DT_SINGLELINE, 0, &lpBand->rcCapText);
64392732f1bSGiannis Adamopoulos }
644edd99e8cSAmine Khaldi #else
645edd99e8cSAmine Khaldi DrawTextW (hdc, lpBand->lpText, -1, &lpBand->rcCapText,
646edd99e8cSAmine Khaldi DT_CENTER | DT_VCENTER | DT_SINGLELINE);
647edd99e8cSAmine Khaldi #endif
64892732f1bSGiannis Adamopoulos
649c2c66affSColin Finck if (oldBkMode != TRANSPARENT)
650c2c66affSColin Finck SetBkMode (hdc, oldBkMode);
651c2c66affSColin Finck if (lpBand->clrFore != CLR_NONE)
652c2c66affSColin Finck SetTextColor (hdc, oldcolor);
653c2c66affSColin Finck SelectObject (hdc, hOldFont);
654c2c66affSColin Finck }
655c2c66affSColin Finck
656c2c66affSColin Finck if (!IsRectEmpty(&lpBand->rcChevron))
657c2c66affSColin Finck {
658c2c66affSColin Finck if (theme)
659c2c66affSColin Finck {
660c2c66affSColin Finck int stateId;
661c2c66affSColin Finck if (lpBand->fDraw & DRAW_CHEVRONPUSHED)
662c2c66affSColin Finck stateId = CHEVS_PRESSED;
663c2c66affSColin Finck else if (lpBand->fDraw & DRAW_CHEVRONHOT)
664c2c66affSColin Finck stateId = CHEVS_HOT;
665c2c66affSColin Finck else
666c2c66affSColin Finck stateId = CHEVS_NORMAL;
667c2c66affSColin Finck DrawThemeBackground (theme, hdc, RP_CHEVRON, stateId, &lpBand->rcChevron, NULL);
668c2c66affSColin Finck }
669c2c66affSColin Finck else
670c2c66affSColin Finck {
671c2c66affSColin Finck if (lpBand->fDraw & DRAW_CHEVRONPUSHED)
672c2c66affSColin Finck {
673c2c66affSColin Finck DrawEdge(hdc, &lpBand->rcChevron, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE);
674c2c66affSColin Finck REBAR_DrawChevron(hdc, lpBand->rcChevron.left+1, lpBand->rcChevron.top + 11, COLOR_WINDOWFRAME);
675c2c66affSColin Finck }
676c2c66affSColin Finck else if (lpBand->fDraw & DRAW_CHEVRONHOT)
677c2c66affSColin Finck {
678c2c66affSColin Finck DrawEdge(hdc, &lpBand->rcChevron, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
679c2c66affSColin Finck REBAR_DrawChevron(hdc, lpBand->rcChevron.left, lpBand->rcChevron.top + 10, COLOR_WINDOWFRAME);
680c2c66affSColin Finck }
681c2c66affSColin Finck else
682c2c66affSColin Finck REBAR_DrawChevron(hdc, lpBand->rcChevron.left, lpBand->rcChevron.top + 10, COLOR_WINDOWFRAME);
683c2c66affSColin Finck }
684c2c66affSColin Finck }
685c2c66affSColin Finck
686c2c66affSColin Finck if (lpBand->uCDret == (CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYITEMDRAW)) {
687c2c66affSColin Finck nmcd.dwDrawStage = CDDS_ITEMPOSTPAINT;
688c2c66affSColin Finck nmcd.hdc = hdc;
689c2c66affSColin Finck nmcd.rc = rcBand;
690c2c66affSColin Finck nmcd.rc.right = lpBand->rcCapText.right;
691c2c66affSColin Finck nmcd.rc.bottom = lpBand->rcCapText.bottom;
692c2c66affSColin Finck nmcd.dwItemSpec = lpBand->wID;
693c2c66affSColin Finck nmcd.uItemState = 0;
694c2c66affSColin Finck nmcd.lItemlParam = lpBand->lParam;
695c2c66affSColin Finck lpBand->uCDret = REBAR_Notify ((NMHDR *)&nmcd, infoPtr, NM_CUSTOMDRAW);
696c2c66affSColin Finck }
697c2c66affSColin Finck }
698c2c66affSColin Finck
699c2c66affSColin Finck
700c2c66affSColin Finck static VOID
REBAR_Refresh(const REBAR_INFO * infoPtr,HDC hdc)701c2c66affSColin Finck REBAR_Refresh (const REBAR_INFO *infoPtr, HDC hdc)
702c2c66affSColin Finck {
703c2c66affSColin Finck REBAR_BAND *lpBand;
704c2c66affSColin Finck UINT i;
705c2c66affSColin Finck
706c2c66affSColin Finck if (!infoPtr->DoRedraw) return;
707c2c66affSColin Finck
708c2c66affSColin Finck for (i = 0; i < infoPtr->uNumBands; i++) {
709c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
710c2c66affSColin Finck
711c2c66affSColin Finck if (HIDDENBAND(lpBand)) continue;
712c2c66affSColin Finck
713c2c66affSColin Finck /* now draw the band */
714c2c66affSColin Finck TRACE("[%p] drawing band %i, flags=%08x\n",
715c2c66affSColin Finck infoPtr->hwndSelf, i, lpBand->fDraw);
716c2c66affSColin Finck REBAR_DrawBand (hdc, infoPtr, lpBand);
717c2c66affSColin Finck }
718c2c66affSColin Finck }
719c2c66affSColin Finck
720c2c66affSColin Finck
721c2c66affSColin Finck static void
REBAR_CalcHorzBand(const REBAR_INFO * infoPtr,UINT rstart,UINT rend)722c2c66affSColin Finck REBAR_CalcHorzBand (const REBAR_INFO *infoPtr, UINT rstart, UINT rend)
723c2c66affSColin Finck /* Function: this routine initializes all the rectangles in */
724c2c66affSColin Finck /* each band in a row to fit in the adjusted rcBand rect. */
725c2c66affSColin Finck /* *** Supports only Horizontal bars. *** */
726c2c66affSColin Finck {
727c2c66affSColin Finck REBAR_BAND *lpBand;
728c2c66affSColin Finck UINT i, xoff;
729c2c66affSColin Finck RECT work;
730c2c66affSColin Finck
731c2c66affSColin Finck for(i=rstart; i<rend; i++){
732c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
733c2c66affSColin Finck if (HIDDENBAND(lpBand)) {
734c2c66affSColin Finck SetRect (&lpBand->rcChild,
735c2c66affSColin Finck lpBand->rcBand.right, lpBand->rcBand.top,
736c2c66affSColin Finck lpBand->rcBand.right, lpBand->rcBand.bottom);
737c2c66affSColin Finck continue;
738c2c66affSColin Finck }
739c2c66affSColin Finck
740c2c66affSColin Finck /* set initial gripper rectangle */
741c2c66affSColin Finck SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
742c2c66affSColin Finck lpBand->rcBand.left, lpBand->rcBand.bottom);
743c2c66affSColin Finck
744c2c66affSColin Finck /* calculate gripper rectangle */
745c2c66affSColin Finck if ( lpBand->fStatus & HAS_GRIPPER) {
746c2c66affSColin Finck lpBand->fDraw |= DRAW_GRIPPER;
747c2c66affSColin Finck lpBand->rcGripper.left += REBAR_PRE_GRIPPER;
748c2c66affSColin Finck lpBand->rcGripper.right = lpBand->rcGripper.left + GRIPPER_WIDTH;
749c2c66affSColin Finck InflateRect(&lpBand->rcGripper, 0, -2);
750c2c66affSColin Finck
751c2c66affSColin Finck SetRect (&lpBand->rcCapImage,
752c2c66affSColin Finck lpBand->rcGripper.right+REBAR_ALWAYS_SPACE, lpBand->rcBand.top,
753c2c66affSColin Finck lpBand->rcGripper.right+REBAR_ALWAYS_SPACE, lpBand->rcBand.bottom);
754c2c66affSColin Finck }
755c2c66affSColin Finck else { /* no gripper will be drawn */
756c2c66affSColin Finck xoff = 0;
757c2c66affSColin Finck if (lpBand->fStatus & (HAS_IMAGE | HAS_TEXT))
758c2c66affSColin Finck /* if no gripper but either image or text, then leave space */
759c2c66affSColin Finck xoff = REBAR_ALWAYS_SPACE;
760c2c66affSColin Finck SetRect (&lpBand->rcCapImage,
761c2c66affSColin Finck lpBand->rcBand.left+xoff, lpBand->rcBand.top,
762c2c66affSColin Finck lpBand->rcBand.left+xoff, lpBand->rcBand.bottom);
763c2c66affSColin Finck }
764c2c66affSColin Finck
765c2c66affSColin Finck /* image is visible */
766c2c66affSColin Finck if (lpBand->fStatus & HAS_IMAGE) {
767c2c66affSColin Finck lpBand->fDraw |= DRAW_IMAGE;
768c2c66affSColin Finck lpBand->rcCapImage.right += infoPtr->imageSize.cx;
769c2c66affSColin Finck lpBand->rcCapImage.bottom = lpBand->rcCapImage.top + infoPtr->imageSize.cy;
770c2c66affSColin Finck
771c2c66affSColin Finck /* set initial caption text rectangle */
772c2c66affSColin Finck SetRect (&lpBand->rcCapText,
773c2c66affSColin Finck lpBand->rcCapImage.right+REBAR_POST_IMAGE, lpBand->rcBand.top+1,
774c2c66affSColin Finck lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.bottom-1);
775c2c66affSColin Finck }
776c2c66affSColin Finck else {
777c2c66affSColin Finck /* set initial caption text rectangle */
778c2c66affSColin Finck SetRect (&lpBand->rcCapText, lpBand->rcCapImage.right, lpBand->rcBand.top+1,
779c2c66affSColin Finck lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.bottom-1);
780c2c66affSColin Finck }
781c2c66affSColin Finck
782c2c66affSColin Finck /* text is visible */
783c2c66affSColin Finck if ((lpBand->fStatus & HAS_TEXT) && !(lpBand->fStyle & RBBS_HIDETITLE)) {
784c2c66affSColin Finck lpBand->fDraw |= DRAW_TEXT;
785c2c66affSColin Finck lpBand->rcCapText.right = max(lpBand->rcCapText.left,
786c2c66affSColin Finck lpBand->rcCapText.right-REBAR_POST_TEXT);
787c2c66affSColin Finck }
788c2c66affSColin Finck
789c2c66affSColin Finck /* set initial child window rectangle if there is a child */
790c2c66affSColin Finck if (lpBand->hwndChild) {
791c2c66affSColin Finck
792c2c66affSColin Finck lpBand->rcChild.left = lpBand->rcBand.left + lpBand->cxHeader;
793c2c66affSColin Finck lpBand->rcChild.right = lpBand->rcBand.right - REBAR_POST_CHILD;
794c2c66affSColin Finck
795c2c66affSColin Finck if (lpBand->cyChild > 0) {
796c2c66affSColin Finck
797c2c66affSColin Finck UINT yoff = (lpBand->rcBand.bottom - lpBand->rcBand.top - lpBand->cyChild) / 2;
798c2c66affSColin Finck
799c2c66affSColin Finck /* center child if height is known */
800c2c66affSColin Finck lpBand->rcChild.top = lpBand->rcBand.top + yoff;
801c2c66affSColin Finck lpBand->rcChild.bottom = lpBand->rcBand.top + yoff + lpBand->cyChild;
802c2c66affSColin Finck }
803c2c66affSColin Finck else {
804c2c66affSColin Finck lpBand->rcChild.top = lpBand->rcBand.top;
805c2c66affSColin Finck lpBand->rcChild.bottom = lpBand->rcBand.bottom;
806c2c66affSColin Finck }
807c2c66affSColin Finck
808c2c66affSColin Finck if ((lpBand->fStyle & RBBS_USECHEVRON) && (lpBand->rcChild.right - lpBand->rcChild.left < lpBand->cxIdeal))
809c2c66affSColin Finck {
810c2c66affSColin Finck lpBand->rcChild.right -= CHEVRON_WIDTH;
811c2c66affSColin Finck SetRect(&lpBand->rcChevron, lpBand->rcChild.right,
812c2c66affSColin Finck lpBand->rcChild.top, lpBand->rcChild.right + CHEVRON_WIDTH,
813c2c66affSColin Finck lpBand->rcChild.bottom);
814c2c66affSColin Finck }
815c2c66affSColin Finck }
816c2c66affSColin Finck else {
817c2c66affSColin Finck SetRect (&lpBand->rcChild,
818c2c66affSColin Finck lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.top,
819c2c66affSColin Finck lpBand->rcBand.right, lpBand->rcBand.bottom);
820c2c66affSColin Finck }
821c2c66affSColin Finck
822c2c66affSColin Finck /* flag if notify required and invalidate rectangle */
823c2c66affSColin Finck if (lpBand->fDraw & NTF_INVALIDATE) {
824c2c66affSColin Finck lpBand->fDraw &= ~NTF_INVALIDATE;
825c2c66affSColin Finck work = lpBand->rcBand;
826c2c66affSColin Finck work.right += SEP_WIDTH;
827c2c66affSColin Finck work.bottom += SEP_WIDTH;
828c2c66affSColin Finck TRACE("invalidating %s\n", wine_dbgstr_rect(&work));
829c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, &work, TRUE);
830c2c66affSColin Finck if (lpBand->hwndChild) InvalidateRect(lpBand->hwndChild, NULL, TRUE);
831c2c66affSColin Finck }
832c2c66affSColin Finck
833c2c66affSColin Finck }
834c2c66affSColin Finck
835c2c66affSColin Finck }
836c2c66affSColin Finck
837c2c66affSColin Finck
838c2c66affSColin Finck static VOID
REBAR_CalcVertBand(const REBAR_INFO * infoPtr,UINT rstart,UINT rend)839c2c66affSColin Finck REBAR_CalcVertBand (const REBAR_INFO *infoPtr, UINT rstart, UINT rend)
840c2c66affSColin Finck /* Function: this routine initializes all the rectangles in */
841c2c66affSColin Finck /* each band in a row to fit in the adjusted rcBand rect. */
842c2c66affSColin Finck /* *** Supports only Vertical bars. *** */
843c2c66affSColin Finck {
844c2c66affSColin Finck REBAR_BAND *lpBand;
845c2c66affSColin Finck UINT i, xoff;
846c2c66affSColin Finck RECT work;
847c2c66affSColin Finck
848c2c66affSColin Finck for(i=rstart; i<rend; i++){
849c2c66affSColin Finck RECT rcBand;
850c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
851c2c66affSColin Finck if (HIDDENBAND(lpBand)) continue;
852c2c66affSColin Finck
853c2c66affSColin Finck translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
854c2c66affSColin Finck
855c2c66affSColin Finck /* set initial gripper rectangle */
856c2c66affSColin Finck SetRect (&lpBand->rcGripper, rcBand.left, rcBand.top, rcBand.right, rcBand.top);
857c2c66affSColin Finck
858c2c66affSColin Finck /* calculate gripper rectangle */
859c2c66affSColin Finck if (lpBand->fStatus & HAS_GRIPPER) {
860c2c66affSColin Finck lpBand->fDraw |= DRAW_GRIPPER;
861c2c66affSColin Finck
862c2c66affSColin Finck if (infoPtr->dwStyle & RBS_VERTICALGRIPPER) {
863c2c66affSColin Finck /* vertical gripper */
864c2c66affSColin Finck lpBand->rcGripper.left += 3;
865c2c66affSColin Finck lpBand->rcGripper.right = lpBand->rcGripper.left + GRIPPER_WIDTH;
866c2c66affSColin Finck lpBand->rcGripper.top += REBAR_PRE_GRIPPER;
867c2c66affSColin Finck lpBand->rcGripper.bottom = lpBand->rcGripper.top + GRIPPER_HEIGHT;
868c2c66affSColin Finck
869c2c66affSColin Finck /* initialize Caption image rectangle */
870c2c66affSColin Finck SetRect (&lpBand->rcCapImage, rcBand.left,
871c2c66affSColin Finck lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE,
872c2c66affSColin Finck rcBand.right,
873c2c66affSColin Finck lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE);
874c2c66affSColin Finck }
875c2c66affSColin Finck else {
876c2c66affSColin Finck /* horizontal gripper */
877c2c66affSColin Finck InflateRect(&lpBand->rcGripper, -2, 0);
878c2c66affSColin Finck lpBand->rcGripper.top += REBAR_PRE_GRIPPER;
879c2c66affSColin Finck lpBand->rcGripper.bottom = lpBand->rcGripper.top + GRIPPER_WIDTH;
880c2c66affSColin Finck
881c2c66affSColin Finck /* initialize Caption image rectangle */
882c2c66affSColin Finck SetRect (&lpBand->rcCapImage, rcBand.left,
883c2c66affSColin Finck lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE,
884c2c66affSColin Finck rcBand.right,
885c2c66affSColin Finck lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE);
886c2c66affSColin Finck }
887c2c66affSColin Finck }
888c2c66affSColin Finck else { /* no gripper will be drawn */
889c2c66affSColin Finck xoff = 0;
890c2c66affSColin Finck if (lpBand->fStatus & (HAS_IMAGE | HAS_TEXT))
891c2c66affSColin Finck /* if no gripper but either image or text, then leave space */
892c2c66affSColin Finck xoff = REBAR_ALWAYS_SPACE;
893c2c66affSColin Finck /* initialize Caption image rectangle */
894c2c66affSColin Finck SetRect (&lpBand->rcCapImage,
895c2c66affSColin Finck rcBand.left, rcBand.top+xoff,
896c2c66affSColin Finck rcBand.right, rcBand.top+xoff);
897c2c66affSColin Finck }
898c2c66affSColin Finck
899c2c66affSColin Finck /* image is visible */
900c2c66affSColin Finck if (lpBand->fStatus & HAS_IMAGE) {
901c2c66affSColin Finck lpBand->fDraw |= DRAW_IMAGE;
902c2c66affSColin Finck
903c2c66affSColin Finck lpBand->rcCapImage.right = lpBand->rcCapImage.left + infoPtr->imageSize.cx;
904c2c66affSColin Finck lpBand->rcCapImage.bottom += infoPtr->imageSize.cy;
905c2c66affSColin Finck
906c2c66affSColin Finck /* set initial caption text rectangle */
907c2c66affSColin Finck SetRect (&lpBand->rcCapText,
908c2c66affSColin Finck rcBand.left, lpBand->rcCapImage.bottom+REBAR_POST_IMAGE,
909c2c66affSColin Finck rcBand.right, rcBand.top+lpBand->cxHeader);
910c2c66affSColin Finck }
911c2c66affSColin Finck else {
912c2c66affSColin Finck /* set initial caption text rectangle */
913c2c66affSColin Finck SetRect (&lpBand->rcCapText,
914c2c66affSColin Finck rcBand.left, lpBand->rcCapImage.bottom,
915c2c66affSColin Finck rcBand.right, rcBand.top+lpBand->cxHeader);
916c2c66affSColin Finck }
917c2c66affSColin Finck
918c2c66affSColin Finck /* text is visible */
919c2c66affSColin Finck if ((lpBand->fStatus & HAS_TEXT) && !(lpBand->fStyle & RBBS_HIDETITLE)) {
920c2c66affSColin Finck lpBand->fDraw |= DRAW_TEXT;
921c2c66affSColin Finck lpBand->rcCapText.bottom = max(lpBand->rcCapText.top,
922c2c66affSColin Finck lpBand->rcCapText.bottom);
923c2c66affSColin Finck }
924c2c66affSColin Finck
925c2c66affSColin Finck /* set initial child window rectangle if there is a child */
926c2c66affSColin Finck if (lpBand->hwndChild) {
927c2c66affSColin Finck int cxBand = rcBand.right - rcBand.left;
928c2c66affSColin Finck xoff = (cxBand - lpBand->cyChild) / 2;
929c2c66affSColin Finck SetRect (&lpBand->rcChild,
930c2c66affSColin Finck rcBand.left + xoff, rcBand.top + lpBand->cxHeader,
931c2c66affSColin Finck rcBand.left + xoff + lpBand->cyChild, rcBand.bottom - REBAR_POST_CHILD);
932c2c66affSColin Finck }
933c2c66affSColin Finck else {
934c2c66affSColin Finck SetRect (&lpBand->rcChild,
935c2c66affSColin Finck rcBand.left, rcBand.top+lpBand->cxHeader,
936c2c66affSColin Finck rcBand.right, rcBand.bottom);
937c2c66affSColin Finck }
938c2c66affSColin Finck
939c2c66affSColin Finck if (lpBand->fDraw & NTF_INVALIDATE) {
940c2c66affSColin Finck lpBand->fDraw &= ~NTF_INVALIDATE;
941c2c66affSColin Finck work = rcBand;
942c2c66affSColin Finck work.bottom += SEP_WIDTH;
943c2c66affSColin Finck work.right += SEP_WIDTH;
944c2c66affSColin Finck TRACE("invalidating %s\n", wine_dbgstr_rect(&work));
945c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, &work, TRUE);
946c2c66affSColin Finck if (lpBand->hwndChild) InvalidateRect(lpBand->hwndChild, NULL, TRUE);
947c2c66affSColin Finck }
948c2c66affSColin Finck
949c2c66affSColin Finck }
950c2c66affSColin Finck }
951c2c66affSColin Finck
952c2c66affSColin Finck
953c2c66affSColin Finck static VOID
REBAR_ForceResize(REBAR_INFO * infoPtr)954c2c66affSColin Finck REBAR_ForceResize (REBAR_INFO *infoPtr)
955c2c66affSColin Finck /* Function: This changes the size of the REBAR window to that */
956c2c66affSColin Finck /* calculated by REBAR_Layout. */
957c2c66affSColin Finck {
958c2c66affSColin Finck INT x, y, width, height;
959c2c66affSColin Finck INT xedge = 0, yedge = 0;
960c2c66affSColin Finck RECT rcSelf;
961c2c66affSColin Finck
962c2c66affSColin Finck TRACE("new size [%d x %d]\n", infoPtr->calcSize.cx, infoPtr->calcSize.cy);
963c2c66affSColin Finck
964c2c66affSColin Finck if (infoPtr->dwStyle & CCS_NORESIZE)
965c2c66affSColin Finck return;
966c2c66affSColin Finck
967c2c66affSColin Finck if (infoPtr->dwStyle & WS_BORDER)
968c2c66affSColin Finck {
969c2c66affSColin Finck xedge = GetSystemMetrics(SM_CXEDGE);
970c2c66affSColin Finck yedge = GetSystemMetrics(SM_CYEDGE);
971c2c66affSColin Finck /* swap for CCS_VERT? */
972c2c66affSColin Finck }
973c2c66affSColin Finck
974c2c66affSColin Finck /* compute rebar window rect in parent client coordinates */
975c2c66affSColin Finck GetWindowRect(infoPtr->hwndSelf, &rcSelf);
976c2c66affSColin Finck MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->hwndSelf), (LPPOINT)&rcSelf, 2);
977c2c66affSColin Finck translate_rect(infoPtr, &rcSelf, &rcSelf);
978c2c66affSColin Finck
979c2c66affSColin Finck height = infoPtr->calcSize.cy + 2*yedge;
980c2c66affSColin Finck if (!(infoPtr->dwStyle & CCS_NOPARENTALIGN)) {
981c2c66affSColin Finck RECT rcParent;
982c2c66affSColin Finck
983c2c66affSColin Finck x = -xedge;
984c2c66affSColin Finck width = infoPtr->calcSize.cx + 2*xedge;
985c2c66affSColin Finck y = 0; /* quiet compiler warning */
986c2c66affSColin Finck switch ( infoPtr->dwStyle & CCS_LAYOUT_MASK) {
987c2c66affSColin Finck case 0: /* shouldn't happen - see NCCreate */
988c2c66affSColin Finck case CCS_TOP:
989c2c66affSColin Finck y = ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER) - yedge;
990c2c66affSColin Finck break;
991c2c66affSColin Finck case CCS_NOMOVEY:
992c2c66affSColin Finck y = rcSelf.top;
993c2c66affSColin Finck break;
994c2c66affSColin Finck case CCS_BOTTOM:
995c2c66affSColin Finck GetClientRect(GetParent(infoPtr->hwndSelf), &rcParent);
996c2c66affSColin Finck translate_rect(infoPtr, &rcParent, &rcParent);
997c2c66affSColin Finck y = rcParent.bottom - infoPtr->calcSize.cy - yedge;
998c2c66affSColin Finck break;
999c2c66affSColin Finck }
1000c2c66affSColin Finck }
1001c2c66affSColin Finck else {
1002c2c66affSColin Finck x = rcSelf.left;
1003c2c66affSColin Finck /* As on Windows if the CCS_NODIVIDER is not present the control will move
1004c2c66affSColin Finck * 2 pixel down after every layout */
1005c2c66affSColin Finck y = rcSelf.top + ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER);
1006c2c66affSColin Finck width = rcSelf.right - rcSelf.left;
1007c2c66affSColin Finck }
1008c2c66affSColin Finck
1009c2c66affSColin Finck TRACE("hwnd %p, style=%08x, setting at (%d,%d) for (%d,%d)\n",
1010c2c66affSColin Finck infoPtr->hwndSelf, infoPtr->dwStyle, x, y, width, height);
1011c2c66affSColin Finck
1012c2c66affSColin Finck /* Set flag to ignore next WM_SIZE message and resize the window */
1013c2c66affSColin Finck infoPtr->fStatus |= SELF_RESIZE;
1014c2c66affSColin Finck if ((infoPtr->dwStyle & CCS_VERT) == 0)
1015c2c66affSColin Finck SetWindowPos(infoPtr->hwndSelf, 0, x, y, width, height, SWP_NOZORDER);
1016c2c66affSColin Finck else
1017c2c66affSColin Finck SetWindowPos(infoPtr->hwndSelf, 0, y, x, height, width, SWP_NOZORDER);
1018c2c66affSColin Finck infoPtr->fStatus &= ~SELF_RESIZE;
1019c2c66affSColin Finck }
1020c2c66affSColin Finck
1021c2c66affSColin Finck
1022c2c66affSColin Finck static VOID
REBAR_MoveChildWindows(const REBAR_INFO * infoPtr,UINT start,UINT endplus)1023c2c66affSColin Finck REBAR_MoveChildWindows (const REBAR_INFO *infoPtr, UINT start, UINT endplus)
1024c2c66affSColin Finck {
1025c2c66affSColin Finck static const WCHAR strComboBox[] = { 'C','o','m','b','o','B','o','x',0 };
1026c2c66affSColin Finck REBAR_BAND *lpBand;
1027c2c66affSColin Finck WCHAR szClassName[40];
1028c2c66affSColin Finck UINT i;
1029c2c66affSColin Finck NMREBARCHILDSIZE rbcz;
1030c2c66affSColin Finck HDWP deferpos;
1031c2c66affSColin Finck
1032c2c66affSColin Finck if (!(deferpos = BeginDeferWindowPos(infoPtr->uNumBands)))
1033c2c66affSColin Finck ERR("BeginDeferWindowPos returned NULL\n");
1034c2c66affSColin Finck
1035c2c66affSColin Finck for (i = start; i < endplus; i++) {
1036c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
1037c2c66affSColin Finck
1038c2c66affSColin Finck if (HIDDENBAND(lpBand)) continue;
1039c2c66affSColin Finck if (lpBand->hwndChild) {
1040c2c66affSColin Finck TRACE("hwndChild = %p\n", lpBand->hwndChild);
1041c2c66affSColin Finck
1042c2c66affSColin Finck /* Always generate the RBN_CHILDSIZE even if child
1043c2c66affSColin Finck did not change */
1044c2c66affSColin Finck rbcz.uBand = i;
1045c2c66affSColin Finck rbcz.wID = lpBand->wID;
1046c2c66affSColin Finck rbcz.rcChild = lpBand->rcChild;
1047c2c66affSColin Finck translate_rect(infoPtr, &rbcz.rcBand, &lpBand->rcBand);
1048c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT)
1049c2c66affSColin Finck rbcz.rcBand.top += lpBand->cxHeader;
1050c2c66affSColin Finck else
1051c2c66affSColin Finck rbcz.rcBand.left += lpBand->cxHeader;
1052c2c66affSColin Finck REBAR_Notify ((NMHDR *)&rbcz, infoPtr, RBN_CHILDSIZE);
1053c2c66affSColin Finck if (!EqualRect (&lpBand->rcChild, &rbcz.rcChild)) {
1054c2c66affSColin Finck TRACE("Child rect changed by NOTIFY for band %u\n", i);
1055c2c66affSColin Finck TRACE(" from (%s) to (%s)\n",
1056c2c66affSColin Finck wine_dbgstr_rect(&lpBand->rcChild),
1057c2c66affSColin Finck wine_dbgstr_rect(&rbcz.rcChild));
1058c2c66affSColin Finck lpBand->rcChild = rbcz.rcChild; /* *** ??? */
1059c2c66affSColin Finck }
1060c2c66affSColin Finck
1061b3fb8555SGiannis Adamopoulos GetClassNameW (lpBand->hwndChild, szClassName, ARRAY_SIZE(szClassName));
1062c2c66affSColin Finck if (!lstrcmpW (szClassName, strComboBox) ||
1063c2c66affSColin Finck !lstrcmpW (szClassName, WC_COMBOBOXEXW)) {
1064c2c66affSColin Finck INT nEditHeight, yPos;
1065c2c66affSColin Finck RECT rc;
1066c2c66affSColin Finck
1067c2c66affSColin Finck /* special placement code for combo or comboex box */
1068c2c66affSColin Finck
1069c2c66affSColin Finck
1070c2c66affSColin Finck /* get size of edit line */
1071c2c66affSColin Finck GetWindowRect (lpBand->hwndChild, &rc);
1072c2c66affSColin Finck nEditHeight = rc.bottom - rc.top;
1073c2c66affSColin Finck yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;
1074c2c66affSColin Finck
1075c2c66affSColin Finck /* center combo box inside child area */
1076c2c66affSColin Finck TRACE("moving child (Combo(Ex)) %p to (%d,%d) for (%d,%d)\n",
1077c2c66affSColin Finck lpBand->hwndChild,
1078c2c66affSColin Finck lpBand->rcChild.left, yPos,
1079c2c66affSColin Finck lpBand->rcChild.right - lpBand->rcChild.left,
1080c2c66affSColin Finck nEditHeight);
1081c2c66affSColin Finck deferpos = DeferWindowPos (deferpos, lpBand->hwndChild, HWND_TOP,
1082c2c66affSColin Finck lpBand->rcChild.left,
1083c2c66affSColin Finck /*lpBand->rcChild.top*/ yPos,
1084c2c66affSColin Finck lpBand->rcChild.right - lpBand->rcChild.left,
1085c2c66affSColin Finck nEditHeight,
1086c2c66affSColin Finck SWP_NOZORDER);
1087c2c66affSColin Finck if (!deferpos)
1088c2c66affSColin Finck ERR("DeferWindowPos returned NULL\n");
1089c2c66affSColin Finck }
1090c2c66affSColin Finck else {
1091c2c66affSColin Finck TRACE("moving child (Other) %p to (%d,%d) for (%d,%d)\n",
1092c2c66affSColin Finck lpBand->hwndChild,
1093c2c66affSColin Finck lpBand->rcChild.left, lpBand->rcChild.top,
1094c2c66affSColin Finck lpBand->rcChild.right - lpBand->rcChild.left,
1095c2c66affSColin Finck lpBand->rcChild.bottom - lpBand->rcChild.top);
1096c2c66affSColin Finck deferpos = DeferWindowPos (deferpos, lpBand->hwndChild, HWND_TOP,
1097c2c66affSColin Finck lpBand->rcChild.left,
1098c2c66affSColin Finck lpBand->rcChild.top,
1099c2c66affSColin Finck lpBand->rcChild.right - lpBand->rcChild.left,
1100c2c66affSColin Finck lpBand->rcChild.bottom - lpBand->rcChild.top,
1101c2c66affSColin Finck SWP_NOZORDER);
1102c2c66affSColin Finck if (!deferpos)
1103c2c66affSColin Finck ERR("DeferWindowPos returned NULL\n");
1104c2c66affSColin Finck }
1105c2c66affSColin Finck }
1106c2c66affSColin Finck }
1107c2c66affSColin Finck if (!EndDeferWindowPos(deferpos))
1108c2c66affSColin Finck ERR("EndDeferWindowPos returned NULL\n");
1109c2c66affSColin Finck
1110c2c66affSColin Finck if (infoPtr->DoRedraw)
1111c2c66affSColin Finck UpdateWindow (infoPtr->hwndSelf);
1112c2c66affSColin Finck }
1113c2c66affSColin Finck
1114c2c66affSColin Finck /* Returns the next visible band (the first visible band in [i+1; infoPtr->uNumBands) )
1115c2c66affSColin Finck * or infoPtr->uNumBands if none */
next_visible(const REBAR_INFO * infoPtr,int i)1116c2c66affSColin Finck static int next_visible(const REBAR_INFO *infoPtr, int i)
1117c2c66affSColin Finck {
1118c2c66affSColin Finck unsigned int n;
1119c2c66affSColin Finck for (n = i + 1; n < infoPtr->uNumBands; n++)
1120c2c66affSColin Finck if (!HIDDENBAND(REBAR_GetBand(infoPtr, n)))
1121c2c66affSColin Finck break;
1122c2c66affSColin Finck return n;
1123c2c66affSColin Finck }
1124c2c66affSColin Finck
1125c2c66affSColin Finck /* Returns the previous visible band (the last visible band in [0; i) )
1126c2c66affSColin Finck * or -1 if none */
prev_visible(const REBAR_INFO * infoPtr,int i)1127c2c66affSColin Finck static int prev_visible(const REBAR_INFO *infoPtr, int i)
1128c2c66affSColin Finck {
1129c2c66affSColin Finck int n;
1130c2c66affSColin Finck for (n = i - 1; n >= 0; n--)
1131c2c66affSColin Finck if (!HIDDENBAND(REBAR_GetBand(infoPtr, n)))
1132c2c66affSColin Finck break;
1133c2c66affSColin Finck return n;
1134c2c66affSColin Finck }
1135c2c66affSColin Finck
1136c2c66affSColin Finck /* Returns the first visible band or infoPtr->uNumBands if none */
first_visible(const REBAR_INFO * infoPtr)1137c2c66affSColin Finck static int first_visible(const REBAR_INFO *infoPtr)
1138c2c66affSColin Finck {
1139c2c66affSColin Finck return next_visible(infoPtr, -1); /* this works*/
1140c2c66affSColin Finck }
1141c2c66affSColin Finck
1142c2c66affSColin Finck /* Returns the first visible band for the given row (or iBand if none) */
get_row_begin_for_band(const REBAR_INFO * infoPtr,INT iBand)1143c2c66affSColin Finck static int get_row_begin_for_band(const REBAR_INFO *infoPtr, INT iBand)
1144c2c66affSColin Finck {
1145c2c66affSColin Finck int iLastBand = iBand;
1146c2c66affSColin Finck int iRow = REBAR_GetBand(infoPtr, iBand)->iRow;
1147c2c66affSColin Finck while ((iBand = prev_visible(infoPtr, iBand)) >= 0) {
1148c2c66affSColin Finck if (REBAR_GetBand(infoPtr, iBand)->iRow != iRow)
1149c2c66affSColin Finck break;
1150c2c66affSColin Finck else
1151c2c66affSColin Finck iLastBand = iBand;
1152c2c66affSColin Finck }
1153c2c66affSColin Finck return iLastBand;
1154c2c66affSColin Finck }
1155c2c66affSColin Finck
1156c2c66affSColin Finck /* Returns the first visible band for the next row (or infoPtr->uNumBands if none) */
get_row_end_for_band(const REBAR_INFO * infoPtr,INT iBand)1157c2c66affSColin Finck static int get_row_end_for_band(const REBAR_INFO *infoPtr, INT iBand)
1158c2c66affSColin Finck {
1159c2c66affSColin Finck int iRow = REBAR_GetBand(infoPtr, iBand)->iRow;
1160c2c66affSColin Finck while ((iBand = next_visible(infoPtr, iBand)) < infoPtr->uNumBands)
1161c2c66affSColin Finck if (REBAR_GetBand(infoPtr, iBand)->iRow != iRow)
1162c2c66affSColin Finck break;
1163c2c66affSColin Finck return iBand;
1164c2c66affSColin Finck }
1165c2c66affSColin Finck
1166c2c66affSColin Finck /* Compute the rcBand.{left,right} from the cxEffective bands widths computed earlier.
1167c2c66affSColin Finck * iBeginBand must be visible */
REBAR_SetRowRectsX(const REBAR_INFO * infoPtr,INT iBeginBand,INT iEndBand)1168c2c66affSColin Finck static void REBAR_SetRowRectsX(const REBAR_INFO *infoPtr, INT iBeginBand, INT iEndBand)
1169c2c66affSColin Finck {
1170c2c66affSColin Finck int xPos = 0, i;
1171c2c66affSColin Finck for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
1172c2c66affSColin Finck {
1173c2c66affSColin Finck REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, i);
1174c2c66affSColin Finck if (lpBand->rcBand.left != xPos || lpBand->rcBand.right != xPos + lpBand->cxEffective) {
1175c2c66affSColin Finck lpBand->fDraw |= NTF_INVALIDATE;
1176c2c66affSColin Finck TRACE("Setting rect %d to %d,%d\n", i, xPos, xPos + lpBand->cxEffective);
1177c2c66affSColin Finck lpBand->rcBand.left = xPos;
1178c2c66affSColin Finck lpBand->rcBand.right = xPos + lpBand->cxEffective;
1179c2c66affSColin Finck }
1180c2c66affSColin Finck xPos += lpBand->cxEffective + SEP_WIDTH;
1181c2c66affSColin Finck }
1182c2c66affSColin Finck }
1183c2c66affSColin Finck
1184c2c66affSColin Finck /* The rationale of this function is probably as follows: if we have some space
1185c2c66affSColin Finck * to distribute we want to add it to a band on the right. However we don't want
1186c2c66affSColin Finck * to unminimize a minimized band so we search for a band that is big enough.
1187c2c66affSColin Finck * For some reason "big enough" is defined as bigger than the minimum size of the
1188c2c66affSColin Finck * first band in the row
1189c2c66affSColin Finck */
REBAR_FindBandToGrow(const REBAR_INFO * infoPtr,INT iBeginBand,INT iEndBand)1190c2c66affSColin Finck static REBAR_BAND *REBAR_FindBandToGrow(const REBAR_INFO *infoPtr, INT iBeginBand, INT iEndBand)
1191c2c66affSColin Finck {
1192c2c66affSColin Finck INT cxMinFirstBand = 0, i;
1193c2c66affSColin Finck
1194c2c66affSColin Finck cxMinFirstBand = REBAR_GetBand(infoPtr, iBeginBand)->cxMinBand;
1195c2c66affSColin Finck
1196c2c66affSColin Finck for (i = prev_visible(infoPtr, iEndBand); i >= iBeginBand; i = prev_visible(infoPtr, i))
1197c2c66affSColin Finck if (REBAR_GetBand(infoPtr, i)->cxEffective > cxMinFirstBand &&
1198c2c66affSColin Finck !(REBAR_GetBand(infoPtr, i)->fStyle & RBBS_FIXEDSIZE))
1199c2c66affSColin Finck break;
1200c2c66affSColin Finck
1201c2c66affSColin Finck if (i < iBeginBand)
1202c2c66affSColin Finck for (i = prev_visible(infoPtr, iEndBand); i >= iBeginBand; i = prev_visible(infoPtr, i))
1203c2c66affSColin Finck if (REBAR_GetBand(infoPtr, i)->cxMinBand == cxMinFirstBand)
1204c2c66affSColin Finck break;
1205c2c66affSColin Finck
1206c2c66affSColin Finck TRACE("Extra space for row [%d..%d) should be added to band %d\n", iBeginBand, iEndBand, i);
1207c2c66affSColin Finck return REBAR_GetBand(infoPtr, i);
1208c2c66affSColin Finck }
1209c2c66affSColin Finck
1210c2c66affSColin Finck /* Try to shrink the visible bands in [iBeginBand; iEndBand) by cxShrink, starting from the right */
REBAR_ShrinkBandsRTL(const REBAR_INFO * infoPtr,INT iBeginBand,INT iEndBand,INT cxShrink,BOOL bEnforce)1211c2c66affSColin Finck static int REBAR_ShrinkBandsRTL(const REBAR_INFO *infoPtr, INT iBeginBand, INT iEndBand, INT cxShrink, BOOL bEnforce)
1212c2c66affSColin Finck {
1213c2c66affSColin Finck REBAR_BAND *lpBand;
1214c2c66affSColin Finck INT width, i;
1215c2c66affSColin Finck
1216c2c66affSColin Finck TRACE("Shrinking bands [%d..%d) by %d, right-to-left\n", iBeginBand, iEndBand, cxShrink);
1217c2c66affSColin Finck for (i = prev_visible(infoPtr, iEndBand); i >= iBeginBand; i = prev_visible(infoPtr, i))
1218c2c66affSColin Finck {
1219c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
1220c2c66affSColin Finck
1221c2c66affSColin Finck width = max(lpBand->cxEffective - cxShrink, (int)lpBand->cxMinBand);
1222c2c66affSColin Finck cxShrink -= lpBand->cxEffective - width;
1223c2c66affSColin Finck lpBand->cxEffective = width;
1224c2c66affSColin Finck if (bEnforce && lpBand->cx > lpBand->cxEffective)
1225c2c66affSColin Finck lpBand->cx = lpBand->cxEffective;
1226c2c66affSColin Finck if (cxShrink == 0)
1227c2c66affSColin Finck break;
1228c2c66affSColin Finck }
1229c2c66affSColin Finck return cxShrink;
1230c2c66affSColin Finck }
1231c2c66affSColin Finck
1232c2c66affSColin Finck
1233c2c66affSColin Finck /* Try to shrink the visible bands in [iBeginBand; iEndBand) by cxShrink, starting from the left.
1234c2c66affSColin Finck * iBeginBand must be visible */
REBAR_ShrinkBandsLTR(const REBAR_INFO * infoPtr,INT iBeginBand,INT iEndBand,INT cxShrink,BOOL bEnforce)1235c2c66affSColin Finck static int REBAR_ShrinkBandsLTR(const REBAR_INFO *infoPtr, INT iBeginBand, INT iEndBand, INT cxShrink, BOOL bEnforce)
1236c2c66affSColin Finck {
1237c2c66affSColin Finck REBAR_BAND *lpBand;
1238c2c66affSColin Finck INT width, i;
1239c2c66affSColin Finck
1240c2c66affSColin Finck TRACE("Shrinking bands [%d..%d) by %d, left-to-right\n", iBeginBand, iEndBand, cxShrink);
1241c2c66affSColin Finck for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
1242c2c66affSColin Finck {
1243c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
1244c2c66affSColin Finck
1245c2c66affSColin Finck width = max(lpBand->cxEffective - cxShrink, (int)lpBand->cxMinBand);
1246c2c66affSColin Finck cxShrink -= lpBand->cxEffective - width;
1247c2c66affSColin Finck lpBand->cxEffective = width;
1248c2c66affSColin Finck if (bEnforce)
1249c2c66affSColin Finck lpBand->cx = lpBand->cxEffective;
1250c2c66affSColin Finck if (cxShrink == 0)
1251c2c66affSColin Finck break;
1252c2c66affSColin Finck }
1253c2c66affSColin Finck return cxShrink;
1254c2c66affSColin Finck }
1255c2c66affSColin Finck
1256c2c66affSColin Finck /* Tries to move a band to a given offset within a row. */
REBAR_MoveBandToRowOffset(REBAR_INFO * infoPtr,INT iBand,INT iFirstBand,INT iLastBand,INT xOff,BOOL reorder)1257c2c66affSColin Finck static int REBAR_MoveBandToRowOffset(REBAR_INFO *infoPtr, INT iBand, INT iFirstBand,
1258c2c66affSColin Finck INT iLastBand, INT xOff, BOOL reorder)
1259c2c66affSColin Finck {
1260c2c66affSColin Finck REBAR_BAND *insertBand = REBAR_GetBand(infoPtr, iBand);
1261c2c66affSColin Finck int xPos = 0, i;
1262c2c66affSColin Finck const BOOL setBreak = REBAR_GetBand(infoPtr, iFirstBand)->fStyle & RBBS_BREAK;
1263c2c66affSColin Finck
1264c2c66affSColin Finck /* Find the band's new position */
1265c2c66affSColin Finck if(reorder)
1266c2c66affSColin Finck {
1267c2c66affSColin Finck /* Used during an LR band reorder drag */
1268c2c66affSColin Finck for (i = iFirstBand; i < iLastBand; i = next_visible(infoPtr, i))
1269c2c66affSColin Finck {
1270c2c66affSColin Finck if(xPos > xOff)
1271c2c66affSColin Finck break;
1272c2c66affSColin Finck xPos += REBAR_GetBand(infoPtr, i)->cxEffective + SEP_WIDTH;
1273c2c66affSColin Finck }
1274c2c66affSColin Finck }
1275c2c66affSColin Finck else
1276c2c66affSColin Finck {
1277c2c66affSColin Finck /* Used during a UD band insertion drag */
1278c2c66affSColin Finck for (i = iFirstBand; i < iLastBand; i = next_visible(infoPtr, i))
1279c2c66affSColin Finck {
1280c2c66affSColin Finck const REBAR_BAND *band = REBAR_GetBand(infoPtr, i);
1281c2c66affSColin Finck if(xPos + band->cxMinBand / 2 > xOff)
1282c2c66affSColin Finck break;
1283c2c66affSColin Finck xPos += band->cxEffective + SEP_WIDTH;
1284c2c66affSColin Finck }
1285c2c66affSColin Finck }
1286c2c66affSColin Finck
1287c2c66affSColin Finck /* Move the band to its new position */
1288c2c66affSColin Finck DPA_DeletePtr(infoPtr->bands, iBand);
1289c2c66affSColin Finck if(i > iBand)
1290c2c66affSColin Finck i--;
1291c2c66affSColin Finck DPA_InsertPtr(infoPtr->bands, i, insertBand);
1292c2c66affSColin Finck
1293c2c66affSColin Finck /* Ensure only the last band has the RBBS_BREAK flag set */
1294c2c66affSColin Finck insertBand->fStyle &= ~RBBS_BREAK;
1295c2c66affSColin Finck if(setBreak)
1296c2c66affSColin Finck REBAR_GetBand(infoPtr, iFirstBand)->fStyle |= RBBS_BREAK;
1297c2c66affSColin Finck
1298c2c66affSColin Finck /* Return the currently grabbed band */
1299c2c66affSColin Finck if(infoPtr->iGrabbedBand == iBand)
1300c2c66affSColin Finck {
1301c2c66affSColin Finck infoPtr->iGrabbedBand = i;
1302c2c66affSColin Finck return i;
1303c2c66affSColin Finck }
1304c2c66affSColin Finck else return -1;
1305c2c66affSColin Finck }
1306c2c66affSColin Finck
1307c2c66affSColin Finck /* Set the heights of the visible bands in [iBeginBand; iEndBand) to the max height. iBeginBand must be visible */
REBAR_SetBandsHeight(const REBAR_INFO * infoPtr,INT iBeginBand,INT iEndBand,INT yStart)1308c2c66affSColin Finck static int REBAR_SetBandsHeight(const REBAR_INFO *infoPtr, INT iBeginBand, INT iEndBand, INT yStart)
1309c2c66affSColin Finck {
1310c2c66affSColin Finck REBAR_BAND *lpBand;
1311c2c66affSColin Finck int yMaxHeight = 0;
1312c2c66affSColin Finck int yPos = yStart;
13130707475fSJustin Miller int row, i;
13140707475fSJustin Miller
1315c2c66affSColin Finck for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
1316c2c66affSColin Finck {
1317c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
1318c2c66affSColin Finck lpBand->cyRowSoFar = yMaxHeight;
1319c2c66affSColin Finck yMaxHeight = max(yMaxHeight, lpBand->cyMinBand);
1320c2c66affSColin Finck }
1321c2c66affSColin Finck TRACE("Bands [%d; %d) height: %d\n", iBeginBand, iEndBand, yMaxHeight);
1322c2c66affSColin Finck
13230707475fSJustin Miller row = iBeginBand < iEndBand ? REBAR_GetBand(infoPtr, iBeginBand)->iRow : 0;
13240707475fSJustin Miller
1325c2c66affSColin Finck for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
1326c2c66affSColin Finck {
1327c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
1328c2c66affSColin Finck /* we may be called for multiple rows if RBS_VARHEIGHT not set */
1329c2c66affSColin Finck if (lpBand->iRow != row) {
1330c2c66affSColin Finck yPos += yMaxHeight + SEP_WIDTH;
1331c2c66affSColin Finck row = lpBand->iRow;
1332c2c66affSColin Finck }
1333c2c66affSColin Finck
1334c2c66affSColin Finck if (lpBand->rcBand.top != yPos || lpBand->rcBand.bottom != yPos + yMaxHeight) {
1335c2c66affSColin Finck lpBand->fDraw |= NTF_INVALIDATE;
1336c2c66affSColin Finck lpBand->rcBand.top = yPos;
1337c2c66affSColin Finck lpBand->rcBand.bottom = yPos + yMaxHeight;
1338c2c66affSColin Finck TRACE("Band %d: %s\n", i, wine_dbgstr_rect(&lpBand->rcBand));
1339c2c66affSColin Finck }
1340c2c66affSColin Finck }
1341c2c66affSColin Finck return yPos + yMaxHeight;
1342c2c66affSColin Finck }
1343c2c66affSColin Finck
1344c2c66affSColin Finck /* Layout the row [iBeginBand; iEndBand). iBeginBand must be visible */
REBAR_LayoutRow(const REBAR_INFO * infoPtr,int iBeginBand,int iEndBand,int cx,int * piRow,int * pyPos)1345c2c66affSColin Finck static void REBAR_LayoutRow(const REBAR_INFO *infoPtr, int iBeginBand, int iEndBand, int cx, int *piRow, int *pyPos)
1346c2c66affSColin Finck {
1347c2c66affSColin Finck REBAR_BAND *lpBand;
1348c2c66affSColin Finck int i, extra;
1349c2c66affSColin Finck int width = 0;
1350c2c66affSColin Finck
1351c2c66affSColin Finck TRACE("Adjusting row [%d;%d). Width: %d\n", iBeginBand, iEndBand, cx);
1352c2c66affSColin Finck for (i = iBeginBand; i < iEndBand; i++)
1353c2c66affSColin Finck REBAR_GetBand(infoPtr, i)->iRow = *piRow;
1354c2c66affSColin Finck
1355c2c66affSColin Finck /* compute the extra space */
1356c2c66affSColin Finck for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
1357c2c66affSColin Finck {
1358c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
1359c2c66affSColin Finck if (i > iBeginBand)
1360c2c66affSColin Finck width += SEP_WIDTH;
1361c2c66affSColin Finck lpBand->cxEffective = max(lpBand->cxMinBand, lpBand->cx);
1362c2c66affSColin Finck width += lpBand->cxEffective;
1363c2c66affSColin Finck }
1364c2c66affSColin Finck
1365c2c66affSColin Finck extra = cx - width;
1366c2c66affSColin Finck TRACE("Extra space: %d\n", extra);
1367c2c66affSColin Finck if (extra < 0) {
1368c2c66affSColin Finck int ret = REBAR_ShrinkBandsRTL(infoPtr, iBeginBand, iEndBand, -extra, FALSE);
1369c2c66affSColin Finck if (ret > 0 && next_visible(infoPtr, iBeginBand) != iEndBand) /* one band may be longer than expected... */
1370c2c66affSColin Finck ERR("Error layouting row %d - couldn't shrink for %d pixels (%d total shrink)\n", *piRow, ret, -extra);
1371c2c66affSColin Finck } else
1372c2c66affSColin Finck if (extra > 0) {
1373c2c66affSColin Finck lpBand = REBAR_FindBandToGrow(infoPtr, iBeginBand, iEndBand);
1374c2c66affSColin Finck lpBand->cxEffective += extra;
1375c2c66affSColin Finck }
1376c2c66affSColin Finck
1377c2c66affSColin Finck REBAR_SetRowRectsX(infoPtr, iBeginBand, iEndBand);
1378c2c66affSColin Finck if (infoPtr->dwStyle & RBS_VARHEIGHT)
1379c2c66affSColin Finck {
1380c2c66affSColin Finck if (*piRow > 0)
1381c2c66affSColin Finck *pyPos += SEP_WIDTH;
1382c2c66affSColin Finck *pyPos = REBAR_SetBandsHeight(infoPtr, iBeginBand, iEndBand, *pyPos);
1383c2c66affSColin Finck }
1384c2c66affSColin Finck (*piRow)++;
1385c2c66affSColin Finck }
1386c2c66affSColin Finck
1387c2c66affSColin Finck static VOID
REBAR_Layout(REBAR_INFO * infoPtr)1388c2c66affSColin Finck REBAR_Layout(REBAR_INFO *infoPtr)
1389c2c66affSColin Finck {
1390c2c66affSColin Finck REBAR_BAND *lpBand;
1391c2c66affSColin Finck RECT rcAdj;
1392c2c66affSColin Finck SIZE oldSize;
1393c2c66affSColin Finck INT adjcx, i;
1394c2c66affSColin Finck INT rowstart;
1395c2c66affSColin Finck INT row = 0;
1396c2c66affSColin Finck INT xMin, yPos;
1397c2c66affSColin Finck
1398c2c66affSColin Finck if (infoPtr->dwStyle & (CCS_NORESIZE | CCS_NOPARENTALIGN) || GetParent(infoPtr->hwndSelf) == NULL)
1399c2c66affSColin Finck GetClientRect(infoPtr->hwndSelf, &rcAdj);
1400c2c66affSColin Finck else
1401c2c66affSColin Finck GetClientRect(GetParent(infoPtr->hwndSelf), &rcAdj);
1402c2c66affSColin Finck TRACE("adjustment rect is (%s)\n", wine_dbgstr_rect(&rcAdj));
1403c2c66affSColin Finck
1404c2c66affSColin Finck adjcx = get_rect_cx(infoPtr, &rcAdj);
1405c2c66affSColin Finck
1406c2c66affSColin Finck if (infoPtr->uNumBands == 0) {
1407c2c66affSColin Finck TRACE("No bands - setting size to (0,%d), style: %x\n", adjcx, infoPtr->dwStyle);
1408c2c66affSColin Finck infoPtr->calcSize.cx = adjcx;
1409c2c66affSColin Finck /* the calcSize.cy won't change for a 0 band rebar */
1410c2c66affSColin Finck infoPtr->uNumRows = 0;
1411c2c66affSColin Finck REBAR_ForceResize(infoPtr);
1412c2c66affSColin Finck return;
1413c2c66affSColin Finck }
1414c2c66affSColin Finck
1415c2c66affSColin Finck yPos = 0;
1416c2c66affSColin Finck xMin = 0;
1417c2c66affSColin Finck rowstart = first_visible(infoPtr);
1418c2c66affSColin Finck /* divide rows */
1419c2c66affSColin Finck for (i = rowstart; i < infoPtr->uNumBands; i = next_visible(infoPtr, i))
1420c2c66affSColin Finck {
1421c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
1422c2c66affSColin Finck
1423c2c66affSColin Finck if (i > rowstart && (lpBand->fStyle & RBBS_BREAK || xMin + lpBand->cxMinBand > adjcx)) {
1424c2c66affSColin Finck TRACE("%s break on band %d\n", (lpBand->fStyle & RBBS_BREAK ? "Hard" : "Soft"), i - 1);
1425c2c66affSColin Finck REBAR_LayoutRow(infoPtr, rowstart, i, adjcx, &row, &yPos);
1426c2c66affSColin Finck rowstart = i;
1427c2c66affSColin Finck xMin = 0;
1428c2c66affSColin Finck }
1429c2c66affSColin Finck else
1430c2c66affSColin Finck xMin += SEP_WIDTH;
1431c2c66affSColin Finck
1432c2c66affSColin Finck xMin += lpBand->cxMinBand;
1433c2c66affSColin Finck }
1434c2c66affSColin Finck if (rowstart < infoPtr->uNumBands)
1435c2c66affSColin Finck REBAR_LayoutRow(infoPtr, rowstart, infoPtr->uNumBands, adjcx, &row, &yPos);
1436c2c66affSColin Finck
1437c2c66affSColin Finck if (!(infoPtr->dwStyle & RBS_VARHEIGHT))
1438c2c66affSColin Finck yPos = REBAR_SetBandsHeight(infoPtr, first_visible(infoPtr), infoPtr->uNumBands, 0);
1439c2c66affSColin Finck
1440c2c66affSColin Finck infoPtr->uNumRows = row;
1441c2c66affSColin Finck
1442c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT)
1443c2c66affSColin Finck REBAR_CalcVertBand(infoPtr, 0, infoPtr->uNumBands);
1444c2c66affSColin Finck else
1445c2c66affSColin Finck REBAR_CalcHorzBand(infoPtr, 0, infoPtr->uNumBands);
1446c2c66affSColin Finck /* now compute size of Rebar itself */
1447c2c66affSColin Finck oldSize = infoPtr->calcSize;
1448c2c66affSColin Finck
1449c2c66affSColin Finck infoPtr->calcSize.cx = adjcx;
1450c2c66affSColin Finck infoPtr->calcSize.cy = yPos;
1451c2c66affSColin Finck TRACE("calcsize size=(%d, %d), origheight=(%d,%d)\n",
1452c2c66affSColin Finck infoPtr->calcSize.cx, infoPtr->calcSize.cy,
1453c2c66affSColin Finck oldSize.cx, oldSize.cy);
1454c2c66affSColin Finck
1455c2c66affSColin Finck REBAR_DumpBand (infoPtr);
1456c2c66affSColin Finck REBAR_MoveChildWindows (infoPtr, 0, infoPtr->uNumBands);
1457c2c66affSColin Finck REBAR_ForceResize (infoPtr);
1458c2c66affSColin Finck
1459c2c66affSColin Finck /* note: after a RBN_HEIGHTCHANGE native sends once again all the RBN_CHILDSIZE
1460c2c66affSColin Finck * and does another ForceResize */
1461c2c66affSColin Finck if (oldSize.cy != infoPtr->calcSize.cy)
1462c2c66affSColin Finck {
1463c2c66affSColin Finck NMHDR heightchange;
1464c2c66affSColin Finck REBAR_Notify(&heightchange, infoPtr, RBN_HEIGHTCHANGE);
1465c2c66affSColin Finck REBAR_AutoSize(infoPtr, FALSE);
1466c2c66affSColin Finck }
1467c2c66affSColin Finck }
1468c2c66affSColin Finck
1469c2c66affSColin Finck /* iBeginBand must be visible */
1470c2c66affSColin Finck static int
REBAR_SizeChildrenToHeight(const REBAR_INFO * infoPtr,int iBeginBand,int iEndBand,int extra,BOOL * fChanged)1471c2c66affSColin Finck REBAR_SizeChildrenToHeight(const REBAR_INFO *infoPtr, int iBeginBand, int iEndBand, int extra, BOOL *fChanged)
1472c2c66affSColin Finck {
1473c2c66affSColin Finck int cyBandsOld;
1474c2c66affSColin Finck int cyBandsNew = 0;
1475c2c66affSColin Finck int i;
1476c2c66affSColin Finck
1477c2c66affSColin Finck TRACE("[%d;%d) by %d\n", iBeginBand, iEndBand, extra);
1478c2c66affSColin Finck
1479c2c66affSColin Finck cyBandsOld = REBAR_GetBand(infoPtr, iBeginBand)->rcBand.bottom -
1480c2c66affSColin Finck REBAR_GetBand(infoPtr, iBeginBand)->rcBand.top;
1481c2c66affSColin Finck for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
1482c2c66affSColin Finck {
1483c2c66affSColin Finck REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, i);
1484c2c66affSColin Finck int cyMaxChild = cyBandsOld - REBARSPACE(lpBand) + extra;
1485c2c66affSColin Finck int cyChild = round_child_height(lpBand, cyMaxChild);
1486c2c66affSColin Finck
1487c2c66affSColin Finck if (lpBand->hwndChild && cyChild != lpBand->cyChild && (lpBand->fStyle & RBBS_VARIABLEHEIGHT))
1488c2c66affSColin Finck {
1489c2c66affSColin Finck TRACE("Resizing %d: %d -> %d [%d]\n", i, lpBand->cyChild, cyChild, lpBand->cyMaxChild);
1490c2c66affSColin Finck *fChanged = TRUE;
1491c2c66affSColin Finck lpBand->cyChild = cyChild;
1492c2c66affSColin Finck lpBand->fDraw |= NTF_INVALIDATE;
1493c2c66affSColin Finck update_min_band_height(infoPtr, lpBand);
1494c2c66affSColin Finck }
1495c2c66affSColin Finck cyBandsNew = max(cyBandsNew, lpBand->cyMinBand);
1496c2c66affSColin Finck }
1497c2c66affSColin Finck return cyBandsNew - cyBandsOld;
1498c2c66affSColin Finck }
1499c2c66affSColin Finck
1500c2c66affSColin Finck /* worker function for RB_SIZETORECT and RBS_AUTOSIZE */
1501c2c66affSColin Finck static VOID
REBAR_SizeToHeight(REBAR_INFO * infoPtr,int height)1502c2c66affSColin Finck REBAR_SizeToHeight(REBAR_INFO *infoPtr, int height)
1503c2c66affSColin Finck {
1504c2c66affSColin Finck int extra = height - infoPtr->calcSize.cy; /* may be negative */
1505c2c66affSColin Finck BOOL fChanged = FALSE;
1506c2c66affSColin Finck UINT uNumRows = infoPtr->uNumRows;
1507c2c66affSColin Finck int i;
1508c2c66affSColin Finck
1509c2c66affSColin Finck if (uNumRows == 0) /* avoid division by 0 */
1510c2c66affSColin Finck return;
1511c2c66affSColin Finck
1512c2c66affSColin Finck /* That's not exactly what Windows does but should be similar */
1513c2c66affSColin Finck
1514c2c66affSColin Finck /* Pass one: break-up/glue rows */
1515c2c66affSColin Finck if (extra > 0)
1516c2c66affSColin Finck {
1517c2c66affSColin Finck for (i = prev_visible(infoPtr, infoPtr->uNumBands); i > 0; i = prev_visible(infoPtr, i))
1518c2c66affSColin Finck {
1519c2c66affSColin Finck REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, i);
1520c2c66affSColin Finck int cyBreakExtra; /* additional cy for the rebar after a RBBS_BREAK on this band */
1521c2c66affSColin Finck
1522c2c66affSColin Finck height = lpBand->rcBand.bottom - lpBand->rcBand.top;
1523c2c66affSColin Finck
1524c2c66affSColin Finck if (infoPtr->dwStyle & RBS_VARHEIGHT)
1525c2c66affSColin Finck cyBreakExtra = lpBand->cyRowSoFar; /* 'height' => 'lpBand->cyRowSoFar' + 'height'*/
1526c2c66affSColin Finck else
1527c2c66affSColin Finck cyBreakExtra = height; /* 'height' => 'height' + 'height'*/
1528c2c66affSColin Finck cyBreakExtra += SEP_WIDTH;
1529c2c66affSColin Finck
1530c2c66affSColin Finck if (extra <= cyBreakExtra / 2)
1531c2c66affSColin Finck break;
1532c2c66affSColin Finck
1533c2c66affSColin Finck if (!(lpBand->fStyle & RBBS_BREAK))
1534c2c66affSColin Finck {
1535c2c66affSColin Finck TRACE("Adding break on band %d - extra %d -> %d\n", i, extra, extra - cyBreakExtra);
1536c2c66affSColin Finck lpBand->fStyle |= RBBS_BREAK;
1537c2c66affSColin Finck lpBand->fDraw |= NTF_INVALIDATE;
1538c2c66affSColin Finck fChanged = TRUE;
1539c2c66affSColin Finck extra -= cyBreakExtra;
1540c2c66affSColin Finck uNumRows++;
1541c2c66affSColin Finck /* temporary change for _SizeControlsToHeight. The true values will be computed in _Layout */
1542c2c66affSColin Finck if (infoPtr->dwStyle & RBS_VARHEIGHT)
1543c2c66affSColin Finck lpBand->rcBand.bottom = lpBand->rcBand.top + lpBand->cyMinBand;
1544c2c66affSColin Finck }
1545c2c66affSColin Finck }
1546c2c66affSColin Finck }
1547c2c66affSColin Finck /* TODO: else if (extra < 0) { try to remove some RBBS_BREAKs } */
1548c2c66affSColin Finck
1549c2c66affSColin Finck /* Pass two: increase/decrease control height */
1550c2c66affSColin Finck if (infoPtr->dwStyle & RBS_VARHEIGHT)
1551c2c66affSColin Finck {
1552c2c66affSColin Finck int i = first_visible(infoPtr);
1553c2c66affSColin Finck int iRow = 0;
1554c2c66affSColin Finck while (i < infoPtr->uNumBands)
1555c2c66affSColin Finck {
1556c2c66affSColin Finck REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, i);
1557c2c66affSColin Finck int extraForRow = extra / (int)(uNumRows - iRow);
1558c2c66affSColin Finck int rowEnd;
1559c2c66affSColin Finck
1560c2c66affSColin Finck /* we can't use get_row_end_for_band as we might have added RBBS_BREAK in the first phase */
1561c2c66affSColin Finck for (rowEnd = next_visible(infoPtr, i); rowEnd < infoPtr->uNumBands; rowEnd = next_visible(infoPtr, rowEnd))
1562c2c66affSColin Finck if (REBAR_GetBand(infoPtr, rowEnd)->iRow != lpBand->iRow ||
1563c2c66affSColin Finck REBAR_GetBand(infoPtr, rowEnd)->fStyle & RBBS_BREAK)
1564c2c66affSColin Finck break;
1565c2c66affSColin Finck
1566c2c66affSColin Finck extra -= REBAR_SizeChildrenToHeight(infoPtr, i, rowEnd, extraForRow, &fChanged);
1567c2c66affSColin Finck TRACE("extra = %d\n", extra);
1568c2c66affSColin Finck i = rowEnd;
1569c2c66affSColin Finck iRow++;
1570c2c66affSColin Finck }
1571c2c66affSColin Finck }
1572c2c66affSColin Finck else
1573c2c66affSColin Finck REBAR_SizeChildrenToHeight(infoPtr, first_visible(infoPtr), infoPtr->uNumBands, extra / infoPtr->uNumRows, &fChanged);
1574c2c66affSColin Finck
1575c2c66affSColin Finck if (fChanged)
1576c2c66affSColin Finck REBAR_Layout(infoPtr);
1577c2c66affSColin Finck }
1578c2c66affSColin Finck
1579c2c66affSColin Finck static VOID
REBAR_AutoSize(REBAR_INFO * infoPtr,BOOL needsLayout)1580c2c66affSColin Finck REBAR_AutoSize(REBAR_INFO *infoPtr, BOOL needsLayout)
1581c2c66affSColin Finck {
1582c2c66affSColin Finck RECT rc, rcNew;
1583c2c66affSColin Finck NMRBAUTOSIZE autosize;
1584c2c66affSColin Finck
1585c2c66affSColin Finck if (needsLayout)
1586c2c66affSColin Finck REBAR_Layout(infoPtr);
1587c2c66affSColin Finck GetClientRect(infoPtr->hwndSelf, &rc);
1588c2c66affSColin Finck REBAR_SizeToHeight(infoPtr, get_rect_cy(infoPtr, &rc));
1589c2c66affSColin Finck GetClientRect(infoPtr->hwndSelf, &rcNew);
1590c2c66affSColin Finck
1591c2c66affSColin Finck GetClientRect(infoPtr->hwndSelf, &autosize.rcTarget);
1592c2c66affSColin Finck autosize.fChanged = EqualRect(&rc, &rcNew);
1593c2c66affSColin Finck autosize.rcTarget = rc;
1594c2c66affSColin Finck autosize.rcActual = rcNew;
1595c2c66affSColin Finck REBAR_Notify((NMHDR *)&autosize, infoPtr, RBN_AUTOSIZE);
1596c2c66affSColin Finck }
1597c2c66affSColin Finck
1598c2c66affSColin Finck static VOID
REBAR_ValidateBand(const REBAR_INFO * infoPtr,REBAR_BAND * lpBand)1599c2c66affSColin Finck REBAR_ValidateBand (const REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
1600c2c66affSColin Finck /* Function: This routine evaluates the band specs supplied */
1601c2c66affSColin Finck /* by the user and updates the following 5 fields in */
1602c2c66affSColin Finck /* the internal band structure: cxHeader, cyHeader, cxMinBand, cyMinBand, fStatus */
1603c2c66affSColin Finck {
1604c2c66affSColin Finck UINT header=0;
1605c2c66affSColin Finck UINT textheight=0, imageheight = 0;
1606c2c66affSColin Finck UINT i, nonfixed;
1607c2c66affSColin Finck REBAR_BAND *tBand;
1608c2c66affSColin Finck
1609c2c66affSColin Finck lpBand->fStatus = 0;
1610c2c66affSColin Finck lpBand->cxMinBand = 0;
1611c2c66affSColin Finck lpBand->cyMinBand = 0;
1612c2c66affSColin Finck
1613c2c66affSColin Finck /* Data coming in from users into the cx... and cy... fields */
1614c2c66affSColin Finck /* may be bad, just garbage, because the user never clears */
1615c2c66affSColin Finck /* the fields. RB_{SET|INSERT}BAND{A|W} just passes the data */
1616c2c66affSColin Finck /* along if the fields exist in the input area. Here we must */
1617c2c66affSColin Finck /* determine if the data is valid. I have no idea how MS does */
1618c2c66affSColin Finck /* the validation, but it does because the RB_GETBANDINFO */
1619c2c66affSColin Finck /* returns a 0 when I know the sample program passed in an */
1620c2c66affSColin Finck /* address. Here I will use the algorithm that if the value */
1621c2c66affSColin Finck /* is greater than 65535 then it is bad and replace it with */
1622c2c66affSColin Finck /* a zero. Feel free to improve the algorithm. - GA 12/2000 */
1623c2c66affSColin Finck if (lpBand->cxMinChild > 65535) lpBand->cxMinChild = 0;
1624c2c66affSColin Finck if (lpBand->cyMinChild > 65535) lpBand->cyMinChild = 0;
1625c2c66affSColin Finck if (lpBand->cx > 65535) lpBand->cx = 0;
1626c2c66affSColin Finck if (lpBand->cyChild > 65535) lpBand->cyChild = 0;
1627c2c66affSColin Finck if (lpBand->cyIntegral > 65535) lpBand->cyIntegral = 0;
1628c2c66affSColin Finck if (lpBand->cxIdeal > 65535) lpBand->cxIdeal = 0;
1629c2c66affSColin Finck if (lpBand->cxHeader > 65535) lpBand->cxHeader = 0;
1630c2c66affSColin Finck
1631c2c66affSColin Finck /* TODO : we could try return to the caller if a value changed so that */
1632c2c66affSColin Finck /* a REBAR_Layout is needed. Till now the caller should call it */
1633c2c66affSColin Finck /* it always (we should also check what native does) */
1634c2c66affSColin Finck
1635c2c66affSColin Finck /* Header is where the image, text and gripper exist */
1636c2c66affSColin Finck /* in the band and precede the child window. */
1637c2c66affSColin Finck
1638c2c66affSColin Finck /* count number of non-FIXEDSIZE and non-Hidden bands */
1639c2c66affSColin Finck nonfixed = 0;
1640c2c66affSColin Finck for (i=0; i<infoPtr->uNumBands; i++){
1641c2c66affSColin Finck tBand = REBAR_GetBand(infoPtr, i);
1642c2c66affSColin Finck if (!HIDDENBAND(tBand) && !(tBand->fStyle & RBBS_FIXEDSIZE))
1643c2c66affSColin Finck nonfixed++;
1644c2c66affSColin Finck }
1645c2c66affSColin Finck
1646c2c66affSColin Finck /* calculate gripper rectangle */
1647c2c66affSColin Finck if ( (!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
1648c2c66affSColin Finck ( (lpBand->fStyle & RBBS_GRIPPERALWAYS) ||
1649c2c66affSColin Finck ( !(lpBand->fStyle & RBBS_FIXEDSIZE) && (nonfixed > 1)))
1650c2c66affSColin Finck ) {
1651c2c66affSColin Finck lpBand->fStatus |= HAS_GRIPPER;
1652c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT)
1653c2c66affSColin Finck if (infoPtr->dwStyle & RBS_VERTICALGRIPPER)
1654c2c66affSColin Finck header += (GRIPPER_HEIGHT + REBAR_PRE_GRIPPER);
1655c2c66affSColin Finck else
1656c2c66affSColin Finck header += (GRIPPER_WIDTH + REBAR_PRE_GRIPPER);
1657c2c66affSColin Finck else
1658c2c66affSColin Finck header += (REBAR_PRE_GRIPPER + GRIPPER_WIDTH);
1659c2c66affSColin Finck /* Always have 4 pixels before anything else */
1660c2c66affSColin Finck header += REBAR_ALWAYS_SPACE;
1661c2c66affSColin Finck }
1662c2c66affSColin Finck
1663c2c66affSColin Finck /* image is visible */
1664c2c66affSColin Finck if (lpBand->iImage != -1 && (infoPtr->himl)) {
1665c2c66affSColin Finck lpBand->fStatus |= HAS_IMAGE;
1666c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT) {
1667c2c66affSColin Finck header += (infoPtr->imageSize.cy + REBAR_POST_IMAGE);
1668c2c66affSColin Finck imageheight = infoPtr->imageSize.cx + 4;
1669c2c66affSColin Finck }
1670c2c66affSColin Finck else {
1671c2c66affSColin Finck header += (infoPtr->imageSize.cx + REBAR_POST_IMAGE);
1672c2c66affSColin Finck imageheight = infoPtr->imageSize.cy + 4;
1673c2c66affSColin Finck }
1674c2c66affSColin Finck }
1675c2c66affSColin Finck
1676c2c66affSColin Finck /* text is visible */
1677c2c66affSColin Finck if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText) &&
1678c2c66affSColin Finck !(lpBand->fStyle & RBBS_HIDETITLE)) {
1679c2c66affSColin Finck HDC hdc = GetDC (0);
1680c2c66affSColin Finck HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
1681c2c66affSColin Finck SIZE size;
1682c2c66affSColin Finck
1683c2c66affSColin Finck lpBand->fStatus |= HAS_TEXT;
1684c2c66affSColin Finck GetTextExtentPoint32W (hdc, lpBand->lpText,
1685c2c66affSColin Finck lstrlenW (lpBand->lpText), &size);
1686c2c66affSColin Finck header += ((infoPtr->dwStyle & CCS_VERT) ? (size.cy + REBAR_POST_TEXT) : (size.cx + REBAR_POST_TEXT));
1687c2c66affSColin Finck textheight = (infoPtr->dwStyle & CCS_VERT) ? 0 : size.cy;
1688c2c66affSColin Finck
1689c2c66affSColin Finck SelectObject (hdc, hOldFont);
1690c2c66affSColin Finck ReleaseDC (0, hdc);
1691c2c66affSColin Finck }
1692c2c66affSColin Finck
1693c2c66affSColin Finck /* if no gripper but either image or text, then leave space */
1694c2c66affSColin Finck if ((lpBand->fStatus & (HAS_IMAGE | HAS_TEXT)) &&
1695c2c66affSColin Finck !(lpBand->fStatus & HAS_GRIPPER)) {
1696c2c66affSColin Finck header += REBAR_ALWAYS_SPACE;
1697c2c66affSColin Finck }
1698c2c66affSColin Finck
1699c2c66affSColin Finck /* check if user overrode the header value */
1700c2c66affSColin Finck if (!(lpBand->fStyle & RBBS_UNDOC_FIXEDHEADER))
1701c2c66affSColin Finck lpBand->cxHeader = header;
1702c2c66affSColin Finck lpBand->cyHeader = max(textheight, imageheight);
1703c2c66affSColin Finck
1704c2c66affSColin Finck /* Now compute minimum size of child window */
1705c2c66affSColin Finck update_min_band_height(infoPtr, lpBand); /* update lpBand->cyMinBand from cyHeader and cyChild*/
1706c2c66affSColin Finck
1707c2c66affSColin Finck lpBand->cxMinBand = lpBand->cxMinChild + lpBand->cxHeader + REBAR_POST_CHILD;
1708c2c66affSColin Finck if (lpBand->fStyle & RBBS_USECHEVRON && lpBand->cxMinChild < lpBand->cxIdeal)
1709c2c66affSColin Finck lpBand->cxMinBand += CHEVRON_WIDTH;
1710c2c66affSColin Finck }
1711c2c66affSColin Finck
1712c2c66affSColin Finck static UINT
REBAR_CommonSetupBand(HWND hwnd,const REBARBANDINFOW * lprbbi,REBAR_BAND * lpBand)1713c2c66affSColin Finck REBAR_CommonSetupBand(HWND hwnd, const REBARBANDINFOW *lprbbi, REBAR_BAND *lpBand)
1714c2c66affSColin Finck /* Function: This routine copies the supplied values from */
1715c2c66affSColin Finck /* user input (lprbbi) to the internal band structure. */
1716c2c66affSColin Finck /* It returns the mask of what changed. */
1717c2c66affSColin Finck {
1718c2c66affSColin Finck UINT uChanged = 0x0;
1719c2c66affSColin Finck
1720c2c66affSColin Finck lpBand->fMask |= lprbbi->fMask;
1721c2c66affSColin Finck
1722c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_STYLE) &&
1723c2c66affSColin Finck (lpBand->fStyle != lprbbi->fStyle ) )
1724c2c66affSColin Finck {
1725c2c66affSColin Finck lpBand->fStyle = lprbbi->fStyle;
1726c2c66affSColin Finck uChanged |= RBBIM_STYLE;
1727c2c66affSColin Finck }
1728c2c66affSColin Finck
1729c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_COLORS) &&
1730c2c66affSColin Finck ( ( lpBand->clrFore != lprbbi->clrFore ) ||
1731c2c66affSColin Finck ( lpBand->clrBack != lprbbi->clrBack ) ) )
1732c2c66affSColin Finck {
1733c2c66affSColin Finck lpBand->clrFore = lprbbi->clrFore;
1734c2c66affSColin Finck lpBand->clrBack = lprbbi->clrBack;
1735c2c66affSColin Finck uChanged |= RBBIM_COLORS;
1736c2c66affSColin Finck }
1737c2c66affSColin Finck
1738c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_IMAGE) &&
1739c2c66affSColin Finck ( lpBand->iImage != lprbbi->iImage ) )
1740c2c66affSColin Finck {
1741c2c66affSColin Finck lpBand->iImage = lprbbi->iImage;
1742c2c66affSColin Finck uChanged |= RBBIM_IMAGE;
1743c2c66affSColin Finck }
1744c2c66affSColin Finck
1745c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_CHILD) &&
1746c2c66affSColin Finck (lprbbi->hwndChild != lpBand->hwndChild ) )
1747c2c66affSColin Finck {
1748c2c66affSColin Finck if (lprbbi->hwndChild) {
1749c2c66affSColin Finck lpBand->hwndChild = lprbbi->hwndChild;
1750c2c66affSColin Finck lpBand->hwndPrevParent =
1751c2c66affSColin Finck SetParent (lpBand->hwndChild, hwnd);
1752c2c66affSColin Finck /* below in trace from WinRAR */
1753c2c66affSColin Finck ShowWindow(lpBand->hwndChild, SW_SHOWNOACTIVATE | SW_SHOWNORMAL);
1754c2c66affSColin Finck /* above in trace from WinRAR */
1755c2c66affSColin Finck }
1756c2c66affSColin Finck else {
1757c2c66affSColin Finck TRACE("child: %p prev parent: %p\n",
1758c2c66affSColin Finck lpBand->hwndChild, lpBand->hwndPrevParent);
1759c2c66affSColin Finck lpBand->hwndChild = 0;
1760c2c66affSColin Finck lpBand->hwndPrevParent = 0;
1761c2c66affSColin Finck }
1762c2c66affSColin Finck uChanged |= RBBIM_CHILD;
1763c2c66affSColin Finck }
1764c2c66affSColin Finck
1765c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_CHILDSIZE) &&
1766c2c66affSColin Finck ( (lpBand->cxMinChild != lprbbi->cxMinChild) ||
1767c2c66affSColin Finck (lpBand->cyMinChild != lprbbi->cyMinChild ) ||
1768c2c66affSColin Finck ( (lprbbi->cbSize >= REBARBANDINFOA_V6_SIZE && (lpBand->fStyle & RBBS_VARIABLEHEIGHT)) &&
1769c2c66affSColin Finck ( (lpBand->cyChild != lprbbi->cyChild ) ||
1770c2c66affSColin Finck (lpBand->cyMaxChild != lprbbi->cyMaxChild ) ||
1771c2c66affSColin Finck (lpBand->cyIntegral != lprbbi->cyIntegral ) ) ) ||
1772c2c66affSColin Finck ( (lprbbi->cbSize < REBARBANDINFOA_V6_SIZE) &&
1773c2c66affSColin Finck ( (lpBand->cyChild ||
1774c2c66affSColin Finck lpBand->cyMaxChild ||
1775c2c66affSColin Finck lpBand->cyIntegral ) ) ) ) )
1776c2c66affSColin Finck {
1777c2c66affSColin Finck lpBand->cxMinChild = lprbbi->cxMinChild;
1778c2c66affSColin Finck lpBand->cyMinChild = lprbbi->cyMinChild;
1779c2c66affSColin Finck /* These fields where added in WIN32_IE == 0x400 and are set only for RBBS_VARIABLEHEIGHT bands */
1780c2c66affSColin Finck if (lprbbi->cbSize >= REBARBANDINFOA_V6_SIZE && (lpBand->fStyle & RBBS_VARIABLEHEIGHT)) {
1781c2c66affSColin Finck lpBand->cyMaxChild = lprbbi->cyMaxChild;
1782c2c66affSColin Finck lpBand->cyIntegral = lprbbi->cyIntegral;
1783c2c66affSColin Finck
1784c2c66affSColin Finck lpBand->cyChild = round_child_height(lpBand, lprbbi->cyChild); /* make (cyChild - cyMinChild) a multiple of cyIntergral */
1785c2c66affSColin Finck }
1786c2c66affSColin Finck else {
1787c2c66affSColin Finck lpBand->cyChild = lpBand->cyMinChild;
1788c2c66affSColin Finck lpBand->cyMaxChild = 0x7fffffff;
1789c2c66affSColin Finck lpBand->cyIntegral = 0;
1790c2c66affSColin Finck }
1791c2c66affSColin Finck uChanged |= RBBIM_CHILDSIZE;
1792c2c66affSColin Finck }
1793c2c66affSColin Finck
1794c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_SIZE) &&
1795c2c66affSColin Finck (lpBand->cx != lprbbi->cx ) )
1796c2c66affSColin Finck {
1797c2c66affSColin Finck lpBand->cx = lprbbi->cx;
1798c2c66affSColin Finck uChanged |= RBBIM_SIZE;
1799c2c66affSColin Finck }
1800c2c66affSColin Finck
1801c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_BACKGROUND) &&
1802c2c66affSColin Finck ( lpBand->hbmBack != lprbbi->hbmBack ) )
1803c2c66affSColin Finck {
1804c2c66affSColin Finck lpBand->hbmBack = lprbbi->hbmBack;
1805c2c66affSColin Finck uChanged |= RBBIM_BACKGROUND;
1806c2c66affSColin Finck }
1807c2c66affSColin Finck
1808c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_ID) &&
1809c2c66affSColin Finck (lpBand->wID != lprbbi->wID ) )
1810c2c66affSColin Finck {
1811c2c66affSColin Finck lpBand->wID = lprbbi->wID;
1812c2c66affSColin Finck uChanged |= RBBIM_ID;
1813c2c66affSColin Finck }
1814c2c66affSColin Finck
1815c2c66affSColin Finck /* check for additional data */
1816c2c66affSColin Finck if (lprbbi->cbSize >= REBARBANDINFOA_V6_SIZE) {
1817c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_IDEALSIZE) &&
1818c2c66affSColin Finck ( lpBand->cxIdeal != lprbbi->cxIdeal ) )
1819c2c66affSColin Finck {
1820c2c66affSColin Finck lpBand->cxIdeal = lprbbi->cxIdeal;
1821c2c66affSColin Finck uChanged |= RBBIM_IDEALSIZE;
1822c2c66affSColin Finck }
1823c2c66affSColin Finck
1824c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_LPARAM) &&
1825c2c66affSColin Finck (lpBand->lParam != lprbbi->lParam ) )
1826c2c66affSColin Finck {
1827c2c66affSColin Finck lpBand->lParam = lprbbi->lParam;
1828c2c66affSColin Finck uChanged |= RBBIM_LPARAM;
1829c2c66affSColin Finck }
1830c2c66affSColin Finck
1831c2c66affSColin Finck if( (lprbbi->fMask & RBBIM_HEADERSIZE) &&
1832c2c66affSColin Finck (lpBand->cxHeader != lprbbi->cxHeader ) )
1833c2c66affSColin Finck {
1834c2c66affSColin Finck lpBand->cxHeader = lprbbi->cxHeader;
1835c2c66affSColin Finck lpBand->fStyle |= RBBS_UNDOC_FIXEDHEADER;
1836c2c66affSColin Finck uChanged |= RBBIM_HEADERSIZE;
1837c2c66affSColin Finck }
1838c2c66affSColin Finck }
1839c2c66affSColin Finck
1840c2c66affSColin Finck return uChanged;
1841c2c66affSColin Finck }
1842c2c66affSColin Finck
REBAR_EraseBkGnd(const REBAR_INFO * infoPtr,HDC hdc)1843c2c66affSColin Finck static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
1844c2c66affSColin Finck /* Function: This erases the background rectangle by drawing */
1845c2c66affSColin Finck /* each band with its background color (or the default) and */
1846c2c66affSColin Finck /* draws each bands right separator if necessary. The row */
1847c2c66affSColin Finck /* separators are drawn on the first band of the next row. */
1848c2c66affSColin Finck {
1849c2c66affSColin Finck REBAR_BAND *lpBand;
1850c2c66affSColin Finck UINT i;
1851c2c66affSColin Finck INT oldrow;
1852c2c66affSColin Finck RECT cr;
1853c2c66affSColin Finck COLORREF old = CLR_NONE, new;
1854c2c66affSColin Finck HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
1855c2c66affSColin Finck
1856c2c66affSColin Finck GetClientRect (infoPtr->hwndSelf, &cr);
1857c2c66affSColin Finck
1858c2c66affSColin Finck #ifdef __REACTOS__
1859c2c66affSColin Finck if (theme)
1860c2c66affSColin Finck {
1861b8062bdeSGiannis Adamopoulos if (IsThemeBackgroundPartiallyTransparent(theme, 0, 0))
1862c2c66affSColin Finck {
1863c2c66affSColin Finck DrawThemeParentBackground (infoPtr->hwndSelf, hdc, &cr);
1864c2c66affSColin Finck }
1865c2c66affSColin Finck DrawThemeBackground (theme, hdc, 0, 0, &cr, NULL);
1866c2c66affSColin Finck }
1867c2c66affSColin Finck #endif
1868c2c66affSColin Finck
1869c2c66affSColin Finck oldrow = -1;
1870c2c66affSColin Finck for(i=0; i<infoPtr->uNumBands; i++) {
1871c2c66affSColin Finck RECT rcBand;
1872c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
1873c2c66affSColin Finck if (HIDDENBAND(lpBand)) continue;
1874c2c66affSColin Finck translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
1875c2c66affSColin Finck
1876c2c66affSColin Finck /* draw band separator between rows */
1877c2c66affSColin Finck if (lpBand->iRow != oldrow) {
1878c2c66affSColin Finck oldrow = lpBand->iRow;
1879c2c66affSColin Finck if (infoPtr->dwStyle & RBS_BANDBORDERS) {
1880c2c66affSColin Finck RECT rcRowSep;
1881c2c66affSColin Finck rcRowSep = rcBand;
1882c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT) {
1883c2c66affSColin Finck rcRowSep.right += SEP_WIDTH_SIZE;
1884c2c66affSColin Finck rcRowSep.bottom = infoPtr->calcSize.cx;
1885c2c66affSColin Finck if (theme)
1886c2c66affSColin Finck DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcRowSep, EDGE_ETCHED, BF_RIGHT, NULL);
1887c2c66affSColin Finck else
1888c2c66affSColin Finck DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_RIGHT);
1889c2c66affSColin Finck }
1890c2c66affSColin Finck else {
1891c2c66affSColin Finck rcRowSep.bottom += SEP_WIDTH_SIZE;
1892c2c66affSColin Finck rcRowSep.right = infoPtr->calcSize.cx;
1893c2c66affSColin Finck if (theme)
1894c2c66affSColin Finck DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcRowSep, EDGE_ETCHED, BF_BOTTOM, NULL);
1895c2c66affSColin Finck else
1896c2c66affSColin Finck DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_BOTTOM);
1897c2c66affSColin Finck }
1898c2c66affSColin Finck TRACE ("drawing band separator bottom (%s)\n",
1899c2c66affSColin Finck wine_dbgstr_rect(&rcRowSep));
1900c2c66affSColin Finck }
1901c2c66affSColin Finck }
1902c2c66affSColin Finck
1903c2c66affSColin Finck /* draw band separator between bands in a row */
1904c2c66affSColin Finck if (infoPtr->dwStyle & RBS_BANDBORDERS && lpBand->rcBand.left > 0) {
1905c2c66affSColin Finck RECT rcSep;
1906c2c66affSColin Finck rcSep = rcBand;
1907c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT) {
1908c2c66affSColin Finck rcSep.bottom = rcSep.top;
1909c2c66affSColin Finck rcSep.top -= SEP_WIDTH_SIZE;
1910c2c66affSColin Finck if (theme)
1911c2c66affSColin Finck DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_BOTTOM, NULL);
1912c2c66affSColin Finck else
1913c2c66affSColin Finck DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_BOTTOM);
1914c2c66affSColin Finck }
1915c2c66affSColin Finck else {
1916c2c66affSColin Finck rcSep.right = rcSep.left;
1917c2c66affSColin Finck rcSep.left -= SEP_WIDTH_SIZE;
1918c2c66affSColin Finck if (theme)
1919c2c66affSColin Finck DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_RIGHT, NULL);
1920c2c66affSColin Finck else
1921c2c66affSColin Finck DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_RIGHT);
1922c2c66affSColin Finck }
1923c2c66affSColin Finck TRACE("drawing band separator right (%s)\n",
1924c2c66affSColin Finck wine_dbgstr_rect(&rcSep));
1925c2c66affSColin Finck }
1926c2c66affSColin Finck
1927c2c66affSColin Finck /* draw the actual background */
1928c2c66affSColin Finck if (lpBand->clrBack != CLR_NONE) {
1929c2c66affSColin Finck new = (lpBand->clrBack == CLR_DEFAULT) ? infoPtr->clrBtnFace :
1930c2c66affSColin Finck lpBand->clrBack;
1931c2c66affSColin Finck #if GLATESTING
1932c2c66affSColin Finck /* testing only - make background green to see it */
1933c2c66affSColin Finck new = RGB(0,128,0);
1934c2c66affSColin Finck #endif
1935c2c66affSColin Finck }
1936c2c66affSColin Finck else {
1937c2c66affSColin Finck /* In the absence of documentation for Rebar vs. CLR_NONE,
1938c2c66affSColin Finck * we will use the default BtnFace color. Note documentation
1939c2c66affSColin Finck * exists for Listview and Imagelist.
1940c2c66affSColin Finck */
1941c2c66affSColin Finck new = infoPtr->clrBtnFace;
1942c2c66affSColin Finck #if GLATESTING
1943c2c66affSColin Finck /* testing only - make background green to see it */
1944c2c66affSColin Finck new = RGB(0,128,0);
1945c2c66affSColin Finck #endif
1946c2c66affSColin Finck }
1947c2c66affSColin Finck
1948c2c66affSColin Finck if (theme)
1949c2c66affSColin Finck {
1950c2c66affSColin Finck /* When themed, the background color is ignored (but not a
1951c2c66affSColin Finck * background bitmap */
1952c2c66affSColin Finck DrawThemeBackground (theme, hdc, 0, 0, &cr, &rcBand);
1953c2c66affSColin Finck }
1954c2c66affSColin Finck else
1955c2c66affSColin Finck {
1956c2c66affSColin Finck old = SetBkColor (hdc, new);
1957c2c66affSColin Finck TRACE("%s background color=0x%06x, band %s\n",
1958c2c66affSColin Finck (lpBand->clrBack == CLR_NONE) ? "none" :
1959c2c66affSColin Finck ((lpBand->clrBack == CLR_DEFAULT) ? "dft" : ""),
1960c2c66affSColin Finck GetBkColor(hdc), wine_dbgstr_rect(&rcBand));
1961c2c66affSColin Finck ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rcBand, NULL, 0, 0);
1962c2c66affSColin Finck if (lpBand->clrBack != CLR_NONE)
1963c2c66affSColin Finck SetBkColor (hdc, old);
1964c2c66affSColin Finck }
1965c2c66affSColin Finck }
1966c2c66affSColin Finck return TRUE;
1967c2c66affSColin Finck }
1968c2c66affSColin Finck
1969c2c66affSColin Finck static void
REBAR_InternalHitTest(const REBAR_INFO * infoPtr,const POINT * lpPt,UINT * pFlags,INT * pBand)1970c2c66affSColin Finck REBAR_InternalHitTest (const REBAR_INFO *infoPtr, const POINT *lpPt, UINT *pFlags, INT *pBand)
1971c2c66affSColin Finck {
1972c2c66affSColin Finck REBAR_BAND *lpBand;
1973c2c66affSColin Finck RECT rect;
1974c2c66affSColin Finck UINT iCount;
1975c2c66affSColin Finck
1976c2c66affSColin Finck GetClientRect (infoPtr->hwndSelf, &rect);
1977c2c66affSColin Finck
1978c2c66affSColin Finck *pFlags = RBHT_NOWHERE;
1979c2c66affSColin Finck if (PtInRect (&rect, *lpPt))
1980c2c66affSColin Finck {
1981c2c66affSColin Finck if (infoPtr->uNumBands == 0) {
1982c2c66affSColin Finck *pFlags = RBHT_NOWHERE;
1983c2c66affSColin Finck if (pBand)
1984c2c66affSColin Finck *pBand = -1;
1985c2c66affSColin Finck TRACE("NOWHERE\n");
1986c2c66affSColin Finck return;
1987c2c66affSColin Finck }
1988c2c66affSColin Finck else {
1989c2c66affSColin Finck /* somewhere inside */
1990c2c66affSColin Finck for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) {
1991c2c66affSColin Finck RECT rcBand;
1992c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, iCount);
1993c2c66affSColin Finck translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
1994c2c66affSColin Finck if (HIDDENBAND(lpBand)) continue;
1995c2c66affSColin Finck if (PtInRect (&rcBand, *lpPt)) {
1996c2c66affSColin Finck if (pBand)
1997c2c66affSColin Finck *pBand = iCount;
1998c2c66affSColin Finck if (PtInRect (&lpBand->rcGripper, *lpPt)) {
1999c2c66affSColin Finck *pFlags = RBHT_GRABBER;
2000c2c66affSColin Finck TRACE("ON GRABBER %d\n", iCount);
2001c2c66affSColin Finck return;
2002c2c66affSColin Finck }
2003c2c66affSColin Finck else if (PtInRect (&lpBand->rcCapImage, *lpPt)) {
2004c2c66affSColin Finck *pFlags = RBHT_CAPTION;
2005c2c66affSColin Finck TRACE("ON CAPTION %d\n", iCount);
2006c2c66affSColin Finck return;
2007c2c66affSColin Finck }
2008c2c66affSColin Finck else if (PtInRect (&lpBand->rcCapText, *lpPt)) {
2009c2c66affSColin Finck *pFlags = RBHT_CAPTION;
2010c2c66affSColin Finck TRACE("ON CAPTION %d\n", iCount);
2011c2c66affSColin Finck return;
2012c2c66affSColin Finck }
2013c2c66affSColin Finck else if (PtInRect (&lpBand->rcChild, *lpPt)) {
2014c2c66affSColin Finck *pFlags = RBHT_CLIENT;
2015c2c66affSColin Finck TRACE("ON CLIENT %d\n", iCount);
2016c2c66affSColin Finck return;
2017c2c66affSColin Finck }
2018c2c66affSColin Finck else if (PtInRect (&lpBand->rcChevron, *lpPt)) {
2019c2c66affSColin Finck *pFlags = RBHT_CHEVRON;
2020c2c66affSColin Finck TRACE("ON CHEVRON %d\n", iCount);
2021c2c66affSColin Finck return;
2022c2c66affSColin Finck }
2023c2c66affSColin Finck else {
2024c2c66affSColin Finck *pFlags = RBHT_NOWHERE;
2025c2c66affSColin Finck TRACE("NOWHERE %d\n", iCount);
2026c2c66affSColin Finck return;
2027c2c66affSColin Finck }
2028c2c66affSColin Finck }
2029c2c66affSColin Finck }
2030c2c66affSColin Finck
2031c2c66affSColin Finck *pFlags = RBHT_NOWHERE;
2032c2c66affSColin Finck if (pBand)
2033c2c66affSColin Finck *pBand = -1;
2034c2c66affSColin Finck
2035c2c66affSColin Finck TRACE("NOWHERE\n");
2036c2c66affSColin Finck return;
2037c2c66affSColin Finck }
2038c2c66affSColin Finck }
2039c2c66affSColin Finck else {
2040c2c66affSColin Finck *pFlags = RBHT_NOWHERE;
2041c2c66affSColin Finck if (pBand)
2042c2c66affSColin Finck *pBand = -1;
2043c2c66affSColin Finck TRACE("NOWHERE\n");
2044c2c66affSColin Finck return;
2045c2c66affSColin Finck }
2046c2c66affSColin Finck }
2047c2c66affSColin Finck
2048c2c66affSColin Finck static void
REBAR_HandleLRDrag(REBAR_INFO * infoPtr,const POINT * ptsmove)2049c2c66affSColin Finck REBAR_HandleLRDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
2050c2c66affSColin Finck /* Function: This will implement the functionality of a */
2051c2c66affSColin Finck /* Gripper drag within a row. It will not implement "out- */
2052c2c66affSColin Finck /* of-row" drags. (They are detected and handled in */
2053c2c66affSColin Finck /* REBAR_MouseMove.) */
2054c2c66affSColin Finck {
2055c2c66affSColin Finck REBAR_BAND *hitBand;
2056c2c66affSColin Finck INT iHitBand, iRowBegin, iRowEnd;
2057c2c66affSColin Finck INT movement, xBand, cxLeft = 0;
2058c2c66affSColin Finck BOOL shrunkBands = FALSE;
2059c2c66affSColin Finck
2060c2c66affSColin Finck iHitBand = infoPtr->iGrabbedBand;
2061c2c66affSColin Finck iRowBegin = get_row_begin_for_band(infoPtr, iHitBand);
2062c2c66affSColin Finck iRowEnd = get_row_end_for_band(infoPtr, iHitBand);
2063c2c66affSColin Finck hitBand = REBAR_GetBand(infoPtr, iHitBand);
2064c2c66affSColin Finck
2065c2c66affSColin Finck xBand = hitBand->rcBand.left;
2066c2c66affSColin Finck movement = (infoPtr->dwStyle&CCS_VERT ? ptsmove->y : ptsmove->x)
2067c2c66affSColin Finck - (xBand + REBAR_PRE_GRIPPER - infoPtr->ihitoffset);
2068c2c66affSColin Finck
2069c2c66affSColin Finck /* Dragging the first band in a row cannot cause shrinking */
2070c2c66affSColin Finck if(iHitBand != iRowBegin)
2071c2c66affSColin Finck {
2072c2c66affSColin Finck if (movement < 0) {
2073c2c66affSColin Finck cxLeft = REBAR_ShrinkBandsRTL(infoPtr, iRowBegin, iHitBand, -movement, TRUE);
2074c2c66affSColin Finck
2075c2c66affSColin Finck if(cxLeft < -movement)
2076c2c66affSColin Finck {
2077c2c66affSColin Finck hitBand->cxEffective += -movement - cxLeft;
2078c2c66affSColin Finck hitBand->cx = hitBand->cxEffective;
2079c2c66affSColin Finck shrunkBands = TRUE;
2080c2c66affSColin Finck }
2081c2c66affSColin Finck
2082c2c66affSColin Finck } else if (movement > 0) {
2083c2c66affSColin Finck
2084c2c66affSColin Finck cxLeft = movement;
2085c2c66affSColin Finck if (prev_visible(infoPtr, iHitBand) >= 0)
2086c2c66affSColin Finck cxLeft = REBAR_ShrinkBandsLTR(infoPtr, iHitBand, iRowEnd, movement, TRUE);
2087c2c66affSColin Finck
2088c2c66affSColin Finck if(cxLeft < movement)
2089c2c66affSColin Finck {
2090c2c66affSColin Finck REBAR_BAND *lpPrev = REBAR_GetBand(infoPtr, prev_visible(infoPtr, iHitBand));
2091c2c66affSColin Finck lpPrev->cxEffective += movement - cxLeft;
2092c2c66affSColin Finck lpPrev->cx = hitBand->cxEffective;
2093c2c66affSColin Finck shrunkBands = TRUE;
2094c2c66affSColin Finck }
2095c2c66affSColin Finck
2096c2c66affSColin Finck }
2097c2c66affSColin Finck }
2098c2c66affSColin Finck
2099c2c66affSColin Finck if(!shrunkBands)
2100c2c66affSColin Finck {
2101c2c66affSColin Finck /* It was not possible to move the band by shrinking bands.
2102c2c66affSColin Finck * Try relocating the band instead. */
2103c2c66affSColin Finck REBAR_MoveBandToRowOffset(infoPtr, iHitBand, iRowBegin,
2104c2c66affSColin Finck iRowEnd, xBand + movement, TRUE);
2105c2c66affSColin Finck }
2106c2c66affSColin Finck
2107c2c66affSColin Finck REBAR_SetRowRectsX(infoPtr, iRowBegin, iRowEnd);
2108c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT)
2109c2c66affSColin Finck REBAR_CalcVertBand(infoPtr, 0, infoPtr->uNumBands);
2110c2c66affSColin Finck else
2111c2c66affSColin Finck REBAR_CalcHorzBand(infoPtr, 0, infoPtr->uNumBands);
2112c2c66affSColin Finck REBAR_MoveChildWindows(infoPtr, iRowBegin, iRowEnd);
2113c2c66affSColin Finck }
2114c2c66affSColin Finck
2115c2c66affSColin Finck static void
REBAR_HandleUDDrag(REBAR_INFO * infoPtr,const POINT * ptsmove)2116c2c66affSColin Finck REBAR_HandleUDDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
2117c2c66affSColin Finck {
2118c2c66affSColin Finck INT yOff = (infoPtr->dwStyle & CCS_VERT) ? ptsmove->x : ptsmove->y;
2119c2c66affSColin Finck INT iHitBand, iRowBegin, iNextRowBegin;
2120c2c66affSColin Finck REBAR_BAND *hitBand, *rowBeginBand;
2121c2c66affSColin Finck
2122c2c66affSColin Finck if(infoPtr->uNumBands <= 0)
2123c2c66affSColin Finck ERR("There are no bands in this rebar\n");
2124c2c66affSColin Finck
2125c2c66affSColin Finck /* Up/down dragging can only occur when there is more than one
2126c2c66affSColin Finck * band in the rebar */
2127c2c66affSColin Finck if(infoPtr->uNumBands <= 1)
2128c2c66affSColin Finck return;
2129c2c66affSColin Finck
2130c2c66affSColin Finck iHitBand = infoPtr->iGrabbedBand;
2131c2c66affSColin Finck hitBand = REBAR_GetBand(infoPtr, iHitBand);
2132c2c66affSColin Finck
2133c2c66affSColin Finck /* If we're taking a band that has the RBBS_BREAK style set, this
2134c2c66affSColin Finck * style needs to be reapplied to the band that is going to become
2135c2c66affSColin Finck * the new start of the row. */
2136c2c66affSColin Finck if((hitBand->fStyle & RBBS_BREAK) &&
2137c2c66affSColin Finck (iHitBand < infoPtr->uNumBands - 1))
2138c2c66affSColin Finck REBAR_GetBand(infoPtr, iHitBand + 1)->fStyle |= RBBS_BREAK;
2139c2c66affSColin Finck
2140c2c66affSColin Finck if(yOff < 0)
2141c2c66affSColin Finck {
2142c2c66affSColin Finck /* Place the band above the current top row */
2143c2c66affSColin Finck if(iHitBand==0 && (infoPtr->uNumBands==1 || REBAR_GetBand(infoPtr, 1)->fStyle&RBBS_BREAK))
2144c2c66affSColin Finck return;
2145c2c66affSColin Finck DPA_DeletePtr(infoPtr->bands, iHitBand);
2146c2c66affSColin Finck hitBand->fStyle &= ~RBBS_BREAK;
2147c2c66affSColin Finck REBAR_GetBand(infoPtr, 0)->fStyle |= RBBS_BREAK;
2148c2c66affSColin Finck infoPtr->iGrabbedBand = DPA_InsertPtr(
2149c2c66affSColin Finck infoPtr->bands, 0, hitBand);
2150c2c66affSColin Finck }
2151c2c66affSColin Finck else if(yOff > REBAR_GetBand(infoPtr, infoPtr->uNumBands - 1)->rcBand.bottom)
2152c2c66affSColin Finck {
2153c2c66affSColin Finck /* Place the band below the current bottom row */
2154c2c66affSColin Finck if(iHitBand == infoPtr->uNumBands-1 && hitBand->fStyle&RBBS_BREAK)
2155c2c66affSColin Finck return;
2156c2c66affSColin Finck DPA_DeletePtr(infoPtr->bands, iHitBand);
2157c2c66affSColin Finck hitBand->fStyle |= RBBS_BREAK;
2158c2c66affSColin Finck infoPtr->iGrabbedBand = DPA_InsertPtr(
2159c2c66affSColin Finck infoPtr->bands, infoPtr->uNumBands - 1, hitBand);
2160c2c66affSColin Finck }
2161c2c66affSColin Finck else
2162c2c66affSColin Finck {
21630707475fSJustin Miller /* Place the band in the preexisting row the mouse is hovering over */
2164c2c66affSColin Finck iRowBegin = first_visible(infoPtr);
2165c2c66affSColin Finck while(iRowBegin < infoPtr->uNumBands)
2166c2c66affSColin Finck {
2167c2c66affSColin Finck iNextRowBegin = get_row_end_for_band(infoPtr, iRowBegin);
2168c2c66affSColin Finck rowBeginBand = REBAR_GetBand(infoPtr, iRowBegin);
2169c2c66affSColin Finck if(rowBeginBand->rcBand.bottom > yOff)
2170c2c66affSColin Finck {
2171c2c66affSColin Finck REBAR_MoveBandToRowOffset(
2172c2c66affSColin Finck infoPtr, iHitBand, iRowBegin, iNextRowBegin,
2173c2c66affSColin Finck ((infoPtr->dwStyle & CCS_VERT) ? ptsmove->y : ptsmove->x)
2174c2c66affSColin Finck - REBAR_PRE_GRIPPER - infoPtr->ihitoffset, FALSE);
2175c2c66affSColin Finck break;
2176c2c66affSColin Finck }
2177c2c66affSColin Finck
2178c2c66affSColin Finck iRowBegin = iNextRowBegin;
2179c2c66affSColin Finck }
2180c2c66affSColin Finck }
2181c2c66affSColin Finck
2182c2c66affSColin Finck REBAR_Layout(infoPtr);
2183c2c66affSColin Finck }
2184c2c66affSColin Finck
2185c2c66affSColin Finck
2186c2c66affSColin Finck /* << REBAR_BeginDrag >> */
2187c2c66affSColin Finck
2188c2c66affSColin Finck
2189c2c66affSColin Finck static LRESULT
REBAR_DeleteBand(REBAR_INFO * infoPtr,WPARAM wParam)2190c2c66affSColin Finck REBAR_DeleteBand (REBAR_INFO *infoPtr, WPARAM wParam)
2191c2c66affSColin Finck {
2192c2c66affSColin Finck UINT uBand = (UINT)wParam;
2193c2c66affSColin Finck REBAR_BAND *lpBand;
2194c2c66affSColin Finck
2195c2c66affSColin Finck if (uBand >= infoPtr->uNumBands)
2196c2c66affSColin Finck return FALSE;
2197c2c66affSColin Finck
2198c2c66affSColin Finck TRACE("deleting band %u!\n", uBand);
2199c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, uBand);
2200c2c66affSColin Finck REBAR_Notify_NMREBAR (infoPtr, uBand, RBN_DELETINGBAND);
2201c2c66affSColin Finck /* TODO: a return of 1 should probably cancel the deletion */
2202c2c66affSColin Finck
2203c2c66affSColin Finck if (lpBand->hwndChild)
2204c2c66affSColin Finck ShowWindow(lpBand->hwndChild, SW_HIDE);
2205c2c66affSColin Finck Free(lpBand->lpText);
2206c2c66affSColin Finck Free(lpBand);
2207c2c66affSColin Finck
2208c2c66affSColin Finck infoPtr->uNumBands--;
2209c2c66affSColin Finck DPA_DeletePtr(infoPtr->bands, uBand);
2210c2c66affSColin Finck
2211c2c66affSColin Finck REBAR_Notify_NMREBAR (infoPtr, -1, RBN_DELETEDBAND);
2212c2c66affSColin Finck
2213c2c66affSColin Finck /* if only 1 band left the re-validate to possible eliminate gripper */
2214c2c66affSColin Finck if (infoPtr->uNumBands == 1)
2215c2c66affSColin Finck REBAR_ValidateBand (infoPtr, REBAR_GetBand(infoPtr, 0));
2216c2c66affSColin Finck
2217c2c66affSColin Finck REBAR_Layout(infoPtr);
2218c2c66affSColin Finck
2219c2c66affSColin Finck return TRUE;
2220c2c66affSColin Finck }
2221c2c66affSColin Finck
2222c2c66affSColin Finck
2223c2c66affSColin Finck /* << REBAR_DragMove >> */
2224c2c66affSColin Finck /* << REBAR_EndDrag >> */
2225c2c66affSColin Finck
2226c2c66affSColin Finck
2227c2c66affSColin Finck static LRESULT
REBAR_GetBandBorders(const REBAR_INFO * infoPtr,UINT uBand,RECT * lpRect)2228c2c66affSColin Finck REBAR_GetBandBorders (const REBAR_INFO *infoPtr, UINT uBand, RECT *lpRect)
2229c2c66affSColin Finck {
2230c2c66affSColin Finck REBAR_BAND *lpBand;
2231c2c66affSColin Finck
2232c2c66affSColin Finck if (!lpRect)
2233c2c66affSColin Finck return 0;
2234c2c66affSColin Finck if (uBand >= infoPtr->uNumBands)
2235c2c66affSColin Finck return 0;
2236c2c66affSColin Finck
2237c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, uBand);
2238c2c66affSColin Finck
2239c2c66affSColin Finck /* FIXME - the following values were determined by experimentation */
2240c2c66affSColin Finck /* with the REBAR Control Spy. I have guesses as to what the 4 and */
2241c2c66affSColin Finck /* 1 are, but I am not sure. There doesn't seem to be any actual */
2242c2c66affSColin Finck /* difference in size of the control area with and without the */
2243c2c66affSColin Finck /* style. - GA */
2244c2c66affSColin Finck if (infoPtr->dwStyle & RBS_BANDBORDERS) {
2245c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT) {
2246c2c66affSColin Finck lpRect->left = 1;
2247c2c66affSColin Finck lpRect->top = lpBand->cxHeader + 4;
2248c2c66affSColin Finck lpRect->right = 1;
2249c2c66affSColin Finck lpRect->bottom = 0;
2250c2c66affSColin Finck }
2251c2c66affSColin Finck else {
2252c2c66affSColin Finck lpRect->left = lpBand->cxHeader + 4;
2253c2c66affSColin Finck lpRect->top = 1;
2254c2c66affSColin Finck lpRect->right = 0;
2255c2c66affSColin Finck lpRect->bottom = 1;
2256c2c66affSColin Finck }
2257c2c66affSColin Finck }
2258c2c66affSColin Finck else {
2259c2c66affSColin Finck lpRect->left = lpBand->cxHeader;
2260c2c66affSColin Finck }
2261c2c66affSColin Finck return 0;
2262c2c66affSColin Finck }
2263c2c66affSColin Finck
2264c2c66affSColin Finck
2265c2c66affSColin Finck static inline LRESULT
REBAR_GetBandCount(const REBAR_INFO * infoPtr)2266c2c66affSColin Finck REBAR_GetBandCount (const REBAR_INFO *infoPtr)
2267c2c66affSColin Finck {
2268c2c66affSColin Finck TRACE("band count %u!\n", infoPtr->uNumBands);
2269c2c66affSColin Finck
2270c2c66affSColin Finck return infoPtr->uNumBands;
2271c2c66affSColin Finck }
2272c2c66affSColin Finck
2273c2c66affSColin Finck
2274c2c66affSColin Finck static LRESULT
REBAR_GetBandInfoT(const REBAR_INFO * infoPtr,UINT uIndex,LPREBARBANDINFOW lprbbi,BOOL bUnicode)2275c2c66affSColin Finck REBAR_GetBandInfoT(const REBAR_INFO *infoPtr, UINT uIndex, LPREBARBANDINFOW lprbbi, BOOL bUnicode)
2276c2c66affSColin Finck {
2277c2c66affSColin Finck REBAR_BAND *lpBand;
2278c2c66affSColin Finck
2279c2c66affSColin Finck if (!lprbbi || lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
2280c2c66affSColin Finck return FALSE;
2281c2c66affSColin Finck
2282c2c66affSColin Finck if (uIndex >= infoPtr->uNumBands)
2283c2c66affSColin Finck return FALSE;
2284c2c66affSColin Finck
2285c2c66affSColin Finck TRACE("index %u (bUnicode=%d)\n", uIndex, bUnicode);
2286c2c66affSColin Finck
2287c2c66affSColin Finck /* copy band information */
2288c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, uIndex);
2289c2c66affSColin Finck
2290c2c66affSColin Finck if (lprbbi->fMask & RBBIM_STYLE)
2291c2c66affSColin Finck lprbbi->fStyle = lpBand->fStyle;
2292c2c66affSColin Finck
2293c2c66affSColin Finck if (lprbbi->fMask & RBBIM_COLORS) {
2294c2c66affSColin Finck lprbbi->clrFore = lpBand->clrFore;
2295c2c66affSColin Finck lprbbi->clrBack = lpBand->clrBack;
2296c2c66affSColin Finck if (lprbbi->clrBack == CLR_DEFAULT)
2297c2c66affSColin Finck lprbbi->clrBack = infoPtr->clrBtnFace;
2298c2c66affSColin Finck }
2299c2c66affSColin Finck
2300c2c66affSColin Finck if (lprbbi->fMask & RBBIM_TEXT) {
2301c2c66affSColin Finck if (bUnicode)
2302c2c66affSColin Finck Str_GetPtrW(lpBand->lpText, lprbbi->lpText, lprbbi->cch);
2303c2c66affSColin Finck else
2304c2c66affSColin Finck Str_GetPtrWtoA(lpBand->lpText, (LPSTR)lprbbi->lpText, lprbbi->cch);
2305c2c66affSColin Finck }
2306c2c66affSColin Finck
2307c2c66affSColin Finck if (lprbbi->fMask & RBBIM_IMAGE)
2308c2c66affSColin Finck lprbbi->iImage = lpBand->iImage;
2309c2c66affSColin Finck
2310c2c66affSColin Finck if (lprbbi->fMask & RBBIM_CHILD)
2311c2c66affSColin Finck lprbbi->hwndChild = lpBand->hwndChild;
2312c2c66affSColin Finck
2313c2c66affSColin Finck if (lprbbi->fMask & RBBIM_CHILDSIZE) {
2314c2c66affSColin Finck lprbbi->cxMinChild = lpBand->cxMinChild;
2315c2c66affSColin Finck lprbbi->cyMinChild = lpBand->cyMinChild;
2316c2c66affSColin Finck /* to make tests pass we follow Windows' behaviour and allow reading these fields only
2317c2c66affSColin Finck * for RBBS_VARIABLEHEIGHTS bands */
2318c2c66affSColin Finck if (lprbbi->cbSize >= REBARBANDINFOW_V6_SIZE && (lpBand->fStyle & RBBS_VARIABLEHEIGHT)) {
2319c2c66affSColin Finck lprbbi->cyChild = lpBand->cyChild;
2320c2c66affSColin Finck lprbbi->cyMaxChild = lpBand->cyMaxChild;
2321c2c66affSColin Finck lprbbi->cyIntegral = lpBand->cyIntegral;
2322c2c66affSColin Finck }
2323c2c66affSColin Finck }
2324c2c66affSColin Finck
2325c2c66affSColin Finck if (lprbbi->fMask & RBBIM_SIZE)
2326c2c66affSColin Finck lprbbi->cx = lpBand->cx;
2327c2c66affSColin Finck
2328c2c66affSColin Finck if (lprbbi->fMask & RBBIM_BACKGROUND)
2329c2c66affSColin Finck lprbbi->hbmBack = lpBand->hbmBack;
2330c2c66affSColin Finck
2331c2c66affSColin Finck if (lprbbi->fMask & RBBIM_ID)
2332c2c66affSColin Finck lprbbi->wID = lpBand->wID;
2333c2c66affSColin Finck
2334c2c66affSColin Finck /* check for additional data */
2335c2c66affSColin Finck if (lprbbi->cbSize >= REBARBANDINFOW_V6_SIZE) {
2336c2c66affSColin Finck if (lprbbi->fMask & RBBIM_IDEALSIZE)
2337c2c66affSColin Finck lprbbi->cxIdeal = lpBand->cxIdeal;
2338c2c66affSColin Finck
2339c2c66affSColin Finck if (lprbbi->fMask & RBBIM_LPARAM)
2340c2c66affSColin Finck lprbbi->lParam = lpBand->lParam;
2341c2c66affSColin Finck
2342c2c66affSColin Finck if (lprbbi->fMask & RBBIM_HEADERSIZE)
2343c2c66affSColin Finck lprbbi->cxHeader = lpBand->cxHeader;
2344c2c66affSColin Finck }
2345c2c66affSColin Finck
2346c2c66affSColin Finck REBAR_DumpBandInfo(lprbbi);
2347c2c66affSColin Finck
2348c2c66affSColin Finck return TRUE;
2349c2c66affSColin Finck }
2350c2c66affSColin Finck
2351c2c66affSColin Finck
2352c2c66affSColin Finck static LRESULT
REBAR_GetBarHeight(const REBAR_INFO * infoPtr)2353c2c66affSColin Finck REBAR_GetBarHeight (const REBAR_INFO *infoPtr)
2354c2c66affSColin Finck {
2355c2c66affSColin Finck INT nHeight;
2356c2c66affSColin Finck
2357c2c66affSColin Finck nHeight = infoPtr->calcSize.cy;
2358c2c66affSColin Finck
2359c2c66affSColin Finck TRACE("height = %d\n", nHeight);
2360c2c66affSColin Finck
2361c2c66affSColin Finck return nHeight;
2362c2c66affSColin Finck }
2363c2c66affSColin Finck
2364c2c66affSColin Finck
2365c2c66affSColin Finck static LRESULT
REBAR_GetBarInfo(const REBAR_INFO * infoPtr,LPREBARINFO lpInfo)2366c2c66affSColin Finck REBAR_GetBarInfo (const REBAR_INFO *infoPtr, LPREBARINFO lpInfo)
2367c2c66affSColin Finck {
2368c2c66affSColin Finck if (!lpInfo || lpInfo->cbSize < sizeof (REBARINFO))
2369c2c66affSColin Finck return FALSE;
2370c2c66affSColin Finck
2371c2c66affSColin Finck TRACE("getting bar info!\n");
2372c2c66affSColin Finck
2373c2c66affSColin Finck if (infoPtr->himl) {
2374c2c66affSColin Finck lpInfo->himl = infoPtr->himl;
2375c2c66affSColin Finck lpInfo->fMask |= RBIM_IMAGELIST;
2376c2c66affSColin Finck }
2377c2c66affSColin Finck
2378c2c66affSColin Finck return TRUE;
2379c2c66affSColin Finck }
2380c2c66affSColin Finck
2381c2c66affSColin Finck
2382c2c66affSColin Finck static inline LRESULT
REBAR_GetBkColor(const REBAR_INFO * infoPtr)2383c2c66affSColin Finck REBAR_GetBkColor (const REBAR_INFO *infoPtr)
2384c2c66affSColin Finck {
2385c2c66affSColin Finck COLORREF clr = infoPtr->clrBk;
2386c2c66affSColin Finck
2387c2c66affSColin Finck if (clr == CLR_DEFAULT)
2388c2c66affSColin Finck clr = infoPtr->clrBtnFace;
2389c2c66affSColin Finck
2390c2c66affSColin Finck TRACE("background color 0x%06x!\n", clr);
2391c2c66affSColin Finck
2392c2c66affSColin Finck return clr;
2393c2c66affSColin Finck }
2394c2c66affSColin Finck
2395c2c66affSColin Finck
2396c2c66affSColin Finck /* << REBAR_GetColorScheme >> */
2397c2c66affSColin Finck /* << REBAR_GetDropTarget >> */
2398c2c66affSColin Finck
2399c2c66affSColin Finck
2400c2c66affSColin Finck static LRESULT
REBAR_GetPalette(const REBAR_INFO * infoPtr)2401c2c66affSColin Finck REBAR_GetPalette (const REBAR_INFO *infoPtr)
2402c2c66affSColin Finck {
2403c2c66affSColin Finck FIXME("empty stub!\n");
2404c2c66affSColin Finck
2405c2c66affSColin Finck return 0;
2406c2c66affSColin Finck }
2407c2c66affSColin Finck
2408c2c66affSColin Finck
2409c2c66affSColin Finck static LRESULT
REBAR_GetRect(const REBAR_INFO * infoPtr,INT iBand,RECT * lprc)2410c2c66affSColin Finck REBAR_GetRect (const REBAR_INFO *infoPtr, INT iBand, RECT *lprc)
2411c2c66affSColin Finck {
2412c2c66affSColin Finck REBAR_BAND *lpBand;
2413c2c66affSColin Finck
2414c2c66affSColin Finck if (iBand < 0 || iBand >= infoPtr->uNumBands)
2415c2c66affSColin Finck return FALSE;
2416c2c66affSColin Finck if (!lprc)
2417c2c66affSColin Finck return FALSE;
2418c2c66affSColin Finck
2419c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, iBand);
2420c2c66affSColin Finck /* For CCS_VERT the coordinates will be swapped - like on Windows */
2421c2c66affSColin Finck *lprc = lpBand->rcBand;
2422c2c66affSColin Finck
2423c2c66affSColin Finck TRACE("band %d, (%s)\n", iBand, wine_dbgstr_rect(lprc));
2424c2c66affSColin Finck
2425c2c66affSColin Finck return TRUE;
2426c2c66affSColin Finck }
2427c2c66affSColin Finck
2428c2c66affSColin Finck
2429c2c66affSColin Finck static inline LRESULT
REBAR_GetRowCount(const REBAR_INFO * infoPtr)2430c2c66affSColin Finck REBAR_GetRowCount (const REBAR_INFO *infoPtr)
2431c2c66affSColin Finck {
2432c2c66affSColin Finck TRACE("%u\n", infoPtr->uNumRows);
2433c2c66affSColin Finck
2434c2c66affSColin Finck return infoPtr->uNumRows;
2435c2c66affSColin Finck }
2436c2c66affSColin Finck
2437c2c66affSColin Finck
2438c2c66affSColin Finck static LRESULT
REBAR_GetRowHeight(const REBAR_INFO * infoPtr,INT iRow)2439c2c66affSColin Finck REBAR_GetRowHeight (const REBAR_INFO *infoPtr, INT iRow)
2440c2c66affSColin Finck {
2441c2c66affSColin Finck int j = 0, ret = 0;
2442c2c66affSColin Finck UINT i;
2443c2c66affSColin Finck REBAR_BAND *lpBand;
2444c2c66affSColin Finck
2445c2c66affSColin Finck for (i=0; i<infoPtr->uNumBands; i++) {
2446c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
2447c2c66affSColin Finck if (HIDDENBAND(lpBand)) continue;
2448c2c66affSColin Finck if (lpBand->iRow != iRow) continue;
2449c2c66affSColin Finck j = lpBand->rcBand.bottom - lpBand->rcBand.top;
2450c2c66affSColin Finck if (j > ret) ret = j;
2451c2c66affSColin Finck }
2452c2c66affSColin Finck
2453c2c66affSColin Finck TRACE("row %d, height %d\n", iRow, ret);
2454c2c66affSColin Finck
2455c2c66affSColin Finck return ret;
2456c2c66affSColin Finck }
2457c2c66affSColin Finck
2458c2c66affSColin Finck
2459c2c66affSColin Finck static inline LRESULT
REBAR_GetTextColor(const REBAR_INFO * infoPtr)2460c2c66affSColin Finck REBAR_GetTextColor (const REBAR_INFO *infoPtr)
2461c2c66affSColin Finck {
2462c2c66affSColin Finck TRACE("text color 0x%06x!\n", infoPtr->clrText);
2463c2c66affSColin Finck
2464c2c66affSColin Finck return infoPtr->clrText;
2465c2c66affSColin Finck }
2466c2c66affSColin Finck
2467c2c66affSColin Finck
2468c2c66affSColin Finck static inline LRESULT
REBAR_GetToolTips(const REBAR_INFO * infoPtr)2469c2c66affSColin Finck REBAR_GetToolTips (const REBAR_INFO *infoPtr)
2470c2c66affSColin Finck {
2471c2c66affSColin Finck return (LRESULT)infoPtr->hwndToolTip;
2472c2c66affSColin Finck }
2473c2c66affSColin Finck
2474c2c66affSColin Finck
2475c2c66affSColin Finck static inline LRESULT
REBAR_GetUnicodeFormat(const REBAR_INFO * infoPtr)2476c2c66affSColin Finck REBAR_GetUnicodeFormat (const REBAR_INFO *infoPtr)
2477c2c66affSColin Finck {
2478c2c66affSColin Finck TRACE("%s hwnd=%p\n",
2479c2c66affSColin Finck infoPtr->bUnicode ? "TRUE" : "FALSE", infoPtr->hwndSelf);
2480c2c66affSColin Finck
2481c2c66affSColin Finck return infoPtr->bUnicode;
2482c2c66affSColin Finck }
2483c2c66affSColin Finck
2484c2c66affSColin Finck
2485c2c66affSColin Finck static inline LRESULT
REBAR_GetVersion(const REBAR_INFO * infoPtr)2486c2c66affSColin Finck REBAR_GetVersion (const REBAR_INFO *infoPtr)
2487c2c66affSColin Finck {
2488c2c66affSColin Finck TRACE("version %d\n", infoPtr->iVersion);
2489c2c66affSColin Finck return infoPtr->iVersion;
2490c2c66affSColin Finck }
2491c2c66affSColin Finck
2492c2c66affSColin Finck
2493c2c66affSColin Finck static LRESULT
REBAR_HitTest(const REBAR_INFO * infoPtr,LPRBHITTESTINFO lprbht)2494c2c66affSColin Finck REBAR_HitTest (const REBAR_INFO *infoPtr, LPRBHITTESTINFO lprbht)
2495c2c66affSColin Finck {
2496c2c66affSColin Finck if (!lprbht)
2497c2c66affSColin Finck return -1;
2498c2c66affSColin Finck
2499c2c66affSColin Finck REBAR_InternalHitTest (infoPtr, &lprbht->pt, &lprbht->flags, &lprbht->iBand);
2500c2c66affSColin Finck
2501c2c66affSColin Finck return lprbht->iBand;
2502c2c66affSColin Finck }
2503c2c66affSColin Finck
2504c2c66affSColin Finck
2505c2c66affSColin Finck static LRESULT
REBAR_IdToIndex(const REBAR_INFO * infoPtr,UINT uId)2506c2c66affSColin Finck REBAR_IdToIndex (const REBAR_INFO *infoPtr, UINT uId)
2507c2c66affSColin Finck {
2508c2c66affSColin Finck UINT i;
2509c2c66affSColin Finck
2510c2c66affSColin Finck if (infoPtr->uNumBands < 1)
2511c2c66affSColin Finck return -1;
2512c2c66affSColin Finck
2513c2c66affSColin Finck for (i = 0; i < infoPtr->uNumBands; i++) {
2514c2c66affSColin Finck if (REBAR_GetBand(infoPtr, i)->wID == uId) {
2515c2c66affSColin Finck TRACE("id %u is band %u found!\n", uId, i);
2516c2c66affSColin Finck return i;
2517c2c66affSColin Finck }
2518c2c66affSColin Finck }
2519c2c66affSColin Finck
2520c2c66affSColin Finck TRACE("id %u is not found\n", uId);
2521c2c66affSColin Finck return -1;
2522c2c66affSColin Finck }
2523c2c66affSColin Finck
2524c2c66affSColin Finck
2525c2c66affSColin Finck static LRESULT
REBAR_InsertBandT(REBAR_INFO * infoPtr,INT iIndex,const REBARBANDINFOW * lprbbi,BOOL bUnicode)2526c2c66affSColin Finck REBAR_InsertBandT(REBAR_INFO *infoPtr, INT iIndex, const REBARBANDINFOW *lprbbi, BOOL bUnicode)
2527c2c66affSColin Finck {
2528c2c66affSColin Finck REBAR_BAND *lpBand;
2529c2c66affSColin Finck
2530c2c66affSColin Finck if (!lprbbi || lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
2531c2c66affSColin Finck return FALSE;
2532c2c66affSColin Finck
2533c2c66affSColin Finck /* trace the index as signed to see the -1 */
2534c2c66affSColin Finck TRACE("insert band at %d (bUnicode=%d)!\n", iIndex, bUnicode);
2535c2c66affSColin Finck REBAR_DumpBandInfo(lprbbi);
2536c2c66affSColin Finck
2537c2c66affSColin Finck if (!(lpBand = Alloc(sizeof(REBAR_BAND)))) return FALSE;
2538c2c66affSColin Finck if ((iIndex == -1) || (iIndex > infoPtr->uNumBands))
2539c2c66affSColin Finck iIndex = infoPtr->uNumBands;
2540c2c66affSColin Finck if (DPA_InsertPtr(infoPtr->bands, iIndex, lpBand) == -1)
2541c2c66affSColin Finck {
2542c2c66affSColin Finck Free(lpBand);
2543c2c66affSColin Finck return FALSE;
2544c2c66affSColin Finck }
2545c2c66affSColin Finck infoPtr->uNumBands++;
2546c2c66affSColin Finck
2547c2c66affSColin Finck TRACE("index %d!\n", iIndex);
2548c2c66affSColin Finck
2549c2c66affSColin Finck /* initialize band */
2550c2c66affSColin Finck memset(lpBand, 0, sizeof(*lpBand));
2551*751641c2SWhindmar Saksit #ifdef __REACTOS__
2552*751641c2SWhindmar Saksit lpBand->clrFore = infoPtr->clrText == CLR_NONE ? CLR_DEFAULT : infoPtr->clrText;
2553*751641c2SWhindmar Saksit lpBand->clrBack = infoPtr->clrBk == CLR_NONE ? CLR_DEFAULT : infoPtr->clrBk;
2554*751641c2SWhindmar Saksit #else
2555c2c66affSColin Finck lpBand->clrFore = infoPtr->clrText == CLR_NONE ? infoPtr->clrBtnText :
2556c2c66affSColin Finck infoPtr->clrText;
2557c2c66affSColin Finck lpBand->clrBack = infoPtr->clrBk == CLR_NONE ? infoPtr->clrBtnFace :
2558c2c66affSColin Finck infoPtr->clrBk;
2559*751641c2SWhindmar Saksit #endif
2560c2c66affSColin Finck lpBand->iImage = -1;
2561c2c66affSColin Finck
2562c2c66affSColin Finck REBAR_CommonSetupBand(infoPtr->hwndSelf, lprbbi, lpBand);
2563c2c66affSColin Finck
2564c2c66affSColin Finck /* Make sure the defaults for these are correct */
2565c2c66affSColin Finck if (lprbbi->cbSize < REBARBANDINFOA_V6_SIZE || !(lpBand->fStyle & RBBS_VARIABLEHEIGHT)) {
2566c2c66affSColin Finck lpBand->cyChild = lpBand->cyMinChild;
2567c2c66affSColin Finck lpBand->cyMaxChild = 0x7fffffff;
2568c2c66affSColin Finck lpBand->cyIntegral = 0;
2569c2c66affSColin Finck }
2570c2c66affSColin Finck
2571c2c66affSColin Finck if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
2572c2c66affSColin Finck if (bUnicode)
2573c2c66affSColin Finck Str_SetPtrW(&lpBand->lpText, lprbbi->lpText);
2574c2c66affSColin Finck else
2575c2c66affSColin Finck Str_SetPtrAtoW(&lpBand->lpText, (LPSTR)lprbbi->lpText);
2576c2c66affSColin Finck }
2577c2c66affSColin Finck
2578c2c66affSColin Finck REBAR_ValidateBand (infoPtr, lpBand);
2579c2c66affSColin Finck /* On insert of second band, revalidate band 1 to possible add gripper */
2580c2c66affSColin Finck if (infoPtr->uNumBands == 2)
2581c2c66affSColin Finck REBAR_ValidateBand (infoPtr, REBAR_GetBand(infoPtr, 0));
2582c2c66affSColin Finck
2583c2c66affSColin Finck REBAR_DumpBand (infoPtr);
2584c2c66affSColin Finck
2585c2c66affSColin Finck REBAR_Layout(infoPtr);
2586c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
2587c2c66affSColin Finck
2588c2c66affSColin Finck return TRUE;
2589c2c66affSColin Finck }
2590c2c66affSColin Finck
2591c2c66affSColin Finck
2592c2c66affSColin Finck static LRESULT
REBAR_MaximizeBand(const REBAR_INFO * infoPtr,INT iBand,LPARAM lParam)2593c2c66affSColin Finck REBAR_MaximizeBand (const REBAR_INFO *infoPtr, INT iBand, LPARAM lParam)
2594c2c66affSColin Finck {
2595c2c66affSColin Finck REBAR_BAND *lpBand;
2596c2c66affSColin Finck int iRowBegin, iRowEnd;
2597c2c66affSColin Finck int cxDesired, extra, extraOrig;
2598c2c66affSColin Finck int cxIdealBand;
2599c2c66affSColin Finck
2600c2c66affSColin Finck /* Validate */
2601c2c66affSColin Finck if (infoPtr->uNumBands == 0 || iBand < 0 || iBand >= infoPtr->uNumBands) {
2602c2c66affSColin Finck /* error !!! */
2603c2c66affSColin Finck ERR("Illegal MaximizeBand, requested=%d, current band count=%d\n",
2604c2c66affSColin Finck iBand, infoPtr->uNumBands);
2605c2c66affSColin Finck return FALSE;
2606c2c66affSColin Finck }
2607c2c66affSColin Finck
2608c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, iBand);
2609c2c66affSColin Finck
2610c2c66affSColin Finck if (lpBand->fStyle & RBBS_HIDDEN)
2611c2c66affSColin Finck {
2612c2c66affSColin Finck /* Windows is buggy and creates a hole */
2613c2c66affSColin Finck WARN("Ignoring maximize request on a hidden band (%d)\n", iBand);
2614c2c66affSColin Finck return FALSE;
2615c2c66affSColin Finck }
2616c2c66affSColin Finck
2617c2c66affSColin Finck cxIdealBand = lpBand->cxIdeal + lpBand->cxHeader + REBAR_POST_CHILD;
2618c2c66affSColin Finck if (lParam && (lpBand->cxEffective < cxIdealBand))
2619c2c66affSColin Finck cxDesired = cxIdealBand;
2620c2c66affSColin Finck else
2621c2c66affSColin Finck cxDesired = infoPtr->calcSize.cx;
2622c2c66affSColin Finck
2623c2c66affSColin Finck iRowBegin = get_row_begin_for_band(infoPtr, iBand);
2624c2c66affSColin Finck iRowEnd = get_row_end_for_band(infoPtr, iBand);
2625c2c66affSColin Finck extraOrig = extra = cxDesired - lpBand->cxEffective;
2626c2c66affSColin Finck if (extra > 0)
2627c2c66affSColin Finck extra = REBAR_ShrinkBandsRTL(infoPtr, iRowBegin, iBand, extra, TRUE);
2628c2c66affSColin Finck if (extra > 0)
2629c2c66affSColin Finck extra = REBAR_ShrinkBandsLTR(infoPtr, next_visible(infoPtr, iBand), iRowEnd, extra, TRUE);
2630c2c66affSColin Finck lpBand->cxEffective += extraOrig - extra;
2631c2c66affSColin Finck lpBand->cx = lpBand->cxEffective;
2632c2c66affSColin Finck TRACE("(%d, %ld): Wanted size %d, obtained %d (shrink %d, %d)\n", iBand, lParam, cxDesired, lpBand->cx, extraOrig, extra);
2633c2c66affSColin Finck REBAR_SetRowRectsX(infoPtr, iRowBegin, iRowEnd);
2634c2c66affSColin Finck
2635c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT)
2636c2c66affSColin Finck REBAR_CalcVertBand(infoPtr, iRowBegin, iRowEnd);
2637c2c66affSColin Finck else
2638c2c66affSColin Finck REBAR_CalcHorzBand(infoPtr, iRowBegin, iRowEnd);
2639c2c66affSColin Finck REBAR_MoveChildWindows(infoPtr, iRowBegin, iRowEnd);
2640c2c66affSColin Finck return TRUE;
2641c2c66affSColin Finck
2642c2c66affSColin Finck }
2643c2c66affSColin Finck
2644c2c66affSColin Finck
2645c2c66affSColin Finck static LRESULT
REBAR_MinimizeBand(const REBAR_INFO * infoPtr,INT iBand)2646c2c66affSColin Finck REBAR_MinimizeBand (const REBAR_INFO *infoPtr, INT iBand)
2647c2c66affSColin Finck {
2648c2c66affSColin Finck REBAR_BAND *lpBand;
2649c2c66affSColin Finck int iPrev, iRowBegin, iRowEnd;
2650c2c66affSColin Finck
2651c2c66affSColin Finck /* A "minimize" band is equivalent to "dragging" the gripper
2652c2c66affSColin Finck * of than band to the right till the band is only the size
2653c2c66affSColin Finck * of the cxHeader.
2654c2c66affSColin Finck */
2655c2c66affSColin Finck
2656c2c66affSColin Finck /* Validate */
2657c2c66affSColin Finck if (infoPtr->uNumBands == 0 || iBand < 0 || iBand >= infoPtr->uNumBands) {
2658c2c66affSColin Finck /* error !!! */
2659c2c66affSColin Finck ERR("Illegal MinimizeBand, requested=%d, current band count=%d\n",
2660c2c66affSColin Finck iBand, infoPtr->uNumBands);
2661c2c66affSColin Finck return FALSE;
2662c2c66affSColin Finck }
2663c2c66affSColin Finck
2664c2c66affSColin Finck /* compute amount of movement and validate */
2665c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, iBand);
2666c2c66affSColin Finck
2667c2c66affSColin Finck if (lpBand->fStyle & RBBS_HIDDEN)
2668c2c66affSColin Finck {
2669c2c66affSColin Finck /* Windows is buggy and creates a hole/overlap */
2670c2c66affSColin Finck WARN("Ignoring minimize request on a hidden band (%d)\n", iBand);
2671c2c66affSColin Finck return FALSE;
2672c2c66affSColin Finck }
2673c2c66affSColin Finck
2674c2c66affSColin Finck iPrev = prev_visible(infoPtr, iBand);
2675c2c66affSColin Finck /* if first band in row */
2676c2c66affSColin Finck if (iPrev < 0 || REBAR_GetBand(infoPtr, iPrev)->iRow != lpBand->iRow) {
2677c2c66affSColin Finck int iNext = next_visible(infoPtr, iBand);
2678c2c66affSColin Finck if (iNext < infoPtr->uNumBands && REBAR_GetBand(infoPtr, iNext)->iRow == lpBand->iRow) {
2679c2c66affSColin Finck TRACE("(%d): Minimizing the first band in row is by maximizing the second\n", iBand);
2680c2c66affSColin Finck REBAR_MaximizeBand(infoPtr, iNext, FALSE);
2681c2c66affSColin Finck }
2682c2c66affSColin Finck else
2683c2c66affSColin Finck TRACE("(%d): Only one band in row - nothing to do\n", iBand);
2684c2c66affSColin Finck return TRUE;
2685c2c66affSColin Finck }
2686c2c66affSColin Finck
2687c2c66affSColin Finck REBAR_GetBand(infoPtr, iPrev)->cxEffective += lpBand->cxEffective - lpBand->cxMinBand;
2688c2c66affSColin Finck REBAR_GetBand(infoPtr, iPrev)->cx = REBAR_GetBand(infoPtr, iPrev)->cxEffective;
2689c2c66affSColin Finck lpBand->cx = lpBand->cxEffective = lpBand->cxMinBand;
2690c2c66affSColin Finck
2691c2c66affSColin Finck iRowBegin = get_row_begin_for_band(infoPtr, iBand);
2692c2c66affSColin Finck iRowEnd = get_row_end_for_band(infoPtr, iBand);
2693c2c66affSColin Finck REBAR_SetRowRectsX(infoPtr, iRowBegin, iRowEnd);
2694c2c66affSColin Finck
2695c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT)
2696c2c66affSColin Finck REBAR_CalcVertBand(infoPtr, iRowBegin, iRowEnd);
2697c2c66affSColin Finck else
2698c2c66affSColin Finck REBAR_CalcHorzBand(infoPtr, iRowBegin, iRowEnd);
2699c2c66affSColin Finck REBAR_MoveChildWindows(infoPtr, iRowBegin, iRowEnd);
2700c2c66affSColin Finck return FALSE;
2701c2c66affSColin Finck }
2702c2c66affSColin Finck
2703c2c66affSColin Finck
2704c2c66affSColin Finck static LRESULT
REBAR_MoveBand(REBAR_INFO * infoPtr,INT iFrom,INT iTo)2705c2c66affSColin Finck REBAR_MoveBand (REBAR_INFO *infoPtr, INT iFrom, INT iTo)
2706c2c66affSColin Finck {
2707c2c66affSColin Finck REBAR_BAND *lpBand;
2708c2c66affSColin Finck
2709c2c66affSColin Finck /* Validate */
2710c2c66affSColin Finck if ((infoPtr->uNumBands == 0) ||
2711c2c66affSColin Finck (iFrom < 0) || iFrom >= infoPtr->uNumBands ||
2712c2c66affSColin Finck (iTo < 0) || iTo >= infoPtr->uNumBands) {
2713c2c66affSColin Finck /* error !!! */
2714c2c66affSColin Finck ERR("Illegal MoveBand, from=%d, to=%d, current band count=%d\n",
2715c2c66affSColin Finck iFrom, iTo, infoPtr->uNumBands);
2716c2c66affSColin Finck return FALSE;
2717c2c66affSColin Finck }
2718c2c66affSColin Finck
2719c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, iFrom);
2720c2c66affSColin Finck DPA_DeletePtr(infoPtr->bands, iFrom);
2721c2c66affSColin Finck DPA_InsertPtr(infoPtr->bands, iTo, lpBand);
2722c2c66affSColin Finck
2723c2c66affSColin Finck TRACE("moved band %d to index %d\n", iFrom, iTo);
2724c2c66affSColin Finck REBAR_DumpBand (infoPtr);
2725c2c66affSColin Finck
2726c2c66affSColin Finck /* **************************************************** */
2727c2c66affSColin Finck /* */
2728c2c66affSColin Finck /* We do not do a REBAR_Layout here because the native */
2729c2c66affSColin Finck /* control does not do that. The actual layout and */
2730c2c66affSColin Finck /* repaint is done by the *next* real action, ex.: */
2731c2c66affSColin Finck /* RB_INSERTBAND, RB_DELETEBAND, RB_SIZETORECT, etc. */
2732c2c66affSColin Finck /* */
2733c2c66affSColin Finck /* **************************************************** */
2734c2c66affSColin Finck
2735c2c66affSColin Finck return TRUE;
2736c2c66affSColin Finck }
2737c2c66affSColin Finck
2738c2c66affSColin Finck
2739c2c66affSColin Finck /* return TRUE if two strings are different */
2740c2c66affSColin Finck static BOOL
REBAR_strdifW(LPCWSTR a,LPCWSTR b)2741c2c66affSColin Finck REBAR_strdifW( LPCWSTR a, LPCWSTR b )
2742c2c66affSColin Finck {
2743c2c66affSColin Finck return ( (a && !b) || (b && !a) || (a && b && lstrcmpW(a, b) ) );
2744c2c66affSColin Finck }
2745c2c66affSColin Finck
2746c2c66affSColin Finck static LRESULT
REBAR_SetBandInfoT(REBAR_INFO * infoPtr,INT iBand,const REBARBANDINFOW * lprbbi,BOOL bUnicode)2747c2c66affSColin Finck REBAR_SetBandInfoT(REBAR_INFO *infoPtr, INT iBand, const REBARBANDINFOW *lprbbi, BOOL bUnicode)
2748c2c66affSColin Finck {
2749c2c66affSColin Finck REBAR_BAND *lpBand;
2750c2c66affSColin Finck UINT uChanged;
2751c2c66affSColin Finck
2752c2c66affSColin Finck if (!lprbbi || lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
2753c2c66affSColin Finck return FALSE;
2754c2c66affSColin Finck
2755c2c66affSColin Finck if (iBand >= infoPtr->uNumBands)
2756c2c66affSColin Finck return FALSE;
2757c2c66affSColin Finck
2758c2c66affSColin Finck TRACE("index %d\n", iBand);
2759c2c66affSColin Finck REBAR_DumpBandInfo (lprbbi);
2760c2c66affSColin Finck
2761c2c66affSColin Finck /* set band information */
2762c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, iBand);
2763c2c66affSColin Finck
2764c2c66affSColin Finck uChanged = REBAR_CommonSetupBand (infoPtr->hwndSelf, lprbbi, lpBand);
2765c2c66affSColin Finck if (lprbbi->fMask & RBBIM_TEXT) {
2766c2c66affSColin Finck LPWSTR wstr = NULL;
2767c2c66affSColin Finck if (bUnicode)
2768c2c66affSColin Finck Str_SetPtrW(&wstr, lprbbi->lpText);
2769c2c66affSColin Finck else
2770c2c66affSColin Finck Str_SetPtrAtoW(&wstr, (LPSTR)lprbbi->lpText);
2771c2c66affSColin Finck
2772c2c66affSColin Finck if (REBAR_strdifW(wstr, lpBand->lpText)) {
2773c2c66affSColin Finck Free(lpBand->lpText);
2774c2c66affSColin Finck lpBand->lpText = wstr;
2775c2c66affSColin Finck uChanged |= RBBIM_TEXT;
2776c2c66affSColin Finck }
2777c2c66affSColin Finck else
2778c2c66affSColin Finck Free(wstr);
2779c2c66affSColin Finck }
2780c2c66affSColin Finck
2781c2c66affSColin Finck REBAR_ValidateBand (infoPtr, lpBand);
2782c2c66affSColin Finck
2783c2c66affSColin Finck REBAR_DumpBand (infoPtr);
2784c2c66affSColin Finck
2785c2c66affSColin Finck if (uChanged & (RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE | RBBIM_IMAGE)) {
2786c2c66affSColin Finck REBAR_Layout(infoPtr);
2787c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
2788c2c66affSColin Finck }
2789c2c66affSColin Finck
2790c2c66affSColin Finck return TRUE;
2791c2c66affSColin Finck }
2792c2c66affSColin Finck
2793c2c66affSColin Finck
2794c2c66affSColin Finck static LRESULT
REBAR_SetBarInfo(REBAR_INFO * infoPtr,const REBARINFO * lpInfo)2795c2c66affSColin Finck REBAR_SetBarInfo (REBAR_INFO *infoPtr, const REBARINFO *lpInfo)
2796c2c66affSColin Finck {
2797c2c66affSColin Finck REBAR_BAND *lpBand;
2798c2c66affSColin Finck UINT i;
2799c2c66affSColin Finck
2800c2c66affSColin Finck if (!lpInfo || lpInfo->cbSize < sizeof (REBARINFO))
2801c2c66affSColin Finck return FALSE;
2802c2c66affSColin Finck
2803c2c66affSColin Finck TRACE("setting bar info!\n");
2804c2c66affSColin Finck
2805c2c66affSColin Finck if (lpInfo->fMask & RBIM_IMAGELIST) {
2806c2c66affSColin Finck infoPtr->himl = lpInfo->himl;
2807c2c66affSColin Finck if (infoPtr->himl) {
2808c2c66affSColin Finck INT cx, cy;
2809c2c66affSColin Finck ImageList_GetIconSize (infoPtr->himl, &cx, &cy);
2810c2c66affSColin Finck infoPtr->imageSize.cx = cx;
2811c2c66affSColin Finck infoPtr->imageSize.cy = cy;
2812c2c66affSColin Finck }
2813c2c66affSColin Finck else {
2814c2c66affSColin Finck infoPtr->imageSize.cx = 0;
2815c2c66affSColin Finck infoPtr->imageSize.cy = 0;
2816c2c66affSColin Finck }
2817c2c66affSColin Finck TRACE("new image cx=%d, cy=%d\n", infoPtr->imageSize.cx,
2818c2c66affSColin Finck infoPtr->imageSize.cy);
2819c2c66affSColin Finck }
2820c2c66affSColin Finck
2821c2c66affSColin Finck /* revalidate all bands to reset flags for images in headers of bands */
2822c2c66affSColin Finck for (i=0; i<infoPtr->uNumBands; i++) {
2823c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
2824c2c66affSColin Finck REBAR_ValidateBand (infoPtr, lpBand);
2825c2c66affSColin Finck }
2826c2c66affSColin Finck
2827c2c66affSColin Finck return TRUE;
2828c2c66affSColin Finck }
2829c2c66affSColin Finck
2830c2c66affSColin Finck
2831c2c66affSColin Finck static LRESULT
REBAR_SetBkColor(REBAR_INFO * infoPtr,COLORREF clr)2832c2c66affSColin Finck REBAR_SetBkColor (REBAR_INFO *infoPtr, COLORREF clr)
2833c2c66affSColin Finck {
2834c2c66affSColin Finck COLORREF clrTemp;
2835c2c66affSColin Finck
2836c2c66affSColin Finck clrTemp = infoPtr->clrBk;
2837c2c66affSColin Finck infoPtr->clrBk = clr;
2838c2c66affSColin Finck
2839c2c66affSColin Finck TRACE("background color 0x%06x!\n", infoPtr->clrBk);
2840c2c66affSColin Finck
2841c2c66affSColin Finck return clrTemp;
2842c2c66affSColin Finck }
2843c2c66affSColin Finck
2844c2c66affSColin Finck
2845c2c66affSColin Finck /* << REBAR_SetColorScheme >> */
2846c2c66affSColin Finck /* << REBAR_SetPalette >> */
2847c2c66affSColin Finck
2848c2c66affSColin Finck
2849c2c66affSColin Finck static LRESULT
REBAR_SetParent(REBAR_INFO * infoPtr,HWND parent)2850c2c66affSColin Finck REBAR_SetParent (REBAR_INFO *infoPtr, HWND parent)
2851c2c66affSColin Finck {
2852c2c66affSColin Finck HWND hwndTemp = infoPtr->hwndNotify;
2853c2c66affSColin Finck
2854c2c66affSColin Finck infoPtr->hwndNotify = parent;
2855c2c66affSColin Finck
2856c2c66affSColin Finck return (LRESULT)hwndTemp;
2857c2c66affSColin Finck }
2858c2c66affSColin Finck
2859c2c66affSColin Finck
2860c2c66affSColin Finck static LRESULT
REBAR_SetTextColor(REBAR_INFO * infoPtr,COLORREF clr)2861c2c66affSColin Finck REBAR_SetTextColor (REBAR_INFO *infoPtr, COLORREF clr)
2862c2c66affSColin Finck {
2863c2c66affSColin Finck COLORREF clrTemp;
2864c2c66affSColin Finck
2865c2c66affSColin Finck clrTemp = infoPtr->clrText;
2866c2c66affSColin Finck infoPtr->clrText = clr;
2867c2c66affSColin Finck
2868c2c66affSColin Finck TRACE("text color 0x%06x!\n", infoPtr->clrText);
2869c2c66affSColin Finck
2870c2c66affSColin Finck return clrTemp;
2871c2c66affSColin Finck }
2872c2c66affSColin Finck
2873c2c66affSColin Finck
2874c2c66affSColin Finck /* << REBAR_SetTooltips >> */
2875c2c66affSColin Finck
2876c2c66affSColin Finck
2877c2c66affSColin Finck static inline LRESULT
REBAR_SetUnicodeFormat(REBAR_INFO * infoPtr,BOOL unicode)2878c2c66affSColin Finck REBAR_SetUnicodeFormat (REBAR_INFO *infoPtr, BOOL unicode)
2879c2c66affSColin Finck {
2880c2c66affSColin Finck BOOL bTemp = infoPtr->bUnicode;
2881c2c66affSColin Finck
2882c2c66affSColin Finck TRACE("to %s hwnd=%p, was %s\n",
2883c2c66affSColin Finck unicode ? "TRUE" : "FALSE", infoPtr->hwndSelf,
2884c2c66affSColin Finck (bTemp) ? "TRUE" : "FALSE");
2885c2c66affSColin Finck
2886c2c66affSColin Finck infoPtr->bUnicode = unicode;
2887c2c66affSColin Finck
2888c2c66affSColin Finck return bTemp;
2889c2c66affSColin Finck }
2890c2c66affSColin Finck
2891c2c66affSColin Finck
2892c2c66affSColin Finck static LRESULT
REBAR_SetVersion(REBAR_INFO * infoPtr,INT iVersion)2893c2c66affSColin Finck REBAR_SetVersion (REBAR_INFO *infoPtr, INT iVersion)
2894c2c66affSColin Finck {
2895c2c66affSColin Finck INT iOldVersion = infoPtr->iVersion;
2896c2c66affSColin Finck
2897c2c66affSColin Finck if (iVersion > COMCTL32_VERSION)
2898c2c66affSColin Finck return -1;
2899c2c66affSColin Finck
2900c2c66affSColin Finck infoPtr->iVersion = iVersion;
2901c2c66affSColin Finck
2902c2c66affSColin Finck TRACE("new version %d\n", iVersion);
2903c2c66affSColin Finck
2904c2c66affSColin Finck return iOldVersion;
2905c2c66affSColin Finck }
2906c2c66affSColin Finck
2907c2c66affSColin Finck
2908c2c66affSColin Finck static LRESULT
REBAR_ShowBand(REBAR_INFO * infoPtr,INT iBand,BOOL show)2909c2c66affSColin Finck REBAR_ShowBand (REBAR_INFO *infoPtr, INT iBand, BOOL show)
2910c2c66affSColin Finck {
2911c2c66affSColin Finck REBAR_BAND *lpBand;
2912c2c66affSColin Finck
2913c2c66affSColin Finck if (iBand < 0 || iBand >= infoPtr->uNumBands)
2914c2c66affSColin Finck return FALSE;
2915c2c66affSColin Finck
2916c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, iBand);
2917c2c66affSColin Finck
2918c2c66affSColin Finck if (show) {
2919c2c66affSColin Finck TRACE("show band %d\n", iBand);
2920c2c66affSColin Finck lpBand->fStyle = lpBand->fStyle & ~RBBS_HIDDEN;
2921c2c66affSColin Finck if (IsWindow (lpBand->hwndChild))
2922c2c66affSColin Finck ShowWindow (lpBand->hwndChild, SW_SHOW);
2923c2c66affSColin Finck }
2924c2c66affSColin Finck else {
2925c2c66affSColin Finck TRACE("hide band %d\n", iBand);
2926c2c66affSColin Finck lpBand->fStyle = lpBand->fStyle | RBBS_HIDDEN;
2927c2c66affSColin Finck if (IsWindow (lpBand->hwndChild))
2928c2c66affSColin Finck ShowWindow (lpBand->hwndChild, SW_HIDE);
2929c2c66affSColin Finck }
2930c2c66affSColin Finck
2931c2c66affSColin Finck REBAR_Layout(infoPtr);
2932c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
2933c2c66affSColin Finck
2934c2c66affSColin Finck return TRUE;
2935c2c66affSColin Finck }
2936c2c66affSColin Finck
2937c2c66affSColin Finck
2938c2c66affSColin Finck static LRESULT
2939c2c66affSColin Finck #ifdef __REACTOS__
REBAR_SizeToRect(REBAR_INFO * infoPtr,WPARAM flags,RECT * lpRect)2940c2c66affSColin Finck REBAR_SizeToRect (REBAR_INFO *infoPtr, WPARAM flags, RECT *lpRect)
2941c2c66affSColin Finck #else
2942c2c66affSColin Finck REBAR_SizeToRect (REBAR_INFO *infoPtr, const RECT *lpRect)
2943c2c66affSColin Finck #endif
2944c2c66affSColin Finck {
2945c2c66affSColin Finck if (!lpRect) return FALSE;
2946c2c66affSColin Finck
2947c2c66affSColin Finck TRACE("[%s]\n", wine_dbgstr_rect(lpRect));
2948c2c66affSColin Finck REBAR_SizeToHeight(infoPtr, get_rect_cy(infoPtr, lpRect));
2949c2c66affSColin Finck
2950c2c66affSColin Finck #ifdef __REACTOS__
2951c2c66affSColin Finck /* Note that this undocumented flag is available on comctl32 v6 or later */
2952c2c66affSColin Finck if ((flags & RBSTR_CHANGERECT) != 0)
2953c2c66affSColin Finck {
2954c2c66affSColin Finck RECT rcRebar;
2955c2c66affSColin Finck GetClientRect(infoPtr->hwndSelf, &rcRebar);
2956c2c66affSColin Finck lpRect->bottom = lpRect->top + (rcRebar.bottom - rcRebar.top);
2957c2c66affSColin Finck }
2958c2c66affSColin Finck #endif
2959c2c66affSColin Finck return TRUE;
2960c2c66affSColin Finck }
2961c2c66affSColin Finck
2962c2c66affSColin Finck
2963c2c66affSColin Finck
2964c2c66affSColin Finck static LRESULT
REBAR_Create(REBAR_INFO * infoPtr,LPCREATESTRUCTW cs)2965c2c66affSColin Finck REBAR_Create (REBAR_INFO *infoPtr, LPCREATESTRUCTW cs)
2966c2c66affSColin Finck {
2967c2c66affSColin Finck RECT wnrc1, clrc1;
2968c2c66affSColin Finck
2969c2c66affSColin Finck if (TRACE_ON(rebar)) {
2970c2c66affSColin Finck GetWindowRect(infoPtr->hwndSelf, &wnrc1);
2971c2c66affSColin Finck GetClientRect(infoPtr->hwndSelf, &clrc1);
2972c2c66affSColin Finck TRACE("window=(%s) client=(%s) cs=(%d,%d %dx%d)\n",
2973c2c66affSColin Finck wine_dbgstr_rect(&wnrc1), wine_dbgstr_rect(&clrc1),
2974c2c66affSColin Finck cs->x, cs->y, cs->cx, cs->cy);
2975c2c66affSColin Finck }
2976c2c66affSColin Finck
2977c2c66affSColin Finck TRACE("created!\n");
2978c2c66affSColin Finck
2979c2c66affSColin Finck if (OpenThemeData (infoPtr->hwndSelf, themeClass))
2980c2c66affSColin Finck {
2981c2c66affSColin Finck /* native seems to clear WS_BORDER when themed */
2982c2c66affSColin Finck infoPtr->dwStyle &= ~WS_BORDER;
2983c2c66affSColin Finck }
2984c2c66affSColin Finck
2985c2c66affSColin Finck return 0;
2986c2c66affSColin Finck }
2987c2c66affSColin Finck
2988c2c66affSColin Finck
2989c2c66affSColin Finck static LRESULT
REBAR_Destroy(REBAR_INFO * infoPtr)2990c2c66affSColin Finck REBAR_Destroy (REBAR_INFO *infoPtr)
2991c2c66affSColin Finck {
2992c2c66affSColin Finck REBAR_BAND *lpBand;
2993c2c66affSColin Finck UINT i;
2994c2c66affSColin Finck
2995c2c66affSColin Finck /* clean up each band */
2996c2c66affSColin Finck for (i = 0; i < infoPtr->uNumBands; i++) {
2997c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
2998c2c66affSColin Finck
2999c2c66affSColin Finck /* delete text strings */
3000c2c66affSColin Finck Free (lpBand->lpText);
3001c2c66affSColin Finck lpBand->lpText = NULL;
3002c2c66affSColin Finck /* destroy child window */
3003c2c66affSColin Finck DestroyWindow (lpBand->hwndChild);
3004c2c66affSColin Finck Free (lpBand);
3005c2c66affSColin Finck }
3006c2c66affSColin Finck
3007c2c66affSColin Finck /* free band array */
3008c2c66affSColin Finck DPA_Destroy (infoPtr->bands);
3009c2c66affSColin Finck infoPtr->bands = NULL;
3010c2c66affSColin Finck
3011c2c66affSColin Finck DestroyCursor (infoPtr->hcurArrow);
3012c2c66affSColin Finck DestroyCursor (infoPtr->hcurHorz);
3013c2c66affSColin Finck DestroyCursor (infoPtr->hcurVert);
3014c2c66affSColin Finck DestroyCursor (infoPtr->hcurDrag);
3015c2c66affSColin Finck if (infoPtr->hDefaultFont) DeleteObject (infoPtr->hDefaultFont);
3016c2c66affSColin Finck SetWindowLongPtrW (infoPtr->hwndSelf, 0, 0);
3017c2c66affSColin Finck
3018c2c66affSColin Finck CloseThemeData (GetWindowTheme (infoPtr->hwndSelf));
3019c2c66affSColin Finck
3020c2c66affSColin Finck /* free rebar info data */
3021c2c66affSColin Finck Free (infoPtr);
3022c2c66affSColin Finck TRACE("destroyed!\n");
3023c2c66affSColin Finck return 0;
3024c2c66affSColin Finck }
3025c2c66affSColin Finck
3026c2c66affSColin Finck static LRESULT
REBAR_GetFont(const REBAR_INFO * infoPtr)3027c2c66affSColin Finck REBAR_GetFont (const REBAR_INFO *infoPtr)
3028c2c66affSColin Finck {
3029c2c66affSColin Finck return (LRESULT)infoPtr->hFont;
3030c2c66affSColin Finck }
3031c2c66affSColin Finck
3032c2c66affSColin Finck static LRESULT
REBAR_PushChevron(const REBAR_INFO * infoPtr,UINT uBand,LPARAM lParam)3033c2c66affSColin Finck REBAR_PushChevron(const REBAR_INFO *infoPtr, UINT uBand, LPARAM lParam)
3034c2c66affSColin Finck {
3035c2c66affSColin Finck if (uBand < infoPtr->uNumBands)
3036c2c66affSColin Finck {
3037c2c66affSColin Finck NMREBARCHEVRON nmrbc;
3038c2c66affSColin Finck REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, uBand);
3039c2c66affSColin Finck
3040c2c66affSColin Finck TRACE("Pressed chevron on band %u\n", uBand);
3041c2c66affSColin Finck
3042c2c66affSColin Finck /* redraw chevron in pushed state */
3043c2c66affSColin Finck lpBand->fDraw |= DRAW_CHEVRONPUSHED;
3044c2c66affSColin Finck RedrawWindow(infoPtr->hwndSelf, &lpBand->rcChevron,0,
3045c2c66affSColin Finck RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3046c2c66affSColin Finck
3047c2c66affSColin Finck /* notify app so it can display a popup menu or whatever */
3048c2c66affSColin Finck nmrbc.uBand = uBand;
3049c2c66affSColin Finck nmrbc.wID = lpBand->wID;
3050c2c66affSColin Finck nmrbc.lParam = lpBand->lParam;
3051c2c66affSColin Finck nmrbc.rc = lpBand->rcChevron;
3052c2c66affSColin Finck nmrbc.lParamNM = lParam;
3053c2c66affSColin Finck REBAR_Notify((NMHDR*)&nmrbc, infoPtr, RBN_CHEVRONPUSHED);
3054c2c66affSColin Finck
3055c2c66affSColin Finck /* redraw chevron in previous state */
3056c2c66affSColin Finck lpBand->fDraw &= ~DRAW_CHEVRONPUSHED;
3057c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, &lpBand->rcChevron, TRUE);
3058c2c66affSColin Finck
3059c2c66affSColin Finck return TRUE;
3060c2c66affSColin Finck }
3061c2c66affSColin Finck return FALSE;
3062c2c66affSColin Finck }
3063c2c66affSColin Finck
3064c2c66affSColin Finck static LRESULT
REBAR_LButtonDown(REBAR_INFO * infoPtr,LPARAM lParam)3065c2c66affSColin Finck REBAR_LButtonDown (REBAR_INFO *infoPtr, LPARAM lParam)
3066c2c66affSColin Finck {
3067c2c66affSColin Finck UINT htFlags;
3068c2c66affSColin Finck INT iHitBand;
3069c2c66affSColin Finck POINT ptMouseDown;
3070c2c66affSColin Finck ptMouseDown.x = (short)LOWORD(lParam);
3071c2c66affSColin Finck ptMouseDown.y = (short)HIWORD(lParam);
3072c2c66affSColin Finck
3073c2c66affSColin Finck REBAR_InternalHitTest(infoPtr, &ptMouseDown, &htFlags, &iHitBand);
3074c2c66affSColin Finck
3075c2c66affSColin Finck if (htFlags == RBHT_CHEVRON)
3076c2c66affSColin Finck {
3077c2c66affSColin Finck REBAR_PushChevron(infoPtr, iHitBand, 0);
3078c2c66affSColin Finck }
3079c2c66affSColin Finck else if (htFlags == RBHT_GRABBER || htFlags == RBHT_CAPTION)
3080c2c66affSColin Finck {
3081c2c66affSColin Finck REBAR_BAND *lpBand;
3082c2c66affSColin Finck
3083c2c66affSColin Finck TRACE("Starting drag\n");
3084c2c66affSColin Finck
3085c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, iHitBand);
3086c2c66affSColin Finck
3087c2c66affSColin Finck SetCapture (infoPtr->hwndSelf);
3088c2c66affSColin Finck infoPtr->iGrabbedBand = iHitBand;
3089c2c66affSColin Finck
3090c2c66affSColin Finck /* save off the LOWORD and HIWORD of lParam as initial x,y */
3091c2c66affSColin Finck infoPtr->dragStart.x = (short)LOWORD(lParam);
3092c2c66affSColin Finck infoPtr->dragStart.y = (short)HIWORD(lParam);
3093c2c66affSColin Finck infoPtr->dragNow = infoPtr->dragStart;
3094c2c66affSColin Finck if (infoPtr->dwStyle & CCS_VERT)
3095c2c66affSColin Finck infoPtr->ihitoffset = infoPtr->dragStart.y - (lpBand->rcBand.left + REBAR_PRE_GRIPPER);
3096c2c66affSColin Finck else
3097c2c66affSColin Finck infoPtr->ihitoffset = infoPtr->dragStart.x - (lpBand->rcBand.left + REBAR_PRE_GRIPPER);
3098c2c66affSColin Finck }
3099c2c66affSColin Finck return 0;
3100c2c66affSColin Finck }
3101c2c66affSColin Finck
3102c2c66affSColin Finck static LRESULT
REBAR_LButtonUp(REBAR_INFO * infoPtr)3103c2c66affSColin Finck REBAR_LButtonUp (REBAR_INFO *infoPtr)
3104c2c66affSColin Finck {
3105c2c66affSColin Finck if (infoPtr->iGrabbedBand >= 0)
3106c2c66affSColin Finck {
3107c2c66affSColin Finck NMHDR layout;
3108c2c66affSColin Finck RECT rect;
3109c2c66affSColin Finck
3110c2c66affSColin Finck infoPtr->dragStart.x = 0;
3111c2c66affSColin Finck infoPtr->dragStart.y = 0;
3112c2c66affSColin Finck infoPtr->dragNow = infoPtr->dragStart;
3113c2c66affSColin Finck
3114c2c66affSColin Finck ReleaseCapture ();
3115c2c66affSColin Finck
3116c2c66affSColin Finck if (infoPtr->fStatus & BEGIN_DRAG_ISSUED) {
3117c2c66affSColin Finck REBAR_Notify(&layout, infoPtr, RBN_LAYOUTCHANGED);
3118c2c66affSColin Finck REBAR_Notify_NMREBAR (infoPtr, infoPtr->iGrabbedBand, RBN_ENDDRAG);
3119c2c66affSColin Finck infoPtr->fStatus &= ~BEGIN_DRAG_ISSUED;
3120c2c66affSColin Finck }
3121c2c66affSColin Finck
3122c2c66affSColin Finck infoPtr->iGrabbedBand = -1;
3123c2c66affSColin Finck
3124c2c66affSColin Finck GetClientRect(infoPtr->hwndSelf, &rect);
3125c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
3126c2c66affSColin Finck }
3127c2c66affSColin Finck
3128c2c66affSColin Finck return 0;
3129c2c66affSColin Finck }
3130c2c66affSColin Finck
3131c2c66affSColin Finck static LRESULT
REBAR_MouseLeave(REBAR_INFO * infoPtr)3132c2c66affSColin Finck REBAR_MouseLeave (REBAR_INFO *infoPtr)
3133c2c66affSColin Finck {
3134c2c66affSColin Finck if (infoPtr->ichevronhotBand >= 0)
3135c2c66affSColin Finck {
3136c2c66affSColin Finck REBAR_BAND *lpChevronBand = REBAR_GetBand(infoPtr, infoPtr->ichevronhotBand);
3137c2c66affSColin Finck if (lpChevronBand->fDraw & DRAW_CHEVRONHOT)
3138c2c66affSColin Finck {
3139c2c66affSColin Finck lpChevronBand->fDraw &= ~DRAW_CHEVRONHOT;
3140c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, &lpChevronBand->rcChevron, TRUE);
3141c2c66affSColin Finck }
3142c2c66affSColin Finck }
3143c2c66affSColin Finck infoPtr->iOldBand = -1;
3144c2c66affSColin Finck infoPtr->ichevronhotBand = -2;
3145c2c66affSColin Finck
3146c2c66affSColin Finck return TRUE;
3147c2c66affSColin Finck }
3148c2c66affSColin Finck
3149c2c66affSColin Finck static LRESULT
REBAR_MouseMove(REBAR_INFO * infoPtr,LPARAM lParam)3150c2c66affSColin Finck REBAR_MouseMove (REBAR_INFO *infoPtr, LPARAM lParam)
3151c2c66affSColin Finck {
3152c2c66affSColin Finck REBAR_BAND *lpChevronBand;
3153c2c66affSColin Finck POINT ptMove;
3154c2c66affSColin Finck
3155c2c66affSColin Finck ptMove.x = (short)LOWORD(lParam);
3156c2c66affSColin Finck ptMove.y = (short)HIWORD(lParam);
3157c2c66affSColin Finck
3158c2c66affSColin Finck /* if we are currently dragging a band */
3159c2c66affSColin Finck if (infoPtr->iGrabbedBand >= 0)
3160c2c66affSColin Finck {
3161c2c66affSColin Finck REBAR_BAND *band;
3162c2c66affSColin Finck int yPtMove = (infoPtr->dwStyle & CCS_VERT ? ptMove.x : ptMove.y);
3163c2c66affSColin Finck
3164c2c66affSColin Finck if (GetCapture() != infoPtr->hwndSelf)
3165c2c66affSColin Finck ERR("We are dragging but haven't got capture?!?\n");
3166c2c66affSColin Finck
3167c2c66affSColin Finck band = REBAR_GetBand(infoPtr, infoPtr->iGrabbedBand);
3168c2c66affSColin Finck
3169c2c66affSColin Finck /* if mouse did not move much, exit */
3170c2c66affSColin Finck if ((abs(ptMove.x - infoPtr->dragNow.x) <= mindragx) &&
3171c2c66affSColin Finck (abs(ptMove.y - infoPtr->dragNow.y) <= mindragy)) return 0;
3172c2c66affSColin Finck
3173c2c66affSColin Finck /* on first significant mouse movement, issue notify */
3174c2c66affSColin Finck if (!(infoPtr->fStatus & BEGIN_DRAG_ISSUED)) {
3175c2c66affSColin Finck if (REBAR_Notify_NMREBAR (infoPtr, -1, RBN_BEGINDRAG)) {
3176c2c66affSColin Finck /* Notify returned TRUE - abort drag */
3177c2c66affSColin Finck infoPtr->dragStart.x = 0;
3178c2c66affSColin Finck infoPtr->dragStart.y = 0;
3179c2c66affSColin Finck infoPtr->dragNow = infoPtr->dragStart;
3180c2c66affSColin Finck infoPtr->iGrabbedBand = -1;
3181c2c66affSColin Finck ReleaseCapture ();
3182c2c66affSColin Finck return 0;
3183c2c66affSColin Finck }
3184c2c66affSColin Finck infoPtr->fStatus |= BEGIN_DRAG_ISSUED;
3185c2c66affSColin Finck }
3186c2c66affSColin Finck
3187c2c66affSColin Finck /* Test for valid drag case - must not be first band in row */
3188c2c66affSColin Finck if ((yPtMove < band->rcBand.top) ||
3189c2c66affSColin Finck (yPtMove > band->rcBand.bottom)) {
3190c2c66affSColin Finck REBAR_HandleUDDrag (infoPtr, &ptMove);
3191c2c66affSColin Finck }
3192c2c66affSColin Finck else {
3193c2c66affSColin Finck REBAR_HandleLRDrag (infoPtr, &ptMove);
3194c2c66affSColin Finck }
3195c2c66affSColin Finck }
3196c2c66affSColin Finck else
3197c2c66affSColin Finck {
3198c2c66affSColin Finck INT iHitBand;
3199c2c66affSColin Finck UINT htFlags;
3200c2c66affSColin Finck TRACKMOUSEEVENT trackinfo;
3201c2c66affSColin Finck
3202c2c66affSColin Finck REBAR_InternalHitTest(infoPtr, &ptMove, &htFlags, &iHitBand);
3203c2c66affSColin Finck
3204c2c66affSColin Finck if (infoPtr->iOldBand >= 0 && infoPtr->iOldBand == infoPtr->ichevronhotBand)
3205c2c66affSColin Finck {
3206c2c66affSColin Finck lpChevronBand = REBAR_GetBand(infoPtr, infoPtr->ichevronhotBand);
3207c2c66affSColin Finck if (lpChevronBand->fDraw & DRAW_CHEVRONHOT)
3208c2c66affSColin Finck {
3209c2c66affSColin Finck lpChevronBand->fDraw &= ~DRAW_CHEVRONHOT;
3210c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, &lpChevronBand->rcChevron, TRUE);
3211c2c66affSColin Finck }
3212c2c66affSColin Finck infoPtr->ichevronhotBand = -2;
3213c2c66affSColin Finck }
3214c2c66affSColin Finck
3215c2c66affSColin Finck if (htFlags == RBHT_CHEVRON)
3216c2c66affSColin Finck {
3217c2c66affSColin Finck /* fill in the TRACKMOUSEEVENT struct */
3218c2c66affSColin Finck trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
3219c2c66affSColin Finck trackinfo.dwFlags = TME_QUERY;
3220c2c66affSColin Finck trackinfo.hwndTrack = infoPtr->hwndSelf;
3221c2c66affSColin Finck trackinfo.dwHoverTime = 0;
3222c2c66affSColin Finck
3223c2c66affSColin Finck /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
3224c2c66affSColin Finck _TrackMouseEvent(&trackinfo);
3225c2c66affSColin Finck
3226c2c66affSColin Finck /* Make sure tracking is enabled so we receive a WM_MOUSELEAVE message */
3227c2c66affSColin Finck if(!(trackinfo.dwFlags & TME_LEAVE))
3228c2c66affSColin Finck {
3229c2c66affSColin Finck trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
3230c2c66affSColin Finck
3231c2c66affSColin Finck /* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
3232c2c66affSColin Finck /* and can properly deactivate the hot chevron */
3233c2c66affSColin Finck _TrackMouseEvent(&trackinfo);
3234c2c66affSColin Finck }
3235c2c66affSColin Finck
3236c2c66affSColin Finck lpChevronBand = REBAR_GetBand(infoPtr, iHitBand);
3237c2c66affSColin Finck if (!(lpChevronBand->fDraw & DRAW_CHEVRONHOT))
3238c2c66affSColin Finck {
3239c2c66affSColin Finck lpChevronBand->fDraw |= DRAW_CHEVRONHOT;
3240c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, &lpChevronBand->rcChevron, TRUE);
3241c2c66affSColin Finck infoPtr->ichevronhotBand = iHitBand;
3242c2c66affSColin Finck }
3243c2c66affSColin Finck }
3244c2c66affSColin Finck infoPtr->iOldBand = iHitBand;
3245c2c66affSColin Finck }
3246c2c66affSColin Finck
3247c2c66affSColin Finck return 0;
3248c2c66affSColin Finck }
3249c2c66affSColin Finck
3250c2c66affSColin Finck
3251c2c66affSColin Finck static inline LRESULT
REBAR_NCCalcSize(const REBAR_INFO * infoPtr,RECT * rect)3252c2c66affSColin Finck REBAR_NCCalcSize (const REBAR_INFO *infoPtr, RECT *rect)
3253c2c66affSColin Finck {
3254c2c66affSColin Finck HTHEME theme;
3255c2c66affSColin Finck
3256c2c66affSColin Finck if (infoPtr->dwStyle & WS_BORDER) {
3257c2c66affSColin Finck rect->left = min(rect->left + GetSystemMetrics(SM_CXEDGE), rect->right);
3258c2c66affSColin Finck rect->right = max(rect->right - GetSystemMetrics(SM_CXEDGE), rect->left);
3259c2c66affSColin Finck rect->top = min(rect->top + GetSystemMetrics(SM_CYEDGE), rect->bottom);
3260c2c66affSColin Finck rect->bottom = max(rect->bottom - GetSystemMetrics(SM_CYEDGE), rect->top);
3261c2c66affSColin Finck }
3262c2c66affSColin Finck else if ((theme = GetWindowTheme (infoPtr->hwndSelf)))
3263c2c66affSColin Finck {
3264c2c66affSColin Finck /* FIXME: should use GetThemeInt */
3265c2c66affSColin Finck #ifdef __REACTOS__
3266c2c66affSColin Finck rect->top = (rect->top + 1 < rect->bottom) ? rect->top : rect->bottom;
3267c2c66affSColin Finck #else
3268c2c66affSColin Finck rect->top = min(rect->top + 1, rect->bottom);
3269c2c66affSColin Finck #endif
3270c2c66affSColin Finck }
3271c2c66affSColin Finck TRACE("new client=(%s)\n", wine_dbgstr_rect(rect));
3272c2c66affSColin Finck return 0;
3273c2c66affSColin Finck }
3274c2c66affSColin Finck
3275c2c66affSColin Finck
3276c2c66affSColin Finck static LRESULT
REBAR_NCCreate(HWND hwnd,const CREATESTRUCTW * cs)3277c2c66affSColin Finck REBAR_NCCreate (HWND hwnd, const CREATESTRUCTW *cs)
3278c2c66affSColin Finck {
3279c2c66affSColin Finck REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
3280c2c66affSColin Finck RECT wnrc1, clrc1;
3281c2c66affSColin Finck NONCLIENTMETRICSW ncm;
3282c2c66affSColin Finck HFONT tfont;
3283c2c66affSColin Finck
3284c2c66affSColin Finck if (infoPtr) {
3285c2c66affSColin Finck ERR("Strange info structure pointer *not* NULL\n");
3286c2c66affSColin Finck return FALSE;
3287c2c66affSColin Finck }
3288c2c66affSColin Finck
3289c2c66affSColin Finck if (TRACE_ON(rebar)) {
3290c2c66affSColin Finck GetWindowRect(hwnd, &wnrc1);
3291c2c66affSColin Finck GetClientRect(hwnd, &clrc1);
3292c2c66affSColin Finck TRACE("window=(%s) client=(%s) cs=(%d,%d %dx%d)\n",
3293c2c66affSColin Finck wine_dbgstr_rect(&wnrc1), wine_dbgstr_rect(&clrc1),
3294c2c66affSColin Finck cs->x, cs->y, cs->cx, cs->cy);
3295c2c66affSColin Finck }
3296c2c66affSColin Finck
3297c2c66affSColin Finck /* allocate memory for info structure */
3298c2c66affSColin Finck infoPtr = Alloc (sizeof(REBAR_INFO));
3299c2c66affSColin Finck SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
3300c2c66affSColin Finck
3301c2c66affSColin Finck /* initialize info structure - initial values are 0 */
3302c2c66affSColin Finck infoPtr->clrBk = CLR_NONE;
3303c2c66affSColin Finck infoPtr->clrText = CLR_NONE;
3304c2c66affSColin Finck infoPtr->clrBtnText = comctl32_color.clrBtnText;
3305c2c66affSColin Finck infoPtr->clrBtnFace = comctl32_color.clrBtnFace;
3306c2c66affSColin Finck infoPtr->iOldBand = -1;
3307c2c66affSColin Finck infoPtr->ichevronhotBand = -2;
3308c2c66affSColin Finck infoPtr->iGrabbedBand = -1;
3309c2c66affSColin Finck infoPtr->hwndSelf = hwnd;
3310c2c66affSColin Finck infoPtr->DoRedraw = TRUE;
3311c2c66affSColin Finck infoPtr->hcurArrow = LoadCursorW (0, (LPWSTR)IDC_ARROW);
3312c2c66affSColin Finck infoPtr->hcurHorz = LoadCursorW (0, (LPWSTR)IDC_SIZEWE);
3313c2c66affSColin Finck infoPtr->hcurVert = LoadCursorW (0, (LPWSTR)IDC_SIZENS);
3314c2c66affSColin Finck infoPtr->hcurDrag = LoadCursorW (0, (LPWSTR)IDC_SIZE);
3315c2c66affSColin Finck infoPtr->fStatus = 0;
3316c2c66affSColin Finck infoPtr->hFont = GetStockObject (SYSTEM_FONT);
3317c2c66affSColin Finck infoPtr->bands = DPA_Create(8);
3318c2c66affSColin Finck
3319c2c66affSColin Finck /* issue WM_NOTIFYFORMAT to get unicode status of parent */
3320c2c66affSColin Finck REBAR_NotifyFormat(infoPtr, NF_REQUERY);
3321c2c66affSColin Finck
3322c2c66affSColin Finck /* Stow away the original style */
3323c2c66affSColin Finck infoPtr->orgStyle = cs->style;
3324c2c66affSColin Finck /* add necessary styles to the requested styles */
3325c2c66affSColin Finck infoPtr->dwStyle = cs->style | WS_VISIBLE;
3326c2c66affSColin Finck if ((infoPtr->dwStyle & CCS_LAYOUT_MASK) == 0)
3327c2c66affSColin Finck infoPtr->dwStyle |= CCS_TOP;
3328c2c66affSColin Finck SetWindowLongW (hwnd, GWL_STYLE, infoPtr->dwStyle);
3329c2c66affSColin Finck
3330c2c66affSColin Finck /* get font handle for Caption Font */
3331c2c66affSColin Finck ncm.cbSize = sizeof(ncm);
3332c2c66affSColin Finck SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
3333c2c66affSColin Finck /* if the font is bold, set to normal */
3334c2c66affSColin Finck if (ncm.lfCaptionFont.lfWeight > FW_NORMAL) {
3335c2c66affSColin Finck ncm.lfCaptionFont.lfWeight = FW_NORMAL;
3336c2c66affSColin Finck }
3337c2c66affSColin Finck tfont = CreateFontIndirectW (&ncm.lfCaptionFont);
3338c2c66affSColin Finck if (tfont) {
3339c2c66affSColin Finck infoPtr->hFont = infoPtr->hDefaultFont = tfont;
3340c2c66affSColin Finck }
3341c2c66affSColin Finck
3342c2c66affSColin Finck return TRUE;
3343c2c66affSColin Finck }
3344c2c66affSColin Finck
3345c2c66affSColin Finck
3346c2c66affSColin Finck static LRESULT
REBAR_NCHitTest(const REBAR_INFO * infoPtr,LPARAM lParam)3347c2c66affSColin Finck REBAR_NCHitTest (const REBAR_INFO *infoPtr, LPARAM lParam)
3348c2c66affSColin Finck {
3349c2c66affSColin Finck NMMOUSE nmmouse;
3350c2c66affSColin Finck POINT clpt;
3351c2c66affSColin Finck INT i;
3352c2c66affSColin Finck UINT scrap;
3353c2c66affSColin Finck LRESULT ret = HTCLIENT;
3354c2c66affSColin Finck
3355c2c66affSColin Finck /*
3356c2c66affSColin Finck * Differences from doc at MSDN (as observed with version 4.71 of
3357c2c66affSColin Finck * comctl32.dll
3358c2c66affSColin Finck * 1. doc says nmmouse.pt is in screen coord, trace shows client coord.
3359c2c66affSColin Finck * 2. if band is not identified .dwItemSpec is 0xffffffff.
3360c2c66affSColin Finck * 3. native always seems to return HTCLIENT if notify return is 0.
3361c2c66affSColin Finck */
3362c2c66affSColin Finck
3363c2c66affSColin Finck clpt.x = (short)LOWORD(lParam);
3364c2c66affSColin Finck clpt.y = (short)HIWORD(lParam);
3365c2c66affSColin Finck ScreenToClient (infoPtr->hwndSelf, &clpt);
3366c2c66affSColin Finck REBAR_InternalHitTest (infoPtr, &clpt, &scrap,
3367c2c66affSColin Finck (INT *)&nmmouse.dwItemSpec);
3368c2c66affSColin Finck nmmouse.dwItemData = 0;
3369c2c66affSColin Finck nmmouse.pt = clpt;
3370c2c66affSColin Finck #ifdef __REACTOS__
3371c2c66affSColin Finck nmmouse.dwHitInfo = scrap;
3372c2c66affSColin Finck #else
3373c2c66affSColin Finck nmmouse.dwHitInfo = 0;
3374c2c66affSColin Finck #endif
3375c2c66affSColin Finck if ((i = REBAR_Notify((NMHDR *) &nmmouse, infoPtr, NM_NCHITTEST))) {
3376c2c66affSColin Finck TRACE("notify changed return value from %ld to %d\n",
3377c2c66affSColin Finck ret, i);
3378c2c66affSColin Finck ret = (LRESULT) i;
3379c2c66affSColin Finck }
3380c2c66affSColin Finck TRACE("returning %ld, client point %s\n", ret, wine_dbgstr_point(&clpt));
3381c2c66affSColin Finck return ret;
3382c2c66affSColin Finck }
3383c2c66affSColin Finck
3384c2c66affSColin Finck
3385c2c66affSColin Finck static LRESULT
REBAR_NCPaint(const REBAR_INFO * infoPtr)3386c2c66affSColin Finck REBAR_NCPaint (const REBAR_INFO *infoPtr)
3387c2c66affSColin Finck {
3388c2c66affSColin Finck RECT rcWindow;
3389c2c66affSColin Finck HDC hdc;
3390c2c66affSColin Finck HTHEME theme;
3391c2c66affSColin Finck
3392c2c66affSColin Finck if (infoPtr->dwStyle & WS_MINIMIZE)
3393c2c66affSColin Finck return 0; /* Nothing to do */
3394c2c66affSColin Finck
3395c2c66affSColin Finck if (infoPtr->dwStyle & WS_BORDER) {
3396c2c66affSColin Finck
3397c2c66affSColin Finck /* adjust rectangle and draw the necessary edge */
3398c2c66affSColin Finck if (!(hdc = GetDCEx( infoPtr->hwndSelf, 0, DCX_USESTYLE | DCX_WINDOW )))
3399c2c66affSColin Finck return 0;
3400c2c66affSColin Finck GetWindowRect (infoPtr->hwndSelf, &rcWindow);
3401c2c66affSColin Finck OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3402c2c66affSColin Finck TRACE("rect (%s)\n", wine_dbgstr_rect(&rcWindow));
3403c2c66affSColin Finck DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_RECT);
3404c2c66affSColin Finck ReleaseDC( infoPtr->hwndSelf, hdc );
3405c2c66affSColin Finck }
3406c2c66affSColin Finck else if ((theme = GetWindowTheme (infoPtr->hwndSelf)))
3407c2c66affSColin Finck {
3408c2c66affSColin Finck /* adjust rectangle and draw the necessary edge */
3409c2c66affSColin Finck if (!(hdc = GetDCEx( infoPtr->hwndSelf, 0, DCX_USESTYLE | DCX_WINDOW )))
3410c2c66affSColin Finck return 0;
3411c2c66affSColin Finck GetWindowRect (infoPtr->hwndSelf, &rcWindow);
3412c2c66affSColin Finck OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3413c2c66affSColin Finck TRACE("rect (%s)\n", wine_dbgstr_rect(&rcWindow));
3414c2c66affSColin Finck DrawThemeEdge (theme, hdc, 0, 0, &rcWindow, BDR_RAISEDINNER, BF_TOP, NULL);
3415c2c66affSColin Finck ReleaseDC( infoPtr->hwndSelf, hdc );
3416c2c66affSColin Finck }
3417c2c66affSColin Finck
3418c2c66affSColin Finck return 0;
3419c2c66affSColin Finck }
3420c2c66affSColin Finck
3421c2c66affSColin Finck
3422c2c66affSColin Finck static LRESULT
REBAR_NotifyFormat(REBAR_INFO * infoPtr,LPARAM cmd)3423c2c66affSColin Finck REBAR_NotifyFormat (REBAR_INFO *infoPtr, LPARAM cmd)
3424c2c66affSColin Finck {
3425c2c66affSColin Finck INT i;
3426c2c66affSColin Finck
3427c2c66affSColin Finck if (cmd == NF_REQUERY) {
3428c2c66affSColin Finck i = SendMessageW(REBAR_GetNotifyParent (infoPtr),
3429c2c66affSColin Finck WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, NF_QUERY);
3430c2c66affSColin Finck if ((i != NFR_ANSI) && (i != NFR_UNICODE)) {
3431c2c66affSColin Finck ERR("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n", i);
3432c2c66affSColin Finck i = NFR_ANSI;
3433c2c66affSColin Finck }
3434c2c66affSColin Finck infoPtr->bUnicode = (i == NFR_UNICODE);
3435c2c66affSColin Finck return (LRESULT)i;
3436c2c66affSColin Finck }
3437c2c66affSColin Finck return (LRESULT)((infoPtr->bUnicode) ? NFR_UNICODE : NFR_ANSI);
3438c2c66affSColin Finck }
3439c2c66affSColin Finck
3440c2c66affSColin Finck
3441c2c66affSColin Finck static LRESULT
REBAR_Paint(const REBAR_INFO * infoPtr,HDC hdc)3442c2c66affSColin Finck REBAR_Paint (const REBAR_INFO *infoPtr, HDC hdc)
3443c2c66affSColin Finck {
3444c2c66affSColin Finck if (hdc) {
3445c2c66affSColin Finck TRACE("painting\n");
3446c2c66affSColin Finck #ifdef __REACTOS__
3447c2c66affSColin Finck REBAR_EraseBkGnd (infoPtr, hdc);
3448c2c66affSColin Finck #endif
3449c2c66affSColin Finck REBAR_Refresh (infoPtr, hdc);
3450c2c66affSColin Finck } else {
3451c2c66affSColin Finck PAINTSTRUCT ps;
3452c2c66affSColin Finck hdc = BeginPaint (infoPtr->hwndSelf, &ps);
3453c2c66affSColin Finck TRACE("painting (%s)\n", wine_dbgstr_rect(&ps.rcPaint));
3454c2c66affSColin Finck if (ps.fErase) {
3455c2c66affSColin Finck /* Erase area of paint if requested */
3456c2c66affSColin Finck REBAR_EraseBkGnd (infoPtr, hdc);
3457c2c66affSColin Finck }
3458c2c66affSColin Finck REBAR_Refresh (infoPtr, hdc);
3459c2c66affSColin Finck EndPaint (infoPtr->hwndSelf, &ps);
3460c2c66affSColin Finck }
3461c2c66affSColin Finck
3462c2c66affSColin Finck return 0;
3463c2c66affSColin Finck }
3464c2c66affSColin Finck
3465c2c66affSColin Finck
3466c2c66affSColin Finck static LRESULT
REBAR_SetCursor(const REBAR_INFO * infoPtr,LPARAM lParam)3467c2c66affSColin Finck REBAR_SetCursor (const REBAR_INFO *infoPtr, LPARAM lParam)
3468c2c66affSColin Finck {
3469c2c66affSColin Finck POINT pt;
3470c2c66affSColin Finck UINT flags;
3471c2c66affSColin Finck
3472c2c66affSColin Finck TRACE("code=0x%X id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
3473c2c66affSColin Finck
3474c2c66affSColin Finck GetCursorPos (&pt);
3475c2c66affSColin Finck ScreenToClient (infoPtr->hwndSelf, &pt);
3476c2c66affSColin Finck
3477c2c66affSColin Finck REBAR_InternalHitTest (infoPtr, &pt, &flags, NULL);
3478c2c66affSColin Finck
3479c2c66affSColin Finck if (flags == RBHT_GRABBER) {
3480c2c66affSColin Finck if ((infoPtr->dwStyle & CCS_VERT) &&
3481c2c66affSColin Finck !(infoPtr->dwStyle & RBS_VERTICALGRIPPER))
3482c2c66affSColin Finck SetCursor (infoPtr->hcurVert);
3483c2c66affSColin Finck else
3484c2c66affSColin Finck SetCursor (infoPtr->hcurHorz);
3485c2c66affSColin Finck }
3486c2c66affSColin Finck else if (flags != RBHT_CLIENT)
3487c2c66affSColin Finck SetCursor (infoPtr->hcurArrow);
3488c2c66affSColin Finck
3489c2c66affSColin Finck return 0;
3490c2c66affSColin Finck }
3491c2c66affSColin Finck
3492c2c66affSColin Finck
3493c2c66affSColin Finck static LRESULT
REBAR_SetFont(REBAR_INFO * infoPtr,HFONT font)3494c2c66affSColin Finck REBAR_SetFont (REBAR_INFO *infoPtr, HFONT font)
3495c2c66affSColin Finck {
3496c2c66affSColin Finck REBAR_BAND *lpBand;
3497c2c66affSColin Finck UINT i;
3498c2c66affSColin Finck
3499c2c66affSColin Finck infoPtr->hFont = font;
3500c2c66affSColin Finck
3501c2c66affSColin Finck /* revalidate all bands to change sizes of text in headers of bands */
3502c2c66affSColin Finck for (i=0; i<infoPtr->uNumBands; i++) {
3503c2c66affSColin Finck lpBand = REBAR_GetBand(infoPtr, i);
3504c2c66affSColin Finck REBAR_ValidateBand (infoPtr, lpBand);
3505c2c66affSColin Finck }
3506c2c66affSColin Finck
3507c2c66affSColin Finck REBAR_Layout(infoPtr);
3508c2c66affSColin Finck return 0;
3509c2c66affSColin Finck }
3510c2c66affSColin Finck
3511c2c66affSColin Finck
3512c2c66affSColin Finck /*****************************************************
3513c2c66affSColin Finck *
3514c2c66affSColin Finck * Handles the WM_SETREDRAW message.
3515c2c66affSColin Finck *
3516c2c66affSColin Finck * Documentation:
3517c2c66affSColin Finck * According to testing V4.71 of COMCTL32 returns the
3518c2c66affSColin Finck * *previous* status of the redraw flag (either 0 or -1)
3519c2c66affSColin Finck * instead of the MSDN documented value of 0 if handled
3520c2c66affSColin Finck *
3521c2c66affSColin Finck *****************************************************/
3522c2c66affSColin Finck static inline LRESULT
REBAR_SetRedraw(REBAR_INFO * infoPtr,BOOL redraw)3523c2c66affSColin Finck REBAR_SetRedraw (REBAR_INFO *infoPtr, BOOL redraw)
3524c2c66affSColin Finck {
3525c2c66affSColin Finck BOOL oldredraw = infoPtr->DoRedraw;
3526c2c66affSColin Finck
3527c2c66affSColin Finck TRACE("set to %s, fStatus=%08x\n",
3528c2c66affSColin Finck (redraw) ? "TRUE" : "FALSE", infoPtr->fStatus);
3529c2c66affSColin Finck infoPtr->DoRedraw = redraw;
3530c2c66affSColin Finck if (redraw) {
3531c2c66affSColin Finck if (infoPtr->fStatus & BAND_NEEDS_REDRAW) {
3532c2c66affSColin Finck REBAR_MoveChildWindows (infoPtr, 0, infoPtr->uNumBands);
3533c2c66affSColin Finck REBAR_ForceResize (infoPtr);
3534c2c66affSColin Finck InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
3535c2c66affSColin Finck }
3536c2c66affSColin Finck infoPtr->fStatus &= ~BAND_NEEDS_REDRAW;
3537c2c66affSColin Finck }
3538c2c66affSColin Finck return (oldredraw) ? -1 : 0;
3539c2c66affSColin Finck }
3540c2c66affSColin Finck
3541c2c66affSColin Finck
3542c2c66affSColin Finck static LRESULT
REBAR_Size(REBAR_INFO * infoPtr,WPARAM wParam,LPARAM lParam)3543c2c66affSColin Finck REBAR_Size (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
3544c2c66affSColin Finck {
3545c2c66affSColin Finck TRACE("wParam=%lx, lParam=%lx\n", wParam, lParam);
3546c2c66affSColin Finck
3547c2c66affSColin Finck /* avoid _Layout resize recursion (but it shouldn't be infinite and it seems Windows does recurse) */
3548c2c66affSColin Finck if (infoPtr->fStatus & SELF_RESIZE) {
3549c2c66affSColin Finck infoPtr->fStatus &= ~SELF_RESIZE;
3550c2c66affSColin Finck TRACE("SELF_RESIZE was set, reset, fStatus=%08x lparam=%08lx\n",
3551c2c66affSColin Finck infoPtr->fStatus, lParam);
3552c2c66affSColin Finck return 0;
3553c2c66affSColin Finck }
3554c2c66affSColin Finck
3555c2c66affSColin Finck if (infoPtr->dwStyle & RBS_AUTOSIZE)
3556c2c66affSColin Finck REBAR_AutoSize(infoPtr, TRUE);
3557c2c66affSColin Finck else
3558c2c66affSColin Finck REBAR_Layout(infoPtr);
3559c2c66affSColin Finck
3560c2c66affSColin Finck return 0;
3561c2c66affSColin Finck }
3562c2c66affSColin Finck
3563c2c66affSColin Finck
3564c2c66affSColin Finck static LRESULT
REBAR_StyleChanged(REBAR_INFO * infoPtr,INT nType,const STYLESTRUCT * lpStyle)3565c2c66affSColin Finck REBAR_StyleChanged (REBAR_INFO *infoPtr, INT nType, const STYLESTRUCT *lpStyle)
3566c2c66affSColin Finck {
3567c2c66affSColin Finck TRACE("current style=%08x, styleOld=%08x, style being set to=%08x\n",
3568c2c66affSColin Finck infoPtr->dwStyle, lpStyle->styleOld, lpStyle->styleNew);
3569c2c66affSColin Finck if (nType == GWL_STYLE)
3570c2c66affSColin Finck {
3571c2c66affSColin Finck infoPtr->orgStyle = infoPtr->dwStyle = lpStyle->styleNew;
3572c2c66affSColin Finck if (GetWindowTheme (infoPtr->hwndSelf))
3573c2c66affSColin Finck infoPtr->dwStyle &= ~WS_BORDER;
3574c2c66affSColin Finck /* maybe it should be COMMON_STYLES like in toolbar */
3575c2c66affSColin Finck if ((lpStyle->styleNew ^ lpStyle->styleOld) & CCS_VERT)
3576c2c66affSColin Finck REBAR_Layout(infoPtr);
3577c2c66affSColin Finck }
3578c2c66affSColin Finck return FALSE;
3579c2c66affSColin Finck }
3580c2c66affSColin Finck
3581c2c66affSColin Finck /* update theme after a WM_THEMECHANGED message */
theme_changed(REBAR_INFO * infoPtr)3582c2c66affSColin Finck static LRESULT theme_changed (REBAR_INFO* infoPtr)
3583c2c66affSColin Finck {
3584c2c66affSColin Finck HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
3585c2c66affSColin Finck CloseThemeData (theme);
3586c2c66affSColin Finck theme = OpenThemeData (infoPtr->hwndSelf, themeClass);
3587c2c66affSColin Finck /* WS_BORDER disappears when theming is enabled and reappears when
3588c2c66affSColin Finck * disabled... */
3589c2c66affSColin Finck infoPtr->dwStyle &= ~WS_BORDER;
3590c2c66affSColin Finck infoPtr->dwStyle |= theme ? 0 : (infoPtr->orgStyle & WS_BORDER);
3591c2c66affSColin Finck return 0;
3592c2c66affSColin Finck }
3593c2c66affSColin Finck
3594c2c66affSColin Finck static LRESULT
REBAR_WindowPosChanged(const REBAR_INFO * infoPtr,WPARAM wParam,LPARAM lParam)3595c2c66affSColin Finck REBAR_WindowPosChanged (const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
3596c2c66affSColin Finck {
3597c2c66affSColin Finck LRESULT ret;
3598c2c66affSColin Finck RECT rc;
3599c2c66affSColin Finck
3600c2c66affSColin Finck ret = DefWindowProcW(infoPtr->hwndSelf, WM_WINDOWPOSCHANGED,
3601c2c66affSColin Finck wParam, lParam);
3602c2c66affSColin Finck GetWindowRect(infoPtr->hwndSelf, &rc);
3603c2c66affSColin Finck TRACE("hwnd %p new pos (%s)\n", infoPtr->hwndSelf, wine_dbgstr_rect(&rc));
3604c2c66affSColin Finck return ret;
3605c2c66affSColin Finck }
3606c2c66affSColin Finck
3607c2c66affSColin Finck
3608c2c66affSColin Finck static LRESULT WINAPI
REBAR_WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)3609c2c66affSColin Finck REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3610c2c66affSColin Finck {
3611c2c66affSColin Finck REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
3612c2c66affSColin Finck
3613c2c66affSColin Finck TRACE("hwnd=%p msg=%x wparam=%lx lparam=%lx\n",
3614c2c66affSColin Finck hwnd, uMsg, wParam, lParam);
3615c2c66affSColin Finck if (!infoPtr && (uMsg != WM_NCCREATE))
3616c2c66affSColin Finck return DefWindowProcW (hwnd, uMsg, wParam, lParam);
3617c2c66affSColin Finck switch (uMsg)
3618c2c66affSColin Finck {
3619c2c66affSColin Finck /* case RB_BEGINDRAG: */
3620c2c66affSColin Finck
3621c2c66affSColin Finck case RB_DELETEBAND:
3622c2c66affSColin Finck return REBAR_DeleteBand (infoPtr, wParam);
3623c2c66affSColin Finck
3624c2c66affSColin Finck /* case RB_DRAGMOVE: */
3625c2c66affSColin Finck /* case RB_ENDDRAG: */
3626c2c66affSColin Finck
3627c2c66affSColin Finck case RB_GETBANDBORDERS:
3628c2c66affSColin Finck return REBAR_GetBandBorders (infoPtr, wParam, (LPRECT)lParam);
3629c2c66affSColin Finck
3630c2c66affSColin Finck case RB_GETBANDCOUNT:
3631c2c66affSColin Finck return REBAR_GetBandCount (infoPtr);
3632c2c66affSColin Finck
3633c2c66affSColin Finck case RB_GETBANDINFO_OLD:
3634c2c66affSColin Finck case RB_GETBANDINFOA:
3635c2c66affSColin Finck case RB_GETBANDINFOW:
3636c2c66affSColin Finck return REBAR_GetBandInfoT(infoPtr, wParam, (LPREBARBANDINFOW)lParam,
3637c2c66affSColin Finck uMsg == RB_GETBANDINFOW);
3638c2c66affSColin Finck case RB_GETBARHEIGHT:
3639c2c66affSColin Finck return REBAR_GetBarHeight (infoPtr);
3640c2c66affSColin Finck
3641c2c66affSColin Finck case RB_GETBARINFO:
3642c2c66affSColin Finck return REBAR_GetBarInfo (infoPtr, (LPREBARINFO)lParam);
3643c2c66affSColin Finck
3644c2c66affSColin Finck case RB_GETBKCOLOR:
3645c2c66affSColin Finck return REBAR_GetBkColor (infoPtr);
3646c2c66affSColin Finck
3647c2c66affSColin Finck /* case RB_GETCOLORSCHEME: */
3648c2c66affSColin Finck /* case RB_GETDROPTARGET: */
3649c2c66affSColin Finck
3650c2c66affSColin Finck case RB_GETPALETTE:
3651c2c66affSColin Finck return REBAR_GetPalette (infoPtr);
3652c2c66affSColin Finck
3653c2c66affSColin Finck case RB_GETRECT:
3654c2c66affSColin Finck return REBAR_GetRect (infoPtr, wParam, (LPRECT)lParam);
3655c2c66affSColin Finck
3656c2c66affSColin Finck case RB_GETROWCOUNT:
3657c2c66affSColin Finck return REBAR_GetRowCount (infoPtr);
3658c2c66affSColin Finck
3659c2c66affSColin Finck case RB_GETROWHEIGHT:
3660c2c66affSColin Finck return REBAR_GetRowHeight (infoPtr, wParam);
3661c2c66affSColin Finck
3662c2c66affSColin Finck case RB_GETTEXTCOLOR:
3663c2c66affSColin Finck return REBAR_GetTextColor (infoPtr);
3664c2c66affSColin Finck
3665c2c66affSColin Finck case RB_GETTOOLTIPS:
3666c2c66affSColin Finck return REBAR_GetToolTips (infoPtr);
3667c2c66affSColin Finck
3668c2c66affSColin Finck case RB_GETUNICODEFORMAT:
3669c2c66affSColin Finck return REBAR_GetUnicodeFormat (infoPtr);
3670c2c66affSColin Finck
3671c2c66affSColin Finck case CCM_GETVERSION:
3672c2c66affSColin Finck return REBAR_GetVersion (infoPtr);
3673c2c66affSColin Finck
3674c2c66affSColin Finck case RB_HITTEST:
3675c2c66affSColin Finck return REBAR_HitTest (infoPtr, (LPRBHITTESTINFO)lParam);
3676c2c66affSColin Finck
3677c2c66affSColin Finck case RB_IDTOINDEX:
3678c2c66affSColin Finck return REBAR_IdToIndex (infoPtr, wParam);
3679c2c66affSColin Finck
3680c2c66affSColin Finck case RB_INSERTBANDA:
3681c2c66affSColin Finck case RB_INSERTBANDW:
3682c2c66affSColin Finck return REBAR_InsertBandT(infoPtr, wParam, (LPREBARBANDINFOW)lParam,
3683c2c66affSColin Finck uMsg == RB_INSERTBANDW);
3684c2c66affSColin Finck case RB_MAXIMIZEBAND:
3685c2c66affSColin Finck return REBAR_MaximizeBand (infoPtr, wParam, lParam);
3686c2c66affSColin Finck
3687c2c66affSColin Finck case RB_MINIMIZEBAND:
3688c2c66affSColin Finck return REBAR_MinimizeBand (infoPtr, wParam);
3689c2c66affSColin Finck
3690c2c66affSColin Finck case RB_MOVEBAND:
3691c2c66affSColin Finck return REBAR_MoveBand (infoPtr, wParam, lParam);
3692c2c66affSColin Finck
3693c2c66affSColin Finck case RB_PUSHCHEVRON:
3694c2c66affSColin Finck return REBAR_PushChevron (infoPtr, wParam, lParam);
3695c2c66affSColin Finck
3696c2c66affSColin Finck case RB_SETBANDINFOA:
3697c2c66affSColin Finck case RB_SETBANDINFOW:
3698c2c66affSColin Finck return REBAR_SetBandInfoT(infoPtr, wParam, (LPREBARBANDINFOW)lParam,
3699c2c66affSColin Finck uMsg == RB_SETBANDINFOW);
3700c2c66affSColin Finck case RB_SETBARINFO:
3701c2c66affSColin Finck return REBAR_SetBarInfo (infoPtr, (LPREBARINFO)lParam);
3702c2c66affSColin Finck
3703c2c66affSColin Finck case RB_SETBKCOLOR:
3704c2c66affSColin Finck return REBAR_SetBkColor (infoPtr, lParam);
3705c2c66affSColin Finck
3706c2c66affSColin Finck /* case RB_SETCOLORSCHEME: */
3707c2c66affSColin Finck /* case RB_SETPALETTE: */
3708c2c66affSColin Finck
3709c2c66affSColin Finck case RB_SETPARENT:
3710c2c66affSColin Finck return REBAR_SetParent (infoPtr, (HWND)wParam);
3711c2c66affSColin Finck
3712c2c66affSColin Finck case RB_SETTEXTCOLOR:
3713c2c66affSColin Finck return REBAR_SetTextColor (infoPtr, lParam);
3714c2c66affSColin Finck
3715c2c66affSColin Finck /* case RB_SETTOOLTIPS: */
3716c2c66affSColin Finck
3717c2c66affSColin Finck case RB_SETUNICODEFORMAT:
3718c2c66affSColin Finck return REBAR_SetUnicodeFormat (infoPtr, wParam);
3719c2c66affSColin Finck
3720c2c66affSColin Finck case CCM_SETVERSION:
3721c2c66affSColin Finck return REBAR_SetVersion (infoPtr, (INT)wParam);
3722c2c66affSColin Finck
3723c2c66affSColin Finck case RB_SHOWBAND:
3724c2c66affSColin Finck return REBAR_ShowBand (infoPtr, wParam, lParam);
3725c2c66affSColin Finck
3726c2c66affSColin Finck case RB_SIZETORECT:
3727c2c66affSColin Finck #ifdef __REACTOS__
3728c2c66affSColin Finck return REBAR_SizeToRect (infoPtr, wParam, (LPRECT)lParam);
3729c2c66affSColin Finck #else
3730c2c66affSColin Finck return REBAR_SizeToRect (infoPtr, (LPCRECT)lParam);
3731c2c66affSColin Finck #endif
3732c2c66affSColin Finck
3733c2c66affSColin Finck
3734c2c66affSColin Finck /* Messages passed to parent */
3735c2c66affSColin Finck case WM_COMMAND:
3736c2c66affSColin Finck case WM_DRAWITEM:
3737c2c66affSColin Finck case WM_NOTIFY:
3738c2c66affSColin Finck case WM_MEASUREITEM:
3739c2c66affSColin Finck return SendMessageW(REBAR_GetNotifyParent (infoPtr), uMsg, wParam, lParam);
3740c2c66affSColin Finck
3741c2c66affSColin Finck
3742c2c66affSColin Finck /* case WM_CHARTOITEM: supported according to ControlSpy */
3743c2c66affSColin Finck
3744c2c66affSColin Finck case WM_CREATE:
3745c2c66affSColin Finck return REBAR_Create (infoPtr, (LPCREATESTRUCTW)lParam);
3746c2c66affSColin Finck
3747c2c66affSColin Finck case WM_DESTROY:
3748c2c66affSColin Finck return REBAR_Destroy (infoPtr);
3749c2c66affSColin Finck
3750c2c66affSColin Finck case WM_ERASEBKGND:
3751c2c66affSColin Finck return REBAR_EraseBkGnd (infoPtr, (HDC)wParam);
3752c2c66affSColin Finck
3753c2c66affSColin Finck case WM_GETFONT:
3754c2c66affSColin Finck return REBAR_GetFont (infoPtr);
3755c2c66affSColin Finck
3756c2c66affSColin Finck /* case WM_LBUTTONDBLCLK: supported according to ControlSpy */
3757c2c66affSColin Finck
3758c2c66affSColin Finck case WM_LBUTTONDOWN:
3759c2c66affSColin Finck return REBAR_LButtonDown (infoPtr, lParam);
3760c2c66affSColin Finck
3761c2c66affSColin Finck case WM_LBUTTONUP:
3762c2c66affSColin Finck return REBAR_LButtonUp (infoPtr);
3763c2c66affSColin Finck
3764c2c66affSColin Finck case WM_MOUSEMOVE:
3765c2c66affSColin Finck return REBAR_MouseMove (infoPtr, lParam);
3766c2c66affSColin Finck
3767c2c66affSColin Finck case WM_MOUSELEAVE:
3768c2c66affSColin Finck return REBAR_MouseLeave (infoPtr);
3769c2c66affSColin Finck
3770c2c66affSColin Finck case WM_NCCALCSIZE:
3771c2c66affSColin Finck return REBAR_NCCalcSize (infoPtr, (RECT*)lParam);
3772c2c66affSColin Finck
3773c2c66affSColin Finck case WM_NCCREATE:
3774c2c66affSColin Finck return REBAR_NCCreate (hwnd, (LPCREATESTRUCTW)lParam);
3775c2c66affSColin Finck
3776c2c66affSColin Finck case WM_NCHITTEST:
3777c2c66affSColin Finck return REBAR_NCHitTest (infoPtr, lParam);
3778c2c66affSColin Finck
3779c2c66affSColin Finck case WM_NCPAINT:
3780c2c66affSColin Finck return REBAR_NCPaint (infoPtr);
3781c2c66affSColin Finck
3782c2c66affSColin Finck case WM_NOTIFYFORMAT:
3783c2c66affSColin Finck return REBAR_NotifyFormat (infoPtr, lParam);
3784c2c66affSColin Finck
3785c2c66affSColin Finck case WM_PRINTCLIENT:
3786c2c66affSColin Finck case WM_PAINT:
3787c2c66affSColin Finck return REBAR_Paint (infoPtr, (HDC)wParam);
3788c2c66affSColin Finck
3789c2c66affSColin Finck /* case WM_PALETTECHANGED: supported according to ControlSpy */
3790c2c66affSColin Finck /* case WM_QUERYNEWPALETTE:supported according to ControlSpy */
3791c2c66affSColin Finck /* case WM_RBUTTONDOWN: supported according to ControlSpy */
3792c2c66affSColin Finck /* case WM_RBUTTONUP: supported according to ControlSpy */
3793c2c66affSColin Finck
3794c2c66affSColin Finck case WM_SETCURSOR:
3795c2c66affSColin Finck return REBAR_SetCursor (infoPtr, lParam);
3796c2c66affSColin Finck
3797c2c66affSColin Finck case WM_SETFONT:
3798c2c66affSColin Finck return REBAR_SetFont (infoPtr, (HFONT)wParam);
3799c2c66affSColin Finck
3800c2c66affSColin Finck case WM_SETREDRAW:
3801c2c66affSColin Finck return REBAR_SetRedraw (infoPtr, wParam);
3802c2c66affSColin Finck
3803c2c66affSColin Finck case WM_SIZE:
3804c2c66affSColin Finck return REBAR_Size (infoPtr, wParam, lParam);
3805c2c66affSColin Finck
3806c2c66affSColin Finck case WM_STYLECHANGED:
3807c2c66affSColin Finck return REBAR_StyleChanged (infoPtr, wParam, (LPSTYLESTRUCT)lParam);
3808c2c66affSColin Finck
3809c2c66affSColin Finck case WM_THEMECHANGED:
3810c2c66affSColin Finck return theme_changed (infoPtr);
3811c2c66affSColin Finck
3812c2c66affSColin Finck case WM_SYSCOLORCHANGE:
3813c2c66affSColin Finck COMCTL32_RefreshSysColors();
3814c2c66affSColin Finck #ifdef __REACTOS__
3815c2c66affSColin Finck /* r51522 - Properly support WM_SYSCOLORCHANGE */
3816c2c66affSColin Finck infoPtr->clrBtnText = comctl32_color.clrBtnText;
3817c2c66affSColin Finck infoPtr->clrBtnFace = comctl32_color.clrBtnFace;
3818c2c66affSColin Finck #endif
3819c2c66affSColin Finck return 0;
3820c2c66affSColin Finck
3821c2c66affSColin Finck /* case WM_VKEYTOITEM: supported according to ControlSpy */
3822c2c66affSColin Finck /* case WM_WININICHANGE: */
3823c2c66affSColin Finck
3824c2c66affSColin Finck case WM_WINDOWPOSCHANGED:
3825c2c66affSColin Finck return REBAR_WindowPosChanged (infoPtr, wParam, lParam);
3826c2c66affSColin Finck
3827c2c66affSColin Finck default:
3828c2c66affSColin Finck if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg))
3829c2c66affSColin Finck ERR("unknown msg %04x wp=%08lx lp=%08lx\n",
3830c2c66affSColin Finck uMsg, wParam, lParam);
3831c2c66affSColin Finck return DefWindowProcW (hwnd, uMsg, wParam, lParam);
3832c2c66affSColin Finck }
3833c2c66affSColin Finck }
3834c2c66affSColin Finck
3835c2c66affSColin Finck
3836c2c66affSColin Finck VOID
REBAR_Register(void)3837c2c66affSColin Finck REBAR_Register (void)
3838c2c66affSColin Finck {
3839c2c66affSColin Finck WNDCLASSW wndClass;
3840c2c66affSColin Finck
3841c2c66affSColin Finck ZeroMemory (&wndClass, sizeof(WNDCLASSW));
3842c2c66affSColin Finck wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
3843c2c66affSColin Finck wndClass.lpfnWndProc = REBAR_WindowProc;
3844c2c66affSColin Finck wndClass.cbClsExtra = 0;
3845c2c66affSColin Finck wndClass.cbWndExtra = sizeof(REBAR_INFO *);
3846c2c66affSColin Finck wndClass.hCursor = 0;
3847c2c66affSColin Finck wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
3848c2c66affSColin Finck #if GLATESTING
3849c2c66affSColin Finck wndClass.hbrBackground = CreateSolidBrush(RGB(0,128,0));
3850c2c66affSColin Finck #endif
3851c2c66affSColin Finck wndClass.lpszClassName = REBARCLASSNAMEW;
3852c2c66affSColin Finck
3853c2c66affSColin Finck RegisterClassW (&wndClass);
3854c2c66affSColin Finck
3855c2c66affSColin Finck mindragx = GetSystemMetrics (SM_CXDRAG);
3856c2c66affSColin Finck mindragy = GetSystemMetrics (SM_CYDRAG);
3857c2c66affSColin Finck
3858c2c66affSColin Finck }
3859c2c66affSColin Finck
3860c2c66affSColin Finck
3861c2c66affSColin Finck VOID
REBAR_Unregister(void)3862c2c66affSColin Finck REBAR_Unregister (void)
3863c2c66affSColin Finck {
3864c2c66affSColin Finck UnregisterClassW (REBARCLASSNAMEW, NULL);
3865c2c66affSColin Finck }
3866