DVTARGETDEVICE* AFXAPI _AfxOleCreateTargetDevice(LPDEVNAMES pDN, LPDEVMODE pDM) { USES_CONVERSION; DVTARGETDEVICE* ptd = NULL; DWORD dwDevNamesSize, dwDevModeSize, dwPtdSize; LPCTSTR lpszDriverName = DEVNAMEPART(pDN, wDriverOffset); LPCTSTR lpszDeviceName = DEVNAMEPART(pDN, wDeviceOffset); LPCTSTR lpszPortName = DEVNAMEPART(pDN, wOutputOffset); LPCOLESTR lpszDriverNameOle = T2COLE(lpszDriverName); LPCOLESTR lpszDeviceNameOle = T2COLE(lpszDeviceName); LPCOLESTR lpszPortNameOle = T2COLE(lpszPortName); int nDriverNameSize = (lpszDriverNameOle == NULL) ? 0 : (ocslen(lpszDriverNameOle)+1)*sizeof(OLECHAR); int nDeviceNameSize = (lpszDeviceNameOle == NULL) ? 0 : (ocslen(lpszDeviceNameOle)+1)*sizeof(OLECHAR); int nPortNameSize = (lpszPortNameOle == NULL) ? 0 : (ocslen(lpszPortNameOle)+1)*sizeof(OLECHAR); LPDEVMODEOLE lpDevModeOle = DEVMODET2OLE(pDM); dwDevNamesSize = nDriverNameSize + nDeviceNameSize + nPortNameSize; dwDevModeSize = (DWORD)(lpDevModeOle->dmSize + lpDevModeOle->dmDriverExtra); dwPtdSize = sizeof(DVTARGETDEVICE) + dwDevNamesSize + dwDevModeSize; if ((ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(dwPtdSize)) != NULL) { // copy in the info ptd->tdSize = (UINT)dwPtdSize; ptd->tdDriverNameOffset = sizeof(DVTARGETDEVICE); ocscpy((LPOLESTR)((BYTE*)ptd + ptd->tdDriverNameOffset), lpszDriverNameOle); ptd->tdDeviceNameOffset = (WORD)(ptd->tdDriverNameOffset + nDriverNameSize); ocscpy((LPOLESTR)((BYTE*)ptd + ptd->tdDeviceNameOffset), lpszDeviceNameOle); ptd->tdPortNameOffset = (WORD)(ptd->tdDeviceNameOffset + nDeviceNameSize); ocscpy((LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset), lpszPortNameOle); ptd->tdExtDevmodeOffset = (WORD)(ptd->tdPortNameOffset + nPortNameSize); memcpy((BYTE*)ptd + ptd->tdExtDevmodeOffset, lpDevModeOle, sizeof(DEVMODEOLE)+lpDevModeOle->dmDriverExtra); } return ptd; }
HRESULT RegisterTypeLib(HINSTANCE hInstTypeLib, LPCOLESTR lpszIndex) { CComBSTR bstrPath; CComPtr<ITypeLib> pTypeLib; HRESULT hr = LoadTypeLib(hInstTypeLib, lpszIndex, &bstrPath, &pTypeLib); if (SUCCEEDED(hr)) { OLECHAR szDir[MAX_PATH]; ocscpy_s(szDir, MAX_PATH,bstrPath); // If index is specified remove it from the path if (lpszIndex != NULL) { size_t nLenPath = ocslen(szDir); size_t nLenIndex = ocslen(lpszIndex); if (memcmp(szDir + nLenPath - nLenIndex, lpszIndex, nLenIndex) == 0) szDir[nLenPath - nLenIndex] = 0; } szDir[GetDirLen(szDir)] = 0; hr = ::RegisterTypeLib(pTypeLib, bstrPath, szDir); } return hr; }
HGLOBAL AFXAPI _AfxOleGetObjectDescriptorData( LPOLEOBJECT lpOleObj, LPCOLESTR lpszSrcOfCopy, DWORD dwDrawAspect, POINTL pointl, LPSIZEL lpSizelHim) { USES_CONVERSION; CLSID clsid; LPOLESTR lpszFullUserTypeName = NULL; LPMONIKER lpSrcMonikerOfCopy = NULL; HGLOBAL hObjDesc = NULL; IBindCtx *pbc = NULL; SCODE sc; SIZEL sizelHim; BOOL bFreeSrcOfCopy = FALSE; LPVIEWOBJECT2 lpViewObj2; LPOLELINK lpOleLink; BOOL fIsLink; TCHAR szLinkedTypeFmt[80]; LPCOLESTR lpszLinkedTypeFmt; LPOLESTR lpszBuf = NULL; DWORD dwStatus = 0; // query for IOleLink lpOleLink = QUERYINTERFACE(lpOleObj, IOleLink); fIsLink = lpOleLink != NULL; // query for IViewObject2 lpViewObj2 = QUERYINTERFACE(lpOleObj, IViewObject2); // Get CLSID sc = lpOleObj->GetUserClassID(&clsid); if (sc != S_OK) clsid = CLSID_NULL; // Get FullUserTypeName sc = lpOleObj->GetUserType(USERCLASSTYPE_FULL, &lpszFullUserTypeName); // if object is a link, then expand usertypename to be "Linked %s" if (fIsLink && lpszFullUserTypeName != NULL) { // Note: If this LoadString call fails, it is likely that // _AFX_NO_OLE_RESOURCES is defined in your .RC file. // To correct the situation remove the following line from your // resource script: // #define _AFX_NO_OLE_RESOURCES // This should be done using the Resource.Set Includes... command. VERIFY(AfxLoadString(AFX_IDS_PASTELINKEDTYPE, szLinkedTypeFmt)); lpszLinkedTypeFmt = T2COLE(szLinkedTypeFmt); lpszBuf = (LPOLESTR)CoTaskMemAlloc((ocslen(lpszFullUserTypeName) + ocslen(lpszLinkedTypeFmt) + 1) * sizeof(OLECHAR)); if (lpszBuf != NULL) { #ifdef OLE2ANSI sprintf(lpszBuf, lpszLinkedTypeFmt, lpszFullUserTypeName); #else swprintf(lpszBuf, lpszLinkedTypeFmt, lpszFullUserTypeName); #endif CoTaskMemFree(lpszFullUserTypeName); lpszFullUserTypeName = lpszBuf; } } // get source of copy if (fIsLink) { sc = lpOleLink->GetSourceDisplayName((LPOLESTR*)&lpszSrcOfCopy); bFreeSrcOfCopy = TRUE; } else if (lpszSrcOfCopy == NULL) { sc = lpOleObj->GetMoniker( OLEGETMONIKER_TEMPFORUSER, OLEWHICHMK_OBJFULL, &lpSrcMonikerOfCopy); if (sc == S_OK) { CreateBindCtx(0, &pbc); lpSrcMonikerOfCopy->GetDisplayName(pbc, NULL, (LPOLESTR*)&lpszSrcOfCopy); RELEASE(pbc); bFreeSrcOfCopy = TRUE; } } if (lpSizelHim) { // Use extents passed by the caller sizelHim = *lpSizelHim; } else if (lpViewObj2) { // Get the current extents from the object sc = lpViewObj2->GetExtent(dwDrawAspect, -1, NULL, (LPSIZEL)&sizelHim); if (sc != S_OK) sizelHim.cx = sizelHim.cy = 0; } else { sizelHim.cx = sizelHim.cy = 0; } // Get dwStatus sc = lpOleObj->GetMiscStatus(dwDrawAspect, &dwStatus); if (sc != S_OK) dwStatus = 0; // Get OBJECTDESCRIPTOR hObjDesc = _AfxOleGetObjectDescriptorData(clsid, dwDrawAspect, sizelHim, pointl, dwStatus, lpszFullUserTypeName, lpszSrcOfCopy); // Clean up CoTaskMemFree(lpszFullUserTypeName); if (bFreeSrcOfCopy) CoTaskMemFree((LPOLESTR)lpszSrcOfCopy); RELEASE(lpSrcMonikerOfCopy); RELEASE(lpOleLink); RELEASE(lpViewObj2); return hObjDesc; }
HGLOBAL AFXAPI _AfxOleGetObjectDescriptorData( CLSID clsid, DWORD dwDrawAspect, SIZEL sizel, POINTL pointl, DWORD dwStatus, LPCOLESTR lpszFullUserTypeName, LPCOLESTR lpszSrcOfCopy) { HGLOBAL hMem = NULL; LPOBJECTDESCRIPTOR lpOD; DWORD dwObjectDescSize, dwFullUserTypeNameLen, dwSrcOfCopyLen; // Get the length of Full User Type Name; Add 1 for the null terminator dwFullUserTypeNameLen = lpszFullUserTypeName ? ocslen(lpszFullUserTypeName)+1 : 0; // Get the Source of Copy string and it's length; // Add 1 for the null terminator if (lpszSrcOfCopy && lpszSrcOfCopy[0] != '\0') dwSrcOfCopyLen = ocslen(lpszSrcOfCopy)+1; else { // No src moniker so use user type name as source string. lpszSrcOfCopy = lpszFullUserTypeName; dwSrcOfCopyLen = dwFullUserTypeNameLen; } // Allocate space for OBJECTDESCRIPTOR and the additional string data dwObjectDescSize = sizeof(OBJECTDESCRIPTOR); hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, dwObjectDescSize + (dwFullUserTypeNameLen + dwSrcOfCopyLen) * sizeof(OLECHAR)); if (!hMem) return NULL; lpOD = (LPOBJECTDESCRIPTOR)GlobalLock(hMem); // Set the FullUserTypeName offset and copy the string if (lpszFullUserTypeName) { lpOD->dwFullUserTypeName = dwObjectDescSize; ocscpy((LPOLESTR)((LPBYTE)lpOD+lpOD->dwFullUserTypeName), lpszFullUserTypeName); } else lpOD->dwFullUserTypeName = 0; // zero offset indicates that string is not present // Set the SrcOfCopy offset and copy the string if (lpszSrcOfCopy) { lpOD->dwSrcOfCopy = dwObjectDescSize + dwFullUserTypeNameLen * sizeof(OLECHAR); ocscpy((LPOLESTR)((LPBYTE)lpOD+lpOD->dwSrcOfCopy), lpszSrcOfCopy); } else lpOD->dwSrcOfCopy = 0; // zero offset indicates that string is not present // Initialize the rest of the OBJECTDESCRIPTOR lpOD->cbSize = dwObjectDescSize + (dwFullUserTypeNameLen + dwSrcOfCopyLen) * sizeof(OLECHAR); lpOD->clsid = clsid; lpOD->dwDrawAspect = dwDrawAspect; lpOD->sizel = sizel; lpOD->pointl = pointl; lpOD->dwStatus = dwStatus; GlobalUnlock(hMem); return hMem; }
BOOL AFXAPI _AfxCopyStgMedium( CLIPFORMAT cfFormat, LPSTGMEDIUM lpDest, LPSTGMEDIUM lpSource) { if (lpDest->tymed == TYMED_NULL) { ASSERT(lpSource->tymed != TYMED_NULL); switch (lpSource->tymed) { case TYMED_ENHMF: case TYMED_HGLOBAL: ASSERT(sizeof(HGLOBAL) == sizeof(HENHMETAFILE)); lpDest->tymed = lpSource->tymed; lpDest->hGlobal = NULL; break; // fall through to CopyGlobalMemory case case TYMED_ISTREAM: lpDest->pstm = lpSource->pstm; lpDest->pstm->AddRef(); lpDest->tymed = TYMED_ISTREAM; return TRUE; case TYMED_ISTORAGE: lpDest->pstg = lpSource->pstg; lpDest->pstg->AddRef(); lpDest->tymed = TYMED_ISTORAGE; return TRUE; case TYMED_MFPICT: { // copy LPMETAFILEPICT struct + embedded HMETAFILE HGLOBAL hDest = _AfxCopyGlobalMemory(NULL, lpSource->hGlobal); if (hDest == NULL) return FALSE; LPMETAFILEPICT lpPict = (LPMETAFILEPICT)::GlobalLock(hDest); ASSERT(lpPict != NULL); lpPict->hMF = ::CopyMetaFile(lpPict->hMF, NULL); if (lpPict->hMF == NULL) { ::GlobalUnlock(hDest); ::GlobalFree(hDest); return FALSE; } ::GlobalUnlock(hDest); // fill STGMEDIUM struct lpDest->hGlobal = hDest; lpDest->tymed = TYMED_MFPICT; } return TRUE; case TYMED_GDI: lpDest->tymed = TYMED_GDI; lpDest->hGlobal = NULL; break; case TYMED_FILE: { USES_CONVERSION; lpDest->tymed = TYMED_FILE; ASSERT(lpSource->lpszFileName != NULL); UINT cbSrc = ocslen(lpSource->lpszFileName); LPOLESTR szFileName = (LPOLESTR)CoTaskMemAlloc(cbSrc*sizeof(OLECHAR)); lpDest->lpszFileName = szFileName; if (szFileName == NULL) return FALSE; memcpy(szFileName, lpSource->lpszFileName, (cbSrc+1)*sizeof(OLECHAR)); return TRUE; } // unable to create + copy other TYMEDs default: return FALSE; } } ASSERT(lpDest->tymed == lpSource->tymed); switch (lpSource->tymed) { case TYMED_HGLOBAL: { HGLOBAL hDest = _AfxCopyGlobalMemory(lpDest->hGlobal, lpSource->hGlobal); if (hDest == NULL) return FALSE; lpDest->hGlobal = hDest; } return TRUE; case TYMED_ISTREAM: { ASSERT(lpDest->pstm != NULL); ASSERT(lpSource->pstm != NULL); // get the size of the source stream STATSTG stat; if (lpSource->pstm->Stat(&stat, STATFLAG_NONAME) != S_OK) { // unable to get size of source stream return FALSE; } ASSERT(stat.pwcsName == NULL); // always seek to zero before copy LARGE_INTEGER zero = { 0, 0 }; lpDest->pstm->Seek(zero, STREAM_SEEK_SET, NULL); lpSource->pstm->Seek(zero, STREAM_SEEK_SET, NULL); // copy source to destination if (lpSource->pstm->CopyTo(lpDest->pstm, stat.cbSize, NULL, NULL) != NULL) { // copy from source to dest failed return FALSE; } // always seek to zero after copy lpDest->pstm->Seek(zero, STREAM_SEEK_SET, NULL); lpSource->pstm->Seek(zero, STREAM_SEEK_SET, NULL); } return TRUE; case TYMED_ISTORAGE: { ASSERT(lpDest->pstg != NULL); ASSERT(lpSource->pstg != NULL); // just copy source to destination if (lpSource->pstg->CopyTo(0, NULL, NULL, lpDest->pstg) != S_OK) return FALSE; } return TRUE; case TYMED_FILE: { USES_CONVERSION; ASSERT(lpSource->lpszFileName != NULL); ASSERT(lpDest->lpszFileName != NULL); return CopyFile(OLE2T(lpSource->lpszFileName), OLE2T(lpDest->lpszFileName), FALSE); } case TYMED_ENHMF: case TYMED_GDI: { ASSERT(sizeof(HGLOBAL) == sizeof(HENHMETAFILE)); // with TYMED_GDI cannot copy into existing HANDLE if (lpDest->hGlobal != NULL) return FALSE; // otherwise, use OleDuplicateData for the copy lpDest->hGlobal = OleDuplicateData(lpSource->hGlobal, cfFormat, 0); if (lpDest->hGlobal == NULL) return FALSE; } return TRUE; // other TYMEDs cannot be copied default: return FALSE; } }