Como exibir, ocultar, mover ou redimensionar o Teclado Virtual
Você pode usar Mensagens do Windows para manipular o teclado virtual.
Assim:
WM_CSKEYBOARD = WM_USER + 192;
WM_CSKEYBOARDMOVE = WM_USER + 193;
WM_CSKEYBOARDRESIZE = WM_USER + 197;
// para mostrar o teclado
PostMessage(FindWindow('TFirstForm', 'CKeyboardFirstForm'), WM_CSKEYBOARD, 1, 0);
// fechar o teclado
PostMessage(FindWindow('TFirstForm', 'CKeyboardFirstForm'), WM_CSKEYBOARD, 2, 0);
// para esmaecer o teclado
PostMessage(FindWindow('TFirstForm', 'CKeyboardFirstForm'), WM_CSKEYBOARD, 3, 0);
// alternar (mostrar/ocultar) o teclado
PostMessage(FindWindow('TFirstForm', 'CKeyboardFirstForm'), WM_CSKEYBOARD, 4, 0);
// mover o teclado (Left, Top - nova posição)
PostMessage(FindWindow('TFirstForm', 'CKeyboardFirstForm'), WM_CSKEYBOARDMOVE, Left, Top);
// redimensionar o teclado
PostMessage(FindWindow('TFirstForm', 'CKeyboardFirstForm'), 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
'Código para mostrar o teclado Dim hWnd As Long hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm") PostMessage hWnd, WM_CSKEYBOARD, 1, 0
'Código para fechar o teclado Dim hWnd As Long hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm") PostMessage hWnd, WM_CSKEYBOARD, 2, 0
'Código para mover o teclado Dim hWnd As Long hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm") PostMessage hWnd, WM_CSKEYBOARDMOVE, 0, 0
'Código para redimensionar o teclado Dim hWnd As Long hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm") 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", "CKeyboardFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 1, 0 ); // Mostrar PostMessage(hWnd, WM_CSKEYBOARD, 2, 0); // Ocultar PostMessage(hWnd, WM_CSKEYBOARDMOVE, 0, 0); // Mover para 0, 0 PostMessage(hWnd, WM_CSKEYBOARDRESIZE, 600, 300); // Redimensionar para 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
'Abrir/mostrar o 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", "CKeyboardFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) End Sub
'Fechar o 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", "CKeyboardFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 2, 0) End Sub
'Mover o Comfort On-Screen Keyboard; mova-o primeiro e depois mostre-o Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Dim hWnd As Integer hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm") PostMessage(hWnd, WM_CSKEYBOARDMOVE, 200, 200) PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) End Sub
'Alternar o 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", "CKeyboardFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 4, 0) End Sub
'Esmaecer o 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", "CKeyboardFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 3, 0) End Sub
'Alterar o tipo de teclado e exibi-lo Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click 'Alterar a entrada do Registro para o teclado desejado My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\ComfortSoftware\CKeyboard", "KeyboardName", "Name of your chosen keyboard") 'Abrir o teclado Dim hWnd As Integer hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm") PostMessage(hWnd, WM_CSKEYBOARD, 1, 0) End Sub
'Alterar para outro tipo de teclado e exibi-lo Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click 'Alterar a entrada do Registro para o teclado desejado My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\ComfortSoftware\CKeyboard", "KeyboardName", "Name of another chosen keyboard") 'Abrir o teclado Dim hWnd As Integer hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm") 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) { // Abrir/exibir Comfort On-Screen Keyboard IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 1, 0); } void button2_Click(System::Object^ sender, System::EventArgs^ e) { // Fechar Comfort On-Screen Keyboard IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 2, 0); } void button3_Click(System::Object^ sender, System::EventArgs^ e) { //Mover o Comfort On-Screen Keyboard; mova-o primeiro e depois mostre-o IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm"); PostMessage(hWnd, WM_CSKEYBOARDMOVE, 200, 200); PostMessage(hWnd, WM_CSKEYBOARD, 1, 0); } void button4_Click(System::Object^ sender, System::EventArgs^ e) { //Alternar o Comfort On-Screen Keyboard IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 4, 0); } void button5_Click(System::Object^ sender, System::EventArgs^ e) { //Esmaecer o Comfort On-Screen Keyboard IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm"); PostMessage(hWnd, WM_CSKEYBOARD, 3, 0); } void button6_Click(System::Object^ sender, System::EventArgs^ e) { //Alterar o tipo de teclado e exibi-lo System::Object ^kname="NumPad";
//Alterar a entrada do Registro para o teclado desejado
RegistryKey ^key= Registry::CurrentUser->OpenSubKey ( "Software\\ComfortSoftware\\CKeyboard",true); key->SetValue("KeyboardName",kname);
//Abrir o teclado IntPtr hWnd; hWnd = FindWindow("TFirstForm", "CKeyboardFirstForm"); 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 = "CKeyboardFirstForm"; 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;} } |
Se você não puder usar mensagens do Windows, baixe e experimente estes arquivos:
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 (Formato da linha de comando: MoveKB.exe Left Top)
https://www.comfortsoftware.com/download/SetNameKB.exe (Formato da linha de comando: SetNameKB.exe KeyboardName)
Se você estiver desenvolvendo software de quiosque usando HTML, pode usar as funções especiais do JavaScript para controlar o Teclado Virtual.
Com JavaScript, você pode exibir, ocultar ou mover o teclado. Basta usar as funções especiais de JavaScript para adicionar informações relacionadas ao teclado à legenda do navegador, e o aplicativo monitorará a legenda em busca de alterações.
Baixe aqui o arquivo com funções JavaScript e exemplos: https://www.comfortsoftware.com/commander.html
WM_CSKEYBOARDMOVE: Solução para o problema ao mover o teclado quando se utilizam várias telas com DPI diferentes.
Por exemplo, a Tela 1 tem resolução de 2560x1440 e está definida como "escala de 125%" nas configurações de exibição do Windows. A Tela 2 tem 1920x1080 e está definida como "escala de 100%".
Abra as configurações de compatibilidade de aplicativos do Windows do arquivo CKeyboard.exe e defina o comportamento de DPI como "Aplicativo", o que significa que o aplicativo gerencia todos os cálculos relacionados a DPI. Com essa configuração ativada, você pode passar valores de pixels físicos para a função move da sua API, e a janela do teclado será então movida exatamente para essa posição.
Se você quiser ativar esse modo de compatibilidade de forma programática (por exemplo, com seu próprio instalador), é necessário definir a seguinte chave do registro:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers:
"C:\Program Files\ComfortKeyboard\CKeyboard.exe"="~ HIGHDPIAWARE"
Isso será aplicado a todos os usuários. Como alternativa, você pode colocar esta chave no registro para o usuário atual (HKCU).

