Mercurial > foo_out_sdl
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #include "stdafx.h" | |
| 2 | |
| 3 #include "IDataObjectUtils.h" | |
| 4 | |
| 5 HRESULT IDataObjectUtils::DataBlockToSTGMEDIUM(const void * blockPtr, t_size blockSize, STGMEDIUM * medium, DWORD tymed, bool bHere) throw() { | |
| 6 try { | |
| 7 if (bHere) { | |
| 8 switch(tymed) { | |
| 9 case TYMED_ISTREAM: | |
| 10 { | |
| 11 if (medium->pstm == NULL) return E_INVALIDARG; | |
| 12 ULONG written = 0; | |
| 13 HRESULT state; | |
| 14 state = medium->pstm->Write(blockPtr, pfc::downcast_guarded<ULONG>(blockSize),&written); | |
| 15 if (FAILED(state)) return state; | |
| 16 if (written != blockSize) return STG_E_MEDIUMFULL; | |
| 17 return S_OK; | |
| 18 } | |
| 19 default: | |
| 20 return DV_E_TYMED; | |
| 21 } | |
| 22 } else { | |
| 23 if (tymed & TYMED_HGLOBAL) { | |
| 24 HGLOBAL hMem = HGlobalFromMemblock(blockPtr, blockSize); | |
| 25 if (hMem == NULL) return E_OUTOFMEMORY; | |
| 26 medium->tymed = TYMED_HGLOBAL; | |
| 27 medium->hGlobal = hMem; | |
| 28 medium->pUnkForRelease = NULL; | |
| 29 return S_OK; | |
| 30 } | |
| 31 if (tymed & TYMED_ISTREAM) { | |
| 32 HRESULT state; | |
| 33 HGLOBAL hMem = HGlobalFromMemblock(blockPtr, blockSize); | |
| 34 if (hMem == NULL) return E_OUTOFMEMORY; | |
| 35 medium->tymed = TYMED_ISTREAM; | |
| 36 pfc::com_ptr_t<IStream> stream; | |
| 37 if (FAILED( state = CreateStreamOnHGlobal(hMem,TRUE,stream.receive_ptr()) ) ) { | |
| 38 GlobalFree(hMem); | |
| 39 return state; | |
| 40 } | |
| 41 { | |
| 42 LARGE_INTEGER wtf = {}; | |
| 43 if (FAILED( state = stream->Seek(wtf,STREAM_SEEK_END,NULL) ) ) { | |
| 44 return state; | |
| 45 } | |
| 46 } | |
| 47 medium->pstm = stream.detach(); | |
| 48 medium->pUnkForRelease = NULL; | |
| 49 return S_OK; | |
| 50 } | |
| 51 return DV_E_TYMED; | |
| 52 } | |
| 53 } catch(pfc::exception_not_implemented const &) { | |
| 54 return E_NOTIMPL; | |
| 55 } catch(std::bad_alloc const &) { | |
| 56 return E_OUTOFMEMORY; | |
| 57 } catch(...) { | |
| 58 return E_UNEXPECTED; | |
| 59 } | |
| 60 } | |
| 61 | |
| 62 | |
| 63 HGLOBAL IDataObjectUtils::HGlobalFromMemblock(const void * ptr,t_size size) { | |
| 64 HGLOBAL handle = GlobalAlloc(GMEM_MOVEABLE,size); | |
| 65 if (handle != NULL) { | |
| 66 void * destptr = GlobalLock(handle); | |
| 67 if (destptr == NULL) { | |
| 68 GlobalFree(handle); | |
| 69 handle = NULL; | |
| 70 } else { | |
| 71 memcpy(destptr,ptr,size); | |
| 72 GlobalUnlock(handle); | |
| 73 } | |
| 74 } | |
| 75 return handle; | |
| 76 } | |
| 77 | |
| 78 HRESULT IDataObjectUtils::ExtractDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index, pfc::array_t<t_uint8> & out) { | |
| 79 FORMATETC fmt = {}; | |
| 80 fmt.cfFormat = (CLIPFORMAT)format; fmt.dwAspect = aspect; fmt.lindex = index; | |
| 81 fmt.tymed = TYMED_HGLOBAL /* | TYMED_ISTREAM*/; | |
| 82 | |
| 83 STGMEDIUM med = {}; | |
| 84 HRESULT state; | |
| 85 if (FAILED( state = obj->GetData(&fmt,&med) ) ) return state; | |
| 86 ReleaseStgMediumScope relScope(&med); | |
| 87 return STGMEDIUMToDataBlock(med, out); | |
| 88 } | |
| 89 | |
| 90 HRESULT IDataObjectUtils::STGMEDIUMToDataBlock(const STGMEDIUM & med, pfc::array_t<t_uint8> & out) { | |
| 91 switch(med.tymed) { | |
| 92 case TYMED_HGLOBAL: | |
| 93 { | |
| 94 CGlobalLockScope lock(med.hGlobal); | |
| 95 out.set_data_fromptr( (const t_uint8*) lock.GetPtr(), lock.GetSize() ); | |
| 96 } | |
| 97 return S_OK; | |
| 98 case TYMED_ISTREAM: | |
| 99 { | |
| 100 HRESULT state; | |
| 101 IStream * stream = med.pstm; | |
| 102 LARGE_INTEGER offset = {}; | |
| 103 STATSTG stats = {}; | |
| 104 if (FAILED( state = stream->Stat(&stats,STATFLAG_NONAME ) ) ) return state; | |
| 105 t_size toRead = pfc::downcast_guarded<t_size>(stats.cbSize.QuadPart); | |
| 106 out.set_size(toRead); | |
| 107 if (FAILED( state = stream->Seek(offset,STREAM_SEEK_SET,NULL) ) ) return state; | |
| 108 ULONG cbRead = 0; | |
| 109 if (FAILED( state = stream->Read(out.get_ptr(), pfc::downcast_guarded<ULONG>(toRead), &cbRead) ) ) return state; | |
| 110 if (cbRead != toRead) return E_UNEXPECTED; | |
| 111 } | |
| 112 return S_OK; | |
| 113 default: | |
| 114 return DV_E_TYMED; | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 HRESULT IDataObjectUtils::ExtractDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, pfc::array_t<t_uint8> & out) { | |
| 119 return ExtractDataObjectContent(obj, format, DVASPECT_CONTENT, -1, out); | |
| 120 } | |
| 121 | |
| 122 HRESULT IDataObjectUtils::ExtractDataObjectContentTest(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index) { | |
| 123 FORMATETC fmt = {}; | |
| 124 fmt.cfFormat = (CLIPFORMAT)format; fmt.dwAspect = aspect; fmt.lindex = index; | |
| 125 for(t_uint32 walk = 0; walk < 32; ++walk) { | |
| 126 const DWORD tymed = 1 << walk; | |
| 127 if ((ExtractDataObjectContent_SupportedTymeds & tymed) != 0) { | |
| 128 fmt.tymed = tymed; | |
| 129 HRESULT state = obj->QueryGetData(&fmt); | |
| 130 if (SUCCEEDED(state)) { | |
| 131 if (state == S_OK) return S_OK; | |
| 132 } else { | |
| 133 if (state != DV_E_TYMED) return state; | |
| 134 } | |
| 135 } | |
| 136 } | |
| 137 return E_FAIL; | |
| 138 } | |
| 139 | |
| 140 HRESULT IDataObjectUtils::ExtractDataObjectContentTest(pfc::com_ptr_t<IDataObject> obj, UINT format) { | |
| 141 return ExtractDataObjectContentTest(obj,format,DVASPECT_CONTENT,-1); | |
| 142 } | |
| 143 | |
| 144 HRESULT IDataObjectUtils::ExtractDataObjectString(pfc::com_ptr_t<IDataObject> obj, pfc::string_base & out) { | |
| 145 pfc::array_t<t_uint8> data; | |
| 146 HRESULT state; | |
| 147 state = ExtractDataObjectContent(obj,CF_UNICODETEXT,data); | |
| 148 if (SUCCEEDED(state)) { | |
| 149 out = pfc::stringcvt::string_utf8_from_os_ex( (const wchar_t*) data.get_ptr(), data.get_size() / sizeof(wchar_t) ); | |
| 150 return S_OK; | |
| 151 } | |
| 152 state = ExtractDataObjectContent(obj,CF_TEXT,data); | |
| 153 if (SUCCEEDED(state)) { | |
| 154 out = pfc::stringcvt::string_utf8_from_os_ex( (const char*) data.get_ptr(), data.get_size() / sizeof(char) ); | |
| 155 return S_OK; | |
| 156 } | |
| 157 return E_FAIL; | |
| 158 } | |
| 159 | |
| 160 HRESULT IDataObjectUtils::SetDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index, const void * data, t_size dataSize) { | |
| 161 STGMEDIUM med = {}; | |
| 162 FORMATETC fmt = {}; | |
| 163 fmt.cfFormat = (CLIPFORMAT)format; fmt.dwAspect = aspect; fmt.lindex = index; fmt.tymed = TYMED_HGLOBAL; | |
| 164 HRESULT state; | |
| 165 if (FAILED(state = DataBlockToSTGMEDIUM(data,dataSize,&med,TYMED_HGLOBAL,false))) return state; | |
| 166 return obj->SetData(&fmt,&med,TRUE); | |
| 167 } | |
| 168 | |
| 169 HRESULT IDataObjectUtils::SetDataObjectString(pfc::com_ptr_t<IDataObject> obj, const char * str) { | |
| 170 pfc::stringcvt::string_wide_from_utf8 s(str); | |
| 171 return SetDataObjectContent(obj,CF_UNICODETEXT,DVASPECT_CONTENT,-1,s.get_ptr(), (s.length()+1) * sizeof(s[0])); | |
| 172 } | |
| 173 | |
| 174 HRESULT IDataObjectUtils::ExtractDataObjectDWORD(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD & val) { | |
| 175 HRESULT state; | |
| 176 pfc::array_t<t_uint8> buffer; | |
| 177 if (FAILED( state = ExtractDataObjectContent(obj, format, DVASPECT_CONTENT, -1, buffer) ) ) return state; | |
| 178 if (buffer.get_size() < sizeof(val)) return E_UNEXPECTED; | |
| 179 val = *(DWORD*) buffer.get_ptr(); | |
| 180 return S_OK; | |
| 181 } | |
| 182 HRESULT IDataObjectUtils::SetDataObjectDWORD(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD val) { | |
| 183 return SetDataObjectContent(obj,format,DVASPECT_CONTENT,-1,&val,sizeof(val)); | |
| 184 } | |
| 185 HRESULT IDataObjectUtils::PasteSucceeded(pfc::com_ptr_t<IDataObject> obj, DWORD effect) { | |
| 186 return SetDataObjectDWORD(obj, RegisterClipboardFormat(CFSTR_PASTESUCCEEDED), effect); | |
| 187 } |
