C# GetActiveWindow返回0
上面的代码似乎返回了一个在其dimensions.Right和dimensions.Left值中包含0的rect。我对winapi的引用如下C# GetActiveWindow返回0,c#,winapi,pinvoke,C#,Winapi,Pinvoke,上面的代码似乎返回了一个在其dimensions.Right和dimensions.Left值中包含0的rect。我对winapi的引用如下 IntPtr win = GetActiveWindow(); RECT dimensions; GetWindowRect(win, out dimensions); GetActiveWindow似乎没有返回用户当前选择的窗口。我注意到,如果我将上面的内容改为下面的内容,它似乎会起作用 [Dll
IntPtr win = GetActiveWindow();
RECT dimensions;
GetWindowRect(win, out dimensions);
GetActiveWindow似乎没有返回用户当前选择的窗口。我注意到,如果我将上面的内容改为下面的内容,它似乎会起作用
[DllImport("user32.dll", SetLastError=true)]
static extern IntPtr GetActiveWindow();
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
enum GetWindow_Cmd : uint
{
GW_HWNDFIRST = 0,
GW_HWNDLAST = 1,
GW_HWNDNEXT = 2,
GW_HWNDPREV = 3,
GW_OWNER = 4,
GW_CHILD = 5,
GW_ENABLEDPOPUP = 6
}
[DllImport("user32.dll", SetLastError=true))]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, out 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
}
编辑:带有复选框的代码
IntPtr win = GetForegroundWindow();
RECT dimensions;
GetWindowRect(win, out dimensions);
SSCCE:
IntPtr win = GetActiveWindow();
if (win == IntPtr.Zero)
{
//this triggers
Debug.WriteLine("Win: " + win.ToString());
Debug.WriteLine("Unable to get window handle.");
}
else
{
RECT dimensions;
uint pid;
GetWindowThreadProcessId(win, out pid);
Debug.WriteLine(Marshal.GetLastWin32Error().ToString());
Debug.WriteLine(pid.ToString());
if (GetWindowRect(win, out dimensions))
{
Debug.WriteLine(dimensions.Top.ToString() + ", " + dimensions.Right.ToString() + ", "
+ dimensions.Bottom.ToString() + ", " + dimensions.Left.ToString() + "\nPID: " + pid.ToString());
ScreenCapture sc = new ScreenCapture();
int width = dimensions.Right - dimensions.Left;
int height = dimensions.Bottom - dimensions.Top;
Clipboard.SetImage(sc.CaptureArea(dimensions.Left, dimensions.Top, width, height));
}
else
{
Debug.WriteLine(Marshal.GetLastWin32Error().ToString() + "\nPID:" + pid.ToString());
Debug.WriteLine("Unable to get window dimensions.\nPID:" + pid.ToString());
}
}
这是正常的
GetActiveWindow
获取调用线程的活动窗口。如果调用线程不拥有前台窗口,则GetActiveWindow
返回NULL
我不熟悉C#,但是您确定IntPtr
是HWND
的正确替代品吗?特别是在32位与64位的上下文中。永远不要忽略winapi函数的返回值。您没有友好的.NET异常来避免麻烦,当您pinvoke时,错误检查不是可选的。很可能函数失败了,因为您传递了IntPtr.Zero作为窗口句柄。我可以统计6个API调用,其中您没有检查返回值。您每次调用都无法检查返回值。我不知道你为什么忽视我们检查返回值的建议。文档告诉您要这样做。我们每天都在这里重复这个建议。请检查返回值。我建议您这样做,然后编辑问题以显示更正的代码,并报告检查结果。调试输出如下:Win:0无法获取窗口句柄。
因此,当我按下Win+a时,GetActiveWindow没有返回有效的窗口。我希望您能够直接了解事实。在早期版本中,您声明了一个非零窗口句柄。你的应用程序是一个GUI应用程序。你绝对还没有弄清楚这个问题。你可以使用GetForeGroundIndow而不是GetActiveWindow
using System;
using System.Runtime.InteropServices;
namespace GetWindow
{
class Program
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetActiveWindow();
static void Main(string[] args)
{
IntPtr win = GetActiveWindow();
Console.WriteLine("Win: " + win.ToString()); //outputs 0 to console
Console.Read();
}
}
}