我在c#上编写了一个实现鼠标和键盘钩子的程序,一旦指定的键点击它就会抓住前景窗口并将它的x,y,高度和宽度保存到xml文件中。
我不确定出了什么问题,但我的错误尺码和错误的参数仍然存在。
我很感激对这个问题的帮助,因为我现在已经奋斗了两天。
贝娄是相关代码。
标准声明:
//rectangle for the windows size
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
//win API
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow();
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern bool SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetWindowRect(IntPtr hWnd, ref RECT Rect);
相关代码本身
void mouseHook_MouseDown(object sender, MouseEventArgs e)
{
this.handle = GetForegroundWindow();
}
#region keyboard pressed
void keyboardHook_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F9) //if slot selected
{
RECT Rect = new RECT();
SetForegroundWindow(this.handle);
//this.handle = GetForegroundWindow();
GetWindowRect(this.handle, ref Rect);
Grid newSlot = new Grid();
newSlot.topX = Rect.Top;
newSlot.topY = Rect.Left;
newSlot.width = Rect.Right - Rect.Left;
newSlot.height = Rect.Bottom - Rect.Top;
layoutGrid.Add(newSlot);
lbl_slots.Text = layoutGrid.Count().ToString();
}
else if (e.KeyCode == Keys.F10) //if main stack slot selected
{
RECT Rect = new RECT();
SetForegroundWindow(handle);
GetWindowRect(GetForegroundWindow(), ref Rect);
for (int i = 0; i < layoutGrid.Count(); i++) //selecting slot for main stack
{
layoutGrid[i].slot_number = i + 1; //setting slots numbers
if (layoutGrid[i].topX != Rect.Top && layoutGrid[i].topY != Rect.Left)
layoutGrid[i].is_stack = false;
else
{
layoutGrid[i].is_stack = true;
lbl_stackSlot.Text = (i + 1).ToString();
}
}
}
}
修改 我试图同时使用公共结构RECT和Rectangle,我收到的RECT值似乎是随机的,我的意思是左边和顶部以及高度和宽度,有时它会找到合适的点,但有时它看起来完全是随机的。我使用Rectangle接收的值似乎有正确的左侧和顶部但返回错误的高度和宽度。
答案 0 :(得分:2)
我终于找到了解决方案。如果有人遇到同样的问题,想出来就会在这里发布。
我最终使用了GetWindowInfo而不是GetWindowRect,它就像魅力一样。
从我在网上http://kenneththorman.blogspot.com/2010/08/c-net-active-windows-size-helper.html
找到的代码示例和文章感谢所有试图提供帮助的人。
答案 1 :(得分:0)
使用System.Drawing.Rectangle
不正确。字段不匹配。您对RECT
的定义是正确的。
我猜一点,但您的问题可能与GetWindowRect
MSDN主题底部的评论有关。
Vista下未与WINVER = 6链接的应用程序将在此处收到一组误导性值,这些值不会影响Vista Aero应用于窗口的“玻璃”像素的额外填充。即使在Aero Basic(没有玻璃)中也可能出现这种情况,以保持尺寸一致性。解决方法(如果你不想设置WINVER = 6)似乎是动态绑定到dwmapi.dll并使用GetProcAddress()来获取DwmGetWindowAttribute()函数,并使用DWMWA_EXTENDED_FRAME_BOUNDS参数调用它来请求真正的窗口框架尺寸。