c# windows程序调用本地输入法
好久没写博客了,今天写了一个DEMO,在WINform程序中调用本地输入法,并在窗体中显示出来。其中使用到了很多API,现把代码贴出来,供大家参考

private string _CurrentImeHandleStr = "";
public delegate bool EnumResNameProc(IntPtr hModule, IntPtr nType, StringBuilder sName, IntPtr lParam);
System.ComponentModel.ComponentResourceManager resources = new ComponentResourceManager(typeof(Form17));
public Form17()
{
InitializeComponent();
}
#region API定义
private static readonly int BTN_HEIGHT = 21;
private static readonly int IMAGE_ICON = 1;
private const int DONT_RESOLVE_DLL_REFERENCES = 0x1;
private const int LOAD_LIBRARY_AS_DATAFILE = 0x2;
private const int LOAD_WITH_ALTERED_SEARCH_PATH = 0x8;
private const int RT_ICON = 0x3;
private const int RT_BITMAP = 0x2;
private const int RT_GROUP_ICON = (RT_ICON + 11);
//API定义
[DllImport("Kernel32.dll")]
public extern static bool FreeLibrary(IntPtr hModule);
[DllImport("user32.dll")]
public extern static IntPtr LoadIcon(IntPtr hInstance, string iID);
/// <summary>
/// 得到输入法说明
/// </summary>
/// <param name="Hkl"></param>
/// <param name="sName"></param>
/// <param name="nBuffer"></param>
/// <returns></returns>
[DllImport("Imm32.dll")]
public extern static int ImmGetDescription(IntPtr Hkl, StringBuilder sName, int nBuffer);
/// <summary>
/// 得到输入法的文件名
/// </summary>
/// <param name="Hkl"></param>
/// <param name="sFileName"></param>
/// <param name="nBuffer"></param>
/// <returns></returns>
[DllImport("Imm32.dll")]
public extern static int ImmGetIMEFileName(IntPtr Hkl, StringBuilder sFileName, int nBuffer);
[DllImport("Kernel32.dll")]
public extern static IntPtr LoadLibraryEx(string sFileName, IntPtr hFile, int dwFlags);
[DllImport("Kernel32.dll")]
public extern static bool EnumResourceNames(IntPtr hModule, IntPtr nType, EnumResNameProc lpEnumFunc, int lParam);
[DllImport("shell32.dll")]
public extern static IntPtr ExtractIcon(IntPtr hInstance, string sExeFileName, int nIconIndex);
[DllImport("user32.dll")]
public extern static IntPtr LoadImage(IntPtr hInstance, string sID, int nType, int cx, int cy, int fuLoad);
#endregion
private void Form17_Load(object sender, EventArgs e)
{
//初始化菜单
InitMenus();
}
void Application_Idle(object sender, EventArgs e)
{
if (this._CurrentImeHandleStr == Application.CurrentInputLanguage.Handle.ToString())
return;
//显示新的输入法
ChangeIme(Application.CurrentInputLanguage.Handle);
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
this.contextMenuStrip1.Show(this.toolStrip1, new Point(0, 0), ToolStripDropDownDirection.AboveRight);
}
/// <summary>
/// 初始化菜单
/// </summary>
private void InitMenus()
{
this.contextMenuStrip1.Items.Clear();
string sLayoutName = "";
foreach (InputLanguage item in InputLanguage.InstalledInputLanguages)
{
sLayoutName = GetImmDescription(item);//item.LayoutName; //
if (string.IsNullOrEmpty(sLayoutName))
{
continue;
}
ToolStripMenuItem oMenuItem = new ToolStripMenuItem();
oMenuItem.Checked = (item.Handle.ToString() == InputLanguage.CurrentInputLanguage.Handle.ToString());
oMenuItem.Text = sLayoutName;
oMenuItem.ToolTipText = sLayoutName;
oMenuItem.Click += new EventHandler(oMenuItem_Click);
oMenuItem.Tag = item;
oMenuItem.Image = GetImeBitmap(item);
this.contextMenuStrip1.Items.Add(oMenuItem);
}
}
/// <summary>
/// 得到指定输入法的说明
/// </summary>
/// <param name="hKl"></param>
/// <returns></returns>
private string GetImmDescription(InputLanguage inpt)
{
int nBuffer = 0;
StringBuilder sName = new StringBuilder();
string sDesc = "";
nBuffer = ImmGetDescription(inpt.Handle, null, nBuffer);
sName = new StringBuilder(nBuffer);
ImmGetDescription(inpt.Handle, sName, nBuffer);
sDesc = sName.ToString();
if (string.IsNullOrEmpty(sDesc))
{
sDesc = inpt.LayoutName;
}
return sDesc;
}
/// <summary>
/// 单击输入法事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void oMenuItem_Click(object sender, EventArgs e)
{
ToolStripMenuItem oItem = (ToolStripMenuItem)sender;
foreach (ToolStripMenuItem item in this.contextMenuStrip1.Items)
{
item.CheckState = CheckState.Unchecked;
}
oItem.CheckState = CheckState.Checked;
Application.CurrentInputLanguage = ((InputLanguage)oItem.Tag);
InputLanauageChangedUI();
}
/// <summary>
/// 得到指定输入法的图标
/// </summary>
/// <param name="ime"></param>
/// <returns></returns>
private Image GetImeBitmap(InputLanguage ime)
{
int nBuffer = 0;
StringBuilder sName;
Image oBitmap = null;
//得到IME文件
nBuffer = ImmGetIMEFileName(ime.Handle, null, nBuffer);
sName = new StringBuilder(nBuffer);
ImmGetIMEFileName(ime.Handle, sName, nBuffer);
if (string.IsNullOrEmpty(sName.ToString()))
{
return Properties.Resources.input;
}
else
{
//从资源文件中得到图标
string sFileName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), sName.ToString());
if (File.Exists(sFileName))
{
oBitmap = GetBitmapFromResource(sFileName, "");
}
if (oBitmap == null)
{
oBitmap = Properties.Resources.input;
}
return oBitmap;
}
}
private Image GetBitmapFromResource(string sFileName, string sBitmapFlag)
{
Bitmap oBitmap = null;
IntPtr hModule = LoadLibraryEx(sFileName, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
if (hModule == IntPtr.Zero)
{
System.Diagnostics.Debug.WriteLine("未能成功加载" + sFileName);
return null;
}
string sName = "IMEICO";
IntPtr hIcon = IntPtr.Zero;
System.Diagnostics.Debug.WriteLine("正在获取" + sFileName + "中所有图标。");
hIcon = ExtractIcon(this.Handle, sFileName, 0);
if (hIcon == IntPtr.Zero)
{
sName = "#101";
hIcon = LoadImage(hModule, sName, IMAGE_ICON, 16, 16, 0);
}
if (hIcon != IntPtr.Zero)
{
System.Diagnostics.Debug.WriteLine(string.Format("Hicon:{0}", hIcon.ToString()));
oBitmap = Icon.FromHandle(hIcon).ToBitmap();
}
EnumResourceNames(hModule, this.MAKEINTRESOURCE(RT_GROUP_ICON), this.EnumIconResourceProc, 0);
//释放
FreeLibrary(hModule);
return oBitmap;
}
private IntPtr MAKEINTRESOURCE(int nID)
{
return new IntPtr((long)((short)nID));
}
private bool EnumIconResourceProc(IntPtr hModule, IntPtr nType, StringBuilder sName, IntPtr lParam)
{
System.Diagnostics.Debug.WriteLine(string.Format("得到的资源名称:{0}", sName));
//得到图标
IntPtr hIcon = LoadIcon(hModule, sName.ToString());
Icon icon = Icon.FromHandle(hIcon);
return true;
}
private void Form17_InputLanguageChanged(object sender, InputLanguageChangedEventArgs e)
{
Application.CurrentInputLanguage = e.InputLanguage;
this.ChangeIme(e.InputLanguage.Handle);
}
/// <summary>
/// 改变输入法函数
/// </summary>
/// <param name="handle"></param>
private void ChangeIme(IntPtr handle)
{
this._CurrentImeHandleStr = handle.ToString();
//改变输入法的状态
foreach (ToolStripMenuItem item in this.contextMenuStrip1.Items)
{
if (((InputLanguage)item.Tag).Handle.ToString() == handle.ToString())
{
item.CheckState = CheckState.Checked;
}
else
{
item.CheckState = CheckState.Unchecked;
}
}
InputLanauageChangedUI();
}
/// <summary>
/// 输入法改变时界面的变化
/// </summary>
private void InputLanauageChangedUI()
{
//改变相应的图标
foreach (ToolStripMenuItem item in this.contextMenuStrip1.Items)
{
if (item.CheckState == CheckState.Checked)
{
this.ToolBtn.Image = item.Image;
this.ToolBtn.ToolTipText = item.Text;
}
}
//重新设置组件的大小
this.toolStrip1.Height = BTN_HEIGHT;
}
下载地址http://download.csdn.net/source/2819817
c# windows程序调用本地输入法的更多相关文章
- [AIR] AIR程序调用本地默认应用程序打开本地文件
摘要: File类提供了一个方法openWithDefaultApplication可以用本地默认应用程序打开指定路径下的文件. 当我用下面语句的时候,可以成功打开桌面文件夹下面的文件: v ...
- AIR程序调用本地默认应用程序打开本地文件
当我用下面语句的时候,可以成功打开桌面文件夹下面的文件: var file:File = File.desktopDirectory.resolvePath("test.jpg") ...
- 自定义浏览器协议,实现web程序调用本地程序
转自 http://blog.csdn.net/talking12391239/article/details/40712759 亲测可用 tencent://Message/?Uin=000000 ...
- Windows程序调用dll
可以写在WndProc的WM_CREATE里面,不能写在WinMain里面
- 网页调用本地程序(Windows下浏览器全兼容)
用网页调用本地应用程序的思路是,先进行注册表注册自定义一个URL Protocol协议,再利用URL Protocol实现网页调用本地应用程序. 1.先写一个注册表文件,将其保存为.reg后缀的注册表 ...
- ubuntu下浏览器调用本地应用程序
ubunut下浏览器调用本地应用程序需要desktop文件和scheme协议的支持,和windows 的url protocol类似,只是注册协议的方式不一样. 首先是desktop文件,里面需要加入 ...
- html网页调用本地exe程序的实现方法:
html网页调用本地exe程序的实现方法:1.新建注册表具体文件: Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\hhtpexe] [ ...
- web调用本地exe应用程序并传入参数
从网页中通过自定义URL Protocol调用本地程序,需要将协议写到注册表中.浏览器在解析到自定义URL Protocol之后,寻找注册表,通过注册表启动相应的程序并传入参数.协议里面需要记录本地程 ...
- PC网页js调用本地应用程序
最近要现实一个在PC网页中实现点击按钮调用本地应用程序的功能 其实实现原理也非常简单, 首先注册一个本地注册表文件,指向本地应用程序路径 其次在网页中用js指向这个注册表文件,就可以实现网页调用本地应 ...
随机推荐
- 【a703】求逆序对(线段树的解法)
Time Limit: 10 second Memory Limit: 2 MB 问题描述 给定一个序列a1,a2...an.如果存在i小于j 并且ai大于aj,那么我们称之为逆序对,求给定序列中逆序 ...
- 数据库使用char要留心
表根据要求需要变更,加一个标识字段,一个字母搞定,我加了一个长度为2的字段 char(2)..... 结果,他们前台开发数据一直不出来,看前台与后台都有记录了,最后发现,此字段我默认加上一个字符,其实 ...
- java获取访问路径、域名、项目名、请求入参
废话不多说(这句不是废话吗>>),直接提出可以运行的类,你放到一个web项目访问下就知道了. //测试页面-跳转到输入数据的form表单 public String test1(){ Ac ...
- Go 快速入门
入门 Go 语言需要多久?答案是 -- 读完这篇文章的时间!不妨找一个周末的下午,踏上 Go 之旅吧! 更新记录: 2016.12.12: 完成重制 2016.11.02: 增加重点理解和参考链接 2 ...
- Python爬虫突破封禁的6种常见方法
转 Python爬虫突破封禁的6种常见方法 2016年08月17日 22:36:59 阅读数:37936 在互联网上进行自动数据采集(抓取)这件事和互联网存在的时间差不多一样长.今天大众好像更倾向于用 ...
- 云平台DevOps实践
基于TFS的.net技术路线的云平台DevOps实践 DevOps是近几年非常流行的系统研发管理模式,很多公司都或多或少在践行DevOps.那么,今天就说说特来电云平台在DevOps方面的实践吧. ...
- CSS知识总结之浏览器
web页面浏览器渲染过程 1.解析html文件,并构建DOM树: 在DOM树中,每一个html标签都有一个对应的节点,并且每一个文本也有一个对应 的节点(js的textNode),DOM树的根节点就是 ...
- bootstrap, boosting, bagging
介绍boosting算法的资源: 视频讲义.介绍boosting算法,主要介绍AdaBoosing http://videolectures.net/mlss05us_schapire_b/ 在这个站 ...
- Windows完成端口与Linux epoll技术简介(能看懂)
WINDOWS完成端口编程1.基本概念2.WINDOWS完成端口的特点3.完成端口(Completion Ports )相关数据结构和创建4.完成端口线程的工作原理5.Windows完成端口的实例代码 ...
- zookeeper 客户端操作
代码 /** * 创建zk客户端 * 实现循环监听的两个必要条件:1.程序不能结束2.递归调用监听器 * @author tele * */ public class Demo { ; //多个节点用 ...