艾伟_转载:C#下实现空白窗体上中文输入,可以实现类PS的文字工具
2011-08-29 00:21
661 查看
C#下实现空白窗体上中文输入
关键字:类PS的文字工具,中文输入.重复截取中文
最近在研究做一个类PS的文字工具,查了N多的资料,问了N多个人,总算功夫不负有人心.终于给弄出来了.写出来给大家一起讨论.(高手们请多多指点)
在空白窗体上打开输入法,在C#里的空白窗口是无论如何也是打不开输入法.设置了this.ImeMode= ImeMode.NoControl也是无法打开输入法的录字窗口.去Microsoft 开发论坛上问了一些问题.感谢周雪峰版主与Riquel_Dong 版主给的指点.用了API函数: ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);终于把输入法给调了出来,它的功能是把输入与指定的窗口进行关联.
代码如下:
现在可以调用输入法了.可是又出现了新的问题.怎么样取得输入法录字窗体上的字呢.
当打开输入法输入文字时,会发送WM_IME_CHAR的消息.我们在这个消息下处理下就可以得到汉字了
可以用IMM的函数: ImmGetCompositionString(IntPtr hIMC, int dwIndex, StringBuilder lpBuf, int dwBufLen);取得录字窗体上输入的汉字或者NUICODE类的字.当然,这里就不研究别的了.只说汉字问题.
取字的代码如下:
OK,.好象是大功告成了.测试了一下才发现打印出来的都是重复的文字.比如输入”为人民服务”,打印出的却是”为为人人民民服服务务”我的天呐,问题出在哪里呢.
去查了一下MSDN.对WM_IME_CHAR有这样的说明:
the WM_IME_CHAR message includes a double-byte character and the application passes this message to DefWindowProc
是不是问题就出在这里了.是发送消息两次的问题.
看了一个网上的讨论,得出一个解决方案:加上判断
if (m.WParam.ToInt32() == PM_REMOVE)
{
}
测试.终于没有了问题了
代码帖子上
关键字:类PS的文字工具,中文输入.重复截取中文
最近在研究做一个类PS的文字工具,查了N多的资料,问了N多个人,总算功夫不负有人心.终于给弄出来了.写出来给大家一起讨论.(高手们请多多指点)
在空白窗体上打开输入法,在C#里的空白窗口是无论如何也是打不开输入法.设置了this.ImeMode= ImeMode.NoControl也是无法打开输入法的录字窗口.去Microsoft 开发论坛上问了一些问题.感谢周雪峰版主与Riquel_Dong 版主给的指点.用了API函数: ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);终于把输入法给调了出来,它的功能是把输入与指定的窗口进行关联.
代码如下:
f (m.Msg == WM_IME_SETCONTEXT && m.WParam.ToInt32() == 1) { ImmAssociateContext(this.Handle, m_hImc); }
现在可以调用输入法了.可是又出现了新的问题.怎么样取得输入法录字窗体上的字呢.
当打开输入法输入文字时,会发送WM_IME_CHAR的消息.我们在这个消息下处理下就可以得到汉字了
可以用IMM的函数: ImmGetCompositionString(IntPtr hIMC, int dwIndex, StringBuilder lpBuf, int dwBufLen);取得录字窗体上输入的汉字或者NUICODE类的字.当然,这里就不研究别的了.只说汉字问题.
取字的代码如下:
case WM_IME_CHAR: int size = ImmGetCompositionString(m_hImc, GCS_COMPSTR, null, 0); size += sizeof(Char); ImmGetCompositionString(m_hImc, GCS_RESULTSTR, str, size); sb.Append(str.ToString()); MessageBox.Show(str.ToString()); intoText();//打印文字 isShowChina = true; break;
OK,.好象是大功告成了.测试了一下才发现打印出来的都是重复的文字.比如输入”为人民服务”,打印出的却是”为为人人民民服服务务”我的天呐,问题出在哪里呢.
去查了一下MSDN.对WM_IME_CHAR有这样的说明:
the WM_IME_CHAR message includes a double-byte character and the application passes this message to DefWindowProc
是不是问题就出在这里了.是发送消息两次的问题.
看了一个网上的讨论,得出一个解决方案:加上判断
if (m.WParam.ToInt32() == PM_REMOVE)
{
}
测试.终于没有了问题了
代码帖子上
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsApplication2 { public partial class UserControl1 : UserControl { IntPtr m_hImc; bool isShowChina = false; public const int WM_IME_SETCONTEXT = 0x0281; private const int WM_IME_CHAR = 0x0286; private const int WM_CHAR = 0x0102; private const int WM_IME_COMPOSITION = 0x010F; private const int GCS_COMPSTR = 0x0008; [DllImport("Imm32.dll")] public static extern IntPtr ImmGetContext(IntPtr hWnd); [DllImport("Imm32.dll")] public static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC); [DllImport("imm32.dll")] static extern int ImmGetCompositionString(IntPtr hIMC, int dwIndex, StringBuilder
lpBuf, int dwBufLen);
private int GCS_RESULTSTR = 0x0800;
private const int HC_ACTION = 0;
private const int PM_REMOVE = 0x0001;
StringBuilder sb = new StringBuilder();
Font font = new Font("宋体", 14, FontStyle.Regular);
public UserControl1()
{
InitializeComponent();
}
private void UserControl1_Load(object sender, EventArgs e)
{
m_hImc = ImmGetContext(this.Handle);
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_IME_SETCONTEXT && m.WParam.ToInt32() == 1) { ImmAssociateContext(this.Handle, m_hImc); }
switch (m.Msg)
{
case WM_CHAR:
KeyEventArgs e = new KeyEventArgs(((Keys)((int)((long)m.WParam))) |
ModifierKeys); char a = (char)e.KeyData; //英文 sb.Append(a); intoText(); isShowChina = false; break; case WM_IME_CHAR: if (m.WParam.ToInt32() == PM_REMOVE) //如果不做这个判断.会打印出重复的中文 { StringBuilder str = new StringBuilder(); int size = ImmGetCompositionString(m_hImc, GCS_COMPSTR, null, 0); size += sizeof(Char); ImmGetCompositionString(m_hImc, GCS_RESULTSTR, str, size); sb.Append(str.ToString()); MessageBox.Show(str.ToString()); intoText(); isShowChina = true; } break; } } /// /// 打印文字 /// private void intoText()// { Graphics g = this.CreateGraphics(); g.DrawString(sb.ToString(), font, Brushes.Black, 10, 10); } } }
相关文章推荐
- C#下实现空白窗体上中文输入,可以实现类PS的文字工具
- C#下实现空白窗体中文输入,实现类PS的文字工具
- C#下实现空白窗体中文输入
- C#下实现空白窗体中文输入
- 实现:C#窗体中的文本框只能输入中文汉字,其他输入无效。问:正则表达式怎么用?
- C# 实现完整功能的截图控件(1)-实现绘图工具栏控件 控件实现了截图、绘制矩形、圆形、箭头、线条、文字,还需要可以撤销绘制步骤、保存图形等功能,基本实现了跟QQ2008截图一样的功能,还可以更
- C#实现VB6.0的输入窗体InputBox代码
- c#动态设置combobox控件下拉项宽度以实现下拉项文字可以完全显示。
- C#连接oracle 数据库查询时输入中文查询不出来,用plsql就可以
- c#实例化继承类,必须对被继承类的程序集做引用 .net core Redis分布式缓存客户端实现逻辑分析及示例demo 数据库笔记之索引和事务 centos 7下安装python 3.6笔记 你大波哥~ C#开源框架(转载) JSON C# Class Generator ---由json字符串生成C#实体类的工具
- luyikk 的C# PING 工具 与 传统的不一样的是 他可以修改你的 IP地址实现伪造ICMP数据包 ,当然 XP下无法使用 2003下才可以使用
- 艾伟_转载:用C#实现基于TCP协议的网络通讯
- 【转载】C#实现主窗体工具栏上按钮两幅图片的交互效果
- 如何实现可以输入文字可以插入图片的输入框?如图:
- 艾伟_转载:ASP.NET(c#)实现中英文域名查询
- 艾伟_转载:老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现
- 艾伟_转载:在C#中实现3层架构
- Android editText.addTextChangedListener实现还有多少文字可以输入
- 【转载】C#中实现窗体间传值
- C#里的空白窗口实现输入功能