|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.