如何显示、隐藏、移动或调整屏幕键盘大小
你可以使用 Windows 消息来操控屏幕键盘。
如下所示:
WM_CSKEYBOARD = WM_USER + 192;
WM_CSKEYBOARDMOVE = WM_USER + 193;
WM_CSKEYBOARDRESIZE = WM_USER + 197;
// 显示键盘
PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARD, 1, 0);
// 关闭键盘
PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARD, 2, 0);
// 淡出键盘
PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARD, 3, 0);
// 切换(显示/隐藏)键盘
PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARD, 4, 0);
// 移动键盘(Left, Top — 新位置)
PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARDMOVE, Left, Top);
// 调整键盘大小
PostMessage(FindWindow('TFirstForm', 'CKeysFirstForm'), WM_CSKEYBOARDRESIZE, Width, Height);
Private Const WM_CSKEYBOARD = WM_USER + 192 Private Const WM_CSKEYBOARDMOVE = WM_USER + 193 Private Const WM_CSKEYBOARDRESIZE = WM_USER + 197
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
'显示键盘的代码 Dim hWnd As Long hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage hWnd, WM_CSKEYBOARD, 1, 0
'关闭键盘的代码 Dim hWnd As Long hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage hWnd, WM_CSKEYBOARD, 2, 0
'移动键盘的代码 Dim hWnd As Long hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage hWnd, WM_CSKEYBOARDMOVE, 0, 0
'调整键盘大小的代码 Dim hWnd As Long hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage hWnd, WM_CSKEYBOARDMOVE, Width, Height |
using System; using System.Windows.Forms; using System.Runtime.InteropServices;
public const Int32 WM_USER = 1024; public const Int32 WM_CSKEYBOARD = WM_USER + 192; public const Int32 WM_CSKEYBOARDMOVE = WM_USER + 193; public const Int32 WM_CSKEYBOARDRESIZE = WM_USER + 197;
[DllImport("user32.dll", EntryPoint = "FindWindow")] private static extern Int32 FindWindow(string _ClassName, string _WindowName);
[DllImport("User32.DLL")] public static extern Boolean PostMessage(Int32 hWnd, Int32 Msg, Int32 wParam, Int32 lParam);
Int32 hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 1, 0 ); // 显示 PostMessage(hWnd, WM_CSKEYBOARD, 2, 0); // 隐藏 PostMessage(hWnd, WM_CSKEYBOARDMOVE, 0, 0); // 移动至 0, 0 PostMessage(hWnd, WM_CSKEYBOARDRESIZE, 600, 300); // 调整大小至 600, 300 |
Const WM_CSKEYBOARD = &H400 + 192 Const WM_CSKEYBOARDMOVE = &H400 + 193 Const WM_CSKEYBOARDRESIZE = &H400 + 197
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
'打开/显示 Comfort On-Screen Keyboard Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim hWnd As Integer hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) End Sub
'关闭 Comfort On-Screen Keyboard Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim hWnd As Integer hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 2, 0) End Sub
'移动 Comfort On-Screen Keyboard;先移动再显示 Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Dim hWnd As Integer hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage(hWnd, WM_CSKEYBOARDMOVE, 200, 200) PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) End Sub
'切换 Comfort On-Screen Keyboard Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click Dim hWnd As Integer hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 4, 0) End Sub
'淡出 Comfort On-Screen Keyboard Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click Dim hWnd As Integer hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 3, 0) End Sub
'更改键盘类型并显示 Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click '更改所需键盘的注册表项 My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\ComfortSoftware\CKeys", "KeyboardName", "Name of your chosen keyboard") '打开键盘 Dim hWnd As Integer hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) End Sub
'切换到其他键盘类型并显示 Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click '更改所需键盘的注册表项 My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\ComfortSoftware\CKeys", "KeyboardName", "Name of another chosen keyboard") '打开键盘 Dim hWnd As Integer hWnd = FindWindow("TFirstForm", "CKeysFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) End Sub |
using namespace System::Runtime::InteropServices; using namespace System::Security::Permissions; using namespace Microsoft::Win32;
const System::UInt32 WM_USER = 1024; const System::UInt32 WM_CSKEYBOARD = WM_USER + 192; const System::UInt32 WM_CSKEYBOARDMOVE = WM_USER + 193;
[DllImport("user32.dll")] extern IntPtr FindWindow(String^ lpClassName, String^ lpWindowName); [DllImport("user32.dll")] extern IntPtr PostMessage(System::IntPtr hWnd, System::UInt32 Msg, int wParam, int lParam); [assembly:RegistryPermissionAttribute(SecurityAction::RequestMinimum, All = "HKEY_CURRENT_USER")];
....blah blah blah you normal code...
void button1_Click(System::Object^ sender, System::EventArgs^ e) { // 打开/显示 Comfort On-Screen Keyboard IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 1, 0); } void button2_Click(System::Object^ sender, System::EventArgs^ e) { // 关闭 Comfort On-Screen Keyboard IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 2, 0); } void button3_Click(System::Object^ sender, System::EventArgs^ e) { //移动 Comfort On-Screen Keyboard;先移动再显示 IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); PostMessage(hWnd, WM_CSKEYBOARDMOVE, 200, 200); PostMessage(hWnd, WM_CSKEYBOARD, 1, 0); } void button4_Click(System::Object^ sender, System::EventArgs^ e) { //切换 Comfort On-Screen Keyboard IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 4, 0); } void button5_Click(System::Object^ sender, System::EventArgs^ e) { //淡出 Comfort On-Screen Keyboard IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 3, 0); } void button6_Click(System::Object^ sender, System::EventArgs^ e) { //更改键盘类型并显示 System::Object ^kname="NumPad";
//更改所需键盘的注册表项
RegistryKey ^key= Registry::CurrentUser->OpenSubKey ( "Software\\ComfortSoftware\\CKeys",true); key->SetValue("KeyboardName",kname);
//打开键盘 IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeysFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 1, 0); } |
/* * This file is heavily based on Jawin: <a href="http://jawinproject.sourceforge.net/" rel="external">http://jawinproject.sourceforge.net/</a> * * assumes ComfortSoftware keyboard is loaded... * */
package client.keyboard;
import java.io.ByteArrayInputStream; import java.io.IOException;
import org.jawin.COMException; import org.jawin.FuncPtr; import org.jawin.ReturnFlags; import org.jawin.io.LittleEndianInputStream; import org.jawin.io.LittleEndianOutputStream; import org.jawin.io.NakedByteStream;
public class ComfortSoftwareKeyboard {
protected static final String COMFORT_SOFTWARE_WINDOW_NAME = "CKeysFirstForm"; protected static final String COMFORT_SOFTWARE_CLASS_NAME = "TFirstForm";
protected static final int WM_USER = 1024; protected static final int WM_CSKEYBOARD = WM_USER + 192; protected static final int WM_CSKEYBOARDMOVE = WM_USER + 193;
protected static final Call FIND_WINDOW = new Call("USER32.DLL", "FindWindowW", "GG:I:", 8); protected static final Call POST_MESSAGE = new Call("USER32.DLL", "PostMessageW", "IIII:I:", 16);
private static ComfortSoftwareKeyboard INSTANCE = new ComfortSoftwareKeyboard();
public static ComfortSoftwareKeyboard getInstance() { return INSTANCE; }
protected int getWindowHandle() throws COMException, IOException { FuncPtr findWindow = null; findWindow = new FuncPtr(FIND_WINDOW.getDllName(), FIND_WINDOW.getFunctionName()); NakedByteStream bs = new NakedByteStream(); LittleEndianOutputStream leo = new LittleEndianOutputStream(bs); leo.writeStringUnicode(COMFORT_SOFTWARE_CLASS_NAME); leo.writeStringUnicode(COMFORT_SOFTWARE_WINDOW_NAME); byte[] b = findWindow.invoke(FIND_WINDOW.getParameterDescription(), FIND_WINDOW.getStackSize(), bs, null, ReturnFlags.CHECK_FALSE); LittleEndianInputStream leis = new LittleEndianInputStream( new ByteArrayInputStream(b)); int l = leis.readInt(); findWindow.close(); return l; }
public int move(int x, int y) throws COMException, IOException { int hWnd = getWindowHandle();
FuncPtr postMessage = null; postMessage = new FuncPtr(POST_MESSAGE.getDllName(), POST_MESSAGE.getFunctionName()); NakedByteStream bs = new NakedByteStream(); LittleEndianOutputStream leo = new LittleEndianOutputStream(bs);
leo.writeInt(hWnd); leo.writeInt(WM_CSKEYBOARDMOVE); leo.writeInt(x); leo.writeInt(y);
byte[] b = postMessage.invoke(POST_MESSAGE.getParameterDescription(), POST_MESSAGE.getStackSize(), bs, null, ReturnFlags.CHECK_FALSE); LittleEndianInputStream leis = new LittleEndianInputStream( new ByteArrayInputStream(b)); int l = leis.readInt(); postMessage.close(); return l; }
public int setVisible(boolean visible) throws COMException, IOException { int hWnd = getWindowHandle();
FuncPtr postMessage = null; postMessage = new FuncPtr(POST_MESSAGE.getDllName(), POST_MESSAGE.getFunctionName()); NakedByteStream bs = new NakedByteStream(); LittleEndianOutputStream leo = new LittleEndianOutputStream(bs);
leo.writeInt(hWnd); leo.writeInt(WM_CSKEYBOARD); leo.writeInt(visible ? 1 : 2); leo.writeInt(0);
byte[] b = postMessage.invoke(POST_MESSAGE.getParameterDescription(), POST_MESSAGE.getStackSize(), bs, null, ReturnFlags.CHECK_FALSE); LittleEndianInputStream leis = new LittleEndianInputStream( new ByteArrayInputStream(b)); int l = leis.readInt(); postMessage.close(); return l; }
public static void main(String[] args) throws Exception { try { ComfortSoftwareKeyboard keyboard = ComfortSoftwareKeyboard.getInstance(); keyboard.setVisible(true); Thread.sleep(1000); keyboard.setVisible(false); Thread.sleep(1000); keyboard.setVisible(true); for (int i = 0; i < 100;i++) { keyboard.move(i, i); } } catch (COMException e) { } finally { } } }
class Call { private int stackSize; private String functionName; private String parameterDescription; private String dllName;
public Call(String dllName, String functionName, String parameterDescription, int stackSize) { this.stackSize = stackSize; this.functionName = functionName; this.parameterDescription = parameterDescription; this.dllName = dllName; } public int getStackSize() {return stackSize;} public String getFunctionName() {return functionName;} public String getParameterDescription() {return parameterDescription;} public String getDllName() {return dllName;} } |
如果您无法使用 Windows 消息,请下载并尝试以下文件:
https://www.comfortsoftware.com/download/ShowKB.exe
https://www.comfortsoftware.com/download/HideKB.exe
https://www.comfortsoftware.com/download/ToggleKB.exe
https://www.comfortsoftware.com/download/MoveTopKB.exe
https://www.comfortsoftware.com/download/MoveBottomKB.exe
https://www.comfortsoftware.com/download/MoveLeftKB.exe
https://www.comfortsoftware.com/download/MoveRightKB.exe
https://www.comfortsoftware.com/download/MoveKB.exe (命令行格式:MoveKB.exe Left Top)
https://www.comfortsoftware.com/download/SetNameKB.exe (命令行格式:SetNameKB.exe KeyboardName)
如果你正在使用 HTML 编写展示终端软件,可以使用特殊的 JavaScript 函数来控制屏幕键盘。
使用 JavaScript,你可以显示、隐藏或移动键盘。只需使用特殊的 JavaScript 函数将与键盘相关的信息添加到浏览器标题中,应用程序将监视标题的更改。
从此处下载包含 JavaScript 函数和示例的文件: https://www.comfortsoftware.com/commander.html
WM_CSKEYBOARDMOVE:解决在使用不同 DPI 的多个屏幕时移动键盘的问题。
例如,屏幕 1 的分辨率为 2560x1440,在 Windows 显示设置中设置为 "125% 缩放"。屏幕 2 的分辨率为 1920x1080,设置为 "100% 缩放"。
打开 CKeys.exe 文件的 Windows 10 应用兼容性设置,并将 DPI 行为设置为"Application",这意味着应用程序管理所有与 DPI 相关的计算。启用此设置后,您可以将物理像素值传递给 API 的移动函数,键盘窗口将准确移动到该位置。
如果你想以编程方式激活此兼容模式(例如,通过你自己的安装程序),你需要设置以下注册表键:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers:
"C:\Program Files\ComfortKeys\CKeys.exe"="~ HIGHDPIAWARE"
这将适用于所有用户。或者,你可以将此项放在当前用户的注册表中 (HKCU)。

