2 * Interface code to StatusWindow widget/control
4 * Copyright 1996 Bruce Milner
7 #define NO_TRANSITION_TYPES /* This file is Win32-clean */
18 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
19 * The second cdrom contains executables drawstat.exe,gettext.exe,
20 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
25 * 1) Add size grip to status bar - SBARS_SIZEGRIP
26 * 2) Don't hard code bar to bottom of window, allow CCS_TOP also
27 * 3) Fix SBT_OWNERDRAW
28 * 4) Add DrawStatusText32A funtion
31 static STATUSWINDOWINFO
*GetStatusInfo(HWND32 hwnd
)
35 wndPtr
= WIN_FindWndPtr(hwnd
);
36 return ((STATUSWINDOWINFO
*) &wndPtr
->wExtra
[0]);
39 /***********************************************************************
40 * DrawStatusText32A (COMCTL32.3)
42 void DrawStatusText32A( HDC32 hdc
, LPRECT32 lprc
, LPCSTR text
, UINT32 style
)
50 style
== SBT_POPOUT
) {
51 InflateRect32(&r
, -1, -1);
52 SelectObject32(hdc
, sysColorObjects
.hbrushScrollbar
);
53 Rectangle32(hdc
, r
.left
, r
.top
, r
.right
, r
.bottom
);
56 SelectObject32(hdc
, sysColorObjects
.hpenWindowFrame
);
58 DrawEdge32(hdc
, &r
, EDGE_SUNKEN
, BF_RECT
);
60 DrawEdge32(hdc
, &r
, EDGE_RAISED
, BF_RECT
);
62 else if (style
== SBT_NOBORDERS
) {
63 SelectObject32(hdc
, sysColorObjects
.hbrushScrollbar
);
64 Rectangle32(hdc
, r
.left
, r
.top
, r
.right
, r
.bottom
);
66 else { /* fixme for SBT_OWNERDRAW, SBT_RTLREADING */
71 if ((style
!= SBT_OWNERDRAW
) && text
) {
72 SelectObject32(hdc
, sysColorObjects
.hpenWindowText
);
73 oldbkmode
= SetBkMode32(hdc
, TRANSPARENT
);
76 DrawText32A(hdc
, text
, lstrlen32A(text
),
77 &rt
, DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
);
79 if (oldbkmode
!= TRANSPARENT
)
80 SetBkMode32(hdc
, oldbkmode
);
84 static BOOL32
SW_Refresh( HWND32 hwnd
, HDC32 hdc
, STATUSWINDOWINFO
*self
)
88 if (!IsWindowVisible(hwnd
)) {
93 DrawStatusText32A(hdc
,
99 for (i
= 0; i
< self
->numParts
; i
++) {
100 DrawStatusText32A(hdc
,
101 &self
->parts
[i
].bound
,
103 self
->parts
[i
].style
);
112 SW_GetBorders(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
116 /* FIXME for sizegrips */
117 out
= (LPINT32
) lParam
;
118 out
[0] = 1; /* vertical border width */
119 out
[1] = 1; /* horizontal border width */
120 out
[2] = 1; /* width of border between rectangles */
125 SW_SetPartBounds(HWND32 hwnd
, STATUSWINDOWINFO
*self
)
129 STATUSWINDOWPART
*part
;
132 /* get our window size */
133 GetClientRect32(hwnd
, &rect
);
135 /* set bounds for simple rectangle */
136 self
->part0
.bound
= rect
;
138 /* set bounds for non-simple rectangles */
139 for (i
= 0; i
< self
->numParts
; i
++) {
140 part
= &self
->parts
[i
];
141 r
= &self
->parts
[i
].bound
;
143 r
->bottom
= rect
.bottom
;
147 r
->left
= self
->parts
[i
-1].bound
.right
+sep
;
149 r
->right
= rect
.right
;
156 SW_SetText(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
162 STATUSWINDOWPART
*part
;
164 text
= (LPSTR
) lParam
;
165 part_num
= ((INT32
) wParam
) & 0x00ff;
166 style
= ((INT32
) wParam
) & 0xff00;
174 part
= &self
->parts
[part_num
];
176 if (style
== SBT_OWNERDRAW
) {
180 /* duplicate string */
182 HeapFree(SystemHeap
, 0, part
->text
);
184 if (text
&& (len
= lstrlen32A(text
))) {
185 part
->text
= HeapAlloc(SystemHeap
, 0, len
+1);
186 lstrcpy32A(part
->text
, text
);
189 InvalidateRect32(hwnd
, &part
->bound
, FALSE
);
194 SW_SetParts(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
198 STATUSWINDOWPART
* tmp
;
203 self
->simple
= FALSE
;
205 oldNumParts
= self
->numParts
;
206 self
->numParts
= (INT32
) wParam
;
207 parts
= (LPINT32
) lParam
;
208 if (oldNumParts
> self
->numParts
) {
209 for (i
= self
->numParts
; i
< oldNumParts
; i
++) {
210 if (self
->parts
[i
].text
&& (self
->parts
[i
].style
!= SBT_OWNERDRAW
))
211 HeapFree(SystemHeap
, 0, self
->parts
[i
].text
);
214 else if (oldNumParts
< self
->numParts
) {
215 tmp
= HeapAlloc(SystemHeap
, HEAP_ZERO_MEMORY
,
216 sizeof(STATUSWINDOWPART
) * self
->numParts
);
217 for (i
= 0; i
< oldNumParts
; i
++) {
218 tmp
[i
] = self
->parts
[i
];
221 HeapFree(SystemHeap
, 0, self
->parts
);
225 for (i
= 0; i
< self
->numParts
; i
++) {
226 self
->parts
[i
].x
= parts
[i
];
228 SW_SetPartBounds(hwnd
, self
);
231 SW_Refresh(hwnd
, hdc
, self
);
232 ReleaseDC32(hwnd
, hdc
);
237 SW_GetParts(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
243 self
= GetStatusInfo(hwnd
);
244 num_parts
= (INT32
) wParam
;
245 parts
= (LPINT32
) lParam
;
247 return (self
->numParts
);
248 for (i
= 0; i
< num_parts
; i
++) {
249 parts
[i
] = self
->parts
[i
].x
;
252 return (self
->numParts
);
256 SW_Create(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
259 LPCREATESTRUCT32A lpCreate
= (LPCREATESTRUCT32A
) lParam
;
267 GetClientRect32(hwnd
, &rect
);
269 /* initialize simple case */
270 self
->part0
.bound
= rect
;
271 self
->part0
.text
= 0;
273 self
->part0
.style
= 0;
276 if ((hdc
= GetDC32(0))) {
278 GetTextMetrics32A(hdc
, &tm
);
279 self
->textHeight
= tm
.tmHeight
;
283 parent
= GetParent32(hwnd
);
284 GetClientRect32(parent
, &rect
);
285 width
= rect
.right
- rect
.left
;
286 height
= (self
->textHeight
* 3)/2;
287 MoveWindow(hwnd
, lpCreate
->x
, lpCreate
->y
-1, width
, height
, FALSE
);
288 SW_SetPartBounds(hwnd
, self
);
293 SW_GetRect(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
298 part_num
= ((INT32
) wParam
) & 0x00ff;
299 rect
= (LPRECT32
) lParam
;
301 *rect
= self
->part0
.bound
;
303 *rect
= self
->parts
[part_num
].bound
;
308 SW_GetText(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
312 STATUSWINDOWPART
*part
;
315 part_num
= ((INT32
) wParam
) & 0x00ff;
316 out_text
= (LPSTR
) lParam
;
320 part
= &self
->parts
[part_num
];
322 if (part
->style
== SBT_OWNERDRAW
)
323 result
= (LRESULT
) part
->text
;
325 result
= part
->text
? lstrlen32A(part
->text
) : 0;
326 result
|= (part
->style
<< 16);
328 lstrcpy32A(out_text
, part
->text
);
335 SW_GetTextLength(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
338 STATUSWINDOWPART
*part
;
341 part_num
= ((INT32
) wParam
) & 0x00ff;
346 part
= &self
->parts
[part_num
];
349 result
= lstrlen32A(part
->text
);
353 result
|= (part
->style
<< 16);
358 SW_SetMinHeight(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
361 /* size is wParam | 2*pixels_of_horz_border */
366 SW_Simple(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
371 simple
= (BOOL32
) wParam
;
372 self
->simple
= simple
;
374 SW_Refresh(hwnd
, hdc
, self
);
375 ReleaseDC32(hwnd
, hdc
);
380 SW_Size(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
382 /* Need to resize width to match parent */
383 INT32 width
, height
, x
, y
;
389 flags
= (INT32
) wParam
;
392 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
395 if (flags
== SIZE_RESTORED
) {
396 /* width and height don't apply */
397 parent
= GetParent32(hwnd
);
398 GetClientRect32(parent
, &parent_rect
);
399 height
= (self
->textHeight
* 3)/2;
400 width
= parent_rect
.right
- parent_rect
.left
;
401 x
= parent_rect
.left
;
402 y
= parent_rect
.bottom
- height
;
403 MoveWindow(hwnd
, parent_rect
.left
, parent_rect
.bottom
- height
- 1,
404 width
, height
, TRUE
);
405 SW_SetPartBounds(hwnd
, self
);
411 SW_Destroy(STATUSWINDOWINFO
*self
, HWND32 hwnd
, WPARAM32 wParam
, LPARAM lParam
)
415 for (i
= 0; i
< self
->numParts
; i
++) {
416 if (self
->parts
[i
].text
&& (self
->parts
[i
].style
!= SBT_OWNERDRAW
))
417 HeapFree(SystemHeap
, 0, self
->parts
[i
].text
);
419 if (self
->part0
.text
&& (self
->part0
.style
!= SBT_OWNERDRAW
))
420 HeapFree(SystemHeap
, 0, self
->part0
.text
);
421 HeapFree(SystemHeap
, 0, self
->parts
);
428 SW_Paint(STATUSWINDOWINFO
*self
, HWND32 hwnd
)
433 hdc
= BeginPaint32(hwnd
, &ps
);
434 SW_Refresh(hwnd
, hdc
, self
);
435 EndPaint32(hwnd
, &ps
);
439 LRESULT
StatusWindowProc( HWND32 hwnd
, UINT32 msg
,
440 WPARAM32 wParam
, LPARAM lParam
)
442 STATUSWINDOWINFO
*self
;
444 self
= GetStatusInfo(hwnd
);
448 return SW_GetBorders(self
, hwnd
, wParam
, lParam
);
450 return SW_GetParts(self
, hwnd
, wParam
, lParam
);
452 return SW_GetRect(self
, hwnd
, wParam
, lParam
);
454 return SW_GetText(self
, hwnd
, wParam
, lParam
);
455 case SB_GETTEXTLENGTH32A
:
456 return SW_GetTextLength(self
, hwnd
, wParam
, lParam
);
457 case SB_SETMINHEIGHT
:
458 return SW_SetMinHeight(self
, hwnd
, wParam
, lParam
);
460 return SW_SetParts(self
, hwnd
, wParam
, lParam
);
462 return SW_SetText(self
, hwnd
, wParam
, lParam
);
464 return SW_Simple(self
, hwnd
, wParam
, lParam
);
467 return SW_Create(self
, hwnd
, wParam
, lParam
);
469 return SW_Destroy(self
, hwnd
, wParam
, lParam
);
471 return SW_Paint(self
, hwnd
);
473 return SW_Size(self
, hwnd
, wParam
, lParam
);
475 return DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
481 /***********************************************************************
482 * CreateStatusWindow32A (COMCTL32.4)
484 HWND32
CreateStatusWindow32A( INT32 style
, LPCSTR text
, HWND32 parent
,
490 atom
= GlobalFindAtom32A(STATUSCLASSNAME32A
);
492 /* Some apps don't call InitCommonControls */
493 InitCommonControls();
496 ret
= CreateWindowEx32A(0, STATUSCLASSNAME32A
, "Status Window",
497 style
, CW_USEDEFAULT32
, CW_USEDEFAULT32
,
498 CW_USEDEFAULT32
, CW_USEDEFAULT32
, parent
, 0, 0, 0);