无法使GetWindowRect()API调用正常工作

时间:2015-03-30 04:30:25

标签: c# wpf winapi pinvoke

我需要能够获得Windows 8.1屏幕键盘的高度,“TabTip.exe”。到目前为止,我已经设法随意打开和关闭它,但现在我还需要达到它的高度,以便我可以在我的应用程序中补偿它。我在靠近窗口底部的TextBox控件被键盘覆盖了。

所有使用Win API调用“GetWindowRect”的尝试都失败了。

代码放在类定义的开头:

private const string OnScreenKeyboardName = "TabTip";

DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(HandleRef hWnd, ref 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
}

代码放在Window中的一个事件处理程序中:

RECT rct = new RECT();

if (Process.GetProcessesByName(OnScreenKeyboardName).Length > 0)
{
   Process[] Processes = Process.GetProcessesByName(OnScreenKeyboardName);
   foreach (Process pOnScreenKeyboard in Processes)
   {
      if (!GetWindowRect(new HandleRef(this, pOnScreenKeyboard.Handle), ref rct))
      {
         MessageBox.Show("ERROR");
         return;
      }
      MessageBox.Show(rct.ToString());
   }
}

与大多数示例一致,我最初使用“FindWindow”调用来获取TabTip.exe窗口的句柄。这似乎有点好用,但它在最近几天内突然停止工作,所以我切换到“Process.FindByName ......”

我的测试用例涉及将上面的代码(第二部分)放入Window的“MouseMove”事件处理程序中。然后我确保屏幕键盘显示,然后我移动鼠标。这会导致事件触发,然后它总是显示“ERROR”MessageBox,表明“GetWindowRect”返回false(或者有某种错误?

我花了很多时间在Google搜索,p / invoke等上。这很令人沮丧,因为似乎很少有如何正确执行此操作的示例。似乎有一些叫做HandleRef的新东西(我是否正确使用它? - 基本上没有任何例子!!!)

我真的需要让这个工作。有人可以告诉我哪里出错了吗?谢谢!

1 个答案:

答案 0 :(得分:0)

您正在将进程句柄(pOnScreenKeyboard.Handle)传递给GetWindowRect,其中GetWindowRect需要窗口句柄(HWND)。找到这个过程是不够的 - 一个过程可以创建许多窗口,因此你需要找到屏幕键盘的窗口句柄。您可以尝试使用pOnScreenKeyboard.MainWindowHandle,但是从this post,您可能会发现它为空。你说你有一个使用FindWindow的先前解决方案。我会回过头来弄清楚它为什么停止工作。