2 * Interface code to StatusWindow widget/control
4 * Copyright 1996 Bruce Milner
17 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
18 * The second cdrom contains executables drawstat.exe,gettext.exe,
19 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
24 * 1) Add size grip to status bar - SBARS_SIZEGRIP
25 * 2) Don't hard code bar to bottom of window, allow CCS_TOP also
26 * 3) Fix SBT_OWNERDRAW
27 * 4) Add DrawStatusText32A funtion
30 static STATUSWINDOWINFO
*GetStatusInfo(HWND32 hwnd
)
34 wndPtr
= WIN_FindWndPtr(hwnd
);
35 return ((STATUSWINDOWINFO
*) &wndPtr
->wExtra
[0]);
38 /***********************************************************************
39 * DrawStatusText32A (COMCTL32.3)
41 void DrawStatusText32A( HDC32 hdc
, LPRECT32 lprc
, LPCSTR text
, UINT32 style
)
49 style
== SBT_POPOUT
) {
50 InflateRect32(&r
, -1, -1);
51 SelectObject(hdc
, sysColorObjects
.hbrushScrollbar
);
52 Rectangle(hdc
, r
.left
, r
.top
, r
.right
, r
.bottom
);
55 SelectObject(hdc
, sysColorObjects
.hpenWindowFrame
);
57 DrawEdge32(hdc
, &r
, EDGE_SUNKEN
, BF_RECT
);
59 DrawEdge32(hdc
, &r
, EDGE_RAISED
, BF_RECT
);
61 else if (style
== SBT_NOBORDERS
) {
62 SelectObject(hdc
, sysColorObjects
.hbrushScrollbar
);
63 Rectangle(hdc
, r
.left
, r
.top
, r
.right
, r
.bottom
);
65 else { /* fixme for SBT_OWNERDRAW, SBT_RTLREADING */
70 if ((style
!= SBT_OWNERDRAW
) && text
) {
71 SelectObject(hdc
, sysColorObjects
.hpenWindowText
);
72 oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
75 DrawText32A(hdc
, text
, lstrlen32A(text
),
76 &rt
, DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
);
78 if (oldbkmode
!= TRANSPARENT
)
79 SetBkMode(hdc
, oldbkmode
);
83 static BOOL32
SW_Refresh( HWND32 hwnd
, HDC32 hdc
, STATUSWINDOWINFO
*self
)
87 if (!IsWindowVisible(hwnd
)) {
92 DrawStatusText32A(hdc
,
98 for (i
= 0; i
< self
->numParts
; i
++) {
99 DrawStatusText32A(hdc
,
100 &self
->parts
[i
].bound
,
102 self
->parts
[i
].style
);
111 SW_GetBorders(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
115 /* FIXME for sizegrips */
116 out
= (LPINT32
) lParam
;
117 out
[0] = 1; /* vertical border width */
118 out
[1] = 1; /* horizontal border width */
119 out
[2] = 1; /* width of border between rectangles */
124 SW_SetPartBounds(HWND32 hwnd
, STATUSWINDOWINFO
*self
)
128 STATUSWINDOWPART
*part
;
131 /* get our window size */
132 GetClientRect32(hwnd
, &rect
);
134 /* set bounds for simple rectangle */
135 self
->part0
.bound
= rect
;
137 /* set bounds for non-simple rectangles */
138 for (i
= 0; i
< self
->numParts
; i
++) {
139 part
= &self
->parts
[i
];
140 r
= &self
->parts
[i
].bound
;
142 r
->bottom
= rect
.bottom
;
146 r
->left
= self
->parts
[i
-1].bound
.right
+sep
;
148 r
->right
= rect
.right
;
155 SW_SetText(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
161 STATUSWINDOWPART
*part
;
163 text
= (LPSTR
) lParam
;
164 part_num
= ((INT32
) wParam
) & 0x00ff;
165 style
= ((INT32
) wParam
) & 0xff00;
173 part
= &self
->parts
[part_num
];
175 if (style
== SBT_OWNERDRAW
) {
179 /* duplicate string */
181 HeapFree(SystemHeap
, 0, part
->text
);
183 if (text
&& (len
= lstrlen32A(text
))) {
184 part
->text
= HeapAlloc(SystemHeap
, 0, len
+1);
185 lstrcpy32A(part
->text
, text
);
188 InvalidateRect32(hwnd
, &part
->bound
, FALSE
);
193 SW_SetParts(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
197 STATUSWINDOWPART
* tmp
;
202 self
->simple
= FALSE
;
204 oldNumParts
= self
->numParts
;
205 self
->numParts
= (INT32
) wParam
;
206 parts
= (LPINT32
) lParam
;
207 if (oldNumParts
> self
->numParts
) {
208 for (i
= self
->numParts
; i
< oldNumParts
; i
++) {
209 if (self
->parts
[i
].text
&& (self
->parts
[i
].style
!= SBT_OWNERDRAW
))
210 HeapFree(SystemHeap
, 0, self
->parts
[i
].text
);
213 else if (oldNumParts
< self
->numParts
) {
214 tmp
= HeapAlloc(SystemHeap
, HEAP_ZERO_MEMORY
,
215 sizeof(STATUSWINDOWPART
) * self
->numParts
);
216 for (i
= 0; i
< oldNumParts
; i
++) {
217 tmp
[i
] = self
->parts
[i
];
220 HeapFree(SystemHeap
, 0, self
->parts
);
224 for (i
= 0; i
< self
->numParts
; i
++) {
225 self
->parts
[i
].x
= parts
[i
];
227 SW_SetPartBounds(hwnd
, self
);
230 SW_Refresh(hwnd
, hdc
, self
);
231 ReleaseDC(hwnd
, hdc
);
236 SW_GetParts(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
242 self
= GetStatusInfo(hwnd
);
243 num_parts
= (INT32
) wParam
;
244 parts
= (LPINT32
) lParam
;
246 return (self
->numParts
);
247 for (i
= 0; i
< num_parts
; i
++) {
248 parts
[i
] = self
->parts
[i
].x
;
251 return (self
->numParts
);
255 SW_Create(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
258 LPCREATESTRUCT32A lpCreate
= (LPCREATESTRUCT32A
) lParam
;
266 GetClientRect32(hwnd
, &rect
);
268 /* initialize simple case */
269 self
->part0
.bound
= rect
;
270 self
->part0
.text
= 0;
272 self
->part0
.style
= 0;
275 if ((hdc
= GetDC(0))) {
277 GetTextMetrics32A(hdc
, &tm
);
278 self
->textHeight
= tm
.tmHeight
;
282 parent
= GetParent(hwnd
);
283 GetClientRect32(parent
, &rect
);
284 width
= rect
.right
- rect
.left
;
285 height
= (self
->textHeight
* 3)/2;
286 MoveWindow(hwnd
, lpCreate
->x
, lpCreate
->y
-1, width
, height
, FALSE
);
287 SW_SetPartBounds(hwnd
, self
);
292 SW_GetRect(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
297 part_num
= ((INT32
) wParam
) & 0x00ff;
298 rect
= (LPRECT32
) lParam
;
300 *rect
= self
->part0
.bound
;
302 *rect
= self
->parts
[part_num
].bound
;
307 SW_GetText(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
311 STATUSWINDOWPART
*part
;
314 part_num
= ((INT32
) wParam
) & 0x00ff;
315 out_text
= (LPSTR
) lParam
;
319 part
= &self
->parts
[part_num
];
321 if (part
->style
== SBT_OWNERDRAW
)
322 result
= (LRESULT
) part
->text
;
324 result
= part
->text
? lstrlen32A(part
->text
) : 0;
325 result
|= (part
->style
<< 16);
327 lstrcpy32A(out_text
, part
->text
);
334 SW_GetTextLength(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
337 STATUSWINDOWPART
*part
;
340 part_num
= ((INT32
) wParam
) & 0x00ff;
345 part
= &self
->parts
[part_num
];
348 result
= lstrlen32A(part
->text
);
352 result
|= (part
->style
<< 16);
357 SW_SetMinHeight(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
360 /* size is wParam | 2*pixels_of_horz_border */
365 SW_Simple(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
370 simple
= (BOOL32
) wParam
;
371 self
->simple
= simple
;
373 SW_Refresh(hwnd
, hdc
, self
);
374 ReleaseDC(hwnd
, hdc
);
379 SW_Size(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
381 /* Need to resize width to match parent */
382 INT32 width
, height
, x
, y
;
388 flags
= (INT32
) wParam
;
391 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
394 if (flags
== SIZE_RESTORED
) {
395 /* width and height don't apply */
396 parent
= GetParent(hwnd
);
397 GetClientRect32(parent
, &parent_rect
);
398 height
= (self
->textHeight
* 3)/2;
399 width
= parent_rect
.right
- parent_rect
.left
;
400 x
= parent_rect
.left
;
401 y
= parent_rect
.bottom
- height
;
402 MoveWindow(hwnd
, parent_rect
.left
, parent_rect
.bottom
- height
- 1,
403 width
, height
, TRUE
);
404 SW_SetPartBounds(hwnd
, self
);
410 SW_Destroy(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
414 for (i
= 0; i
< self
->numParts
; i
++) {
415 if (self
->parts
[i
].text
&& (self
->parts
[i
].style
!= SBT_OWNERDRAW
))
416 HeapFree(SystemHeap
, 0, self
->parts
[i
].text
);
418 if (self
->part0
.text
&& (self
->part0
.style
!= SBT_OWNERDRAW
))
419 HeapFree(SystemHeap
, 0, self
->part0
.text
);
420 HeapFree(SystemHeap
, 0, self
->parts
);
427 SW_Paint(STATUSWINDOWINFO
*self
, HWND32 hwnd
)
432 hdc
= BeginPaint32(hwnd
, &ps
);
433 SW_Refresh(hwnd
, hdc
, self
);
434 EndPaint32(hwnd
, &ps
);
438 LRESULT
StatusWindowProc( HWND32 hwnd
, UINT32 msg
,
439 WPARAM32 wParam
, LPARAM lParam
)
441 STATUSWINDOWINFO
*self
;
443 self
= GetStatusInfo(hwnd
);
447 return SW_GetBorders(self
, hwnd
, wParam
, lParam
);
449 return SW_GetParts(self
, hwnd
, wParam
, lParam
);
451 return SW_GetRect(self
, hwnd
, wParam
, lParam
);
453 return SW_GetText(self
, hwnd
, wParam
, lParam
);
454 case SB_GETTEXTLENGTH32A
:
455 return SW_GetTextLength(self
, hwnd
, wParam
, lParam
);
456 case SB_SETMINHEIGHT
:
457 return SW_SetMinHeight(self
, hwnd
, wParam
, lParam
);
459 return SW_SetParts(self
, hwnd
, wParam
, lParam
);
461 return SW_SetText(self
, hwnd
, wParam
, lParam
);
463 return SW_Simple(self
, hwnd
, wParam
, lParam
);
466 return SW_Create(self
, hwnd
, wParam
, lParam
);
468 return SW_Destroy(self
, hwnd
, wParam
, lParam
);
470 return SW_Paint(self
, hwnd
);
472 return SW_Size(self
, hwnd
, wParam
, lParam
);
474 return DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
480 /***********************************************************************
481 * CreateStatusWindow32A (COMCTL32.4)
483 HWND32
CreateStatusWindow32A( INT32 style
, LPCSTR text
, HWND32 parent
,
489 atom
= GlobalFindAtom32A(STATUSCLASSNAME32A
);
491 /* Some apps don't call InitCommonControls */
492 InitCommonControls();
495 ret
= CreateWindowEx32A(0, STATUSCLASSNAME32A
, "Status Window",
496 style
, CW_USEDEFAULT32
, CW_USEDEFAULT32
,
497 CW_USEDEFAULT32
, CW_USEDEFAULT32
, parent
, 0, 0, 0);