1
2
3
4
5
6 using System;
7 using System.Windows.API;
8
9 namespace System.Windows
10 {
11 public class ClipboardFormat : GraphicsObject
12 {
13 public enum Format : uint
14 {
15 text = 1u, unicodeText = 13u
16 }
17 public ClipboardFormat(Format format) : formatName(), formatNumber(format)
18 {
19 }
20 public ClipboardFormat(const string& formatName_) : formatName(formatName_), formatNumber(0u)
21 {
22 auto registerResult = RegisterClipboardFormat(formatName.Chars());
23 if (registerResult.Error())
24 {
25 SetErrorId(registerResult.GetErrorId());
26 }
27 formatNumber = registerResult.Value();
28 }
29 public inline uint Number() const
30 {
31 return formatNumber;
32 }
33 private string formatName;
34 private uint formatNumber;
35 }
36
37 public class MemoryHandle : GraphicsObject
38 {
39 public MemoryHandle() : base(), handle(null)
40 {
41 }
42 public MemoryHandle(void* handle_) : base(), handle(handle_), memory(null)
43 {
44 auto result = GlobalLock(handle);
45 if (result.Error())
46 {
47 SetErrorId(result.GetErrorId());
48 }
49 memory = result.Value();
50 }
51 suppress MemoryHandle(const MemoryHandle&);
52 suppress void operator=(const MemoryHandle&);
53 public MemoryHandle(MemoryHandle&& that) : handle(that.handle)
54 {
55 that.handle = null;
56 }
57 public default void operator=(MemoryHandle&&);
58 public ~MemoryHandle()
59 {
60 if (handle != null)
61 {
62 auto result = GlobalUnlock(handle);
63 }
64 }
65 public static Result<MemoryHandle> AllocateMemory(ulong size)
66 {
67 auto result = GlobalAlloc(GlobalAllocFlags.GHND, size);
68 if (result.Error())
69 {
70 return Result<MemoryHandle>(ErrorId(result.GetErrorId()));
71 }
72 MemoryHandle memoryHandle(result.Value());
73 if (memoryHandle.Error())
74 {
75 return Result<MemoryHandle>(ErrorId(memoryHandle.GetErrorId()));
76 }
77 return Result<MemoryHandle>(Rvalue(memoryHandle));
78 }
79 public void* Memory() const
80 {
81 return memory;
82 }
83 [nodiscard]
84 public Result<ulong> Size() const
85 {
86 return GlobalSize(handle);
87 }
88 public void* Handle() const
89 {
90 return handle;
91 }
92 private void* handle;
93 private void* memory;
94 }
95
96 public class ClipboardListener : GraphicsObject
97 {
98 public ClipboardListener(void* windowHandle_) : windowHandle(windowHandle_)
99 {
100 auto result = AddClipboardFormatListener(windowHandle);
101 if (result.Error())
102 {
103 SetErrorId(result.GetErrorId());
104 }
105 }
106 public ~ClipboardListener()
107 {
108 auto result = RemoveClipboardFormatListener(windowHandle);
109 }
110 private void* windowHandle;
111 }
112
113 public class Clipboard : GraphicsObject
114 {
115 public Clipboard(void* windowHandle_) : windowHandle(windowHandle_)
116 {
117 auto result = OpenClipboard(windowHandle);
118 if (result.Error())
119 {
120 SetErrorId(result.GetErrorId());
121 }
122 }
123 public ~Clipboard()
124 {
125 auto result = CloseClipboard();
126 }
127 public bool IsClipboardFormatAvailable(const ClipboardFormat& clipboardFormat) const
128 {
129 return IsClipboardFormatAvailable(clipboardFormat.Number());
130 }
131 [nodiscard]
132 public Result<bool> SetEmpty()
133 {
134 return EmptyClipboard();
135 }
136 [nodiscard]
137 public Result<MemoryHandle> GetData(const ClipboardFormat& clipboardFormat)
138 {
139 auto result = GetClipboardData(clipboardFormat.Number());
140 if (result.Error())
141 {
142 return Result<MemoryHandle>(ErrorId(result.GetErrorId()));
143 }
144 return Result<MemoryHandle>(MemoryHandle(result.Value()));
145 }
146 [nodiscard]
147 public Result<bool> SetData(const ClipboardFormat& clipboardFormat, const MemoryHandle& memoryHandle)
148 {
149 auto result = SetEmpty();
150 if (result.Error())
151 {
152 return Result<bool>(ErrorId(result.GetErrorId()));
153 }
154 auto setResult = SetClipboardData(clipboardFormat.Number(), memoryHandle.Handle());
155 if (setResult.Error())
156 {
157 return Result<bool>(ErrorId(setResult.GetErrorId()));
158 }
159 return Result<bool>(true);
160 }
161 [nodiscard]
162 public Result<ustring> GetStringData(const ClipboardFormat& clipboardFormat)
163 {
164 Result<MemoryHandle> memoryHandleResult = GetData(clipboardFormat);
165 if (memoryHandleResult.Error())
166 {
167 return Result<ustring>(ErrorId(memoryHandleResult.GetErrorId()));
168 }
169 MemoryHandle& memoryHandle = memoryHandleResult.Value();
170 Result<ulong> sizeResult = memoryHandle.Size();
171 if (sizeResult.Error())
172 {
173 return Result<ustring>(ErrorId(sizeResult.GetErrorId()));
174 }
175 ulong size = sizeResult.Value();
176 if (clipboardFormat.Number() == ClipboardFormat.Format.text)
177 {
178 UniquePtr<char> ptr(cast<char*>(MemAlloc(cast<long>(size))));
179 StrCopy(ptr.Get(), cast<char*>(memoryHandle.Memory()));
180 string str(ptr.Get());
181 auto utf32Result = ToUtf32(str);
182 if (utf32Result.Error())
183 {
184 return Result<ustring>(ErrorId(utf32Result.GetErrorId()));
185 }
186 return Result<ustring>(Rvalue(utf32Result.Value()));
187 }
188 else if (clipboardFormat.Number() == ClipboardFormat.Format.unicodeText)
189 {
190 UniquePtr<wchar> ptr(cast<wchar*>(MemAlloc(cast<long>(size))));
191 StrCopy(ptr.Get(), cast<wchar*>(memoryHandle.Memory()));
192 wstring str(ptr.Get());
193 auto utf32Result = ToUtf32(str);
194 if (utf32Result.Error())
195 {
196 return Result<ustring>(ErrorId(utf32Result.GetErrorId()));
197 }
198 return Result<ustring>(Rvalue(utf32Result.Value()));
199 }
200 else
201 {
202 UniquePtr<uchar> ptr(cast<uchar*>(MemAlloc(cast<long>(size))));
203 StrCopy(ptr.Get(), cast<uchar*>(memoryHandle.Memory()));
204 ustring str(ptr.Get());
205 return Result<ustring>(Rvalue(str));;
206 }
207 }
208 [nodiscard]
209 public Result<bool> SetStringData(const ClipboardFormat& clipboardFormat, const ustring& str)
210 {
211 if (clipboardFormat.Number() == ClipboardFormat.Format.text)
212 {
213 auto utf8Result = ToUtf8(str);
214 if (utf8Result.Error())
215 {
216 return Result<bool>(ErrorId(utf8Result.GetErrorId()));
217 }
218 string s = Rvalue(utf8Result.Value());
219 Result<MemoryHandle> memoryHandleResult = MemoryHandle.AllocateMemory(cast<ulong>((s.Length() + 1) * sizeof(char)));
220 if (memoryHandleResult.Error())
221 {
222 return Result<bool>(ErrorId(memoryHandleResult.GetErrorId()));
223 }
224 MemoryHandle& memoryHandle = memoryHandleResult.Value();
225 StrCopy(cast<char*>(memoryHandle.Memory()), s.Chars());
226 auto result = SetData(clipboardFormat, memoryHandle);
227 return result;
228 }
229 else if (clipboardFormat.Number() == ClipboardFormat.Format.unicodeText)
230 {
231 auto utf16Result = ToUtf16(str);
232 if (utf16Result.Error())
233 {
234 return Result<bool>(ErrorId(utf16Result.GetErrorId()));
235 }
236 wstring s = Rvalue(utf16Result.Value());
237 Result<MemoryHandle> memoryHandleResult = MemoryHandle.AllocateMemory(cast<ulong>((s.Length() + 1) * sizeof(wchar)));
238 if (memoryHandleResult.Error())
239 {
240 return Result<bool>(ErrorId(memoryHandleResult.GetErrorId()));
241 }
242 MemoryHandle& memoryHandle = memoryHandleResult.Value();
243 StrCopy(cast<wchar*>(memoryHandle.Memory()), s.Chars());
244 auto result = SetData(clipboardFormat, memoryHandle);
245 return result;
246 }
247 else
248 {
249 Result<MemoryHandle> memoryHandleResult = MemoryHandle.AllocateMemory(cast<ulong>((str.Length() + 1) * sizeof(uchar)));
250 if (memoryHandleResult.Error())
251 {
252 return Result<bool>(ErrorId(memoryHandleResult.GetErrorId()));
253 }
254 MemoryHandle& memoryHandle = memoryHandleResult.Value();
255 StrCopy(cast<uchar*>(memoryHandle.Memory()), str.Chars());
256 auto result = SetData(clipboardFormat, memoryHandle);
257 return result;
258 }
259 }
260 private void* windowHandle;
261 }