Annotation of mstools/samples/sdktools/windiff/status.c, revision 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.