Annotation of mstools/samples/ddeml/client/infoctrl.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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