WinForm 监听剪贴板复制的内容出现乱码

JPF1024 2018-05-16 11:01:50
WinForm里面监听剪贴板改变,中文和英文没问题,泰语和韩语就出现一串问号了,请问这是为什么?

使用的库:

namespace ClipboardHelper
{
public static class ClipboardMonitor
{
public delegate void OnClipboardChangeEventHandler(ClipboardFormat format, object data);
public static event OnClipboardChangeEventHandler OnClipboardChange;

public static void Start()
{
ClipboardWatcher.Start();
ClipboardWatcher.OnClipboardChange += (ClipboardFormat format, object data) =>
{
if (OnClipboardChange != null)
OnClipboardChange(format, data);
};
}

public static void Stop()
{
OnClipboardChange = null;
ClipboardWatcher.Stop();
}

class ClipboardWatcher : Form
{
private static ClipboardWatcher mInstance;
static IntPtr nextClipboardViewer;
public delegate void OnClipboardChangeEventHandler(ClipboardFormat format, object data);
public static event OnClipboardChangeEventHandler OnClipboardChange;
public static void Start()
{
if (mInstance != null)
return;

var t = new Thread(new ParameterizedThreadStart(x => Application.Run(new ClipboardWatcher())));
t.SetApartmentState(ApartmentState.STA); // give the [STAThread] attribute
t.Start();
}
public static void Stop()
{
mInstance.Invoke(new MethodInvoker(() =>
{
ChangeClipboardChain(mInstance.Handle, nextClipboardViewer);
}));
mInstance.Invoke(new MethodInvoker(mInstance.Close));

mInstance.Dispose();

mInstance = null;
}
protected override void SetVisibleCore(bool value)
{
CreateHandle();
mInstance = this;
nextClipboardViewer = SetClipboardViewer(mInstance.Handle);
base.SetVisibleCore(false);
}

[DllImport("User32.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);

[DllImport("User32.dll", CharSet = CharSet.Unicode)]
private static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

// defined in winuser.h
const int WM_DRAWCLIPBOARD = 0x308;
const int WM_CHANGECBCHAIN = 0x030D;

protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_DRAWCLIPBOARD:
ClipChanged();
SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;

case WM_CHANGECBCHAIN:
if (m.WParam == nextClipboardViewer)
nextClipboardViewer = m.LParam;
else
SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;

default:
base.WndProc(ref m);
break;
}
}

static readonly string[] formats = Enum.GetNames(typeof(ClipboardFormat));

private void ClipChanged()
{
System.Windows.Forms.IDataObject iData = Clipboard.GetDataObject();

ClipboardFormat? format = null;

foreach (var f in formats)
{
if (iData.GetDataPresent(f))
{
format = (ClipboardFormat)Enum.Parse(typeof(ClipboardFormat), f);
break;
}
}

object data = iData.GetData(format.ToString());

if (data == null || format == null)
return;

if (OnClipboardChange != null)
OnClipboardChange((ClipboardFormat)format, data);
}
}
}

public enum ClipboardFormat : byte
{
/// <summary>Specifies the standard ANSI text format. This static field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
Text,
/// <summary>Specifies the standard Windows Unicode text format. This static field
/// is read-only.</summary>
/// <filterpriority>1</filterpriority>
UnicodeText,
/// <summary>Specifies the Windows device-independent bitmap (DIB) format. This static
/// field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Dib,
/// <summary>Specifies a Windows bitmap format. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Bitmap,
/// <summary>Specifies the Windows enhanced metafile format. This static field is
/// read-only.</summary>
/// <filterpriority>1</filterpriority>
EnhancedMetafile,
/// <summary>Specifies the Windows metafile format, which Windows Forms does not
/// directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
MetafilePict,
/// <summary>Specifies the Windows symbolic link format, which Windows Forms does
/// not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
SymbolicLink,
/// <summary>Specifies the Windows Data Interchange Format (DIF), which Windows Forms
/// does not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Dif,
/// <summary>Specifies the Tagged Image File Format (TIFF), which Windows Forms does
/// not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Tiff,
/// <summary>Specifies the standard Windows original equipment manufacturer (OEM)
/// text format. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
OemText,
/// <summary>Specifies the Windows palette format. This static field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
Palette,
/// <summary>Specifies the Windows pen data format, which consists of pen strokes
/// for handwriting software, Windows Forms does not use this format. This static
/// field is read-only.</summary>
/// <filterpriority>1</filterpriority>
PenData,
/// <summary>Specifies the Resource Interchange File Format (RIFF) audio format,
/// which Windows Forms does not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Riff,
/// <summary>Specifies the wave audio format, which Windows Forms does not directly
/// use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
WaveAudio,
/// <summary>Specifies the Windows file drop format, which Windows Forms does not
/// directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
FileDrop,
/// <summary>Specifies the Windows culture format, which Windows Forms does not directly
/// use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Locale,
/// <summary>Specifies text consisting of HTML data. This static field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
Html,
/// <summary>Specifies text consisting of Rich Text Format (RTF) data. This static
/// field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Rtf,
/// Specifies a comma-separated value (CSV) format, which is a common interchange format used by spreadsheets. This format is not used directly by Windows Forms.This static field is read-only.
CommaSeparatedValue,
/// Specifies the Windows Forms string class format, which Windows Forms uses to store string objects. This static field is read-only.
StringFormat,
///Specifies a format that encapsulates any type of Windows Forms object.This static field is read-only.
Serializable,
}
}



调用:

// 窗体加载:
ClipboardMonitor.OnClipboardChange += ClipboardMonitor_OnClipboardChange;
ClipboardMonitor.Start();
// 设置值.
// oldText 是一个文本框.

private delegate void SetTextCallback(string text);
//在给textBox1.text赋值的地方调用以下方法即可
private void SetOldText(string text)
{
// InvokeRequired需要比较调用线程ID和创建线程ID
// 如果它们不相同则返回true
if (this.oldText.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetOldText);
this.Invoke(d, new object[] { text });
}
else
{
this.oldText.Text = text;
}
}
private void ClipboardMonitor_OnClipboardChange(ClipboardFormat format, object data)
{
if (Properties.Settings.Default.AutoReadClipBoardContent)
{
switch (format)
{
case ClipboardFormat.Text:
case ClipboardFormat.UnicodeText:
SetOldText(data.ToString());
break;
}

}
}

该怎么处理才能正常把剪贴板的泰语或者韩语正常显示到文本框里面呢?(直接ctrl+v是可以正常显示的)?
谢谢.

...全文
591 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
JPF1024 2018-05-18
  • 打赏
  • 举报
回复
引用 1 楼 assky124 的回复:
直接调用.net 自带的剪贴板,获取 似乎没问题 Clipboard.GetText(); 韩文可以正常显示
我解决了,解决方式是: 在调用的地方,不使用监控类(剪贴板监控)传递过来的数据,而是实时的去获取一次:


private void ClipboardMonitor_OnClipboardChange(ClipboardFormat format, object data)
        {
            if (Properties.Settings.Default.AutoReadClipBoardContent)
            {
                switch (format)
                {
                    case ClipboardFormat.Text:
                    case ClipboardFormat.UnicodeText:
                        // 原来的写法       SetOldText(data.ToString());
                         /////////   
                         ///////// 修改为下面的写法,即可避免乱码.              
                        SetOldText(Clipboard.GetText());
                        break;
                }
 
            }
        }


assky124 2018-05-17
  • 打赏
  • 举报
回复
直接调用.net 自带的剪贴板,获取 似乎没问题 Clipboard.GetText(); 韩文可以正常显示

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧