Last active
August 10, 2020 17:33
-
-
Save orange-in-space/9a3a097d3495a07a3277c8937f6e7eb6 to your computer and use it in GitHub Desktop.
C# Win32apiでクリップボードにテキスト送るライブラリ的な><(System.Clipboardが使えない場面用><)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
namespace Orange.Fragment | |
{ | |
//please give it a name you like to namespace><; | |
//a kind of Clipboard.SetText(), Win32API version | |
//(C) orange_in_space | |
// | |
//License: CC0 1.0 | |
// SetTextSimple() Simple Version | |
// SetText() Error handled And Open-Retry Version (non tested code!><;) | |
public static class ClipboardTextWin32 | |
{ | |
//Simple Version | |
// Let's Copy And Paste!>< (?) | |
//------------------------------------- | |
// | |
public static void SetTextSimple(string text) | |
{ | |
string nullTerminatedStr = text + "\0"; | |
byte[] strBytes = System.Text.Encoding.Unicode.GetBytes(nullTerminatedStr); | |
IntPtr hglobal = System.Runtime.InteropServices.Marshal.AllocHGlobal(strBytes.Length); | |
System.Runtime.InteropServices.Marshal.Copy(strBytes, 0, hglobal, strBytes.Length); | |
OpenClipboard(IntPtr.Zero); | |
EmptyClipboard(); | |
SetClipboardData(CF_UNICODETEXT, hglobal); | |
CloseClipboard(); | |
System.Runtime.InteropServices.Marshal.FreeHGlobal(hglobal); | |
} | |
#region Win32Api | |
private const uint CF_UNICODETEXT = 13; | |
[System.Runtime.InteropServices.DllImport("user32.dll")] | |
static extern bool OpenClipboard(IntPtr hWndNewOwner); | |
[System.Runtime.InteropServices.DllImport("user32.dll")] | |
static extern bool EmptyClipboard(); | |
[System.Runtime.InteropServices.DllImport("user32.dll")] | |
static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem); | |
[System.Runtime.InteropServices.DllImport("user32.dll")] | |
static extern bool CloseClipboard(); | |
#endregion | |
// | |
//------------------------------------- | |
// | |
// | |
//Error handled And Open-Retry Version | |
// | |
/// <summary> | |
/// Clipboard.SetText() in Win32API | |
/// </summary> | |
/// <param name="text">Clipboard Text</param> | |
/// <param name="silent">none throw mode</param> | |
/// <param name="retryMax">Open-Retry Maximum(Default: 3 times)</param> | |
/// <param name="retryIntervalInMs">Open-Retry, Sleep wait !!Minimum!! time in Millisecconds(Default: 20 ms)</param> | |
/// <returns>Win32 GetLastError Value. 0 is Succeeded.</returns> | |
public static int SetText(string text, bool silent = false, int retryMax = 3, int retryIntervalInMs = 20) | |
{ | |
string nullTerminatedStr = text + "\0"; | |
byte[] strBytes = System.Text.Encoding.Unicode.GetBytes(nullTerminatedStr); | |
IntPtr hglobal = Marshal.AllocHGlobal(strBytes.Length); | |
int errorResult = 0; | |
CbResult cbApiInternalResult = CbResult.None; | |
try | |
{ | |
int retry = (retryMax > 0) ? retryMax + 1 : 1; | |
while (retry > 0) | |
{ | |
Marshal.Copy(strBytes, 0, hglobal, strBytes.Length); | |
if (OpenClipboard(IntPtr.Zero)) | |
{ | |
if (EmptyClipboard()) | |
{ | |
if (SetClipboardData(CF_UNICODETEXT, hglobal) == IntPtr.Zero) | |
{ | |
errorResult = Marshal.GetLastWin32Error(); | |
cbApiInternalResult = CbResult.SetClipboardDataFailed; | |
} | |
else | |
{ | |
cbApiInternalResult = CbResult.Succeeded; | |
errorResult = 0; | |
} | |
} | |
else | |
{ | |
errorResult = Marshal.GetLastWin32Error(); | |
cbApiInternalResult = CbResult.EmptyFailed; | |
} | |
if (!CloseClipboard()) | |
{ | |
errorResult = Marshal.GetLastWin32Error(); | |
cbApiInternalResult = CbResult.CloseFailed; | |
} | |
} | |
else | |
{ | |
errorResult = Marshal.GetLastWin32Error(); | |
cbApiInternalResult = CbResult.OpenFailed; | |
} | |
if (cbApiInternalResult != CbResult.OpenFailed) | |
{ | |
break; | |
} | |
System.Threading.Thread.Sleep(retryIntervalInMs); | |
retry--; | |
} | |
} | |
finally | |
{ | |
Marshal.FreeHGlobal(hglobal); | |
} | |
if (!silent) | |
{ | |
switch (cbApiInternalResult) | |
{ | |
case CbResult.OpenFailed: | |
{ | |
throw new OrangeClipboardException("Clipboard Open Failed"); | |
} | |
case CbResult.EmptyFailed: | |
{ | |
throw new OrangeClipboardException("Clipboard Empty Failed"); | |
} | |
case CbResult.CloseFailed: | |
{ | |
throw new OrangeClipboardException("Clipboard Close Failed"); | |
} | |
case CbResult.SetClipboardDataFailed: | |
{ | |
throw new OrangeClipboardException("Clipboard SetClipboardData Failed"); | |
} | |
} | |
} | |
return errorResult; | |
} | |
public class OrangeClipboardException : Exception | |
{ | |
public OrangeClipboardException() | |
{ | |
} | |
public OrangeClipboardException(string Message) : base(Message) | |
{ | |
} | |
}; | |
// | |
private enum CbResult | |
{ | |
None, Succeeded, OpenFailed, SetClipboardDataFailed, EmptyFailed, CloseFailed | |
} | |
// | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment