home *** CD-ROM | disk | FTP | other *** search
-
- /******************************************************************************\
- * This is a part of the Microsoft Source Code Samples.
- * Copyright (C) 1993-1997 Microsoft Corporation.
- * All rights reserved.
- * This source code is only intended as a supplement to
- * Microsoft Development Tools and/or WinHelp documentation.
- * See these sources for detailed information regarding the
- * Microsoft samples programs.
- \******************************************************************************/
-
- /****************************** Module Header *******************************
- * Module Name: custcntl.c
- *
- * Contains functions to support custom controls.
- *
- * Functions:
- * NewCustDlgProc()
- * OpenCustomDialog()
- * SelCustDialog()
- * SelCustDlgProc()
- * RemCustDlgProc()
- * CustomWndProc()
- * AddCustomLink()
- * RemoveCustomLink()
- * CallCustomStyle()
- * CallCustomSizeToText()
- * ReadCustomProfile()
- * WriteCustomProfile()
- * NewCustInit()
- * NewCustOK()
- * OpenDLLFile()
- * CallCustomInfoA()
- * SelCustInit()
- * SelCustSelect()
- * SelCustOK()
- * RemCustInit()
- * RemCustOK()
- * AllocCUSTLINK()
- * FreeCUSTLINK()
- *
- * Comments:
- *
- ****************************************************************************/
-
- #include "dlgedit.h"
- #include "dlgfuncs.h"
- #include "dlgextrn.h"
- #include "dialogs.h"
- #include "dlghelp.h"
-
- #include <stdlib.h>
- #include <string.h>
-
- #include <commdlg.h>
-
-
- /*
- * Minimum margin around the sample control.
- */
- #define SAMPLEMARGIN 4
-
-
- STATICFN VOID NewCustInit(HWND hwnd);
- STATICFN BOOL NewCustOK(HWND hwnd);
- STATICFN VOID OpenDLLFile(LPTSTR pszFileName);
- STATICFN UINT CallCustomInfoA(LPFNCCINFOA lpfnInfoA, LPCCINFO acciW,
- INT nControls);
- STATICFN VOID SelCustInit(HWND hwnd);
- STATICFN VOID SelCustSelect(HWND hwnd);
- STATICFN BOOL SelCustOK(HWND hwnd);
- STATICFN VOID RemCustInit(HWND hwnd);
- STATICFN BOOL RemCustOK(HWND hwnd);
- STATICFN PCUSTLINK AllocCUSTLINK(LPCCINFO pcci, BOOL fEmulated,
- BOOL fUnicodeDLL, LPTSTR pszFileName, HANDLE hmod);
- STATICFN VOID FreeCUSTLINK(PCUSTLINK pclFree);
-
-
- /*
- * Used to return the pwcd that is chosen from the Select Custom
- * Control dialog.
- */
- static PWINDOWCLASSDESC pwcdChosen;
-
- /*
- * Has the window handle of the sample custom control in the
- * Select Custom Control dialog.
- */
- static HWND hwndCustomSample;
-
-
-
-
- /************************************************************************
- * NewCustDlgProc
- *
- * This is the Add Custom Control dialog procedure.
- *
- * :
- *
- ************************************************************************/
-
- DIALOGPROC NewCustDlgProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- switch (msg) {
- case WM_INITDIALOG:
- NewCustInit(hwnd);
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDOK:
- if (NewCustOK(hwnd))
- EndDialog(hwnd, IDOK);
-
- break;
-
- case IDCANCEL:
- EndDialog(hwnd, IDCANCEL);
- break;
-
- case IDHELPDLG:
- WinHelp(ghwndMain, gszHelpFile, HELP_CONTEXT,
- HELPID_NEWCUST);
- break;
- }
-
- return TRUE;
-
- default:
- return FALSE;
- }
- }
-
-
-
- /************************************************************************
- * NewCustInit
- *
- * Processes the WM_INITDIALOG message for the New Temporary Custom Control
- * dialog procedure.
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN VOID NewCustInit(
- HWND hwnd)
- {
- TCHAR szStyles[32];
-
- SendDlgItemMessage(hwnd, DID_NEWCUSTCLASS, EM_LIMITTEXT, CCHCCCLASS - 1, 0L);
-
- SendDlgItemMessage(hwnd, DID_NEWCUSTSTYLES, EM_LIMITTEXT, CCHHEXLONGMAX, 0L);
- wsprintf(szStyles, L"%#.8lx", awcd[W_CUSTOM].flStyles);
- SetDlgItemText(hwnd, DID_NEWCUSTSTYLES, szStyles);
-
- SendDlgItemMessage(hwnd, DID_NEWCUSTCX, EM_LIMITTEXT, 3, 0L);
- SetDlgItemInt(hwnd, DID_NEWCUSTCX, awcd[W_CUSTOM].cxDefault, FALSE);
-
- SendDlgItemMessage(hwnd, DID_NEWCUSTCY, EM_LIMITTEXT, 3, 0L);
- SetDlgItemInt(hwnd, DID_NEWCUSTCY, awcd[W_CUSTOM].cyDefault, FALSE);
-
- SendDlgItemMessage(hwnd, DID_NEWCUSTTEXT, EM_LIMITTEXT, CCHCCTEXT - 1, 0L);
-
- CenterWindow(hwnd);
- }
-
-
-
- /************************************************************************
- * NewCustOK
- *
- * Processes the OK button from the New Temporary Custom Control dialog.
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN BOOL NewCustOK(
- HWND hwnd)
- {
- TCHAR szStyles[CCHHEXLONGMAX + 1];
- CCINFO cci;
-
- /*
- * Read the class field. It is required.
- */
- if (!GetDlgItemText(hwnd, DID_NEWCUSTCLASS, cci.szClass, CCHCCCLASS)) {
- Message(MSG_NOCLASS);
- SetFocus(GetDlgItem(hwnd, DID_NEWCUSTCLASS));
- return FALSE;
- }
-
- GetDlgItemText(hwnd, DID_NEWCUSTSTYLES, szStyles, CCHHEXLONGMAX + 1);
- cci.flStyleDefault = valtoi(szStyles);
-
- if (!(cci.cxDefault = GetDlgItemInt(hwnd, DID_NEWCUSTCX, NULL, FALSE))) {
- Message(MSG_GTZERO, ids(IDS_WIDTH));
- SetFocus(GetDlgItem(hwnd, DID_NEWCUSTCX));
- return FALSE;
- }
-
- if (!(cci.cyDefault = GetDlgItemInt(hwnd, DID_NEWCUSTCY, NULL, FALSE))) {
- Message(MSG_GTZERO, ids(IDS_HEIGHT));
- SetFocus(GetDlgItem(hwnd, DID_NEWCUSTCY));
- return FALSE;
- }
-
- GetDlgItemText(hwnd, DID_NEWCUSTTEXT, cci.szTextDefault, CCHCCTEXT);
-
- cci.flOptions = 0;
- *cci.szDesc = TEXT('\0');
- cci.flExtStyleDefault = 0;
- cci.flCtrlTypeMask = 0;
- cci.cStyleFlags = 0;
- cci.aStyleFlags = NULL;
- cci.lpfnStyle = NULL;
- cci.lpfnSizeToText = NULL;
- cci.dwReserved1 = 0;
- cci.dwReserved2 = 0;
-
- if (AddCustomLink(&cci, TRUE, FALSE, NULL, NULL))
- return TRUE;
- else
- return FALSE;
- }
-
-
-
- /************************************************************************
- * OpenCustomDialog
- *
- * Displays the file open dialog and allows a custom DLL to be selected
- * and loaded.
- *
- * History:
- *
- ************************************************************************/
-
- VOID OpenCustomDialog(VOID)
- {
- BOOL fGotName;
- OPENFILENAME ofn;
- TCHAR szNewFileName[CCHMAXPATH];
- TCHAR szFilter[CCHTEXTMAX];
- INT idPrevDlg;
-
- /*
- * Begin setting up the globals and the open file dialog structure.
- */
- *szNewFileName = CHAR_NULL;
-
- /*
- * Build up the filter string.
- */
- BuildFilterString(FILE_DLL, szFilter);
-
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = ghwndMain;
- ofn.hInstance = NULL;
- ofn.lpstrFilter = szFilter;
- ofn.lpstrCustomFilter = NULL;
- ofn.nMaxCustFilter = 0;
- ofn.nFilterIndex = 1;
- ofn.lpstrFile = szNewFileName;
- ofn.nMaxFile = CCHMAXPATH;
- ofn.lpstrFileTitle = NULL;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrTitle = ids(IDS_DLLOPENTITLE);
- ofn.Flags = OFN_HIDEREADONLY | OFN_SHOWHELP | OFN_FILEMUSTEXIST;
- ofn.lpstrDefExt = ids(IDS_DLLEXT);
- ofn.lpstrInitialDir = NULL;
- ofn.lCustData = 0;
- ofn.lpfnHook = NULL;
- ofn.lpTemplateName = NULL;
-
- /*
- * Fire off the dialog box to open the file.
- */
- EnteringDialog(DID_COMMONFILEOPENDLL, &idPrevDlg, TRUE);
- fGotName = GetOpenFileName(&ofn);
- EnteringDialog(idPrevDlg, NULL, FALSE);
-
- if (fGotName)
- OpenDLLFile(szNewFileName);
- }
-
-
-
- /************************************************************************
- * OpenDLLFile
- *
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN VOID OpenDLLFile(
- LPTSTR pszFileName)
- {
- HANDLE hmod;
- LPFNCCINFOA lpfnInfoA;
- LPFNCCINFOW lpfnInfoW;
- INT i;
- BOOL fSuccess = FALSE;
- BOOL fUnicodeDLL;
- PCUSTLINK pclT;
- INT nControls;
- INT nControls2;
- LPCCINFO acci;
-
- /*
- * Check to see if the DLL has already been loaded.
- */
- for (pclT = gpclHead; pclT &&
- (pclT->pwcd->fEmulated ||
- lstrcmpi(pclT->pszFileName, pszFileName) != 0);
- pclT = pclT->pclNext)
- ;
-
- /*
- * Is the DLL already loaded?
- */
- if (pclT) {
- Message(MSG_CUSTALREADYLOADED, pszFileName);
- return;
- }
-
- if (!(hmod = LoadLibrary(pszFileName))) {
- Message(MSG_CANTLOADDLL, pszFileName);
- return;
- }
-
- lpfnInfoA = (LPFNCCINFOA)GetProcAddress(hmod, "CustomControlInfoA");
- lpfnInfoW = (LPFNCCINFOW)GetProcAddress(hmod, "CustomControlInfoW");
-
- if (!lpfnInfoA && !lpfnInfoW) {
- Message(MSG_BADCUSTDLL, pszFileName);
- goto Error1;
- }
-
- if (lpfnInfoW) {
- nControls = (*lpfnInfoW)(NULL);
- fUnicodeDLL = TRUE;
- }
- else {
- nControls = (*lpfnInfoA)(NULL);
- fUnicodeDLL = FALSE;
- }
-
- if (!nControls) {
- Message(MSG_CANTINITDLL, pszFileName);
- goto Error1;
- }
-
- if (!(acci = (LPCCINFO)MyAlloc(nControls * sizeof(CCINFO))))
- goto Error1;
-
- if (fUnicodeDLL)
- nControls2 = (*lpfnInfoW)(acci);
- else
- nControls2 = CallCustomInfoA(lpfnInfoA, acci, nControls);
-
- if (!nControls2) {
- Message(MSG_CANTINITDLL, pszFileName);
- goto Error2;
- }
-
- for (i = 0; i < nControls; i++) {
- if (!AddCustomLink(&acci[i], FALSE, fUnicodeDLL, pszFileName, hmod))
- goto Error2;
- }
-
- fSuccess = TRUE;
-
- Error2:
- MyFree(acci);
-
- Error1:
- if (!fSuccess)
- FreeLibrary(hmod);
- }
-
-
-
- /************************************************************************
- * CallCustomInfoA
- *
- * Thunks the call from the unicode DlgEdit to the ANSI custom control
- * info procedure.
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN UINT CallCustomInfoA(
- LPFNCCINFOA lpfnInfoA,
- LPCCINFO acciW,
- INT nControls)
- {
- LPCCINFOA acciA;
- INT nControls2;
- INT i;
- INT j;
- LPCCSTYLEFLAGA lpFlagsA;
- LPCCSTYLEFLAGW aFlagsW = NULL;
- INT cch;
-
- /*
- * Allocate the appropriate number of ANSI info structures.
- */
- if (!(acciA = (LPCCINFOA)MyAlloc(nControls * sizeof(CCINFOA))))
- return 0;
-
- /*
- * Call the ANSI info function.
- */
- if (nControls2 = (*lpfnInfoA)(acciA)) {
- /*
- * Copy all the ANSI structures to the UNICODE structures,
- * converting strings to UNICODE as we go.
- */
- for (i = 0; i < nControls; i++) {
- MultiByteToWideChar(CP_ACP, 0, acciA[i].szClass, -1,
- acciW[i].szClass, CCHCCCLASS);
- acciW[i].flOptions = acciA[i].flOptions;
- MultiByteToWideChar(CP_ACP, 0, acciA[i].szDesc, -1,
- acciW[i].szDesc, CCHCCDESC);
- acciW[i].cxDefault = acciA[i].cxDefault;
- acciW[i].cyDefault = acciA[i].cyDefault;
- acciW[i].flStyleDefault = acciA[i].flStyleDefault;
- acciW[i].flExtStyleDefault = acciA[i].flExtStyleDefault;
- acciW[i].flCtrlTypeMask = acciA[i].flCtrlTypeMask;
- MultiByteToWideChar(CP_ACP, 0, acciA[i].szTextDefault, -1,
- acciW[i].szTextDefault, CCHCCTEXT);
-
- /*
- * Is there a table of style flags? If so, we need to build
- * up a table of unicode style flags. Note that since we
- * allocate this table, the table must be freed when the
- * custom link is destroyed!
- */
- if (acciA[i].cStyleFlags) {
- /*
- * If they specified that there are style flags, the pointer
- * to the table must not be NULL.
- */
- if (!acciA[i].aStyleFlags)
- return 0;
-
- if (!(aFlagsW = (LPCCSTYLEFLAGW)MyAlloc(
- acciA[i].cStyleFlags * sizeof(CCSTYLEFLAGW))))
- return 0;
-
- /*
- * Copy all the flags to the new unicode style flag table.
- */
- for (j = 0, lpFlagsA = acciA[i].aStyleFlags;
- j < acciA[i].cStyleFlags; j++, lpFlagsA++) {
- aFlagsW[j].flStyle = lpFlagsA->flStyle;
- aFlagsW[j].flStyleMask = lpFlagsA->flStyleMask;
-
- cch = lstrlenA(lpFlagsA->pszStyle) + 1;
- aFlagsW[j].pszStyle = (LPWSTR)MyAlloc(cch * sizeof(WCHAR));
-
- if (!aFlagsW[j].pszStyle)
- return 0;
-
- MultiByteToWideChar(CP_ACP, 0, lpFlagsA->pszStyle, -1,
- aFlagsW[j].pszStyle, cch);
- }
- }
-
- acciW[i].cStyleFlags = acciA[i].cStyleFlags;
- acciW[i].aStyleFlags = aFlagsW;
-
- acciW[i].lpfnStyle = (LPFNCCSTYLE)acciA[i].lpfnStyle;
- acciW[i].lpfnSizeToText = (LPFNCCSIZETOTEXT)acciA[i].lpfnSizeToText;
- acciW[i].dwReserved1 = acciA[i].dwReserved1;
- acciW[i].dwReserved2 = acciA[i].dwReserved2;
- }
- }
-
- MyFree(acciA);
-
- return nControls2;
- }
-
-
-
- /************************************************************************
- * SelCustDialog
- *
- * Displays the Select Custom Control dialog to choose which custom
- * control tool should be selected.
- *
- * History:
- *
- ************************************************************************/
-
- PWINDOWCLASSDESC SelCustDialog(VOID)
- {
- if (DlgBox(DID_SELCUST, (WNDPROC)SelCustDlgProc) == IDOK)
- return pwcdChosen;
- else
- return NULL;
- }
-
-
-
- /************************************************************************
- * SelCustDlgProc
- *
- * This is the Select Custom Control dialog procedure.
- *
- * History:
- *
- ************************************************************************/
-
- DIALOGPROC SelCustDlgProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- switch (msg) {
- case WM_INITDIALOG:
- SelCustInit(hwnd);
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case DID_SELCUSTLIST:
- switch (HIWORD(wParam)) {
- case LBN_DBLCLK:
- if (SelCustOK(hwnd))
- EndDialog(hwnd, IDOK);
-
- break;
-
- case LBN_SELCHANGE:
- SelCustSelect(hwnd);
- break;
- }
-
- break;
-
- case IDOK:
- if (SelCustOK(hwnd))
- EndDialog(hwnd, IDOK);
-
- break;
-
- case IDCANCEL:
- EndDialog(hwnd, IDCANCEL);
- break;
-
- case IDHELPDLG:
- WinHelp(ghwndMain, gszHelpFile, HELP_CONTEXT,
- HELPID_SELCUST);
- break;
- }
-
- return TRUE;
-
- default:
- return FALSE;
- }
- }
-
-
-
- /************************************************************************
- * SelCustInit
- *
- * Processes the WM_INITDIALOG message for the Select Custom Control
- * dialog procedure.
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN VOID SelCustInit(
- HWND hwnd)
- {
- HWND hwndLB;
- INT i;
- PCUSTLINK pcl;
- LPTSTR pszDesc;
-
- hwndLB = GetDlgItem(hwnd, DID_SELCUSTLIST);
-
- /*
- * Insert each custom control into the listbox.
- */
- for (pcl = gpclHead; pcl; pcl = pcl->pclNext) {
- /*
- * Use the short description, if the control has one,
- * otherwise use the class name itself.
- */
- if (pcl->pszDesc)
- pszDesc = pcl->pszDesc;
- else
- pszDesc = pcl->pwcd->pszClass;
-
- i = (INT)SendMessage(hwndLB, LB_ADDSTRING, 0, (DWORD)pszDesc);
- SendMessage(hwndLB, LB_SETITEMDATA, i, (DWORD)pcl);
- }
-
- hwndCustomSample = NULL;
-
- /*
- * Select the first item.
- */
- SendMessage(hwndLB, LB_SETCURSEL, 0, 0L);
- SelCustSelect(hwnd);
-
- CenterWindow(hwnd);
- }
-
-
-
- /************************************************************************
- * SelCustSelect
- *
- * Called every time that a different control is selected in the list box
- * in the Select Custom Control dialog. It will create a sample control
- * and show it in the Sample box.
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN VOID SelCustSelect(
- HWND hwnd)
- {
- HWND hwndLB;
- INT iSelect;
- PCUSTLINK pcl;
- PWINDOWCLASSDESC pwcd;
- LPTSTR pszClass;
- RECT rc;
- RECT rcParent;
- HWND hwndParent;
- INT x;
- INT y;
- INT cx;
- INT cy;
- INT cxParent;
- INT cyParent;
-
- hwndLB = GetDlgItem(hwnd, DID_SELCUSTLIST);
-
- if ((iSelect = (INT)SendMessage(hwndLB, LB_GETCURSEL, 0, 0)) == LB_ERR)
- return;
-
- /*
- * Get a pointer to the custom control link (stored in the listbox
- * items data field).
- */
- pcl = (PCUSTLINK)SendMessage(hwndLB, LB_GETITEMDATA, iSelect, 0L);
- pwcd = pcl->pwcd;
-
- /*
- * Get the coordinates of the Sample box.
- */
- hwndParent = GetDlgItem(hwnd, DID_SELCUSTSAMPLE);
- GetWindowRect(hwndParent, &rcParent);
- ScreenToClientRect(hwnd, &rcParent);
- cxParent = (rcParent.right - rcParent.left) - (2 * SAMPLEMARGIN);
- cyParent = (rcParent.bottom - rcParent.top) - (2 * SAMPLEMARGIN);
-
- /*
- * Calculate the window size of the sample control.
- */
- SetRect(&rc, 0, 0, pwcd->cxDefault, pwcd->cyDefault);
- DUToWinRect(&rc);
- cx = rc.right - rc.left;
- cy = rc.bottom - rc.top;
-
- /*
- * Be sure that the control can fit within the sample box. Adjust
- * it down if necessary.
- */
- if (cx < cxParent) {
- x = ((cxParent - cx) / 2) + SAMPLEMARGIN;
- }
- else {
- x = SAMPLEMARGIN;
- cx = cxParent;
- }
-
- if (cy < cyParent) {
- y = ((cyParent - cy) / 2) + SAMPLEMARGIN;
- }
- else {
- y = SAMPLEMARGIN;
- cy = cyParent;
- }
-
- x += rcParent.left;
- y += rcParent.top;
-
- /*
- * Destroy the old sample.
- */
- if (hwndCustomSample)
- DestroyWindow(hwndCustomSample);
-
- /*
- * Get the class name to use.
- * If the control is emulated, use the special emulator class.
- * Otherwise, it is an installed custom control, and we can use
- * it's real class string.
- */
- if (pwcd->fEmulated)
- pszClass = szCustomClass;
- else
- pszClass = pwcd->pszClass;
-
- /*
- * Create the sample control. We always create it visible here,
- * even if the style says it isn't.
- */
- hwndCustomSample = CreateWindow(
- pszClass,
- pwcd->pszTextDefault,
- pwcd->flStyles | WS_VISIBLE,
- x, y, cx, cy,
- hwnd,
- 0,
- ghInst,
- NULL);
- }
-
-
-
- /************************************************************************
- * SelCustOK
- *
- * Processes the final selection of a custom control from the
- * Select Custom Control dialog.
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN BOOL SelCustOK(
- HWND hwnd)
- {
- HWND hwndLB;
- INT iSelect;
- PCUSTLINK pcl;
-
- hwndLB = GetDlgItem(hwnd, DID_SELCUSTLIST);
-
- if ((iSelect = (INT)SendMessage(hwndLB, LB_GETCURSEL, 0, 0)) == LB_ERR)
- return FALSE;
-
- /*
- * Get a pointer to the custom control link (stored in the listbox
- * items data field).
- */
- pcl = (PCUSTLINK)SendMessage(hwndLB, LB_GETITEMDATA, iSelect, 0L);
-
- pwcdChosen = pcl->pwcd;
-
- return TRUE;
- }
-
-
-
- /************************************************************************
- * RemCustDlgProc
- *
- * This is the Remove Custom Control dialog procedure.
- * It is used to de-install a custom control.
- *
- * History:
- *
- ************************************************************************/
-
- DIALOGPROC RemCustDlgProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- switch (msg) {
- case WM_INITDIALOG:
- RemCustInit(hwnd);
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case DID_REMCUSTLIST:
- if (HIWORD(wParam) == LBN_DBLCLK) {
- if (RemCustOK(hwnd))
- EndDialog(hwnd, IDOK);
- }
-
- break;
-
- case IDOK:
- if (RemCustOK(hwnd))
- EndDialog(hwnd, IDOK);
-
- break;
-
- case IDCANCEL:
- EndDialog(hwnd, IDCANCEL);
- break;
-
- case IDHELPDLG:
- WinHelp(ghwndMain, gszHelpFile, HELP_CONTEXT,
- HELPID_REMCUST);
- break;
- }
-
- return TRUE;
-
- default:
- return FALSE;
- }
- }
-
-
-
- /************************************************************************
- * RemCustInit
- *
- * Processes the WM_INITDIALOG message for the Remove Custom Control
- * dialog procedure.
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN VOID RemCustInit(
- HWND hwnd)
- {
- HWND hwndLB;
- INT i;
- PCUSTLINK pcl;
- LPTSTR pszDesc;
-
- hwndLB = GetDlgItem(hwnd, DID_REMCUSTLIST);
-
- /*
- * Insert each custom control into the listbox.
- */
- for (pcl = gpclHead; pcl; pcl = pcl->pclNext) {
- /*
- * Use the short description, if the control has one,
- * otherwise use the class name itself.
- */
- if (pcl->pszDesc)
- pszDesc = pcl->pszDesc;
- else
- pszDesc = pcl->pwcd->pszClass;
-
- i = (INT)SendMessage(hwndLB, LB_ADDSTRING, 0, (DWORD)pszDesc);
- SendMessage(hwndLB, LB_SETITEMDATA, i, (DWORD)pcl);
- }
-
- /*
- * Select the first item.
- */
- SendMessage(hwndLB, LB_SETCURSEL, 0, 0L);
-
- CenterWindow(hwnd);
- }
-
-
-
- /************************************************************************
- * RemCustOK
- *
- * Processes the selection of a custom control to delete from the
- * Remove Custom Control dialog.
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN BOOL RemCustOK(
- HWND hwnd)
- {
- HWND hwndLB;
- INT iSelect;
- PCUSTLINK pcl;
- NPCTYPE npc;
-
- hwndLB = GetDlgItem(hwnd, DID_REMCUSTLIST);
-
- if ((iSelect = (INT)SendMessage(hwndLB, LB_GETCURSEL, 0, 0)) != LB_ERR) {
- /*
- * Get a pointer to the custom control link (stored in the listbox
- * items data field).
- */
- pcl = (PCUSTLINK)SendMessage(hwndLB, LB_GETITEMDATA, iSelect, 0L);
-
- /*
- * Cannot delete if any controls in the current dialog
- * are of this type.
- */
- for (npc = npcHead; npc; npc = npc->npcNext) {
- if (pcl->pwcd == npc->pwcd) {
- Message(MSG_CUSTCNTLINUSE);
- return FALSE;
- }
- }
-
- RemoveCustomLink(pcl);
- }
-
- return TRUE;
- }
-
-
-
- /****************************************************************************
- * CustomWndProc
- *
- * This is the window procedure for the emulated Custom control.
- *
- * History:
- *
- ****************************************************************************/
-
- WINDOWPROC CustomWndProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- switch (msg) {
- case WM_PAINT:
- {
- HDC hDC;
- PAINTSTRUCT ps;
- RECT rc;
- TCHAR szText[CCHTEXTMAX];
-
- hDC = BeginPaint(hwnd, &ps);
-
- SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
- GetClientRect(hwnd, &rc);
- Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
- GetWindowText(hwnd, szText, CCHTEXTMAX);
- #ifdef JAPAN
- {
- TCHAR szTmp[CCHTEXTMAX];
-
- KDExpandCopy(szTmp, szText, CCHTEXTMAX);
- lstrcpy(szText, szTmp);
- }
- #endif
- SetBkMode(hDC, TRANSPARENT);
-
- if (gcd.hFont)
- SelectObject(hDC, gcd.hFont);
-
- DrawText(hDC, szText, -1, &rc,
- DT_CENTER | DT_NOCLIP | DT_VCENTER | DT_SINGLELINE);
-
- EndPaint(hwnd, &ps);
- }
-
- break;
-
- default:
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
-
- return 0;
- }
-
-
-
- /************************************************************************
- * AddCustomLink
- *
- * Adds a new custom control to the linked list.
- *
- * Note that normally duplicates are checked for, but it allows multiple
- * links to be added with the same class if it is a DLL control. This
- * is to support multiple control types being added from the same DLL.
- * Because of this, if the caller is adding a non-emulated link, they
- * are responsible for checking the list for duplicates first!
- *
- * There is one special case. If it is adding a DLL link, and an
- * emulated link with the same class name is found, it will walk the
- * current list of controls and replace all of them with the new DLL
- * control type, then delete the emulated link. This is to support
- * the case where the user creates some controls of class FOO, where
- * FOO is emulated, then later loads the FOO DLL. All controls of
- * this emulated class will be changed to be the real FOO class, and
- * the DLL FOO link replaces the emulated one.
- *
- * History:
- *
- ************************************************************************/
-
- PCUSTLINK AddCustomLink(
- LPCCINFO pcci,
- BOOL fEmulated,
- BOOL fUnicodeDLL,
- LPTSTR pszFileName,
- HANDLE hmod)
- {
- PCUSTLINK pcl;
- PCUSTLINK pclT;
- PCUSTLINK pclPrev;
- NPCTYPE npc;
- HWND hwndOld;
-
- if (!(pcl = AllocCUSTLINK(pcci, fEmulated, fUnicodeDLL, pszFileName, hmod)))
- return NULL;
-
- if (fEmulated) {
- /*
- * Search the list for another link with the same class.
- */
- for (pclT = gpclHead;
- pclT && lstrcmpi(pclT->pwcd->pszClass, pcci->szClass) != 0;
- pclT = pclT->pclNext)
- ;
-
- /*
- * Was a duplicate found?
- */
- if (pclT) {
- FreeCUSTLINK(pcl);
- Message(MSG_CUSTALREADYLOADED, pcci->szClass);
-
- return NULL;
- }
- }
- else {
- /*
- * Search the list for another link with the same class that
- * is an emulated control.
- */
- for (pclT = gpclHead;
- pclT &&
- (lstrcmpi(pclT->pwcd->pszClass, pcci->szClass) != 0 ||
- !pclT->pwcd->fEmulated);
- pclT = pclT->pclNext)
- ;
-
- /*
- * Was a duplicate found?
- */
- if (pclT) {
- /*
- * At this point we know that this is a DLL link replacing
- * an existing emulated control class. We want to go through
- * the existing controls and replace any of this class with
- * the new DLL class. This allows a user to load a dialog
- * with some emulated controls, then later install the custom
- * DLL and have all the existing controls of that class
- * change to show the real control.
- */
- for (npc = npcHead; npc; npc = npc->npcNext) {
- /*
- * Is the control of the type that we are replacing?
- */
- if (npc->pwcd == pclT->pwcd) {
- hwndOld = npc->hwnd;
-
- /*
- * Unsubclass the old control window, then switch
- * the pwcd pointer before calling CreateControl.
- */
- SetWindowLong(hwndOld, GWL_WNDPROC,
- (DWORD)npc->pwcd->pfnOldWndProc);
- UNSETPCINTOHWND(hwndOld);
- npc->pwcd = pcl->pwcd;
-
- /*
- * Create a control of the new type in the same position.
- */
- if (CreateControl(npc, npc->text, npc->flStyle,
- npc->flExtStyle, npc->id, &npc->rc,
- hwndOld, NULL)) {
- /*
- * Get rid of the old control window.
- */
- DestroyWindow(hwndOld);
-
- /*
- * Adjust the size and position of its drag window.
- */
- SizeDragToControl(npc);
- }
- }
- }
-
- /*
- * Remove the old link, now that all the controls that
- * used it are gone.
- */
- RemoveCustomLink(pclT);
- }
- }
-
- /*
- * Search for the end of the list. Get a pointer to the last link.
- */
- for (pclT = gpclHead, pclPrev = NULL; pclT;
- pclPrev = pclT, pclT = pclT->pclNext)
- ;
-
- /*
- * Add the new link to the list. Add it to the end if there are
- * other links, or initialize the head pointer if this is the
- * first one.
- */
- if (pclPrev)
- pclPrev->pclNext = pcl;
- else
- gpclHead = pcl;
-
- return pcl;
- }
-
-
-
- /************************************************************************
- * AllocCUSTLINK
- *
- * Allocates a CUSTLINK structure and initializes it. This includes
- * allocating an associated WINDOWCLASSDESC structure.
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN PCUSTLINK AllocCUSTLINK(
- LPCCINFO pcci,
- BOOL fEmulated,
- BOOL fUnicodeDLL,
- LPTSTR pszFileName,
- HANDLE hmod)
- {
- PCUSTLINK pcl;
- PWINDOWCLASSDESC pwcd;
-
- if (!(pwcd = (PWINDOWCLASSDESC)MyAlloc(sizeof(WINDOWCLASSDESC))))
- return NULL;
-
- /*
- * Initialize the structure to be like an emulated custom control.
- */
- *pwcd = awcd[W_CUSTOM];
-
- /*
- * Now override some values.
- */
- pwcd->flStyles = pcci->flStyleDefault;
- pwcd->flExtStyle = pcci->flExtStyleDefault;
- pwcd->cxDefault = pcci->cxDefault;
- pwcd->cyDefault = pcci->cyDefault;
- pwcd->fEmulated = fEmulated;
- pwcd->fUnicodeDLL = fUnicodeDLL;
- pwcd->hmod = hmod;
- pwcd->cStyleFlags = pcci->cStyleFlags;
- pwcd->aStyleFlags = pcci->aStyleFlags;
- pwcd->lpfnStyle = (PROC)pcci->lpfnStyle;
- pwcd->lpfnSizeToText = (PROC)pcci->lpfnSizeToText;
- pwcd->flCtrlTypeMask = pcci->flCtrlTypeMask;
-
- if (pcci->flOptions & CCF_NOTEXT)
- pwcd->fHasText = FALSE;
- else
- pwcd->fHasText = TRUE;
-
- if (pcci->lpfnSizeToText && pwcd->fHasText)
- pwcd->fSizeToText = TRUE;
-
- /*
- * Copy the class name.
- */
- if (!(pwcd->pszClass = NameOrdDup(pcci->szClass)))
- goto error1;
-
- /*
- * Copy the default text. This is an optional field.
- */
- if (*pcci->szTextDefault) {
- if (!(pwcd->pszTextDefault = NameOrdDup(pcci->szTextDefault)))
- goto error2;
- }
- else {
- pwcd->pszTextDefault = NULL;
- }
-
- if (!(pcl = (PCUSTLINK)MyAlloc(sizeof(CUSTLINK))))
- goto error3;
-
- /*
- * Copy the DLL file name (NULL for emulated controls).
- */
- if (pszFileName && *pszFileName) {
- if (!(pcl->pszFileName = NameOrdDup(pszFileName)))
- goto error4;
- }
- else {
- pcl->pszFileName = NULL;
- }
-
- /*
- * Copy the descriptive text. This is an optional field.
- */
- if (*pcci->szDesc) {
- if (!(pcl->pszDesc = NameOrdDup(pcci->szDesc)))
- goto error5;
- }
- else {
- pcl->pszDesc = NULL;
- }
-
- pcl->pclNext = NULL;
- pcl->pwcd = pwcd;
-
- return pcl;
-
- error5:
- if (pcl->pszFileName)
- MyFree(pcl->pszFileName);
-
- error4:
- MyFree(pcl);
-
- error3:
- if (pwcd->pszTextDefault)
- MyFree(pwcd->pszTextDefault);
-
- error2:
- MyFree(pwcd->pszClass);
-
- error1:
- MyFree(pwcd);
-
- return NULL;
- }
-
-
-
- /************************************************************************
- * RemoveCustomLink
- *
- * Removes and frees a custom control link from the list.
- *
- * History:
- *
- ************************************************************************/
-
- VOID RemoveCustomLink(
- PCUSTLINK pclFree)
- {
- PCUSTLINK pcl;
- PCUSTLINK pclPrev;
-
- /*
- * Search for the link in the list.
- */
- for (pcl = gpclHead, pclPrev = NULL; pcl != pclFree;
- pclPrev = pcl, pcl = pcl->pclNext)
- ;
-
- /*
- * Link was not found.
- */
- if (!pcl)
- return;
-
- /*
- * Remove the link from the list.
- */
- if (pclPrev)
- pclPrev->pclNext = pclFree->pclNext;
- else
- gpclHead = pclFree->pclNext;
-
- /*
- * Finally, free the link completely.
- */
- FreeCUSTLINK(pclFree);
- }
-
-
-
- /************************************************************************
- * FreeCUSTLINK
- *
- * Frees a CUSTLINK structure. This includes freeing the
- * associated WINDOWCLASSDESC structure.
- *
- * History:
- *
- ************************************************************************/
-
- STATICFN VOID FreeCUSTLINK(
- PCUSTLINK pclFree)
- {
- PCUSTLINK pcl;
- INT i;
-
- /*
- * Do we need to unload the associated DLL?
- */
- if (pclFree->pwcd->hmod) {
- /*
- * Run throught the custom list looking to see if any other
- * installed custom control has the same module handle as the
- * one that we are freeing.
- */
- for (pcl = gpclHead;
- pcl &&
- (pcl == pclFree || pcl->pwcd->hmod != pclFree->pwcd->hmod);
- pcl = pcl->pclNext)
- ;
-
- /*
- * If none were found, it is safe to unload this library.
- * Otherwise, we must leave the library loaded for the
- * others!
- */
- if (!pcl)
- FreeLibrary(pclFree->pwcd->hmod);
- }
-
- MyFree(pclFree->pwcd->pszClass);
-
- if (pclFree->pwcd->pszTextDefault)
- MyFree(pclFree->pwcd->pszTextDefault);
-
- /*
- * Is this a non-unicode DLL? If so, then when it was loaded,
- * the dialog editor allocated a table of unicode style strings.
- * This table must now be freed. If the DLL was a unicode one,
- * then the table pointed to by aStyleFlags belongs to the DLL,
- * and it must NOT be freed.
- */
- if (pclFree->pwcd->hmod && !pclFree->pwcd->fUnicodeDLL) {
- for (i = 0; i < pclFree->pwcd->cStyleFlags; i++)
- MyFree(pclFree->pwcd->aStyleFlags[i].pszStyle);
-
- if (pclFree->pwcd->aStyleFlags)
- MyFree(pclFree->pwcd->aStyleFlags);
- }
-
- MyFree(pclFree->pwcd);
-
- if (pclFree->pszFileName)
- MyFree(pclFree->pszFileName);
-
- if (pclFree->pszDesc)
- MyFree(pclFree->pszDesc);
-
- MyFree(pclFree);
- }
-
-
-
- /************************************************************************
- * CallCustomStyle
- *
- *
- * History:
- *
- ************************************************************************/
-
- BOOL CallCustomStyle(
- NPCTYPE npc,
- PDWORD pflStyleNew,
- PDWORD pflExtStyleNew,
- LPTSTR pszTextNew)
- {
- CCSTYLE ccs;
- CCSTYLEA ccsA;
- BOOL fSuccess;
- BOOL fDefCharUsed;
- INT idPrevDlg;
-
- /*
- * Because we are about ready to display the dialog, we need to
- * call EnteringDialog so that the properties bar, toolbox and
- * work mode dialog get disabled. The first parameter is the
- * dialog id, used so that the proper help will be brought up
- * for this dialog. Since we don't have a meaningful help screen
- * for any old random custom control, just pass in a value of
- * zero, which will cause the Help Contents screen to be
- * brought up if the user presses F1 while the dialog is up.
- */
- EnteringDialog(0, &idPrevDlg, TRUE);
-
- /*
- * Is this a UNICODE DLL?
- */
- if (npc->pwcd->fUnicodeDLL) {
- ccs.flStyle = *pflStyleNew;
- ccs.flExtStyle = *pflExtStyleNew;
- lstrcpy(ccs.szText, pszTextNew);
- ccs.lgid = gcd.di.wLanguage;
- ccs.wReserved1 = 0;
-
- fSuccess = ((LPFNCCSTYLE)(*npc->pwcd->lpfnStyle))(ghwndMain, &ccs);
-
- if (fSuccess) {
- *pflStyleNew = ccs.flStyle;
- *pflExtStyleNew = ccs.flExtStyle;
- lstrcpy(pszTextNew, ccs.szText);
- }
- }
- else {
- ccsA.flStyle = *pflStyleNew;
- ccsA.flExtStyle = *pflExtStyleNew;
- WideCharToMultiByte(CP_ACP, 0, pszTextNew, -1, ccsA.szText, CCHCCTEXT,
- NULL, &fDefCharUsed);
- ccsA.lgid = gcd.di.wLanguage;
- ccsA.wReserved1 = 0;
-
- fSuccess = ((LPFNCCSTYLEA)(*npc->pwcd->lpfnStyle))(ghwndMain, &ccsA);
-
- if (fSuccess) {
- *pflStyleNew = ccsA.flStyle;
- *pflExtStyleNew = ccsA.flExtStyle;
- MultiByteToWideChar(CP_ACP, 0, ccsA.szText, -1, pszTextNew,
- CCHTEXTMAX);
- }
- }
-
- EnteringDialog(idPrevDlg, NULL, FALSE);
-
- return fSuccess;
- }
-
-
-
- /************************************************************************
- * CallCustomSizeToText
- *
- *
- *
- * Returns:
- *
- * History:
- *
- ************************************************************************/
-
- INT CallCustomSizeToText(
- NPCTYPE npc)
- {
- INT x;
- INT xDU;
- BOOL fDefCharUsed;
- CHAR szTextA[CCHTEXTMAX];
- PSTR pszTextA;
-
- /*
- * Does this custom control have a SizeToText function?
- */
- if (!npc->pwcd->lpfnSizeToText)
- return -1;
-
- /*
- * Is this a UNICODE DLL that we are calling to?
- */
- if (npc->pwcd->fUnicodeDLL) {
- x = ((LPFNCCSIZETOTEXT)(*npc->pwcd->lpfnSizeToText))
- (npc->flStyle, npc->flExtStyle, gcd.hFont, npc->text);
- }
- else {
- /*
- * No, not a UNICODE DLL. We must convert from UNICODE to
- * ANSI first. NULL text cases must be handled properly.
- */
- if (npc->text) {
- WideCharToMultiByte(CP_ACP, 0, npc->text, -1, szTextA, CCHTEXTMAX,
- NULL, &fDefCharUsed);
- pszTextA = szTextA;
- }
- else {
- pszTextA = NULL;
- }
-
- x = ((LPFNCCSIZETOTEXTA)(*npc->pwcd->lpfnSizeToText))
- (npc->flStyle, npc->flExtStyle, gcd.hFont, pszTextA);
- }
-
- /*
- * Did the call to the DLL fail?
- */
- if (x == -1)
- return -1;
-
- /*
- * Convert the size in pixels to a size in Dialog Units. Be sure
- * that we round any fraction up to the next higher DU. Since
- * we know how wide the control must be to fit the text, we must
- * be sure that the size does not get rounded down below this
- * value when converting to DU's.
- */
- xDU = MulDiv(x, 4, gcd.cxChar);
- if (MulDiv(xDU, gcd.cxChar, 4) != x)
- xDU++;
-
- return xDU;
- }
-
-
-
- /************************************************************************
- * ReadCustomProfile
- *
- *
- * History:
- *
- ************************************************************************/
-
- VOID ReadCustomProfile(VOID)
- {
- TCHAR szBuf[CCHTEXTMAX];
- TCHAR szBuf2[CCHTEXTMAX];
- LPTSTR pszKey;
-
- GetPrivateProfileString(szCustomDLL, NULL, szEmpty,
- szBuf, CCHTEXTMAX, ids(IDS_DLGEDITINI));
-
- /*
- * Get the file name for each custom control DLL and load it.
- */
- for (pszKey = szBuf; *pszKey; pszKey += lstrlen(pszKey) + 1) {
- if (GetPrivateProfileString(szCustomDLL, pszKey, szEmpty,
- szBuf2, CCHTEXTMAX, ids(IDS_DLGEDITINI)))
- OpenDLLFile(szBuf2);
- }
- }
-
-
-
- /************************************************************************
- * WriteCustomProfile
- *
- *
- * History:
- *
- ************************************************************************/
-
- VOID WriteCustomProfile(VOID)
- {
- PCUSTLINK pcl;
- PCUSTLINK pcl2;
- BOOL fSecond;
-
- /*
- * Clear out the section.
- */
- WritePrivateProfileString(szCustomDLL, NULL, NULL, ids(IDS_DLGEDITINI));
-
- for (pcl = gpclHead; pcl; pcl = pcl->pclNext) {
- /*
- * Only write out installed DLL's, not emulated controls.
- */
- if (pcl->pszFileName) {
- /*
- * Before writing out the path to the DLL, be sure
- * that this DLL's path has not been written out
- * already. This would only occur if they have
- * multiple control types within the DLL.
- */
- for (pcl2 = gpclHead, fSecond = FALSE;
- pcl2 && pcl2 != pcl; pcl2 = pcl2->pclNext) {
- if (lstrcmpi(pcl2->pszFileName, pcl->pszFileName) == 0) {
- fSecond = TRUE;
- break;
- }
- }
-
- if (!fSecond)
- WritePrivateProfileString(szCustomDLL, pcl->pwcd->pszClass,
- pcl->pszFileName, ids(IDS_DLGEDITINI));
- }
- }
- }
-