Annotation of mstools/samples/sdktools/dlgedit/groupdlg.c, revision 1.1.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.