HRESULT UIIMEdit::GetNewStorage(LPSTORAGE* ppStg) { if (!ppStg) return E_INVALIDARG; *ppStg = NULL; // // We need to create a new storage for an object to occupy. We're going // to do this the easy way and just create a storage on an HGLOBAL and let // OLE do the management. When it comes to saving things we'll just let // the RichEdit control do the work. Keep in mind this is not efficient, // but this program is just for demonstration. // LPLOCKBYTES pLockBytes; HRESULT hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes); if (FAILED(hr)) return hr; hr = StgCreateDocfileOnILockBytes(pLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, ppStg); pLockBytes->Release(); return (hr); }
//获取信息 bool CImageDataObject::IntercalateReObject(REOBJECT & ReObject, IOleClientSite * pIOleClientSite) { //状态判断 ASSERT(m_StgMedium.hBitmap!=NULL); if (m_StgMedium.hBitmap==NULL) return false; //创建对象 if ((m_pIOleObject==NULL)||(m_pIStorage==NULL)) { try { //创建存储 LPLOCKBYTES lpLockBytes=NULL; CreateILockBytesOnHGlobal(NULL,TRUE,&lpLockBytes); StgCreateDocfileOnILockBytes(lpLockBytes,STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE,0,&m_pIStorage); //创建对象 OleCreateStaticFromData(this,IID_IOleObject,OLERENDER_FORMAT,&m_FormatEtc,NULL,m_pIStorage,(VOID * *)&m_pIOleObject); OleSetContainedObject(m_pIOleObject,TRUE); //对象效验 ASSERT((m_pIOleObject!=NULL)&&(m_pIStorage!=NULL)); if ((m_pIOleObject==NULL)||(m_pIStorage==NULL)) throw 0; } catch (...) { //释放对象 if (m_pIOleObject!=NULL) { m_pIOleObject->Release(); m_pIOleObject=NULL; } //释放对象 if (m_pIStorage!=NULL) { m_pIStorage->Release(); m_pIStorage=NULL; } return false; } } //设置变量 ZeroMemory(&ReObject,sizeof(ReObject)); //属性信息 ReObject.cbStruct=sizeof(ReObject); ReObject.cp=REO_CP_SELECTION; ReObject.dvaspect=DVASPECT_CONTENT; m_pIOleObject->GetUserClassID(&ReObject.clsid); //接口信息 ReObject.pstg=m_pIStorage; ReObject.poleobj=m_pIOleObject; ReObject.polesite=pIOleClientSite; return true; }
//--------------------------------------------------------------------------- HRESULT __stdcall TRichEditOleCallback::GetNewStorage(LPSTORAGE *lplpstg) { ILockBytes* pLockBytes; if(CreateILockBytesOnHGlobal(0, true, &pLockBytes))return E_OUTOFMEMORY; StgCreateDocfileOnILockBytes(pLockBytes, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE, 0, lplpstg); pLockBytes->Release(); return 0; }
static HRESULT create_storage(IStorage **stg) { HRESULT hr; ILockBytes *lock_bytes; hr = CreateILockBytesOnHGlobal(NULL, TRUE, &lock_bytes); if(SUCCEEDED(hr)) { hr = StgCreateDocfileOnILockBytes(lock_bytes, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, stg); ILockBytes_Release(lock_bytes); } return hr; }
// @pymethod <o PyILockBytes>|pythoncom|CreateILockBytesOnHGlobal|Creates an ILockBytes interface based on global memory PyObject *pythoncom_CreateILockBytesOnHGlobal(PyObject *self, PyObject *args) { PyObject *obhglobal=Py_None; HGLOBAL hglobal=NULL; BOOL bdelete=TRUE; ILockBytes *pILockBytes=NULL; if (!PyArg_ParseTuple(args, "|Ol:CreateILockBytesOnHGlobal", &obhglobal, // @pyparm <o PyHANDLE>|hGlobal|None|Global memory handle. If None, a new global memory object is allocated. &bdelete)) // @pyparm bool|DeleteOnRelease|True|Indicates if global memory should be freed when interface is released. return NULL; if (!PyWinObject_AsHANDLE(obhglobal, &hglobal)) return NULL; PY_INTERFACE_PRECALL; HRESULT hr = CreateILockBytesOnHGlobal(hglobal, bdelete, &pILockBytes); PY_INTERFACE_POSTCALL; if (FAILED(hr)) return PyCom_BuildPyException(hr); return PyCom_PyObjectFromIUnknown(pILockBytes, IID_ILockBytes, FALSE); }
// returns true on success, false on failure //bool InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap, HGLOBAL hGlobal) bool InsertBitmap(IRichEditOle* pRichEditOle, HENHMETAFILE hEmf) { SCODE sc; // Get the image data object // static const FORMATETC lc_format[] = { { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }//, // { CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, // { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }; STGMEDIUM lc_stgmed[] = { { TYMED_ENHMF, { (HBITMAP)hEmf }, 0 }//, // { TYMED_GDI, { hBitmap }, 0 }, // { TYMED_HGLOBAL, { (HBITMAP)hGlobal }, 0 } }; IDataObject *pods; CreateDataObject(lc_format, lc_stgmed, 1, &pods); // Get the RichEdit container site // IOleClientSite *pOleClientSite; pRichEditOle->GetClientSite(&pOleClientSite); // Initialize a Storage Object // LPLOCKBYTES lpLockBytes = NULL; sc = CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes); if (sc != S_OK) { pOleClientSite->Release(); return false; } IStorage *pStorage; sc = StgCreateDocfileOnILockBytes(lpLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage); if (sc != S_OK) { lpLockBytes->Release(); pOleClientSite->Release(); return false; } // The final ole object which will be inserted in the richedit control // IOleObject *pOleObject; sc = OleCreateStaticFromData(pods, IID_IOleObject, OLERENDER_FORMAT, (LPFORMATETC)lc_format, pOleClientSite, pStorage, (void **)&pOleObject); if (sc != S_OK) { pStorage->Release(); lpLockBytes->Release(); pOleClientSite->Release(); return false; } // all items are "contained" -- this makes our reference to this object // weak -- which is needed for links to embedding silent update. OleSetContainedObject(pOleObject, TRUE); // Now Add the object to the RichEdit // REOBJECT reobject = { 0 }; reobject.cbStruct = sizeof(REOBJECT); reobject.cp = REO_CP_SELECTION; reobject.dvaspect = DVASPECT_CONTENT; reobject.poleobj = pOleObject; reobject.polesite = pOleClientSite; reobject.pstg = pStorage; reobject.dwFlags = REO_BELOWBASELINE; sc = pOleObject->GetUserClassID(&reobject.clsid); if (sc != S_OK) { pOleObject->Release(); pStorage->Release(); lpLockBytes->Release(); pOleClientSite->Release(); return false; } // Insert the bitmap at the current location in the richedit control // sc = pRichEditOle->InsertObject(&reobject); // Release all unnecessary interfaces // pOleObject->Release(); pStorage->Release(); lpLockBytes->Release(); pOleClientSite->Release(); pods->Release(); return sc == S_OK; }
BOOL COleControl::GetPropsetData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium, REFCLSID fmtid) { ASSERT_VALID(this); ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE)); ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM))); BOOL bGetDataHere = (lpStgMedium->tymed != TYMED_NULL); // Allow IStream or IStorage as the storage medium. if (!(lpFormatEtc->tymed & (TYMED_ISTREAM|TYMED_ISTORAGE))) { TRACE0("Propset only supported for stream or storage.\n"); return FALSE; } LPSTORAGE lpStorage = NULL; LPSTREAM lpStream = NULL; if (lpFormatEtc->tymed & TYMED_ISTORAGE) { // Caller wants propset data in a storage object. if (bGetDataHere) { // Use the caller-supplied storage object. lpStorage = lpStgMedium->pstg; } else { // Create a storage object on a memory ILockBytes implementation. LPLOCKBYTES lpLockBytes = NULL; if (FAILED(CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes))) { TRACE0("CreateILockBytesOnHGlobal failed.\n"); return FALSE; } ASSERT_POINTER(lpLockBytes, ILockBytes); if (FAILED(StgCreateDocfileOnILockBytes(lpLockBytes, STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &lpStorage))) { TRACE0("StgCreateDocfileOnILockBytes failed.\n"); lpLockBytes->Release(); return FALSE; } // Docfile now has reference to ILockBytes, so release ours. lpLockBytes->Release(); } ASSERT_POINTER(lpStorage, IStorage); // Create a stream within the storage. if (FAILED(lpStorage->CreateStream(OLESTR("Contents"), STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, 0, &lpStream))) { TRACE0("IStorage::CreateStream failed.\n"); if (!bGetDataHere) lpStorage->Release(); return FALSE; } } else { // Caller wants propset data in a stream object. if (bGetDataHere) { // Use the caller-supplied stream object lpStream = lpStgMedium->pstm; } else { lpStream = _AfxCreateMemoryStream(); if (lpStream == NULL) return FALSE; } } ASSERT_POINTER(lpStream, IStream); // Create the property set. CLSID clsid; GetClassID(&clsid); CPropertySet pset(clsid); pset.SetOSVersion(MAKELONG(LOWORD(GetVersion()), OSTYPE)); CPropertySection* ppsec = pset.AddSection(fmtid); if (ppsec == NULL) { TRACE0("CPropertySet::AddSection failed.\n"); lpStream->Release(); lpStorage->Release(); return FALSE; } // Set the name, based on the ambient display name (from the container). ppsec->SetSectionName(AmbientDisplayName()); CPropsetPropExchange propx(*ppsec, lpStorage, FALSE); BOOL bPropExchange = FALSE; TRY { DoPropExchange(&propx); bPropExchange = TRUE; } END_TRY if (!bPropExchange) { TRACE0("DoPropExchange failed.\n"); lpStream->Release(); lpStorage->Release(); return FALSE; } // Store the property set in the stream. if (FAILED(pset.WriteToStream(lpStream))) { TRACE0("CPropertySet::WriteToStream failed.\n"); lpStream->Release(); lpStorage->Release(); return FALSE; } // Return the property set in the requested medium. if (lpFormatEtc->tymed & TYMED_ISTORAGE) { // Return as a storage object. ASSERT_POINTER(lpStorage, IStorage); lpStream->Release(); lpStgMedium->pstg = lpStorage; lpStgMedium->tymed = TYMED_ISTORAGE; lpStgMedium->pUnkForRelease = NULL; } else { // Return as a stream. ASSERT_POINTER(lpStream, IStream); lpStgMedium->pstm = lpStream; lpStgMedium->tymed = TYMED_ISTREAM; lpStgMedium->pUnkForRelease = NULL; } return TRUE; }
LPLOCKBYTES ReadFileIntoMemory(const std::wstring& fileName) { HRESULT hr = S_OK; HANDLE file = INVALID_HANDLE_VALUE; file = ::CreateFileW(fileName.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(INVALID_HANDLE_VALUE == file) { DWORD lastError = GetLastError(); std::tostringstream msg; msg << _T("Failed to open [") << fileName << _T("] for reading its contents into memory, so we may read its custom properties") << std::ends; throw Workshare::System::SystemException(msg.str().c_str(), lastError); } try { unsigned long size = ::GetFileSize(file, NULL); HGLOBAL memory = GlobalAlloc(GPTR, size); if(NULL == memory) { DWORD lastError = GetLastError(); std::tostringstream msg; msg << _T("Failed to allocate ") << size << _T(" bytes of memory for reading [") << fileName << _T("] into memory, so we may read its custom properties") << std::ends; throw Workshare::System::SystemException(msg.str().c_str(), lastError); } try { DWORD numberOfBytesRead = 0; BOOL ok = ::ReadFile(file, memory, size, &numberOfBytesRead, NULL); if(!ok) { DWORD lastError = GetLastError(); std::tostringstream msg; msg << _T("Failed to read ") << size << _T(" bytes from [") << fileName << _T("] into a buffer that is ") << size << _T(" big, so we may read its custom properties") << std::ends; throw Workshare::System::SystemException(msg.str().c_str(), lastError); } if(size != numberOfBytesRead) { std::tostringstream msg; msg << _T("Failed to read all the ") << size << _T(" bytes from [") << fileName << _T("] into a buffer that is ") << size << _T(" big, so we may read its custom properties. Only ") << numberOfBytesRead << _T(" was read") << std::ends; throw Workshare::System::IO::IOException(msg.str().c_str()); } LPLOCKBYTES lpBytes = NULL; hr = CreateILockBytesOnHGlobal(memory, TRUE, &lpBytes); if(FAILED(hr)) { std::tostringstream msg; msg << _T("Failed to create an instance of ILockBytes from memory ") << size << _T(" bytes from [") << fileName << _T("] into a buffer that is ") << size << _T(" big, so we may read its custom properties. Only ") << numberOfBytesRead << _T(" was read") << std::ends; throw Workshare::System::IO::IOException(msg.str().c_str()); } CloseHandle(file); return lpBytes; } catch(...) { GlobalFree(memory); throw; } } catch(...) { CloseHandle(file); throw; } }
// Does: Saves The Picture That Is Stored In The IPicture Object As a Bitmap // ~~~~ (Converts From Any Known Picture Type To a Bitmap / Icon File) // // InPut: sFilePathName - Path And FileName Target To Save // ~~~~~ // // OutPut: TRUE If Succeeded... // ~~~~~~ //----------------------------------------------------------------------------- BOOL CPicture_Ex::SaveAsBitmap(CString sFilePathName) //============================================================================= { BOOL bResult = FALSE; ILockBytes *Buffer = 0; IStorage *pStorage = 0; IStream *FileStream = 0; BYTE *BufferBytes; STATSTG BytesStatistics; DWORD OutData; long OutStream; CFile BitmapFile; CFileException e; double SkipFloat = 0; DWORD ByteSkip = 0; _ULARGE_INTEGER RealData; CreateILockBytesOnHGlobal(NULL, TRUE, &Buffer); // Create ILockBytes Buffer HRESULT hr = ::StgCreateDocfileOnILockBytes(Buffer, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage); hr = pStorage->CreateStream(L"PICTURE", STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, 0, &FileStream); m_pPict->SaveAsFile(FileStream, TRUE, &OutStream); // Copy Data Stream FileStream->Release(); pStorage->Release(); Buffer->Flush(); // Get Statistics For Final Size Of Byte Array Buffer->Stat(&BytesStatistics, STATFLAG_NONAME); // Cut UnNeeded Data Coming From SaveAsFile() (Leave Only "Pure" Picture Data) SkipFloat = (double(OutStream) / 512); // Must Be In a 512 Blocks... if(SkipFloat > DWORD(SkipFloat)) ByteSkip = (DWORD)SkipFloat + 1; else ByteSkip = (DWORD)SkipFloat; ByteSkip = ByteSkip * 512; // Must Be In a 512 Blocks... // Find Difference Between The Two Values ByteSkip = (DWORD)(BytesStatistics.cbSize.QuadPart - ByteSkip); // Allocate Only The "Pure" Picture Data RealData.LowPart = 0; RealData.HighPart = 0; RealData.QuadPart = ByteSkip; BufferBytes = (BYTE*)malloc(OutStream); if(BufferBytes == NULL) { Buffer->Release(); HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd; MessageBoxEx(hWnd, "Can not allocate enough memory\t", "ERROR"/*ERROR_TITLE*/, MB_OK | MB_ICONSTOP, LANG_ENGLISH); } Buffer->ReadAt(RealData, BufferBytes, OutStream, &OutData); if(BitmapFile.Open(sFilePathName, CFile::typeBinary | CFile::modeCreate | CFile::modeWrite, &e)) { BitmapFile.Write(BufferBytes, OutData); BitmapFile.Close(); bResult = TRUE; } else // Write File Failed... { TCHAR szCause[255]; e.GetErrorMessage(szCause, 255, NULL); HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd; MessageBoxEx(hWnd, szCause, "ERROR"/*ERROR_TITLE*/, MB_OK | MB_ICONSTOP, LANG_ENGLISH); bResult = FALSE; } Buffer->Release(); free(BufferBytes); return(bResult); }