我正在使用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;
现在所有应用程序返回正确的宽度和高度,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);
OR
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并且不返回false值,表明句柄确实是正确的句柄。
所以看来这个应用程序无法通过windowsAPI设置或获取windowsize,任何人都有任何线索可能会出现这种情况?
roclink.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
这也会被忽略,应用程序不会以全屏方式打开,只是上次打开的大小。
编辑:我能想出的唯一解决方案是复制roclink.exe并手动全屏打开然后关闭它,提供没有人打开这个文件它将始终全屏打开,这是狡猾的我不喜欢它,但除非有人有任何想法,为什么会这样,我可能不得不这样做。 :(
答案 0 :(得分:5)
我认为很明显,在您的应用程序中,MainWindowHandle
不是应用程序启动的实际“主窗口”。
答案 1 :(得分:4)
查看这个RockLink800应用程序的屏幕截图,似乎这是一个Delphi应用程序,旧版本的Delphi有一个隐藏的窗口,即Application.Handle。
以下是如何获取旧Delphi应用程序的主窗口句柄的答案: