1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.Windows.API;
  8 
  9 namespace System.Windows
 10 {
 11     public class ClipboardFormat
 12     {
 13         public enum Format : uint
 14         {
 15             text = 1uunicodeText = 13u
 16         }
 17         public nothrow ClipboardFormat(Format format) : formatName()formatNumber(format)
 18         {
 19         }
 20         public ClipboardFormat(const string& formatName_) : formatName(formatName_)formatNumber(0u)
 21         {
 22             formatNumber = RegisterClipboardFormat(formatName.Chars());
 23         }
 24         public inline nothrow uint Number() const
 25         {
 26             return formatNumber;
 27         }
 28         private string formatName;
 29         private uint formatNumber;
 30     }
 31 
 32     public class MemoryHandle
 33     {
 34         public nothrow MemoryHandle() : handle(null)
 35         {
 36         }
 37         public MemoryHandle(void* handle_) : handle(handle_)memory(GlobalLock(handle))
 38         {
 39         }
 40         suppress MemoryHandle(const MemoryHandle&);
 41         suppress void operator=(const MemoryHandle&);
 42         public MemoryHandle(MemoryHandle&& that) : handle(that.handle)
 43         {
 44             that.handle = null;
 45         }
 46         public default nothrow void operator=(MemoryHandle&&);
 47         public ~MemoryHandle()
 48         {
 49             if (handle != null)
 50             {
 51                 GlobalUnlock(handle);
 52             }
 53         }
 54         public static MemoryHandle AllocateMemory(ulong size)
 55         {
 56             return MemoryHandle(GlobalAlloc(GlobalAllocFlags.GHNDsize));
 57         }
 58         public nothrow void* Memory() const
 59         {
 60             return memory;
 61         }
 62         public ulong Size() const
 63         {
 64             return GlobalSize(handle);
 65         }
 66         public nothrow void* Handle() const
 67         {
 68             return handle;
 69         }
 70         private void* handle;
 71         private void* memory;
 72     }
 73 
 74     public class ClipboardListener
 75     {
 76         public ClipboardListener(void* windowHandle_) : windowHandle(windowHandle_)
 77         {
 78             AddClipboardFormatListener(windowHandle);
 79         }
 80         public ~ClipboardListener()
 81         {
 82             try
 83             {
 84                 RemoveClipboardFormatListener(windowHandle);
 85             }
 86             catch (const Exception&)
 87             {
 88             }
 89         }
 90         private void* windowHandle;
 91     }
 92 
 93     public class Clipboard
 94     {
 95         public Clipboard(void* windowHandle_) : windowHandle(windowHandle_)
 96         {
 97             OpenClipboard(windowHandle);
 98         }
 99         public ~Clipboard()
100         {
101             CloseClipboard();
102         }
103         public bool IsClipboardFormatAvailable(const ClipboardFormat& clipboardFormat) const
104         {
105             return IsClipboardFormatAvailable(clipboardFormat.Number());
106         }
107         public void SetEmpty()
108         {
109             EmptyClipboard();
110         }
111         public MemoryHandle GetData(const ClipboardFormat& clipboardFormat)
112         {
113             return MemoryHandle(GetClipboardData(clipboardFormat.Number()));
114         }
115         public void SetData(const ClipboardFormat& clipboardFormatconst MemoryHandle& memoryHandle)
116         {
117             SetEmpty();
118             SetClipboardData(clipboardFormat.Number()memoryHandle.Handle());
119         }
120         public ustring GetStringData(const ClipboardFormat& clipboardFormat)
121         {
122             MemoryHandle memoryHandle = GetData(clipboardFormat);
123             ulong size = memoryHandle.Size();
124             if (clipboardFormat.Number() == ClipboardFormat.Format.text)
125             {
126                 UniquePtr<char> ptr(cast<char*>(MemAlloc(cast<long>(size))));
127                 StrCopy(ptr.Get()cast<char*>(memoryHandle.Memory()));
128                 string str(ptr.Get());
129                 return ToUtf32(str);
130             }
131             else if (clipboardFormat.Number() == ClipboardFormat.Format.unicodeText)
132             {
133                 UniquePtr<wchar> ptr(cast<wchar*>(MemAlloc(cast<long>(size))));
134                 StrCopy(ptr.Get()cast<wchar*>(memoryHandle.Memory()));
135                 wstring str(ptr.Get());
136                 return ToUtf32(str);
137             }
138             else
139             {
140                 UniquePtr<uchar> ptr(cast<uchar*>(MemAlloc(cast<long>(size))));
141                 StrCopy(ptr.Get()cast<uchar*>(memoryHandle.Memory()));
142                 ustring str(ptr.Get());
143                 return str;
144             }
145         }
146         public void SetStringData(const ClipboardFormat& clipboardFormatconst ustring& str)
147         {
148             if (clipboardFormat.Number() == ClipboardFormat.Format.text)
149             {
150                 string s = ToUtf8(str);
151                 MemoryHandle memoryHandle = MemoryHandle.AllocateMemory(cast<ulong>((s.Length() + 1) * sizeof(char)));
152                 StrCopy(cast<char*>(memoryHandle.Memory())s.Chars());
153                 SetData(clipboardFormatmemoryHandle);
154             }
155             else if (clipboardFormat.Number() == ClipboardFormat.Format.unicodeText)
156             {
157                 wstring s = ToUtf16(str);
158                 MemoryHandle memoryHandle = MemoryHandle.AllocateMemory(cast<ulong>((s.Length() + 1) * sizeof(wchar)));
159                 StrCopy(cast<wchar*>(memoryHandle.Memory())s.Chars());
160                 SetData(clipboardFormatmemoryHandle);
161             }
162             else
163             {
164                 MemoryHandle memoryHandle = MemoryHandle.AllocateMemory(cast<ulong>((str.Length() + 1) * sizeof(uchar)));
165                 StrCopy(cast<uchar*>(memoryHandle.Memory())str.Chars());
166                 SetData(clipboardFormatmemoryHandle);
167             }
168         }
169         private void* windowHandle;
170     }
171 }