Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 窗体处于背景(非焦点)时,Picturebox不刷新_C#_Winforms_Visual Studio_Refresh_Picturebox - Fatal编程技术网

C# 窗体处于背景(非焦点)时,Picturebox不刷新

C# 窗体处于背景(非焦点)时,Picturebox不刷新,c#,winforms,visual-studio,refresh,picturebox,C#,Winforms,Visual Studio,Refresh,Picturebox,目的:通过从该窗口捕获图像并使用计时器在picturebox中显示图像,镜像外部进程的窗口 问题:当我的应用程序处于焦点时,一切都会顺利进行!但是,如果我将焦点切换到另一个窗口(不是从我的应用程序),picturebox将停止刷新图像。当我再次关注我的应用程序时,一切都恢复正常 限制:我需要picturebox继续更新,即使我的应用程序在后台 用于捕获图像并在picturebox中显示的计时器: private void timer_picBOX_refresh_Tick(object send

目的:通过从该窗口捕获图像并使用计时器在picturebox中显示图像,镜像外部进程的窗口

问题:当我的应用程序处于焦点时,一切都会顺利进行!但是,如果我将焦点切换到另一个窗口(不是从我的应用程序),picturebox将停止刷新图像。当我再次关注我的应用程序时,一切都恢复正常

限制:我需要picturebox继续更新,即使我的应用程序在后台

用于捕获图像并在picturebox中显示的计时器:

private void timer_picBOX_refresh_Tick(object sender, EventArgs e)
    {
        pictureBox1.BackgroundImage = PrintScreen.CaptureWindow(GAME_MainHandle);            
        pictureBox1.Refresh();            
    }
类以捕获特定窗口:

public class class_ScreenCapture
{
    public Image CaptureScreen()
    {
        return CaptureWindow(User32.GetDesktopWindow());
    }

    /// <summary>
    /// Creates an Image object containing a screen shot of a specific window
    /// </summary>
    public Image CaptureWindow(IntPtr handle, int imgX = 0, int imgY = 0, int largura = 0, int altura = 0)
    {
        // get te hDC of the target window
        IntPtr hdcSrc = User32.GetWindowDC(handle);
        // get the size
        User32.RECT windowRect = new User32.RECT();
        User32.GetWindowRect(handle, ref windowRect);

        if (largura == 0 || altura == 0)
        {
            largura = windowRect.right - windowRect.left;
            altura = windowRect.bottom - windowRect.top;
        }

        // create a device context we can copy to
        IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
        // create a bitmap we can copy it to,
        // using GetDeviceCaps to get the width/height
        IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, largura, altura);
        // select the bitmap object
        IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
        // bitblt over
        GDI32.BitBlt(hdcDest, 0, 0, largura, altura, hdcSrc, imgX, imgY, GDI32.SRCCOPY);
        // restore selection
        GDI32.SelectObject(hdcDest, hOld);
        // clean up 
        GDI32.DeleteDC(hdcDest);
        User32.ReleaseDC(handle, hdcSrc);

        // get a .NET image object for it
        Image img = Image.FromHbitmap(hBitmap);
        // free up the Bitmap object
        GDI32.DeleteObject(hBitmap);

        return img;
    }        

    /// <summary>
    /// Helper class containing Gdi32 API functions
    /// </summary>
    private class GDI32
    {

        public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter

        [DllImport("gdi32.dll")]
        public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
            int nWidth, int nHeight, IntPtr hObjectSource,
            int nXSrc, int nYSrc, int dwRop);
        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
            int nHeight);
        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern bool DeleteDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);
        [DllImport("gdi32.dll")]
        public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
    }

    /// <summary>
    /// Helper class containing User32 API functions
    /// </summary>
    private class User32
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        [DllImport("user32.dll")]
        public static extern IntPtr GetDesktopWindow();
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowDC(IntPtr hWnd);
        [DllImport("user32.dll")]
        public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);

    }
}
public class\u屏幕截图
{
公共图像捕获屏幕()
{
返回CaptureWindow(User32.GetDesktopWindow());
}
/// 
///创建包含特定窗口的屏幕快照的图像对象
/// 
公共图像捕获窗口(IntPtr句柄,int imgX=0,int imgY=0,int largura=0,int altura=0)
{
//获取目标窗口的te hDC
IntPtr hdcSrc=User32.GetWindowDC(句柄);
//知道尺寸了吗
User32.RECT windowRect=新的User32.RECT();
User32.GetWindowRect(句柄,ref windowRect);
如果(拉古拉==0 | |阿尔图拉==0)
{
largura=windowRect.right-windowRect.left;
altura=windowRect.bottom-windowRect.top;
}
//创建可以复制到的设备上下文
IntPtr hdcDest=GDI32.CreateCompatibleDC(hdcSrc);
//创建一个我们可以复制到的位图,
//使用GetDeviceCaps获取宽度/高度
IntPtr hBitmap=GDI32.CreateCompatibleBitmap(hdcSrc、largura、altura);
//选择位图对象
IntPtr hOld=GDI32。选择对象(hdcDest、hBitmap);
//结束
GDI32.BitBlt(hdcDest,0,0,largura,altura,hdcSrc,imgX,imgY,GDI32.srcopy);
//恢复选择
GDI32.选择对象(hdcDest,保持);
//清理
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(句柄,hdcSrc);
//为它获取一个.NET图像对象
图像img=图像。来自hBitmap(hBitmap);
//释放位图对象
GDI32.DeleteObject(hBitmap);
返回img;
}        
/// 
///包含Gdi32 API函数的帮助器类
/// 
私有类GDI32
{
public const int SRCCOPY=0x00CC0020;//BitBlt dwRop参数
[DllImport(“gdi32.dll”)]
公共静态外部bool BitBlt(IntPtr hObject、intnxtest、intnydest、,
int nWidth、int nHeight、IntPtr hObjectSource、,
int nXSrc、int nYSrc、int dwRop);
[DllImport(“gdi32.dll”)]
公共静态外部IntPtr CreateCompatibleBitmap(IntPtr hDC,int nWidth,
内特(右);
[DllImport(“gdi32.dll”)]
公共静态外部IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport(“gdi32.dll”)]
公共静态外部布尔删除DC(IntPtr hDC);
[DllImport(“gdi32.dll”)]
公共静态外部bool DeleteObject(IntPtr-hObject);
[DllImport(“gdi32.dll”)]
公共静态外部IntPtr SelectObject(IntPtr hDC、IntPtr hObject);
}
/// 
///包含user32api函数的Helper类
/// 
私有类User32
{
[StructLayout(LayoutKind.Sequential)]
公共结构矩形
{
公共int左;
公共int top;
公共权利;
公共int底部;
}
[DllImport(“user32.dll”)]
公共静态外部IntPtr GetDesktopWindow();
[DllImport(“user32.dll”)]
公共静态外部IntPtr GetWindowDC(IntPtr hWnd);
[DllImport(“user32.dll”)]
公共静态外部IntPtr ReleaseDC(IntPtr hWnd、IntPtr hDC);
[DllImport(“user32.dll”)]
公共静态外部IntPtr GetWindowRect(IntPtr hWnd,ref RECT RECT);
}
}
测试它

private void timer_picBOX_refresh_Tick(object sender, EventArgs e)
{
    pictureBox1.Image = PrintScreen.CaptureWindow(GAME_MainHandle);            
    pictureBox1.Refresh();
    Refresh();
}

我想你的问题出在这里
pictureBox1.BackgroundImage
换成
pictureBox1.Image
你能告诉我一些关于桌面交互的更多信息吗。你有一个屏幕吗?如果是这样,如果您“失去焦点”,这是否意味着应用程序不再可见?因为您正在使用GetDesktopWindow()捕获桌面,所以如果要捕获的窗口不可见,则无法捕获它并将其显示在picturebox..background或.image中结果没有差异//没有编译错误。调试运行正常。//我捕获的游戏窗口处于“窗口”模式//我的应用程序仅部分被游戏窗口覆盖//我捕获的不是“屏幕”,而是一个特定的窗口(通过主手柄和DC兼容)。重要提示:记事本、计算器、webbrowser等窗口不会出现此问题。仅在我从中捕获图像的游戏窗口(directx游戏窗口)中发生,就像当焦点位于游戏窗口时,我的应用程序在视觉上被冻结一样。我认为picturebox实际上正在更新,但你看不到它,因为在游戏获得焦点后,你从游戏中捕获的图像总是相同的。我会尝试在你的图片盒中显示随机图像,看看是否是这样。由于DirectX直接渲染到屏幕,因此可能无法使用win api捕获游戏屏幕。当游戏不对焦时,Windows可能会从图形卡下载图像,以提供某种预览(例如在任务栏中),当游戏对焦时不再需要这种预览。