|
|
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.