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