After killing the process for TabletKeyboard(TabTi

2020-02-09 19:23发布

问题:

I have a wpf application which runs on the windows 8 tablet . And in order to bring the keyboard for typing when the focus is on any TextBox.

I am invoking the process TabTip.exe to show the keyboard, and when the keyboard is shown my application shrinks. And after all manipulation, there is a save button. When I click on the save button, the keyboard should disappear and my application should come back to its original size.

I am killing the process TabTip.exe to close the keyboard, but the application will not get re-sized to its original size .

I tried:

if (process.ProcessName == "TabTip")
{
    Application.Current.MainWindow.VerticalAlignment = VerticalAlignment.Stretch;
    process.Kill();
    Application.Current.MainWindow.Height = SystemParameters.WorkArea.Height;
    Application.Current.MainWindow.Width = SystemParameters.WorkArea.Width;
    Application.Current.MainWindow.WindowState = WindowState.Normal;
    Application.Current.MainWindow.WindowState = WindowState.Maximized;
    break;
} 

Does anybody knows to restore the application to its original size after killing the TabTip.exe?

回答1:

The Windows 8 keyboard has a number of rendering problems. These can be mitigated by starting the keyboard in its smaller mode (equivalent to hitting the minimize button). It plays much better with WPF then, actually minimizing and expanding when the process is launched and closed.

This requires launching the process in this mode, and closing it in a nicer way than you are doing right now

Include these libraries:

using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Interop;

And define this external functions:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(int hWnd, uint Msg, int wParam, int lParam);

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(String sClassName, String sAppName);

Open the keyboard with:

public static void openKeyboard()
    {
        ProcessStartInfo startInfo = new ProcessStartInfo(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        myProcess = Process.Start(startInfo);
    }

and close it with:

public static void closeKeyboard()
    {
        uint WM_SYSCOMMAND = 274;
        uint SC_CLOSE = 61536;
        IntPtr KeyboardWnd = FindWindow("IPTip_Main_Window", null);
        PostMessage(KeyboardWnd.ToInt32(), WM_SYSCOMMAND, (int)SC_CLOSE, 0);
    }

This will give you the best behaved windows 8 on screen keyboard you can get. With any luck it will fix your rendering issues.



回答2:

Abin - you asked about closing the keyboard window rather than killing the process. That's what I'm doing in a WPF app and by closing the window, my main application's window will resize as expected. A quick console app to demonstrate hiding the keyboard is here (note that this assumes you're using the keyboard in docked mode rather than the floating minimal mode):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace TabTipTest
{
    class Program
    {
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(String sClassName, String sAppName);

        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        /// <summary>
        /// The command for a user choosing a command from the Window menu (see http://msdn.microsoft.com/en-gb/library/windows/desktop/ms646360(v=vs.85).aspx).
        /// </summary>
        public const int WM_SYSCOMMAND = 0x0112;

        /// <summary>
        /// Closes the window.
        /// </summary>
        public const int SC_CLOSE = 0xF060;

        static void Main(string[] args)
        {
            HideKeyboard();
        }

        /// <summary>
        /// Gets the window handler for the virtual keyboard.
        /// </summary>
        /// <returns>The handle.</returns>
        public static IntPtr GetKeyboardWindowHandle()
        {
            return FindWindow("IPTip_Main_Window", null);
        }

        /// <summary>
        /// Hides the keyboard by sending the window the close command.
        /// </summary>
        public static void HideKeyboard()
        {
            IntPtr keyboardHandle = GetKeyboardWindowHandle();

            if (keyboardHandle != IntPtr.Zero)
            {
                SendMessage(keyboardHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
            }
        }
    }
}