C++和C#实现剪切板数据交互
c#端由于system.windows.form自带的剪切板功能太少,所以写了一个Helper类把接口转了出来。这样就可以用不同的uint的id了。
并且自带的剪切板必须执行在[STAThread]模式下,很麻烦
而c++端拷贝字符串由于编码问题,需要使用宽字符。否则会乱码
c#
ClipboardHelper
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Hont.Win32 { public static class ClipboardHelper { #region Win32 Interface [DllImport("user32.dll")] public static extern bool EmptyClipboard(); [DllImport("user32.dll", SetLastError = true)] private extern static IntPtr SetClipboardData(uint format, IntPtr handle); [DllImport("user32.dll")] static extern IntPtr GetClipboardData(uint uFormat); [DllImport("user32.dll")] static extern bool IsClipboardFormatAvailable(uint format); [DllImport("user32.dll", SetLastError = true)] static extern bool OpenClipboard(IntPtr hWndNewOwner); [DllImport("user32.dll", SetLastError = true)] static extern bool CloseClipboard(); [DllImport("kernel32.dll")] static extern IntPtr GlobalLock(IntPtr hMem); [DllImport("kernel32.dll")] static extern bool GlobalUnlock(IntPtr hMem); public const uint CF_UNICODETEXT = 13; #endregion public static bool CopyToClipboard(uint id, string content) { if (OpenClipboard(IntPtr.Zero)) { EmptyClipboard(); IntPtr hmem = Marshal.StringToHGlobalUni(content); var ptr = GlobalLock(hmem); GlobalUnlock(ptr); SetClipboardData(id, ptr); CloseClipboard(); return true; } return false; } public static string GetFromClipboard(uint id) { if (!IsClipboardFormatAvailable(id)) return null; if (!OpenClipboard(IntPtr.Zero)) return null; string data = null; var hGlobal = GetClipboardData(id); if (hGlobal != IntPtr.Zero) { var lpwcstr = GlobalLock(hGlobal); if (lpwcstr != IntPtr.Zero) { data = Marshal.PtrToStringAuto(lpwcstr); GlobalUnlock(lpwcstr); } } CloseClipboard(); return data; } } }
Main
using System; namespace ClipboardTest { class Program { //[STAThread] static void Main(string[] args) { //ClipboardHelper.CopyToClipboard(90, "qweqweqwe"); var str = ClipboardHelper.GetFromClipboard(90); Console.WriteLine(str); Console.ReadLine(); } } }
c++
#include<Windows.h> #include <iostream> #include <windows.h> #include <ctime> #include <atlstr.h> #include "stdafx.h" BOOL CopyStringToClipBoard(HWND hOwner, CString strSource) { if (::OpenClipboard(hOwner)) { int buff_size = strSource.GetLength(); CStringW strWide = CStringW(strSource); int nLen = strWide.GetLength(); HANDLE clipbuffer; char* buffer; ::EmptyClipboard(); clipbuffer = ::GlobalAlloc(GMEM_DDESHARE, (nLen + 1) * 2); buffer = (char*)::GlobalLock(clipbuffer); memset(buffer, 0, (nLen + 1) * 2); memcpy_s(buffer, nLen * 2, strWide.GetBuffer(0), nLen * 2); strWide.ReleaseBuffer(); ::GlobalUnlock(clipbuffer); ::SetClipboardData(90, clipbuffer); ::CloseClipboard(); } return FALSE; } BOOL GetTextFromClipboard() { if (::OpenClipboard(NULL)) { HGLOBAL hMem = GetClipboardData(90); if (NULL != hMem) { char* lpStr = (char*)::GlobalLock(hMem); if (NULL != lpStr) { printf(lpStr); ::GlobalUnlock(hMem); } } ::CloseClipboard(); return TRUE; } return FALSE; } int _tmain(int argc, _TCHAR* argv[]) { CopyStringToClipBoard(NULL, "asdsad"); GetTextFromClipboard(); return 0; }