gpt4 book ai didi

c# - 如何在非主线程中获取剪贴板数据?

转载 作者:太空宇宙 更新时间:2023-11-03 19:44:50 24 4
gpt4 key购买 nike

我正在尝试使用以下代码从剪贴板获取数据。

private void TestBtn_Click(object sender, EventArgs e)
{
Thread sampleThread = new Thread(SampleMethod);
sampleThread.IsBackground = true;
sampleThread.Start();
Thread.Sleep(2000);
var textFromMain = Clipboard.GetText(TextDataFormat.Text);
}

private void SampleMethod()
{
var textFromThread = Clipboard.GetText(TextDataFormat.Text);
Thread.Sleep(1000);
}

我正在使用此行将任何文本复制到剪贴板 -

var textFromMain = Clipboard.GetText(TextDataFormat.Text);

但下面一行返回空字符串或空白字符串。

var textFromThread = Clipboard.GetText(TextDataFormat.Text);

我不明白是什么问题。有人可以帮助我理解。如果是多线程,请指出正确的方向。

最佳答案

Clipboard.GetText(TextDataFormat.Text) 使用 COM 并在未标记 STAThreadAttribute 的线程中调用时抛出异常

一种解决方法是使用委托(delegate)将 Clipboard.GetText 的调用返回到主线程,并使用 Invoke。但在这种情况下,线程将卡住它在 Invoke 上的执行,直到 SampleMethod() 结束它在主窗体线程上的执行,并且主线程将空闲。

其他方法是使用自己对 COM 的调用来获取剪贴板文本而不是 System.Windows.Forms.Clipboard.GetText(),参见 ClipboardCom.GetText() ,该方法不需要等待主窗体线程。

    private string _textFromMain, _textFromThreadByInvoke, _textFromThreadByCom;

private delegate string GetClipboardInvoke(TextDataFormat textformat);
private void SampleInvokeMethod()
{
GetClipboardInvoke invokerClipboard = new GetClipboardInvoke(Clipboard.GetText);
_textFromThreadByInvoke = (string)this.Invoke(invokerClipboard, TextDataFormat.Text); // where this is a Form
Thread.Sleep(1000);
}



private void button1_Click(object sender, EventArgs e)
{
Thread sampleInvokeThread = new Thread(SampleInvokeMethod) { IsBackground = true };
sampleInvokeThread.Start();

Thread sampleComThread = new Thread(SampleComMethod) { IsBackground = true };
sampleComThread.Start();

Thread.Sleep(10000);
_textFromMain = Clipboard.GetText(TextDataFormat.Text);
}


private void SampleComMethod()
{
_textFromThreadByCom = ClipboardCom.GetText();
Thread.Sleep(1000);
}

public static class ClipboardCom
{
[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);

const uint CF_UNICODETEXT = 13;

public static string GetText()
{
if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
return null;
if (!OpenClipboard(IntPtr.Zero))
return null;

string data = null;
var hGlobal = GetClipboardData(CF_UNICODETEXT);
if (hGlobal != IntPtr.Zero)
{
var lpwcstr = GlobalLock(hGlobal);
if (lpwcstr != IntPtr.Zero)
{
data = Marshal.PtrToStringUni(lpwcstr);
GlobalUnlock(lpwcstr);
}
}
CloseClipboard();

return data;
}
}

关于c# - 如何在非主线程中获取剪贴板数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47344799/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com