Annotation of mstools/samples/sdktools/dlgedit/custcntl.c, revision 1.1.1.1

1.1       root        1: 
                      2: /******************************************************************************\
                      3: *       This is a part of the Microsoft Source Code Samples. 
                      4: *       Copyright (C) 1993 Microsoft Corporation.
                      5: *       All rights reserved. 
                      6: *       This source code is only intended as a supplement to 
                      7: *       Microsoft Development Tools and/or WinHelp documentation.
                      8: *       See these sources for detailed information regarding the 
                      9: *       Microsoft samples programs.
                     10: \******************************************************************************/
                     11: 
                     12: /****************************** Module Header *******************************
                     13: * Module Name: 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.