C# GetActiveWindow返回0

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

上面的代码似乎返回了一个在其dimensions.Right和dimensions.Left值中包含0的rect。我对winapi的引用如下

        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();
        }
    }
}