简体   繁体   中英

Programmatically control Windows 7 on screen keyboard

I have an application that is to be run on a Windows 7 tablet and needs the on screen keyboard to be docked at the bottom of the screen. Ideally I want to stop someone being able to move or change these settings.

Using the comment posted to the stack overflow answer on here How do I control the text input panel programmatically (TabTip.exe) in Windows Vista/7 I am able to programmatically dock the keyboard to the bottom of the screen so that's a start. I had to run with elevated permission to get it to work

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

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

string onScreenKeyboardPath = @"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe";
var onScreenKeyboardProc = Process.Start(onScreenKeyboardPath);

IntPtr wKB = FindWindow("IPTip_Main_Window", null);

const uint WM_COMMAND = 0x111;
// Where message is 10021 for dock bottom, 10023 for dock top and 10020 for floating
bool x = PostMessage(wKB, WM_COMMAND, new IntPtr(10021), IntPtr.Zero);

I would prefer being able to control the size a bit better than that so I tried to move the window like so:

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

private const uint SWP_SHOWWINDOW = 0x0040;
bool ok = SetWindowPos(wKB, this.Handle, 0, 500, 750, 500, SWP_SHOWWINDOW);

ok returns true but the windows doesn't budge. If I try and do this with notepad it works perfectly. So is it an issue with this particular program?

Your problem can be split in the following parts

1) prevent window from being moved
2) prevent window from being resized
3) prevent window from being minimized

1) seems to be easy: How do you prevent a windows from being moved?

2) & 3) can be solved in the same step.

I have different ideas for a solution:
a) Create a thread that periodically checks if the keyboard window was resized/minimized/moved and reset it's position with (for example) SetWindowPos
How to get and set the window position of another application in C#
b) "Listen" for resize/minimize/move events (WH_CBT = happens BEFORE any of those events) and end it. Sadly, I do not know if and how to forcefully disable events announced through WH_CBT.
There seems to be another solution:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
Scroll down to the comments section, to what user Pavel Shkleinik wrote.
EVENT_SYSTEM_MOVESIZ* and EVENT_SYSTEM_MINIMIZE* seem to be interesting for your case.
You could detect the before events and stop them (If I only knew how) or detect the end of those events and forcefully reset the window position (SetWindowPos).
The Pinvoke Wiki and Google will help you with setting up hooks:
http://www.pinvoke.net/default.aspx/user32.setwineventhook

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM