diff --git a/Samples/Sample.SimpleWindow/Program.cs b/Samples/Sample.SimpleWindow/Program.cs index cb2406f..2137766 100644 --- a/Samples/Sample.SimpleWindow/Program.cs +++ b/Samples/Sample.SimpleWindow/Program.cs @@ -1,8 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Text; -using System.Threading.Tasks; using WinApi.Gdi32; using WinApi.User32; using WinApi.Windows; @@ -16,6 +13,9 @@ static int Main(string[] args) { using (var win = Window.Create("Hello")) { + User32Methods.AddClipboardFormatListener(win.Handle); + User32Helpers.TrySetClipboardData(Encoding.Unicode.GetBytes("WOWSER\0"), ClipboardFormat.CF_UNICODETEXT); + win.Show(); return new EventLoop().Run(win); } @@ -62,6 +62,15 @@ protected override void OnMessage(ref WindowMessage msg) msg.Result = new IntPtr(1); return; } + case WM.CLIPBOARDUPDATE: + { + if (User32Helpers.TryGetClipboardUnicodeText(out var text)) + User32Helpers.MessageBox(text, "You've just copied something"); + else + User32Helpers.MessageBox("This form can handle only the text-copy event"); + break; + } + } base.OnMessage(ref msg); } diff --git a/Samples/Sample.Win32/Program.cs b/Samples/Sample.Win32/Program.cs index 8797b37..ad813ca 100644 --- a/Samples/Sample.Win32/Program.cs +++ b/Samples/Sample.Win32/Program.cs @@ -50,6 +50,8 @@ static int Main(string[] args) User32Methods.ShowWindow(hwnd, ShowWindowCommands.SW_SHOWNORMAL); User32Methods.UpdateWindow(hwnd); + User32Methods.AddClipboardFormatListener(hwnd); + Message msg; int res; while ((res = User32Methods.GetMessage(out msg, IntPtr.Zero, 0, 0)) != 0) @@ -83,6 +85,14 @@ private static IntPtr WindowProc(IntPtr hwnd, uint umsg, User32Methods.EndPaint(hwnd, ref ps); break; } + case WM.CLIPBOARDUPDATE: + { + if (User32Helpers.TryGetClipboardUnicodeText(out var text)) + User32Helpers.MessageBox(text, "You've just copied something"); + else + User32Helpers.MessageBox("This form can handle only the text-copy event"); + break; + } } return User32Methods.DefWindowProc(hwnd, umsg, wParam, lParam); } diff --git a/WinApi/User32/Helpers.cs b/WinApi/User32/Helpers.cs index 2b46a36..e1f79c1 100644 --- a/WinApi/User32/Helpers.cs +++ b/WinApi/User32/Helpers.cs @@ -1,6 +1,13 @@ using System; +using System.Collections; +using System.IO; +using System.Linq; using System.Runtime.InteropServices; +using System.Text; +using NetCoreEx.BinaryExtensions; using NetCoreEx.Geometry; +using WinApi.Gdi32; +using WinApi.Kernel32; namespace WinApi.User32 { @@ -213,5 +220,107 @@ public static bool InverseAdjustWindowRectEx( if (res) Rectangle.Subtract(ref lpRect, ref rc); return res; } + + #region Clipboard helpers + + /// + /// Will try to set the specified data to the clipboard. + /// If it is a string keep in mind that string should be passed with a null-terminated character. + /// + /// The data to set + /// + /// + public static bool TrySetClipboardData(byte[] data, ClipboardFormat clipboardFormat) + { + if (!User32Methods.OpenClipboard(new IntPtr())) return false; + + var bytesLength = data.Length; + var allocatedMemory = Marshal.AllocHGlobal(bytesLength); + + Marshal.Copy(data, 0, allocatedMemory, bytesLength); + + var result = User32Methods.SetClipboardData((uint)clipboardFormat, allocatedMemory); + + //https://msdn.microsoft.com/en-us/library/windows/desktop/ms649051%28v=vs.85%29.aspx + // If SetClipboardData succeeds, the system owns the object identified by the hMem parameter. + // The application may not write to or free the data once ownership has been transferred to the system, + //but it can lock and read from the data until the CloseClipboard function is called + + //The allocated memory should not be freed + + return User32Methods.CloseClipboard() && result != IntPtr.Zero; + } + + /// + /// Will try to set the specified text to the clipboard + /// + /// The text to set + /// + public static bool TrySetClipboardUnicodeText(string textToSet) + { + if (!User32Methods.OpenClipboard(new IntPtr())) return false; + + var ptrToStr = Marshal.StringToHGlobalUni(textToSet); + + var result = User32Methods.SetClipboardData((uint)ClipboardFormat.CF_UNICODETEXT, ptrToStr); + + //https://msdn.microsoft.com/en-us/library/windows/desktop/ms649051%28v=vs.85%29.aspx + // If SetClipboardData succeeds, the system owns the object identified by the hMem parameter. + // The application may not write to or free the data once ownership has been transferred to the system, + //but it can lock and read from the data until the CloseClipboard function is called + + //The allocated memory should not be freed + + return User32Methods.CloseClipboard() && result != IntPtr.Zero; + } + + /// + /// Will try to get a unicode-string from the clipbard + /// + /// + /// + public static unsafe bool TryGetClipboardUnicodeText(out string outString) + { + outString = string.Empty; + if (!User32Methods.OpenClipboard(new IntPtr())) return true; + + var ptrToData = User32Methods.GetClipboardData((uint)ClipboardFormat.CF_UNICODETEXT); + + if (User32Methods.CloseClipboard() == false || ptrToData == IntPtr.Zero) + return false; + + outString = new string((char*)ptrToData); + + return true; + } + + /// + /// Will try to retrieve the first available clipboard format. + /// + /// + /// + /// + public static unsafe bool TryGetPriorityClipboardFormat(ClipboardFormat[] format, out ClipboardFormat clipBoardFormat) + { + clipBoardFormat = ClipboardFormat.CF_ZERO; + fixed (ClipboardFormat* first = &format[0]) + { + var result = User32Methods.GetPriorityClipboardFormat((IntPtr)first, format.Length); + + //https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms649045(v=vs.85).aspx + switch (result) + { + case -1: + return false; + case 0: + return true; + default: + clipBoardFormat = (ClipboardFormat)result; + return true; + } + } + } + + #endregion } } \ No newline at end of file