|
|
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.