GetWindowRect 在一个应用程序上返回错误的值,所有其他应用程序都是正确的

本文关键字:应用程序 其他 返回 一个 GetWindowRect 程序上 应用 错误 | 更新日期: 2023-09-27 18:32:36

我正在使用Windows API中的GetWindowRect来获取正在运行的应用程序的边界,然后使用这些边界来截取应用程序的屏幕截图。

我的代码适用于我测试过的大约 10 个程序、记事本和其他一些程序.exe但是我想将其与 RocLink800 一起使用的一个应用程序,无论应用程序位置如何,它都会返回不正确的静态值。

代码是 C# .NET

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int X;
        public int Y;
        public int Width;
        public int Height;
    }
    [DllImport("user32.dll", SetLastError = true)]
    static extern bool GetWindowRect(IntPtr hWnd, ref RECT Rect);
    IntPtr error = GetWindowRect(proc.MainWindowHandle, ref rect);
    ... main code
    while (error == (IntPtr)0)
    {
        error = GetWindowRect(proc.MainWindowHandle, ref rect);
    }
    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top;

现在所有应用程序都返回正确的宽度和高度,使用 roclink800 它返回错误值 1 表示成功,但无论应用程序位置如何,它都会返回以下值:

右边 = 960左矩形 = 960矩形底部 = 600rect.top = 600

我完全不知道为什么会发生这种情况或如何纠正它,roclink800 是从 windows95 天移植的旧程序,所以也许它正在使用一些奇怪的 API,如果是这种情况,是否有任何替代方案从 windows API(user32.dll(获取其屏幕坐标?

我想我可以强制应用程序全屏并以这种方式进行屏幕截图,但它不那么优雅。

有人的想法吗?

编辑:我获取句柄的代码

        Process roclink = new Process();
        roclink.StartInfo.FileName = "C:/Program Files (x86)/ROCLINK800/Roclink.exe";
        //roclink.StartInfo.FileName = "notepad.exe";
        roclink.Start();
        IntPtr error = GetWindowRect(roclink.MainWindowHandle, ref rect);

        try
        {
            proc = Process.GetProcessesByName("roclink")[0];
        }
        catch (IndexOutOfRangeException e)
        {
            return null;
        }

两个代码块都返回相同的 IntPtr,它们都返回 960,960,600,600,但是如果我调用

int error = SetWindowPos(roclink.MainWindowHandle, HWND_TOPMOST, 0, 0, 25,50, SWP_SHOWWINDOW);

然后我得到返回的坐标为 0,0,25,50,但应用程序大小没有改变。

我尝试破坏程序,关闭roclink,SetWindowPos和GetWindowRect都返回0并且不返回假值,表明句柄确实是正确的句柄。

因此,似乎此应用程序无法通过WindowsAPI设置其窗口大小或获取,任何人都有任何线索,为什么会这样?

roclink.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;

这也将被忽略,应用程序不会全屏打开,只需上次打开的大小即可。

编辑:我能想到的唯一解决方案是制作 roclink 的副本.exe然后手动全屏打开它然后关闭它,前提是没有其他人打开这个文件,它将始终全屏打开,这是狡猾的,我不喜欢它,但除非有人有任何想法,为什么会这样,我可能不得不这样做。 :(

GetWindowRect 在一个应用程序上返回错误的值,所有其他应用程序都是正确的

我认为很明显

,在您的应用程序的情况下,MainWindowHandle不是应用程序启动的实际"主窗口"。

查看此 RockLink800 应用程序的屏幕截图,似乎这是一个 Delphi 应用程序,而旧版本的 Delphi 有一个隐藏窗口,即 Application.Handle。

这是一个如何获取旧德尔福应用程序主窗口句柄的 SO 答案:

检索德尔福窗口句柄