Annotation of mstools/samples/ddeml/client/infoctrl.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       root       12: /***************************************************************************
                     13:  *                                                                         *
                     14:  *  MODULE      : infoctrl.c                                               *
                     15:  *                                                                         *
                     16:  *  PURPOSE     : Functions for the infoctrl control class                 *
                     17:  *                                                                         *
                     18:  ***************************************************************************/
                     19: /*
                     20:  * INFOCTRL.C
                     21:  *
                     22:  * This module implements a custom information display control which
                     23:  * can present up to 7 seperate strings of information at once and is
                     24:  * sizeable and moveable with the mouse.
                     25:  */
                     26: 
                     27: #include <windows.h>
                     28: #include <string.h>
                     29: #include <memory.h>
                     30: #include "infoctrl.h"
                     31: #include "track.h"
                     32: 
                     33: CHAR szClass[] = "InfoCtrl_class";
                     34: DWORD cCreated = 0;
                     35: CHAR szNULL[] = "";
                     36: INT cxMargin = 0;
                     37: INT cyMargin = 0;
                     38: HBRUSH hFocusBrush;
                     39: 
                     40: 
1.1.1.2   root       41: LONG  APIENTRY InfoCtrlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
1.1       root       42: VOID MyDrawText(HDC hdc, LPRECT lprc, PSTR psz, DWORD wFormat);
                     43: VOID DrawFocus(HDC hdc, HWND hwnd, DWORD style);
                     44: INT CountWindows(HWND hwndParent);
                     45: VOID GetCascadeWindowPos(HWND hwndParent, INT  iWindow, LPRECT lprc);
                     46: 
                     47: 
                     48: /****************************************************************************
                     49:  *                                                                          *
                     50:  *  FUNCTION   :                                                            *
                     51:  *                                                                          *
                     52:  *  PURPOSE    :                                                            *
                     53:  *                                                                          *
                     54:  *  RETURNS    :                                                            *
                     55:  *                                                                          *
                     56:  ****************************************************************************/
                     57: HWND CreateInfoCtrl(
                     58: LPSTR pszCenter,              // NULL is ok.
                     59: INT x,
                     60: INT y,
                     61: INT cx,
                     62: INT cy,
                     63: HWND hwndParent,
                     64: HANDLE hInst,
                     65: LPSTR pszUL,                // NULLs here are fine.
                     66: LPSTR pszUC,
                     67: LPSTR pszUR,
                     68: LPSTR pszLL,
                     69: LPSTR pszLC,
                     70: LPSTR pszLR,
                     71: DWORD  style,
                     72: HMENU id,
                     73: DWORD dwUser)
                     74: {
                     75:     INFOCTRL_DATA *picd;
                     76:     HWND hwnd;
                     77: 
                     78:     if (!cCreated) {
                     79:         WNDCLASS wc;
                     80:         TEXTMETRIC metrics;
                     81:         HDC hdc;
                     82: 
                     83:         wc.style = CS_VREDRAW | CS_HREDRAW;
1.1.1.2   root       84:         wc.lpfnWndProc = InfoCtrlWndProc;
1.1       root       85:         wc.cbClsExtra = 0;
                     86:         wc.cbWndExtra = ICCBWNDEXTRA;
                     87:         wc.hInstance = hInst;
                     88:         wc.hIcon = NULL;
                     89:         wc.hCursor = NULL;
                     90:         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
                     91:         wc.lpszMenuName =  NULL;
                     92:         wc.lpszClassName = szClass;
                     93: 
                     94:         RegisterClass(&wc);
                     95: 
                     96:         hdc = GetDC(hwndParent);
                     97:         GetTextMetrics(hdc, &metrics);
                     98:         cyMargin = metrics.tmHeight;
                     99:         cxMargin = metrics.tmAveCharWidth * 2;
                    100:         ReleaseDC(hwndParent, hdc);
                    101:         hFocusBrush = CreateSolidBrush(RGB(0, 0, 255));
                    102:     }
                    103: 
                    104:     if (!(picd = (INFOCTRL_DATA *)LocalAlloc(LPTR, sizeof(INFOCTRL_DATA))))
                    105:         return(FALSE);
                    106: 
                    107:     if (pszCenter) {
1.1.1.2   root      108:         picd->pszCenter = (PSTR)(PSTR)LocalAlloc(LPTR, strlen(pszCenter) + 1);
                    109:         strcpy(picd->pszCenter, pszCenter);
1.1       root      110:     } else {
                    111:         picd->pszCenter = NULL;
                    112:     }
                    113: 
                    114:     if (pszUL) {
1.1.1.2   root      115:         picd->pszUL = (PSTR)(PSTR)LocalAlloc(LPTR, strlen(pszUL) + 1);
                    116:         strcpy(picd->pszUL, pszUL);
1.1       root      117:     } else {
                    118:         picd->pszUL = NULL;
                    119:     }
                    120:     if (pszUC) {
1.1.1.2   root      121:         picd->pszUC = (PSTR)LocalAlloc(LPTR, strlen(pszUC) + 1);
                    122:         strcpy(picd->pszUC, pszUC);
1.1       root      123:     } else {
                    124:         picd->pszUC = NULL;
                    125:     }
                    126:     if (pszUR) {
1.1.1.2   root      127:         picd->pszUR = (PSTR)LocalAlloc(LPTR, strlen(pszUR) + 1);
                    128:         strcpy(picd->pszUR, pszUR);
1.1       root      129:     } else {
                    130:         picd->pszUR = NULL;
                    131:     }
                    132:     if (pszLL) {
1.1.1.2   root      133:         picd->pszLL = (PSTR)LocalAlloc(LPTR, strlen(pszLL) + 1);
                    134:         strcpy(picd->pszLL, pszLL);
1.1       root      135:     } else {
                    136:         picd->pszLL = NULL;
                    137:     }
                    138:     if (pszLC) {
1.1.1.2   root      139:         picd->pszLC = (PSTR)LocalAlloc(LPTR, strlen(pszLC) + 1);
                    140:         strcpy(picd->pszLC, pszLC);
1.1       root      141:     } else {
                    142:         picd->pszLC = NULL;
                    143:     }
                    144:     if (pszLR) {
1.1.1.2   root      145:         picd->pszLR = (PSTR)LocalAlloc(LPTR, strlen(pszLR) + 1);
                    146:         strcpy(picd->pszLR, pszLR);
1.1       root      147:     } else {
                    148:         picd->pszLR = NULL;
                    149:     }
                    150: 
                    151:     picd->style = style;
                    152:     picd->hInst = hInst;
                    153: 
                    154:     if (hwnd = CreateWindow(szClass, szNULL,
                    155:             WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
                    156:             x, y, cx, cy, hwndParent, id, hInst, (LPSTR)picd)) {
                    157:         cCreated++;
                    158:         SetWindowLong(hwnd, GWL_USER, dwUser);
                    159:         BringWindowToTop(hwnd);
                    160:         ShowWindow(hwnd, SW_SHOW);
                    161:         return(hwnd);
                    162:     }
                    163:     return(FALSE);
                    164: }
                    165: 
                    166: 
                    167: 
                    168: 
                    169: /****************************************************************************
                    170:  *                                                                          *
                    171:  *  FUNCTION   : MyDrawText                                                 *
                    172:  *                                                                          *
                    173:  *  PURPOSE    : Draws psz within lprc in hdc according to wFormat.         *
                    174:  *                                                                          *
                    175:  *  RETURNS    : Nothing.                                                   *
                    176:  *                                                                          *
                    177:  ****************************************************************************/
                    178: VOID MyDrawText(
                    179: HDC hdc,
                    180: LPRECT lprc,
                    181: PSTR psz,
                    182: DWORD wFormat)
                    183: {
                    184:     RECT rc;
                    185:     DWORD cx;
                    186: 
                    187:     if (psz == NULL || !*psz)
                    188:         return; // notin to draw dude.
                    189: 
                    190:     SetRect(&rc, 0, 0, 1, 0);
                    191:     DrawText(hdc, psz, -1, &rc, DT_CALCRECT | DT_NOCLIP | DT_SINGLELINE);
                    192:     cx = min(rc.right - rc.left, lprc->right - lprc->left);
                    193:     CopyRect(&rc, lprc);
                    194:     switch (wFormat & (DT_LEFT | DT_CENTER | DT_RIGHT)) {
                    195:     case DT_LEFT:
                    196:         rc.right = rc.left + cx;
                    197:         break;
                    198: 
                    199:     case DT_CENTER:
                    200:         cx = (rc.right - rc.left - cx) / 2;
                    201:         rc.right -= cx;
                    202:         rc.left += cx;
                    203:         break;
                    204: 
                    205:     case DT_RIGHT:
                    206:         rc.left = rc.right - cx;
                    207:         break;
                    208:     }
                    209:     DrawText(hdc, psz, -1, &rc, wFormat | DT_VCENTER);
                    210: }
                    211: 
                    212: 
                    213: 
                    214: 
                    215: /****************************************************************************
                    216:  *                                                                          *
                    217:  *  FUNCTION   : InfoCtrlWndProc                                            *
                    218:  *                                                                          *
                    219:  *  PURPOSE    : Main window proc for info controls                         *
                    220:  *                                                                          *
                    221:  *  RETURNS    : case dependent                                             *
                    222:  *                                                                          *
                    223:  ****************************************************************************/
                    224: LONG  APIENTRY InfoCtrlWndProc(
                    225: HWND hwnd,
1.1.1.2   root      226: UINT msg,
1.1       root      227: WPARAM wParam,
                    228: LPARAM lParam)
                    229: {
                    230:     INFOCTRL_DATA *picd;
                    231:     INT i;
                    232:     RECT rc;
                    233:     HDC hdc;
                    234: 
                    235:     switch (msg) {
                    236:     case WM_CREATE:
                    237:         /*
                    238:          * Info controls keep their information in the GWL_INFODATA window
                    239:          * word.
                    240:          */
                    241:         SetWindowLong(hwnd, GWL_INFODATA,
                    242:                 (DWORD)(DWORD)(((LPCREATESTRUCT)lParam)->lpCreateParams));
                    243:         break;
                    244: 
                    245:     case WM_SIZE:
                    246:         /*
                    247:          * size the info control, updating the hittest rectangles.
                    248:          * The window is only allowed to get so small.
                    249:          */
                    250:         if ((short)LOWORD(lParam) < 2 * cxMargin || (short)HIWORD(lParam) < 2 * cyMargin) {
                    251:             MoveWindow(hwnd, 0, 0, max((short)LOWORD(lParam), 2 * cxMargin),
                    252:                 max((short)HIWORD(lParam), 2 * cyMargin), TRUE);
                    253:         } else {
                    254:             picd = (INFOCTRL_DATA *)GetWindowLong(hwnd, GWL_INFODATA);
                    255:             SetRect(&picd->rcFocusUL, 0, 0, cxMargin, cyMargin);
                    256:             SetRect(&picd->rcFocusUR, (short)LOWORD(lParam) - cxMargin, 0,
                    257:                     (short)LOWORD(lParam), cyMargin);
                    258:             SetRect(&picd->rcFocusLL, 0, (short)HIWORD(lParam) - cyMargin,
                    259:                     cxMargin, (INT)HIWORD(lParam));
                    260:             SetRect(&picd->rcFocusLR, picd->rcFocusUR.left, picd->rcFocusLL.top,
                    261:                     picd->rcFocusUR.right, picd->rcFocusLL.bottom);
                    262:         }
                    263:         break;
                    264: 
                    265: 
                    266:     case WM_DESTROY:
                    267:         /*
                    268:          * Info control death:
                    269:          *
                    270:          * Inform out parent - last chance to access GWL_USER.
                    271:          * Free our information if it still exists.
                    272:          * Free all strings associated with this control.
                    273:          */
                    274:         {
                    275:             PSTR *ppsz;
                    276: 
                    277:             SendMessage(GetParent(hwnd), ICN_BYEBYE, (WPARAM)hwnd,
                    278:                     GetWindowLong(hwnd, GWL_USER));
                    279:             SetWindowLong(hwnd, GWL_USER, 0);
                    280: 
                    281:             picd = (INFOCTRL_DATA *)GetWindowLong(hwnd, GWL_INFODATA);
                    282:             if (picd) {
                    283:                 ppsz = &picd->pszUL;
                    284:                 for (i = 0; i < 5; i++, ppsz++) {
                    285:                     if (*ppsz) {
                    286:                         LocalUnlock((HANDLE)*ppsz);
                    287:                         *ppsz = (PSTR)LocalFree((HANDLE)*ppsz);
                    288:                     }
                    289:                 }
                    290:                 LocalUnlock((HANDLE)picd);
                    291:                 LocalFree((HANDLE)picd);
                    292:                 SetWindowLong(hwnd, GWL_INFODATA, 0);
                    293:             }
                    294:         }
                    295:         break;
                    296: 
                    297:     case WM_SETFOCUS:
                    298:     case WM_KILLFOCUS:
                    299:         /*
                    300:          * When focus changes:
                    301:          *
                    302:          * Alter our look apropriately
                    303:          * Bring ourselves to the top if necessary.
                    304:          * Inform our parent.
                    305:          * Repaint the focus portion of ourselves.
                    306:          * Call DefWindowProc()
                    307:          */
                    308:         picd = (INFOCTRL_DATA *)GetWindowLong(hwnd, GWL_INFODATA);
                    309:         if (picd != NULL) {
                    310:             if (picd->style & ICSTY_SHOWFOCUS) {
                    311:                 if (msg == WM_SETFOCUS)
                    312:                     picd->style |= ICSTY_HASFOCUS;
                    313:                 else
                    314:                     picd->style &= ~ICSTY_HASFOCUS;
                    315:                 BringWindowToTop(hwnd);
                    316:                 // notify parent
                    317:                 SendMessage(GetParent(hwnd), ICN_HASFOCUS,
                    318:                         msg == WM_SETFOCUS, (LPARAM)hwnd);
                    319:             } else {
                    320:                 picd->style &= ~ICSTY_HASFOCUS;
                    321:             }
                    322:             hdc = GetDC(hwnd);
                    323:             DrawFocus(hdc, hwnd, picd->style);
                    324:             ReleaseDC(hwnd, hdc);
                    325:         }
                    326:         goto DoDWP;
                    327:         break;
                    328: 
                    329:     case WM_MOUSEMOVE:
                    330:         /*
                    331:          * Keep the cursor updated to show sizing or moving state.
                    332:          */
                    333:         {
                    334:             LPSTR cursor;
                    335: 
                    336:             picd = (INFOCTRL_DATA *)GetWindowLong(hwnd, GWL_INFODATA);
                    337:             if (picd->style & ICSTY_SHOWFOCUS) {
                    338: 
                    339:                 if ((INT)HIWORD(lParam) < cyMargin) {
                    340:                     if ((short)LOWORD(lParam) < cxMargin) {
                    341:                         cursor = IDC_SIZENWSE;
                    342:                     } else if ((short)LOWORD(lParam) > picd->rcFocusUR.left) {
                    343:                         cursor = IDC_SIZENESW;
                    344:                     } else {
                    345:                         cursor = IDC_SIZENS;
                    346:                     }
                    347:                 } else if ((INT)HIWORD(lParam) > picd->rcFocusLL.top) {
                    348:                     if ((short)LOWORD(lParam) < cxMargin) {
                    349:                         cursor = IDC_SIZENESW;
                    350:                     } else if ((short)LOWORD(lParam) > picd->rcFocusUR.left) {
                    351:                         cursor = IDC_SIZENWSE;
                    352:                     } else {
                    353:                         cursor = IDC_SIZENS;
                    354:                     }
                    355:                 } else {
                    356:                     if ((short)LOWORD(lParam) < cxMargin) {
                    357:                         cursor = IDC_SIZEWE;
                    358:                     } else if ((short)LOWORD(lParam) > picd->rcFocusUR.left) {
                    359:                         cursor = IDC_SIZEWE;
                    360:                     } else {
                    361:                         cursor = IDC_CROSS;
                    362:                     }
                    363:                 }
                    364:             } else {
                    365:                 cursor = IDC_ARROW;
                    366:             }
                    367:             SetCursor(LoadCursor(NULL, cursor));
                    368:         }
                    369:         break;
                    370: 
                    371:     case WM_LBUTTONDOWN:
                    372:         /*
                    373:          * Track window according do mouse location.
                    374:          */
                    375:         picd = (INFOCTRL_DATA *)GetWindowLong(hwnd, GWL_INFODATA);
                    376:         if (picd->style & ICSTY_SHOWFOCUS) {
                    377:             DWORD fs = 0;
                    378: 
                    379:             if (!(picd->style & ICSTY_HASFOCUS)) {
                    380:                 SetFocus(hwnd);
                    381:             }
                    382: 
                    383:             if ((short)HIWORD(lParam) < cyMargin) {
                    384:                 fs = TF_TOP;
                    385:             } else if ((INT)HIWORD(lParam) > picd->rcFocusLL.top) {
                    386:                 fs = TF_BOTTOM;
                    387:             }
                    388:             if ((short)LOWORD(lParam) < cxMargin) {
                    389:                 fs |= TF_LEFT;
                    390:             } else if ((short)LOWORD(lParam) > picd->rcFocusUR.left) {
                    391:                 fs |= TF_RIGHT;
                    392:             } else if (fs == 0) {
                    393:                 fs = TF_MOVE;
                    394:             }
                    395: 
                    396:             GetClientRect(hwnd, &rc);
                    397:             ClientToScreen(hwnd, (LPPOINT)&rc.left);
                    398:             ClientToScreen(hwnd, (LPPOINT)&rc.right);
                    399:             ScreenToClient(GetParent(hwnd), (LPPOINT)&rc.left);
                    400:             ScreenToClient(GetParent(hwnd), (LPPOINT)&rc.right);
                    401:             if (TrackRect(picd->hInst, GetParent(hwnd),
                    402:                     rc.left, rc.top, rc.right, rc.bottom,
                    403:                     2 * cxMargin, 2 * cyMargin,
                    404:                     fs | TF_ALLINBOUNDARY, &rc)) {
                    405: 
                    406:                 MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left,
                    407:                         rc.bottom - rc.top, TRUE);
                    408:             }
                    409:         }
                    410:         break;
                    411: 
                    412:     case ICM_SETSTRING:
                    413:         /*
                    414:          * This message is sent when a info control string value is changeing.
                    415:          *
                    416:          * wParam = ICSID_ constant
                    417:          * lParam = new string.
                    418:          *
                    419:          * If new string is different from old, free old and allocate space
                    420:          * for new one and copy in.
                    421:          * Redraw invalidated part of info control.
                    422:          */
                    423:         {
                    424:             PSTR *ppsz;
                    425: 
                    426:             picd = (INFOCTRL_DATA *)GetWindowLong(hwnd, GWL_INFODATA);
                    427:             ppsz = (PSTR *)&picd->pszUL + wParam;
                    428: 
1.1.1.3 ! root      429:             if (lParam == 0)
1.1       root      430:                 lParam = (DWORD)(LPSTR)szNULL;
                    431: 
                    432:             if (*ppsz) {
1.1.1.2   root      433:                 if (!strcmp(*ppsz, (LPSTR)lParam)) {
1.1       root      434:                     return 0;
                    435:                 }
                    436:                 LocalUnlock((HANDLE)*ppsz);
                    437:                 *ppsz = (PSTR)LocalFree((HANDLE)*ppsz);
                    438:             }
                    439:             if (lParam) {
1.1.1.2   root      440:                 *ppsz = (PSTR)LocalAlloc(LPTR, strlen((LPSTR)lParam) + 1);
                    441:                 strcpy((LPSTR)*ppsz, (LPSTR)lParam);
1.1       root      442:             }
                    443:             GetClientRect(hwnd, &rc);
                    444:             switch (wParam) {
                    445:             case ICSID_UL:
                    446:             case ICSID_UC:
                    447:             case ICSID_UR:
                    448:                 rc.bottom = cyMargin;
                    449:                 break;
                    450: 
                    451:             case ICSID_LL:
                    452:             case ICSID_LC:
                    453:             case ICSID_LR:
                    454:                 rc.top = rc.bottom - cyMargin;
                    455:                 break;
                    456: 
                    457:             case ICSID_CENTER:
                    458:                 InflateRect(&rc, -cxMargin, -cyMargin);
                    459:                 break;
                    460:             }
                    461:             InvalidateRect(hwnd, &rc, TRUE);
                    462:             UpdateWindow(hwnd);
                    463:         }
                    464:         break;
                    465: 
                    466:     case WM_PAINT:
                    467:         /*
                    468:          * Paint ourselves.
                    469:          *
                    470:          * Draw frame.
                    471:          * Draw info strings.
                    472:          * Send ownerdraw message to parent if ICSTY_OWNERDRAW.
                    473:          */
                    474:         {
                    475:             PAINTSTRUCT ps;
                    476:             HANDLE brush;
                    477: 
                    478:             picd = (INFOCTRL_DATA *)GetWindowLong(hwnd, GWL_INFODATA);
                    479:             BeginPaint(hwnd, &ps);
                    480:             // erasure should have already been done for us.
                    481:             GetClientRect(hwnd, &rc);
                    482:             brush = GetStockObject(BLACK_BRUSH);
                    483:             InflateRect(&rc, -cxMargin / 2, -cyMargin / 2);
                    484:             FrameRect(ps.hdc, &rc, brush);
                    485:             InflateRect(&rc, cxMargin / 2, cyMargin / 2);
                    486:             SetRect(&rc, picd->rcFocusUL.right, 0, picd->rcFocusUR.left,
                    487:                     cyMargin);
                    488:             MyDrawText(ps.hdc, &rc, picd->pszUR, DT_RIGHT);
                    489:             MyDrawText(ps.hdc, &rc, picd->pszUL, DT_LEFT);
                    490:             MyDrawText(ps.hdc, &rc, picd->pszUC, DT_CENTER);
                    491:             SetRect(&rc, picd->rcFocusLL.right, picd->rcFocusLL.top,
                    492:                     picd->rcFocusLR.left, picd->rcFocusLR.bottom);
                    493:             MyDrawText(ps.hdc, &rc, picd->pszLR, DT_RIGHT);
                    494:             MyDrawText(ps.hdc, &rc, picd->pszLL, DT_LEFT);
                    495:             MyDrawText(ps.hdc, &rc, picd->pszLC, DT_CENTER);
                    496: 
                    497:             GetClientRect(hwnd, &rc);
                    498:             InflateRect(&rc, -cxMargin, -cyMargin);
                    499:             if (picd->style & ICSTY_OWNERDRAW) {
                    500:                 OWNERDRAWPS odps;
                    501: 
                    502:                 if (IntersectRect(&odps.rcPaint, &rc, &ps.rcPaint)) {
                    503:                     if (IntersectClipRect(ps.hdc, rc.left, rc.top, rc.right,
                    504:                             rc.bottom) != NULLREGION) {
                    505:                         odps.rcBound = rc;
                    506:                         odps.hdc = ps.hdc;
                    507:                         odps.dwUser = GetWindowLong(hwnd, GWL_USER);
                    508:                         SendMessage(GetParent(hwnd), ICN_OWNERDRAW,
                    509:                                 GetWindowLong(hwnd, GWL_ID), (DWORD)(LPSTR)&odps);
                    510:                     }
                    511:                 }
                    512:             } else {
                    513:                 MyDrawText(ps.hdc, &rc, picd->pszCenter, DT_LEFT | DT_WORDBREAK | DT_EXPANDTABS);
                    514:             }
                    515:             DrawFocus(ps.hdc, hwnd, picd->style);
                    516:             EndPaint(hwnd, &ps);
                    517:         }
                    518:         break;
                    519: 
                    520: DoDWP:
                    521:     default:
                    522:         return (DefWindowProc(hwnd, msg, wParam, lParam));
                    523:     }
1.1.1.3 ! root      524:     return (0);
1.1       root      525: }
                    526: 
                    527: 
                    528: /****************************************************************************
                    529:  *                                                                          *
                    530:  *  FUNCTION   : DrawFocus                                                  *
                    531:  *                                                                          *
                    532:  *  PURPOSE    : To draw focus part of info control.                        *
                    533:  *                                                                          *
                    534:  *  RETURNS    : nothing                                                    *
                    535:  *                                                                          *
                    536:  ****************************************************************************/
                    537: VOID DrawFocus(
                    538: HDC hdc,
                    539: HWND hwnd,
                    540: DWORD style)
                    541: {
                    542:     RECT rc;
                    543: 
                    544:     GetClientRect(hwnd, &rc);
                    545:     FrameRect(hdc, &rc, style & ICSTY_HASFOCUS ?
                    546:             hFocusBrush : GetStockObject(GRAY_BRUSH));
                    547: }
                    548: 
                    549: 
                    550: 
                    551: 
                    552: /****************************************************************************
                    553:  *                                                                          *
                    554:  *  FUNCTION   : CountWindows                                               *
                    555:  *                                                                          *
                    556:  *  PURPOSE    : Counts how many info controls the parent of this window has*
                    557:  *                                                                          *
                    558:  *  RETURNS    : the count.                                                 *
                    559:  *                                                                          *
                    560:  ****************************************************************************/
                    561: INT CountWindows(
                    562: register HWND hwndParent)
                    563: {
                    564:   INT cWindows = 0;
                    565:   register HWND hwnd;
                    566: 
                    567:   for (hwnd=GetWindow(hwndParent, GW_CHILD);
                    568:         hwnd;
                    569:         hwnd= GetWindow(hwnd, GW_HWNDNEXT)) {
                    570:       cWindows++;
                    571:   }
                    572:   return(cWindows);
                    573: }
                    574: 
                    575: 
                    576: 
                    577: /****************************************************************************
                    578:  *                                                                          *
                    579:  *  FUNCTION   : GetCascadeWindowPos                                        *
                    580:  *                                                                          *
                    581:  *  PURPOSE    : Based on a window index and the parent window size,        *
                    582:  *               calculates where to place a cascaded window.               *
                    583:  *                                                                          *
                    584:  *  RETURNS    : rectangle in lprc.                                         *
                    585:  *                                                                          *
                    586:  ****************************************************************************/
                    587: VOID GetCascadeWindowPos(
                    588: HWND hwndParent,
                    589: INT  iWindow,
                    590: LPRECT lprc)
                    591: {
                    592:   RECT      rc;
                    593:   INT       cStack;
                    594:   register INT dxClient, dyClient;
                    595: 
                    596:   /* Compute the width and breadth of the situation. */
                    597:   GetClientRect(hwndParent, (LPRECT)&rc);
                    598:   dxClient = rc.right - rc.left;
                    599:   dyClient = rc.bottom - rc.top;
                    600: 
                    601:   /* How many windows per stack? */
                    602:   cStack = dyClient / (3 * cyMargin);
                    603: 
                    604:   lprc->right = dxClient - (cStack * cxMargin);
                    605:   lprc->bottom = dyClient - (cStack * cyMargin);
                    606: 
                    607:   cStack++;             /* HACK!: Mod by cStack+1 */
                    608: 
                    609:   lprc->left = (iWindow % cStack) * cxMargin;
                    610:   lprc->top = (iWindow % cStack) * cyMargin;
                    611: }
                    612: 
                    613: 
                    614: 
                    615: 
                    616: /****************************************************************************
                    617:  *                                                                          *
                    618:  *  FUNCTION   : MyCascadeChildWindows                                      *
                    619:  *                                                                          *
                    620:  *  PURPOSE    : Cascades all children of a parent window                   *
                    621:  *                                                                          *
                    622:  *  RETURNS    : nothing                                                    *
                    623:  *                                                                          *
                    624:  ****************************************************************************/
                    625: VOID MyCascadeChildWindows(
                    626: register HWND hwndParent)
                    627: {
                    628:   INT       i;
                    629:   INT       cWindows;
                    630:   RECT      rc;
                    631:   DWORD      wFlags;
                    632:   register HWND hwndMove;
                    633:   HANDLE    hDefer;
                    634: 
                    635:   cWindows = CountWindows(hwndParent);
                    636: 
                    637:   if (!cWindows)
                    638:       return;
                    639: 
                    640:   hwndMove = GetWindow(hwndParent, GW_CHILD);
                    641: 
                    642:   hDefer = BeginDeferWindowPos(cWindows);
                    643: 
                    644:   for (i=0; i < cWindows; i++) {
                    645:       GetCascadeWindowPos(hwndParent, i, (LPRECT)&rc);
                    646: 
                    647:       wFlags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS;
                    648: 
                    649:       /* Size the window. */
                    650:       hDefer = DeferWindowPos(hDefer,
                    651:                  hwndMove, NULL,
                    652:                  rc.left, rc.top,
                    653:                  rc.right, rc.bottom,
                    654:                  wFlags);
                    655: 
                    656:       hwndMove = GetWindow(hwndMove, GW_HWNDNEXT);
                    657:   }
                    658: 
                    659:   EndDeferWindowPos(hDefer);
                    660: }
                    661: 
                    662: 
                    663: /****************************************************************************
                    664:  *                                                                          *
                    665:  *  FUNCTION   : TileChildWindows                                           *
                    666:  *                                                                          *
                    667:  *  PURPOSE    : Tiles all children of a parent window                      *
                    668:  *                                                                          *
                    669:  *  RETURNS    : nothing.                                                   *
                    670:  *                                                                          *
                    671:  ****************************************************************************/
                    672: VOID TileChildWindows(
                    673: register HWND hwndParent)
                    674: {
                    675:   INT       i;
                    676:   INT       dx;
                    677:   INT       dy;
                    678:   INT       xRes;
                    679:   INT       yRes;
                    680:   INT       iCol;
                    681:   INT       iRow;
                    682:   INT       cCols;
                    683:   INT       cRows;
                    684:   INT       cExtra;
                    685:   INT       cWindows;
                    686:   register HWND hwndMove;
                    687:   RECT      rcClient;
                    688:   HANDLE    hDefer;
                    689:   DWORD      wFlags;
                    690: 
                    691:   cWindows = CountWindows(hwndParent);
                    692: 
                    693:   if (!cWindows)
                    694:       return;
                    695: 
                    696:   /* Compute the smallest nearest square. */
                    697:   for (i=2; i * i <= cWindows; i++);
                    698: 
                    699:   cRows = i - 1;
                    700:   cCols = cWindows / cRows;
                    701:   cExtra = cWindows % cRows;
                    702: 
                    703:   GetClientRect(hwndParent, (LPRECT)&rcClient);
                    704:   xRes = rcClient.right - rcClient.left;
                    705:   yRes = rcClient.bottom - rcClient.top;
                    706: 
                    707:   if (xRes<=0 || yRes<=0)
                    708:       return;
                    709: 
                    710:   hwndMove = GetWindow(hwndParent, GW_CHILD);
                    711: 
                    712:   hDefer = BeginDeferWindowPos(cWindows);
                    713: 
                    714:   for (iCol=0; iCol < cCols; iCol++) {
                    715:       if ((cCols-iCol) <= cExtra)
                    716:       cRows++;
                    717: 
                    718:       for (iRow=0; iRow < cRows; iRow++) {
                    719:           dx = xRes / cCols;
                    720:           dy = yRes / cRows;
                    721: 
                    722:           wFlags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS;
                    723: 
                    724:           /* Position and size the window. */
                    725:           hDefer = DeferWindowPos(hDefer, hwndMove, NULL,
                    726:                      dx * iCol,
                    727:                      dy * iRow,
                    728:                      dx,
                    729:                      dy,
                    730:                      wFlags);
                    731: 
                    732:           hwndMove = GetWindow(hwndMove, GW_HWNDNEXT);
                    733:       }
                    734: 
                    735:       if ((cCols-iCol) <= cExtra) {
                    736:           cRows--;
                    737:           cExtra--;
                    738:       }
                    739:   }
                    740: 
                    741:   EndDeferWindowPos(hDefer);
                    742: 
                    743: }

unix.superglobalmegacorp.com

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