2017-02-15 279 views
0

我已经制作了这个小小的.ps1脚本,因为它允许我在不使用编译器(至少直接)的情况下运行C#。我想移动“无障碍屏幕键盘”,以cmd /c osk.exe打开,因为我无法真正使用TabTip - Win8 +上的平移触摸屏键盘。使用C#&Win API移动屏幕键盘(osk.exe)

由于屏幕键盘是不是真的那么漂亮像平移的键盘,我想移动键盘到所需的位置调整其大小。我注意到OSK有一个子窗口(OSKMainClassDirectUIHWND),所以我甚至为此付出了代价,但没有运气。另一方面,单个窗口的相同代码适用于记事本,并正确放置并调整其大小。

我把Process.Start()纳入if,这样它就给出了一些反馈,所以我看到它找到了子窗口 - 那很好。 但是,它没有移动它。

当我按下Alt+Tab并保持Alt时,出现了一个有趣的事情 - OSK窗口显示为灰色全屏(类似于metro的风格)。我不确定这是否是父窗口的预期行为。另外,我认为它会是窗口风格的东西,但不是,风格几乎相同(除了两个不相关的风格),所以我没有任何线索如何继续。有任何想法吗?

代码:

$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

回答

3

OSK已在其清单所以它运行在一个解释第1条r完整性等级(略高于中等)。

与它进行交互,你需要:

  1. 运行你的应用程序提升
在您的清单
    1. 将UIAccess = “真” 签署。 exe(This blog post表示您可以在测试过程中自行签名)
    2. 把.exe文件的某处Program Files文件夹

    里面你也可以尝试禁用UAC来验证你缺乏UIAccess的是这个问题。

  • +0

    是的,那很可能是我错过的东西。你有没有尝试运行脚本提升?我不确定我是否可以编写和签名,因为我打算从PowerShell中运行。 – KeyWeeUsr