为了方便控制软键盘的打开和关闭,自己写了个帮助类。
该类仅对外暴露三个方法,其接口如下:
public interface ISoftKeyHelper
{
///
/// 检测软键盘是否已经打开了
///
/// 如果打开,返回true,否则返回false
bool IsKeyboardOpen();
///
/// 打开软键盘。调用之前应先通过IsKeyboardOpen()来检查keyboard是否已经被打开,
/// 如果已经打开,就不要再打开了
///
void OpenKeyBoard();
///
/// 关闭软键盘
///
void CloseKeyBoard();
}
使用方法如下(注:需要把c:\Windows\System32\osk.exe文件拷贝到当前应用程序的执行目录中去):
//该方法负责打开或关闭软键盘。如果已经打开,则关闭之;反之则打开
private void KeyboardButton_Click(object sender, RoutedEventArgs e)
{
if(SKHelper.IsKeyboardOpen())
{
SKHelper.CloseKeyBoard();
}
else
{
SKHelper.OpenKeyBoard();
// textBox.Focus(); //如果需要打开软键盘的同时使得某个输入框获得焦点,则此处可以调用Focus()方法
}
}
//软键盘帮助类的对象
private ISoftKeyHelper SKHelper = new SoftKeyHelper();
具体的实现如下:
///
/// 软件盘打开或关闭的帮助类,暴露了IsKeyboardOpen()、OpenKeyBoard()和CloseKeyboard()
///
public class SoftKeyHelper: ISoftKeyHelper
{
private const int WM_CLOSE = 0x0010;
///
/// 检测软键盘是否已经打开了
///
/// 如果打开,返回true,否则返回false
public bool IsKeyboardOpen()
{
if (_softKeyboardProc == null)
return false;
return !_softKeyboardProc.HasExited;
//以下是采用检查是否存在主窗口来判断是否打开
//int id = _softKeyboardProc.Id;
//IntPtr ptr = GetMainWindowHandle(_softKeyboardProc.Id); //通过检查其主窗口是否还在。也可以用Process.HasExited属性
//return ptr != IntPtr.Zero;
}
///
/// 打开软键盘。调用之前应先通过IsKeyboardOpen()来检查keyboard是否已经被打开,如果已经打开,就不要再打开了
///
public void OpenKeyBoard()
{
string oskFileName =Path.Combine(Environment.CurrentDirectory,"osk.exe");
if (!System.IO.File.Exists(oskFileName))
{
MessageBox.Show("软键盘可执行文件osk.exe不存在!");
return;
}
try
{
// Start a process and raise an event when done.
_softKeyboardProc = new System.Diagnostics.Process();
_softKeyboardProc.StartInfo.FileName = oskFileName;
_softKeyboardProc.EnableRaisingEvents = true; //允许退出
_softKeyboardProc.Exited += new EventHandler(SoftKeyboard_Exited); //如果退出,则调用回调函数来关闭对象
_softKeyboardProc.Start();
}
catch (Exception ex)
{
Console.WriteLine("打开文件 \"{0}\" 时发生错误:" + "\n" + ex.Message, oskFileName);
return;
}
System.Threading.Thread.Sleep(100);
_keyBoardWindowHwnd = GetMainWindowHandle(_softKeyboardProc.Id);
if (_keyBoardWindowHwnd != IntPtr.Zero)
{
}
//设定键盘显示位置
//NativeMethods.MoveWindow(_keyBoardWindowHwnd, posX, posY, 1000, 400, true);
//将键盘设置于顶面
// NativeMethods.SetWindowPos(_keyBoardWindowHwnd, -1, 0, 0, 0, 0, 1 | 2);
//设置软键盘到前端显示
// NativeMethods.SetForegroundWindow(_keyBoardWindowHwnd);
}
///
/// 关闭软键盘
///
public void CloseKeyBoard()
{
if (_softKeyboardProc != null)
{
try
{
_softKeyboardProc.Kill();//虽然_softKeyboardProc!=null存在,也不代表进程没有被关闭。如果进程已经被关闭,则调用Kill会抛出异常
}
catch
{ }
_softKeyboardProc.Dispose();
_softKeyboardProc = null;
_keyBoardWindowHwnd = IntPtr.Zero;
}
}
///
/// 当键盘被手工关闭的时候,调用该函数,关闭_softKeyboardProc对象并将_keyBoardWindowHwnd置为IntPtr.Zero
///
///
///
private void SoftKeyboard_Exited(object sender, EventArgs e)
{
if (_softKeyboardProc != null)
{
_softKeyboardProc.Dispose();
_softKeyboardProc = null;
_keyBoardWindowHwnd = IntPtr.Zero;
}
}
///
/// 根据进程ID,获取其主窗口
///
///
///
private static IntPtr GetMainWindowHandle(int processId)
{
IntPtr MainWindowHandle = IntPtr.Zero;
NativeMethods.EnumWindows(new NativeMethods.EnumWindowsProc((hWnd, lParam) =>
{
IntPtr PID;
NativeMethods.GetWindowThreadProcessId(hWnd, out PID);
if (PID == lParam && NativeMethods.IsWindowVisible(hWnd) && NativeMethods.GetWindow(hWnd, NativeMethods.GW_OWNER) == IntPtr.Zero)
{
MainWindowHandle = hWnd;
return false;
}
return true;
}), new IntPtr(processId));
return MainWindowHandle;
}
///
/// 进程对象
///
private System.Diagnostics.Process _softKeyboardProc;
///
/// 主窗口句柄
///
private IntPtr _keyBoardWindowHwnd = IntPtr.Zero;
}
public static class NativeMethods
{
[DllImport("User32.dll", EntryPoint = "FindWindow")]
public extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
[System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "MoveWindow")]
public static extern bool MoveWindow(System.IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
public const uint GW_OWNER = 4;
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hWnd, out IntPtr lpdwProcessId);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindowVisible(IntPtr hWnd);
}