diff options
Diffstat (limited to 'private/oleutest/letest/ole2ui/insobj.c')
-rw-r--r-- | private/oleutest/letest/ole2ui/insobj.c | 1724 |
1 files changed, 1724 insertions, 0 deletions
diff --git a/private/oleutest/letest/ole2ui/insobj.c b/private/oleutest/letest/ole2ui/insobj.c new file mode 100644 index 000000000..53fa094c9 --- /dev/null +++ b/private/oleutest/letest/ole2ui/insobj.c @@ -0,0 +1,1724 @@ +/* + * INSOBJ.C + * + * Implements the OleUIInsertObject function which invokes the complete + * Insert Object dialog. Makes use of the OleChangeIcon function in + * ICON.C. + * + * Copyright (c)1993 Microsoft Corporation, All Rights Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" +#include <commdlg.h> +#include <memory.h> +#include <direct.h> +#include <malloc.h> +#include <dos.h> +#include <stdlib.h> +#include "common.h" +#include "utility.h" +#include "icon.h" +#include "insobj.h" +#include "resimage.h" +#include "iconbox.h" +#include "geticon.h" + +#define IS_FILENAME_DELIM(c) ( (c) == TEXT('\\') || (c) == TEXT('/') || (c) == TEXT(':') ) + +/* + * OleUIInsertObject + * + * Purpose: + * Invokes the standard OLE Insert Object dialog box allowing the + * user to select an object source and classname as well as the option + * to display the object as itself or as an icon. + * + * Parameters: + * lpIO LPOLEUIINSERTOBJECT pointing to the in-out structure + * for this dialog. + * + * Return Value: + * UINT OLEUI_SUCCESS or OLEUI_OK if all is well, otherwise + * an error value. + */ + +STDAPI_(UINT) OleUIInsertObject(LPOLEUIINSERTOBJECT lpIO) + { + UINT uRet; + HGLOBAL hMemDlg=NULL; + HRESULT hrErr; + + uRet=UStandardValidation((LPOLEUISTANDARD)lpIO, sizeof(OLEUIINSERTOBJECT) + , &hMemDlg); + + if (OLEUI_SUCCESS!=uRet) + return uRet; + + //Now we can do Insert Object specific validation. + + + // NULL is NOT valid for lpszFile + if ( (NULL == lpIO->lpszFile) + || (IsBadReadPtr(lpIO->lpszFile, lpIO->cchFile)) + || (IsBadWritePtr(lpIO->lpszFile, lpIO->cchFile)) ) + uRet=OLEUI_IOERR_LPSZFILEINVALID; + + if (NULL != lpIO->lpszFile + && (lpIO->cchFile <= 0 || lpIO->cchFile > OLEUI_CCHPATHMAX_SIZE)) + uRet=OLEUI_IOERR_CCHFILEINVALID; + + if (0!=lpIO->cClsidExclude) + { + if (NULL!=lpIO->lpClsidExclude && IsBadReadPtr(lpIO->lpClsidExclude + , lpIO->cClsidExclude*sizeof(CLSID))) + uRet=OLEUI_IOERR_LPCLSIDEXCLUDEINVALID; + } + + //If we have flags to create any object, validate necessary data. + if (lpIO->dwFlags & (IOF_CREATENEWOBJECT | IOF_CREATEFILEOBJECT | IOF_CREATELINKOBJECT)) + { + if (NULL!=lpIO->lpFormatEtc + && IsBadReadPtr(lpIO->lpFormatEtc, sizeof(FORMATETC))) + uRet=OLEUI_IOERR_LPFORMATETCINVALID; + + if (NULL!=lpIO->ppvObj && IsBadWritePtr(lpIO->ppvObj, sizeof(LPVOID))) + uRet=OLEUI_IOERR_PPVOBJINVALID; + + if (NULL!=lpIO->lpIOleClientSite + && IsBadReadPtr(lpIO->lpIOleClientSite->lpVtbl, sizeof(IOleClientSiteVtbl))) + uRet=OLEUI_IOERR_LPIOLECLIENTSITEINVALID; + + if (NULL!=lpIO->lpIStorage + && IsBadReadPtr(lpIO->lpIStorage->lpVtbl, sizeof(IStorageVtbl))) + uRet=OLEUI_IOERR_LPISTORAGEINVALID; + } + + if (OLEUI_ERR_STANDARDMIN <= uRet) + { + if (NULL!=hMemDlg) + FreeResource(hMemDlg); + + return uRet; + } + + //Now that we've validated everything, we can invoke the dialog. + uRet=UStandardInvocation(InsertObjectDialogProc, (LPOLEUISTANDARD)lpIO + , hMemDlg, MAKEINTRESOURCE(IDD_INSERTOBJECT)); + + + //Stop here if we cancelled or had an error. + if (OLEUI_SUCCESS !=uRet && OLEUI_OK!=uRet) + return uRet; + + + /* + * If any of the flags specify that we're to create objects on return + * from this dialog, then do so. If we encounter an error in this + * processing, we return OLEUI_IOERR_SCODEHASERROR. Since the + * three select flags are mutually exclusive, we don't have to + * if...else here, just if each case (keeps things cleaner that way). + */ + + lpIO->sc=S_OK; + + //Check if Create New was selected and we have IOF_CREATENEWOBJECT + if ((lpIO->dwFlags & IOF_SELECTCREATENEW) && (lpIO->dwFlags & IOF_CREATENEWOBJECT)) + { + hrErr=OleCreate(&lpIO->clsid, &lpIO->iid, lpIO->oleRender + , lpIO->lpFormatEtc, lpIO->lpIOleClientSite, lpIO->lpIStorage + , lpIO->ppvObj); + lpIO->sc = GetScode(hrErr); + } + + //Try Create From File + if ((lpIO->dwFlags & IOF_SELECTCREATEFROMFILE)) + { + if (!(lpIO->dwFlags & IOF_CHECKLINK) && (lpIO->dwFlags & IOF_CREATEFILEOBJECT)) + { + hrErr=OleCreateFromFileA(&CLSID_NULL, lpIO->lpszFile, &lpIO->iid + , lpIO->oleRender, lpIO->lpFormatEtc, lpIO->lpIOleClientSite + , lpIO->lpIStorage, lpIO->ppvObj); + lpIO->sc = GetScode(hrErr); + } + + if ((lpIO->dwFlags & IOF_CHECKLINK) && (lpIO->dwFlags & IOF_CREATELINKOBJECT)) + { + hrErr=OleCreateLinkToFileA(lpIO->lpszFile, &lpIO->iid + , lpIO->oleRender, lpIO->lpFormatEtc, lpIO->lpIOleClientSite + , lpIO->lpIStorage, lpIO->ppvObj); + lpIO->sc = GetScode(hrErr); + } + } + + //If we tried but failed a create option, then return the appropriate error + if (S_OK!=lpIO->sc) + uRet=OLEUI_IOERR_SCODEHASERROR; + + return uRet; + } + + + + + +/* + * InsertObjectDialogProc + * + * Purpose: + * Implements the OLE Insert Object dialog as invoked through the + * OleUIInsertObject function. + */ + +BOOL CALLBACK EXPORT InsertObjectDialogProc(HWND hDlg, UINT iMsg + , WPARAM wParam, LPARAM lParam) + { + LPOLEUIINSERTOBJECT lpOIO; + LPINSERTOBJECT lpIO; + OLEUICHANGEICON ci; + UINT i; + BOOL fCheck=FALSE; + UINT uRet=0; + + //Declare Win16/Win32 compatible WM_COMMAND parameters. + COMMANDPARAMS(wID, wCode, hWndMsg); + + //This will fail under WM_INITDIALOG, where we allocate it. + lpIO=(LPINSERTOBJECT)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet); + + //If the hook processed the message, we're done. + if (0!=uRet) + return (BOOL)uRet; + + //Process help message from Change Icon + if (iMsg==uMsgHelp) + { + PostMessage(lpIO->lpOIO->hWndOwner, uMsgHelp, wParam, lParam); + return FALSE; + } + + //Process the temination message + if (iMsg==uMsgEndDialog) + { + InsertObjectCleanup(hDlg); + StandardCleanup(lpIO, hDlg); + EndDialog(hDlg, wParam); + return TRUE; + } + + switch (iMsg) + { + case WM_INITDIALOG: + return FInsertObjectInit(hDlg, wParam, lParam); + + case WM_COMMAND: + switch (wID) + { + case ID_IO_CREATENEW: + FToggleObjectSource(hDlg, lpIO, IOF_SELECTCREATENEW); + break; + + case ID_IO_CREATEFROMFILE: + FToggleObjectSource(hDlg, lpIO, IOF_SELECTCREATEFROMFILE); + break; + + case ID_IO_LINKFILE: + fCheck=IsDlgButtonChecked(hDlg, wID); + + if (fCheck) + lpIO->dwFlags |=IOF_CHECKLINK; + else + lpIO->dwFlags &=~IOF_CHECKLINK; + + //Results change here, so be sure to update it. + SetInsertObjectResults(hDlg, lpIO); + UpdateClassIcon(hDlg, lpIO, NULL); + break; + + case ID_IO_OBJECTTYPELIST: + switch (wCode) + { + case LBN_SELCHANGE: + UpdateClassIcon(hDlg, lpIO, hWndMsg); + SetInsertObjectResults(hDlg, lpIO); + break; + + case LBN_DBLCLK: + //Same as pressing OK. + SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg); + break; + } + break; + + + case ID_IO_FILEDISPLAY: + //If there are characters, enable OK and Display As Icon + if (EN_CHANGE==wCode) + { + lpIO->fFileDirty = TRUE; + lpIO->fFileValid = FALSE; + + lpIO->fFileSelected= + (0L!=SendMessage(hWndMsg, EM_LINELENGTH, 0, 0L)); + EnableWindow(GetDlgItem(hDlg, ID_IO_LINKFILE), lpIO->fFileSelected); + EnableWindow(GetDlgItem(hDlg, ID_IO_DISPLAYASICON), lpIO->fFileSelected); + EnableWindow(GetDlgItem(hDlg, ID_IO_CHANGEICON), lpIO->fFileSelected); + EnableWindow(GetDlgItem(hDlg, IDOK), lpIO->fFileSelected); + } + + if (EN_KILLFOCUS==wCode && NULL!=lpIO) + { + if (FValidateInsertFile(hDlg,FALSE,&lpIO->nErrCode)) { + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = TRUE; + UpdateClassIcon(hDlg, lpIO, NULL); + UpdateClassType(hDlg, lpIO, TRUE); + } else { + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = FALSE; + UpdateClassType(hDlg, lpIO, FALSE); + } + } + break; + + + case ID_IO_DISPLAYASICON: + fCheck=IsDlgButtonChecked(hDlg, wID); + EnableWindow(GetDlgItem(hDlg, ID_IO_CHANGEICON), fCheck); + + if (fCheck) + lpIO->dwFlags |=IOF_CHECKDISPLAYASICON; + else + lpIO->dwFlags &=~IOF_CHECKDISPLAYASICON; + + //Update the internal flag based on this checking + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + lpIO->fAsIconNew=fCheck; + else + lpIO->fAsIconFile=fCheck; + + //Re-read the class icon on Display checked + if (fCheck) + { + if (lpIO->dwFlags & IOF_SELECTCREATEFROMFILE) + { + if (FValidateInsertFile(hDlg, TRUE,&lpIO->nErrCode)) + { + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = TRUE; + UpdateClassIcon(hDlg, lpIO, + GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST)); + + UpdateClassType(hDlg, lpIO, TRUE); + } + + else + { + HWND hWndEC; + + lpIO->fAsIconFile= FALSE; + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = FALSE; + SendDlgItemMessage(hDlg, ID_IO_ICONDISPLAY, IBXM_IMAGESET, 0, 0L); + UpdateClassType(hDlg, lpIO, FALSE); + + lpIO->dwFlags &=~IOF_CHECKDISPLAYASICON; + CheckDlgButton(hDlg, ID_IO_DISPLAYASICON, 0); + + hWndEC = GetDlgItem(hDlg, ID_IO_FILEDISPLAY); + SetFocus(hWndEC); + SendMessage(hWndEC, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + return TRUE; + } + } + else + UpdateClassIcon(hDlg, lpIO, + GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST)); + } + + + //Results change here, so be sure to update it. + SetInsertObjectResults(hDlg, lpIO); + + + /* + * Show or hide controls as appropriate. Do the icon + * display last because it will take some time to repaint. + * If we do it first then the dialog looks too sluggish. + */ + i=(fCheck) ? SW_SHOWNORMAL : SW_HIDE; + StandardShowDlgItem(hDlg, ID_IO_CHANGEICON, i); + StandardShowDlgItem(hDlg, ID_IO_ICONDISPLAY, i); + + break; + + + case ID_IO_CHANGEICON: + { + + LPMALLOC pIMalloc; + HWND hList; + LPTSTR pszString, pszCLSID; + + int iCurSel; + + // if we're in SELECTCREATEFROMFILE mode, then we need to Validate + // the contents of the edit control first. + + if (lpIO->dwFlags & IOF_SELECTCREATEFROMFILE) + { + if ( lpIO->fFileDirty + && !FValidateInsertFile(hDlg, TRUE, &lpIO->nErrCode) ) + { + HWND hWndEC; + + lpIO->fFileDirty = TRUE; + hWndEC = GetDlgItem(hDlg, ID_IO_FILEDISPLAY); + SetFocus(hWndEC); + SendMessage(hWndEC, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + return TRUE; + } + else + lpIO->fFileDirty = FALSE; + } + + + + //Initialize the structure for the hook. + _fmemset((LPOLEUICHANGEICON)&ci, 0, sizeof(ci)); + + ci.hMetaPict=(HGLOBAL)SendDlgItemMessage(hDlg + , ID_IO_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L); + + ci.cbStruct =sizeof(ci); + ci.hWndOwner=hDlg; + ci.dwFlags =CIF_SELECTCURRENT; + + if (lpIO->dwFlags & IOF_SHOWHELP) + ci.dwFlags |= CIF_SHOWHELP; + + + + + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + // Initialize clsid... + if (NOERROR != CoGetMalloc(MEMCTX_TASK, &pIMalloc)) + return FALSE; + + pszString = (LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, + OLEUI_CCHKEYMAX_SIZE + + OLEUI_CCHCLSIDSTRING_SIZE); + + + hList = GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST); + iCurSel = (int)SendMessage(hList, LB_GETCURSEL, 0, 0L); + SendMessage(hList, LB_GETTEXT, iCurSel, (LONG)pszString); + + pszCLSID = PointerToNthField(pszString, 2, TEXT('\t')); + + CLSIDFromStringA((LPTSTR)pszCLSID, (LPCLSID)&(ci.clsid)); + + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszString); + pIMalloc->lpVtbl->Release(pIMalloc); + } + else // IOF_SELECTCREATEFROMFILE + { + + TCHAR szFileName[OLEUI_CCHPATHMAX]; + + GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, (LPTSTR)szFileName, OLEUI_CCHPATHMAX); + + if (NOERROR != GetClassFileA(szFileName, (LPCLSID)&(ci.clsid))) + { + LPTSTR lpszExtension; + int istrlen; + + istrlen = lstrlen(szFileName); + + lpszExtension = (LPTSTR)szFileName + istrlen -1; + + while ( (lpszExtension > szFileName) && + (*lpszExtension != TEXT('.')) ) + lpszExtension--; + + GetAssociatedExecutable(lpszExtension, (LPTSTR)ci.szIconExe); + ci.cchIconExe = lstrlen(ci.szIconExe); + ci.dwFlags |= CIF_USEICONEXE; + + } + } + + + //Let the hook in to customize Change Icon if desired. + uRet=UStandardHook(lpIO, hDlg, uMsgChangeIcon + , 0, (LONG)(LPTSTR)&ci); + + if (0==uRet) + uRet=(UINT)(OLEUI_OK==OleUIChangeIcon(&ci)); + + //Update the display and itemdata if necessary. + if (0!=uRet) + { + + /* + * OleUIChangeIcon will have already freed our + * current hMetaPict that we passed in when OK is + * pressed in that dialog. So we use 0L as lParam + * here so the IconBox doesn't try to free the + * metafilepict again. + */ + SendDlgItemMessage(hDlg, ID_IO_ICONDISPLAY, IBXM_IMAGESET + , (WPARAM)ci.hMetaPict, 0L); + + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + SendMessage(hList, LB_SETITEMDATA, iCurSel, ci.hMetaPict); + } + } + break; + + + case ID_IO_FILE: + { + /* + * To allow the hook to customize the browse dialog, we + * send OLEUI_MSG_BROWSE. If the hook returns FALSE + * we use the default, otherwise we trust that it retrieved + * a filename for us. This mechanism prevents hooks from + * trapping ID_IO_BROWSE to customize the dialog and from + * trying to figure out what we do after we have the name. + */ + + TCHAR szTemp[OLEUI_CCHPATHMAX]; + TCHAR szInitialDir[OLEUI_CCHPATHMAX]; + DWORD dwOfnFlags; + int nChars; + BOOL fUseInitialDir = FALSE; + + + nChars = GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, (LPTSTR)szTemp, OLEUI_CCHPATHMAX); + + if (FValidateInsertFile(hDlg, FALSE, &lpIO->nErrCode)) + { + + int istrlen; + + GetFileTitle((LPTSTR)szTemp, lpIO->szFile, OLEUI_CCHPATHMAX); + + istrlen = lstrlen(lpIO->szFile); + + LSTRCPYN((LPTSTR)szInitialDir, szTemp, nChars - istrlen); + fUseInitialDir = TRUE; + + } + else // file name isn't valid...lop off end of szTemp to get a + // valid directory + { +#if defined( WIN32 ) + TCHAR szBuffer[OLEUI_CCHPATHMAX]; + DWORD Attribs; + + LSTRCPYN(szBuffer, szTemp, OLEUI_CCHPATHMAX-1); + szBuffer[OLEUI_CCHPATHMAX-1] = TEXT('\0'); + + if (TEXT('\\') == szBuffer[nChars-1]) + szBuffer[nChars-1] = TEXT('\0'); + + Attribs = GetFileAttributes(szBuffer); + if (Attribs != 0xffffffff && + (Attribs & FILE_ATTRIBUTE_DIRECTORY) ) + { + lstrcpy(szInitialDir, (LPTSTR)szBuffer); + fUseInitialDir = TRUE; + } +#else + static TCHAR szBuffer[OLEUI_CCHPATHMAX]; + static int attrib ; + + LSTRCPYN(szBuffer, szTemp, OLEUI_CCHPATHMAX-1); + szBuffer[OLEUI_CCHPATHMAX-1] = TEXT('\0'); + + AnsiToOem(szBuffer, szBuffer); +#if defined( OBSOLETE ) // fix bug# 3575 + if (TEXT('\\') == szBuffer[nChars-1]) + szBuffer[nChars-1] = TEXT('\0'); + + if(0 == _dos_getfileattr(szBuffer, &attrib)) +#endif // OBSOLETE + { + lstrcpy(szInitialDir, (LPTSTR)szBuffer); + fUseInitialDir = TRUE; + } +#endif + *lpIO->szFile = TEXT('\0'); + } + + uRet=UStandardHook(lpIO, hDlg, uMsgBrowse + , OLEUI_CCHPATHMAX_SIZE, (LPARAM)(LPSTR)lpIO->szFile); + + dwOfnFlags = OFN_FILEMUSTEXIST; + + if (lpIO->lpOIO->dwFlags & IOF_SHOWHELP) + dwOfnFlags |= OFN_SHOWHELP; + + if (0==uRet) + uRet=(UINT)Browse(hDlg, + lpIO->szFile, + fUseInitialDir ? (LPTSTR)szInitialDir : NULL, + OLEUI_CCHPATHMAX_SIZE, + IDS_FILTERS, + dwOfnFlags); + + //Only update if the file changed. + if (0!=uRet && 0!=lstrcmpi(szTemp, lpIO->szFile)) + { + SetDlgItemText(hDlg, ID_IO_FILEDISPLAY, lpIO->szFile); + lpIO->fFileSelected=TRUE; + + if (FValidateInsertFile(hDlg, TRUE, &lpIO->nErrCode)) + { + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = TRUE; + UpdateClassIcon(hDlg, lpIO, NULL); + UpdateClassType(hDlg, lpIO, TRUE); + // auto set OK to be default button if valid file + SendMessage(hDlg, DM_SETDEFID, + (WPARAM)GetDlgItem(hDlg, IDOK), 0L); + SetFocus(GetDlgItem(hDlg, IDOK)); + } + else // filename is invalid - set focus back to ec + { + HWND hWnd; + + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = FALSE; + hWnd = GetDlgItem(hDlg, ID_IO_FILEDISPLAY); + SetFocus(hWnd); + SendMessage(hWnd, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + } + + //Once we have a file, Display As Icon is always enabled + EnableWindow(GetDlgItem(hDlg, ID_IO_DISPLAYASICON), TRUE); + + //As well as OK + EnableWindow(GetDlgItem(hDlg, IDOK), TRUE); + + } + } + break; + + + case IDOK: + { + HWND hListBox; + WORD iCurSel; + TCHAR szBuffer[OLEUI_CCHKEYMAX + OLEUI_CCHCLSIDSTRING]; + LPTSTR lpszCLSID; + + if ((HWND)(LOWORD(lParam)) != GetFocus()) + SetFocus((HWND)(LOWORD(lParam))); + + + + // If the file name is clean (already validated), or + // if Create New is selected, then we can skip this part. + + if ( (lpIO->dwFlags & IOF_SELECTCREATEFROMFILE) + && (TRUE == lpIO->fFileDirty) ) + { + + if (FValidateInsertFile(hDlg, TRUE, &lpIO->nErrCode)) + { + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = TRUE; + UpdateClassIcon(hDlg, lpIO, NULL); + UpdateClassType(hDlg, lpIO, TRUE); + } + else // filename is invalid - set focus back to ec + { + HWND hWnd; + + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = FALSE; + hWnd = GetDlgItem(hDlg, ID_IO_FILEDISPLAY); + SetFocus(hWnd); + SendMessage(hWnd, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + UpdateClassType(hDlg, lpIO, FALSE); + } + + return TRUE; // eat this message + } + else if ( (lpIO->dwFlags & IOF_SELECTCREATEFROMFILE) + && (FALSE == lpIO->fFileValid) ) + { + // filename is invalid - set focus back to ec + HWND hWnd; + TCHAR szFile[OLEUI_CCHPATHMAX]; + + if (0!=GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, + szFile, OLEUI_CCHPATHMAX)) + { + OpenFileError(hDlg, lpIO->nErrCode, szFile); + } + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = FALSE; + hWnd = GetDlgItem(hDlg, ID_IO_FILEDISPLAY); + SetFocus(hWnd); + SendMessage(hWnd, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + UpdateClassType(hDlg, lpIO, FALSE); + return TRUE; // eat this message + } + + //Copy the necessary information back to the original struct + lpOIO=lpIO->lpOIO; + lpOIO->dwFlags=lpIO->dwFlags; + + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + hListBox=GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST); + iCurSel=(WORD)SendMessage(hListBox, LB_GETCURSEL, 0, 0); + + if (lpIO->dwFlags & IOF_CHECKDISPLAYASICON) + { + lpOIO->hMetaPict=(HGLOBAL)SendMessage(hListBox, + LB_GETITEMDATA, iCurSel, 0L); + + /* + * Set the item data to 0 here so that the cleanup + * code doesn't delete the metafile. + */ + SendMessage(hListBox, LB_SETITEMDATA, iCurSel, 0L); + } + else + lpOIO->hMetaPict = (HGLOBAL)NULL; + + SendMessage(hListBox, LB_GETTEXT, iCurSel + , (LPARAM)(LPTSTR)szBuffer); + + lpszCLSID=PointerToNthField((LPTSTR)szBuffer, 2, TEXT('\t')); + CLSIDFromStringA(lpszCLSID, &lpOIO->clsid); + + } + else // IOF_SELECTCREATEFROMFILE + { + if (lpIO->dwFlags & IOF_CHECKDISPLAYASICON) + { + // get metafile here + lpOIO->hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg, + ID_IO_ICONDISPLAY, + IBXM_IMAGEGET, + 0, 0L); + + + } + else + lpOIO->hMetaPict = (HGLOBAL)NULL; + + } + + GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, + lpIO->szFile, lpOIO->cchFile); + + LSTRCPYN(lpOIO->lpszFile, lpIO->szFile, lpOIO->cchFile); + + SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L); + } + break; + + case IDCANCEL: + SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L); + break; + + case ID_OLEUIHELP: + PostMessage(lpIO->lpOIO->hWndOwner, uMsgHelp + , (WPARAM)hDlg, MAKELPARAM(IDD_INSERTOBJECT, 0)); + break; + } + break; + + default: + { + if (lpIO && iMsg == lpIO->nBrowseHelpID) { + PostMessage(lpIO->lpOIO->hWndOwner, uMsgHelp, + (WPARAM)hDlg, MAKELPARAM(IDD_INSERTFILEBROWSE, 0)); + } + } + break; + } + + return FALSE; + } + + + + +/* + * FInsertObjectInit + * + * Purpose: + * WM_INITIDIALOG handler for the Insert Object dialog box. + * + * Parameters: + * hDlg HWND of the dialog + * wParam WPARAM of the message + * lParam LPARAM of the message + * + * Return Value: + * BOOL Value to return for WM_INITDIALOG. + */ + +BOOL FInsertObjectInit(HWND hDlg, WPARAM wParam, LPARAM lParam) + { + LPOLEUIINSERTOBJECT lpOIO; + LPINSERTOBJECT lpIO; + RECT rc; + DWORD dw; + HFONT hFont; + HWND hList; + UINT u; + BOOL fCheck; + CHAR *pch; // pointer to current working directory + // ANSI string (to use with _getcwd) + + //1. Copy the structure at lParam into our instance memory. + lpIO=(LPINSERTOBJECT)LpvStandardInit(hDlg, sizeof(INSERTOBJECT), TRUE, &hFont); + + //PvStandardInit send a termination to us already. + if (NULL==lpIO) + return FALSE; + + lpOIO=(LPOLEUIINSERTOBJECT)lParam; + + //2. Save the original pointer and copy necessary information. + lpIO->lpOIO =lpOIO; + lpIO->dwFlags=lpOIO->dwFlags; + lpIO->clsid =lpOIO->clsid; + + if ( (lpOIO->lpszFile) && (TEXT('\0') != *lpOIO->lpszFile) ) + LSTRCPYN((LPTSTR)lpIO->szFile, lpOIO->lpszFile, OLEUI_CCHPATHMAX); + else + *(lpIO->szFile) = TEXT('\0'); + + lpIO->hMetaPictFile = (HGLOBAL)NULL; + + //3. If we got a font, send it to the necessary controls. + if (NULL!=hFont) + { + SendDlgItemMessage(hDlg, ID_IO_RESULTTEXT, WM_SETFONT, (WPARAM)hFont, 0L); + SendDlgItemMessage(hDlg, ID_IO_FILETYPE, WM_SETFONT, (WPARAM)hFont, 0L); + } + + + //4. Fill the Object Type listbox with entries from the reg DB. + hList=GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST); + UFillClassList(hList, lpOIO->cClsidExclude, lpOIO->lpClsidExclude + , (BOOL)(lpOIO->dwFlags & IOF_VERIFYSERVERSEXIST)); + + //Set the tab width in the list to push all the tabs off the side. + GetClientRect(hList, &rc); + dw=GetDialogBaseUnits(); + rc.right =(8*rc.right)/LOWORD(dw); //Convert pixels to 2x dlg units. + SendMessage(hList, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&rc.right); + + + //5. Initilize the file name display to cwd if we don't have any name. + if (TEXT('\0') == *(lpIO->szFile)) + { + TCHAR tch[OLEUI_CCHPATHMAX]; + + pch=_getcwd(NULL, OLEUI_CCHPATHMAX); + if (*(pch+strlen(pch)-1) != '\\') + strcat(pch, "\\"); // put slash on end of cwd +#ifdef UNICODE + mbstowcs(tch, pch, OLEUI_CCHPATHMAX); +#else + strcpy(tch, pch); +#endif + SetDlgItemText(hDlg, ID_IO_FILEDISPLAY, tch); + lpIO->fFileDirty = TRUE; // cwd is not a valid filename + #ifndef __TURBOC__ + free(pch); + #endif + } + else + { + SetDlgItemText(hDlg, ID_IO_FILEDISPLAY, lpIO->szFile); + + if (FValidateInsertFile(hDlg, FALSE, &lpIO->nErrCode)) + lpIO->fFileDirty = FALSE; + else + lpIO->fFileDirty = TRUE; + } + + + //6. Initialize the selected type radiobutton. + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + StandardShowDlgItem(hDlg, ID_IO_FILETEXT, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_FILETYPE, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_FILEDISPLAY, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_FILE, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_LINKFILE, SW_HIDE); + + CheckRadioButton(hDlg, ID_IO_CREATENEW, ID_IO_CREATEFROMFILE, ID_IO_CREATENEW); + + lpIO->fAsIconNew=(0L!=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON)); + SetFocus(hList); + } + else + { + /* + * Use pszType as the initial File. If there's no initial + * file then we have to remove any check from Display As + * Icon. We also check Link if so indicated for this option. + */ + StandardShowDlgItem(hDlg, ID_IO_OBJECTTYPELIST, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_OBJECTTYPETEXT, SW_HIDE); + + // Don't preselect display as icon if the filename isn't valid + if (TRUE == lpIO->fFileDirty) + lpIO->dwFlags &= ~(IOF_CHECKDISPLAYASICON); + + if (IOF_DISABLELINK & lpIO->dwFlags) + StandardShowDlgItem(hDlg, ID_IO_LINKFILE, SW_HIDE); + else + { + CheckDlgButton(hDlg, ID_IO_LINKFILE + , (BOOL)(0L!=(lpIO->dwFlags & IOF_CHECKLINK))); + } + + CheckRadioButton(hDlg, ID_IO_CREATENEW, ID_IO_CREATEFROMFILE, ID_IO_CREATEFROMFILE); + + lpIO->fAsIconFile=(0L!=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON)); + SetFocus(GetDlgItem(hDlg, ID_IO_FILEDISPLAY)); + } + + + //7. Initialize the Display as Icon state + fCheck=(BOOL)(lpIO->dwFlags & IOF_CHECKDISPLAYASICON); + u=fCheck ? SW_SHOWNORMAL : SW_HIDE; + + StandardShowDlgItem(hDlg, ID_IO_CHANGEICON, u); + StandardShowDlgItem(hDlg, ID_IO_ICONDISPLAY, u); + + CheckDlgButton(hDlg, ID_IO_DISPLAYASICON, fCheck); + + + //8. Show or hide the help button + if (!(lpIO->dwFlags & IOF_SHOWHELP)) + StandardShowDlgItem(hDlg, ID_OLEUIHELP, SW_HIDE); + + + //9. Initialize the result display + UpdateClassIcon(hDlg, lpIO, GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST)); + SetInsertObjectResults(hDlg, lpIO); + + //10. Change the caption + if (NULL!=lpOIO->lpszCaption) + SetWindowText(hDlg, lpOIO->lpszCaption); + + //11. Hide all DisplayAsIcon related controls if it should be disabled + if ( lpIO->dwFlags & IOF_DISABLEDISPLAYASICON ) { + StandardShowDlgItem(hDlg, ID_IO_DISPLAYASICON, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_CHANGEICON, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_ICONDISPLAY, SW_HIDE); + } + + lpIO->nBrowseHelpID = RegisterWindowMessage(HELPMSGSTRING); + + //All Done: call the hook with lCustData + UStandardHook(lpIO, hDlg, WM_INITDIALOG, wParam, lpOIO->lCustData); + + /* + * We either set focus to the listbox or the edit control. In either + * case we don't want Windows to do any SetFocus, so we return FALSE. + */ + return FALSE; + } + + + + + + +/* + * UFillClassList + * + * Purpose: + * Enumerates available OLE object classes from the registration + * database and fills a listbox with those names. + * + * Note that this function removes any prior contents of the listbox. + * + * Parameters: + * hList HWND to the listbox to fill. + * cIDEx UINT number of CLSIDs to exclude in lpIDEx + * lpIDEx LPCLSID to CLSIDs to leave out of the listbox. + * fVerify BOOL indicating if we are to validate existence of + * servers before putting them in the list. + * + * Return Value: + * UINT Number of strings added to the listbox, -1 on failure. + */ + +UINT UFillClassList(HWND hList, UINT cIDEx, LPCLSID lpIDEx, BOOL fVerify) + { + DWORD dw; + UINT cStrings=0; + UINT i; + UINT cch; + HKEY hKey; + LONG lRet; + HFILE hFile; + OFSTRUCT of; + BOOL fExclude; + LPMALLOC pIMalloc; + LPTSTR pszExec; + LPTSTR pszClass; + LPTSTR pszKey; + LPTSTR pszID; + CLSID clsid; + + //Get some work buffers + if (NOERROR!=CoGetMalloc(MEMCTX_TASK, &pIMalloc)) + return (UINT)-1; + + pszExec=(LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, OLEUI_CCHKEYMAX_SIZE*4); + + if (NULL==pszExec) + { + pIMalloc->lpVtbl->Release(pIMalloc); + return (UINT)-1; + } + + pszClass=pszExec+OLEUI_CCHKEYMAX; + pszKey=pszClass+OLEUI_CCHKEYMAX; + pszID=pszKey+OLEUI_CCHKEYMAX; + + //Open up the root key. + lRet=RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey); + + if ((LONG)ERROR_SUCCESS!=lRet) + { + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszExec); + pIMalloc->lpVtbl->Release(pIMalloc); + return (UINT)-1; + } + + //Clean out the existing strings. + SendMessage(hList, LB_RESETCONTENT, 0, 0L); + + cStrings=0; + + while (TRUE) + { + lRet=RegEnumKey(hKey, cStrings++, pszClass, OLEUI_CCHKEYMAX_SIZE); + + if ((LONG)ERROR_SUCCESS!=lRet) + break; + + //Cheat on lstrcat by using lstrcpy after this string, saving time + cch=lstrlen(pszClass); + + // Check for \NotInsertable. if this is found then this overrides + // all other keys; this class will NOT be added to the InsertObject + // list. + + lstrcpy(pszClass+cch, TEXT("\\NotInsertable")); + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszClass, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS==lRet) + continue; // NotInsertable IS found--skip this class + + //Check for a \protocol\StdFileEditing\server entry. + lstrcpy(pszClass+cch, TEXT("\\protocol\\StdFileEditing\\server")); + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszClass, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS==lRet) + { + /* + * Check if the EXE actually exists. By default we don't do this + * to bring up the dialog faster. If an application wants to be + * stringent, they can provide IOF_VERIFYSERVERSEXIST. + */ + + hFile = !HFILE_ERROR; + + if (fVerify) + hFile=DoesFileExist(pszKey, &of); + + if (HFILE_ERROR!=hFile) + { + dw=OLEUI_CCHKEYMAX_SIZE; + *(pszClass+cch)=0; // set back to rootkey + // Get full user type name + lRet=RegQueryValue(hKey, pszClass, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + continue; // error getting type name--skip this class + + //Tell the code below to get the string for us. + pszID=NULL; + } + } + else + { + /* + * No \protocol\StdFileEditing\server entry. Look to see if + * there's an Insertable entry. If there is, then use the + * Clsid to look at CLSID\clsid\LocalServer and \InprocServer + */ + + lstrcpy(pszClass+cch, TEXT("\\Insertable")); + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszClass, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + continue; // Insertable NOT found--skip this class + + //Get memory for pszID + pszID=pIMalloc->lpVtbl->Alloc(pIMalloc, OLEUI_CCHKEYMAX_SIZE); + + if (NULL==pszID) + continue; + + *(pszClass+cch)=0; // set back to rootkey + lstrcat(pszClass+cch, TEXT("\\CLSID")); + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszClass, pszID, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + continue; // CLSID subkey not found + + lstrcpy(pszExec, TEXT("CLSID\\")); + lstrcat(pszExec, pszID); + + //CLSID\ is 6, dw contains pszID length. + cch=6+(UINT)dw; + + lstrcpy(pszExec+cch, TEXT("\\LocalServer")); + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszExec, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + { + //Try InprocServer + lstrcpy(pszExec+cch, TEXT("\\InProcServer")); + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszExec, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + continue; + } + + if (fVerify) + { + if (HFILE_ERROR==DoesFileExist(pszKey, &of)) + continue; + } + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszExec, pszKey, &dw); + *(pszExec+cch)=0; //Remove \\*Server + + if ((LONG)ERROR_SUCCESS!=lRet) + continue; + } + + //Get CLSID to add to listbox. + if (NULL==pszID) + { + CLSIDFromProgIDA(pszClass, &clsid); + StringFromCLSIDA(&clsid, &pszID); + } + else + CLSIDFromStringA(pszID, &clsid); + + //Check if this CLSID is in the exclusion list. + fExclude=FALSE; + + for (i=0; i < cIDEx; i++) + { + if (IsEqualCLSID(&clsid, (LPCLSID)(lpIDEx+i))) + { + fExclude=TRUE; + break; + } + } + + if (fExclude) + continue; + + //We go through all the conditions, add the string. + lstrcat(pszKey, TEXT("\t")); + + // only add to listbox if not a duplicate + if (LB_ERR==SendMessage(hList,LB_FINDSTRING,0,(LPARAM)pszKey)) { + lstrcat(pszKey, pszID); + SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)pszKey); + } + + //We always allocated this regardless of the path + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszID); + } + + + //Select the first item by default + SendMessage(hList, LB_SETCURSEL, 0, 0L); + RegCloseKey(hKey); + + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszExec); + pIMalloc->lpVtbl->Release(pIMalloc); + + return cStrings; + } + + + + + +/* + * FToggleObjectSource + * + * Purpose: + * Handles enabling, disabling, showing, and flag manipulation when the + * user changes between Create New, Insert File, and Link File in the + * Insert Object dialog. + * + * Parameters: + * hDlg HWND of the dialog + * lpIO LPINSERTOBJECT pointing to the dialog structure + * dwOption DWORD flag indicating the option just selected: + * IOF_SELECTCREATENEW or IOF_SELECTCREATEFROMFILE + * + * Return Value: + * BOOL TRUE if the option was already selected, FALSE otherwise. + */ + +BOOL FToggleObjectSource(HWND hDlg, LPINSERTOBJECT lpIO, DWORD dwOption) + { + BOOL fTemp; + UINT uTemp; + DWORD dwTemp; + int i; + + //Skip all of this if we're already selected. + if (lpIO->dwFlags & dwOption) + return TRUE; + + + // if we're switching from "from file" to "create new" and we've got + // an icon for "from file", then we need to save it so that we can + // show it if the user reselects "from file". + + if ( (IOF_SELECTCREATENEW == dwOption) && + (lpIO->dwFlags & IOF_CHECKDISPLAYASICON) ) + lpIO->hMetaPictFile = (HGLOBAL)SendDlgItemMessage(hDlg, ID_IO_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L); + + /* + * 1. Change the Display As Icon checked state to reflect the + * selection for this option, stored in the fAsIcon* flags. + */ + fTemp=(IOF_SELECTCREATENEW==dwOption) ? lpIO->fAsIconNew : lpIO->fAsIconFile; + + if (fTemp) + lpIO->dwFlags |=IOF_CHECKDISPLAYASICON; + else + lpIO->dwFlags &=~IOF_CHECKDISPLAYASICON; + + CheckDlgButton(hDlg, ID_IO_DISPLAYASICON + , (BOOL)(0L!=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON))); + + EnableWindow(GetDlgItem(hDlg, ID_IO_CHANGEICON), fTemp); + + /* + * 2. Display Icon: Enabled on Create New or on Create from File if + * there is a selected file. + */ + fTemp=(IOF_SELECTCREATENEW==dwOption) ? TRUE : lpIO->fFileSelected; + EnableWindow(GetDlgItem(hDlg, ID_IO_DISPLAYASICON), fTemp); + + //OK and Link follow the same enabling as Display As Icon. + EnableWindow(GetDlgItem(hDlg, IDOK), fTemp); + EnableWindow(GetDlgItem(hDlg, ID_IO_LINKFILE), fTemp); + + //3. Enable Browse... when Create from File is selected. + fTemp=(IOF_SELECTCREATENEW==dwOption); + EnableWindow(GetDlgItem(hDlg, ID_IO_FILE), !fTemp); + EnableWindow(GetDlgItem(hDlg, ID_IO_FILEDISPLAY), !fTemp); + + /* + * 4. Switch between Object Type listbox on Create New and + * file buttons on others. + */ + uTemp=(fTemp) ? SW_SHOWNORMAL : SW_HIDE; + StandardShowDlgItem(hDlg, ID_IO_OBJECTTYPELIST, uTemp); + StandardShowDlgItem(hDlg, ID_IO_OBJECTTYPETEXT, uTemp); + + uTemp=(fTemp) ? SW_HIDE : SW_SHOWNORMAL; + StandardShowDlgItem(hDlg, ID_IO_FILETEXT, uTemp); + StandardShowDlgItem(hDlg, ID_IO_FILETYPE, uTemp); + StandardShowDlgItem(hDlg, ID_IO_FILEDISPLAY, uTemp); + StandardShowDlgItem(hDlg, ID_IO_FILE, uTemp); + + //Link is always hidden if IOF_DISABLELINK is set. + if (IOF_DISABLELINK & lpIO->dwFlags) + uTemp=SW_HIDE; + + StandardShowDlgItem(hDlg, ID_IO_LINKFILE, uTemp); //last use of uTemp + + + //5. Clear out existing any flags selection and set the new one + dwTemp=IOF_SELECTCREATENEW | IOF_SELECTCREATEFROMFILE; + lpIO->dwFlags=(lpIO->dwFlags & ~dwTemp) | dwOption; + + + /* + * Show or hide controls as appropriate. Do the icon + * display last because it will take some time to repaint. + * If we do it first then the dialog looks too sluggish. + */ + + i=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON) ? SW_SHOWNORMAL : SW_HIDE; + StandardShowDlgItem(hDlg, ID_IO_CHANGEICON, i); + StandardShowDlgItem(hDlg, ID_IO_ICONDISPLAY, i); + + + //6.Change result display + SetInsertObjectResults(hDlg, lpIO); + + /* + * 7. For Create New, twiddle the listbox to think we selected it + * so it updates the icon from the object type. set the focus + * to the list box. + * + * For Insert or Link file, set the focus to the filename button + * and update the icon if necessary. + */ + if (fTemp) { + UpdateClassIcon(hDlg, lpIO, GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST)); + SetFocus(GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST)); + } + else + { + if (lpIO->fAsIconFile && (NULL != lpIO->hMetaPictFile) ) + { + SendDlgItemMessage(hDlg, ID_IO_ICONDISPLAY, IBXM_IMAGESET, (WPARAM)lpIO->hMetaPictFile, 0L); + lpIO->hMetaPictFile = 0; + } + else + UpdateClassIcon(hDlg, lpIO, NULL); + + SetFocus(GetDlgItem(hDlg, ID_IO_FILE)); + } + + return FALSE; + } + + +/* + * UpdateClassType + * + * Purpose: + * Updates static text control to reflect current file type. Assumes + * a valid filename. + * + * Parameters + * hDlg HWND of the dialog box. + * lpIO LPINSERTOBJECT pointing to the dialog structure + * fSet TRUE to set the text, FALSE to explicitly clear it + * + * Return Value: + * None + */ + +void UpdateClassType(HWND hDlg, LPINSERTOBJECT lpIO, BOOL fSet) +{ + + CLSID clsid; + TCHAR szFileName[OLEUI_CCHPATHMAX]; + TCHAR szFileType[OLEUI_CCHLABELMAX]; + + *szFileType = TEXT('\0'); + + if (fSet) + { + GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, (LPTSTR)szFileName, OLEUI_CCHPATHMAX); + + if (NOERROR == GetClassFileA(szFileName, &clsid) ) + OleStdGetUserTypeOfClass(&clsid, szFileType, OLEUI_CCHLABELMAX_SIZE, NULL); + + } + + SetDlgItemText(hDlg, ID_IO_FILETYPE, (LPTSTR)szFileType); + + return; +} + + +/* + * UpdateClassIcon + * + * Purpose: + * Handles LBN_SELCHANGE for the Object Type listbox. On a selection + * change, we extract an icon from the server handling the currently + * selected object type using the utility function HIconFromClass. + * Note that we depend on the behavior of FillClassList to stuff the + * object class after a tab in the listbox string that we hide from + * view (see WM_INITDIALOG). + * + * Parameters + * hDlg HWND of the dialog box. + * lpIO LPINSERTOBJECT pointing to the dialog structure + * hList HWND of the Object Type listbox. + * + * Return Value: + * None + */ + +void UpdateClassIcon(HWND hDlg, LPINSERTOBJECT lpIO, HWND hList) + { + UINT iSel; + DWORD cb; + LPMALLOC pIMalloc; + LPTSTR pszName, pszCLSID, pszTemp; + HGLOBAL hMetaPict; + + LRESULT dwRet; + + + //If Display as Icon is not selected, exit + if (!(lpIO->dwFlags & IOF_CHECKDISPLAYASICON)) + return; + + /* + * When we change object type selection, get the new icon for that + * type into our structure and update it in the display. We use the + * class in the listbox when Create New is selected or the association + * with the extension in Create From File. + */ + + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + iSel=(UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L); + + if (LB_ERR==(int)iSel) + return; + + //Check to see if we've already got the hMetaPict for this item + dwRet=SendMessage(hList, LB_GETITEMDATA, (WPARAM)iSel, 0L); + + hMetaPict=(HGLOBAL)(UINT)dwRet; + + if (hMetaPict) + { + //Yep, we've already got it, so just display it and return. + SendDlgItemMessage(hDlg, ID_IO_ICONDISPLAY, IBXM_IMAGESET, (WPARAM)hMetaPict, 0L); + return; + } + + iSel=(UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L); + + if (LB_ERR==(int)iSel) + return; + + //Allocate a string to hold the entire listbox string + cb=SendMessage(hList, LB_GETTEXTLEN, iSel, 0L); + } + else + cb=OLEUI_CCHPATHMAX_SIZE; + + if (NOERROR!=CoGetMalloc(MEMCTX_TASK, &pIMalloc)) + return; + + pszName=(LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, cb+1*sizeof(TCHAR) ); + + if (NULL==pszName) + { + pIMalloc->lpVtbl->Release(pIMalloc); + return; + } + + *pszName=0; + + //Get the clsid we want. + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + //Grab the classname string from the list + SendMessage(hList, LB_GETTEXT, iSel, (LONG)pszName); + + //Set pointer to CLSID (string) + pszCLSID=PointerToNthField(pszName, 2, TEXT('\t')); + + //Null terminate pszName string +#ifdef WIN32 + // AnsiPrev is obsolete in Win32 + pszTemp=CharPrev((LPCTSTR) pszName,(LPCTSTR) pszCLSID); +#else + pszTemp=AnsiPrev((LPCTSTR) pszName,(LPCTSTR) pszCLSID); +#endif + *pszTemp=TEXT('\0'); + CLSIDFromStringA(pszCLSID, &lpIO->clsid); + +#ifdef OLE201 + hMetaPict = GetIconOfClass(ghInst, &lpIO->clsid, NULL, TRUE); +#endif + } + + else + { + //Get the class from the filename + GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, pszName, OLEUI_CCHPATHMAX); + +#ifdef OLE201 + + hMetaPict = OleGetIconOfFileA(pszName, + lpIO->dwFlags & IOF_CHECKLINK ? TRUE : FALSE); + +#endif + + } + + //Replace the current display with this new one. + SendDlgItemMessage(hDlg, ID_IO_ICONDISPLAY, IBXM_IMAGESET, (WPARAM)hMetaPict, 0L); + + //Enable or disable "Change Icon" button depending on whether + //we've got a valid filename or not. + EnableWindow(GetDlgItem(hDlg, ID_IO_CHANGEICON), hMetaPict ? TRUE : FALSE); + + //Save the hMetaPict so that we won't have to re-create + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + SendMessage(hList, LB_SETITEMDATA, (WPARAM)iSel, hMetaPict); + + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszName); + pIMalloc->lpVtbl->Release(pIMalloc); + return; + } + + + + +/* + * SetInsertObjectResults + * + * Purpose: + * Centralizes setting of the Result and icon displays in the Insert Object + * dialog. Handles loading the appropriate string from the module's + * resources and setting the text, displaying the proper result picture, + * and showing the proper icon. + * + * Parameters: + * hDlg HWND of the dialog box so we can access controls. + * lpIO LPINSERTOBJECT in which we assume that the + * current radiobutton and Display as Icon selections + * are set. We use the state of those variables to + * determine which string we use. + * + * Return Value: + * None + */ + +void SetInsertObjectResults(HWND hDlg, LPINSERTOBJECT lpIO) + { + LPTSTR pszT, psz1, psz2, psz3, psz4, pszTemp; + UINT i, iString1, iString2, iImage, cch; + LPMALLOC pIMalloc; + BOOL fAsIcon; + + /* + * We need scratch memory for loading the stringtable string, loading + * the object type from the listbox, and constructing the final string. + * We therefore allocate three buffers as large as the maximum message + * length (512) plus the object type, guaranteeing that we have enough + * in all cases. + */ + i=(UINT)SendDlgItemMessage(hDlg, ID_IO_OBJECTTYPELIST, LB_GETCURSEL, 0, 0L); + cch=512+ + (UINT)SendDlgItemMessage(hDlg, ID_IO_OBJECTTYPELIST, LB_GETTEXTLEN, i, 0L); + + if (NOERROR!=CoGetMalloc(MEMCTX_TASK, &pIMalloc)) + return; + + pszTemp=(LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, (DWORD)(4*cch*sizeof(TCHAR))); + + if (NULL==pszTemp) + { + pIMalloc->lpVtbl->Release(pIMalloc); + return; + } + + psz1=pszTemp; + psz2=psz1+cch; + psz3=psz2+cch; + psz4=psz3+cch; + + fAsIcon=(0L!=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON)); + + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + iString1 = fAsIcon ? IDS_IORESULTNEWICON : IDS_IORESULTNEW; + iString2 = 0; + iImage = fAsIcon ? RESULTIMAGE_EMBEDICON : RESULTIMAGE_EMBED; + } + + if (lpIO->dwFlags & IOF_SELECTCREATEFROMFILE) + { + //Pay attention to Link checkbox + if (lpIO->dwFlags & IOF_CHECKLINK) + { + iString1 = fAsIcon ? IDS_IORESULTLINKFILEICON1 : IDS_IORESULTLINKFILE1; + iString2 = fAsIcon ? IDS_IORESULTLINKFILEICON2 : IDS_IORESULTLINKFILE2; + iImage =fAsIcon ? RESULTIMAGE_LINKICON : RESULTIMAGE_LINK; + } + else + { + iString1 = IDS_IORESULTFROMFILE1; + iString2 = fAsIcon ? IDS_IORESULTFROMFILEICON2 : IDS_IORESULTFROMFILE2; + iImage =fAsIcon ? RESULTIMAGE_EMBEDICON : RESULTIMAGE_EMBED; + } + } + + //Default is an empty string. + *psz1=0; + + if (0!=LoadString(ghInst, iString1, psz1, cch)) + { + + // Load second string, if necessary + if ( (0 != iString2) + && (0 != LoadString(ghInst, iString2, psz4, cch)) ) + { + lstrcat(psz1, psz4); // concatenate strings together. + } + + + + //In Create New, do the extra step of inserting the object type string + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + SendDlgItemMessage(hDlg, ID_IO_OBJECTTYPELIST, LB_GETTEXT + , i, (LONG)psz2); + + //Null terminate at any tab (before the classname) + pszT=psz2; + while (TEXT('\t')!=*pszT && 0!=*pszT) + pszT++; + *pszT=0; + + //Build the string and point psz1 to it. + wsprintf(psz3, psz1, psz2); + psz1=psz3; + } + } + + //If LoadString failed, we simply clear out the results (*psz1=0 above) + SetDlgItemText(hDlg, ID_IO_RESULTTEXT, psz1); + + //Go change the image and Presto! There you have it. + SendDlgItemMessage(hDlg, ID_IO_RESULTIMAGE, RIM_IMAGESET, iImage, 0L); + + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszTemp); + pIMalloc->lpVtbl->Release(pIMalloc); + return; + } + + + +/* + * FValidateInsertFile + * + * Purpose: + * Given a possibly partial pathname from the file edit control, + * attempt to locate the file and if found, store the full path + * in the edit control ID_IO_FILEDISPLAY. + * + * Parameters: + * hDlg HWND of the dialog box. + * fTellUser BOOL TRUE if function should tell user, FALSE if + * function should validate silently. + * + * Return Value: + * BOOL TRUE if the file is acceptable, FALSE otherwise. + */ + +BOOL FValidateInsertFile(HWND hDlg, BOOL fTellUser, UINT FAR* lpnErrCode) + { + OFSTRUCT of; + HFILE hFile; + TCHAR szFile[OLEUI_CCHPATHMAX]; + + *lpnErrCode = 0; + /* + * To validate we attempt OpenFile on the string. If OpenFile + * fails then we display an error. If not, OpenFile will store + * the complete path to that file in the OFSTRUCT which we can + * then stuff in the edit control. + */ + + if (0==GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, szFile, OLEUI_CCHPATHMAX)) + return FALSE; // #4569 : return FALSE when there is no text in ctl + + hFile=DoesFileExist(szFile, &of); + + // if file is currently open (ie. sharing violation) OleCreateFromFile + // and OleCreateLinkToFile can still succeed; do not consider it an + // error. + if (HFILE_ERROR==hFile && 0x0020/*sharing violation*/!=of.nErrCode) + { + *lpnErrCode = of.nErrCode; + if (fTellUser) + OpenFileError(hDlg, of.nErrCode, szFile); + return FALSE; + } + + //OFSTRUCT contains an OEM name, not ANSI as we need for the edit box. + OemToAnsi(of.szPathName, of.szPathName); + + SetDlgItemText(hDlg, ID_IO_FILEDISPLAY, of.szPathName); + return TRUE; + } + + +/* + * InsertObjectCleanup + * + * Purpose: + * Clears cached icon metafiles from those stored in the listbox. + * + * Parameters: + * hDlg HWND of the dialog. + * + * Return Value: + * None + */ + +void InsertObjectCleanup(HWND hDlg) + { + HWND hList; + UINT iItems; + HGLOBAL hMetaPict; + LRESULT dwRet; + UINT i; + + hList=GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST); + iItems=(UINT)SendMessage(hList, LB_GETCOUNT, 0, 0L); + + for (i=0; i < iItems; i++) + { + dwRet=SendMessage(hList, LB_GETITEMDATA, (WPARAM)i, 0L); + + //Cast of LRESULT to UINT to HGLOBAL portable to Win32. + hMetaPict=(HGLOBAL)(UINT)dwRet; + + if (hMetaPict) + OleUIMetafilePictIconFree(hMetaPict); + } + + return; + } |