|
|
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.