Annotation of mstools/ole20/samples/gizmobar/gizmo.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * GIZMO.C
        !             3:  * GizmoBar Version 1.00, March 1993
        !             4:  *
        !             5:  * Allocate, free, find, and enumerate functions for the GIZMO structure
        !             6:  * and a generic subclass procedure to handle tabbing between gizmos.
        !             7:  *
        !             8:  * Copyright (c)1992 Microsoft Corporation, All Rights Reserved.
        !             9:  *
        !            10:  * Kraig Brockschmidt, Software Design Engineer
        !            11:  * Microsoft Systems Developer Relations
        !            12:  *
        !            13:  * Internet  :  [email protected]
        !            14:  * Compuserve:  >INTERNET:[email protected]
        !            15:  */
        !            16: 
        !            17: #ifdef WIN32
        !            18: #define _INC_OLE
        !            19: #define __RPC_H__
        !            20: #endif
        !            21: 
        !            22: 
        !            23: #define STRICT
        !            24: #include <windows.h>
        !            25: #include "gizmoint.h"
        !            26: 
        !            27: 
        !            28: /*
        !            29:  * In order to control tabbing in the gizmos, we need to subclass
        !            30:  * real pushbuttons, edit controls, listboxes, and comboboxes.  So
        !            31:  * we keep an array of the four original procs for such controls.
        !            32:  */
        !            33: WNDPROC     pfnOrg[CSUBGIZMOS]={NULL, NULL, NULL, NULL};
        !            34: 
        !            35: 
        !            36: char szStatic[]="static";
        !            37: char szEdit[]="edit";
        !            38: char szCombobox[]="combobox";
        !            39: char szListbox[]="listbox";
        !            40: char szButton[]="button";
        !            41: 
        !            42: 
        !            43: //Here so PAINT.C can get at it.
        !            44: TOOLDISPLAYDATA tdd;
        !            45: 
        !            46: 
        !            47: 
        !            48: /*
        !            49:  * GizmoPAllocate
        !            50:  *
        !            51:  * Purpose:
        !            52:  *  Allocates and initializes a GIZMO data structure.
        !            53:  *
        !            54:  * Parameters:
        !            55:  *  pfSuccess       LPINT flag indicating success of failure.
        !            56:  *  ppFirst         PPGIZMO providing the first gizmo in this list.
        !            57:  *  hWndParent      HWND of the parent of this gizmo.  Can be NULL for
        !            58:  *                  iType==GIZMOTYPE_BUTTON* or GIZMOTYPE_SEPARATOR.
        !            59:  *  iType           UINT gizmo control type.
        !            60:  *  iGizmo          UINT index of this gizmo in the GizmoBar.
        !            61:  *  uID             UINT identifier to send with WM_COMMAND for this control.
        !            62:  *  dx, dy          UINT width and height of the gizmo.
        !            63:  *  pszText         LPSTR to the text for edits, listboxes, combobox, and text.
        !            64:  *  dwStyle         DWORD style for edits, lists, and combos, and texts.
        !            65:  *  hBmp            HBITMAP for button gizmos, is applicable.
        !            66:  *  iImage          UINT index into hBmp for the button image, if applicable.
        !            67:  *  uState          UINT initial state of the control.
        !            68:  *
        !            69:  * Return Value:
        !            70:  *  PGIZMO          If NULL returned then GizmoPAllocate could not allocate
        !            71:  *                  memory.  If a non-NULL pointer is returned with
        !            72:  *                  *pfSuccess, then call GizmoPFree immediately.  If you
        !            73:  *                  get a non-NULL pointer and *pfSuccess==TRUE then the
        !            74:  *                  function succeeded.
        !            75:  */
        !            76: 
        !            77: PGIZMO GizmoPAllocate(LPINT pfSuccess, PPGIZMO ppFirst, HWND hWndParent
        !            78:     , UINT iType, UINT iGizmo, UINT uID, UINT dx, UINT dy, LPSTR pszText
        !            79:     , HBITMAP hBmp, UINT iImage, UINT uState)
        !            80:     {
        !            81:     PGIZMO          pGizmo;
        !            82:     PGIZMO          pCur, pPrev;
        !            83:     LPSTR           pszClass;
        !            84:     HINSTANCE       hInst;
        !            85:     UINT            i;
        !            86:     DWORD           dwStyle;
        !            87:     HWND            hWndE;
        !            88: 
        !            89:     if (NULL==pfSuccess)
        !            90:         return NULL;
        !            91: 
        !            92:     //Make sure we know of this gizmo type.
        !            93:     if (GIZMOTYPE_MIN > iType || GIZMOTYPE_MAX < iType)
        !            94:         return NULL;
        !            95: 
        !            96:     *pfSuccess=FALSE;
        !            97: 
        !            98:     //Allocate the structure
        !            99:     pGizmo=(PGIZMO)(char *)LocalAlloc(LPTR, CBGIZMO);
        !           100: 
        !           101:     if (NULL==pGizmo)
        !           102:         return NULL;
        !           103: 
        !           104: 
        !           105:     //Store the necessary information for this gizmo.
        !           106:     pGizmo->iType   =iType;
        !           107:     pGizmo->uID     =uID;
        !           108:     pGizmo->hBmp    =hBmp;
        !           109:     pGizmo->iBmp    =iImage;
        !           110:     pGizmo->uState  =uState;
        !           111:     pGizmo->fNotify =TRUE;
        !           112: 
        !           113: 
        !           114:     /*
        !           115:      * Insert this structure into our gizmo list.  Each time we scan
        !           116:      * we increment the index counter (starting at zero) comparing it
        !           117:      * to the desired index of insertion.  We then know exactly where
        !           118:      * to insert this new gizmo.  Note that we insert the new gizmo in
        !           119:      * the list appropriately for the given owner, so enumerations will
        !           120:      * come out ordered in the same way for that owner.
        !           121:      */
        !           122: 
        !           123:     i=0;
        !           124:     pCur=*ppFirst;
        !           125:     pPrev=NULL;
        !           126: 
        !           127:     while (NULL!=pCur && i++ < iGizmo)
        !           128:         {
        !           129:         pPrev=pCur;
        !           130:         pCur =pCur->pNext;
        !           131:         }
        !           132: 
        !           133:     //Point to our neighbors
        !           134:     pGizmo->pPrev=pPrev;
        !           135:     pGizmo->pNext=pCur;
        !           136: 
        !           137: 
        !           138:     //Point out neighbors to us.
        !           139:     if (NULL==pPrev)
        !           140:         *ppFirst=pGizmo;
        !           141:     else
        !           142:         pPrev->pNext=pGizmo;
        !           143: 
        !           144:     if (NULL!=pCur)
        !           145:         pCur->pPrev=pGizmo;
        !           146: 
        !           147: 
        !           148:     //Our x-coordinate is the x of the previous gizmo plus its width.
        !           149:     if (NULL!=pPrev)
        !           150:         pGizmo->x=pGizmo->pPrev->x+pGizmo->pPrev->dx;
        !           151:     else
        !           152:         pGizmo->x=4;    //First gizmo is at x=4
        !           153: 
        !           154: 
        !           155:     //If we're a separator or image button, force standards on dx.
        !           156:     UIToolConfigureForDisplay(&tdd);
        !           157:     pGizmo->cxImage=tdd.cxImage;
        !           158:     pGizmo->cyImage=tdd.cyImage;
        !           159: 
        !           160: 
        !           161:     if ((GIZMOTYPE_DRAWN & iType) && NULL==hBmp)
        !           162:         dx=tdd.cxButton;
        !           163: 
        !           164:     if (GIZMOTYPE_SEPARATOR==iType)
        !           165:         dx=6;
        !           166: 
        !           167:     /*
        !           168:      * Now create windows for edits, texts, lists, and comboboxes.
        !           169:      * First calculate the most often defaults used in the switch.
        !           170:      */
        !           171:     pGizmo->dx=dx+6;
        !           172:     pGizmo->dy=min(dy, tdd.cyButton);
        !           173:     pGizmo->y=2;
        !           174:     pszClass=NULL;
        !           175: 
        !           176:     /*
        !           177:      * If this is new gizmo is a window, create it.  There's proabably
        !           178:      * a better way to write this code.  Gen, got any ideas?
        !           179:      */
        !           180:     switch (iType)
        !           181:             {
        !           182:             case GIZMOTYPE_TEXT:
        !           183:                 pGizmo->dx=dx;
        !           184:                 pGizmo->y=(tdd.cyBar-1-pGizmo->dy) >> 1;  //Center vertically.
        !           185:                 pszClass=szStatic;
        !           186:                 dwStyle=SS_LEFT;
        !           187:                 break;
        !           188: 
        !           189:             case GIZMOTYPE_EDIT:
        !           190:                 pGizmo->y=(tdd.cyBar-1-pGizmo->dy) >> 1;  //Center vertically.
        !           191:                 pszClass=szEdit;
        !           192:                 dwStyle=ES_LEFT | WS_BORDER | WS_TABSTOP;
        !           193:                 break;
        !           194: 
        !           195:             case GIZMOTYPE_LISTBOX:
        !           196:                 pGizmo->dy=dy;
        !           197:                 pszClass=szCombobox;
        !           198:                 dwStyle=CBS_DROPDOWNLIST | WS_TABSTOP;
        !           199:                 break;
        !           200: 
        !           201:             case GIZMOTYPE_COMBOBOX:
        !           202:                 pGizmo->dy=dy;
        !           203:                 pszClass=szCombobox;
        !           204:                 dwStyle=CBS_DROPDOWN | WS_TABSTOP;
        !           205:                 break;
        !           206: 
        !           207:             case GIZMOTYPE_BUTTONNORMAL:
        !           208:                 pGizmo->dy=dy;
        !           209:                 pszClass=szButton;
        !           210:                 dwStyle=BS_PUSHBUTTON | WS_TABSTOP;
        !           211:                 break;
        !           212: 
        !           213:             case GIZMOTYPE_SEPARATOR:
        !           214:                 pGizmo->dx=dx;
        !           215:                 pGizmo->y=3;
        !           216:                 break;
        !           217: 
        !           218:             case GIZMOTYPE_BUTTONATTRIBUTEIN:
        !           219:             case GIZMOTYPE_BUTTONATTRIBUTEEX:
        !           220:             case GIZMOTYPE_BUTTONCOMMAND:
        !           221:                 pGizmo->dx=dx;
        !           222:                 pGizmo->y=3;
        !           223:                 break;
        !           224:             }
        !           225: 
        !           226: 
        !           227:     //If we matched a classname, create a window.
        !           228:     if (GIZMOTYPE_WINDOWS & iType)
        !           229:         {
        !           230:         if (!IsWindow(hWndParent))
        !           231:             return pGizmo;
        !           232: #ifdef WIN32
        !           233:         hInst=(HINSTANCE)GetWindowLong(hWndParent, GWL_HINSTANCE);
        !           234: #else
        !           235:         hInst=(HINSTANCE)GetWindowWord(hWndParent, GWW_HINSTANCE);
        !           236: #endif
        !           237: 
        !           238:         pGizmo->hWnd=CreateWindow(pszClass, pszText, dwStyle | WS_CHILD | WS_VISIBLE
        !           239:             , pGizmo->x, pGizmo->y, dx, pGizmo->dy, hWndParent
        !           240:             , (HMENU)uID, hInst, NULL);
        !           241: 
        !           242:         if (NULL==pGizmo->hWnd)
        !           243:             return pGizmo;
        !           244: 
        !           245:         /*
        !           246:          * Subclass comboboxes, listboxes, edits, and windowed buttons.
        !           247:          * We use iType to index the original proc array so we can use
        !           248:          * a single subclass procedure for all controls.  If you mess
        !           249:          * with the gizmo type definitions, this is going to break.
        !           250:          */
        !           251: 
        !           252:         if (GIZMOTYPE_WINDOWS & iType && GIZMOTYPE_TEXT!=iType)
        !           253:             {
        !           254:             //Give the window its type.
        !           255:             BITPOSITION(iType, i);
        !           256:             SetProp(pGizmo->hWnd, SZTYPEPROP, (HANDLE)i);
        !           257: 
        !           258:             if (NULL==pfnOrg[i])
        !           259:                 pfnOrg[i]=(WNDPROC)GetWindowLong(pGizmo->hWnd, GWL_WNDPROC);
        !           260: 
        !           261:             SetWindowLong(pGizmo->hWnd, GWL_WNDPROC, (LONG)GenericSubProc);
        !           262: 
        !           263:             //If we're a combobox, get the edit control and subclass it.
        !           264:             if (GIZMOTYPE_COMBOBOX==iType)
        !           265:                 {
        !           266:                 hWndE=GetDlgItem(pGizmo->hWnd, ID_COMBOEDIT);
        !           267:                 SetProp(hWndE, SZTYPEPROP, (HANDLE)-1);        //Special flag.
        !           268: 
        !           269:                 if (NULL==pfnOrg[0])
        !           270:                     pfnOrg[0]=(WNDPROC)GetWindowLong(pGizmo->hWnd, GWL_WNDPROC);
        !           271: 
        !           272:                 SetWindowLong(hWndE, GWL_WNDPROC, (LONG)GenericSubProc);
        !           273:                 }
        !           274:             }
        !           275:         }
        !           276: 
        !           277: 
        !           278:     //Finally, move all our neighbors to the right over to accomodate us.
        !           279:     GizmosExpand(pGizmo);
        !           280: 
        !           281:     *pfSuccess=TRUE;
        !           282:     return pGizmo;
        !           283:     }
        !           284: 
        !           285: 
        !           286: 
        !           287: 
        !           288: 
        !           289: 
        !           290: /*
        !           291:  * GizmoPFree
        !           292:  *
        !           293:  * Purpose:
        !           294:  *  Reverses all initialization done by GizmoPAllocate, cleaning up
        !           295:  *  any allocations including the application structure itself.
        !           296:  *
        !           297:  * Parameters:
        !           298:  *  ppFirst         PPGIZMO providing the first gizmo in this list.
        !           299:  *  pGizmo          PGIZMO to the structure
        !           300:  *
        !           301:  * Return Value:
        !           302:  *  PGIZMO          NULL if successful, pGizmo if not, meaning we couldn't
        !           303:  *                  free something.
        !           304:  */
        !           305: 
        !           306: PGIZMO GizmoPFree(PPGIZMO ppFirst, PGIZMO pGizmo)
        !           307:     {
        !           308:     int     i;
        !           309: 
        !           310:     if (NULL==pGizmo)
        !           311:         return NULL;
        !           312: 
        !           313:     //Move other gizmos to fill in this gap.
        !           314:     GizmosCompact(pGizmo);
        !           315: 
        !           316:     //Unsubclass
        !           317:     if (GIZMOTYPE_WINDOWS & pGizmo->iType && GIZMOTYPE_TEXT!=pGizmo->iType)
        !           318:         {
        !           319:         i=(int)GetProp(pGizmo->hWnd, SZTYPEPROP);
        !           320:         RemoveProp(pGizmo->hWnd, SZTYPEPROP);
        !           321: 
        !           322:         SetWindowLong(pGizmo->hWnd, GWL_WNDPROC, (LONG)pfnOrg[i]);
        !           323:         }
        !           324: 
        !           325:     //If this was a window gizmo, destroy the window.
        !           326:     if (NULL!=pGizmo->hWnd && IsWindow(pGizmo->hWnd))
        !           327:         DestroyWindow(pGizmo->hWnd);
        !           328: 
        !           329:     //Unlink ourselves.
        !           330:     if (NULL!=pGizmo->pNext)
        !           331:         pGizmo->pNext->pPrev=pGizmo->pPrev;
        !           332: 
        !           333:     if (NULL!=pGizmo->pPrev)
        !           334:         pGizmo->pPrev->pNext=pGizmo->pNext;
        !           335:     else
        !           336:         *ppFirst=pGizmo->pNext;
        !           337: 
        !           338:     return (PGIZMO)LocalFree((HLOCAL)(UINT)(LONG)pGizmo);
        !           339:     }
        !           340: 
        !           341: 
        !           342: 
        !           343: 
        !           344: 
        !           345: 
        !           346: /*
        !           347:  * GizmosExpand
        !           348:  *
        !           349:  * Purpose:
        !           350:  *  Given a starting gizmo and a width, moves it and all gizmos to its
        !           351:  *  right to the right by the width to make space for showing or creating
        !           352:  *  a new gizmo.
        !           353:  *
        !           354:  * Parameters:
        !           355:  *  pGizmo          PGIZMO specifying the gizmo that was inserted.
        !           356:  *
        !           357:  * Return Value:
        !           358:  *  None
        !           359:  */
        !           360: 
        !           361: void GizmosExpand(PGIZMO pGizmo)
        !           362:     {
        !           363:     int         cx;
        !           364: 
        !           365:     cx=(int)pGizmo->dx;
        !           366: 
        !           367:     /*
        !           368:      * If we and the next control are buttons, use our width-1 to
        !           369:      * expand so we overlap borders with our neighboring button.
        !           370:      */
        !           371: 
        !           372:     if (NULL!=pGizmo->pNext)
        !           373:         {
        !           374:         if ((GIZMOTYPE_BUTTONS & pGizmo->pNext->iType)
        !           375:             && (GIZMOTYPE_BUTTONS & pGizmo->iType))
        !           376:             cx-=1;
        !           377:         }
        !           378: 
        !           379:     //Walk the gizmo list moving them right by our width.
        !           380:     pGizmo=pGizmo->pNext;
        !           381: 
        !           382:     while (NULL!=pGizmo)
        !           383:         {
        !           384:         pGizmo->x+=cx;
        !           385: 
        !           386:         //hWnd is NULL for buttons and separators.
        !           387:         if (NULL!=pGizmo->hWnd)
        !           388:             SetWindowPos(pGizmo->hWnd, NULL, pGizmo->x, pGizmo->y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
        !           389: 
        !           390:         pGizmo=pGizmo->pNext;
        !           391:         }
        !           392: 
        !           393:     return;
        !           394:     }
        !           395: 
        !           396: 
        !           397: 
        !           398: 
        !           399: 
        !           400: 
        !           401: 
        !           402: /*
        !           403:  * GizmosCompact
        !           404:  *
        !           405:  * Purpose:
        !           406:  *  Given a gizmo, moves all other gizmos to the right of it to the
        !           407:  *  left by its width on the GizmoBar.  Used when removing or hiding
        !           408:  *  the gizmo.
        !           409:  *
        !           410:  * Parameters:
        !           411:  *  pGizmo          PGIZMO that is going away, visibly or physically.
        !           412:  *
        !           413:  * Return Value:
        !           414:  *  None
        !           415:  */
        !           416: 
        !           417: void GizmosCompact(PGIZMO pGizmo)
        !           418:     {
        !           419:     UINT        cx;
        !           420:     PGIZMO       pCur;
        !           421: 
        !           422:     //Move all the gizmos beyond us on the GizmoBar back by our width.
        !           423:     if (NULL!=pGizmo->pNext)
        !           424:         {
        !           425:         cx=pGizmo->pNext->x - pGizmo->x;
        !           426:         pCur=pGizmo->pNext;
        !           427: 
        !           428:         while (NULL!=pCur)
        !           429:             {
        !           430:             pCur->x-=cx;
        !           431: 
        !           432:             if (NULL!=pCur->hWnd)
        !           433:                 {
        !           434:                 SetWindowPos(pCur->hWnd, NULL, pCur->x, pCur->y
        !           435:                              , 0, 0, SWP_NOZORDER | SWP_NOSIZE);
        !           436:                 }
        !           437: 
        !           438:             pCur=pCur->pNext;
        !           439:             }
        !           440:         }
        !           441: 
        !           442:     return;
        !           443:     }
        !           444: 
        !           445: 
        !           446: 
        !           447: 
        !           448: 
        !           449: 
        !           450: /*
        !           451:  * GizmoPFind
        !           452:  *
        !           453:  * Purpose:
        !           454:  *  Given a GIZMO identifier, locates and returns a pointer to the structure
        !           455:  *  for that position.
        !           456:  *
        !           457:  * Parameters:
        !           458:  *  ppFirst         PPGIZMO providing the first gizmo in this list.
        !           459:  *  uID             UINT identifier to find.
        !           460:  *
        !           461:  * Return Value:
        !           462:  *  PGIZMO          A pointer to a GIZMO structure allocated through
        !           463:  *                  GizmoPAllocate, NULL if iGizmo is out of range.
        !           464:  */
        !           465: 
        !           466: PGIZMO GizmoPFind(PPGIZMO ppFirst, UINT uID)
        !           467:     {
        !           468:     PGIZMO       pGizmo;
        !           469: 
        !           470:     pGizmo=*ppFirst;
        !           471: 
        !           472:     /*
        !           473:      * Yep, linear search, but a better search algorithm won't improve
        !           474:      * things appreciably.  The better thing to optimize is what the
        !           475:      * caller passes as ppFirst.
        !           476:      */
        !           477:     while (NULL!=pGizmo && uID!=pGizmo->uID)
        !           478:         pGizmo=pGizmo->pNext;
        !           479: 
        !           480:     return pGizmo;
        !           481:     }
        !           482: 
        !           483: 
        !           484: 
        !           485: 
        !           486: 
        !           487: 
        !           488: /*
        !           489:  * GizmoFEnum
        !           490:  *
        !           491:  * Purpose:
        !           492:  *  Enumerates the list of GIZMO structures, passing each one to
        !           493:  *  an application-defined callback.
        !           494:  *
        !           495:  * Parameters:
        !           496:  *  ppFirst         PPGIZMO providing the first gizmo in this list.
        !           497:  *  pfnEnum         PFNGIZMOENUM to call for each enumerated structure.
        !           498:  *  dw              DWORD extra data to pass to the enumeration function.
        !           499:  *
        !           500:  * Return Value:
        !           501:  *  PGIZMO          NULL if the enumeration completed.  Otherwise a pointer
        !           502:  *                  to the gizmo that enumeration stopped on.
        !           503:  */
        !           504: 
        !           505: PGIZMO GizmoPEnum(PPGIZMO ppFirst, PFNGIZMOENUM pfnEnum, DWORD dw)
        !           506:     {
        !           507:     PGIZMO   pGizmo;
        !           508:     UINT    i=0;
        !           509: 
        !           510:     pGizmo=*ppFirst;
        !           511: 
        !           512:     while (NULL!=pGizmo)
        !           513:         {
        !           514:         if (!(*pfnEnum)(pGizmo, i++, dw))
        !           515:             break;
        !           516: 
        !           517:         pGizmo=pGizmo->pNext;
        !           518:         }
        !           519: 
        !           520:     return pGizmo;
        !           521:     }
        !           522: 
        !           523: 
        !           524: 
        !           525: 
        !           526: /*
        !           527:  * GizmoPStateSet
        !           528:  *
        !           529:  * Purpose:
        !           530:  *  State maniuplation functions.  Set and Clear also invalidate
        !           531:  *  this gizmo's rectangle on the given window and forces a repaint.
        !           532:  *
        !           533:  * Parameters:
        !           534:  *  hWnd            HWND of the window to repaint.
        !           535:  *  pGizmo          PGIZMO affected.
        !           536:  *  dwNew           DWORD new state flags.
        !           537:  *
        !           538:  * Return Value:
        !           539:  *  UINT            Previous state.
        !           540:  */
        !           541: 
        !           542: UINT  GizmoPStateSet(HWND hWnd, PGIZMO pGizmo, UINT uNew)
        !           543:     {
        !           544:     UINT        uRet;
        !           545:     RECT        rc;
        !           546: 
        !           547:     if (GIZMOTYPE_SEPARATOR==pGizmo->iType)
        !           548:         return pGizmo->uState;
        !           549: 
        !           550:     //Preserve the color conversion flags across this state change.
        !           551:     uRet=pGizmo->uState;
        !           552:     pGizmo->uState=(uNew & 0x00FF) | (uRet & 0xFF00);
        !           553: 
        !           554:     //Adjust the rectangle by  one to avoid repainting  borders.
        !           555:     SetRect(&rc, pGizmo->x+1, pGizmo->y+1, pGizmo->x+pGizmo->dx-1, pGizmo->y+pGizmo->dy-1);
        !           556:     InvalidateRect(hWnd, &rc, FALSE);
        !           557:     UpdateWindow(hWnd);
        !           558: 
        !           559:     return uRet;
        !           560:     }
        !           561: 
        !           562: 
        !           563: 
        !           564: 
        !           565: 
        !           566: 
        !           567: 
        !           568: 
        !           569: /*
        !           570:  * GizmoPCheck
        !           571:  *
        !           572:  * Purpose:
        !           573:  *  Handles checking a single button in a group of attribute buttons.
        !           574:  *  If the gizmo belongs to a group of mutually exclusive buttons then
        !           575:  *  the others surrounding it are unchecked appropriately.
        !           576:  *
        !           577:  * Parameters:
        !           578:  *  hWnd            HWND of the GizmoBar.
        !           579:  *  pGizmo          PGIZMO of the gizmo affected.
        !           580:  *  fCheck          BOOL TRUE to check the button, FALSE to uncheck.
        !           581:  *
        !           582:  * Return Value:
        !           583:  *  BOOL            TRUE if the gizmo was previously checked, FALSE
        !           584:  *                  otherwise.
        !           585:  */
        !           586: 
        !           587: BOOL GizmoPCheck(HWND hWnd, PGIZMO pGizmo, BOOL fCheck)
        !           588:     {
        !           589:     BOOL        fPrevCheck;
        !           590:     PGIZMO       pCur;
        !           591: 
        !           592: 
        !           593:     //Ignore command buttons.
        !           594:     if (GIZMOTYPE_BUTTONCOMMAND==pGizmo->iType)
        !           595:         return FALSE;
        !           596: 
        !           597:     //Get the previous state
        !           598:     fPrevCheck=(BOOL)(BUTTONGROUP_DOWN & pGizmo->uState);
        !           599: 
        !           600: 
        !           601:     //Simply set the state for inclusive attribute buttons.
        !           602:     if (GIZMOTYPE_BUTTONATTRIBUTEIN==pGizmo->iType)
        !           603:         {
        !           604:         if (pGizmo->fDisabled)
        !           605:             {
        !           606:             GizmoPStateSet(hWnd, pGizmo
        !           607:                 , fCheck ? ATTRIBUTEBUTTON_DOWNDISABLED : ATTRIBUTEBUTTON_DISABLED);
        !           608:             }
        !           609:         else
        !           610:             {
        !           611:             GizmoPStateSet(hWnd, pGizmo
        !           612:                 , fCheck ? ATTRIBUTEBUTTON_DOWN : ATTRIBUTEBUTTON_UP);
        !           613:             }
        !           614:         }
        !           615: 
        !           616: 
        !           617:     if (GIZMOTYPE_BUTTONATTRIBUTEEX==pGizmo->iType)
        !           618:         {
        !           619:         //We cannot uncheck an exclusive attribute
        !           620:         if (!fCheck)
        !           621:             return fPrevCheck;
        !           622: 
        !           623:         /*
        !           624:          * For exclusive buttons we have to do more work.  First, if we're
        !           625:          * already checked (incliding DOWN and MOUSEDOWN) then we set DOWN
        !           626:          * and exit.  If we're not already checked, then we look for the
        !           627:          * gizmo around us, backwards and forwards, that is checked and
        !           628:          * uncheck him.
        !           629:          */
        !           630: 
        !           631:         //Search  backwards.
        !           632:         pCur=pGizmo->pPrev;
        !           633: 
        !           634:         while (NULL!=pCur)
        !           635:             {
        !           636:             //Stop at any non-exclusive attribute.
        !           637:             if (GIZMOTYPE_BUTTONATTRIBUTEEX!=pCur->iType)
        !           638:                 {
        !           639:                 pCur=NULL;
        !           640:                 break;
        !           641:                 }
        !           642: 
        !           643:             //If it's down, set it up and we've finished.
        !           644:             if (BUTTONGROUP_DOWN & pCur->uState)
        !           645:                 break;
        !           646: 
        !           647:             pCur=pCur->pPrev;
        !           648:             }
        !           649: 
        !           650: 
        !           651:         //If we didn't find a previous one, pCur is NULL, so look ahead.
        !           652:         if (NULL==pCur)
        !           653:             {
        !           654:             pCur=pGizmo->pNext;
        !           655: 
        !           656:             while (NULL!=pCur)
        !           657:                 {
        !           658:                 //Stop at any non-exclusive attribute.
        !           659:                 if (GIZMOTYPE_BUTTONATTRIBUTEEX!=pCur->iType)
        !           660:                     {
        !           661:                     pCur=NULL;
        !           662:                     break;
        !           663:                     }
        !           664: 
        !           665:                 //If it's down, set it up and we've finished.
        !           666:                 if (BUTTONGROUP_DOWN & pCur->uState)
        !           667:                     break;
        !           668: 
        !           669:                 pCur=pCur->pNext;
        !           670:                 }
        !           671:             }
        !           672: 
        !           673:         //If pCur is non-NULL, the we found a neighbor, so uncheck him
        !           674:         if (NULL!=pCur)
        !           675:             {
        !           676:             GizmoPStateSet(hWnd, pCur
        !           677:                 , (pGizmo->fDisabled) ? ATTRIBUTEBUTTON_DISABLED : ATTRIBUTEBUTTON_UP);
        !           678:             }
        !           679: 
        !           680:         //Always set ourselves down
        !           681:         GizmoPStateSet(hWnd, pGizmo
        !           682:             , (pGizmo->fDisabled) ? ATTRIBUTEBUTTON_DOWNDISABLED : ATTRIBUTEBUTTON_DOWN);
        !           683:         }
        !           684: 
        !           685:     return fPrevCheck;
        !           686:     }
        !           687: 
        !           688: 
        !           689: 
        !           690: 
        !           691: 
        !           692: 
        !           693: 
        !           694: /*
        !           695:  * GenericSubProc
        !           696:  *
        !           697:  * Purpose:
        !           698:  *  Subclasses window controls in Gizmos so we can trap the tab key and
        !           699:  *  tab to the next control.  We can have one shared generic subclass
        !           700:  *  procedure because we save the type index for this control in the
        !           701:  *  property "iType."  This allows us to look up the original procedure
        !           702:  *  in the pfnOrg array.
        !           703:  *
        !           704:  * Parameters:
        !           705:  *  Standard
        !           706:  *
        !           707:  * Return Value:
        !           708:  *  Standard
        !           709:  */
        !           710: 
        !           711: LRESULT FAR PASCAL EXPORT GenericSubProc(HWND hWnd, UINT iMsg
        !           712:     , WPARAM wParam, LPARAM lParam)
        !           713:     {
        !           714:     LONG        lRet;
        !           715:     RECT        rc;
        !           716:     RECT        rcE;
        !           717:     HWND        hWndE;
        !           718:     HBRUSH      hBr;
        !           719:     HDC         hDC;
        !           720:     UINT        dx;
        !           721:     UINT        iType, i;
        !           722: 
        !           723:     i=(int)GetProp(hWnd, SZTYPEPROP);
        !           724:     iType=POSITIONBIT(i);
        !           725: 
        !           726:     //Special:  paint the gap in drop-down comboboxes.
        !           727:     if (GIZMOTYPE_COMBOBOX==iType && WM_PAINT==iMsg)
        !           728:         {
        !           729:         //Do default painting.
        !           730:         lRet=(*pfnOrg[i])(hWnd, iMsg, wParam, lParam);
        !           731: 
        !           732:         hWndE=GetDlgItem(hWnd, ID_COMBOEDIT);
        !           733: 
        !           734:         GetClientRect(hWnd, &rc);
        !           735:         GetClientRect(hWndE, &rcE);
        !           736: 
        !           737:         //The width of the button is the scroll bar width.
        !           738:         dx=GetSystemMetrics(SM_CXVSCROLL);
        !           739: 
        !           740:         //Calculate the rectangle
        !           741:         rc.right -=dx;
        !           742:         rc.left   =rcE.right;
        !           743:         rc.bottom+=1;
        !           744: 
        !           745:         //Paint the gap
        !           746:         hDC=GetDC(hWnd);   //Already did BeginPaint and EndPaint
        !           747: 
        !           748:         hBr=CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
        !           749:         FillRect(hDC, &rc, hBr);
        !           750:         DeleteObject(hBr);
        !           751: 
        !           752:         ReleaseDC(hWnd, hDC);
        !           753:         return lRet;
        !           754:         }
        !           755: 
        !           756:     //Control tabbing to the next or previous control in the GizmoBar.
        !           757:     if (WM_KEYDOWN==iMsg && VK_TAB==wParam)
        !           758:         {
        !           759:         hWndE=hWnd;
        !           760: 
        !           761:         if (-1==i)
        !           762:             hWndE=GetParent(hWnd);
        !           763: 
        !           764:         hWndE=GetNextDlgTabItem(GetParent(hWndE), hWnd, (BOOL)(GetKeyState(VK_SHIFT)));
        !           765:         SetFocus(hWndE);
        !           766:         return 0L;
        !           767:         }
        !           768: 
        !           769:     if (-1==i) i=0;
        !           770: 
        !           771:     //Eat tab chars in edit controls to prevent beeping.
        !           772:     if (0==i && WM_CHAR==iMsg && VK_TAB==wParam)
        !           773:         return 0L;
        !           774: 
        !           775: 
        !           776:     //Do this or edit controls bomb big-time.
        !           777:     return CallWindowProc(pfnOrg[i], hWnd, iMsg, wParam, lParam);
        !           778:     }

unix.superglobalmegacorp.com

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