/* * 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 #include #include #include #include #include #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; }