Annotation of mstools/samples/sdktools/dlgedit/addctrl.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: addctrl.c
        !            14: *
        !            15: * Contains routines for adding (creating) and deleting controls.
        !            16: *
        !            17: * Functions:
        !            18: *
        !            19: *    AddNewDialog()
        !            20: *    DropControl()
        !            21: *    AddControl()
        !            22: *    CreateControl()
        !            23: *    CreateDlgFont()
        !            24: *    MyGetCharDimensions()
        !            25: *    AdjustDefaultSizes()
        !            26: *    DeleteControl()
        !            27: *    DeleteDialog()
        !            28: *    DeleteControl2()
        !            29: *    FreeCTYPE()
        !            30: *
        !            31: * Comments:
        !            32: *
        !            33: ****************************************************************************/
        !            34: 
        !            35: #include "dlgedit.h"
        !            36: #include "dlgfuncs.h"
        !            37: #include "dlgextrn.h"
        !            38: #include "dialogs.h"
        !            39: 
        !            40: #include <stdlib.h>
        !            41: #include <string.h>
        !            42: 
        !            43: STATICFN HFONT CreateDlgFont(HWND hwnd, LPTSTR pszFontName,
        !            44:     INT nPointSize);
        !            45: STATICFN INT MyGetCharDimensions(HWND hwnd, HFONT hFont,
        !            46:     PTEXTMETRIC ptm);
        !            47: STATICFN VOID AdjustDefaultSizes(VOID);
        !            48: STATICFN VOID DeleteControl2(NPCTYPE npcDel);
        !            49: STATICFN VOID FreeCTYPE(NPCTYPE npc);
        !            50: 
        !            51: 
        !            52: 
        !            53: /************************************************************************
        !            54: * AddNewDialog
        !            55: *
        !            56: * High level function to add a new dialog to the current resource.
        !            57: * Any existing dialog will be saved away in the resource buffer.
        !            58: * The dialog is created at a default position and size with default
        !            59: * styles.
        !            60: *
        !            61: ************************************************************************/
        !            62: 
        !            63: VOID AddNewDialog(VOID)
        !            64: {
        !            65:     RECT rc;
        !            66: 
        !            67:     if (gfEditingDlg) {
        !            68:         if (!SynchDialogResource())
        !            69:             return;
        !            70: 
        !            71:         DeleteDialog(FALSE);
        !            72:     }
        !            73: 
        !            74:     /*
        !            75:      * Now drop a new dialog window.
        !            76:      */
        !            77:     SetRect(&rc, DEFDIALOGXPOS, DEFDIALOGYPOS,
        !            78:             DEFDIALOGXPOS + awcd[W_DIALOG].cxDefault,
        !            79:             DEFDIALOGYPOS + awcd[W_DIALOG].cyDefault);
        !            80:     DropControl(&awcd[W_DIALOG], &rc);
        !            81: }
        !            82: 
        !            83: 
        !            84: 
        !            85: /************************************************************************
        !            86: * DropControl
        !            87: *
        !            88: * This function drops a new control of Type at the specified
        !            89: * location.  The default style and text of the control is
        !            90: * determined from the awcd table based on its type.  The control
        !            91: * is selected after being dropped.  This function changes the status
        !            92: * window to reflect the selected control.
        !            93: *
        !            94: * Arguments:
        !            95: *   PWINDOWCLASSDESC pwcd - Describes the type of new control.
        !            96: *   PRECT prc             - Rectangle of the new control (in dialog units).
        !            97: *
        !            98: ************************************************************************/
        !            99: 
        !           100: VOID DropControl(
        !           101:     PWINDOWCLASSDESC pwcd,
        !           102:     PRECT prc)
        !           103: {
        !           104:     ORDINAL ordIcon;
        !           105:     ORDINAL ordDlg;
        !           106:     LPTSTR pszText;
        !           107:     NPCTYPE npcNew;
        !           108:     INT idCtrl;
        !           109:     DIALOGINFO di;
        !           110: 
        !           111:     /*
        !           112:      * Get the next available id to use for the new control.
        !           113:      */
        !           114:     idCtrl = NextID((pwcd->iType == W_DIALOG) ? NEXTID_DIALOG : NEXTID_CONTROL,
        !           115:             plInclude, 0);
        !           116: 
        !           117:     if (pwcd->iType == W_ICON) {
        !           118:         /*
        !           119:          * For icon controls, the text is really an ordinal or name
        !           120:          * of the icon resource to display.  We get the next available
        !           121:          * id (skipping the id we just got for the control itself) to
        !           122:          * use as an ordinal.
        !           123:          */
        !           124:         WriteOrd(&ordIcon, NextID(NEXTID_CONTROL, plInclude, idCtrl));
        !           125:         pszText = (LPTSTR)&ordIcon;
        !           126:     }
        !           127:     else {
        !           128:         pszText = pwcd->pszTextDefault;
        !           129:     }
        !           130: 
        !           131:     /*
        !           132:      * Make the control.
        !           133:      */
        !           134:     if (pwcd->iType == W_DIALOG) {
        !           135:         /*
        !           136:          * Pick a default name for the dialog.
        !           137:          */
        !           138:         WriteOrd(&ordDlg, NextID(NEXTID_DIALOG, plInclude, 0));
        !           139: 
        !           140:         di.fResFlags = DEFDLGMEMFLAGS;
        !           141:         di.wLanguage = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
        !           142:         di.pszClass = NULL;
        !           143:         di.pszMenu = NULL;
        !           144:         di.DataVersion = 0;
        !           145:         di.Version = 0;
        !           146:         di.Characteristics = 0;
        !           147:         di.nPointSize = DEFPOINTSIZE;
        !           148:         lstrcpy(di.szFontName, ids(IDS_DEFFONTNAME));
        !           149: 
        !           150:         npcNew = AddControl(pwcd, pszText,
        !           151:                 pwcd->flStyles, pwcd->flExtStyle, idCtrl,
        !           152:                 prc->left, prc->top,
        !           153:                 prc->right - prc->left, prc->bottom - prc->top,
        !           154:                 (LPTSTR)&ordDlg, &di);
        !           155:     }
        !           156:     else {
        !           157:         npcNew = AddControl(pwcd, pszText,
        !           158:                 pwcd->flStyles, pwcd->flExtStyle, idCtrl,
        !           159:                 prc->left, prc->top,
        !           160:                 prc->right - prc->left, prc->bottom - prc->top,
        !           161:                 NULL, NULL);
        !           162:     }
        !           163: 
        !           164:     if (!npcNew)
        !           165:         return;
        !           166: 
        !           167:     /*
        !           168:      * If we just dropped a dialog, we need to now show it.
        !           169:      * It it was some other control, mark the dialog as having
        !           170:      * been changed.
        !           171:      */
        !           172:     if (pwcd->iType == W_DIALOG) {
        !           173:         ShowWindow(npcNew->hwnd, SW_SHOWNA);
        !           174:         ToolboxOnTop();
        !           175:     }
        !           176:     else {
        !           177:         gfDlgChanged = TRUE;
        !           178:     }
        !           179: 
        !           180:     SelectControl(npcNew, FALSE);
        !           181: 
        !           182:     gfResChged = TRUE;
        !           183:     ShowFileStatus(FALSE);
        !           184: 
        !           185:     /*
        !           186:      * Now we determine if one of the fields in the status ribbon
        !           187:      * should be given the focus initially.  The assumption is that
        !           188:      * there are some things that a user will always want to change
        !           189:      * when dropping a new control, such as the text in a push
        !           190:      * button, for example.
        !           191:      */
        !           192:     idCtrl = 0;
        !           193:     switch (pwcd->iType) {
        !           194:         case W_ICON:
        !           195:             /*
        !           196:              * For icons, the first thing the user will
        !           197:              * probably want to do is to change the name.
        !           198:              */
        !           199:             idCtrl = DID_STATUSNAME;
        !           200:             break;
        !           201: 
        !           202:         default:
        !           203:             /*
        !           204:              * If this control has text, they will probably want
        !           205:              * to change it.  This includes the caption if the
        !           206:              * control is a dialog.
        !           207:              */
        !           208:             if (pwcd->fHasText)
        !           209:                 idCtrl = DID_STATUSTEXT;
        !           210: 
        !           211:             break;
        !           212:     }
        !           213: 
        !           214:     if (idCtrl) {
        !           215:         SendDlgItemMessage(hwndStatus, idCtrl,
        !           216:                 EM_SETSEL, (WPARAM)(0), (LONG)(-1));
        !           217:         SetFocus(GetDlgItem(hwndStatus, idCtrl));
        !           218:     }
        !           219: }
        !           220: 
        !           221: 
        !           222: 
        !           223: /************************************************************************
        !           224: * AddControl
        !           225: *
        !           226: * This function is used to add a new control.  CreateControl() does
        !           227: * half the work.
        !           228: *
        !           229: * Arguments:
        !           230: *   PWINDOWCLASSDESC pwcd - Window class structure.  Describes the
        !           231: *                           type of control to add.
        !           232: *   LPTSTR pszText        - Text for the new control.
        !           233: *   DWORD style           - Style of the new control.
        !           234: *   DWORD flExtStyle      - Extended style of the new control.
        !           235: *   INT id                - ID for the new control.
        !           236: *   INT x                 - X location of the new control.
        !           237: *   INT y                 - Y location of the new control.
        !           238: *   INT cx                - Width of the new control.
        !           239: *   INT cy                - Height of the new control.
        !           240: *   LPTSTR pszDlgName     - For dialogs, has dialog name.
        !           241: *   PDIALOGINFO pdi       - Ptr to additional dialog info (NULL for controls).
        !           242: *
        !           243: * Returns:
        !           244: *     A pointer to the CTYPE structure for the new control.
        !           245: *     NULL if it couldn't create the control.
        !           246: *
        !           247: ************************************************************************/
        !           248: 
        !           249: NPCTYPE AddControl(
        !           250:     PWINDOWCLASSDESC pwcd,
        !           251:     LPTSTR pszText,
        !           252:     DWORD style,
        !           253:     DWORD flExtStyle,
        !           254:     INT id,
        !           255:     INT x,
        !           256:     INT y,
        !           257:     INT cx,
        !           258:     INT cy,
        !           259:     LPTSTR pszDlgName,
        !           260:     PDIALOGINFO pdi)
        !           261: {
        !           262:     NPCTYPE npcNew;
        !           263:     NPCTYPE npcT;
        !           264:     NPCTYPE *npnpcLast;
        !           265:     HWND hwndBehind;
        !           266: 
        !           267:     if (!(npcNew = (NPCTYPE)MyAlloc(sizeof(CTYPE))))
        !           268:         return NULL;
        !           269: 
        !           270:     /*
        !           271:      * These are checked later if a failure occurs,
        !           272:      * so we null them out now.
        !           273:      */
        !           274:     npcNew->hwnd = NULL;
        !           275:     npcNew->hwndDrag = NULL;
        !           276:     npcNew->text = NULL;
        !           277: 
        !           278:     /*
        !           279:      * Set up some fields and create the control.
        !           280:      */
        !           281:     npcNew->npcNext = NULL;
        !           282:     npcNew->pwcd = pwcd;
        !           283:     npcNew->fSelected = FALSE;
        !           284:     SetRect(&npcNew->rc, x, y, x + cx, y + cy);
        !           285: 
        !           286:     if (pwcd->iType == W_DIALOG)
        !           287:         hwndBehind = (HWND)NULL;
        !           288:     else
        !           289:         hwndBehind = (HWND)1;
        !           290: 
        !           291:     if (!CreateControl(npcNew, pszText, style, flExtStyle, id, &npcNew->rc,
        !           292:             hwndBehind, pdi))
        !           293:         goto CreateFailed;
        !           294: 
        !           295:     /*
        !           296:      * Create the drag window, unless this is the dialog.
        !           297:      */
        !           298:     if (pwcd->iType != W_DIALOG) {
        !           299:         npcNew->hwndDrag = CreateWindow(
        !           300:                 szDragClass,
        !           301:                 NULL,
        !           302:                 WS_CHILD,
        !           303:                 0, 0, 0, 0,
        !           304:                 gcd.npc->hwnd,
        !           305:                 NULL,
        !           306:                 ghInst,
        !           307:                 NULL);
        !           308: 
        !           309:         /*
        !           310:          * Store the CTYPE pointer into the control's drag window.
        !           311:          * This will be used by PCFROMHWND later.
        !           312:          */
        !           313:         SETPCINTOHWND(npcNew->hwndDrag, npcNew);
        !           314: 
        !           315:         /*
        !           316:          * Move the drag window to the top of the Z-Order.
        !           317:          */
        !           318:         SetWindowPos(npcNew->hwndDrag, NULL, 0, 0, 0, 0,
        !           319:                 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
        !           320: 
        !           321:         SizeDragToControl(npcNew);
        !           322:     }
        !           323: 
        !           324:     /*
        !           325:      * Did we just create a dialog?
        !           326:      */
        !           327:     if (pwcd->iType == W_DIALOG) {
        !           328:         /*
        !           329:          * First, copy the new name (it can be an ordinal!).
        !           330:          */
        !           331:         if (!(gcd.pszDlgName = MyAlloc(NameOrdLen(pszDlgName))))
        !           332:             goto CreateFailed;
        !           333: 
        !           334:         NameOrdCpy(gcd.pszDlgName, pszDlgName);
        !           335: 
        !           336:         /*
        !           337:          * Now, setup some other globals.  We clear the gcd.prl pointer,
        !           338:          * because we are assuming that this dialog was not created
        !           339:          * from a res link (it was dropped instead).  The routines
        !           340:          * that call AddControl when creating a dialog from a res
        !           341:          * link are  responsible for setting this global later.
        !           342:          */
        !           343:         gcd.prl = NULL;
        !           344:         gcd.npc = npcNew;
        !           345:         gfEditingDlg = TRUE;
        !           346:     }
        !           347:     else {
        !           348:         /*
        !           349:          * Search for the last control in the list.
        !           350:          */
        !           351:         npnpcLast = &npcHead;
        !           352:         for (npcT = npcHead; npcT; npcT = npcT->npcNext)
        !           353:             npnpcLast = &npcT->npcNext;
        !           354: 
        !           355:         /*
        !           356:          * Link in the new control at the end of the list.
        !           357:          */
        !           358:         *npnpcLast = npcNew;
        !           359:         cWindows++;
        !           360:     }
        !           361: 
        !           362:     return npcNew;
        !           363: 
        !           364: CreateFailed:
        !           365:     FreeCTYPE(npcNew);
        !           366:     return NULL;
        !           367: }
        !           368: 
        !           369: 
        !           370: 
        !           371: /************************************************************************
        !           372: * CreateControl
        !           373: *
        !           374: * Creates a control.  Some styles may be masked off of the actual
        !           375: * control created.  This function can also create the dialog box.
        !           376: *
        !           377: * If the control created is the dialog box, it will not be made visible.
        !           378: * This must be done by the caller.  This allows the caller to first add
        !           379: * all the controls to the dialog before showing it.
        !           380: *
        !           381: * The x, y, cx and cy coordinates are all in dialog units.  For a
        !           382: * type of W_DIALOG, this will be relative to the apps client.  For a
        !           383: * control, this will be relative to the "client" area of the dialog.
        !           384: *
        !           385: * Arguments:
        !           386: *   NPCTYPE npc       - The CTYPE pointer to the new control.  The hwnd
        !           387: *                       fields of the npc will be set.
        !           388: *   LPTSTR pszText    - The window text.
        !           389: *   DWORD flStyle     - The style to use.
        !           390: *   DWORD flExtStyle  - Extended style of the new control.
        !           391: *   INT id            - ID for the control.
        !           392: *   PRECT prc         - The size and location of the new control.
        !           393: *   HWND hwndBehind   - Put new control behind this hwnd in Z-order.
        !           394: *   PDIALOGINFO pdi   - Pointer to additional dialog info (NULL for controls).
        !           395: *
        !           396: * Returns:
        !           397: *     Handle of the control created.
        !           398: *     NULL if control was not created.
        !           399: *
        !           400: ************************************************************************/
        !           401: 
        !           402: HWND CreateControl(
        !           403:     NPCTYPE npc,
        !           404:     LPTSTR pszText,
        !           405:     DWORD flStyle,
        !           406:     DWORD flExtStyle,
        !           407:     INT id,
        !           408:     PRECT prc,
        !           409:     HWND hwndBehind,
        !           410:     PDIALOGINFO pdi)
        !           411: {
        !           412:     HWND hwnd;
        !           413:     HWND hwndChild;
        !           414:     WNDPROC lpfnChild;
        !           415:     RECT rcT;
        !           416:     TEXTMETRIC tm;
        !           417:     LPTSTR pszCreateClass;
        !           418:     LPTSTR pszTextOld;
        !           419:     INT iType = npc->pwcd->iType;
        !           420: 
        !           421:     /*
        !           422:      * Set the text field.  Remember that it can be an ordinal
        !           423:      * (for icon controls).
        !           424:      */
        !           425:     pszTextOld = npc->text;
        !           426:     if (pszText && *pszText) {
        !           427:         if (!(npc->text = MyAlloc(NameOrdLen(pszText))))
        !           428:             return NULL;
        !           429: 
        !           430:         NameOrdCpy(npc->text, pszText);
        !           431:     }
        !           432:     else {
        !           433:         npc->text = NULL;
        !           434:     }
        !           435: 
        !           436:     /*
        !           437:      * If there was text before on this control, free it now.
        !           438:      * This should be done after the new text is allocated and
        !           439:      * copied, because it is common to pass this routine the same
        !           440:      * pointer, and we don't want to free the text before we have
        !           441:      * copied it!
        !           442:      */
        !           443:     if (pszTextOld)
        !           444:         MyFree(pszTextOld);
        !           445: 
        !           446:     /*
        !           447:      * Also set some other values in the CTYPE structure.
        !           448:      */
        !           449:     npc->id = id;
        !           450:     npc->flStyle = flStyle;
        !           451:     npc->flExtStyle = flExtStyle;
        !           452: 
        !           453:     /*
        !           454:      * If this is a dialog and it has the WS_CHILD style, remove
        !           455:      * it and make it WS_POPUP instead.  This prevents some problems
        !           456:      * when editing the dialog.
        !           457:      */
        !           458:     if (iType == W_DIALOG && (flStyle & WS_CHILD)) {
        !           459:         flStyle &= ~WS_CHILD;
        !           460:         flStyle |= WS_POPUP;
        !           461:     }
        !           462: 
        !           463:     /*
        !           464:      * If this is an emulated custom control, we always make it with the
        !           465:      * default styles no matter what the user has specified.  If not,
        !           466:      * remove any styles that can cause problems for a control of this
        !           467:      * type, such as OWNERDRAW styles.
        !           468:      */
        !           469:     if (npc->pwcd->fEmulated)
        !           470:         flStyle = awcd[W_CUSTOM].flStyles;
        !           471:     else
        !           472:         flStyle &= ~npc->pwcd->flStylesBad;
        !           473: 
        !           474:     if (iType == W_DIALOG) {
        !           475:         /*
        !           476:          * If the style includes the DS_MODALFRAME bit, set the appropriate
        !           477:          * extended style bit.
        !           478:          */
        !           479:         if (flStyle & DS_MODALFRAME)
        !           480:             flExtStyle |= WS_EX_DLGMODALFRAME;
        !           481: 
        !           482:         /*
        !           483:          * Create the dialog, but don't show it yet.
        !           484:          */
        !           485:         hwnd = CreateWindowEx(
        !           486:                 flExtStyle,
        !           487:                 MAKEINTRESOURCE(DIALOGCLASS),
        !           488:                 npc->text,
        !           489:                 flStyle & ~WS_VISIBLE,
        !           490:                 0, 0, 0, 0,
        !           491:                 ghwndSubClient,
        !           492:                 0,
        !           493:                 ghInst,
        !           494:                 NULL);
        !           495:     }
        !           496:     else {
        !           497:         /*
        !           498:          * Get the size of the control.
        !           499:          */
        !           500:         rcT = *prc;
        !           501: 
        !           502:         /*
        !           503:          * Map the dialog unit rectangle to window coords.
        !           504:          */
        !           505:         DUToWinRect(&rcT);
        !           506: 
        !           507:         /*
        !           508:          * If this is an icon, the text field is actually going
        !           509:          * to be an ordinal that has the resource id.  We must map this to
        !           510:          * an id of our own or when we create the control it will cause a
        !           511:          * "Resource not found" error.
        !           512:          */
        !           513:         if (iType == W_ICON)
        !           514:             pszText = (LPTSTR)&gordIcon;
        !           515:         else
        !           516:             pszText = npc->text;
        !           517: 
        !           518:         /*
        !           519:          * Get the class name to use.  In the case of custom controls,
        !           520:          * if the control is emulated, use the special emulator class.
        !           521:          * Otherwise, it is an installed custom control, and we can use
        !           522:          * it's real class string.
        !           523:          */
        !           524:         if (iType == W_CUSTOM) {
        !           525:             if (npc->pwcd->fEmulated)
        !           526:                 pszCreateClass = szCustomClass;
        !           527:             else
        !           528:                 pszCreateClass = npc->pwcd->pszClass;
        !           529:         }
        !           530:         else {
        !           531:             pszCreateClass = ids(acsd[awcd[iType].iClass].idsClass);
        !           532:         }
        !           533: 
        !           534:         /*
        !           535:          * Create the control.  We always create it visible in work mode,
        !           536:          * even if the style says it isn't.
        !           537:          */
        !           538:         hwnd = CreateWindowEx(
        !           539:                 flExtStyle,
        !           540:                 pszCreateClass,
        !           541:                 pszText,
        !           542:                 flStyle | WS_VISIBLE,
        !           543:                 rcT.left, rcT.top,
        !           544:                 rcT.right - rcT.left,
        !           545:                 rcT.bottom - rcT.top,
        !           546:                 gcd.npc->hwnd,
        !           547:                 0,
        !           548:                 ghInst,
        !           549:                 NULL);
        !           550:     }
        !           551: 
        !           552:     if (!hwnd) {
        !           553:         Message(MSG_CREATECTRLERROR, pszCreateClass);
        !           554:         return NULL;
        !           555:     }
        !           556: 
        !           557:     if (iType == W_DIALOG) {
        !           558:         /*
        !           559:          * Did they specify a font?
        !           560:          */
        !           561:         if (*pdi->szFontName) {
        !           562:             gcd.hFont = CreateDlgFont(hwnd, pdi->szFontName, pdi->nPointSize);
        !           563:             lstrcpy(gcd.di.szFontName, pdi->szFontName);
        !           564:             gcd.di.nPointSize = pdi->nPointSize;
        !           565:             gcd.fFontSpecified = TRUE;
        !           566:         }
        !           567:         else {
        !           568:             gcd.hFont = NULL;
        !           569:             *gcd.di.szFontName = CHAR_NULL;
        !           570:             gcd.di.nPointSize = 0;
        !           571:             gcd.fFontSpecified = FALSE;
        !           572:         }
        !           573: 
        !           574:         /*
        !           575:          * Get the dimensions of the font.  It is a possible case that
        !           576:          * they specified a font but it could not be created, so in
        !           577:          * that case we use the system font as well as if they didn't
        !           578:          * specify a font at all.
        !           579:          */
        !           580:         if (gcd.hFont) {
        !           581:             gcd.cxChar = MyGetCharDimensions(hwnd, gcd.hFont, &tm);
        !           582:             gcd.cyChar = tm.tmHeight;
        !           583:         }
        !           584:         else {
        !           585:             gcd.cxChar = gcxSysChar;
        !           586:             gcd.cyChar = gcySysChar;
        !           587:         }
        !           588: 
        !           589:         /*
        !           590:          * Now that we know what font we are using, adjust some entries
        !           591:          * in the awcd (array of window class data) table for default 
        !           592:          * sizing of controls.
        !           593:          */
        !           594:         AdjustDefaultSizes();
        !           595:     }
        !           596: 
        !           597:     /*
        !           598:      * If there is a valid user specified font, inform the control
        !           599:      * of it.  Once the font has been set into the dialog, it
        !           600:      * must not be destroyed, because the dialog window will
        !           601:      * clean it up when it is destroyed.
        !           602:      */
        !           603:     if (gcd.hFont)
        !           604:         SendMessage(hwnd, WM_SETFONT, (WPARAM)gcd.hFont, 0L);
        !           605: 
        !           606:     /*
        !           607:      * Move the window into the requested Z-Order.
        !           608:      */
        !           609:     SetWindowPos(hwnd, hwndBehind, 0, 0, 0, 0,
        !           610:             SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
        !           611: 
        !           612:     /*
        !           613:      * Store the CTYPE pointer into the control's hwnd.
        !           614:      * This will be used by PCFROMHWND later.
        !           615:      */
        !           616:     SETPCINTOHWND(hwnd, npc);
        !           617: 
        !           618:     /*
        !           619:      * Subclass the control.
        !           620:      */
        !           621:     npc->pwcd->pfnOldWndProc =
        !           622:             (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC,
        !           623:             (iType == W_DIALOG) ? (DWORD)DialogCtrlWndProc :
        !           624:             (DWORD)CtrlWndProc);
        !           625: 
        !           626:     /*
        !           627:      * Be sure double-clicks are enabled for this control.
        !           628:      */
        !           629:     (UINT)SetClassLong((hwnd), GCL_STYLE, (LONG)((UINT)GetClassLong((hwnd), GCL_STYLE) | CS_DBLCLKS));
        !           630: 
        !           631:     /*
        !           632:      * Subclass any children this control may have.
        !           633:      */
        !           634:     for (hwndChild = GetTopWindow(hwnd); hwndChild;
        !           635:             hwndChild = GetNextWindow(hwndChild, GW_HWNDNEXT)) {
        !           636:         lpfnChild = (WNDPROC)SetWindowLong(hwndChild,
        !           637:                 GWL_WNDPROC, (DWORD)ChildWndProc);
        !           638:         SETCHILDPROC(hwndChild, lpfnChild);
        !           639:     }
        !           640: 
        !           641:     /*
        !           642:      * Did we just create a dialog?
        !           643:      */
        !           644:     if (iType == W_DIALOG) {
        !           645:         /*
        !           646:          * Now that the dialog is created, we can figure out how to
        !           647:          * size it.  We start by mapping the dialog units to window
        !           648:          * coordinates,
        !           649:          */
        !           650:         rcT = *prc;
        !           651:         DUToWinRect(&rcT);
        !           652: 
        !           653:         /*
        !           654:          * We now have the rectangle for the client area.  Expand it
        !           655:          * to account for the frame controls.
        !           656:          */
        !           657:         AdjustWindowRectEx(&rcT, flStyle, FALSE, flExtStyle);
        !           658: 
        !           659:         /*
        !           660:          * Now we can map the rect from the apps client area
        !           661:          * to the desktop, then we set the dialogs position.
        !           662:          */
        !           663:         ClientToScreenRect(ghwndSubClient, &rcT);
        !           664:         SetWindowPos(hwnd, NULL,
        !           665:                 rcT.left, rcT.top,
        !           666:                 rcT.right - rcT.left, rcT.bottom - rcT.top,
        !           667:                 SWP_NOZORDER | SWP_NOACTIVATE);
        !           668: 
        !           669:         SaveDlgClientRect(hwnd);
        !           670: 
        !           671:         /*
        !           672:          * Save the class name, if any.
        !           673:          */
        !           674:         if (pdi->pszClass && *pdi->pszClass) {
        !           675:             if (!(gcd.di.pszClass = MyAlloc(NameOrdLen(pdi->pszClass)))) {
        !           676:                 DestroyWindow(hwnd);
        !           677:                 return (HWND)NULL;
        !           678:             }
        !           679: 
        !           680:             NameOrdCpy(gcd.di.pszClass, pdi->pszClass);
        !           681:         }
        !           682:         else {
        !           683:             gcd.di.pszClass = NULL;
        !           684:         }
        !           685: 
        !           686:         /*
        !           687:          * Save the menu name, if any.
        !           688:          */
        !           689:         if (pdi->pszMenu && *pdi->pszMenu) {
        !           690:             if (!(gcd.di.pszMenu = MyAlloc(NameOrdLen(pdi->pszMenu)))) {
        !           691:                 DestroyWindow(hwnd);
        !           692:                 return (HWND)NULL;
        !           693:             }
        !           694: 
        !           695:             NameOrdCpy(gcd.di.pszMenu, pdi->pszMenu);
        !           696:         }
        !           697:         else {
        !           698:             gcd.di.pszMenu = NULL;
        !           699:         }
        !           700: 
        !           701:         /*
        !           702:          * Set some other fields in the additional dialog info structure.
        !           703:          */
        !           704:         gcd.di.fResFlags = pdi->fResFlags;
        !           705:         gcd.di.wLanguage = pdi->wLanguage;
        !           706:         gcd.di.DataVersion = pdi->DataVersion;
        !           707:         gcd.di.Version = pdi->Version;
        !           708:         gcd.di.Characteristics = pdi->Characteristics;
        !           709:     }
        !           710: 
        !           711:     npc->hwnd = hwnd;
        !           712:     return hwnd;
        !           713: }
        !           714: 
        !           715: 
        !           716: 
        !           717: /************************************************************************
        !           718: * CreateDlgFont
        !           719: *
        !           720: * This function creates a font with the given face name and point size
        !           721: * and returns a handle to it.
        !           722: *
        !           723: * Arguments:
        !           724: *   HWND hwnd           - Dialog window handle.
        !           725: *   LPTSTR pszFontName  - Name of the font (for example: "Helv").
        !           726: *   INT nPointSize      - Point size of the font (for example: 8 or 12).
        !           727: *
        !           728: * Returns:
        !           729: *   A handle to the created font, or NULL if it could not be created.
        !           730: *
        !           731: ************************************************************************/
        !           732: 
        !           733: STATICFN HFONT CreateDlgFont(
        !           734:     HWND hwnd,
        !           735:     LPTSTR pszFontName,
        !           736:     INT nPointSize)
        !           737: {
        !           738:     HFONT hFont;
        !           739:     HFONT hFontOld;
        !           740:     HDC hDC;
        !           741:     LOGFONT lf;
        !           742:     TCHAR szFaceName[LF_FACESIZE];
        !           743: 
        !           744:     /*
        !           745:      * Initialize the logical font structure.  Note that filling the
        !           746:      * structure with zeros gives it all the default settings.
        !           747:      */
        !           748:     memset(&lf, 0, sizeof(LOGFONT));
        !           749:     lf.lfHeight = (SHORT)-PointSizeToPixels(nPointSize);
        !           750:     lf.lfWeight = FW_BOLD;
        !           751:     lstrcpy(lf.lfFaceName, pszFontName);
        !           752: 
        !           753:     if (!(hFont = CreateFontIndirect(&lf)))
        !           754:         return NULL;
        !           755: 
        !           756:     /*
        !           757:      * If we didn't get the face name that was requested, delete the
        !           758:      * new font and return NULL.  This will effectively select the
        !           759:      * system font for this dialog.
        !           760:      */
        !           761:     hDC = GetDC(hwnd);
        !           762:     if (hFontOld = SelectObject(hDC, hFont)) {
        !           763:         GetTextFace(hDC, LF_FACESIZE, szFaceName);
        !           764:         SelectObject(hDC, hFontOld);
        !           765: 
        !           766:         if (lstrcmpi(szFaceName, pszFontName) != 0) {
        !           767:             DeleteObject(hFont);
        !           768:             hFont = NULL;
        !           769:         }
        !           770:     }
        !           771:     else {
        !           772:         DeleteObject(hFont);
        !           773:         hFont = NULL;
        !           774:     }
        !           775: 
        !           776:     ReleaseDC(hwnd, hDC);
        !           777: 
        !           778:     return hFont;
        !           779: }
        !           780: 
        !           781: 
        !           782: 
        !           783: /************************************************************************
        !           784: * MyGetCharDimensions
        !           785: *
        !           786: * This function calculates the average character width of the given
        !           787: * font for the given window.  This must be used instead of
        !           788: * simply using the tmAveCharWidth field of the text metrics, because
        !           789: * this value is not correct for proportional fonts.  
        !           790: *
        !           791: * Arguments:
        !           792: *   HWND hwnd       - The window handle.
        !           793: *   HFONT hFont     - The font handle.
        !           794: *   PTEXTMETRIC ptm - Where to return the text metrics.
        !           795: *
        !           796: * Returns:
        !           797: *   The average character width.  The text metrics are returned in
        !           798: *   the TEXTMETRIC structure pointed to by ptm.
        !           799: *
        !           800: ************************************************************************/
        !           801: 
        !           802: STATICFN INT MyGetCharDimensions(
        !           803:     HWND hwnd,
        !           804:     HFONT hFont,
        !           805:     PTEXTMETRIC ptm)
        !           806: {
        !           807:     register INT i;
        !           808:     HDC hDC;
        !           809:     SIZE size;
        !           810:     INT iWidth;
        !           811:     TCHAR szAveCharWidth[52];
        !           812:     HFONT hFontOld;
        !           813: 
        !           814:     hDC = GetDC(hwnd);
        !           815:     hFontOld = SelectObject(hDC, hFont);
        !           816: 
        !           817:     GetTextMetrics(hDC, ptm);
        !           818: 
        !           819:     /*
        !           820:      * Is this a variable pitch font?
        !           821:      */
        !           822:     if (ptm->tmPitchAndFamily & 0x01) {
        !           823:         for (i = 0; i < 26; i++)
        !           824:             szAveCharWidth[i] = (TCHAR)(i + CHAR_A);
        !           825: 
        !           826:         for (i = 0; i < 26; i++)
        !           827:             szAveCharWidth[i + 26] = (TCHAR)(i + CHAR_CAP_A);
        !           828: 
        !           829:         GetTextExtentPoint(hDC, szAveCharWidth, 52, &size);
        !           830:         iWidth = (INT)size.cx / 26;
        !           831: 
        !           832:         //
        !           833:         // Round it up.
        !           834:         //
        !           835:         iWidth = (iWidth + 1) / 2;
        !           836:     }
        !           837:     else {
        !           838:         iWidth = ptm->tmAveCharWidth;
        !           839:     }
        !           840: 
        !           841:     SelectObject(hDC, hFontOld);
        !           842:     ReleaseDC(hwnd, hDC);
        !           843: 
        !           844:     return iWidth;
        !           845: }
        !           846: 
        !           847: 
        !           848: 
        !           849: /************************************************************************
        !           850: * AdjustDefaultSizes
        !           851: *
        !           852: * This functions adjusts some default size entries in the awcd (array of
        !           853: * window class data) table.
        !           854: * This must be done at run time, because the actual values depend on the
        !           855: * system that dlgedit is being run on and the font of the current dialog.
        !           856: *
        !           857: * This function should be called any time that a dialog is created,
        !           858: * or its font is changed.
        !           859: *
        !           860: ************************************************************************/
        !           861: 
        !           862: STATICFN VOID AdjustDefaultSizes(VOID)
        !           863: {
        !           864:     awcd[W_ICON].cxDefault =
        !           865:             (((GetSystemMetrics(SM_CXICON) * 4) * 2) + gcd.cxChar)
        !           866:             / (gcd.cxChar * 2);
        !           867: 
        !           868:     awcd[W_ICON].cyDefault =
        !           869:             (((GetSystemMetrics(SM_CYICON) * 8) * 2) + gcd.cyChar)
        !           870:             / (gcd.cyChar * 2);
        !           871: 
        !           872:     awcd[W_VERTSCROLL].cxDefault =
        !           873:             (((GetSystemMetrics(SM_CXVSCROLL) * 4) * 2) + gcd.cxChar)
        !           874:             / (gcd.cxChar * 2);
        !           875: 
        !           876:     awcd[W_HORZSCROLL].cyDefault =
        !           877:             (((GetSystemMetrics(SM_CYHSCROLL) * 8) * 2) + gcd.cyChar)
        !           878:             / (gcd.cyChar * 2);
        !           879: }
        !           880: 
        !           881: 
        !           882: 
        !           883: /************************************************************************
        !           884: * DeleteControl
        !           885: *
        !           886: * This deletes all selected controls from the dialog being edited
        !           887: * (or the dialog itself, if it is selected).
        !           888: *
        !           889: ************************************************************************/
        !           890: 
        !           891: VOID DeleteControl(VOID)
        !           892: {
        !           893:     if (gfDlgSelected) {
        !           894:         if (Message(MSG_DELETEDIALOG) == IDYES)
        !           895:             /*
        !           896:              * Delete the dialog, including the resource for it.
        !           897:              */
        !           898:             DeleteDialog(TRUE);
        !           899:     }
        !           900:     else {
        !           901:         while (gnpcSel)
        !           902:             DeleteControl2(gnpcSel);
        !           903: 
        !           904:         gfDlgChanged = TRUE;
        !           905:     }
        !           906: 
        !           907:     gfResChged = TRUE;
        !           908:     ShowFileStatus(FALSE);
        !           909:     StatusUpdate();
        !           910:     StatusSetEnable();
        !           911: }
        !           912: 
        !           913: 
        !           914: 
        !           915: /************************************************************************
        !           916: * DeleteControl2
        !           917: *
        !           918: * This deletes a control by destroying its window and removing it
        !           919: * from the linked list of controls associated with the dialog box.
        !           920: * The control is destroyed and the window is unlinked and the CTYPE free'd.
        !           921: *
        !           922: ************************************************************************/
        !           923: 
        !           924: STATICFN VOID DeleteControl2(
        !           925:     NPCTYPE npcDel)
        !           926: {
        !           927:     register NPCTYPE npcT;
        !           928:     register NPCTYPE *npnpcLast;
        !           929: 
        !           930:     UnSelectControl(npcDel);
        !           931: 
        !           932:     /*
        !           933:      * Search for the control, unlink it from the list and free it.
        !           934:      */
        !           935:     npcT = npcHead;
        !           936:     npnpcLast = &npcHead;
        !           937:     while (npcT) {
        !           938:         if (npcT == npcDel) {
        !           939:             *npnpcLast = npcT->npcNext;
        !           940:             FreeCTYPE(npcT);
        !           941:             cWindows--;
        !           942:             break;
        !           943:         }
        !           944: 
        !           945:         npnpcLast = &npcT->npcNext;
        !           946:         npcT = npcT->npcNext;
        !           947:     }
        !           948: }
        !           949: 
        !           950: 
        !           951: 
        !           952: /************************************************************************
        !           953: * DeleteDialog
        !           954: *
        !           955: * This deletes the dialog box being worked on and sets globals
        !           956: * and the Status Window appropriately.  All CTYPEs are freed, the
        !           957: * status window is updated and the dialog window is destroyed.
        !           958: *
        !           959: * Arguments:
        !           960: *   BOOL fResAlso - If TRUE, delete the dialog resource also.
        !           961: *
        !           962: ************************************************************************/
        !           963: 
        !           964: VOID DeleteDialog(
        !           965:     BOOL fResAlso)
        !           966: {
        !           967:     register NPCTYPE npcT;
        !           968:     register NPCTYPE npcNext;
        !           969: 
        !           970:     CancelSelection(FALSE);
        !           971: 
        !           972:     /*
        !           973:      * If they requested that the dialog resource be deleted also,
        !           974:      * do it first while some globals are still set.
        !           975:      */
        !           976:     if (fResAlso)
        !           977:         DeleteDialogResource();
        !           978: 
        !           979:     /*
        !           980:      * Hide the window for better painting speed.
        !           981:      */
        !           982:     ShowWindow(gcd.npc->hwnd, SW_HIDE);
        !           983: 
        !           984:     /*
        !           985:      * Free all the controls.
        !           986:      */
        !           987:     npcT = npcHead;
        !           988:     while (npcT) {
        !           989:         npcNext = npcT->npcNext;
        !           990:         FreeCTYPE(npcT);
        !           991:         npcT = npcNext;
        !           992:     }
        !           993:     npcHead = NULL;
        !           994:     cWindows = 0;
        !           995: 
        !           996:     /*
        !           997:      * Free the dialog itself.
        !           998:      */
        !           999:     FreeCTYPE(gcd.npc);
        !          1000: 
        !          1001:     if (gcd.pszDlgName) {
        !          1002:         MyFree(gcd.pszDlgName);
        !          1003:         gcd.pszDlgName = NULL;
        !          1004:     }
        !          1005: 
        !          1006:     if (gcd.di.pszClass) {
        !          1007:         MyFree(gcd.di.pszClass);
        !          1008:         gcd.di.pszClass = NULL;
        !          1009:     }
        !          1010: 
        !          1011:     if (gcd.di.pszMenu) {
        !          1012:         MyFree(gcd.di.pszMenu);
        !          1013:         gcd.di.pszMenu = NULL;
        !          1014:     }
        !          1015: 
        !          1016:     if (gcd.hFont) {
        !          1017:         DeleteObject(gcd.hFont);
        !          1018:         gcd.hFont = NULL;
        !          1019:     }
        !          1020: 
        !          1021:     gcd.fFontSpecified = FALSE;
        !          1022:     *gcd.di.szFontName = CHAR_NULL;
        !          1023: 
        !          1024:     /*
        !          1025:      * Set these globals back to the system font values so that
        !          1026:      * workers like WinToDUPoint will still work.
        !          1027:      */
        !          1028:     gcd.cxChar = gcxSysChar;
        !          1029:     gcd.cyChar = gcySysChar;
        !          1030: 
        !          1031:     gcd.prl = NULL;
        !          1032: 
        !          1033:     gcd.npc = NULL;
        !          1034:     gfEditingDlg = FALSE;
        !          1035:     gfDlgChanged = FALSE;
        !          1036: 
        !          1037:     ToolboxSelectTool(W_NOTHING, FALSE);
        !          1038:     StatusUpdate();
        !          1039:     StatusSetEnable();
        !          1040: }
        !          1041: 
        !          1042: 
        !          1043: 
        !          1044: /************************************************************************
        !          1045: * FreeCTYPE
        !          1046: *
        !          1047: * This function frees an allocated CTYPE.  The associated control or
        !          1048: * dialog window is destroyed, and memory for the text and/or class
        !          1049: * is freed, followed by freeing the actual CTYPE structure itself.
        !          1050: *
        !          1051: * If the hwnd in the CTYPE is NULL, only the text (if not NULL) is
        !          1052: * assumed to be valid and will be freed, followed by the CTYPE structure
        !          1053: * itself.  This allows FreeCTYPE to be called when the CTYPE is only
        !          1054: * partially initialized.  This is a little dependant on the order that
        !          1055: * a CTYPE is allocated and initialized in AddControl().
        !          1056: *
        !          1057: * Arguments:
        !          1058: *     NPCTYPE npc = The CTYPE to free.
        !          1059: *
        !          1060: ************************************************************************/
        !          1061: 
        !          1062: STATICFN VOID FreeCTYPE(
        !          1063:     NPCTYPE npc)
        !          1064: {
        !          1065:     if (npc->hwnd)
        !          1066:         DestroyWindow(npc->hwnd);
        !          1067: 
        !          1068:     if (npc->hwndDrag)
        !          1069:         DestroyWindow(npc->hwndDrag);
        !          1070: 
        !          1071:     if (npc->text)
        !          1072:         MyFree(npc->text);
        !          1073: 
        !          1074:     MyFree(npc);
        !          1075: }

unix.superglobalmegacorp.com

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