如何找到外国窗口并跟踪其位置?

时间:2009-08-30 17:26:48

标签: .net

我希望制作一个简单的应用程序,每隔几毫秒从Skype窗口捕获一次视频。

我的问题是:

  • 如何自动定位窗口手柄?也就是说,这是最好的策略(按名称或?),我如何以编程方式实现?
  • 当用户调整窗口位置/移动它时,如何跟踪窗口位置?

3 个答案:

答案 0 :(得分:2)

如果skype是活动窗口,则可以使用GetForegroundWindow。如果没有,使用进程名称是一个不错的选择。你也可以将它们组合起来,看看你是否得到了相同的窗口句柄。

以下代码将从窗口句柄中抓取图像并将其作为图像保存到磁盘。如果您经常调用此代码并修改代码以创建独特的图像,您将获得几个图像,就像您要求的那样。 GetWindowRect是获取窗口坐标的关键函数。当然,您可以以任何您喜欢的格式保存图像。用于保存图像的WPF函数比此处使用的winform代码更快。

public void GrabActiveWindow()
{   
    IntPtr handle = GetForegroundWindow(); // window handle of active application
    IntPtr handle = WindowsHandleFromProcess("skype.exe");

    RECT screenRect = new RECT();
    GetWindowRect(handle, out screenRect);
    long width = screenRect.Right - screenRect.Left;
    long height = screenRect.Bottom - screenRect.Top;

    Bitmap bmpScreenshot = new Bitmap( (int)width, (int)height, PixelFormat.Format32bppArgb);
    Graphics gfxScreenshot = Graphics.FromImage(bmpScreenshot);
    Size size = new Size((int)width, (int)height );
    gfxScreenshot.CopyFromScreen(screenRect.Left, screenRect.Top, 0, 0, size, CopyPixelOperation.SourceCopy);
    string path = @"c:\savepath.tiff";
    bmpScreenshot.Save(path, ImageFormat.Tiff);
}

public IntPtr WindowsHandleFromProcess(string processName)
{
    foreach (var process in Process.GetProcessesByName(processName))
    {
        return process.MainWindowHandle;
    }
    return IntPtr.Zero;
}

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

答案 1 :(得分:1)

我从未使用过它,但Skype4COM可能会提供帮助。

  

Skype4COM是一个界面   将Skype API表示为对象,   包含属性,命令和事件   和通知。使用Skype4COM   任何ActiveX环境,例如   Visual Studio或Delphi,并使用   熟悉的脚本语言,例如   Visual Basic,PHP或Javascript。

你会在

找到它

https://developer.skype.com/Docs/Skype4COM

答案 2 :(得分:0)

Automating applications using messages的第3页详细介绍了如何查找对话框/窗口等。当我必须控制应用程序时,我发现了一些有用的想法。