Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.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# 仅打印屏幕活动窗口_C#_Winforms - Fatal编程技术网

C# 仅打印屏幕活动窗口

C# 仅打印屏幕活动窗口,c#,winforms,C#,Winforms,我正在编写一个简单的Windows窗体实用程序来截图整个屏幕或活动窗口并保存文件。winform有一个名为“捕获”的按钮,单击该按钮可获取屏幕截图 我的代码完全适用于整个屏幕,但无法在活动窗口中找到它 根据我当前的代码,如果我选择“活动窗口”,它最终会打印筛选应用程序本身,这不是我想要的 下面是我在Capture_Click方法下的代码: try { this.Hide(); bmpScreenshot = new Bitmap(

我正在编写一个简单的Windows窗体实用程序来截图整个屏幕或活动窗口并保存文件。winform有一个名为“捕获”的按钮,单击该按钮可获取屏幕截图

我的代码完全适用于整个屏幕,但无法在活动窗口中找到它

根据我当前的代码,如果我选择“活动窗口”,它最终会打印筛选应用程序本身,这不是我想要的

下面是我在Capture_Click方法下的代码:

try
        {
            this.Hide();

            bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
            //bmpScreenshot = new Bitmap(this.Bounds.Width, this.Bounds.Height, PixelFormat.Format32bppArgb);

            gfxScreenshot = Graphics.FromImage(bmpScreenshot);

            if (AltPrint.Checked)
            {
                gfxScreenshot.CopyFromScreen(this.Bounds.X, this.Bounds.Y, 0, 0, this.Bounds.Size, CopyPixelOperation.SourceCopy);
            }
            else
            {
                gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
            }

            bmpScreenshot.Save(SaveLocation, ImageFormat.Png);

            number++;
        }

你需要借用商用屏幕捕捉应用程序的设计,比如Psp。我认为您需要使用“热键”来触发活动窗口的捕获。而不是在捕获时单击事件。这样,您可以隐藏应用程序的窗口,使其不会成为活动窗口。然后,当用户按下“热键”时,您可以捕获它。

您需要借用商用屏幕捕获应用程序的设计,如Psp。我认为您需要使用“热键”来触发活动窗口的捕获。而不是在捕获时单击事件。这样,您可以隐藏应用程序的窗口,使其不会成为活动窗口。然后,当用户按下“热键”时,您可以捕获它。

SendKeys呢

Windows.Forms.SendKeys.Send("%{PRTSC}");
它将当前选定的窗口复制到剪贴板对象

而不是打电话

BitmapSource image = Clipboard.GetImage();
您可以取回图像

SendKeys呢

Windows.Forms.SendKeys.Send("%{PRTSC}");
它将当前选定的窗口复制到剪贴板对象

而不是打电话

BitmapSource image = Clipboard.GetImage();

就我所知,您可以取回图像。您的代码使用其自身形式的边界来捕获活动窗口。那可能不是你想要的

如果您想使用鼠标打印窗口而不是热键(这可能更容易实现),则需要能够从您自己的表单中让用户指向另一个窗口进行捕获。下面是一个描述如何做到这一点的想法:

当用户按下捕获按钮时,捕获鼠标并启动拖动操作。 让用户拖动鼠标,也许现在有一个靶子或相机光标到窗口捕捉。 当用户释放鼠标时,确定它位于顶部的窗口,并使用此窗口的位置和大小捕获正确的像素。 您可能需要使用p/Invoke来获取有关桌面上所有顶级窗口的信息


请注意,鼠标捕获与屏幕捕获非常不同。当应用程序捕获鼠标时,它拥有鼠标光标的所有权,即使鼠标移动到应用程序窗口的边界之外,也无法跟踪鼠标。

据我所知,您的代码使用其自身形式的边界来捕获活动窗口。那可能不是你想要的

如果您想使用鼠标打印窗口而不是热键(这可能更容易实现),则需要能够从您自己的表单中让用户指向另一个窗口进行捕获。下面是一个描述如何做到这一点的想法:

当用户按下捕获按钮时,捕获鼠标并启动拖动操作。 让用户拖动鼠标,也许现在有一个靶子或相机光标到窗口捕捉。 当用户释放鼠标时,确定它位于顶部的窗口,并使用此窗口的位置和大小捕获正确的像素。 您可能需要使用p/Invoke来获取有关桌面上所有顶级窗口的信息


请注意,鼠标捕获与屏幕捕获非常不同。当应用程序捕获鼠标时,它拥有鼠标光标的所有权,即使鼠标移动到应用程序窗口的边界之外,它也无法跟踪鼠标。

您的评论似乎理解,一旦您的应用程序在单击鼠标时获得焦点,另一个应用程序就会丢失鼠标,不再处于“活动”状态

一种可能的替代方法是:当应用程序获得焦点时,它会收到一条消息。该消息的wParam是刚刚放弃焦点的窗口的句柄,该窗口属于您想要捕获的应用程序


当然,该窗口将只是一个子窗口或控件,但您可以确定哪个应用程序拥有该按钮。

您的评论似乎理解,一旦您的应用程序在单击时获得焦点,另一个应用程序就会丢失该按钮,不再“活动”

一种可能的替代方法是:当应用程序获得焦点时,它会收到一条消息。该消息的wParam是刚刚放弃焦点的窗口的句柄,该窗口属于您想要捕获的应用程序

当然,该窗口将只是一个子窗口或控件,但您可以确定哪个应用程序拥有该按钮。

在您的按钮单击方法中,要捕获正在捕获的窗口以外的窗口,我看到的唯一可能的方法是使用user32 Windows API

您首先需要在平台上调用一些met 像这样的人:

[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, GetWindowLongNIndex nIndex);
我建议您提供更多关于这方面的信息

下面是我自己正在进行的窗口类工作,但可以使用,欢迎您将其用作示例:

其中对您有用的属性包括:

获取所有窗口 获取TaskbarWindows 先发制人 您需要获取当前窗口的句柄,使用get-ForegroundWindow,然后使用handle属性,然后找到要捕获其映像的窗口,可能需要使用与TaskbarWindows中类似的代码。一旦你有了这个窗口,你将需要再次发送按键Alt+PrtScn,也许是使用USER32API,但我不想讨论它。然后使用静态ForegroundWindow属性,使用在开始时保存的句柄将原始窗口设置为放弃窗口

祝你好运

在button\u Click方法中,要捕获正在捕获的窗口以外的窗口,我能看到的唯一可能的方法是使用user32 Windows API

您首先需要在平台上调用以下方法:

[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, GetWindowLongNIndex nIndex);
我建议您提供更多关于这方面的信息

下面是我自己正在进行的窗口类工作,但可以使用,欢迎您将其用作示例:

其中对您有用的属性包括:

获取所有窗口 获取TaskbarWindows 先发制人 您需要获取当前窗口的句柄,使用get-ForegroundWindow,然后使用handle属性,然后找到要捕获其映像的窗口,可能需要使用与TaskbarWindows中类似的代码。一旦你有了这个窗口,你将需要再次发送按键Alt+PrtScn,也许是使用USER32API,但我不想讨论它。然后使用静态ForegroundWindow属性,使用在开始时保存的句柄将原始窗口设置为放弃窗口


祝你好运

我最终选择了另一条路线

我允许用户调整我的窗体窗口的大小,以完全覆盖他们需要截图的区域,然后当他们单击按钮时,窗体将隐藏自己,获取它所覆盖区域的截图并再次显示。与我最初的计划相反,我相信这会更加有益,因为我所在的超频论坛上我的目标用户朋友很少只拍摄一个窗口的屏幕截图。他们主要需要几个窗口覆盖的温度监控、时钟速度监控、稳定性测试等

谢谢大家的回答。他们确实让我思考,让我意识到我的选择是什么

如果其他人需要,这是我用于按钮的代码,该按钮仅捕获屏幕的一部分:

        try
        {
            this.Hide();
            Thread.Sleep(250);

            bmpScreenshot = new Bitmap(this.Bounds.Width, this.Bounds.Height, PixelFormat.Format32bppArgb);

            gfxScreenshot = Graphics.FromImage(bmpScreenshot);

            gfxScreenshot.CopyFromScreen(this.Bounds.X, this.Bounds.Y, 0, 0, this.Bounds.Size, CopyPixelOperation.SourceCopy);

            bmpScreenshot.Save(SaveLocation, ImageFormat.Png);

            tbxStatus.AppendText(Environment.NewLine);
            tbxStatus.AppendText(Environment.NewLine);
            tbxStatus.AppendText("Screenshot saved at " + SaveLocation);

            numSuffix++;
        }
        catch (Exception ex)
        {
            tbxStatus.AppendText(Environment.NewLine);
            tbxStatus.AppendText(Environment.NewLine);
            tbxStatus.AppendText("Unable to take screenshot. Exception: " + ex.ToString());
        }
        finally
        {
            this.Show();
        }

我最终选择了另一条路线

我允许用户调整我的窗体窗口的大小,以完全覆盖他们需要截图的区域,然后当他们单击按钮时,窗体将隐藏自己,获取它所覆盖区域的截图并再次显示。与我最初的计划相反,我相信这会更加有益,因为我所在的超频论坛上我的目标用户朋友很少只拍摄一个窗口的屏幕截图。他们主要需要几个窗口覆盖的温度监控、时钟速度监控、稳定性测试等

谢谢大家的回答。他们确实让我思考,让我意识到我的选择是什么

如果其他人需要,这是我用于按钮的代码,该按钮仅捕获屏幕的一部分:

        try
        {
            this.Hide();
            Thread.Sleep(250);

            bmpScreenshot = new Bitmap(this.Bounds.Width, this.Bounds.Height, PixelFormat.Format32bppArgb);

            gfxScreenshot = Graphics.FromImage(bmpScreenshot);

            gfxScreenshot.CopyFromScreen(this.Bounds.X, this.Bounds.Y, 0, 0, this.Bounds.Size, CopyPixelOperation.SourceCopy);

            bmpScreenshot.Save(SaveLocation, ImageFormat.Png);

            tbxStatus.AppendText(Environment.NewLine);
            tbxStatus.AppendText(Environment.NewLine);
            tbxStatus.AppendText("Screenshot saved at " + SaveLocation);

            numSuffix++;
        }
        catch (Exception ex)
        {
            tbxStatus.AppendText(Environment.NewLine);
            tbxStatus.AppendText(Environment.NewLine);
            tbxStatus.AppendText("Unable to take screenshot. Exception: " + ex.ToString());
        }
        finally
        {
            this.Show();
        }

您正在重建PrintScreen和Alt+PrintScreen按键吗?选择活动窗口的确切含义是什么?你是怎么选择的?@Austin:不,我的winform有一个叫做Capture的按钮。点击它,截图。上面粘贴的代码在按钮单击方法中。@rmx:通过单击windows标题栏进行选择。我确实意识到,只要我在winform上单击“捕获”,上一个窗口就不再被选中,因此我正在寻找一种可能的解决方法。xbonez查看我的答案,了解如何准确地执行此操作。您需要学习一些关于p/invoke的知识才能完成此操作。您正在重建PrintScreen和Alt+PrintScreen按键吗?选择活动窗口的确切含义是什么?你是怎么选择的?@Austin:不,我的winform有一个叫做Capture的按钮。点击它,截图。上面粘贴的代码在按钮单击方法中。@rmx:通过单击windows标题栏进行选择。我确实意识到,只要我在winform上单击“捕获”,上一个窗口就不再被选中,因此我正在寻找一种可能的解决方法。xbonez查看我的答案,了解如何准确地执行此操作。要做到这一点,您需要了解一些关于p/invoke的知识。但是当前选择的窗口是他自己的应用程序。但这让我回到了同样的问题。如果我告诉我的应用程序发送Alt_printscreen,按键将获取我表单的屏幕截图。但是当前选择的窗口是他自己的应用程序。但这让我回到了同样的问题。如果我告诉我的应用程序发送Alt_printscreen,按键会截取我的表单。我有另一个想法。请看OP上的评论。我会接受这个答案,就像你一样
你允许拖动和选择的想法给了我当前解决方案的想法。我有另一个想法。请参阅OP上的评论。我将接受这个答案,因为您允许拖动和选择的想法给了我当前解决方案的想法。