|
|
1.1 ! 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: ! 12: /****************************** Module Header ******************************* ! 13: * Module Name: STATUS.C ! 14: * ! 15: * Status line handler. ! 16: * ! 17: * Functions: ! 18: * ! 19: * StatusInit() ! 20: * StatusCreate() ! 21: * StatusHeight() ! 22: * StatusAlloc() ! 23: * StatusAddItem() ! 24: * StatusCreateTools() ! 25: * StatusDeleteTools() ! 26: * StatusWndProc() ! 27: * StatusResize() ! 28: * StatusCalcHeight() ! 29: * StatusCalcWidth() ! 30: * StatusGetItem() ! 31: * LowerRect() ! 32: * RaiseRect() ! 33: * StatusPaint() ! 34: * BottomRight() ! 35: * TopLeft() ! 36: * StatusButtonDown() ! 37: * StatusButtonUp() ! 38: * InitDC() ! 39: * ! 40: * Comments: ! 41: * ! 42: ****************************************************************************/ ! 43: ! 44: #include <windows.h> ! 45: #include <string.h> ! 46: ! 47: #include "gutils.h" ! 48: ! 49: ! 50: /* --- data structures ------------------------------------------------- */ ! 51: #define SF_MAXLABEL 80 /* no more than 80 in an item within the bar */ ! 52: /* Is this adequate for long pathnames on a ! 53: hi-res screen? ! 54: */ ! 55: ! 56: typedef struct statel { ! 57: int type; /* SF_BUTTON or SF_STATIC */ ! 58: int flags; /* SF_VAR => variable width ! 59: SF_LEFT=> left aligned (else right) ! 60: SF_RAISE=> paint as 'raised' 3d rect ! 61: SF_LOWER=> paint as lowered 3D rect ! 62: SF_SZMIN=>together with SF_VAR ! 63: allows minimum size for ! 64: var sized item ! 65: SF_SZMAX=>see SZMIN and use nouse ! 66: */ ! 67: int id; /* control id */ ! 68: int width; /* width of control in chars */ ! 69: char text[SF_MAXLABEL+1]; /* null-term string for label */ ! 70: ! 71: RECT rc; /* used by status.c */ ! 72: } STATEL, FAR * PSTATEL; ! 73: ! 74: typedef struct itemlist { ! 75: int nitems; ! 76: PSTATEL statels; ! 77: ! 78: int selitem; /* used by status.c */ ! 79: BOOL isselected; /* used by status.c */ ! 80: } ILIST, FAR * PILIST; ! 81: ! 82: /* prototypes of routines in this module */ ! 83: ! 84: void StatusCreateTools(void); ! 85: void StatusDeleteTools(void); ! 86: long APIENTRY StatusWndProc(HWND, UINT, UINT, LONG); ! 87: void StatusResize(HWND hWnd, PILIST pilist); ! 88: int StatusCalcHeight(HWND hWnd, PSTATEL ip); ! 89: int StatusCalcWidth(HWND hWnd, PSTATEL ip); ! 90: PSTATEL StatusGetItem(PILIST plist, int id); ! 91: void LowerRect(HDC hDC, LPRECT rcp); ! 92: void RaiseRect(HDC hDC, LPRECT rcp); ! 93: void StatusPaint(HWND hWnd, PILIST iplistp); ! 94: void BottomRight(HDC hDC, LPRECT rcp, HPEN hpen, BOOL bCorners); ! 95: void TopLeft(HDC hDC, LPRECT rcp, HPEN hpen, BOOL bCorners); ! 96: void StatusButtonDown(HDC hDC, PSTATEL ip); ! 97: void StatusButtonUp(HDC hDC, PSTATEL ip); ! 98: void InitDC(HDC hdc); ! 99: ! 100: ! 101: /*--global data---------------------------------------------------------*/ ! 102: ! 103: HPEN hpenHilight, hpenLowlight; ! 104: HPEN hpenBlack, hpenNeutral; ! 105: HBRUSH hbrBackground; /* pieces and board */ ! 106: HFONT hFont; ! 107: int status_charheight, status_charwidth; ! 108: ! 109: /* default pt size for font (tenths of a pt) */ ! 110: #define DEF_PTSIZE 80 ! 111: ! 112: /*************************************************************************** ! 113: * Function: StatusInit ! 114: * ! 115: * Purpose: ! 116: * ! 117: * Create window class ! 118: */ ! 119: BOOL ! 120: StatusInit(HANDLE hInstance) ! 121: { ! 122: WNDCLASS wc; ! 123: BOOL resp; ! 124: TEXTMETRIC tm; ! 125: HDC hDC; ! 126: ! 127: ! 128: StatusCreateTools(); ! 129: ! 130: wc.style = CS_HREDRAW|CS_VREDRAW|CS_GLOBALCLASS; ! 131: wc.lpfnWndProc = (WNDPROC) StatusWndProc; ! 132: wc.cbClsExtra = 0; ! 133: wc.cbWndExtra = sizeof(HANDLE); ! 134: wc.hInstance = hInstance; ! 135: wc.hIcon = NULL; ! 136: wc.hCursor = LoadCursor(NULL, IDC_ARROW); ! 137: wc.hbrBackground = hbrBackground; ! 138: wc.lpszClassName = (LPSTR) "gdstatusclass"; ! 139: wc.lpszMenuName = NULL; ! 140: ! 141: resp = RegisterClass(&wc); ! 142: ! 143: hDC = GetDC(NULL); ! 144: InitDC(hDC); ! 145: GetTextMetrics(hDC, &tm); ! 146: status_charheight = (int)(tm.tmHeight + tm.tmExternalLeading); ! 147: status_charwidth = (int)tm.tmAveCharWidth; ! 148: ReleaseDC(NULL, hDC); ! 149: ! 150: return(resp); ! 151: } ! 152: ! 153: /* ! 154: /*************************************************************************** ! 155: * Function: StatusCreate ! 156: * ! 157: * Purpose: ! 158: * ! 159: * Create and show the window ! 160: */ ! 161: HWND APIENTRY ! 162: StatusCreate(HANDLE hInst, HWND hParent, int id, LPRECT rcp, HANDLE hmem) ! 163: { ! 164: ! 165: HWND hWnd; ! 166: ! 167: /* create a child window of status class */ ! 168: ! 169: ! 170: hWnd = CreateWindow("gdstatusclass", ! 171: NULL, ! 172: WS_CHILD | WS_VISIBLE, ! 173: rcp->left, ! 174: rcp->top, ! 175: (rcp->right - rcp->left), ! 176: (rcp->bottom - rcp->top), ! 177: hParent, ! 178: (HANDLE) id, ! 179: hInst, ! 180: (LPVOID) hmem); ! 181: ! 182: return(hWnd); ! 183: } ! 184: ! 185: /*************************************************************************** ! 186: * Function: StatusHeight ! 187: * ! 188: * Purpose: ! 189: * ! 190: * Return default height of this window ! 191: */ ! 192: int APIENTRY ! 193: StatusHeight(HANDLE hmem) ! 194: /* The window has a number of items which are arranged horizontally, ! 195: so the window height is the maximum of the individual heights ! 196: */ ! 197: { ! 198: PILIST plist; ! 199: int i; ! 200: int sz; ! 201: int maxsize = 0; ! 202: ! 203: plist = (PILIST) GlobalLock(hmem); ! 204: if (plist != NULL) { ! 205: for (i = 0; i<plist->nitems; i++) { ! 206: sz = StatusCalcHeight(NULL, &plist->statels[i]); ! 207: maxsize = max(sz, maxsize); ! 208: } ! 209: } ! 210: GlobalUnlock(hmem); ! 211: if (maxsize > 0) { ! 212: return(maxsize + 4); ! 213: } else { ! 214: return(status_charheight + 4); ! 215: } ! 216: } ! 217: ! 218: /*************************************************************************** ! 219: * Function: StatusAlloc ! 220: * ! 221: * Purpose: ! 222: * ! 223: * Alloc the plist struct and return handle to caller ! 224: */ ! 225: HANDLE FAR PASCAL ! 226: StatusAlloc(int nitems) ! 227: { ! 228: HANDLE hmem; ! 229: PILIST pilist; ! 230: LPSTR chp; ! 231: ! 232: hmem = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, ! 233: sizeof(ILIST) + (sizeof(STATEL) * nitems)); ! 234: chp = GlobalLock(hmem); ! 235: if (chp == NULL) { ! 236: return(NULL); ! 237: } ! 238: ! 239: pilist = (PILIST) chp; ! 240: pilist->nitems = nitems; ! 241: pilist->statels = (PSTATEL) &chp[sizeof(ILIST)]; ! 242: GlobalUnlock(hmem); ! 243: ! 244: return(hmem); ! 245: } ! 246: ! 247: ! 248: /*************************************************************************** ! 249: * Function: StatusAddItem ! 250: * ! 251: * Purpose: ! 252: * ! 253: * Insert an item into the plist ! 254: */ ! 255: BOOL FAR PASCAL ! 256: StatusAddItem(HANDLE hmem, int itemnr, int type, int flags, int id, ! 257: int width, LPSTR text) ! 258: { ! 259: PILIST pilist; ! 260: PSTATEL pel; ! 261: ! 262: pilist = (PILIST) GlobalLock(hmem); ! 263: if ((pilist == NULL) || (itemnr >= pilist->nitems)) { ! 264: GlobalUnlock(hmem); ! 265: return(FALSE); ! 266: } ! 267: pel = &pilist->statels[itemnr]; ! 268: pel->type = type; ! 269: pel->flags = flags; ! 270: pel->id = id; ! 271: pel->width = width; ! 272: if (text == NULL) { ! 273: pel->text[0] = '\0'; ! 274: } else { ! 275: lstrcpy(pel->text, text); ! 276: } ! 277: ! 278: ! 279: GlobalUnlock(hmem); ! 280: return(TRUE); ! 281: } ! 282: ! 283: /*************************************************************************** ! 284: * Function: InitDC ! 285: * ! 286: * Purpose: ! 287: * ! 288: * Initialize colors and font ! 289: */ ! 290: void ! 291: InitDC(HDC hdc) ! 292: { ! 293: SetBkColor(hdc, RGB(192,192,192)); ! 294: SelectObject(hdc, hbrBackground); ! 295: SelectObject(hdc, hFont); ! 296: } ! 297: ! 298: ! 299: /*************************************************************************** ! 300: * Function: StatusCreateTools ! 301: * ! 302: * Purpose: ! 303: * ! 304: * Create Pens and brushes ! 305: */ ! 306: void ! 307: StatusCreateTools() ! 308: { ! 309: LOGFONT lf; ! 310: HDC hdc; ! 311: int scale; ! 312: ! 313: hbrBackground = CreateSolidBrush(RGB(192,192,192)); ! 314: hpenHilight = CreatePen(0, 1, RGB(255, 255, 255)); ! 315: hpenLowlight = CreatePen(0, 1, RGB(128, 128, 128)); ! 316: hpenNeutral = CreatePen(0, 1, RGB(192, 192, 192)); ! 317: hpenBlack = CreatePen(0, 1, RGB(0, 0, 0)); ! 318: ! 319: hdc = GetDC(NULL); ! 320: scale = GetDeviceCaps(hdc, LOGPIXELSY); ! 321: ReleaseDC(NULL, hdc); ! 322: ! 323: lf.lfHeight = -MulDiv(DEF_PTSIZE, scale, 720); ! 324: lf.lfWidth = 0; ! 325: lf.lfEscapement = 0; ! 326: lf.lfOrientation = 0; ! 327: lf.lfWeight = FW_REGULAR; ! 328: lf.lfItalic = 0; ! 329: lf.lfUnderline = 0; ! 330: lf.lfStrikeOut = 0; ! 331: lf.lfCharSet = ANSI_CHARSET; ! 332: lf.lfOutPrecision = OUT_DEFAULT_PRECIS; ! 333: lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; ! 334: lf.lfQuality = PROOF_QUALITY; ! 335: lf.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS; ! 336: lf.lfFaceName[0] = '\0'; ! 337: #ifdef COMPLEX ! 338: hFont = CreateFontIndirect(&lf); ! 339: #else ! 340: hFont = GetStockObject(SYSTEM_FONT); ! 341: #endif ! 342: ! 343: ! 344: ! 345: } ! 346: ! 347: /*************************************************************************** ! 348: * Function: StatusDeleteTools ! 349: * ! 350: * Purpose: ! 351: * ! 352: * Delete brushes and pens ! 353: */ ! 354: void ! 355: StatusDeleteTools() ! 356: { ! 357: DeleteObject(hbrBackground); ! 358: DeleteObject(hpenHilight); ! 359: DeleteObject(hpenLowlight); ! 360: DeleteObject(hpenBlack); ! 361: DeleteObject(hpenNeutral); ! 362: ! 363: #ifdef COMPLEX ! 364: DeleteObject(hFont); ! 365: #endif ! 366: } ! 367: ! 368: /*************************************************************************** ! 369: * Function: StatusWndProc ! 370: * ! 371: * Purpose: ! 372: * ! 373: * Main winproc for status windows ! 374: * ! 375: * handles create/destroy and paint requests ! 376: */ ! 377: ! 378: long FAR PASCAL ! 379: StatusWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam) ! 380: { ! 381: HANDLE hitems; ! 382: PSTATEL ip; ! 383: PILIST plist; ! 384: CREATESTRUCT FAR * cp; ! 385: int i; ! 386: HDC hDC; ! 387: RECT rc; ! 388: POINT pt; ! 389: ! 390: switch(message) { ! 391: ! 392: case WM_CREATE: ! 393: cp = (CREATESTRUCT FAR *) lParam; ! 394: hitems = (HANDLE) (LONG) cp->lpCreateParams; ! 395: SetWindowLong(hWnd, 0, (LONG)hitems); ! 396: plist = (PILIST) GlobalLock(hitems); ! 397: if (plist != NULL) { ! 398: plist->selitem = -1; ! 399: GlobalUnlock(hitems); ! 400: } ! 401: break; ! 402: ! 403: case WM_SIZE: ! 404: hitems = (HANDLE) GetWindowLong(hWnd, 0); ! 405: plist = (PILIST) GlobalLock(hitems); ! 406: if (plist != NULL) { ! 407: StatusResize(hWnd, plist); ! 408: GlobalUnlock(hitems); ! 409: } ! 410: break; ! 411: ! 412: case WM_PAINT: ! 413: hitems = (HANDLE) GetWindowLong(hWnd, 0); ! 414: plist = (PILIST) GlobalLock(hitems); ! 415: StatusPaint(hWnd, plist); ! 416: GlobalUnlock(hitems); ! 417: ! 418: break; ! 419: ! 420: case WM_LBUTTONUP: ! 421: hitems = (HANDLE) GetWindowLong(hWnd, 0); ! 422: plist = (PILIST) GlobalLock(hitems); ! 423: pt.x = LOWORD(lParam); ! 424: pt.y = HIWORD(lParam); ! 425: ! 426: if (plist == NULL) { ! 427: break; ! 428: } ! 429: if (plist->selitem != -1) { ! 430: ip = &plist->statels[plist->selitem]; ! 431: if (plist->isselected) { ! 432: hDC = GetDC(hWnd); ! 433: InitDC(hDC); ! 434: StatusButtonUp(hDC, ip); ! 435: ReleaseDC(hWnd, hDC); ! 436: } ! 437: plist->selitem = -1; ! 438: ReleaseCapture(); ! 439: if (PtInRect(&ip->rc, pt)) { ! 440: SendMessage(GetParent(hWnd), WM_COMMAND, ! 441: MAKELONG(ip->id, WM_LBUTTONUP), (LONG)hWnd); ! 442: } ! 443: } ! 444: GlobalUnlock(hitems); ! 445: break; ! 446: ! 447: case WM_LBUTTONDOWN: ! 448: hitems = (HANDLE) GetWindowLong(hWnd, 0); ! 449: plist = (PILIST) GlobalLock(hitems); ! 450: if (plist == NULL) { ! 451: break; ! 452: } ! 453: pt.x = LOWORD(lParam); ! 454: pt.y = HIWORD(lParam); ! 455: if (plist->selitem == -1) { ! 456: for (i = 0; i< plist->nitems; i++) { ! 457: ip = &plist->statels[i]; ! 458: if (PtInRect(&ip->rc, pt)) { ! 459: if (ip->type != SF_BUTTON) { ! 460: break; ! 461: } ! 462: plist->selitem = i; ! 463: SetCapture(hWnd); ! 464: ! 465: plist->isselected = TRUE; ! 466: hDC = GetDC(hWnd); ! 467: InitDC(hDC); ! 468: StatusButtonDown(hDC, ip); ! 469: ReleaseDC(hWnd, hDC); ! 470: break; ! 471: } ! 472: } ! 473: } ! 474: GlobalUnlock(hitems); ! 475: break; ! 476: ! 477: case WM_MOUSEMOVE: ! 478: hitems = (HANDLE) GetWindowLong(hWnd, 0); ! 479: plist = (PILIST) GlobalLock(hitems); ! 480: if (plist == NULL) { ! 481: break; ! 482: } ! 483: pt.x = LOWORD(lParam); ! 484: pt.y = HIWORD(lParam); ! 485: if (plist->selitem != -1) { ! 486: ip = &plist->statels[plist->selitem]; ! 487: if (PtInRect(&ip->rc, pt)) { ! 488: if (!plist->isselected) { ! 489: hDC = GetDC(hWnd); ! 490: InitDC(hDC); ! 491: StatusButtonDown(hDC, ip); ! 492: ReleaseDC(hWnd, hDC); ! 493: plist->isselected = TRUE; ! 494: } ! 495: } else { ! 496: if(plist->isselected) { ! 497: hDC = GetDC(hWnd); ! 498: InitDC(hDC); ! 499: StatusButtonUp(hDC, ip); ! 500: ReleaseDC(hWnd, hDC); ! 501: plist->isselected = FALSE; ! 502: } ! 503: } ! 504: } ! 505: GlobalUnlock(hitems); ! 506: break; ! 507: ! 508: ! 509: case WM_DESTROY: ! 510: ! 511: hitems = (HANDLE) GetWindowLong(hWnd, 0); ! 512: GlobalUnlock(hitems); ! 513: GlobalFree(hitems); ! 514: ! 515: SetWindowLong(hWnd, 0, 0L); ! 516: break; ! 517: ! 518: case SM_NEW: ! 519: hitems = (HANDLE) GetWindowLong(hWnd, 0); ! 520: if (hitems != NULL) { ! 521: GlobalFree(hitems); ! 522: } ! 523: hitems = (HANDLE) wParam; ! 524: if (hitems == NULL) { ! 525: SetWindowLong(hWnd, 0, 0L); ! 526: InvalidateRect(hWnd, NULL, TRUE); ! 527: break; ! 528: } ! 529: plist = (PILIST) GlobalLock(hitems); ! 530: if (plist == NULL) { ! 531: SetWindowLong(hWnd, 0, 0L); ! 532: InvalidateRect(hWnd, NULL, TRUE); ! 533: break; ! 534: } ! 535: plist->selitem = -1; ! 536: StatusResize(hWnd, plist); ! 537: GlobalUnlock(hitems); ! 538: SetWindowLong(hWnd, 0, (LONG)hitems); ! 539: InvalidateRect(hWnd, NULL, TRUE); ! 540: break; ! 541: ! 542: case SM_SETTEXT: ! 543: hitems = (HANDLE) GetWindowLong(hWnd, 0); ! 544: if (hitems == NULL) { ! 545: break; ! 546: } ! 547: plist = (PILIST) GlobalLock(hitems); ! 548: ip = StatusGetItem(plist, wParam); ! 549: if (ip != NULL) { ! 550: if (lParam == 0) { ! 551: ip->text[0] = '\0'; ! 552: } else { ! 553: strncpy(ip->text, (LPSTR) lParam, SF_MAXLABEL); ! 554: ip->text[SF_MAXLABEL] = '\0'; ! 555: } ! 556: ! 557: /* if this is a variable width field, we need to redo ! 558: * all size calcs in case the field width has changed. ! 559: * in that case, we need to repaint the entire window ! 560: * and not just this field - so set rc to indicate the ! 561: * area to be redrawn. ! 562: */ ! 563: if (ip->flags & SF_VAR) { ! 564: StatusResize(hWnd, plist); ! 565: GetClientRect(hWnd, &rc); ! 566: RedrawWindow(hWnd, &rc, NULL, ! 567: RDW_INVALIDATE|RDW_ERASE|RDW_UPDATENOW); ! 568: } else { ! 569: /* instead of just invalidating the window, we can ! 570: * force the window to be repainted now. This is ! 571: * essential for status updates during a busy ! 572: * loop when no messages are being processed, ! 573: * but we should still update the user on what's ! 574: * happening. ! 575: */ ! 576: RedrawWindow(hWnd, &ip->rc, NULL, ! 577: RDW_INVALIDATE|RDW_NOERASE|RDW_UPDATENOW); ! 578: } ! 579: ! 580: } ! 581: GlobalUnlock(hitems); ! 582: break; ! 583: ! 584: default: ! 585: return(DefWindowProc(hWnd, message, wParam, lParam)); ! 586: } ! 587: return 0; ! 588: } ! 589: ! 590: /*************************************************************************** ! 591: * Function: StatusResize ! 592: * ! 593: * Purpose: ! 594: * ! 595: * Position the labels and buttons within the status window ! 596: */ ! 597: void ! 598: StatusResize(HWND hWnd, PILIST iplistp) ! 599: { ! 600: RECT rc; ! 601: int curpos_right, curpos_left; ! 602: int height, width; ! 603: int i; ! 604: PSTATEL ip; ! 605: ! 606: ! 607: if (iplistp == NULL) { ! 608: return; ! 609: } ! 610: GetClientRect(hWnd, &rc); ! 611: curpos_left = rc.left + status_charwidth / 2; ! 612: curpos_right = rc.right - (status_charwidth / 2); ! 613: ! 614: /* loop through all items setting their position rects. ! 615: * items are flagged as being left or right. We place them ! 616: * in order starting at the left and the right, with a single ! 617: * char's width between each item ! 618: */ ! 619: for (i = 0; i < iplistp->nitems; i++) { ! 620: ip = &iplistp->statels[i]; ! 621: ! 622: width = StatusCalcWidth(hWnd, ip); ! 623: height = StatusCalcHeight(hWnd, ip); ! 624: ip->rc.top = (rc.bottom - height) / 2; ! 625: ip->rc.bottom = ip->rc.top + height; ! 626: ! 627: /* see if this item fits. Items that partially fit ! 628: * are placed reduced in size. ! 629: */ ! 630: if (ip->flags & SF_LEFT) { ! 631: ! 632: if (curpos_left+width >= curpos_right) { ! 633: /* doesn't completely fit-does it partly? */ ! 634: if ((curpos_left + 1) >= curpos_right){ ! 635: ! 636: /* no - this item does not fit */ ! 637: ip->rc.left = 0; ! 638: ip->rc.right = 0; ! 639: } else { ! 640: /* partial fit */ ! 641: ip->rc.left = curpos_left; ! 642: ip->rc.right = curpos_right - 1; ! 643: curpos_left = curpos_right; ! 644: } ! 645: } else { ! 646: /* complete fit */ ! 647: ip->rc.left = curpos_left; ! 648: ip->rc.right = curpos_left + width; ! 649: curpos_left += width + 1; ! 650: } ! 651: } else { ! 652: ! 653: /* same size check for right-aligned items */ ! 654: if (curpos_right-width <= curpos_left) { ! 655: ! 656: /* partial fit ? */ ! 657: if (curpos_right <= curpos_left+1) { ! 658: ip->rc.left = 0; ! 659: ip->rc.right = 0; ! 660: } else { ! 661: /* yes - partial fit */ ! 662: ip->rc.left = curpos_left + 1; ! 663: ip->rc.right = curpos_right; ! 664: curpos_right = curpos_left; ! 665: } ! 666: } else { ! 667: /* complete fit */ ! 668: ip->rc.right = curpos_right; ! 669: ip->rc.left = curpos_right - width; ! 670: curpos_right -= (width + 1); ! 671: } ! 672: } ! 673: } ! 674: } ! 675: ! 676: ! 677: /*************************************************************************** ! 678: * Function: StatusPaint ! 679: * ! 680: * Purpose: ! 681: * ! 682: * Paint the status window ! 683: */ ! 684: void ! 685: StatusPaint(HWND hWnd, PILIST iplistp) ! 686: { ! 687: RECT rc; ! 688: HDC hDC; ! 689: PAINTSTRUCT ps; ! 690: int i; ! 691: PSTATEL ip; ! 692: HPEN hpenOld; ! 693: ! 694: GetClientRect(hWnd, &rc); ! 695: hDC = BeginPaint(hWnd, &ps); ! 696: InitDC(hDC); ! 697: ! 698: RaiseRect(hDC, &rc); ! 699: if (iplistp == NULL) { ! 700: EndPaint(hWnd, &ps); ! 701: return; ! 702: } ! 703: for (i =0; i < iplistp->nitems; i++) { ! 704: ip = &iplistp->statels[i]; ! 705: ! 706: if (ip->rc.left == ip->rc.right) { ! 707: continue; ! 708: } ! 709: if (ip->type == SF_STATIC) { ! 710: if (ip->flags & SF_RAISE) { ! 711: RaiseRect(hDC, &ip->rc); ! 712: } else if (ip->flags & SF_LOWER) { ! 713: LowerRect(hDC, &ip->rc); ! 714: } ! 715: rc = ip->rc; ! 716: rc.left += (status_charwidth / 2); ! 717: rc.right--; ! 718: rc.top++; ! 719: rc.bottom--; ! 720: hpenOld = SelectObject(hDC, hpenNeutral); ! 721: Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); ! 722: SelectObject(hDC, hpenOld); ! 723: DrawText(hDC, ip->text, lstrlen(ip->text), &rc, ! 724: DT_LEFT | DT_VCENTER); ! 725: } else { ! 726: StatusButtonUp(hDC, ip); ! 727: } ! 728: } ! 729: ! 730: EndPaint(hWnd, &ps); ! 731: } ! 732: ! 733: /*************************************************************************** ! 734: * Function: RaiseRect ! 735: * ! 736: * Purpose: ! 737: * ! 738: */ ! 739: void ! 740: RaiseRect(HDC hDC, LPRECT rcp) ! 741: { ! 742: TopLeft(hDC, rcp, hpenHilight, FALSE); ! 743: BottomRight(hDC, rcp, hpenLowlight, FALSE); ! 744: } ! 745: ! 746: /*************************************************************************** ! 747: * Function: LowerRect ! 748: * ! 749: * Purpose: ! 750: * ! 751: */ ! 752: void ! 753: LowerRect(HDC hDC, LPRECT rcp) ! 754: { ! 755: TopLeft(hDC, rcp, hpenLowlight, FALSE); ! 756: BottomRight(hDC, rcp, hpenHilight, FALSE); ! 757: } ! 758: ! 759: /*************************************************************************** ! 760: * Function: StatusButtonUp ! 761: * ! 762: * Purpose: ! 763: * ! 764: */ ! 765: void ! 766: StatusButtonUp(HDC hDC, PSTATEL ip) ! 767: { ! 768: RECT rc; ! 769: HPEN hpenOld; ! 770: ! 771: rc = ip->rc; ! 772: TopLeft(hDC, &rc, hpenBlack, TRUE); ! 773: BottomRight(hDC, &rc, hpenBlack, FALSE); ! 774: ! 775: rc.top++; ! 776: rc.bottom--; ! 777: rc.left++; ! 778: rc.right--; ! 779: TopLeft(hDC, &rc, hpenHilight, FALSE); ! 780: BottomRight(hDC, &rc, hpenLowlight, TRUE); ! 781: ! 782: rc.top++; ! 783: rc.bottom--; ! 784: rc.left++; ! 785: rc.right--; ! 786: BottomRight(hDC, &rc, hpenLowlight, TRUE); ! 787: rc.bottom--; ! 788: rc.right--; ! 789: hpenOld = SelectObject(hDC, hpenNeutral); ! 790: Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); ! 791: SelectObject(hDC, hpenOld); ! 792: DrawText(hDC, ip->text, lstrlen(ip->text), &rc, DT_CENTER | DT_VCENTER); ! 793: } ! 794: ! 795: /*************************************************************************** ! 796: * Function: StatusButtonDown ! 797: * ! 798: * Purpose: ! 799: * ! 800: */ ! 801: void ! 802: StatusButtonDown(HDC hDC, PSTATEL ip) ! 803: { ! 804: RECT rc; ! 805: HPEN hpenOld; ! 806: ! 807: rc = ip->rc; ! 808: TopLeft(hDC, &rc, hpenBlack, TRUE); ! 809: BottomRight(hDC, &rc, hpenBlack, FALSE); ! 810: ! 811: rc.top++; ! 812: rc.bottom--; ! 813: rc.left++; ! 814: rc.right--; ! 815: TopLeft(hDC, &rc, hpenLowlight, TRUE); ! 816: rc.top++; ! 817: rc.left++; ! 818: TopLeft(hDC, &rc, hpenNeutral, TRUE); ! 819: rc.top++; ! 820: rc.left++; ! 821: TopLeft(hDC, &rc, hpenNeutral, TRUE); ! 822: rc.top++; ! 823: rc.left++; ! 824: hpenOld = SelectObject(hDC, hpenNeutral); ! 825: Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); ! 826: SelectObject(hDC, hpenOld); ! 827: DrawText(hDC, ip->text, lstrlen(ip->text), &rc, DT_CENTER | DT_VCENTER); ! 828: } ! 829: ! 830: /*************************************************************************** ! 831: * Function: TopLeft ! 832: * ! 833: * Purpose: ! 834: * ! 835: */ ! 836: void ! 837: TopLeft(HDC hDC, LPRECT rcp, HPEN hpen, BOOL bCorners) ! 838: { ! 839: HPEN hpenOld; ! 840: int x, y; ! 841: ! 842: hpenOld = SelectObject(hDC, hpen); ! 843: x = rcp->right - 1; ! 844: y = rcp->bottom; ! 845: if (!bCorners) { ! 846: x--; ! 847: y--; ! 848: } ! 849: MoveToEx(hDC, x, rcp->top, NULL); ! 850: LineTo(hDC, rcp->left, rcp->top); ! 851: LineTo(hDC, rcp->left, y); ! 852: SelectObject(hDC, hpenOld); ! 853: } ! 854: ! 855: /*************************************************************************** ! 856: * Function: BottomRight ! 857: * ! 858: * Purpose: ! 859: * ! 860: */ ! 861: void ! 862: BottomRight(HDC hDC, LPRECT rcp, HPEN hpen, BOOL bCorners) ! 863: { ! 864: HPEN hpenOld; ! 865: int x, y; ! 866: ! 867: hpenOld = SelectObject(hDC, hpen); ! 868: x = rcp->left - 1; ! 869: y = rcp->top; ! 870: if (!bCorners) { ! 871: x++; ! 872: y++; ! 873: } ! 874: MoveToEx(hDC, rcp->right-1, y, NULL); ! 875: LineTo(hDC, rcp->right-1, rcp->bottom-1); ! 876: LineTo(hDC, x, rcp->bottom-1); ! 877: SelectObject(hDC, hpenOld); ! 878: } ! 879: ! 880: /*************************************************************************** ! 881: * Function: StatusGetItem ! 882: * ! 883: * Purpose: ! 884: * ! 885: */ ! 886: PSTATEL ! 887: StatusGetItem(PILIST plist, int id) ! 888: { ! 889: int i; ! 890: ! 891: if (plist == NULL) { ! 892: return(NULL); ! 893: } ! 894: for (i = 0; i < plist->nitems; i++) { ! 895: if (plist->statels[i].id == id) { ! 896: return(&plist->statels[i]); ! 897: } ! 898: } ! 899: return(NULL); ! 900: } ! 901: ! 902: /*************************************************************************** ! 903: * Function: StatusCalcWidth ! 904: * ! 905: * Purpose: ! 906: * ! 907: * Calculate the width of a given field. This is the width in characters ! 908: * multiplied by the average character width, plus a few units for ! 909: * borders. ! 910: * ! 911: * If SF_VAR is set, this field size varies depending on the text, so ! 912: * we use GetTextExtent for the field size. If SF_VAR is selected, the caller ! 913: * can specify that the size is not to exceed the (width * avecharwidth) ! 914: * size (using SF_SZMAX) or that it is not be less than it (SF_SZMIN). ! 915: */ ! 916: int ! 917: StatusCalcWidth(HWND hWnd, PSTATEL ip) ! 918: { ! 919: int ch_size, t_size; ! 920: SIZE sz; ! 921: HDC hDC; ! 922: ! 923: ch_size = ip->width * status_charwidth; ! 924: if (ip->flags & SF_VAR) { ! 925: hDC = GetDC(hWnd); ! 926: InitDC(hDC); ! 927: GetTextExtentPoint(hDC, ip->text, lstrlen(ip->text), &sz); ! 928: ReleaseDC(hWnd, hDC); ! 929: t_size = sz.cx; ! 930: ! 931: /* ! 932: * check this size against min/max size if ! 933: * requested ! 934: */ ! 935: ! 936: if (ip->flags & SF_SZMIN) { ! 937: if (ch_size > t_size) { ! 938: t_size = ch_size; ! 939: } ! 940: } ! 941: if (ip->flags & SF_SZMAX) { ! 942: if (ch_size < t_size) { ! 943: t_size = ch_size; ! 944: } ! 945: } ! 946: ch_size = t_size; ! 947: } ! 948: ! 949: if (ch_size != 0) { ! 950: if (ip->type == SF_BUTTON) { ! 951: return(ch_size+6); ! 952: } else { ! 953: return(ch_size+4); ! 954: } ! 955: } else { ! 956: return(0); ! 957: } ! 958: } ! 959: ! 960: /*************************************************************************** ! 961: * Function: StatusCalcHeight ! 962: * ! 963: * Purpose: ! 964: * ! 965: * Calculate the height of a given field ! 966: */ ! 967: int ! 968: StatusCalcHeight(HWND hWnd, PSTATEL ip) ! 969: { ! 970: int size; ! 971: ! 972: size = status_charheight; ! 973: if (ip->type == SF_BUTTON) { ! 974: return(size + 6); ! 975: } else { ! 976: return(size + 2); ! 977: } ! 978: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.