Mercurial > foo_out_sdl
diff foosdk/sdk/libPPUI/IDataObjectUtils.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/libPPUI/IDataObjectUtils.cpp Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,187 @@ +#include "stdafx.h" + +#include "IDataObjectUtils.h" + +HRESULT IDataObjectUtils::DataBlockToSTGMEDIUM(const void * blockPtr, t_size blockSize, STGMEDIUM * medium, DWORD tymed, bool bHere) throw() { + try { + if (bHere) { + switch(tymed) { + case TYMED_ISTREAM: + { + if (medium->pstm == NULL) return E_INVALIDARG; + ULONG written = 0; + HRESULT state; + state = medium->pstm->Write(blockPtr, pfc::downcast_guarded<ULONG>(blockSize),&written); + if (FAILED(state)) return state; + if (written != blockSize) return STG_E_MEDIUMFULL; + return S_OK; + } + default: + return DV_E_TYMED; + } + } else { + if (tymed & TYMED_HGLOBAL) { + HGLOBAL hMem = HGlobalFromMemblock(blockPtr, blockSize); + if (hMem == NULL) return E_OUTOFMEMORY; + medium->tymed = TYMED_HGLOBAL; + medium->hGlobal = hMem; + medium->pUnkForRelease = NULL; + return S_OK; + } + if (tymed & TYMED_ISTREAM) { + HRESULT state; + HGLOBAL hMem = HGlobalFromMemblock(blockPtr, blockSize); + if (hMem == NULL) return E_OUTOFMEMORY; + medium->tymed = TYMED_ISTREAM; + pfc::com_ptr_t<IStream> stream; + if (FAILED( state = CreateStreamOnHGlobal(hMem,TRUE,stream.receive_ptr()) ) ) { + GlobalFree(hMem); + return state; + } + { + LARGE_INTEGER wtf = {}; + if (FAILED( state = stream->Seek(wtf,STREAM_SEEK_END,NULL) ) ) { + return state; + } + } + medium->pstm = stream.detach(); + medium->pUnkForRelease = NULL; + return S_OK; + } + return DV_E_TYMED; + } + } catch(pfc::exception_not_implemented const &) { + return E_NOTIMPL; + } catch(std::bad_alloc const &) { + return E_OUTOFMEMORY; + } catch(...) { + return E_UNEXPECTED; + } +} + + +HGLOBAL IDataObjectUtils::HGlobalFromMemblock(const void * ptr,t_size size) { + HGLOBAL handle = GlobalAlloc(GMEM_MOVEABLE,size); + if (handle != NULL) { + void * destptr = GlobalLock(handle); + if (destptr == NULL) { + GlobalFree(handle); + handle = NULL; + } else { + memcpy(destptr,ptr,size); + GlobalUnlock(handle); + } + } + return handle; +} + +HRESULT IDataObjectUtils::ExtractDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index, pfc::array_t<t_uint8> & out) { + FORMATETC fmt = {}; + fmt.cfFormat = (CLIPFORMAT)format; fmt.dwAspect = aspect; fmt.lindex = index; + fmt.tymed = TYMED_HGLOBAL /* | TYMED_ISTREAM*/; + + STGMEDIUM med = {}; + HRESULT state; + if (FAILED( state = obj->GetData(&fmt,&med) ) ) return state; + ReleaseStgMediumScope relScope(&med); + return STGMEDIUMToDataBlock(med, out); +} + +HRESULT IDataObjectUtils::STGMEDIUMToDataBlock(const STGMEDIUM & med, pfc::array_t<t_uint8> & out) { + switch(med.tymed) { + case TYMED_HGLOBAL: + { + CGlobalLockScope lock(med.hGlobal); + out.set_data_fromptr( (const t_uint8*) lock.GetPtr(), lock.GetSize() ); + } + return S_OK; + case TYMED_ISTREAM: + { + HRESULT state; + IStream * stream = med.pstm; + LARGE_INTEGER offset = {}; + STATSTG stats = {}; + if (FAILED( state = stream->Stat(&stats,STATFLAG_NONAME ) ) ) return state; + t_size toRead = pfc::downcast_guarded<t_size>(stats.cbSize.QuadPart); + out.set_size(toRead); + if (FAILED( state = stream->Seek(offset,STREAM_SEEK_SET,NULL) ) ) return state; + ULONG cbRead = 0; + if (FAILED( state = stream->Read(out.get_ptr(), pfc::downcast_guarded<ULONG>(toRead), &cbRead) ) ) return state; + if (cbRead != toRead) return E_UNEXPECTED; + } + return S_OK; + default: + return DV_E_TYMED; + } +} + +HRESULT IDataObjectUtils::ExtractDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, pfc::array_t<t_uint8> & out) { + return ExtractDataObjectContent(obj, format, DVASPECT_CONTENT, -1, out); +} + +HRESULT IDataObjectUtils::ExtractDataObjectContentTest(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index) { + FORMATETC fmt = {}; + fmt.cfFormat = (CLIPFORMAT)format; fmt.dwAspect = aspect; fmt.lindex = index; + for(t_uint32 walk = 0; walk < 32; ++walk) { + const DWORD tymed = 1 << walk; + if ((ExtractDataObjectContent_SupportedTymeds & tymed) != 0) { + fmt.tymed = tymed; + HRESULT state = obj->QueryGetData(&fmt); + if (SUCCEEDED(state)) { + if (state == S_OK) return S_OK; + } else { + if (state != DV_E_TYMED) return state; + } + } + } + return E_FAIL; +} + +HRESULT IDataObjectUtils::ExtractDataObjectContentTest(pfc::com_ptr_t<IDataObject> obj, UINT format) { + return ExtractDataObjectContentTest(obj,format,DVASPECT_CONTENT,-1); +} + +HRESULT IDataObjectUtils::ExtractDataObjectString(pfc::com_ptr_t<IDataObject> obj, pfc::string_base & out) { + pfc::array_t<t_uint8> data; + HRESULT state; + state = ExtractDataObjectContent(obj,CF_UNICODETEXT,data); + if (SUCCEEDED(state)) { + out = pfc::stringcvt::string_utf8_from_os_ex( (const wchar_t*) data.get_ptr(), data.get_size() / sizeof(wchar_t) ); + return S_OK; + } + state = ExtractDataObjectContent(obj,CF_TEXT,data); + if (SUCCEEDED(state)) { + out = pfc::stringcvt::string_utf8_from_os_ex( (const char*) data.get_ptr(), data.get_size() / sizeof(char) ); + return S_OK; + } + return E_FAIL; +} + +HRESULT IDataObjectUtils::SetDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index, const void * data, t_size dataSize) { + STGMEDIUM med = {}; + FORMATETC fmt = {}; + fmt.cfFormat = (CLIPFORMAT)format; fmt.dwAspect = aspect; fmt.lindex = index; fmt.tymed = TYMED_HGLOBAL; + HRESULT state; + if (FAILED(state = DataBlockToSTGMEDIUM(data,dataSize,&med,TYMED_HGLOBAL,false))) return state; + return obj->SetData(&fmt,&med,TRUE); +} + +HRESULT IDataObjectUtils::SetDataObjectString(pfc::com_ptr_t<IDataObject> obj, const char * str) { + pfc::stringcvt::string_wide_from_utf8 s(str); + return SetDataObjectContent(obj,CF_UNICODETEXT,DVASPECT_CONTENT,-1,s.get_ptr(), (s.length()+1) * sizeof(s[0])); +} + +HRESULT IDataObjectUtils::ExtractDataObjectDWORD(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD & val) { + HRESULT state; + pfc::array_t<t_uint8> buffer; + if (FAILED( state = ExtractDataObjectContent(obj, format, DVASPECT_CONTENT, -1, buffer) ) ) return state; + if (buffer.get_size() < sizeof(val)) return E_UNEXPECTED; + val = *(DWORD*) buffer.get_ptr(); + return S_OK; +} +HRESULT IDataObjectUtils::SetDataObjectDWORD(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD val) { + return SetDataObjectContent(obj,format,DVASPECT_CONTENT,-1,&val,sizeof(val)); +} +HRESULT IDataObjectUtils::PasteSucceeded(pfc::com_ptr_t<IDataObject> obj, DWORD effect) { + return SetDataObjectDWORD(obj, RegisterClipboardFormat(CFSTR_PASTESUCCEEDED), effect); +}
