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 }