Annotation of mstools/samples/sdktools/dlgedit/groupdlg.c, revision 1.1

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: 

unix.superglobalmegacorp.com

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