|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.