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

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

unix.superglobalmegacorp.com

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