首先,我要介紹一下編寫這個控件的核心dll:
DLL 文件: imm32.dll
DLL 名稱: Microsoft Windows IMM32 API Client DLL 或
描述:
imm32.dll是微軟Microsoft Windows輸入法管理相關文件。
屬於: Microsoft Windows (IMM)
我們要做的,就是調用這個dll中的:
[DllImport("Imm32.dll")]
public static extern IntPtr ImmGetContext(IntPtr hWnd);
和:
[DllImport("Imm32.dll")]
public static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);
簡單介紹一下:
ImmAssociateContext,這個api函數是調用輸入法的,第一個句柄是要調用輸入法的控件或窗體的句柄,第二個是不太好解釋,簡單說下要在IME中檢索或設置信息,應用程序必須首先獲得一個與指定窗口相關聯的輸入上下文的句柄。你可以通過ImmGetContext函數來獲得這個句柄,這樣說很彆扭啊,不知朋友們能否理解?
ImmGetContext這個api是為ImmAssociateContext它的第二個參數準備的,他的參數是控件或窗體的句柄,返回的是某控件聯繫上下文的句柄。如果你不理解,其實也無所謂,理論性的東西,誰叫微軟搞的這麼抽像呢!
下一步,我們新建一個winform創意,放上一個label控件,name是label1
我先把代碼貼出來,因為過程十分簡單,我也不做太多的介紹了:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
IntPtr m_hImc;
public const int WM_IME_SETCONTEXT = 0x0281;
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);
private const int HC_ACTION = 0;
private const int PM_REMOVE = 0x0001;
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)(m.WParam))) | ModifierKeys);
if (e.KeyCode == Keys.Back)
ChangeChar("back");
else if (e.KeyCode == Keys.Enter)
ChangeChar("enter");
else
{
char a = (char)e.KeyData;
intoText(a.ToString());
}
break;
}
}
private void intoText(string a)
{
label1.Text += a;
}
void ChangeChar(string a)
{
switch (a)
{
case "back":
if (label1.Text.Length > 0)
label1.Text = label1.Text.Remove(label1.Text.Length - 1);
break;
case "enter":
label1.Text += "\r\n";
break;
}
}
private void Form1_Load(object sender, EventArgs e)
{
m_hImc = ImmGetContext(this.Handle);
}
}
}