艾伟_转载:C#下实现空白窗体上中文输入,可以实现类PS的文字工具

简介: C#下实现空白窗体上中文输入关键字:类PS的文字工具,中文输入.重复截取中文最近在研究做一个类PS的文字工具,查了N多的资料,问了N多个人,总算功夫不负有人心.终于给弄出来了.写出来给大家一起讨论.

C#下实现空白窗体上中文输入

关键字: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);
}
}
}

 

 

 

 

目录
相关文章
|
3月前
|
开发框架 .NET C#
C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
【10月更文挑战第9天】在 C#/.NET Core 中,有多种方法可以删除字符串的最后一个字符,包括使用 `Substring` 方法、`Remove` 方法、`ToCharArray` 与 `Array.Copy`、`StringBuilder`、正则表达式、循环遍历字符数组以及使用 LINQ 的 `SkipLast` 方法。
|
4月前
|
存储 C# 索引
C# 一分钟浅谈:数组与集合类的基本操作
【9月更文挑战第1天】本文详细介绍了C#中数组和集合类的基本操作,包括创建、访问、遍历及常见问题的解决方法。数组适用于固定长度的数据存储,而集合类如`List<T>`则提供了动态扩展的能力。文章通过示例代码展示了如何处理索引越界、数组长度不可变及集合容量不足等问题,并提供了解决方案。掌握这些基础知识可使程序更加高效和清晰。
97 2
|
12天前
|
程序员 C# 数据库
C# 比较对象新思路,利用反射技术打造更灵活的比较工具
中途接手的项目,碰到需要在更新对象信息时比较并记录差异的需求,最变态的还有附加要求,怎么办?有没有既能满足需求又能对项目影响最小的方法呢?分享这个我封装的方法,一个利用反射技术打造的更灵活的比较工具
|
3月前
|
API C# Windows
【C#】在winform中如何实现嵌入第三方软件窗体
【C#】在winform中如何实现嵌入第三方软件窗体
160 0
|
3月前
|
XML 存储 安全
C#开发的程序如何良好的防止反编译被破解?ConfuserEx .NET混淆工具使用介绍
C#开发的程序如何良好的防止反编译被破解?ConfuserEx .NET混淆工具使用介绍
149 0
|
3月前
|
Java 程序员 C#
【类的应用】C#应用之派生类构造方法给基类构造方法传参赋值
【类的应用】C#应用之派生类构造方法给基类构造方法传参赋值
17 0
|
3月前
|
SQL JSON BI
最好的 C# .NET 报告工具
最好的 C# .NET 报告工具
53 0
|
4月前
|
C# 数据安全/隐私保护
C# 一分钟浅谈:类与对象的概念理解
【9月更文挑战第2天】本文从零开始详细介绍了C#中的类与对象概念。类作为一种自定义数据类型,定义了对象的属性和方法;对象则是类的实例,拥有独立的状态。通过具体代码示例,如定义 `Person` 类及其实例化过程,帮助读者更好地理解和应用这两个核心概念。此外,还总结了常见的问题及解决方法,为编写高质量的面向对象程序奠定基础。
38 2
|
5月前
|
C#
C#中的类和继承
C#中的类和继承
49 6
|
5月前
|
Java C# 索引
C# 面向对象编程(一)——类
C# 面向对象编程(一)——类
41 0