簡體   English   中英

使用C#和Win API移動屏幕鍵盤(osk.exe)

[英]Move On-Screen Keyboard (osk.exe) with C# & Win API

我已經制作了這個小的.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

OSK在其清單中具有UIAccess="true" ,因此它以更高的完整性級別運行(略高於中等)。

要與它進行交互,您需要:

  1. 升級運行您的應用

要么

  1. 將UIAccess =“true”放入清單中
  2. 簽署.exe( 此博客文章表明您可以在測試期間自簽名)
  3. 將.exe放在Program Files文件夾中的某個位置

您還可以嘗試禁用UAC以驗證您是否缺少UIAccess。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM