c# windows程序调用本地输入法

原文: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

?

原文地址:https://www.cnblogs.com/lonelyxmas/p/9184378.html

时间: 2024-11-20 10:13:47

c# windows程序调用本地输入法的相关文章

平板下windows程序调用软键盘的办法

http://stackoverflow.com/questions/21140852/start-tabtip-with-numpad-view-open [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); [D

自定义浏览器协议,实现web程序调用本地程序

转自  http://blog.csdn.net/talking12391239/article/details/40712759 亲测可用 tencent://Message/?Uin=000000&websiteName=qzone.qq.com&Menu=yes Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Tencent\DefaultIcon] @="C:\\Program Files\\Tencent\

windows映射到本地文件夹中,打开程序

windows映射到本地文件夹中,打开程序,是在调用本地程序执行,如果不能删除或修改,是本地程序占用,关闭本地程序即可 实例: 在ubuntu上映射出来的一个文件夹,直接双击了jar文件,实质是调用本地的Java(TM) Platform SE binary程序,找到本地进程javaw,结束掉即可,跟远程 程序 操作 进程无关

编写chrome插件,调用本地应用程序,并进行通讯(发送信息给应用程序)

开发说明 1.浏览器插件实现manifest.json文件内容.每个chrome的插件都需要该文件,该文件记录插件的关键信息 { "name" : "callapp", "version" : "1.0.1", "description" : "call local application", "background" : { "scripts":

html网页调用本地exe程序的实现方法:

html网页调用本地exe程序的实现方法:1.新建注册表具体文件: Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\hhtpexe] [HKEY_CLASSES_ROOT\hhtpexe\defaulticon ]@="C:\\Program Files\\DMEO\\MultimediaDispatch.exe"--exe程序的路径 [HKEY_CLASSES_ROOT\hhtpexe\shell] [HKEY_CLAS

Firefox中利用javascript调用本地程序

http://blog.csdn.net/jensonhjt/article/details/1765557 script>function hello () {  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  var file = Components.classes["@mozilla.org/file/local;1"].createInstance(

windows下调用外部exe程序 SHELLEXECUTEINFO

本文主要介绍两种在windows下调用外部exe程序的方法: 1.使用SHELLEXECUTEINFO 和 ShellExecuteEx SHELLEXECUTEINFO 结构体的定义如下: 1 typedef struct _SHELLEXECUTEINFO { 2 DWORD cbSize; 3 ULONG fMask; 4 HWND hwnd; 5 LPCTSTR lpVerb; 6 LPCTSTR lpFile; 7 LPCTSTR lpParameters; 8 LPCTSTR lpD

Windows批处理 调用程序后 不等待子进程 父进程继续执行命令

从DOS过来的老鸟应该都知道批处理,这个功能在WINDOWS中仍然保留着.批处理 说白了就是把一系列DOS命令写在一个文本文件里,然后把这个文件命名为XXX.bat(WINXP以后的系统也可以命名为*.cmd),然后运行它就可 以一次执行一系列命令和程序了,当然也包括WINDOWS下的程序. 昨天处理一个问题时需要写一个批处理,批处理的前面运行了几个DOS命令,最后调用一 个WINDOWS程序.可问题是,调用的WINDOWS程序打开后,CMD命令提示符窗口不会关闭,而是要等待这个WINDOWS程

Js调用本地程序

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>无标题文档</title> <script language=javascript> function Open() { var wsh=new ActiveXObject("wscript.shell&