Annotation of mstools/samples/sdktools/dlgedit/restodlg.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: restodlg.c
        !            14: *
        !            15: * Routines that take a dialog resource and create the dialog to edit, or
        !            16: * the other way around.
        !            17: *
        !            18: * Fucntions:
        !            19: *   SynchDialogResource()
        !            20: *   AllocDialogResource()
        !            21: *   ResLinkToDialog()
        !            22: *   ResToDialog()
        !            23: *   GetiClass()
        !            24: *   Duplicate()
        !            25: *   MakeCopyFromRes()
        !            26: *   TypeFromClassStyle()
        !            27: *
        !            28: * Comments:
        !            29: *
        !            30: ****************************************************************************/
        !            31: 
        !            32: #include "dlgedit.h"
        !            33: #include "dlgfuncs.h"
        !            34: #include "dlgextrn.h"
        !            35: 
        !            36: STATICFN INT TypeFromClassStyle(INT iClass, DWORD flStyle);
        !            37: 
        !            38: 
        !            39: 
        !            40: /************************************************************************
        !            41: * SynchDialogResource
        !            42: *
        !            43: * This routine synchronizes the resource buffer with the contents of
        !            44: * the current dialog being edited.  This may involve deleting the old
        !            45: * contents of the current dialog prior to adding the new data.
        !            46: *
        !            47: * It is ok to call this routine even if there is not an existing dialog
        !            48: * being edited (it will just return) and it should be called before any
        !            49: * operation that needs the in memory copy of the dialog to accurately
        !            50: * reflect the contents of the current dialog, such as just before a
        !            51: * save to disk.
        !            52: *
        !            53: * Returns:
        !            54: *     TRUE if all goes well (includes the case where nothing was done).
        !            55: *     FALSE if an error occurs updating the resource.
        !            56: *
        !            57: ************************************************************************/
        !            58: 
        !            59: BOOL SynchDialogResource(VOID)
        !            60: {
        !            61:     PRES pRes;
        !            62:     PRESLINK prl;
        !            63:     PRESLINK prlNew;
        !            64:     PRESLINK prlPrev;
        !            65: 
        !            66:     if (!gfEditingDlg)
        !            67:         return TRUE;
        !            68: 
        !            69:     /*
        !            70:      * Allocate a resource for the current dialog.
        !            71:      */
        !            72:     if (!(pRes = AllocDialogResource(FALSE, FALSE)))
        !            73:         return FALSE;
        !            74: 
        !            75:     /*
        !            76:      * Allocate a new link for it.
        !            77:      */
        !            78:     if (!(prlNew = AllocResLink(pRes)))
        !            79:         return FALSE;
        !            80: 
        !            81:     /*
        !            82:      * Free the local copy of the dialog resource now that the
        !            83:      * link has been created (and the resource copied to global
        !            84:      * memory).
        !            85:      */
        !            86:     MyFree(pRes);
        !            87: 
        !            88:     /*
        !            89:      * Does a link for the dialog already exist?
        !            90:      */
        !            91:     if (gcd.prl) {
        !            92:         /*
        !            93:          * Find the existing link and get it's previous link.
        !            94:          */
        !            95:         for (prl = gprlHead, prlPrev = NULL; prl && prl != gcd.prl;
        !            96:                 prlPrev = prl, prl = prl->prlNext)
        !            97:             ;
        !            98: 
        !            99:         /*
        !           100:          * Start linking it in.
        !           101:          */
        !           102:         prlNew->prlNext = gcd.prl->prlNext;
        !           103: 
        !           104:         if (prlPrev)
        !           105:             prlPrev->prlNext = prlNew;
        !           106:         else
        !           107:             gprlHead = prlNew;
        !           108: 
        !           109:         /*
        !           110:          * Delete the old link now that it is replaced.
        !           111:          */
        !           112:         FreeResLink(gcd.prl);
        !           113:     }
        !           114:     else {
        !           115:         /*
        !           116:          * Search for the end of the list.  Get a pointer to the last link.
        !           117:          */
        !           118:         for (prl = gprlHead, prlPrev = NULL; prl;
        !           119:                 prlPrev = prl, prl = prl->prlNext)
        !           120:             ;
        !           121: 
        !           122:         /*
        !           123:          * Add the new link to the end of the list.
        !           124:          */
        !           125:         if (prlPrev)
        !           126:             prlPrev->prlNext = prlNew;
        !           127:         else
        !           128:             gprlHead = prlNew;
        !           129:     }
        !           130: 
        !           131:     /*
        !           132:      * Update our global with the new link.  Clear the "dialog changed"
        !           133:      * flag.
        !           134:      */
        !           135:     gcd.prl = prlNew;
        !           136:     gfDlgChanged = FALSE;
        !           137: 
        !           138:     return TRUE;
        !           139: }
        !           140: 
        !           141: 
        !           142: 
        !           143: /************************************************************************
        !           144: * AllocDialogResource
        !           145: *
        !           146: * This function allocates memory and builds a resource file format
        !           147: * image in it of the current dialog.
        !           148: *
        !           149: * Arguments:
        !           150: *   BOOL fTestMode     - TRUE if a special test mode version of the current
        !           151: *                        dialog should be created.
        !           152: *   BOOL fClipboard    - If TRUE, only the selected control(s) will be
        !           153: *                        placed in the resource.  This is used when putting
        !           154: *                        controls or groups of controls into the clipboard.
        !           155: *                        If the dialog is selected, this flag is ignored,
        !           156: *                        because selecting the dialog implies all the
        !           157: *                        controls will be written out also.
        !           158: *
        !           159: * Returns:
        !           160: *     Pointer to the resource buffer.
        !           161: *     NULL if unable to create the resource.
        !           162: *
        !           163: ************************************************************************/
        !           164: 
        !           165: PRES AllocDialogResource(
        !           166:     BOOL fTestMode,
        !           167:     BOOL fClipboard)
        !           168: {
        !           169:     NPCTYPE npc;
        !           170:     INT cControls;
        !           171:     BOOL fSelectedOnly = FALSE;
        !           172:     INT cbDlgName;
        !           173:     INT cbCaption;
        !           174:     INT cbPointSize;
        !           175:     INT cbFontName;
        !           176:     INT cbCD;
        !           177:     INT cbResHeader;
        !           178:     INT cbResData;
        !           179:     INT cbResSize;
        !           180:     INT cbMenuName;
        !           181:     INT cbClass;
        !           182:     INT cbText;
        !           183:     INT cbAlloc;
        !           184:     PBYTE pb;
        !           185:     PRES pResBegin;
        !           186:     PRES pResBegin2;
        !           187:     LPTSTR pszClass;
        !           188:     LPTSTR pszMenu;
        !           189:     LPTSTR pszText;
        !           190:     DWORD flStyle;
        !           191:     PDIALOGBOXHEADER pdbh;
        !           192:     PCONTROLDATA pcd;
        !           193:     ORDINAL ordClass;
        !           194: 
        !           195:     cControls = cWindows;
        !           196:     if (fClipboard && !gfDlgSelected) {
        !           197:         fSelectedOnly = TRUE;
        !           198:         for (cControls = 0, npc = npcHead; npc; npc = npc->npcNext)
        !           199:             if (npc->fSelected)
        !           200:                 cControls++;
        !           201:     }
        !           202: 
        !           203:     /*
        !           204:      * If testing, don't allow a dialog to be created with any
        !           205:      * special class, or with the real menu.
        !           206:      */
        !           207:     if (fTestMode) {
        !           208:         pszClass = NULL;
        !           209:         pszMenu = NULL;
        !           210:     }
        !           211:     else {
        !           212:         pszClass = gcd.di.pszClass;
        !           213:         pszMenu = gcd.di.pszMenu;
        !           214:     }
        !           215: 
        !           216:     cbDlgName = NameOrdLen(gcd.pszDlgName);
        !           217:     cbCaption = (gcd.npc->text) ?
        !           218:             (lstrlen(gcd.npc->text) + 1) * sizeof(TCHAR) : sizeof(TCHAR);
        !           219:     cbClass = pszClass ? NameOrdLen(pszClass) : sizeof(TCHAR);
        !           220:     cbMenuName = pszMenu ? NameOrdLen(pszMenu) : sizeof(TCHAR);
        !           221: 
        !           222:     if (gcd.fFontSpecified) {
        !           223:         cbPointSize = sizeof(WORD);
        !           224:         cbFontName = (lstrlen(gcd.di.szFontName) + 1) * sizeof(TCHAR);
        !           225:     }
        !           226:     else {
        !           227:         cbPointSize = cbFontName = 0;
        !           228:     }
        !           229: 
        !           230:     /*
        !           231:      * Calculate the size of the resource header.
        !           232:      */
        !           233:     cbResHeader = sizeof(RES) +             // The first fixed part.
        !           234:             sizeof(ORDINAL) +               // The RT_DIALOG ordinal.
        !           235:             cbDlgName;                      // The dialog's name.
        !           236:     DWordAlign((PBYTE *)&cbResHeader);      // Pad for the dialog's name.
        !           237:     cbResHeader += sizeof(RES2);            // The last fixed part.
        !           238: 
        !           239:     /*
        !           240:      * Calculate the size of the resource data.  This will just include
        !           241:      * the dialog box header right now.
        !           242:      */
        !           243:     cbResData = SIZEOF_DIALOGBOXHEADER +    // The first fixed part.
        !           244:             cbMenuName +                    // The menu.
        !           245:             cbClass +                       // The class.
        !           246:             cbCaption +                     // The caption.
        !           247:             cbPointSize +                   // The point size.
        !           248:             cbFontName;                     // The font name.
        !           249: 
        !           250:     /*
        !           251:      * Allocate some buffer space.  Be sure to round this up to a DWORD
        !           252:      * boundary to allow space for padding if necessary, but don't round
        !           253:      * cbResData field because it will need to be written into the header
        !           254:      * later, and the value that is written is an exact size (not rounded
        !           255:      * up).
        !           256:      */
        !           257:     cbAlloc = cbResSize = cbResHeader + cbResData;
        !           258:     DWordAlign((PBYTE *)&cbAlloc);
        !           259:     if (!(pResBegin = (PRES)MyAlloc(cbAlloc)))
        !           260:         return NULL;
        !           261: 
        !           262:     /*
        !           263:      * Write the resource header.
        !           264:      */
        !           265:     pdbh = (PDIALOGBOXHEADER)WriteResHeader(pResBegin, 0, ORDID_RT_DIALOG,
        !           266:             gcd.pszDlgName, gcd.di.fResFlags, gcd.di.wLanguage,
        !           267:             gcd.di.DataVersion, gcd.di.Version, gcd.di.Characteristics);
        !           268: 
        !           269:     /*
        !           270:      * Write out the style.
        !           271:      */
        !           272:     flStyle = gcd.npc->flStyle;
        !           273:     if (fTestMode) {
        !           274:         flStyle &= ~awcd[W_DIALOG].flStylesTestBad;
        !           275:         flStyle |= WS_VISIBLE;
        !           276:     }
        !           277: 
        !           278:     pdbh->lStyle = flStyle;
        !           279:     pdbh->lExtendedStyle = gcd.npc->flExtStyle;
        !           280:     pdbh->NumberOfItems = (WORD)cControls;
        !           281: 
        !           282:     /*
        !           283:      * Write the coordinates.
        !           284:      *
        !           285:      * If we are allocating a template that only has the selected controls
        !           286:      * in it, we put the value of CONTROLS_ONLY in the "cx" field of the
        !           287:      * dialog header.  This is what we will check when the user pastes
        !           288:      * something from the clipboard into a dialog to determine whether
        !           289:      * to paste the entire dialog, or only the controls within the dialog
        !           290:      * item array.
        !           291:      */
        !           292:     pdbh->x = (WORD)gcd.npc->rc.left;
        !           293:     pdbh->y = (WORD)gcd.npc->rc.top;
        !           294: 
        !           295:     if (fSelectedOnly)
        !           296:         pdbh->cx = CONTROLS_ONLY;
        !           297:     else
        !           298:         pdbh->cx = (WORD)(gcd.npc->rc.right - gcd.npc->rc.left);
        !           299: 
        !           300:     pdbh->cy = (WORD)(gcd.npc->rc.bottom - gcd.npc->rc.top);
        !           301: 
        !           302:     pb = (PBYTE)pdbh + SIZEOF_DIALOGBOXHEADER;
        !           303: 
        !           304:     /*
        !           305:      * Write the menu name if there is one (we always write at least a null.
        !           306:      */
        !           307:     pb = NameOrdCpy((LPTSTR)pb, pszMenu ? pszMenu : szEmpty);
        !           308: 
        !           309:     /*
        !           310:      * Write the class if there is one (we always write at least a null.
        !           311:      */
        !           312:     pb = NameOrdCpy((LPTSTR)pb, pszClass ? pszClass : szEmpty);
        !           313: 
        !           314:     /*
        !           315:      * Write the caption if there is one (we always write at least a null).
        !           316:      */
        !           317:     pb = WriteSz((LPTSTR)pb, gcd.npc->text ? gcd.npc->text : szEmpty);
        !           318: 
        !           319:     /*
        !           320:      * Write out the font, if there is one specified.
        !           321:      */
        !           322:     if (gcd.fFontSpecified) {
        !           323:         *(PWORD)pb = (WORD)gcd.di.nPointSize;
        !           324:         pb += sizeof(WORD);
        !           325: 
        !           326:         pb = WriteSz((LPTSTR)pb, gcd.di.szFontName);
        !           327:     }
        !           328: 
        !           329:     /*
        !           330:      * Pad to a DWORD boundary.  This is ok even if there are no controls
        !           331:      * that follow, because we were sure to allocate on an even dword
        !           332:      * boundary above.
        !           333:      */
        !           334:     DWordPad(&pb);
        !           335: 
        !           336:     /*
        !           337:      * Now do dialog items.
        !           338:      */
        !           339:     for (npc = npcHead; npc; npc = npc->npcNext) {
        !           340:         /*
        !           341:          * Skip the control if it is NOT selected and we only want the
        !           342:          * selected controls.
        !           343:          */
        !           344:         if (fSelectedOnly && !npc->fSelected)
        !           345:             continue;
        !           346: 
        !           347:         /*
        !           348:          * If we are testing, we don't want to really create a control
        !           349:          * with some funny class because it probably won't be found.
        !           350:          * We will substitute our custom class emulator instead.
        !           351:          */
        !           352:         if (fTestMode && npc->pwcd->fEmulated)
        !           353:             pszClass = szCustomClass;
        !           354:         else
        !           355:             pszClass = npc->pwcd->pszClass;
        !           356: 
        !           357:         /*
        !           358:          * Get a pointer to the text.  If this is an icon control and
        !           359:          * we are going into test mode, change the text field so that
        !           360:          * it points to an ordinal for DlgEdit's icon to display, or
        !           361:          * the icon resource will probably not be found when the dialog
        !           362:          * is created.
        !           363:          */
        !           364:         pszText = npc->text;
        !           365:         if (npc->pwcd->iType == W_ICON && fTestMode)
        !           366:             pszText = (LPTSTR)&gordIcon;
        !           367: 
        !           368:         cbText = pszText ? NameOrdLen(pszText) : sizeof(TCHAR);
        !           369:         cbClass = pszClass ? NameOrdLen(pszClass) : sizeof(ORDINAL);
        !           370: 
        !           371:         cbCD = SIZEOF_CONTROLDATA +         // The fixed portion.
        !           372:                 cbClass +                   // The class.
        !           373:                 cbText +                    // The text.
        !           374:                 sizeof(WORD);               // nExtraStuff field.
        !           375: 
        !           376:         /*
        !           377:          * Since we are adding a new control, we dword align the
        !           378:          * previous size of the resource data to ensure the new
        !           379:          * control starts on a dword boundary.
        !           380:          */
        !           381:         DWordAlign((PBYTE *)&cbResSize);
        !           382: 
        !           383:         /*
        !           384:          * Allocate room for this control.  This includes room for the
        !           385:          * template structure, class, text and a byte for the cb field
        !           386:          * for the create struct data.
        !           387:          */
        !           388:         cbAlloc = cbResSize + cbCD;
        !           389:         DWordAlign((PBYTE *)&cbAlloc);
        !           390:         pResBegin2 = (PRES)MyRealloc((PBYTE)pResBegin, cbAlloc);
        !           391:         if (!pResBegin2) {
        !           392:             MyFree(pResBegin);
        !           393:             return NULL;
        !           394:         }
        !           395: 
        !           396:         pResBegin = pResBegin2;
        !           397:         pcd = (PCONTROLDATA)((PBYTE)pResBegin + cbResSize);
        !           398:         cbResSize += cbCD;
        !           399: 
        !           400:         /*
        !           401:          * Write the style.  If testing, remove any styles that can
        !           402:          * cause problems, such as ownerdraw styles.  If testing and
        !           403:          * this is an emulated custom control, always make it with
        !           404:          * the default styles no matter what the user has specified.
        !           405:          */
        !           406:         flStyle = npc->flStyle;
        !           407:         if (fTestMode) {
        !           408:             if (npc->pwcd->fEmulated)
        !           409:                 flStyle = awcd[W_CUSTOM].flStyles;
        !           410:             else
        !           411:                 flStyle &= ~npc->pwcd->flStylesTestBad;
        !           412:         }
        !           413: 
        !           414:         pcd->lStyle = flStyle;
        !           415:         pcd->lExtendedStyle = npc->flExtStyle;
        !           416: 
        !           417:         /*
        !           418:          * Write the coordinates.
        !           419:          */
        !           420:         pcd->x = (WORD)npc->rc.left;
        !           421:         pcd->y = (WORD)npc->rc.top;
        !           422:         pcd->cx = (WORD)(npc->rc.right - npc->rc.left);
        !           423:         pcd->cy = (WORD)(npc->rc.bottom - npc->rc.top);
        !           424: 
        !           425:         /*
        !           426:          * Write the id.
        !           427:          */
        !           428:         pcd->wId = (WORD)npc->id;
        !           429: 
        !           430:         pb = (PBYTE)pcd + SIZEOF_CONTROLDATA;
        !           431: 
        !           432:         /*
        !           433:          * Write the class.  This will be a string, except for the
        !           434:          * predefined control classes, which all have an ordinal
        !           435:          * value defined for them.
        !           436:          */
        !           437:         if (pszClass) {
        !           438:             pb = NameOrdCpy((LPTSTR)pb, pszClass);
        !           439:         }
        !           440:         else {
        !           441:             WriteOrd(&ordClass, acsd[awcd[npc->pwcd->iType].iClass].idOrd);
        !           442:             pb = NameOrdCpy((LPTSTR)pb, (LPTSTR)&ordClass);
        !           443:         }
        !           444: 
        !           445:         /*
        !           446:          * Write the text.
        !           447:          */
        !           448:         pb = NameOrdCpy((LPTSTR)pb, pszText ? pszText : szEmpty);
        !           449: 
        !           450:         /*
        !           451:          * Write out a zero because there are no additional bytes
        !           452:          * of create struct data.
        !           453:          */
        !           454:         *(PWORD)pb = 0;
        !           455:         pb += sizeof(WORD);
        !           456: 
        !           457:         /*
        !           458:          * Pad to a DWORD boundary.  This is ok even if there are no more
        !           459:          * controls, because we were sure to allocate on an even dword
        !           460:          * boundary above.
        !           461:          */
        !           462:         DWordPad(&pb);
        !           463:     }
        !           464: 
        !           465:     /*
        !           466:      * Now go back and fill in the resource data size field.
        !           467:      */
        !           468:     pResBegin->DataSize = cbResSize - cbResHeader;
        !           469: 
        !           470:     return pResBegin;
        !           471: }
        !           472: 
        !           473: 
        !           474: 
        !           475: /************************************************************************
        !           476: * ResLinkToDialog
        !           477: *
        !           478: * This function is used to create a dialog out of a dialog resource
        !           479: * that has been stored in the resource linked list.
        !           480: *
        !           481: * Arguments:
        !           482: *   PRESLINK prl - Points to the link that describes the dialog to
        !           483: *                  create.  It is assumed that the resource is a
        !           484: *                  dialog resource.
        !           485: *
        !           486: ************************************************************************/
        !           487: 
        !           488: VOID ResLinkToDialog(
        !           489:     PRESLINK prl)
        !           490: {
        !           491:     PRES pRes;
        !           492: 
        !           493:     pRes = (PRES)GlobalLock(prl->hRes);
        !           494:     ResToDialog(pRes, TRUE);
        !           495:     GlobalUnlock(prl->hRes);
        !           496: 
        !           497:     /*
        !           498:      * If the dialog was successfully created, remember which res link
        !           499:      * it was created from.
        !           500:      */
        !           501:     if (gfEditingDlg)
        !           502:         gcd.prl = prl;
        !           503: }
        !           504: 
        !           505: 
        !           506: 
        !           507: /************************************************************************
        !           508: * ResToDialog
        !           509: *
        !           510: * This function creates a dialog box, complete with controls,
        !           511: * from a dialog resource template.
        !           512: *
        !           513: * Arguments:
        !           514: *   PRES pRes        - Pointer to the dialog resource to use.
        !           515: *   BOOL fDoDialog   - TRUE if a new dialog should be created, followed
        !           516: *                      by the controls.  If this is FALSE, just the
        !           517: *                      controls will be created and added to the current
        !           518: *                      dialog.
        !           519: *
        !           520: * Returns:
        !           521: *     TRUE on success, FALSE if an error occured.
        !           522: *
        !           523: ************************************************************************/
        !           524: 
        !           525: BOOL ResToDialog(
        !           526:     PRES pRes,
        !           527:     BOOL fDoDialog)
        !           528: {
        !           529:     LPTSTR pszText;
        !           530:     LPTSTR pszClass;
        !           531:     INT x;
        !           532:     INT y;
        !           533:     INT cx;
        !           534:     INT cy;
        !           535:     INT id;
        !           536:     INT iClass;
        !           537:     INT cdit;
        !           538:     INT Type;
        !           539:     DWORD flStyle;
        !           540:     DWORD flExtStyle;
        !           541:     NPCTYPE npc;
        !           542:     LPTSTR pszMenuName;
        !           543:     LPTSTR pszFontName;
        !           544:     INT nPointSize;
        !           545:     LPTSTR pszDlgName;
        !           546:     LPTSTR pszCaption;
        !           547:     PDIALOGBOXHEADER pdbh;
        !           548:     PCONTROLDATA pcd;
        !           549:     PWINDOWCLASSDESC pwcd;
        !           550:     PCUSTLINK pcl;
        !           551:     PRES2 pRes2;
        !           552:     DIALOGINFO di;
        !           553:     CCINFO cci;
        !           554: 
        !           555:     /*
        !           556:      * First check that the pointer is ok.
        !           557:      */
        !           558:     if (!pRes)
        !           559:         return FALSE;
        !           560: 
        !           561:     pRes2 = ResourcePart2(pRes);
        !           562:     pdbh = (PDIALOGBOXHEADER)SkipResHeader(pRes);
        !           563: 
        !           564:     /*
        !           565:      * Parse out the dialog box header.
        !           566:      * After this point, pcd is pointing to the first dialog control item.
        !           567:      */
        !           568:     pcd = ParseDialogBoxHeader(pdbh,
        !           569:             &flStyle, &flExtStyle, &cdit, &x, &y, &cx, &cy,
        !           570:             &pszMenuName, &pszClass, &pszCaption,
        !           571:             &nPointSize, &pszFontName);
        !           572: 
        !           573:     /*
        !           574:      * Are we pasting the entire dialog?
        !           575:      */
        !           576:     if (fDoDialog) {
        !           577:         pszDlgName = ResourceName(pRes);
        !           578: 
        !           579:         /*
        !           580:          * Determine the best base id for the dialog.
        !           581:          */
        !           582:         if (IsOrd(pszDlgName))
        !           583:             id = OrdID(pszDlgName);
        !           584:         else
        !           585:             id = NextID(NEXTID_DIALOG, plInclude, 0);
        !           586: 
        !           587:         di.fResFlags = pRes2->MemoryFlags;
        !           588:         di.wLanguage = pRes2->LanguageId;
        !           589:         di.pszClass = pszClass;
        !           590:         di.pszMenu = pszMenuName;
        !           591:         di.DataVersion = pRes2->DataVersion;
        !           592:         di.Version = pRes2->Version;
        !           593:         di.Characteristics = pRes2->Characteristics;
        !           594:         di.nPointSize = nPointSize;
        !           595:         lstrcpy(di.szFontName, pszFontName ? pszFontName : szEmpty);
        !           596: 
        !           597:         /*
        !           598:          * Create the dialog.
        !           599:          */
        !           600:         if (!AddControl(&awcd[W_DIALOG], pszCaption, flStyle, flExtStyle, id,
        !           601:                 x, y, cx, cy, pszDlgName, &di))
        !           602:             return FALSE;
        !           603:     }
        !           604: 
        !           605:     while (cdit--) {
        !           606:         pcd = ParseControlData(pcd, &flStyle, &flExtStyle, &x, &y, &cx, &cy,
        !           607:                 &id, &pszClass, &pszText);
        !           608: 
        !           609:         /*
        !           610:          * If we are not creating a new dialog, and the id in
        !           611:          * the resource is already in use, we will use the next
        !           612:          * available one instead.
        !           613:          */
        !           614:         if (!fDoDialog && !IsUniqueID(id))
        !           615:             id = NextID(NEXTID_CONTROL, plInclude, 0);
        !           616: 
        !           617:         /*
        !           618:          * Fix up the class.  If the class is a predefined ordinal type,
        !           619:          * we will null out pszClass so it doesn't confuse AddControl
        !           620:          * into thinking that there is a string class for this control.
        !           621:          */
        !           622:         iClass = GetiClass(pszClass);
        !           623:         Type = TypeFromClassStyle(iClass, flStyle);
        !           624:         if (IsOrd(pszClass))
        !           625:             pszClass = NULL;
        !           626: 
        !           627:         if (Type == W_CUSTOM) {
        !           628:             /*
        !           629:              * Search the list of installed custom controls for one
        !           630:              * that matches the class.
        !           631:              */
        !           632:             for (pcl = gpclHead;
        !           633:                     pcl && lstrcmpi(pcl->pwcd->pszClass, pszClass) != 0;
        !           634:                     pcl = pcl->pclNext)
        !           635:                 ;
        !           636: 
        !           637:             /*
        !           638:              * Was a match found?
        !           639:              */
        !           640:             if (pcl) {
        !           641:                 pwcd = pcl->pwcd;
        !           642:             }
        !           643:             else {
        !           644:                 /*
        !           645:                  * An existing custom control link for this class was
        !           646:                  * not found.  We will add an emulated custom control
        !           647:                  * to support it.  We assume the default style and size
        !           648:                  * should be what this control has.
        !           649:                  */
        !           650:                 lstrcpy(cci.szClass, pszClass);
        !           651:                 cci.flOptions = 0;
        !           652:                 *cci.szDesc = TEXT('\0');
        !           653:                 cci.cxDefault = cx;
        !           654:                 cci.cyDefault = cy;
        !           655:                 cci.flStyleDefault = flStyle;
        !           656:                 cci.flExtStyleDefault = flExtStyle;
        !           657:                 *cci.szTextDefault = TEXT('\0');
        !           658:                 cci.cStyleFlags = 0;
        !           659:                 cci.aStyleFlags = NULL;
        !           660:                 cci.lpfnStyle = NULL;
        !           661:                 cci.lpfnSizeToText = NULL;
        !           662:                 cci.dwReserved1 = 0;
        !           663:                 cci.dwReserved2 = 0;
        !           664: 
        !           665:                 if (pcl = AddCustomLink(&cci, TRUE, FALSE, NULL, NULL))
        !           666:                     pwcd = pcl->pwcd;
        !           667:                 else
        !           668:                     /*
        !           669:                      * Skip this control and continue creating the
        !           670:                      * rest of the dialog.
        !           671:                      */
        !           672:                     continue;
        !           673:             }
        !           674:         }
        !           675:         else {
        !           676:             pwcd = &awcd[Type];
        !           677:         }
        !           678: 
        !           679:         /*
        !           680:          * If we are not creating the entire dialog (we allow existing
        !           681:          * resource files to be a little messed up), and this control
        !           682:          * is a default pushbutton, we will then loop through all the
        !           683:          * existing controls checking for another default pushbutton.
        !           684:          * If one is found, we convert the default pushbutton being
        !           685:          * created into a normal pushbutton instead.  It is not allowed
        !           686:          * to have more than one default pushbuttons in the same dialog.
        !           687:          */
        !           688:         if (!fDoDialog && Type == W_PUSHBUTTON &&
        !           689:                 (flStyle & BS_ALL) == BS_DEFPUSHBUTTON) {
        !           690:             for (npc = npcHead; npc; npc = npc->npcNext) {
        !           691:                 if (npc->pwcd->iType == W_PUSHBUTTON &&
        !           692:                         (npc->flStyle & BS_ALL) == BS_DEFPUSHBUTTON) {
        !           693:                     flStyle = (flStyle & ~BS_ALL) | BS_PUSHBUTTON;
        !           694:                     break;
        !           695:                 }
        !           696:             }
        !           697:         }
        !           698: 
        !           699:         npc = AddControl(pwcd, pszText, flStyle, flExtStyle, id,
        !           700:                 x, y, cx, cy, NULL, NULL);
        !           701: 
        !           702:         /*
        !           703:          * If the control creation succeeded, and we are just adding
        !           704:          * controls (not creating a whole new dialog), select the
        !           705:          * controls as they are added, but don't do any drawing yet.
        !           706:          */
        !           707:         if (!fDoDialog && npc)
        !           708:             SelectControl2(npc, TRUE);
        !           709:     }
        !           710: 
        !           711:     /*
        !           712:      * Update the selected rectangle.  This is normally done by
        !           713:      * SelectControl2 but we told it not to so that the selection
        !           714:      * could be done faster.  We also select the first control here.
        !           715:      */
        !           716:     if (!fDoDialog) {
        !           717:         SetAnchorToFirstSel(TRUE);
        !           718:         CalcSelectedRect();
        !           719:     }
        !           720: 
        !           721:     ShowWindow(gcd.npc->hwnd, SW_SHOWNA);
        !           722:     ToolboxOnTop();
        !           723: 
        !           724:     return TRUE;
        !           725: }
        !           726: 
        !           727: 
        !           728: 
        !           729: /************************************************************************
        !           730: * TypeFromClassStyle
        !           731: *
        !           732: * This function returns the type of a control (one of the W_ constants)
        !           733: * based on the class in iClass and the style in flStyle.
        !           734: *
        !           735: * Arguments:
        !           736: *     INT iClass    = The class of the control, as an IC_* defined constant.
        !           737: *     DWORD flStyle = The style of the control.
        !           738: *
        !           739: * Returns:
        !           740: *     The type of the control (W_* constant).
        !           741: *     W_NOTHING is the error return.
        !           742: *
        !           743: ************************************************************************/
        !           744: 
        !           745: STATICFN INT TypeFromClassStyle(
        !           746:     INT iClass,
        !           747:     DWORD flStyle)
        !           748: {
        !           749:     switch (iClass) {
        !           750:         case IC_BUTTON:
        !           751:             return rgmpiClsBtnType[flStyle & BS_ALL];
        !           752: 
        !           753:         case IC_EDIT:
        !           754:             return W_EDIT;
        !           755: 
        !           756:         case IC_SCROLLBAR:
        !           757:             return (flStyle & SBS_VERT) ? W_VERTSCROLL : W_HORZSCROLL;
        !           758: 
        !           759:         case IC_STATIC:
        !           760:             return rgmpiClsStcType[flStyle & SS_ALL];
        !           761: 
        !           762:         case IC_LISTBOX:
        !           763:             return W_LISTBOX;
        !           764: 
        !           765:         case IC_COMBOBOX:
        !           766:             return W_COMBOBOX;
        !           767: 
        !           768:         case IC_CUSTOM:
        !           769:             return W_CUSTOM;
        !           770: 
        !           771:         case IC_DIALOG:
        !           772:             return W_DIALOG;
        !           773: 
        !           774:         default:
        !           775:             return W_NOTHING;
        !           776:     }
        !           777: }
        !           778: 
        !           779: 
        !           780: 
        !           781: /************************************************************************
        !           782: * GetiClass
        !           783: *
        !           784: * This function returns the class identifier number for the
        !           785: * window class of the control, given the class string from the
        !           786: * dialog template.
        !           787: *
        !           788: * An ordinal class is a special ordinal that is used to identify
        !           789: * each of the standard control classes.  It is used in the
        !           790: * dialog template to save space.  The class string passed in
        !           791: * can be an ordinal and if so, it will be checked against these
        !           792: * predefined ordinal class values for a match.
        !           793: *
        !           794: * Arguments:
        !           795: *     LPTSTR pszClass - The class string or ordinal.
        !           796: *
        !           797: * Returns:
        !           798: *     The class identifier, one of the IC_* symbols in dlgedit.h.
        !           799: *     If the class cannot be determined, it assumes it is a custom
        !           800: *     class and returns IC_CUSTOM.
        !           801: *
        !           802: ************************************************************************/
        !           803: 
        !           804: INT GetiClass(
        !           805:     LPTSTR pszClass)
        !           806: {
        !           807:     INT i;
        !           808:     WORD idOrd;
        !           809: 
        !           810:     if (IsOrd(pszClass)) {
        !           811:         idOrd = OrdID(pszClass);
        !           812:         for (i = 0; i < IC_DIALOG; i++) {
        !           813:             if (acsd[i].idOrd == idOrd)
        !           814:                 return i;
        !           815:         }
        !           816:     }
        !           817:     else {
        !           818:         for (i = 0; i < IC_DIALOG; i++) {
        !           819:             if (lstrcmpi(ids(acsd[i].idsClass), pszClass) == 0)
        !           820:                 return i;
        !           821:         }
        !           822:     }
        !           823: 
        !           824:     /*
        !           825:      * Not found.  Assume it is a user defined class.
        !           826:      */
        !           827:     return IC_CUSTOM;
        !           828: }
        !           829: 
        !           830: 
        !           831: 
        !           832: /************************************************************************
        !           833: * Duplicate
        !           834: *
        !           835: * This routine duplicates the current selection.
        !           836: *
        !           837: ************************************************************************/
        !           838: 
        !           839: VOID Duplicate(VOID)
        !           840: {
        !           841:     PRES pRes;
        !           842: 
        !           843:     if (gcSelected) {
        !           844:         /*
        !           845:          * Store the current selection in a dialog resource.
        !           846:          */
        !           847:         if (!(pRes = AllocDialogResource(FALSE, TRUE)))
        !           848:             return;
        !           849: 
        !           850:         MakeCopyFromRes(pRes);
        !           851:     }
        !           852: }
        !           853: 
        !           854: 
        !           855: 
        !           856: /************************************************************************
        !           857: * MakeCopyFromRes
        !           858: *
        !           859: * This function uses the given dialog template to either add a new
        !           860: * dialog to the current resource file, or drop controls from the
        !           861: * template into the current dialog.  If copying a dialog, it is created
        !           862: * right away.  If copying controls, an operation is begun to start
        !           863: * tracking them to their final destination in the current dialog.
        !           864: *
        !           865: * The caller of this function should NOT free pRes.  This will
        !           866: * be done either before the function returns, or after the drag
        !           867: * operation is complete.
        !           868: *
        !           869: * Arguments:
        !           870: *   PRES pRes - Points to the dialog resource that contains
        !           871: *               the dialog or controls to make a copy of.
        !           872: *
        !           873: ************************************************************************/
        !           874: 
        !           875: VOID MakeCopyFromRes(
        !           876:     PRES pRes)
        !           877: {
        !           878:     PDIALOGBOXHEADER pdbh;
        !           879:     PCONTROLDATA pcd;
        !           880:     INT cControls;
        !           881:     INT i;
        !           882:     BOOL fFreeData = TRUE;
        !           883:     INT iType;
        !           884:     INT iClass;
        !           885:     INT nBottom;
        !           886:     INT nBottomLowest;
        !           887: 
        !           888:     gpResCopy = pRes;
        !           889:     pdbh = (PDIALOGBOXHEADER)SkipResHeader(gpResCopy);
        !           890: 
        !           891:     /*
        !           892:      * If cx is CONTROLS_ONLY, then we know that we only
        !           893:      * want to copy the controls in the template, not
        !           894:      * the entire dialog plus controls.
        !           895:      */
        !           896:     if (pdbh->cx == CONTROLS_ONLY) {
        !           897:         /*
        !           898:          * Begin copying in new controls into the current dialog.
        !           899:          */
        !           900:         cControls = pdbh->NumberOfItems;
        !           901:         if (cControls) {
        !           902:             /*
        !           903:              * Seed the rectangle with impossible values.
        !           904:              */
        !           905:             SetRect(&grcCopy, 32000, 32000, -32000, -32000);
        !           906:             nBottomLowest = 0;
        !           907: 
        !           908:             /*
        !           909:              * Loop through all the controls, expanding the rectangle
        !           910:              * to fit around all of them.
        !           911:              */
        !           912:             pcd = SkipDialogBoxHeader(pdbh);
        !           913:             for (i = 0; i < cControls; i++) {
        !           914:                 iClass = GetiClass((LPTSTR)((PBYTE)pcd + SIZEOF_CONTROLDATA));
        !           915:                 iType = TypeFromClassStyle(iClass, pcd->lStyle);
        !           916: 
        !           917:                 if (grcCopy.left > (INT)pcd->x)
        !           918:                     grcCopy.left = (INT)pcd->x;
        !           919: 
        !           920:                 if (grcCopy.top > (INT)pcd->y)
        !           921:                     grcCopy.top = (INT)pcd->y;
        !           922: 
        !           923:                 if (grcCopy.right < (INT)pcd->x + (INT)pcd->cx)
        !           924:                     grcCopy.right = (INT)pcd->x + (INT)pcd->cx;
        !           925: 
        !           926:                 nBottom = ((INT)pcd->y + (INT)pcd->cy) -
        !           927:                         GetOverHang(iType, (INT)pcd->cy);
        !           928:                 if (nBottom > nBottomLowest)
        !           929:                     nBottomLowest = nBottom;
        !           930: 
        !           931:                 if (grcCopy.bottom < (INT)pcd->y + (INT)pcd->cy)
        !           932:                     grcCopy.bottom = (INT)pcd->y + (INT)pcd->cy;
        !           933: 
        !           934:                 pcd = SkipControlData(pcd);
        !           935:             }
        !           936: 
        !           937:             /*
        !           938:              * Begin dragging the new control(s).  Set a flag so that
        !           939:              * the resource data is NOT free'd until after the drag
        !           940:              * is finished.
        !           941:              */
        !           942:             DragNewBegin(grcCopy.right - grcCopy.left,
        !           943:                     grcCopy.bottom - grcCopy.top,
        !           944:                     grcCopy.bottom - nBottomLowest);
        !           945:             fFreeData = FALSE;
        !           946:         }
        !           947:     }
        !           948:     else {
        !           949:         /*
        !           950:          * Begin copying in a new dialog, complete with controls.
        !           951:          */
        !           952:         if (SynchDialogResource()) {
        !           953:             /*
        !           954:              * Remove any existing dialog.
        !           955:              */
        !           956:             if (gfEditingDlg)
        !           957:                 DeleteDialog(FALSE);
        !           958: 
        !           959:             if (ResToDialog(gpResCopy, TRUE)) {
        !           960:                 SelectControl(gcd.npc, FALSE);
        !           961:                 gfResChged = TRUE;
        !           962:                 ShowFileStatus(FALSE);
        !           963:             }
        !           964:         }
        !           965:     }
        !           966: 
        !           967:     if (fFreeData) {
        !           968:         MyFree(gpResCopy);
        !           969:         gpResCopy = NULL;
        !           970:     }
        !           971: }

unix.superglobalmegacorp.com

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