3
votes

I am trying to reposition the TabTib keyboard without success the SetWindowPos function returns "True" but the keyboard is not moving. I am using C# on windows 7.

` [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
    int Y, int cx, int cy, uint uFlags);

    [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    [DllImport("user32.dll")]
    static extern IntPtr FindWindow(string ClassName, string WindowName);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left;        // x position of upper-left corner
        public int Top;         // y position of upper-left corner
        public int Right;       // x position of lower-right corner
        public int Bottom;      // y position of lower-right corner
    }

    Rectangle KeyboardRect;
    IntPtr TabTipHandle;

   IntPtr GetWindowHandle()
    {
        return FindWindow("IPTip_Main_Window",null);
    }

   bool MoveKeyBoard(IntPtr hWnd, int ToX, int ToY)
    {
       return SetWindowPos(hWnd, this.Handle, ToX, ToY, KeyboardRect.Width, KeyaboardRect.Height, 0x0045);
    }
    void StartKeyboard()
    {
        Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
        TabTipHandle = GetWindowHandle();
        KeyboardRect = GetKeyboardRect(TabTipHandle);
        textBox1.Text = KeyaboardRect.Top.ToString() + ", " + KeyboardRect .Left.ToString()      + ", " + KeyboardRect .Width.ToString() + ", " + KeyboardRect .Height.ToString();

        MoveKeyBoard(TabTipHandle, 100, 100);
        KeyboardRect = GetKeyboardRect(TabTipHandle);
        textBox2.Text = KeyaboardRect.Top.ToString() + ", " + KeyboardRect .Left.ToString()      + ", " + KeyboardRect .Width.ToString() + ", " + KeyboardRect .Height.ToString();
     }
    void button1_Click(object sender, EventArgs e)
    {
      StartKeyboard();
    }
    void button2_Click(object sender, EventArgs e)
    {
        MoveKeyBoard(TabTipHandle, 200, 100);
        KeyboardRect = GetKeyboardRect(TabTipHandle);
        textBox2.Text = KeyboardRect .Top.ToString() + ", " + KeyboardRect .Left.ToString()      + ", " + KeyboardRect .Width.ToString() + ", " + KeyboardRect .Height.ToString();

    }

`

1
Are you sure the handle is the correct one? You can use spyxx.exe program to ensure that the handle returned by FindWindow is the correct oneγηράσκω δ' αεί πολλά διδασκόμε
The handle is OK I used spy++ to check it. I get the same handle by using "Process.GetProcessesByName("TabTip");"ofer

1 Answers

0
votes

It will work if you put a small delay just after creating the process like so:

 Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
 await Task.Delay(150); // Just a tiny delay before continuing
 ...
 MoveKeyBoard(TabTipHandle, 100, 100);
 ...

However now I am facing the curious problem that the keyboard will not be exactly positioned where I want it to be by using SetWindowPos. The window seems to wobble around the point until it stays fixed after several calls to SetWindowPos. Very strange, if you would ask me. In lack of any documentation I searched the registry, because I noted that TabTip.exe will start at the exact same position where it was shutdown. So I found these two DWORD registry values:

HKCU\SOFTWARE\Microsoft\TabletTip\1.7\OptimizedKeyboardRelativeXPositionOnScreen
HKCU\SOFTWARE\Microsoft\TabletTip\1.7\OptimizedKeyboardRelativeYPositionOnScreen

I experimented with those values and it seems that setting both to 50000 before starting the process will position the keyboard's top left corner to the center of the screen. Setting both to 0 will position it exactly in the top left corner and 100000 for both means top right corner accordingly.