用C#和&移动屏幕键盘(osk.exe)赢得API

时间:2017-02-15 22:09:33

标签: c# windows winapi keyboard on-screen-keyboard

我已经创建了这个小.ps1脚本,因为它允许我在不使用编译器的情况下运行C#(至少直接)。我想移动"辅助功能屏幕键盘"以cmd /c osk.exe打开,因为我无法使用TabTip - Win8 +上的平移触摸屏键盘。

由于屏幕键盘与平板键盘非常相似,我希望键盘移动到所需位置调整大小。我注意到OSK有一个子窗口(OSKMainClassDirectUIHWND),所以我去了,但没有运气。另一方面,单个窗口的相同代码适用于记事本,并正确放置和调整其大小。

我将Process.Start()放入if中,以便它给出一些反馈,因此我看到它找到了子窗口 - 这很好。 但是,它没有移动它。

当我按下Alt+Tab并按住Alt时出现了一个有趣的事情 - OSK窗口看起来像一个灰色的全屏(类似地铁的风格)。我不确定这是否是父窗口的预期行为。

另外,我认为它是窗口样式'很不错,但不是,风格几乎相同(除了两个不相关的风格),所以我没有任何线索如何继续。有什么想法吗?

代码:

$CSsource = @"
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace Win {
    public static class API {
        [DllImport("user32.dll")]
        static extern IntPtr FindWindow(
            string lpClassName,
            string lpWindowName
        );

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindowEx(
            IntPtr parentHwnd,
            IntPtr childAfter,
            string className,
            string windowTitle
        );

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

        [DllImport("user32.dll")]
        static extern bool MoveWindow(
            IntPtr hWnd,
            int X, int Y,
            int Width, int Height,
            bool Repaint
        );

        public static void Move(
            string wClass, string wName,
            string childClass,
            int top, int left,
            int width, int height
        ) {
            IntPtr hwnd = FindWindow(wClass, wName);
            if ((int) hwnd > 0) {
                IntPtr subHwnd;
                if (childClass != String.Empty) {
                    subHwnd = FindWindowEx(hwnd, IntPtr.Zero, childClass, null);
                } else {
                    subHwnd = IntPtr.Zero;
                }

                if ((int) subHwnd > 0) {
                    MoveWindow(subHwnd, left, top, width, height + 50, true);
                    Process.Start("cmd"); //feedback from loop, heh
                } else {
                    MoveWindow(hwnd, left, top, width, height + 50, true);
                }
            }
        }
    }
}
"@

add-type -TypeDefinition $CSsource
#[Win.API]::Move('OSKMainClass', 'On-Screen Keyboard', 'DirectUIHWND', 50, 50, 200, 100)
#[Win.API]::Move('OSKMainClass', 'Accessibility On-Screen Keyboard', 'DirectUIHWND', 50, 50, 200, 100)
[Win.API]::Move('OSKMainClass', 'Accessibility On-Screen Keyboard', '', 50, 50, 200, 100)
[Win.API]::Move('Notepad', 'Untitled - Notepad', '', 50, 50, 200, 100)

OSK窗口样式:

  • WS_CAPTION
  • WS_VISIBLE
  • WS_CLIPSIBLINGS
  • WS_CLIPCHILDREN
  • WS_SYSMENU
  • WS_THICKFRAME
  • WS_OVERLAPPED
  • WS_MINIMIZEBOX
  • WS_EX_LEFT
  • WS_EX_LTRREADING
  • WS_EX_TOPMOST
  • WS_EX_WINDOWEDGE
  • WS_EX_APPWINDOW
  • WS_EX_LAYERED
  • WS_EX_NOACTIVATE

记事本窗口样式:

高于+

  • WS_RIGHTSCROLLBAR
  • WS_ACCEPTFILES

1 个答案:

答案 0 :(得分:3)

OSK在其清单中有UIAccess="true",因此它以更高的完整性级别运行(略高于中等)。

要与之互动,您需要:

  1. 升级您的应用
    1. 在您的清单中放置UIAccess =“true”
    2. 签署.exe(This blog post表示您可以在测试期间自签名)
    3. 将.exe放在Program Files文件夹中的某个位置
    4. 您还可以尝试禁用UAC以验证您是否缺少UIAccess。