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