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