www.pudn.com > input.rar > IME.cs
using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Text.RegularExpressions;
namespace InputMethodReader
{
public class IME : Form
{
///
/// 争渡(QQ258190355)
/// 20080529
///
// 型定義
#region API Calls
// Imm系メソッド
[DllImport("imm32.dll")]
public static extern IntPtr ImmGetContext(IntPtr hWnd);
[DllImport("imm32.dll")]
public static extern bool ImmSetCompositionWindow(IntPtr hIMC, ref COMPOSITIONFORM lpCompForm);
[DllImport("imm32.dll")]
public static extern int ImmSetCompositionFont(IntPtr hIMC, ref LOGFONT lplf);
[DllImport("imm32.dll")]
public static extern int ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
//获取选择上去的字符
[DllImport("imm32.dll")]
public static extern int ImmGetCompositionString(IntPtr hIMC, uint dwIndex, StringBuilder lpBuf, uint dwBufLen);
//获取候选所有字
[DllImport("imm32.dll", EntryPoint = "ImmGetCandidateList")]
public static extern int ImmGetCandidateList(IntPtr himc, int deIndex, IntPtr lpCandidateList, int dwBufLen);
#endregion
#region structs
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LOGFONT
{
public int lfHeight;
public int lfWidth;
public int lfEscapement;
public int lfOrientation;
public int lfWeight;
public byte lfItalic;
public byte lfUnderline;
public byte lfStrikeOut;
public byte lfCharSet;
public byte lfOutPrecision;
public byte lfClipPrecision;
public byte lfQuality;
public byte lfPitchAndFamily;
// stringでいけると書いてあったがうまく動かないのでこれで
[MarshalAs(UnmanagedType.ByValArray, SizeConst = LF_FACESIZE * 2)]
public byte[] lfFaceName;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINTAPI
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
public struct COMPOSITIONFORM
{
public uint dwStyle;
public POINTAPI ptCurrentPos;
public RECT rcArea;
}
[StructLayout(LayoutKind.Sequential)]
public class CANDIDATELIST
{
public int dwSize;// 用字节表示的内存大小:=sizeof(CANDIDATELIST)+选择字符数据
public int dwStyle;// 列表串的取值方式
public int dwCount;// 当前列表个数
public int dwSelection; // 当前选择的列表序号
public int dwPageStart;// 在列表窗口中所显示的列表的起始序号(上下翻页时用)
public int dwPageSize;// 一页显示的列表个数
public int dwOffset;// 列表数据存放区地址:[阿];[大]。。。。
}
#endregion
#region variables
#endregion
#region constants
// IME系定義
public const int CFS_DEFAULT = 0x0000;
public const int CFS_RECT = 0x0001;
public const int CFS_POINT = 0x0002;
public const int CFS_FORCE_POSITION = 0x0020;
public const int CFS_CANDIDATEPOS = 0x0040;
public const int CFS_EXCLUDE = 0x0080;
public const int NI_COMPOSITIONSTR = 0x0015;
public const int CPS_CANCEL = 0x0004;
public const int NI_OPENCANDIDATE = 0x0010;
public const int IMN_OPENCANDIDATE = 0x0005;
public const int WM_IME_NOTIFY = 0x0282;
// IME系メッセージ
public const int WM_IME_STARTCOMPOSITION = 0x010D;
public const int WM_IME_ENDCOMPOSITION = 0x010E;
public const int WM_IME_COMPOSITION = 0x010F;
public const int WM_IME_KEYDOWN = 0x0209;
public const int LF_FACESIZE = 32;
#endregion
#region methods
// IMEで入力された文字列を取得
public string getImeString(IntPtr hwnd)
{
IntPtr hIMC = ImmGetContext(hwnd);//this.Handle);
StringBuilder buf;
try
{
// 訳のわからん処理だがこうしないとゴミる模様
int strLen = ImmGetCompositionString(hIMC, 0x800, null, 0);
buf = new StringBuilder(strLen);
int getSize = ImmGetCompositionString(hIMC, 0x800, buf, (uint)strLen);
byte[] by = System.Text.Encoding.Default.GetBytes(buf.ToString());
return System.Text.Encoding.Default.GetString(by, 0, strLen);
}
finally
{
ImmReleaseContext(hwnd, hIMC);
}
}
// ImmSetCompositionWindowとImmSetCompositionFontのラッパー
public void setImeContext(bool setFont)
{
IntPtr hIMC = ImmGetContext(this.Handle);//this.Handle);
if (hIMC == IntPtr.Zero)
return;
try
{
// ウィンドウセット
COMPOSITIONFORM form = new COMPOSITIONFORM();
form.dwStyle = CFS_POINT;
form.ptCurrentPos.x = 0;// MEMO:X位置設定
form.ptCurrentPos.y = 0;// MEMO:Y位置設定
ImmSetCompositionWindow(hIMC, ref form);
if (setFont)
{
// なんかラッパかまして変換しないとうまくいかない
object logFontWrap = new LOGFONT();
this.Font.ToLogFont(logFontWrap);
LOGFONT logFont = (IME.LOGFONT)logFontWrap;
byte[] by = Encoding.Default.GetBytes(this.Font.Name); // MEMO:英語環境とかの挙動怪しいかも?
for (int i = 0; i < logFont.lfFaceName.Length; i++)
{
logFont.lfFaceName[i] = (i >= by.Length) ? (byte)0 : by[i];
}
ImmSetCompositionFont(hIMC, ref logFont);
}
}
finally
{
ImmReleaseContext(this.Handle, hIMC);
}
}
public string[] GetAllCandidateList(IntPtr hwnd)
{
string[] strList = null;
string str = "";
try
{
IntPtr hIMC = ImmGetContext(hwnd);
//MessageBox.Show(hIMC.ToString());
if (hIMC != IntPtr.Zero)
{
CANDIDATELIST c = new CANDIDATELIST();
IntPtr ip = IntPtr.Zero;
int dwSize = ImmGetCandidateList(hIMC, 0, ip, 0);
if (dwSize > 28)
{
//MessageBox.Show(hIMC.ToString());
CANDIDATELIST list = new CANDIDATELIST();
IntPtr BufList = Marshal.AllocHGlobal(dwSize);
ImmGetCandidateList(hIMC, 0, BufList, dwSize);
Marshal.PtrToStructure(BufList, list);
byte[] buf = new byte[dwSize];
Marshal.Copy(BufList, buf, 0, dwSize);
Marshal.FreeHGlobal(BufList);
int os = list.dwOffset;
str = System.Text.Encoding.Default.GetString(buf, os, buf.Length - os - 2);
char[] par = "\0".ToCharArray();
strList = str.Split(par);
ImmReleaseContext(hwnd, hIMC);
if (str != "")
return strList;
}
}
}
catch (Exception ex)
{
return new string[1] { "" };
}
return new string[1] { "" };
}
#endregion
}
}