|
|
1.1 root 1: #include "FirstAid.H"
2:
3: #define NOMINMAX // we will get min/max from stdlib.h
4: #include <windows.h>
5: //#include <port1632.h>
6:
7: #include <stdlib.h> // For 'abs'
8:
9: //typedef LONG (APIENTRY *WNDPROC)(HWND, UINT, DWORD, LONG);
10:
11: #define MAXSTATUS 10
12: typedef struct _tagStatus {
13: HWND hwnd;
14: INT iMaxWidth, iMinWidth, iGiveWidth;
15: } Status;
16: Status statusField[MAXSTATUS];
17:
18: HWND hwndStatus;
19: INT cntStatusField = 0;
20: INT dyStatus, cxStatusBorder, cyStatusBorder, cxFrame, cyFrame, dyField;
21: HFONT hfontStatus;
22: TEXTMETRIC tmStatusFont;
23: HBRUSH hbrBtnFace;
24:
25: LONG APIENTRY StatusProc (HWND, UINT, UINT, LONG);
26: LONG APIENTRY StatusFieldProc (HWND, UINT, UINT, LONG);
27:
28: BOOL InitStatusBar (HANDLE hInstance)
29: {
30: WNDCLASS wndclass;
31:
32: hbrBtnFace = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
33:
34: wndclass.style = CS_HREDRAW | CS_VREDRAW;
35: wndclass.lpfnWndProc = (WNDPROC)StatusProc;
36: wndclass.cbClsExtra = 0;
37: wndclass.cbWndExtra = 0;
38: wndclass.hInstance = hInstance;
39: wndclass.hIcon = NULL;
40: wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
41: wndclass.hbrBackground = hbrBtnFace;
42: wndclass.lpszMenuName = NULL;
43: wndclass.lpszClassName = "SamplerStatus";
44:
45: if (!RegisterClass (&wndclass))
46: return FALSE;
47:
48: wndclass.style = CS_HREDRAW | CS_VREDRAW;
49: wndclass.lpfnWndProc = (WNDPROC)StatusFieldProc;
50: wndclass.cbClsExtra = 0;
51: wndclass.cbWndExtra = 0;
52: wndclass.hInstance = hInstance;
53: wndclass.hIcon = NULL;
54: wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
55: wndclass.hbrBackground = hbrBtnFace;
56: wndclass.lpszMenuName = NULL;
57: wndclass.lpszClassName = "StatusField";
58:
59: if (!RegisterClass (&wndclass))
60: return FALSE;
61:
62: }
63:
64: BOOL CreateStatusBar (HWND hwnd, HANDLE hInst, INT iId)
65: {
66: cxStatusBorder = GetSystemMetrics (SM_CXBORDER);
67: cyStatusBorder = GetSystemMetrics (SM_CYBORDER);
68:
69: //OutputDebugString (__FILE__": Calling CreateWindow\n");
70: hwndStatus = CreateWindow ("SamplerStatus", "SamplerStatus",
71: WS_CHILD //| WS_CLIPSIBLINGS
72: | WS_BORDER | WS_VISIBLE,
73: 0, 0, 0, 0,
74: hwnd, (HMENU)iId, hInst, NULL);
75:
76: if (!hwndStatus) {
77: return FALSE;
78: }
79: //OutputDebugString (__FILE__": CreateWindow Succeeded\n");
80: return TRUE;
81: }
82:
83: int StatusBarHeight (HWND hwnd)
84: {
85: RECT rect;
86: GetClientRect (hwndStatus, &rect);
87: return rect.bottom-rect.top;
88:
89: hwnd; // unreferenced
90: }
91:
92: BOOL AdjustStatusBar (HWND hwnd)
93: {
94: RECT rect;
95: GetClientRect (hwnd, &rect);
96: MoveWindow (hwndStatus,
97: rect.left-cxStatusBorder,
98: rect.bottom - dyStatus + cyStatusBorder,
99: rect.right - rect.left + (cxStatusBorder*2),
100: dyStatus,
101: TRUE);
102: return TRUE;
103: }
104:
105: HWND AddStatusField (HANDLE hInst, INT iId, INT iMin, INT iMax, BOOL bNewGroup)
106: {
107: LONG lStyle;
108:
109: if (cntStatusField >= MAXSTATUS) return (HWND)0; // No room left in our fixed array
110:
111: statusField[cntStatusField].hwnd = CreateWindow ("StatusField", "",
112: WS_CHILD //| WS_CLIPSIBLINGS
113: | WS_VISIBLE,
114: 0, 0, 0, 0,
115: hwndStatus, (HMENU)iId, hInst, NULL);
116:
117: if (!statusField[cntStatusField].hwnd) return (HWND)0; // CreateWindow failed for some reason
118:
119: if (iMin < 0) {
120: statusField[cntStatusField].iMinWidth = tmStatusFont.tmAveCharWidth*abs(iMin);
121: } else {
122: statusField[cntStatusField].iMinWidth = iMin;
123: }
124:
125: if (iMax < 0) {
126: statusField[cntStatusField].iMaxWidth = tmStatusFont.tmAveCharWidth*abs(iMax);
127: } else {
128: statusField[cntStatusField].iMaxWidth = iMax;
129: }
130:
131: if (bNewGroup) {
132: lStyle = GetWindowLong (statusField[cntStatusField].hwnd, GWL_STYLE);
133: lStyle |= WS_GROUP;
134: SetWindowLong (statusField[cntStatusField].hwnd, GWL_STYLE, lStyle);
135: }
136:
137: return statusField[cntStatusField++].hwnd;
138: }
139:
140: BOOL DestroyStatusBar (void)
141: {
142: return DeleteObject (hbrBtnFace);
143: }
144:
145: LONG APIENTRY StatusProc (HWND hwnd, UINT msg, UINT wParam, LONG lParam)
146: {
147: HDC hdc;
148: PAINTSTRUCT ps;
149: INT x, y, i;
150: INT wAvailWidth, wFlexWidth, cntFlexWidth, wNeedWidth, cntNeedWidth;
151: RECT rect, border;
152: HBRUSH hBrush;
153:
154: switch (msg) {
155: case WM_CREATE:
156: #ifdef NOCREATEFONT // CreateFont is failing in NT
157: hfontStatus = (HFONT)NULL;
158: #else
159: hfontStatus = CreateFont(16, 0, 0, 0, 0, 0, 0, 0,
160: ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
161: DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
162: if (!hfontStatus) {
163: MessageBox (GetFocus(), "Failed To Create Font", "StatusProc", MB_OK);
164: }
165: #endif
166: hdc = GetDC (hwnd);
167: SelectObject (hdc, hfontStatus);
168: GetTextMetrics (hdc, &tmStatusFont);
169: cxStatusBorder = GetSystemMetrics (SM_CXBORDER);
170: cyStatusBorder = GetSystemMetrics (SM_CYBORDER);
171: cxFrame = 3*cxStatusBorder;
172: cyFrame = 3*cyStatusBorder;
173: dyField = tmStatusFont.tmHeight + (2*cyStatusBorder);
174: dyStatus = dyField + (2*cyFrame);
175: ReleaseDC (hwnd, hdc);
176: return DefWindowProc (hwnd, msg, wParam, lParam);
177:
178: case WM_SIZE:
179: if (cntStatusField) {
180: GetClientRect (hwnd, &rect);
181: wAvailWidth = rect.right - rect.left - (cxStatusBorder*8);
182: wNeedWidth = 0;
183: cntNeedWidth = 0;
184: cntFlexWidth = 0;
185:
186: /* First Pass: Dole out to fields that have a minimum need */
187: for (i=0; i<cntStatusField; i++) {
188: statusField[i].iGiveWidth = 0; // Make sure all are initialized to 0
189: if (statusField[i].iMinWidth) {
190: /* (n, ?) */
191: statusField[i].iGiveWidth = statusField[i].iMinWidth;
192: wAvailWidth -= (statusField[i].iGiveWidth + cxStatusBorder*2);
193: if (GetWindowLong(statusField[i].hwnd, GWL_STYLE) & WS_GROUP) {
194: wAvailWidth -= cxStatusBorder*4;
195: }
196: } else {
197: /* They didn't specify a minimum... don't give them anything yet */
198: /* (0, ?) */
199: statusField[i].iGiveWidth = 0;
200: //++cntFlexWidth;
201: }
202:
203: /* For those that have a minimum, but can grow to be as large as possible...*/
204: /* (n, 0) */
205: if ((statusField[i].iMinWidth >0) && (statusField[i].iMaxWidth ==0)) {
206: ++cntFlexWidth;
207: }
208:
209: /* For those that have a max that is greater then their min... */
210: /* Includes (0,n) and (n,>n) */
211: if (statusField[i].iMaxWidth > statusField[i].iGiveWidth) {
212: wNeedWidth += (statusField[i].iMaxWidth - statusField[i].iGiveWidth);
213: ++cntNeedWidth;
214: }
215: }
216:
217: /* Second Pass: Dole out to fields that have a stated maximum need */
218: /* This will also hit those who had no minimum, but did have a maximum */
219: /* It will still not give anything to those with no min, no max */
220: if ((cntNeedWidth > 0) && (wAvailWidth > 0)) {
221: if (wNeedWidth > wAvailWidth) {
222: wNeedWidth = wAvailWidth;
223: }
224: wNeedWidth = wNeedWidth / cntNeedWidth;
225: for (i=0; i<cntStatusField; i++) {
226: if (statusField[i].iMaxWidth > statusField[i].iGiveWidth) {
227: statusField[i].iGiveWidth += wNeedWidth;
228: wAvailWidth -= (statusField[i].iGiveWidth + cxStatusBorder*2);
229: if (GetWindowLong(statusField[i].hwnd, GWL_STYLE) & WS_GROUP) {
230: wAvailWidth -= cxStatusBorder*4;
231: }
232: }
233: }
234: }
235:
236: /* Third Pass: Dole out the remaining to fields that want all they can get */
237: /* This includes those who had a minimum, but no maximum */
238: if ((cntFlexWidth > 0) && (wAvailWidth > 0)) {
239: wFlexWidth = wAvailWidth / cntFlexWidth;
240: for (i=0; i<cntStatusField; i++) {
241: if (statusField[i].iMaxWidth==0) {
242: statusField[i].iGiveWidth += wFlexWidth;
243: wAvailWidth -= ((wFlexWidth - statusField[i].iMinWidth) + cxStatusBorder*2);
244: if (GetWindowLong(statusField[i].hwnd, GWL_STYLE) & WS_GROUP) {
245: wAvailWidth -= cxStatusBorder*4;
246: }
247: }
248: }
249: }
250:
251: x = cxStatusBorder*4;
252: y = rect.top + (2*cyStatusBorder);
253: for (i=0; i<cntStatusField; i++) {
254: if (GetWindowLong (statusField[i].hwnd, GWL_STYLE) & WS_GROUP) {
255: x += (cxStatusBorder*4);
256: }
257: MoveWindow (statusField[i].hwnd, x, y, statusField[i].iGiveWidth, dyField, TRUE);
258: x += statusField[i].iGiveWidth + (cxStatusBorder*2);
259: }
260: }
261: break;
262:
263: case WM_PAINT:
264: hdc = BeginPaint (hwnd, &ps);
265: GetClientRect (hwnd, &rect);
266:
267: hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
268: border = rect;
269: border.bottom = border.top + cyStatusBorder;
270: FillRect (hdc, &border, hBrush);
271: DeleteObject (hBrush);
272:
273: hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
274: border = rect;
275: border.top = border.bottom - cyStatusBorder;
276: FillRect (hdc, &border, hBrush);
277: DeleteObject (hBrush);
278:
279: EndPaint (hwnd, &ps);
280:
281: return DefWindowProc (hwnd, msg, wParam, lParam);
282:
283: default:
284: return DefWindowProc (hwnd, msg, wParam, lParam);
285: }
286: return 0L;
287: }
288:
289:
290:
291: LONG APIENTRY StatusFieldProc (HWND hwnd, UINT msg, UINT wParam, LONG lParam)
292: {
293: static HFONT hFieldFont;
294:
295: HDC hdc;
296: PAINTSTRUCT ps;
297: RECT rect, border;
298: HBRUSH hBrush;
299: WORD edge = 1;
300: HFONT hTmp;
301: char szText[80];
302: INT len;
303:
304: switch (msg) {
305: case WM_CREATE:
306: hFieldFont = CreateFont(8, 0, 0, 0, 0, 0, 0, 0,
307: ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
308: DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "Helv");
309: return DefWindowProc (hwnd, msg, wParam, lParam);
310:
311: case WM_PAINT:
312: hdc = BeginPaint (hwnd, &ps);
313: GetClientRect (hwnd, &rect);
314:
315: hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
316: border = rect;
317: border.bottom = border.top + cyStatusBorder;
318: FillRect (hdc, &border, hBrush);
319: border = rect;
320: border.right = border.left + cxStatusBorder;
321: FillRect (hdc, &border, hBrush);
322: DeleteObject (hBrush);
323:
324: hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
325: border = rect;
326: border.top = border.bottom - cyStatusBorder;
327: FillRect (hdc, &border, hBrush);
328: border = rect;
329: border.left = border.right - cxStatusBorder;
330: FillRect (hdc, &border, hBrush);
331: DeleteObject (hBrush);
332:
333: if (len = GetWindowText(hwnd, szText, sizeof (szText))) {
334: hTmp = SelectObject(hdc, hfontStatus);
335:
336: SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
337: SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
338:
339: InflateRect (&rect, -(cxStatusBorder*2), -cyStatusBorder);
340: ExtTextOut(hdc, rect.left, rect.top,
341: ETO_OPAQUE | ETO_CLIPPED,
342: &rect,
343: (LPSTR)szText,
344: len, NULL);
345:
346: SelectObject (hdc, hTmp);
347: }
348:
349: EndPaint (hwnd, &ps);
350: break;
351:
352: case WM_SETTEXT:
353: InvalidateRect (hwnd, NULL, TRUE);
354: return DefWindowProc (hwnd, msg, wParam, lParam);
355:
356: default:
357: return DefWindowProc (hwnd, msg, wParam, lParam);
358: }
359: return 0L;
360: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.