Annotation of mstools/samples/sdktools/dlgedit/custcntl.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: custcntl.c
        !            14: *
        !            15: * Contains functions to support custom controls.
        !            16: *
        !            17: * Functions:
        !            18: *    NewCustDlgProc()
        !            19: *    OpenCustomDialog()
        !            20: *    SelCustDialog()
        !            21: *    SelCustDlgProc()
        !            22: *    RemCustDlgProc()
        !            23: *    CustomWndProc()
        !            24: *    AddCustomLink()
        !            25: *    RemoveCustomLink()
        !            26: *    CallCustomStyle()
        !            27: *    CallCustomSizeToText()
        !            28: *    ReadCustomProfile()
        !            29: *    WriteCustomProfile()
        !            30: *    NewCustInit()
        !            31: *    NewCustOK()
        !            32: *    OpenDLLFile()
        !            33: *    CallCustomInfoA()
        !            34: *    SelCustInit()
        !            35: *    SelCustSelect()
        !            36: *    SelCustOK()
        !            37: *    RemCustInit()
        !            38: *    RemCustOK()
        !            39: *    AllocCUSTLINK()
        !            40: *    FreeCUSTLINK()
        !            41: *
        !            42: * Comments:
        !            43: *
        !            44: ****************************************************************************/
        !            45: 
        !            46: #include "dlgedit.h"
        !            47: #include "dlgfuncs.h"
        !            48: #include "dlgextrn.h"
        !            49: #include "dialogs.h"
        !            50: #include "dlghelp.h"
        !            51: 
        !            52: #include <stdlib.h>
        !            53: #include <string.h>
        !            54: 
        !            55: #include <commdlg.h>
        !            56: 
        !            57: 
        !            58: /*
        !            59:  * Minimum margin around the sample control.
        !            60:  */
        !            61: #define SAMPLEMARGIN                4
        !            62: 
        !            63: 
        !            64: STATICFN VOID NewCustInit(HWND hwnd);
        !            65: STATICFN BOOL NewCustOK(HWND hwnd);
        !            66: STATICFN VOID OpenDLLFile(LPTSTR pszFileName);
        !            67: STATICFN UINT CallCustomInfoA(LPFNCCINFOA lpfnInfoA, LPCCINFO acciW,
        !            68:     INT nControls);
        !            69: STATICFN VOID SelCustInit(HWND hwnd);
        !            70: STATICFN VOID SelCustSelect(HWND hwnd);
        !            71: STATICFN BOOL SelCustOK(HWND hwnd);
        !            72: STATICFN VOID RemCustInit(HWND hwnd);
        !            73: STATICFN BOOL RemCustOK(HWND hwnd);
        !            74: STATICFN PCUSTLINK AllocCUSTLINK(LPCCINFO pcci, BOOL fEmulated,
        !            75:     BOOL fUnicodeDLL, LPTSTR pszFileName, HANDLE hmod);
        !            76: STATICFN VOID FreeCUSTLINK(PCUSTLINK pclFree);
        !            77: 
        !            78: 
        !            79: /*
        !            80:  * Used to return the pwcd that is chosen from the Select Custom
        !            81:  * Control dialog.
        !            82:  */
        !            83: static PWINDOWCLASSDESC pwcdChosen;
        !            84: 
        !            85: /*
        !            86:  * Has the window handle of the sample custom control in the
        !            87:  * Select Custom Control dialog.
        !            88:  */
        !            89: static HWND hwndCustomSample;
        !            90: 
        !            91: 
        !            92: 
        !            93: 
        !            94: /************************************************************************
        !            95: * NewCustDlgProc
        !            96: *
        !            97: * This is the Add Custom Control dialog procedure.
        !            98: *
        !            99: * :
        !           100: *
        !           101: ************************************************************************/
        !           102: 
        !           103: DIALOGPROC NewCustDlgProc(
        !           104:     HWND hwnd,
        !           105:     UINT msg,
        !           106:     WPARAM wParam,
        !           107:     LPARAM lParam)
        !           108: {
        !           109:     switch (msg) {
        !           110:         case WM_INITDIALOG:
        !           111:             NewCustInit(hwnd);
        !           112:             return TRUE;
        !           113: 
        !           114:         case WM_COMMAND:
        !           115:             switch (LOWORD(wParam)) {
        !           116:                 case IDOK:
        !           117:                     if (NewCustOK(hwnd))
        !           118:                         EndDialog(hwnd, IDOK);
        !           119: 
        !           120:                     break;
        !           121: 
        !           122:                 case IDCANCEL:
        !           123:                     EndDialog(hwnd, IDCANCEL);
        !           124:                     break;
        !           125: 
        !           126:                 case IDHELP:
        !           127:                     WinHelp(ghwndMain, gszHelpFile, HELP_CONTEXT,
        !           128:                             HELPID_NEWCUST);
        !           129:                     break;
        !           130:             }
        !           131: 
        !           132:             return TRUE;
        !           133: 
        !           134:         default:
        !           135:             return FALSE;
        !           136:     }
        !           137: }
        !           138: 
        !           139: 
        !           140: 
        !           141: /************************************************************************
        !           142: * NewCustInit
        !           143: *
        !           144: * Processes the WM_INITDIALOG message for the New Temporary Custom Control
        !           145: * dialog procedure.
        !           146: *
        !           147: * History:
        !           148: *
        !           149: ************************************************************************/
        !           150: 
        !           151: STATICFN VOID NewCustInit(
        !           152:     HWND hwnd)
        !           153: {
        !           154:     TCHAR szStyles[32];
        !           155: 
        !           156:     SendDlgItemMessage(hwnd, DID_NEWCUSTCLASS, EM_LIMITTEXT, CCHCCCLASS - 1, 0L);
        !           157: 
        !           158:     SendDlgItemMessage(hwnd, DID_NEWCUSTSTYLES, EM_LIMITTEXT, CCHHEXLONGMAX, 0L);
        !           159:     wsprintf(szStyles, L"%#.8lx", awcd[W_CUSTOM].flStyles);
        !           160:     SetDlgItemText(hwnd, DID_NEWCUSTSTYLES, szStyles);
        !           161: 
        !           162:     SendDlgItemMessage(hwnd, DID_NEWCUSTCX, EM_LIMITTEXT, 3, 0L);
        !           163:     SetDlgItemInt(hwnd, DID_NEWCUSTCX, awcd[W_CUSTOM].cxDefault, FALSE);
        !           164: 
        !           165:     SendDlgItemMessage(hwnd, DID_NEWCUSTCY, EM_LIMITTEXT, 3, 0L);
        !           166:     SetDlgItemInt(hwnd, DID_NEWCUSTCY, awcd[W_CUSTOM].cyDefault, FALSE);
        !           167: 
        !           168:     SendDlgItemMessage(hwnd, DID_NEWCUSTTEXT, EM_LIMITTEXT, CCHCCTEXT - 1, 0L);
        !           169: 
        !           170:     CenterWindow(hwnd);
        !           171: }
        !           172: 
        !           173: 
        !           174: 
        !           175: /************************************************************************
        !           176: * NewCustOK
        !           177: *
        !           178: * Processes the OK button from the New Temporary Custom Control dialog.
        !           179: *
        !           180: * History:
        !           181: *
        !           182: ************************************************************************/
        !           183: 
        !           184: STATICFN BOOL NewCustOK(
        !           185:     HWND hwnd)
        !           186: {
        !           187:     TCHAR szStyles[CCHHEXLONGMAX + 1];
        !           188:     CCINFO cci;
        !           189: 
        !           190:     /*
        !           191:      * Read the class field.  It is required.
        !           192:      */
        !           193:     if (!GetDlgItemText(hwnd, DID_NEWCUSTCLASS, cci.szClass, CCHCCCLASS)) {
        !           194:         Message(MSG_NOCLASS);
        !           195:         SetFocus(GetDlgItem(hwnd, DID_NEWCUSTCLASS));
        !           196:         return FALSE;
        !           197:     }
        !           198: 
        !           199:     GetDlgItemText(hwnd, DID_NEWCUSTSTYLES, szStyles, CCHHEXLONGMAX + 1);
        !           200:     cci.flStyleDefault = valtoi(szStyles);
        !           201: 
        !           202:     if (!(cci.cxDefault = GetDlgItemInt(hwnd, DID_NEWCUSTCX, NULL, FALSE))) {
        !           203:         Message(MSG_GTZERO, ids(IDS_WIDTH));
        !           204:         SetFocus(GetDlgItem(hwnd, DID_NEWCUSTCX));
        !           205:         return FALSE;
        !           206:     }
        !           207: 
        !           208:     if (!(cci.cyDefault = GetDlgItemInt(hwnd, DID_NEWCUSTCY, NULL, FALSE))) {
        !           209:         Message(MSG_GTZERO, ids(IDS_HEIGHT));
        !           210:         SetFocus(GetDlgItem(hwnd, DID_NEWCUSTCY));
        !           211:         return FALSE;
        !           212:     }
        !           213: 
        !           214:     GetDlgItemText(hwnd, DID_NEWCUSTTEXT, cci.szTextDefault, CCHCCTEXT);
        !           215: 
        !           216:     cci.flOptions = 0;
        !           217:     *cci.szDesc = TEXT('\0');
        !           218:     cci.flExtStyleDefault = 0;
        !           219:     cci.flCtrlTypeMask = 0;
        !           220:     cci.cStyleFlags = 0;
        !           221:     cci.aStyleFlags = NULL;
        !           222:     cci.lpfnStyle = NULL;
        !           223:     cci.lpfnSizeToText = NULL;
        !           224:     cci.dwReserved1 = 0;
        !           225:     cci.dwReserved2 = 0;
        !           226: 
        !           227:     if (AddCustomLink(&cci, TRUE, FALSE, NULL, NULL))
        !           228:         return TRUE;
        !           229:     else
        !           230:         return FALSE;
        !           231: }
        !           232: 
        !           233: 
        !           234: 
        !           235: /************************************************************************
        !           236: * OpenCustomDialog
        !           237: *
        !           238: * Displays the file open dialog and allows a custom DLL to be selected
        !           239: * and loaded.
        !           240: *
        !           241: * History:
        !           242: *
        !           243: ************************************************************************/
        !           244: 
        !           245: VOID OpenCustomDialog(VOID)
        !           246: {
        !           247:     BOOL fGotName;
        !           248:     OPENFILENAME ofn;
        !           249:     TCHAR szNewFileName[CCHMAXPATH];
        !           250:     TCHAR szFilter[CCHTEXTMAX];
        !           251:     INT idPrevDlg;
        !           252: 
        !           253:     /*
        !           254:      * Begin setting up the globals and the open file dialog structure.
        !           255:      */
        !           256:     *szNewFileName = CHAR_NULL;
        !           257: 
        !           258:     /*
        !           259:      * Build up the filter string.
        !           260:      */
        !           261:     BuildFilterString(FILE_DLL, szFilter);
        !           262: 
        !           263:     ofn.lStructSize = sizeof(ofn);
        !           264:     ofn.hwndOwner = ghwndMain;
        !           265:     ofn.hInstance = NULL;
        !           266:     ofn.lpstrFilter = szFilter;
        !           267:     ofn.lpstrCustomFilter = NULL;
        !           268:     ofn.nMaxCustFilter = 0;
        !           269:     ofn.nFilterIndex = 1;
        !           270:     ofn.lpstrFile = szNewFileName;
        !           271:     ofn.nMaxFile = CCHMAXPATH;
        !           272:     ofn.lpstrFileTitle = NULL;
        !           273:     ofn.nMaxFileTitle = 0;
        !           274:     ofn.lpstrTitle = ids(IDS_DLLOPENTITLE);
        !           275:     ofn.Flags = OFN_HIDEREADONLY | OFN_SHOWHELP | OFN_FILEMUSTEXIST;
        !           276:     ofn.lpstrDefExt = ids(IDS_DLLEXT);
        !           277:     ofn.lpstrInitialDir = NULL;
        !           278:     ofn.lCustData = 0;
        !           279:     ofn.lpfnHook = NULL;
        !           280:     ofn.lpTemplateName = NULL;
        !           281: 
        !           282:     /*
        !           283:      * Fire off the dialog box to open the file.
        !           284:      */
        !           285:     EnteringDialog(DID_COMMONFILEOPENDLL, &idPrevDlg, TRUE);
        !           286:     fGotName = GetOpenFileName(&ofn);
        !           287:     EnteringDialog(idPrevDlg, NULL, FALSE);
        !           288: 
        !           289:     if (fGotName)
        !           290:         OpenDLLFile(szNewFileName);
        !           291: }
        !           292: 
        !           293: 
        !           294: 
        !           295: /************************************************************************
        !           296: * OpenDLLFile
        !           297: *
        !           298: *
        !           299: * History:
        !           300: *
        !           301: ************************************************************************/
        !           302: 
        !           303: STATICFN VOID OpenDLLFile(
        !           304:     LPTSTR pszFileName)
        !           305: {
        !           306:     HANDLE hmod;
        !           307:     LPFNCCINFOA lpfnInfoA;
        !           308:     LPFNCCINFOW lpfnInfoW;
        !           309:     INT i;
        !           310:     BOOL fSuccess = FALSE;
        !           311:     BOOL fUnicodeDLL;
        !           312:     PCUSTLINK pclT;
        !           313:     INT nControls;
        !           314:     INT nControls2;
        !           315:     LPCCINFO acci;
        !           316: 
        !           317:     /*
        !           318:      * Check to see if the DLL has already been loaded.
        !           319:      */
        !           320:     for (pclT = gpclHead; pclT &&
        !           321:             (pclT->pwcd->fEmulated ||
        !           322:             lstrcmpi(pclT->pszFileName, pszFileName) != 0);
        !           323:             pclT = pclT->pclNext)
        !           324:         ;
        !           325: 
        !           326:     /*
        !           327:      * Is the DLL already loaded?
        !           328:      */
        !           329:     if (pclT) {
        !           330:         Message(MSG_CUSTALREADYLOADED, pszFileName);
        !           331:         return;
        !           332:     }
        !           333: 
        !           334:     if (!(hmod = LoadLibrary(pszFileName))) {
        !           335:         Message(MSG_CANTLOADDLL, pszFileName);
        !           336:         return;
        !           337:     }
        !           338: 
        !           339:     lpfnInfoA = (LPFNCCINFOA)GetProcAddress(hmod, "CustomControlInfoA");
        !           340:     lpfnInfoW = (LPFNCCINFOW)GetProcAddress(hmod, "CustomControlInfoW");
        !           341: 
        !           342:     if (!lpfnInfoA && !lpfnInfoW) {
        !           343:         Message(MSG_BADCUSTDLL, pszFileName);
        !           344:         goto Error1;
        !           345:     }
        !           346: 
        !           347:     if (lpfnInfoW) {
        !           348:         nControls = (*lpfnInfoW)(NULL);
        !           349:         fUnicodeDLL = TRUE;
        !           350:     }
        !           351:     else {
        !           352:         nControls = (*lpfnInfoA)(NULL);
        !           353:         fUnicodeDLL = FALSE;
        !           354:     }
        !           355: 
        !           356:     if (!nControls) {
        !           357:         Message(MSG_CANTINITDLL, pszFileName);
        !           358:         goto Error1;
        !           359:     }
        !           360: 
        !           361:     if (!(acci = (LPCCINFO)MyAlloc(nControls * sizeof(CCINFO))))
        !           362:         goto Error1;
        !           363: 
        !           364:     if (fUnicodeDLL)
        !           365:         nControls2 = (*lpfnInfoW)(acci);
        !           366:     else
        !           367:         nControls2 = CallCustomInfoA(lpfnInfoA, acci, nControls);
        !           368: 
        !           369:     if (!nControls2) {
        !           370:         Message(MSG_CANTINITDLL, pszFileName);
        !           371:         goto Error2;
        !           372:     }
        !           373: 
        !           374:     for (i = 0; i < nControls; i++) {
        !           375:         if (!AddCustomLink(&acci[i], FALSE, fUnicodeDLL, pszFileName, hmod))
        !           376:             goto Error2;
        !           377:     }
        !           378: 
        !           379:     fSuccess = TRUE;
        !           380: 
        !           381: Error2:
        !           382:     MyFree(acci);
        !           383: 
        !           384: Error1:
        !           385:     if (!fSuccess)
        !           386:         FreeLibrary(hmod);
        !           387: }
        !           388: 
        !           389: 
        !           390: 
        !           391: /************************************************************************
        !           392: * CallCustomInfoA
        !           393: *
        !           394: * Thunks the call from the unicode DlgEdit to the ANSI custom control
        !           395: * info procedure.
        !           396: *
        !           397: * History:
        !           398: *
        !           399: ************************************************************************/
        !           400: 
        !           401: STATICFN UINT CallCustomInfoA(
        !           402:     LPFNCCINFOA lpfnInfoA,
        !           403:     LPCCINFO acciW,
        !           404:     INT nControls)
        !           405: {
        !           406:     LPCCINFOA acciA;
        !           407:     INT nControls2;
        !           408:     INT i;
        !           409:     INT j;
        !           410:     LPCCSTYLEFLAGA lpFlagsA;
        !           411:     LPCCSTYLEFLAGW aFlagsW = NULL;
        !           412:     INT cch;
        !           413: 
        !           414:     /*
        !           415:      * Allocate the appropriate number of ANSI info structures.
        !           416:      */
        !           417:     if (!(acciA = (LPCCINFOA)MyAlloc(nControls * sizeof(CCINFOA))))
        !           418:         return 0;
        !           419: 
        !           420:     /*
        !           421:      * Call the ANSI info function.
        !           422:      */
        !           423:     if (nControls2 = (*lpfnInfoA)(acciA)) {
        !           424:         /*
        !           425:          * Copy all the ANSI structures to the UNICODE structures,
        !           426:          * converting strings to UNICODE as we go.
        !           427:          */
        !           428:         for (i = 0; i < nControls; i++) {
        !           429:             MultiByteToWideChar(CP_ACP, 0, acciA[i].szClass, -1,
        !           430:                     acciW[i].szClass, CCHCCCLASS);
        !           431:             acciW[i].flOptions = acciA[i].flOptions;
        !           432:             MultiByteToWideChar(CP_ACP, 0, acciA[i].szDesc, -1,
        !           433:                     acciW[i].szDesc, CCHCCDESC);
        !           434:             acciW[i].cxDefault = acciA[i].cxDefault;
        !           435:             acciW[i].cyDefault = acciA[i].cyDefault;
        !           436:             acciW[i].flStyleDefault = acciA[i].flStyleDefault;
        !           437:             acciW[i].flExtStyleDefault = acciA[i].flExtStyleDefault;
        !           438:             acciW[i].flCtrlTypeMask = acciA[i].flCtrlTypeMask;
        !           439:             MultiByteToWideChar(CP_ACP, 0, acciA[i].szTextDefault, -1,
        !           440:                     acciW[i].szTextDefault, CCHCCTEXT);
        !           441: 
        !           442:             /*
        !           443:              * Is there a table of style flags?  If so, we need to build
        !           444:              * up a table of unicode style flags.  Note that since we
        !           445:              * allocate this table, the table must be freed when the
        !           446:              * custom link is destroyed!
        !           447:              */
        !           448:             if (acciA[i].cStyleFlags) {
        !           449:                 /*
        !           450:                  * If they specified that there are style flags, the pointer
        !           451:                  * to the table must not be NULL.
        !           452:                  */
        !           453:                 if (!acciA[i].aStyleFlags)
        !           454:                     return 0;
        !           455: 
        !           456:                 if (!(aFlagsW = (LPCCSTYLEFLAGW)MyAlloc(
        !           457:                         acciA[i].cStyleFlags * sizeof(CCSTYLEFLAGW))))
        !           458:                     return 0;
        !           459: 
        !           460:                 /*
        !           461:                  * Copy all the flags to the new unicode style flag table.
        !           462:                  */
        !           463:                 for (j = 0, lpFlagsA = acciA[i].aStyleFlags;
        !           464:                         j < acciA[i].cStyleFlags; j++, lpFlagsA++) {
        !           465:                     aFlagsW[j].flStyle = lpFlagsA->flStyle;
        !           466:                     aFlagsW[j].flStyleMask = lpFlagsA->flStyleMask;
        !           467: 
        !           468:                     cch =  lstrlenA(lpFlagsA->pszStyle) + 1;
        !           469:                     aFlagsW[j].pszStyle = (LPWSTR)MyAlloc(cch * sizeof(WCHAR));
        !           470: 
        !           471:                     if (!aFlagsW[j].pszStyle)
        !           472:                         return 0;
        !           473: 
        !           474:                     MultiByteToWideChar(CP_ACP, 0, lpFlagsA->pszStyle, -1,
        !           475:                             aFlagsW[j].pszStyle, cch);
        !           476:                 }
        !           477:             }
        !           478: 
        !           479:             acciW[i].cStyleFlags = acciA[i].cStyleFlags;
        !           480:             acciW[i].aStyleFlags = aFlagsW;
        !           481: 
        !           482:             acciW[i].lpfnStyle = (LPFNCCSTYLE)acciA[i].lpfnStyle;
        !           483:             acciW[i].lpfnSizeToText = (LPFNCCSIZETOTEXT)acciA[i].lpfnSizeToText;
        !           484:             acciW[i].dwReserved1 = acciA[i].dwReserved1;
        !           485:             acciW[i].dwReserved2 = acciA[i].dwReserved2;
        !           486:         }
        !           487:     }
        !           488: 
        !           489:     MyFree(acciA);
        !           490: 
        !           491:     return nControls2;
        !           492: }
        !           493: 
        !           494: 
        !           495: 
        !           496: /************************************************************************
        !           497: * SelCustDialog
        !           498: *
        !           499: * Displays the Select Custom Control dialog to choose which custom
        !           500: * control tool should be selected.
        !           501: *
        !           502: * History:
        !           503: *
        !           504: ************************************************************************/
        !           505: 
        !           506: PWINDOWCLASSDESC SelCustDialog(VOID)
        !           507: {
        !           508:     if (DlgBox(DID_SELCUST, (WNDPROC)SelCustDlgProc) == IDOK)
        !           509:         return pwcdChosen;
        !           510:     else
        !           511:         return NULL;
        !           512: }
        !           513: 
        !           514: 
        !           515: 
        !           516: /************************************************************************
        !           517: * SelCustDlgProc
        !           518: *
        !           519: * This is the Select Custom Control dialog procedure.
        !           520: *
        !           521: * History:
        !           522: *
        !           523: ************************************************************************/
        !           524: 
        !           525: DIALOGPROC SelCustDlgProc(
        !           526:     HWND hwnd,
        !           527:     UINT msg,
        !           528:     WPARAM wParam,
        !           529:     LPARAM lParam)
        !           530: {
        !           531:     switch (msg) {
        !           532:         case WM_INITDIALOG:
        !           533:             SelCustInit(hwnd);
        !           534:             return TRUE;
        !           535: 
        !           536:         case WM_COMMAND:
        !           537:             switch (LOWORD(wParam)) {
        !           538:                 case DID_SELCUSTLIST:
        !           539:                     switch (HIWORD(wParam)) {
        !           540:                         case LBN_DBLCLK:
        !           541:                             if (SelCustOK(hwnd))
        !           542:                                 EndDialog(hwnd, IDOK);
        !           543: 
        !           544:                             break;
        !           545: 
        !           546:                         case LBN_SELCHANGE:
        !           547:                             SelCustSelect(hwnd);
        !           548:                             break;
        !           549:                     }
        !           550: 
        !           551:                     break;
        !           552: 
        !           553:                 case IDOK:
        !           554:                     if (SelCustOK(hwnd))
        !           555:                         EndDialog(hwnd, IDOK);
        !           556: 
        !           557:                     break;
        !           558: 
        !           559:                 case IDCANCEL:
        !           560:                     EndDialog(hwnd, IDCANCEL);
        !           561:                     break;
        !           562: 
        !           563:                 case IDHELP:
        !           564:                     WinHelp(ghwndMain, gszHelpFile, HELP_CONTEXT,
        !           565:                             HELPID_SELCUST);
        !           566:                     break;
        !           567:             }
        !           568: 
        !           569:             return TRUE;
        !           570: 
        !           571:         default:
        !           572:             return FALSE;
        !           573:     }
        !           574: }
        !           575: 
        !           576: 
        !           577: 
        !           578: /************************************************************************
        !           579: * SelCustInit
        !           580: *
        !           581: * Processes the WM_INITDIALOG message for the Select Custom Control
        !           582: * dialog procedure.
        !           583: *
        !           584: * History:
        !           585: *
        !           586: ************************************************************************/
        !           587: 
        !           588: STATICFN VOID SelCustInit(
        !           589:     HWND hwnd)
        !           590: {
        !           591:     HWND hwndLB;
        !           592:     INT i;
        !           593:     PCUSTLINK pcl;
        !           594:     LPTSTR pszDesc;
        !           595: 
        !           596:     hwndLB = GetDlgItem(hwnd, DID_SELCUSTLIST);
        !           597: 
        !           598:     /*
        !           599:      * Insert each custom control into the listbox.
        !           600:      */
        !           601:     for (pcl = gpclHead; pcl; pcl = pcl->pclNext) {
        !           602:         /*
        !           603:          * Use the short description, if the control has one,
        !           604:          * otherwise use the class name itself.
        !           605:          */
        !           606:         if (pcl->pszDesc)
        !           607:             pszDesc = pcl->pszDesc;
        !           608:         else
        !           609:             pszDesc = pcl->pwcd->pszClass;
        !           610: 
        !           611:         i = (INT)SendMessage(hwndLB, LB_ADDSTRING, 0, (DWORD)pszDesc);
        !           612:         SendMessage(hwndLB, LB_SETITEMDATA, i, (DWORD)pcl);
        !           613:     }
        !           614: 
        !           615:     hwndCustomSample = NULL;
        !           616: 
        !           617:     /*
        !           618:      * Select the first item.
        !           619:      */
        !           620:     SendMessage(hwndLB, LB_SETCURSEL, 0, 0L);
        !           621:     SelCustSelect(hwnd);
        !           622: 
        !           623:     CenterWindow(hwnd);
        !           624: }
        !           625: 
        !           626: 
        !           627: 
        !           628: /************************************************************************
        !           629: * SelCustSelect
        !           630: *
        !           631: * Called every time that a different control is selected in the list box
        !           632: * in the Select Custom Control dialog.  It will create a sample control
        !           633: * and show it in the Sample box.
        !           634: *
        !           635: * History:
        !           636: *
        !           637: ************************************************************************/
        !           638: 
        !           639: STATICFN VOID SelCustSelect(
        !           640:     HWND hwnd)
        !           641: {
        !           642:     HWND hwndLB;
        !           643:     INT iSelect;
        !           644:     PCUSTLINK pcl;
        !           645:     PWINDOWCLASSDESC pwcd;
        !           646:     LPTSTR pszClass;
        !           647:     RECT rc;
        !           648:     RECT rcParent;
        !           649:     HWND hwndParent;
        !           650:     INT x;
        !           651:     INT y;
        !           652:     INT cx;
        !           653:     INT cy;
        !           654:     INT cxParent;
        !           655:     INT cyParent;
        !           656: 
        !           657:     hwndLB = GetDlgItem(hwnd, DID_SELCUSTLIST);
        !           658: 
        !           659:     if ((iSelect = (INT)SendMessage(hwndLB, LB_GETCURSEL, 0, 0)) == LB_ERR)
        !           660:         return;
        !           661: 
        !           662:     /*
        !           663:      * Get a pointer to the custom control link (stored in the listbox
        !           664:      * items data field).
        !           665:      */
        !           666:     pcl = (PCUSTLINK)SendMessage(hwndLB, LB_GETITEMDATA, iSelect, 0L);
        !           667:     pwcd = pcl->pwcd;
        !           668: 
        !           669:     /*
        !           670:      * Get the coordinates of the Sample box.
        !           671:      */
        !           672:     hwndParent = GetDlgItem(hwnd, DID_SELCUSTSAMPLE);
        !           673:     GetWindowRect(hwndParent, &rcParent);
        !           674:     ScreenToClientRect(hwnd, &rcParent);
        !           675:     cxParent = (rcParent.right - rcParent.left) - (2 * SAMPLEMARGIN);
        !           676:     cyParent = (rcParent.bottom - rcParent.top) - (2 * SAMPLEMARGIN);
        !           677: 
        !           678:     /*
        !           679:      * Calculate the window size of the sample control.
        !           680:      */
        !           681:     SetRect(&rc, 0, 0, pwcd->cxDefault, pwcd->cyDefault);
        !           682:     DUToWinRect(&rc);
        !           683:     cx = rc.right - rc.left;
        !           684:     cy = rc.bottom - rc.top;
        !           685: 
        !           686:     /*
        !           687:      * Be sure that the control can fit within the sample box.  Adjust
        !           688:      * it down if necessary.
        !           689:      */
        !           690:     if (cx < cxParent) {
        !           691:         x = ((cxParent - cx) / 2) + SAMPLEMARGIN;
        !           692:     }
        !           693:     else {
        !           694:         x = SAMPLEMARGIN;
        !           695:         cx = cxParent;
        !           696:     }
        !           697: 
        !           698:     if (cy < cyParent) {
        !           699:         y = ((cyParent - cy) / 2) + SAMPLEMARGIN;
        !           700:     }
        !           701:     else {
        !           702:         y = SAMPLEMARGIN;
        !           703:         cy = cyParent;
        !           704:     }
        !           705: 
        !           706:     x += rcParent.left;
        !           707:     y += rcParent.top;
        !           708: 
        !           709:     /*
        !           710:      * Destroy the old sample.
        !           711:      */
        !           712:     if (hwndCustomSample)
        !           713:         DestroyWindow(hwndCustomSample);
        !           714: 
        !           715:     /*
        !           716:      * Get the class name to use.
        !           717:      * If the control is emulated, use the special emulator class.
        !           718:      * Otherwise, it is an installed custom control, and we can use
        !           719:      * it's real class string.
        !           720:      */
        !           721:     if (pwcd->fEmulated)
        !           722:         pszClass = szCustomClass;
        !           723:     else
        !           724:         pszClass = pwcd->pszClass;
        !           725: 
        !           726:     /*
        !           727:      * Create the sample control.  We always create it visible here,
        !           728:      * even if the style says it isn't.
        !           729:      */
        !           730:     hwndCustomSample = CreateWindow(
        !           731:             pszClass,
        !           732:             pwcd->pszTextDefault,
        !           733:             pwcd->flStyles | WS_VISIBLE,
        !           734:             x, y, cx, cy,
        !           735:             hwnd,
        !           736:             0,
        !           737:             ghInst,
        !           738:             NULL);
        !           739: }
        !           740: 
        !           741: 
        !           742: 
        !           743: /************************************************************************
        !           744: * SelCustOK
        !           745: *
        !           746: * Processes the final selection of a custom control from the
        !           747: * Select Custom Control dialog.
        !           748: *
        !           749: * History:
        !           750: *
        !           751: ************************************************************************/
        !           752: 
        !           753: STATICFN BOOL SelCustOK(
        !           754:     HWND hwnd)
        !           755: {
        !           756:     HWND hwndLB;
        !           757:     INT iSelect;
        !           758:     PCUSTLINK pcl;
        !           759: 
        !           760:     hwndLB = GetDlgItem(hwnd, DID_SELCUSTLIST);
        !           761: 
        !           762:     if ((iSelect = (INT)SendMessage(hwndLB, LB_GETCURSEL, 0, 0)) == LB_ERR)
        !           763:         return FALSE;
        !           764: 
        !           765:     /*
        !           766:      * Get a pointer to the custom control link (stored in the listbox
        !           767:      * items data field).
        !           768:      */
        !           769:     pcl = (PCUSTLINK)SendMessage(hwndLB, LB_GETITEMDATA, iSelect, 0L);
        !           770: 
        !           771:     pwcdChosen = pcl->pwcd;
        !           772: 
        !           773:     return TRUE;
        !           774: }
        !           775: 
        !           776: 
        !           777: 
        !           778: /************************************************************************
        !           779: * RemCustDlgProc
        !           780: *
        !           781: * This is the Remove Custom Control dialog procedure.
        !           782: * It is used to de-install a custom control.
        !           783: *
        !           784: * History:
        !           785: *
        !           786: ************************************************************************/
        !           787: 
        !           788: DIALOGPROC RemCustDlgProc(
        !           789:     HWND hwnd,
        !           790:     UINT msg,
        !           791:     WPARAM wParam,
        !           792:     LPARAM lParam)
        !           793: {
        !           794:     switch (msg) {
        !           795:         case WM_INITDIALOG:
        !           796:             RemCustInit(hwnd);
        !           797:             return TRUE;
        !           798: 
        !           799:         case WM_COMMAND:
        !           800:             switch (LOWORD(wParam)) {
        !           801:                 case DID_REMCUSTLIST:
        !           802:                     if (HIWORD(wParam) == LBN_DBLCLK) {
        !           803:                         if (RemCustOK(hwnd))
        !           804:                             EndDialog(hwnd, IDOK);
        !           805:                     }
        !           806: 
        !           807:                     break;
        !           808: 
        !           809:                 case IDOK:
        !           810:                     if (RemCustOK(hwnd))
        !           811:                         EndDialog(hwnd, IDOK);
        !           812: 
        !           813:                     break;
        !           814: 
        !           815:                 case IDCANCEL:
        !           816:                     EndDialog(hwnd, IDCANCEL);
        !           817:                     break;
        !           818: 
        !           819:                 case IDHELP:
        !           820:                     WinHelp(ghwndMain, gszHelpFile, HELP_CONTEXT,
        !           821:                             HELPID_REMCUST);
        !           822:                     break;
        !           823:             }
        !           824: 
        !           825:             return TRUE;
        !           826: 
        !           827:         default:
        !           828:             return FALSE;
        !           829:     }
        !           830: }
        !           831: 
        !           832: 
        !           833: 
        !           834: /************************************************************************
        !           835: * RemCustInit
        !           836: *
        !           837: * Processes the WM_INITDIALOG message for the Remove Custom Control
        !           838: * dialog procedure.
        !           839: *
        !           840: * History:
        !           841: *
        !           842: ************************************************************************/
        !           843: 
        !           844: STATICFN VOID RemCustInit(
        !           845:     HWND hwnd)
        !           846: {
        !           847:     HWND hwndLB;
        !           848:     INT i;
        !           849:     PCUSTLINK pcl;
        !           850:     LPTSTR pszDesc;
        !           851: 
        !           852:     hwndLB = GetDlgItem(hwnd, DID_REMCUSTLIST);
        !           853: 
        !           854:     /*
        !           855:      * Insert each custom control into the listbox.
        !           856:      */
        !           857:     for (pcl = gpclHead; pcl; pcl = pcl->pclNext) {
        !           858:         /*
        !           859:          * Use the short description, if the control has one,
        !           860:          * otherwise use the class name itself.
        !           861:          */
        !           862:         if (pcl->pszDesc)
        !           863:             pszDesc = pcl->pszDesc;
        !           864:         else
        !           865:             pszDesc = pcl->pwcd->pszClass;
        !           866: 
        !           867:         i = (INT)SendMessage(hwndLB, LB_ADDSTRING, 0, (DWORD)pszDesc);
        !           868:         SendMessage(hwndLB, LB_SETITEMDATA, i, (DWORD)pcl);
        !           869:     }
        !           870: 
        !           871:     /*
        !           872:      * Select the first item.
        !           873:      */
        !           874:     SendMessage(hwndLB, LB_SETCURSEL, 0, 0L);
        !           875: 
        !           876:     CenterWindow(hwnd);
        !           877: }
        !           878: 
        !           879: 
        !           880: 
        !           881: /************************************************************************
        !           882: * RemCustOK
        !           883: *
        !           884: * Processes the selection of a custom control to delete from the
        !           885: * Remove Custom Control dialog.
        !           886: *
        !           887: * History:
        !           888: *
        !           889: ************************************************************************/
        !           890: 
        !           891: STATICFN BOOL RemCustOK(
        !           892:     HWND hwnd)
        !           893: {
        !           894:     HWND hwndLB;
        !           895:     INT iSelect;
        !           896:     PCUSTLINK pcl;
        !           897:     NPCTYPE npc;
        !           898: 
        !           899:     hwndLB = GetDlgItem(hwnd, DID_REMCUSTLIST);
        !           900: 
        !           901:     if ((iSelect = (INT)SendMessage(hwndLB, LB_GETCURSEL, 0, 0)) != LB_ERR) {
        !           902:         /*
        !           903:          * Get a pointer to the custom control link (stored in the listbox
        !           904:          * items data field).
        !           905:          */
        !           906:         pcl = (PCUSTLINK)SendMessage(hwndLB, LB_GETITEMDATA, iSelect, 0L);
        !           907: 
        !           908:         /*
        !           909:          * Cannot delete if any controls in the current dialog
        !           910:          * are of this type.
        !           911:          */
        !           912:         for (npc = npcHead; npc; npc = npc->npcNext) {
        !           913:             if (pcl->pwcd == npc->pwcd) {
        !           914:                 Message(MSG_CUSTCNTLINUSE);
        !           915:                 return FALSE;
        !           916:             }
        !           917:         }
        !           918: 
        !           919:         RemoveCustomLink(pcl);
        !           920:     }
        !           921: 
        !           922:     return TRUE;
        !           923: }
        !           924: 
        !           925: 
        !           926: 
        !           927: /****************************************************************************
        !           928: * CustomWndProc
        !           929: *
        !           930: * This is the window procedure for the emulated Custom control.
        !           931: *
        !           932: * History:
        !           933: *
        !           934: ****************************************************************************/
        !           935: 
        !           936: WINDOWPROC CustomWndProc(
        !           937:     HWND hwnd,
        !           938:     UINT msg,
        !           939:     WPARAM wParam,
        !           940:     LPARAM lParam)
        !           941: {
        !           942:     switch (msg) {
        !           943:         case WM_PAINT:
        !           944:             {
        !           945:                 HDC hDC;
        !           946:                 PAINTSTRUCT ps;
        !           947:                 RECT rc;
        !           948:                 TCHAR szText[CCHTEXTMAX];
        !           949: 
        !           950:                 hDC = BeginPaint(hwnd, &ps);
        !           951: 
        !           952:                 SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
        !           953:                 GetClientRect(hwnd, &rc);
        !           954:                 Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
        !           955:                 GetWindowText(hwnd, szText, CCHTEXTMAX);
        !           956:                 SetBkMode(hDC, TRANSPARENT);
        !           957: 
        !           958:                 if (gcd.hFont)
        !           959:                     SelectObject(hDC, gcd.hFont);
        !           960: 
        !           961:                 DrawText(hDC, szText, -1, &rc,
        !           962:                         DT_CENTER | DT_NOCLIP | DT_VCENTER | DT_SINGLELINE);
        !           963: 
        !           964:                 EndPaint(hwnd, &ps);
        !           965:             }
        !           966: 
        !           967:             break;
        !           968: 
        !           969:         default:
        !           970:             return DefWindowProc(hwnd, msg, wParam, lParam);
        !           971:     }
        !           972: 
        !           973:     return 0;
        !           974: }
        !           975: 
        !           976: 
        !           977: 
        !           978: /************************************************************************
        !           979: * AddCustomLink
        !           980: *
        !           981: * Adds a new custom control to the linked list.
        !           982: *
        !           983: * Note that normally duplicates are checked for, but it allows multiple
        !           984: * links to be added with the same class if it is a DLL control.  This
        !           985: * is to support multiple control types being added from the same DLL.
        !           986: * Because of this, if the caller is adding a non-emulated link, they
        !           987: * are responsible for checking the list for duplicates first!
        !           988: *
        !           989: * There is one special case.  If it is adding a DLL link, and an
        !           990: * emulated link with the same class name is found, it will walk the
        !           991: * current list of controls and replace all of them with the new DLL
        !           992: * control type, then delete the emulated link.  This is to support
        !           993: * the case where the user creates some controls of class FOO, where
        !           994: * FOO is emulated, then later loads the FOO DLL.  All controls of
        !           995: * this emulated class will be changed to be the real FOO class, and
        !           996: * the DLL FOO link replaces the emulated one.
        !           997: *
        !           998: * History:
        !           999: *
        !          1000: ************************************************************************/
        !          1001: 
        !          1002: PCUSTLINK AddCustomLink(
        !          1003:     LPCCINFO pcci,
        !          1004:     BOOL fEmulated,
        !          1005:     BOOL fUnicodeDLL,
        !          1006:     LPTSTR pszFileName,
        !          1007:     HANDLE hmod)
        !          1008: {
        !          1009:     PCUSTLINK pcl;
        !          1010:     PCUSTLINK pclT;
        !          1011:     PCUSTLINK pclPrev;
        !          1012:     NPCTYPE npc;
        !          1013:     HWND hwndOld;
        !          1014: 
        !          1015:     if (!(pcl = AllocCUSTLINK(pcci, fEmulated, fUnicodeDLL, pszFileName, hmod)))
        !          1016:         return NULL;
        !          1017: 
        !          1018:     if (fEmulated) {
        !          1019:         /*
        !          1020:          * Search the list for another link with the same class.
        !          1021:          */
        !          1022:         for (pclT = gpclHead;
        !          1023:                 pclT && lstrcmpi(pclT->pwcd->pszClass, pcci->szClass) != 0;
        !          1024:                 pclT = pclT->pclNext)
        !          1025:             ;
        !          1026: 
        !          1027:         /*
        !          1028:          * Was a duplicate found?
        !          1029:          */
        !          1030:         if (pclT) {
        !          1031:             FreeCUSTLINK(pcl);
        !          1032:             Message(MSG_CUSTALREADYLOADED, pcci->szClass);
        !          1033: 
        !          1034:             return NULL;
        !          1035:         }
        !          1036:     }
        !          1037:     else {
        !          1038:         /*
        !          1039:          * Search the list for another link with the same class that
        !          1040:          * is an emulated control.
        !          1041:          */
        !          1042:         for (pclT = gpclHead;
        !          1043:                 pclT &&
        !          1044:                 (lstrcmpi(pclT->pwcd->pszClass, pcci->szClass) != 0 ||
        !          1045:                 !pclT->pwcd->fEmulated);
        !          1046:                 pclT = pclT->pclNext)
        !          1047:             ;
        !          1048: 
        !          1049:         /*
        !          1050:          * Was a duplicate found?
        !          1051:          */
        !          1052:         if (pclT) {
        !          1053:             /*
        !          1054:              * At this point we know that this is a DLL link replacing
        !          1055:              * an existing emulated control class.  We want to go through
        !          1056:              * the existing controls and replace any of this class with
        !          1057:              * the new DLL class.  This allows a user to load a dialog
        !          1058:              * with some emulated controls, then later install the custom
        !          1059:              * DLL and have all the existing controls of that class
        !          1060:              * change to show the real control.
        !          1061:              */
        !          1062:             for (npc = npcHead; npc; npc = npc->npcNext) {
        !          1063:                 /*
        !          1064:                  * Is the control of the type that we are replacing?
        !          1065:                  */
        !          1066:                 if (npc->pwcd == pclT->pwcd) {
        !          1067:                     hwndOld = npc->hwnd;
        !          1068: 
        !          1069:                     /*
        !          1070:                      * Unsubclass the old control window, then switch
        !          1071:                      * the pwcd pointer before calling CreateControl.
        !          1072:                      */
        !          1073:                     SetWindowLong(hwndOld, GWL_WNDPROC,
        !          1074:                             (DWORD)npc->pwcd->pfnOldWndProc);
        !          1075:                     UNSETPCINTOHWND(hwndOld);
        !          1076:                     npc->pwcd = pcl->pwcd;
        !          1077: 
        !          1078:                     /*
        !          1079:                      * Create a control of the new type in the same position.
        !          1080:                      */
        !          1081:                     if (CreateControl(npc, npc->text, npc->flStyle,
        !          1082:                             npc->flExtStyle, npc->id, &npc->rc,
        !          1083:                             hwndOld, NULL)) {
        !          1084:                         /*
        !          1085:                          * Get rid of the old control window.
        !          1086:                          */
        !          1087:                         DestroyWindow(hwndOld);
        !          1088: 
        !          1089:                         /*
        !          1090:                          * Adjust the size and position of its drag window.
        !          1091:                          */
        !          1092:                         SizeDragToControl(npc);
        !          1093:                     }
        !          1094:                 }
        !          1095:             }
        !          1096: 
        !          1097:             /*
        !          1098:              * Remove the old link, now that all the controls that
        !          1099:              * used it are gone.
        !          1100:              */
        !          1101:             RemoveCustomLink(pclT);
        !          1102:         }
        !          1103:     }
        !          1104: 
        !          1105:     /*
        !          1106:      * Search for the end of the list.  Get a pointer to the last link.
        !          1107:      */
        !          1108:     for (pclT = gpclHead, pclPrev = NULL; pclT;
        !          1109:             pclPrev = pclT, pclT = pclT->pclNext)
        !          1110:         ;
        !          1111: 
        !          1112:     /*
        !          1113:      * Add the new link to the list.  Add it to the end if there are
        !          1114:      * other links, or initialize the head pointer if this is the
        !          1115:      * first one.
        !          1116:      */
        !          1117:     if (pclPrev)
        !          1118:         pclPrev->pclNext = pcl;
        !          1119:     else
        !          1120:         gpclHead = pcl;
        !          1121: 
        !          1122:     return pcl;
        !          1123: }
        !          1124: 
        !          1125: 
        !          1126: 
        !          1127: /************************************************************************
        !          1128: * AllocCUSTLINK
        !          1129: *
        !          1130: * Allocates a CUSTLINK structure and initializes it.  This includes
        !          1131: * allocating an associated WINDOWCLASSDESC structure.
        !          1132: *
        !          1133: * History:
        !          1134: *
        !          1135: ************************************************************************/
        !          1136: 
        !          1137: STATICFN PCUSTLINK AllocCUSTLINK(
        !          1138:     LPCCINFO pcci,
        !          1139:     BOOL fEmulated,
        !          1140:     BOOL fUnicodeDLL,
        !          1141:     LPTSTR pszFileName,
        !          1142:     HANDLE hmod)
        !          1143: {
        !          1144:     PCUSTLINK pcl;
        !          1145:     PWINDOWCLASSDESC pwcd;
        !          1146: 
        !          1147:     if (!(pwcd = (PWINDOWCLASSDESC)MyAlloc(sizeof(WINDOWCLASSDESC))))
        !          1148:         return NULL;
        !          1149: 
        !          1150:     /*
        !          1151:      * Initialize the structure to be like an emulated custom control.
        !          1152:      */
        !          1153:     *pwcd = awcd[W_CUSTOM];
        !          1154: 
        !          1155:     /*
        !          1156:      * Now override some values.
        !          1157:      */
        !          1158:     pwcd->flStyles = pcci->flStyleDefault;
        !          1159:     pwcd->flExtStyle = pcci->flExtStyleDefault;
        !          1160:     pwcd->cxDefault = pcci->cxDefault;
        !          1161:     pwcd->cyDefault = pcci->cyDefault;
        !          1162:     pwcd->fEmulated = fEmulated;
        !          1163:     pwcd->fUnicodeDLL = fUnicodeDLL;
        !          1164:     pwcd->hmod = hmod;
        !          1165:     pwcd->cStyleFlags = pcci->cStyleFlags;
        !          1166:     pwcd->aStyleFlags = pcci->aStyleFlags;
        !          1167:     pwcd->lpfnStyle = (PROC)pcci->lpfnStyle;
        !          1168:     pwcd->lpfnSizeToText = (PROC)pcci->lpfnSizeToText;
        !          1169:     pwcd->flCtrlTypeMask = pcci->flCtrlTypeMask;
        !          1170: 
        !          1171:     if (pcci->flOptions & CCF_NOTEXT)
        !          1172:         pwcd->fHasText = FALSE;
        !          1173:     else
        !          1174:         pwcd->fHasText = TRUE;
        !          1175: 
        !          1176:     if (pcci->lpfnSizeToText && pwcd->fHasText)
        !          1177:         pwcd->fSizeToText = TRUE;
        !          1178: 
        !          1179:     /*
        !          1180:      * Copy the class name.
        !          1181:      */
        !          1182:     if (!(pwcd->pszClass = NameOrdDup(pcci->szClass)))
        !          1183:         goto error1;
        !          1184: 
        !          1185:     /*
        !          1186:      * Copy the default text.  This is an optional field.
        !          1187:      */
        !          1188:     if (*pcci->szTextDefault) {
        !          1189:         if (!(pwcd->pszTextDefault = NameOrdDup(pcci->szTextDefault)))
        !          1190:             goto error2;
        !          1191:     }
        !          1192:     else {
        !          1193:         pwcd->pszTextDefault = NULL;
        !          1194:     }
        !          1195: 
        !          1196:     if (!(pcl = (PCUSTLINK)MyAlloc(sizeof(CUSTLINK))))
        !          1197:         goto error3;
        !          1198: 
        !          1199:     /*
        !          1200:      * Copy the DLL file name (NULL for emulated controls).
        !          1201:      */
        !          1202:     if (pszFileName && *pszFileName) {
        !          1203:         if (!(pcl->pszFileName = NameOrdDup(pszFileName)))
        !          1204:             goto error4;
        !          1205:     }
        !          1206:     else {
        !          1207:         pcl->pszFileName = NULL;
        !          1208:     }
        !          1209: 
        !          1210:     /*
        !          1211:      * Copy the descriptive text.  This is an optional field.
        !          1212:      */
        !          1213:     if (*pcci->szDesc) {
        !          1214:         if (!(pcl->pszDesc = NameOrdDup(pcci->szDesc)))
        !          1215:             goto error5;
        !          1216:     }
        !          1217:     else {
        !          1218:         pcl->pszDesc = NULL;
        !          1219:     }
        !          1220: 
        !          1221:     pcl->pclNext = NULL;
        !          1222:     pcl->pwcd = pwcd;
        !          1223: 
        !          1224:     return pcl;
        !          1225: 
        !          1226: error5:
        !          1227:     if (pcl->pszFileName)
        !          1228:         MyFree(pcl->pszFileName);
        !          1229: 
        !          1230: error4:
        !          1231:     MyFree(pcl);
        !          1232: 
        !          1233: error3:
        !          1234:     if (pwcd->pszTextDefault)
        !          1235:         MyFree(pwcd->pszTextDefault);
        !          1236: 
        !          1237: error2:
        !          1238:     MyFree(pwcd->pszClass);
        !          1239: 
        !          1240: error1:
        !          1241:     MyFree(pwcd);
        !          1242: 
        !          1243:     return NULL;
        !          1244: }
        !          1245: 
        !          1246: 
        !          1247: 
        !          1248: /************************************************************************
        !          1249: * RemoveCustomLink
        !          1250: *
        !          1251: * Removes and frees a custom control link from the list.
        !          1252: *
        !          1253: * History:
        !          1254: *
        !          1255: ************************************************************************/
        !          1256: 
        !          1257: VOID RemoveCustomLink(
        !          1258:     PCUSTLINK pclFree)
        !          1259: {
        !          1260:     PCUSTLINK pcl;
        !          1261:     PCUSTLINK pclPrev;
        !          1262: 
        !          1263:     /*
        !          1264:      * Search for the link in the list.
        !          1265:      */
        !          1266:     for (pcl = gpclHead, pclPrev = NULL; pcl != pclFree;
        !          1267:             pclPrev = pcl, pcl = pcl->pclNext)
        !          1268:         ;
        !          1269: 
        !          1270:     /*
        !          1271:      * Link was not found.
        !          1272:      */
        !          1273:     if (!pcl)
        !          1274:         return;
        !          1275: 
        !          1276:     /*
        !          1277:      * Remove the link from the list.
        !          1278:      */
        !          1279:     if (pclPrev)
        !          1280:         pclPrev->pclNext = pclFree->pclNext;
        !          1281:     else
        !          1282:         gpclHead = pclFree->pclNext;
        !          1283: 
        !          1284:     /*
        !          1285:      * Finally, free the link completely.
        !          1286:      */
        !          1287:     FreeCUSTLINK(pclFree);
        !          1288: }
        !          1289: 
        !          1290: 
        !          1291: 
        !          1292: /************************************************************************
        !          1293: * FreeCUSTLINK
        !          1294: *
        !          1295: * Frees a CUSTLINK structure.  This includes freeing the
        !          1296: * associated WINDOWCLASSDESC structure.
        !          1297: *
        !          1298: * History:
        !          1299: *
        !          1300: ************************************************************************/
        !          1301: 
        !          1302: STATICFN VOID FreeCUSTLINK(
        !          1303:     PCUSTLINK pclFree)
        !          1304: {
        !          1305:     PCUSTLINK pcl;
        !          1306:     INT i;
        !          1307: 
        !          1308:     /*
        !          1309:      * Do we need to unload the associated DLL?
        !          1310:      */
        !          1311:     if (pclFree->pwcd->hmod) {
        !          1312:         /*
        !          1313:          * Run throught the custom list looking to see if any other
        !          1314:          * installed custom control has the same module handle as the
        !          1315:          * one that we are freeing.
        !          1316:          */
        !          1317:         for (pcl = gpclHead;
        !          1318:                 pcl &&
        !          1319:                 (pcl == pclFree || pcl->pwcd->hmod != pclFree->pwcd->hmod);
        !          1320:                 pcl = pcl->pclNext)
        !          1321:             ;
        !          1322: 
        !          1323:         /*
        !          1324:          * If none were found, it is safe to unload this library.
        !          1325:          * Otherwise, we must leave the library loaded for the
        !          1326:          * others!
        !          1327:          */
        !          1328:         if (!pcl)
        !          1329:             FreeLibrary(pclFree->pwcd->hmod);
        !          1330:     }
        !          1331: 
        !          1332:     MyFree(pclFree->pwcd->pszClass);
        !          1333: 
        !          1334:     if (pclFree->pwcd->pszTextDefault)
        !          1335:         MyFree(pclFree->pwcd->pszTextDefault);
        !          1336: 
        !          1337:     /*
        !          1338:      * Is this a non-unicode DLL?  If so, then when it was loaded,
        !          1339:      * the dialog editor allocated a table of unicode style strings.
        !          1340:      * This table must now be freed.  If the DLL was a unicode one,
        !          1341:      * then the table pointed to by aStyleFlags belongs to the DLL,
        !          1342:      * and it must NOT be freed.
        !          1343:      */
        !          1344:     if (pclFree->pwcd->hmod && !pclFree->pwcd->fUnicodeDLL) {
        !          1345:         for (i = 0; i < pclFree->pwcd->cStyleFlags; i++)
        !          1346:             MyFree(pclFree->pwcd->aStyleFlags[i].pszStyle);
        !          1347: 
        !          1348:         if (pclFree->pwcd->aStyleFlags)
        !          1349:             MyFree(pclFree->pwcd->aStyleFlags);
        !          1350:     }
        !          1351: 
        !          1352:     MyFree(pclFree->pwcd);
        !          1353: 
        !          1354:     if (pclFree->pszFileName)
        !          1355:         MyFree(pclFree->pszFileName);
        !          1356: 
        !          1357:     if (pclFree->pszDesc)
        !          1358:         MyFree(pclFree->pszDesc);
        !          1359: 
        !          1360:     MyFree(pclFree);
        !          1361: }
        !          1362: 
        !          1363: 
        !          1364: 
        !          1365: /************************************************************************
        !          1366: * CallCustomStyle
        !          1367: *
        !          1368: *
        !          1369: * History:
        !          1370: *
        !          1371: ************************************************************************/
        !          1372: 
        !          1373: BOOL CallCustomStyle(
        !          1374:     NPCTYPE npc,
        !          1375:     PDWORD pflStyleNew,
        !          1376:     PDWORD pflExtStyleNew,
        !          1377:     LPTSTR pszTextNew)
        !          1378: {
        !          1379:     CCSTYLE ccs;
        !          1380:     CCSTYLEA ccsA;
        !          1381:     BOOL fSuccess;
        !          1382:     BOOL fDefCharUsed;
        !          1383:     INT idPrevDlg;
        !          1384: 
        !          1385:     /*
        !          1386:      * Because we are about ready to display the dialog, we need to
        !          1387:      * call EnteringDialog so that the properties bar, toolbox and
        !          1388:      * work mode dialog get disabled.  The first parameter is the
        !          1389:      * dialog id, used so that the proper help will be brought up
        !          1390:      * for this dialog.  Since we don't have a meaningful help screen
        !          1391:      * for any old random custom control, just pass in a value of
        !          1392:      * zero, which will cause the Help Contents screen to be
        !          1393:      * brought up if the user presses F1 while the dialog is up.
        !          1394:      */
        !          1395:     EnteringDialog(0, &idPrevDlg, TRUE);
        !          1396: 
        !          1397:     /*
        !          1398:      * Is this a UNICODE DLL?
        !          1399:      */
        !          1400:     if (npc->pwcd->fUnicodeDLL) {
        !          1401:         ccs.flStyle = *pflStyleNew;
        !          1402:         ccs.flExtStyle = *pflExtStyleNew;
        !          1403:         lstrcpy(ccs.szText, pszTextNew);
        !          1404:         ccs.lgid = gcd.di.wLanguage;
        !          1405:         ccs.wReserved1 = 0;
        !          1406: 
        !          1407:         fSuccess = ((LPFNCCSTYLE)(*npc->pwcd->lpfnStyle))(ghwndMain, &ccs);
        !          1408: 
        !          1409:         if (fSuccess) {
        !          1410:             *pflStyleNew = ccs.flStyle;
        !          1411:             *pflExtStyleNew = ccs.flExtStyle;
        !          1412:             lstrcpy(pszTextNew, ccs.szText);
        !          1413:         }
        !          1414:     }
        !          1415:     else {
        !          1416:         ccsA.flStyle = *pflStyleNew;
        !          1417:         ccsA.flExtStyle = *pflExtStyleNew;
        !          1418:         WideCharToMultiByte(CP_ACP, 0, pszTextNew, -1, ccsA.szText, CCHCCTEXT,
        !          1419:                 NULL, &fDefCharUsed);
        !          1420:         ccsA.lgid = gcd.di.wLanguage;
        !          1421:         ccsA.wReserved1 = 0;
        !          1422: 
        !          1423:         fSuccess = ((LPFNCCSTYLEA)(*npc->pwcd->lpfnStyle))(ghwndMain, &ccsA);
        !          1424: 
        !          1425:         if (fSuccess) {
        !          1426:             *pflStyleNew = ccsA.flStyle;
        !          1427:             *pflExtStyleNew = ccsA.flExtStyle;
        !          1428:             MultiByteToWideChar(CP_ACP, 0, ccsA.szText, -1, pszTextNew,
        !          1429:                     CCHTEXTMAX);
        !          1430:         }
        !          1431:     }
        !          1432: 
        !          1433:     EnteringDialog(idPrevDlg, NULL, FALSE);
        !          1434: 
        !          1435:     return fSuccess;
        !          1436: }
        !          1437: 
        !          1438: 
        !          1439: 
        !          1440: /************************************************************************
        !          1441: * CallCustomSizeToText
        !          1442: *
        !          1443: *
        !          1444: *
        !          1445: * Returns:
        !          1446: *
        !          1447: * History:
        !          1448: *
        !          1449: ************************************************************************/
        !          1450: 
        !          1451: INT CallCustomSizeToText(
        !          1452:     NPCTYPE npc)
        !          1453: {
        !          1454:     INT x;
        !          1455:     INT xDU;
        !          1456:     BOOL fDefCharUsed;
        !          1457:     CHAR szTextA[CCHTEXTMAX];
        !          1458:     PSTR pszTextA;
        !          1459: 
        !          1460:     /*
        !          1461:      * Does this custom control have a SizeToText function?
        !          1462:      */
        !          1463:     if (!npc->pwcd->lpfnSizeToText)
        !          1464:         return -1;
        !          1465: 
        !          1466:     /*
        !          1467:      * Is this a UNICODE DLL that we are calling to?
        !          1468:      */
        !          1469:     if (npc->pwcd->fUnicodeDLL) {
        !          1470:         x = ((LPFNCCSIZETOTEXT)(*npc->pwcd->lpfnSizeToText))
        !          1471:                 (npc->flStyle, npc->flExtStyle, gcd.hFont, npc->text);
        !          1472:     }
        !          1473:     else {
        !          1474:         /*
        !          1475:          * No, not a UNICODE DLL.  We must convert from UNICODE to
        !          1476:          * ANSI first.  NULL text cases must be handled properly.
        !          1477:          */
        !          1478:         if (npc->text) {
        !          1479:             WideCharToMultiByte(CP_ACP, 0, npc->text, -1, szTextA, CCHTEXTMAX,
        !          1480:                     NULL, &fDefCharUsed);
        !          1481:             pszTextA = szTextA;
        !          1482:         }
        !          1483:         else {
        !          1484:             pszTextA = NULL;
        !          1485:         }
        !          1486: 
        !          1487:         x = ((LPFNCCSIZETOTEXTA)(*npc->pwcd->lpfnSizeToText))
        !          1488:                 (npc->flStyle, npc->flExtStyle, gcd.hFont, pszTextA);
        !          1489:     }
        !          1490: 
        !          1491:     /*
        !          1492:      * Did the call to the DLL fail?
        !          1493:      */
        !          1494:     if (x == -1)
        !          1495:         return -1;
        !          1496: 
        !          1497:     /*
        !          1498:      * Convert the size in pixels to a size in Dialog Units.  Be sure
        !          1499:      * that we round any fraction up to the next higher DU.  Since
        !          1500:      * we know how wide the control must be to fit the text, we must
        !          1501:      * be sure that the size does not get rounded down below this
        !          1502:      * value when converting to DU's.
        !          1503:      */
        !          1504:     xDU = MulDiv(x, 4, gcd.cxChar);
        !          1505:     if (MulDiv(xDU, gcd.cxChar, 4) != x)
        !          1506:         xDU++;
        !          1507: 
        !          1508:     return xDU;
        !          1509: }
        !          1510: 
        !          1511: 
        !          1512: 
        !          1513: /************************************************************************
        !          1514: * ReadCustomProfile
        !          1515: *
        !          1516: *
        !          1517: * History:
        !          1518: *
        !          1519: ************************************************************************/
        !          1520: 
        !          1521: VOID ReadCustomProfile(VOID)
        !          1522: {
        !          1523:     TCHAR szBuf[CCHTEXTMAX];
        !          1524:     TCHAR szBuf2[CCHTEXTMAX];
        !          1525:     LPTSTR pszKey;
        !          1526: 
        !          1527:     GetPrivateProfileString(szCustomDLL, NULL, szEmpty,
        !          1528:             szBuf, CCHTEXTMAX, ids(IDS_DLGEDITINI));
        !          1529: 
        !          1530:     /*
        !          1531:      * Get the file name for each custom control DLL and load it.
        !          1532:      */
        !          1533:     for (pszKey = szBuf; *pszKey; pszKey += lstrlen(pszKey) + 1) {
        !          1534:         if (GetPrivateProfileString(szCustomDLL, pszKey, szEmpty,
        !          1535:                 szBuf2, CCHTEXTMAX, ids(IDS_DLGEDITINI)))
        !          1536:             OpenDLLFile(szBuf2);
        !          1537:     }
        !          1538: }
        !          1539: 
        !          1540: 
        !          1541: 
        !          1542: /************************************************************************
        !          1543: * WriteCustomProfile
        !          1544: *
        !          1545: *
        !          1546: * History:
        !          1547: *
        !          1548: ************************************************************************/
        !          1549: 
        !          1550: VOID WriteCustomProfile(VOID)
        !          1551: {
        !          1552:     PCUSTLINK pcl;
        !          1553:     PCUSTLINK pcl2;
        !          1554:     BOOL fSecond;
        !          1555: 
        !          1556:     /*
        !          1557:      * Clear out the section.
        !          1558:      */
        !          1559:     WritePrivateProfileString(szCustomDLL, NULL, NULL, ids(IDS_DLGEDITINI));
        !          1560: 
        !          1561:     for (pcl = gpclHead; pcl; pcl = pcl->pclNext) {
        !          1562:         /*
        !          1563:          * Only write out installed DLL's, not emulated controls.
        !          1564:          */
        !          1565:         if (pcl->pszFileName) {
        !          1566:             /*
        !          1567:              * Before writing out the path to the DLL, be sure
        !          1568:              * that this DLL's path has not been written out
        !          1569:              * already.  This would only occur if they have
        !          1570:              * multiple control types within the DLL.
        !          1571:              */
        !          1572:             for (pcl2 = gpclHead, fSecond = FALSE;
        !          1573:                     pcl2 && pcl2 != pcl; pcl2 = pcl2->pclNext) {
        !          1574:                 if (lstrcmpi(pcl2->pszFileName, pcl->pszFileName) == 0) {
        !          1575:                     fSecond = TRUE;
        !          1576:                     break;
        !          1577:                 }
        !          1578:             }
        !          1579: 
        !          1580:             if (!fSecond)
        !          1581:                 WritePrivateProfileString(szCustomDLL, pcl->pwcd->pszClass,
        !          1582:                         pcl->pszFileName, ids(IDS_DLGEDITINI));
        !          1583:         }
        !          1584:     }
        !          1585: }

unix.superglobalmegacorp.com

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