|
|
1.1 root 1:
2: /******************************************************************************\
3: * This is a part of the Microsoft Source Code Samples.
4: * Copyright (C) 1993 Microsoft Corporation.
5: * All rights reserved.
6: * This source code is only intended as a supplement to
7: * Microsoft Development Tools and/or WinHelp documentation.
8: * See these sources for detailed information regarding the
9: * Microsoft samples programs.
10: \******************************************************************************/
11:
12: /****************************** Module Header *******************************
13: * Module Name: groupdlg.c
14: *
15: * This module handles the "Group Controls" dialog, which changes the
16: * logical order and grouping of controls in the dialog.
17: *
18: *
19: * Functions:
20: * OrderGroupDialog()
21: * OrderDlgProc()
22: * OrderDlgInit()
23: * OrderDlgFillList()
24: * OrderDlgLBWndProc()
25: * OrderDlgInsertHitTest()
26: * OrderDlgEnableControls()
27: * OrderDlgSelChange()
28: * OrderDlgMakeGroup()
29: * OrderDlgMarkGroupEnds()
30: * OrderDlgSetTabs()
31: * OrderDlgClearTabs()
32: * OrderDlgToggleTab()
33: * OrderDlgReorder()
34: * OrderDlgDrawItem()
35: * OrderWindows()
36: * IsListChanged()
37: *
38: *
39: * Comments:
40: *
41: * Note that once a control has either it's WS_TABSTOP or WS_GROUP style
42: * bit changed by this dialog, the style of the actual control in work
43: * mode is not changed. This should not be a problem, however, because
44: * the appearance of controls does not change based on these styles, and
45: * the saved resource and the Test mode dialog WILL have the proper styles
46: * set in them.
47: *
48: ****************************************************************************/
49:
50: #include "dlgedit.h"
51: #include "dlgfuncs.h"
52: #include "dlgextrn.h"
53: #include "dialogs.h"
54: #include "dlghelp.h"
55:
56: /*
57: * Various constants for sizes of items in the list box (in pixels).
58: * Note that if the size of the bitmaps in the .bmp files change,
59: * these defines must be adjusted to match!
60: */
61: #define CYORDERDLGLINE 18 // Height of a line.
62: #define CXTABBMP 10 // Width of the tabstop bmp.
63: #define CYTABBMP 16 // Height of the tabstop bmp.
64: #define CXTYPEBMP 16 // Width of a control type bitmap.
65: #define CYTYPEBMP 14 // Height of a control type bitmap.
66:
67: /*
68: * Structure for ordering the controls into a new order.
69: */
70: typedef struct {
71: INT wNewOrder; // Indexes in the new order.
72: WORD fTaken:1; // TRUE if this item has been copied.
73: WORD fSelected:1; // TRUE if this item is selected.
74: } NEWORDER, *PNEWORDER;
75:
76: STATICFN VOID OrderDlgInit(HWND hwnd);
77: STATICFN VOID OrderDlgFillList(VOID);
78: WINDOWPROC OrderDlgLBWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
79: STATICFN BOOL OrderDlgInsertHitTest(INT y, PINT piInsert);
80: STATICFN VOID OrderDlgEnableControls(VOID);
81: STATICFN VOID OrderDlgSelChange(VOID);
82: STATICFN VOID OrderDlgMakeGroup(VOID);
83: STATICFN VOID OrderDlgMarkGroupEnds(VOID);
84: STATICFN VOID OrderDlgSetTabs(VOID);
85: STATICFN VOID OrderDlgClearTabs(VOID);
86: STATICFN VOID OrderDlgToggleTab(INT y);
87: STATICFN VOID OrderDlgReorder(INT iInsert);
88: STATICFN VOID OrderDlgDrawItem(LPDRAWITEMSTRUCT lpdis);
89: STATICFN VOID OrderWindows(VOID);
90: STATICFN BOOL IsListChanged(VOID);
91:
92: static HWND hwndOrderDlg; // Window handle of the Order/Group dlg.
93: static HWND hwndOrderList; // Window handle of the list box.
94: static NPCTYPE *anpcSave; // Points to array of controls in old order.
95: static PDWORD aflStyleSave; // Points to array of original styles.
96: static PINT aiSelItem; // Points to array of selected items.
97: static BOOL fContiguousSel; // TRUE if selection in LB is contiguous.
98: static PNEWORDER aNewOrder; // Points to array with new control order.
99: static INT cSelItems; // Count of selected items in the array.
100: static WNDPROC lpfnOldLBWndProc; // Original list box window proc.
101:
102:
103:
104: /************************************************************************
105: * OrderGroupDialog
106: *
107: * This function puts up the Order/Group dialog box.
108: * Any move is cancelled.
109: * The Order/Group dialog box is put up.
110: * The child windows are reordered and group and tabstop bits set.
111: * File change is noted.
112: *
113: ************************************************************************/
114:
115: VOID OrderGroupDialog(VOID)
116: {
117: NPCTYPE npc;
118: INT i;
119:
120: /*
121: * Nothing to order. This also protects some calculations below.
122: */
123: if (!cWindows)
124: return;
125:
126: if (!(anpcSave = (NPCTYPE *)MyAlloc(cWindows * sizeof(NPCTYPE))))
127: return;
128:
129: /*
130: * Allocate an array of indexes for selected items. Make it large
131: * enough to handle selecting all of the items in the list.
132: */
133: if (!(aiSelItem = (PINT)MyAlloc(cWindows * sizeof(INT)))) {
134: MyFree(anpcSave);
135: return;
136: }
137:
138: /*
139: * Allocate an array to save the original styles in.
140: */
141: if (!(aflStyleSave = (PDWORD)MyAlloc(cWindows * sizeof(DWORD)))) {
142: MyFree(anpcSave);
143: MyFree(aiSelItem);
144: return;
145: }
146:
147: if (!(aNewOrder = (PNEWORDER)MyAlloc(cWindows * sizeof(NEWORDER)))) {
148: MyFree(aflStyleSave);
149: MyFree(anpcSave);
150: MyFree(aiSelItem);
151: return;
152: }
153:
154: CancelSelection(TRUE);
155:
156: /*
157: * Save the original order of the controls, and their styles.
158: */
159: for (i = 0, npc = npcHead; npc; i++, npc = npc->npcNext) {
160: anpcSave[i] = npc;
161: aflStyleSave[i] = npc->flStyle;
162: }
163:
164: if (DlgBox(DID_ORDERGROUP, (WNDPROC)OrderDlgProc) == IDOK) {
165: if (IsListChanged()) {
166: gfResChged = gfDlgChanged = TRUE;
167: ShowFileStatus(FALSE);
168: }
169:
170: OrderWindows();
171: }
172: else {
173: /*
174: * Restore the linked list to the order that it originally was.
175: */
176: npcHead = anpcSave[0];
177: for (i = 0; i < cWindows - 1; i++)
178: (anpcSave[i])->npcNext = anpcSave[i + 1];
179: (anpcSave[i])->npcNext = NULL;
180:
181: /*
182: * Then restore the styles to the way that they were.
183: */
184: for (i = 0, npc = npcHead; npc; i++, npc = npc->npcNext)
185: npc->flStyle = aflStyleSave[i];
186: }
187:
188: MyFree(aNewOrder);
189: MyFree(aflStyleSave);
190: MyFree(aiSelItem);
191: MyFree(anpcSave);
192: }
193:
194:
195:
196: /************************************************************************
197: * OrderDlgProc
198: *
199: * This is the dialog function for the group ordering dialog box.
200: *
201: ************************************************************************/
202:
203: DIALOGPROC OrderDlgProc(
204: HWND hwnd,
205: UINT msg,
206: WPARAM wParam,
207: LPARAM lParam)
208: {
209: switch (msg) {
210: case WM_INITDIALOG:
211: OrderDlgInit(hwnd);
212: return TRUE;
213:
214: case WM_MEASUREITEM:
215: ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = CYORDERDLGLINE;
216: return TRUE;
217:
218: case WM_DRAWITEM:
219: OrderDlgDrawItem((LPDRAWITEMSTRUCT)lParam);
220: return TRUE;
221:
222: case WM_COMMAND:
223: switch (LOWORD(wParam)) {
224: case DID_ORDERLIST:
225: switch (HIWORD(wParam)) {
226: case LBN_SELCHANGE:
227: OrderDlgSelChange();
228: break;
229: }
230:
231: break;
232:
233: case DID_ORDERMAKEGROUP:
234: OrderDlgMakeGroup();
235: break;
236:
237: case DID_ORDERSETTAB:
238: OrderDlgSetTabs();
239: break;
240:
241: case DID_ORDERCLEARTAB:
242: OrderDlgClearTabs();
243: break;
244:
245: case IDCANCEL:
246: case IDOK:
247: EndDialog(hwnd, LOWORD(wParam));
248: break;
249:
250: case IDHELP:
251: WinHelp(ghwndMain, gszHelpFile, HELP_CONTEXT,
252: HELPID_ORDERGROUP);
253: break;
254: }
255:
256: return TRUE;
257:
258: default:
259: return FALSE;
260: }
261:
262: return FALSE;
263: }
264:
265:
266:
267: /************************************************************************
268: * OrderDlgInit
269: *
270: * Initializes the Order/Group dialog.
271: *
272: * Arguments:
273: * HWND hwnd = The dialog window handle.
274: *
275: ************************************************************************/
276:
277: STATICFN VOID OrderDlgInit(
278: HWND hwnd)
279: {
280: hwndOrderDlg = hwnd;
281: hwndOrderList = GetDlgItem(hwnd, DID_ORDERLIST);
282:
283: lpfnOldLBWndProc = (WNDPROC)SetWindowLong(hwndOrderList,
284: GWL_WNDPROC, (DWORD)OrderDlgLBWndProc);
285:
286: OrderDlgFillList();
287: OrderDlgMarkGroupEnds();
288: OrderDlgSelChange();
289:
290: CenterWindow(hwnd);
291: }
292:
293:
294:
295: /************************************************************************
296: * OrderDlgFillList
297: *
298: * Fill the order listbox
299: *
300: ************************************************************************/
301:
302: STATICFN VOID OrderDlgFillList(VOID)
303: {
304: NPCTYPE npc;
305:
306: SendMessage(hwndOrderList, LB_RESETCONTENT, 0, 0L);
307:
308: for (npc = npcHead; npc; npc = npc->npcNext)
309: SendMessage(hwndOrderList, LB_INSERTSTRING, (WPARAM)-1, (DWORD)npc);
310: }
311:
312:
313:
314: /************************************************************************
315: * OrderDlgLBWndProc
316: *
317: * window procedure for the left button
318: *
319: ************************************************************************/
320:
321: WINDOWPROC OrderDlgLBWndProc(
322: HWND hwnd,
323: UINT msg,
324: WPARAM wParam,
325: LPARAM lParam)
326: {
327: INT iInsert;
328:
329: switch (msg) {
330: case WM_SETCURSOR:
331: /*
332: * Defeat the system changing cursors on us in the client area.
333: */
334: if (LOWORD(lParam) == HTCLIENT)
335: return TRUE;
336:
337: break;
338:
339: case WM_MOUSEMOVE:
340: if (!(GetKeyState(VK_LBUTTON) & 0x8000) &&
341: OrderDlgInsertHitTest(HIWORD(lParam), &iInsert))
342: SetCursor(hcurInsert);
343: else
344: SetCursor(hcurArrow);
345:
346: break;
347:
348: case WM_LBUTTONDOWN:
349: if (OrderDlgInsertHitTest(HIWORD(lParam), &iInsert)) {
350: OrderDlgReorder(iInsert);
351: return FALSE;
352: }
353:
354: break;
355:
356: case WM_LBUTTONDBLCLK:
357: if (!OrderDlgInsertHitTest(HIWORD(lParam), &iInsert)) {
358: OrderDlgToggleTab(HIWORD(lParam));
359: return FALSE;
360: }
361:
362: break;
363: }
364:
365: return CallWindowProc((WNDPROC)lpfnOldLBWndProc,
366: hwnd, msg, wParam, lParam);
367: }
368:
369:
370:
371: /************************************************************************
372: * OrderDlgInsertHitTest
373: *
374: * Inserts item in list box
375: *
376: * Arguments:
377: * INT - the y coordinate of the mouse hit
378: * PINT - pointer to insertion point
379: *
380: * Returns:
381: * Where the mouse hit in the listbox
382: *
383: ************************************************************************/
384:
385: STATICFN BOOL OrderDlgInsertHitTest(
386: INT y,
387: PINT piInsert)
388: {
389: INT i;
390: INT iPixel;
391: INT iInsert;
392: INT iLine;
393: BOOL fInsertZone;
394:
395: /*
396: * Cannot insert if nothing is selected.
397: */
398: if (!cSelItems)
399: return FALSE;
400:
401: /*
402: * Find which pixel it hit.
403: */
404: iPixel = y % CYORDERDLGLINE;
405:
406: /*
407: * Determine if they are in the upper or lower insert zones.
408: */
409: if (iPixel < 3) {
410: iLine = y / CYORDERDLGLINE;
411: fInsertZone = TRUE;
412: }
413: else if (iPixel > CYORDERDLGLINE - 3) {
414: iLine = (y / CYORDERDLGLINE) + 1;
415: fInsertZone = TRUE;
416: }
417: else {
418: fInsertZone = FALSE;
419: }
420:
421: if (fInsertZone) {
422: /*
423: * Do some math, taking into account the top index of the
424: * listbox, to determine which line they are inserting into.
425: */
426: iInsert = iLine + (INT)SendMessage(hwndOrderList,
427: LB_GETTOPINDEX, 0, 0L);
428:
429: /*
430: * If we are too FAR down the listbox, act as if we are not
431: * in the insert zone.
432: */
433: if (iInsert > cWindows) {
434: fInsertZone = FALSE;
435: }
436: else {
437: /*
438: * Check for whether the cursor was inside a selected
439: * area. If it is, we don't allow inserting there
440: * (because it is a noop). However, if the selection
441: * is discontiguous, we always allow inserting, because
442: * inserting at any point with a discontiguous selection
443: * will always cause something to happen, even if it
444: * is just gathering the selection together.
445: */
446: if (fContiguousSel) {
447: for (i = 0; i < cSelItems; i++) {
448: if (aiSelItem[i] == iInsert ||
449: aiSelItem[i] == iInsert - 1)
450: return FALSE;
451: }
452: }
453:
454: *piInsert = iInsert;
455: }
456: }
457:
458: return fInsertZone;
459: }
460:
461:
462:
463: /************************************************************************
464: * OrderDlgEnableControls
465: *
466: * Enable items in order dialog
467: *
468: ************************************************************************/
469:
470: STATICFN VOID OrderDlgEnableControls(VOID)
471: {
472: NPCTYPE npc;
473: BOOL fEnableSetTab = FALSE;
474: BOOL fEnableClearTab = FALSE;
475: INT i;
476:
477: if (cSelItems) {
478: /*
479: * Walk through all the selected items. We will enable the
480: * set/clear tab buttons based on whether there are any tabs
481: * to set/clear in the current selection.
482: */
483: for (i = 0; i < cSelItems && (!fEnableSetTab || !fEnableClearTab); i++) {
484: npc = (NPCTYPE)SendMessage(
485: hwndOrderList, LB_GETITEMDATA, aiSelItem[i], 0L);
486:
487: if (npc->flStyle & WS_TABSTOP)
488: fEnableClearTab = TRUE;
489: else
490: fEnableSetTab = TRUE;
491: }
492: }
493:
494: /*
495: * Normally, if there is a selection we enable "Make Group",
496: * but if the selection is not contiguous, we disable it.
497: */
498: EnableWindow(GetDlgItem(hwndOrderDlg, DID_ORDERMAKEGROUP),
499: cSelItems && fContiguousSel);
500:
501: EnableWindow(GetDlgItem(hwndOrderDlg, DID_ORDERSETTAB),
502: fEnableSetTab);
503: EnableWindow(GetDlgItem(hwndOrderDlg, DID_ORDERCLEARTAB),
504: fEnableClearTab);
505: }
506:
507:
508:
509: /************************************************************************
510: * OrderDlgSelChange
511: *
512: * get selection change in order dialog
513: *
514: ************************************************************************/
515:
516: STATICFN VOID OrderDlgSelChange(VOID)
517: {
518: INT i;
519:
520: cSelItems = (INT)SendMessage(hwndOrderList, LB_GETSELITEMS,
521: cWindows, (DWORD)aiSelItem);
522:
523: /*
524: * Set a flag saying whether the selection is contiguous or not.
525: */
526: fContiguousSel = TRUE;
527: if (cSelItems > 1) {
528: for (i = 1; i < cSelItems; i++) {
529: if (aiSelItem[i] != aiSelItem[i - 1] + 1) {
530: fContiguousSel = FALSE;
531: break;
532: }
533: }
534: }
535:
536: OrderDlgEnableControls();
537: }
538:
539:
540:
541: /************************************************************************
542: * OrderDlgMakeGroup
543: *
544: * Creates a group
545: *
546: ************************************************************************/
547:
548: STATICFN VOID OrderDlgMakeGroup(VOID)
549: {
550: INT i;
551: NPCTYPE npc;
552:
553: for (i = 0; i < cSelItems; i++) {
554: npc = (NPCTYPE)SendMessage(
555: hwndOrderList, LB_GETITEMDATA, aiSelItem[i], 0L);
556:
557: /*
558: * Set the WS_GROUP style on the first selected control
559: * and clear it from all others.
560: */
561: if (i == 0)
562: npc->flStyle |= WS_GROUP;
563: else
564: npc->flStyle &= ~WS_GROUP;
565:
566: /*
567: * Are we on the last selected item and is this item not the
568: * very last item in the list? If so, set the "group" style
569: * on the next control.
570: */
571: if (i == cSelItems - 1 && aiSelItem[i] < cWindows - 1) {
572: npc = (NPCTYPE)SendMessage(
573: hwndOrderList, LB_GETITEMDATA, aiSelItem[i] + 1, 0L);
574: npc->flStyle |= WS_GROUP;
575: }
576: }
577:
578: OrderDlgMarkGroupEnds();
579: OrderDlgEnableControls();
580: InvalidateRect(hwndOrderList, NULL, FALSE);
581: }
582:
583:
584:
585: /************************************************************************
586: * OrderDlgMarkGroupEnds
587: *
588: * Set the end for the items in the group
589: *
590: * Arguments:
591: * HWND hwnd = The dialog window handle.
592: *
593: ************************************************************************/
594:
595: STATICFN VOID OrderDlgMarkGroupEnds(VOID)
596: {
597: NPCTYPE npc;
598: NPCTYPE npcPrev;
599:
600: for (npc = npcHead, npcPrev = NULL; npc;
601: npcPrev = npc, npc = npc->npcNext) {
602: npc->fGroupEnd = FALSE;
603:
604: if ((npc->flStyle & WS_GROUP) && npcPrev)
605: npcPrev->fGroupEnd = TRUE;
606: }
607:
608: if (npcPrev)
609: npcPrev->fGroupEnd = TRUE;
610: }
611:
612:
613:
614: /************************************************************************
615: * OrderDlgSetTabs
616: *
617: * Set WS_TABSTOP behavior for group
618: *
619: ************************************************************************/
620:
621: STATICFN VOID OrderDlgSetTabs(VOID)
622: {
623: INT i;
624: NPCTYPE npc;
625:
626: for (i = 0; i < cSelItems; i++) {
627: npc = (NPCTYPE)SendMessage(hwndOrderList, LB_GETITEMDATA, aiSelItem[i], 0L);
628:
629: npc->flStyle |= WS_TABSTOP;
630: }
631:
632: OrderDlgEnableControls();
633: InvalidateRect(hwndOrderList, NULL, FALSE);
634: }
635:
636:
637:
638: /************************************************************************
639: * OrderDlgClearTabs
640: *
641: * Clear WS_TABSTOPS for group items.
642: *
643: ************************************************************************/
644:
645: STATICFN VOID OrderDlgClearTabs(VOID)
646: {
647: INT i;
648: NPCTYPE npc;
649:
650: for (i = 0; i < cSelItems; i++) {
651: npc = (NPCTYPE)SendMessage(hwndOrderList, LB_GETITEMDATA, aiSelItem[i], 0L);
652:
653: npc->flStyle &= ~WS_TABSTOP;
654: }
655:
656: OrderDlgEnableControls();
657: InvalidateRect(hwndOrderList, NULL, FALSE);
658: }
659:
660:
661:
662: /************************************************************************
663: * OrderDlgToggleTab
664: *
665: * Toggle to WS_TABSTOP attribute for the selected item
666: *
667: * Arguments:
668: * INT - the y coordinate of the item that was selected
669: *
670: ************************************************************************/
671:
672: STATICFN VOID OrderDlgToggleTab(
673: INT y)
674: {
675: NPCTYPE npc;
676: RECT rcItem;
677: INT iLine;
678:
679: /*
680: * Determine which item was clicked on.
681: */
682: iLine = (y / CYORDERDLGLINE) +
683: (INT)SendMessage(hwndOrderList, LB_GETTOPINDEX, 0, 0L);
684:
685: /*
686: * If it is a valid item (it was not in the white space below
687: * all the listbox items), then toggle the WS_TABSTOP style on
688: * it and update the display.
689: */
690: if (iLine < cWindows) {
691: npc = (NPCTYPE)SendMessage(hwndOrderList, LB_GETITEMDATA, iLine, 0L);
692: npc->flStyle ^= WS_TABSTOP;
693:
694: OrderDlgEnableControls();
695: SendMessage(hwndOrderList, LB_GETITEMRECT,
696: iLine, (DWORD)(LPRECT)&rcItem);
697: InvalidateRect(hwndOrderList, &rcItem, FALSE);
698: }
699: }
700:
701:
702:
703: /************************************************************************
704: * OrderDlgReorder
705: *
706: * Inserts a new item at the point indicated
707: *
708: * Arguments:
709: * INT iInsert - Index of where to insert the selection.
710: *
711: ************************************************************************/
712:
713: STATICFN VOID OrderDlgReorder(
714: INT iInsert)
715: {
716: INT i;
717: INT j;
718: INT iNewSelStart;
719: INT iNewSelEnd;
720: INT iTopIndex;
721: INT iNew = 0;
722: NPCTYPE npc;
723: NPCTYPE npcPrev;
724:
725: /*
726: * If there is nothing selected or there is only one item, the
727: * order cannot change so we just return.
728: */
729: if (!cSelItems || cWindows < 2)
730: return;
731:
732: iTopIndex = (INT)SendMessage(hwndOrderList, LB_GETTOPINDEX, 0, 0L);
733:
734: for (i = 0; i < cWindows; i++) {
735: aNewOrder[i].fTaken = FALSE;
736: aNewOrder[i].fSelected = FALSE;
737: }
738:
739: for (i = 0; i < cSelItems; i++)
740: aNewOrder[aiSelItem[i]].fSelected = TRUE;
741:
742: for (j = 0; j < iInsert; j++) {
743: if (aNewOrder[j].fSelected == FALSE)
744: aNewOrder[iNew++].wNewOrder = j;
745: }
746:
747: iNewSelStart = iNew;
748:
749: for (i = 0; i < cWindows; i++) {
750: if (aNewOrder[i].fSelected) {
751: aNewOrder[iNew++].wNewOrder = i;
752: aNewOrder[i].fTaken = TRUE;
753: }
754: }
755:
756: iNewSelEnd = iNew - 1;
757:
758: for (; j < cWindows; j++) {
759: if (!aNewOrder[j].fTaken)
760: aNewOrder[iNew++].wNewOrder = j;
761: }
762:
763: /*
764: * Was the order changed at all?
765: */
766: for (i = 1; i < cWindows; i++)
767: if (aNewOrder[i].wNewOrder != aNewOrder[i - 1].wNewOrder + 1)
768: break;
769:
770: /*
771: * No, get out because there is nothing to do.
772: */
773: if (i == cWindows)
774: return;
775:
776: for (i = 0; i < cWindows; i++) {
777: npc = (NPCTYPE)SendMessage(
778: hwndOrderList, LB_GETITEMDATA, aNewOrder[i].wNewOrder, 0L);
779:
780: if (!i) {
781: npcHead = npc;
782: npcPrev = npc;
783: }
784: else {
785: npcPrev->npcNext = npc;
786: npcPrev = npc;
787: }
788: }
789:
790: npcPrev->npcNext = NULL;
791:
792: OrderDlgMarkGroupEnds();
793: SendMessage(hwndOrderList, WM_SETREDRAW, FALSE, 0L);
794: OrderDlgFillList();
795: SendMessage(hwndOrderList, LB_SETTOPINDEX, iTopIndex, 0L);
796: SendMessage(hwndOrderList, LB_SELITEMRANGE,
797: TRUE, MAKELONG(iNewSelStart, iNewSelEnd));
798: OrderDlgSelChange();
799: SendMessage(hwndOrderList, WM_SETREDRAW, TRUE, 0L);
800: InvalidateRect(hwndOrderList, NULL, FALSE);
801: }
802:
803:
804:
805: /************************************************************************
806: * OrderDlgDrawItem
807: *
808: * draws the text for the group item
809: *
810: * Arguments:
811: * LPDRAWITEMSTRUCT - pointer to the item
812: *
813: ************************************************************************/
814:
815: STATICFN VOID OrderDlgDrawItem(
816: LPDRAWITEMSTRUCT lpdis)
817: {
818: NPCTYPE npc;
819: TCHAR szItem[CCHTEXTMAX];
820: HBITMAP hbmCtrlType;
821: HBITMAP hbmTab;
822: HBITMAP hbmOld;
823:
824: npc = (NPCTYPE)lpdis->itemData;
825:
826: /*
827: * Begin building the text string to draw.
828: */
829: *szItem = CHAR_NULL;
830:
831: if (npc->pwcd->iType == W_CUSTOM)
832: wsprintf(szItem, L"'%s', ", npc->pwcd->pszClass);
833:
834: if (npc->text) {
835: if (IsOrd(npc->text)) {
836: IDToLabel(szItem + lstrlen(szItem), OrdID(npc->text), TRUE);
837: lstrcat(szItem, L", ");
838: }
839: else {
840: wsprintf(szItem + lstrlen(szItem), L"\"%s\", ", npc->text);
841: }
842: }
843:
844: IDToLabel(szItem + lstrlen(szItem), npc->id, TRUE);
845:
846: if (lpdis->itemState & ODS_SELECTED) {
847: SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
848: SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
849: hbmCtrlType = npc->pwcd->hbmCtrlTypeSel;
850: hbmTab = hbmTabStopSel;
851: }
852: else {
853: SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
854: SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
855: hbmCtrlType = npc->pwcd->hbmCtrlType;
856: hbmTab = hbmTabStop;
857: }
858:
859: /*
860: * Draw the string (and paint the background).
861: */
862: ExtTextOut(lpdis->hDC,
863: CXTABBMP + 2 + CXTYPEBMP + 2,
864: lpdis->rcItem.top + (CYORDERDLGLINE - gcySysChar),
865: ETO_OPAQUE | ETO_CLIPPED, &lpdis->rcItem,
866: szItem, lstrlen(szItem), NULL);
867:
868: /*
869: * Draw the group marker separator line.
870: */
871: if (npc->fGroupEnd) {
872: SelectObject(lpdis->hDC, hpenDarkGray);
873: MoveToEx(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.bottom - 1, NULL);
874: LineTo(lpdis->hDC, lpdis->rcItem.right, lpdis->rcItem.bottom - 1);
875: }
876:
877: /*
878: * Draw the tabstop bitmap if necessary.
879: */
880: if (npc->flStyle & WS_TABSTOP) {
881: hbmOld = SelectObject(ghDCMem, hbmTab);
882: BitBlt(lpdis->hDC,
883: 0, lpdis->rcItem.top + ((CYORDERDLGLINE - CYTABBMP) / 2),
884: CXTABBMP, CYTABBMP, ghDCMem, 0, 0, SRCCOPY);
885: SelectObject(ghDCMem, hbmOld);
886: }
887:
888: /*
889: * Draw the control type bitmap.
890: */
891: hbmOld = SelectObject(ghDCMem, hbmCtrlType);
892: BitBlt(lpdis->hDC,
893: lpdis->rcItem.left + CXTABBMP + 2,
894: lpdis->rcItem.top + ((CYORDERDLGLINE - CYTYPEBMP) / 2),
895: CXTYPEBMP, CYTYPEBMP, ghDCMem, 0, 0, SRCCOPY);
896: SelectObject(ghDCMem, hbmOld);
897:
898: /*
899: * Draw the focus rectangle, if necessary.
900: */
901: if (lpdis->itemState & ODS_FOCUS)
902: DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
903: }
904:
905:
906:
907: /************************************************************************
908: * OrderWindows
909: *
910: * Orders the controls in Windows' linked list of windows to be the
911: * same as the order in the linked list of CTYPEs.
912: *
913: * The Z order of the drag windows and the control windows is critical
914: * to all the painting, dragging and selection code working properly!
915: *
916: ************************************************************************/
917:
918: STATICFN VOID OrderWindows(VOID)
919: {
920: register NPCTYPE npc;
921:
922: for (npc = npcHead; npc; npc = npc->npcNext) {
923: /*
924: * The control goes to the bottom of the list.
925: */
926: SetWindowPos(npc->hwnd, (HWND)1, 0, 0, 0, 0,
927: SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
928:
929: /*
930: * The drag window goes to the top of the list.
931: */
932: SetWindowPos(npc->hwndDrag, NULL, 0, 0, 0, 0,
933: SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
934: }
935: }
936:
937:
938:
939: /************************************************************************
940: * IsListChanged
941: *
942: * This function returns TRUE if the current order of the linked list
943: * of controls is different than what it was when the Order/Group dialog
944: * was first entered, or if any of the styles were changed (tabs were
945: * set/cleared, groups were changed, etc.).
946: *
947: ************************************************************************/
948:
949: STATICFN BOOL IsListChanged(VOID)
950: {
951: NPCTYPE *pnpcSave;
952: NPCTYPE npc;
953: INT i;
954:
955: pnpcSave = anpcSave;
956: for (i = 0, npc = npcHead; npc; i++, npc = npc->npcNext, pnpcSave++)
957: if (npc != *pnpcSave || npc->flStyle != aflStyleSave[i])
958: return TRUE;
959:
960: return FALSE;
961: }
962:
963:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.