Annotation of mstools/samples/sdktools/windiff/status.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.