Annotation of mstools/samples/fontview/status.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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