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

rol*_*lls 2 .net c# windows winapi

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

我的代码适用于我测试的大约10个程序,notepad.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;
Run Code Online (Sandbox Code Playgroud)

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

rect.right = 960 rect.left = 960 rect.bottom = 600 rect.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);
Run Code Online (Sandbox Code Playgroud)

要么

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

两个代码块返回相同的IntPtr,如果我打电话,它们都返回960,960,600,600

int error = SetWindowPos(roclink.MainWindowHandle, HWND_TOPMOST, 0, 0, 25,50, SWP_SHOWWINDOW);
Run Code Online (Sandbox Code Playgroud)

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

我试过破解程序,关闭roclink,SetWindowPos和GetWindowRect都返回0并且不返回false值,表明句柄确实是正确的句柄.

因此,似乎这个应用程序不能通过windowsAPI设置或获取它,任何人都有任何线索为什么这可能是?

roclink.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
Run Code Online (Sandbox Code Playgroud)

这也被忽略,应用程序不会在全屏打开,只是它上次打开的大小.

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

Rot*_*tem 5

我认为很明显,在您的应用程序的情况下,MainWindowHandle不是应用程序启动的实际"主窗口".


Ant*_*ula 5

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

这是如何获取旧 Delphi 应用程序的主窗口句柄的 SO 答案:

检索 Delphi 窗口句柄