单击时捕获并保存屏幕截图 - Windows C#

时间:2013-05-05 07:09:14

标签: c# winapi window screenshot mouse-pointer

首先,对不起这个冗长的问题感到抱歉,但我想确保我包含到目前为止所遇到的所有内容。

我想为教程团队制作一个C#Windows应用程序,作为他们在执行教程步骤时出现的每个窗口按Alt + PrtSc执行的无聊手动任务的替代方法,并将其粘贴到ms绘制以将图像保存到文件夹,以便以后可以将其插入到教程文档中。

有多种方法可以捕获桌面快照或仅捕获部分快照。我甚至可以设法在我的WinForms应用程序中拍摄控件的快照;只要您点击并保存它,就会捕获任何窗口的屏幕截图(以及鼠标指针),结果有点棘手。

我遇到this帖子,其中包含使用Win32 API捕获和保存屏幕截图的详细信息。 Thisthis发布了关于使用.NET Framework保存部分桌面的帖子,它运行良好,但并不完全符合我的需要。我确实遇到过一些免费软件和其他商业软件,这些软件也做了很多,但我更喜欢做一些简单和定制的东西。

现在,我的表单有一个浏览按钮,用于选择文件夹(保存图像)和另一个名为START的按钮。单击时其名称将更改为STOP并保持按下状态(直到再次单击停止)。

说,团队必须整理软件的设置和安装教程,并且向导的欢迎屏幕已启动。启动应用程序后,应保存安装向导的每个窗口的图像(以及鼠标指针),同时单击“继续”,“我接受”,“下一步...下一步”和“完成”等按钮。

我希望我能解释清楚。任何帮助将不胜感激。提前谢谢。

  • GJ

2 个答案:

答案 0 :(得分:1)

尝试输入此内容以保存屏幕截图:

int screenWidth = Screen.PrimaryScreen.Bounds.Width;
int screenHeight = Screen.PrimaryScreen.Bounds.Height;

        Graphics Graphics1;
        Bitmap Bitmap1 = new Bitmap(screenWidth, screenHeight);
        Graphics1 = Graphics.FromImage(Bitmap1);
        Graphics1.CopyFromScreen(Point.Empty, Point.Empty, Screen.PrimaryScreen.Bounds.Size);
        Bitmap1.Save(@"c:\ScreenShot1.bmp); //Place that you want to save screenshot

答案 1 :(得分:0)

我使用autohotkey脚本触发了类似的问题来触发GadWin(http://www.gadwin.com/printscreen/)注意Gadwin仅供个人使用。可以购买商业许可证(25美元)

我也有一些您可能想要的C#代码,这是免费的。

AutoHotKey脚本:     #SingleInstance Force     ;点击屏幕 - 每次点击都是新的屏幕截图     ;记录每次单击鼠标的屏幕截图     ;用于Gadwin或由击键触发的其他屏幕捕获,例如, {} PRINTSCREEN     ; 〜表示通过点击     ;关键切换捕获开启和关闭

; open destination folder
destinationFolder:=GadWinDestinationFolder()
ifExist %destinationFolder%
{
    Run explorer.exe %destinationFolder%
    sleep 1000
}

;; shows an opening message
; TBD could be on a message box to let user choose/acknowledge
ShowStatus("Capture is Enabled.`n<Pause/Break> to toggle on/off", 10000)

; ***  ,% <space> func() is autohotkey magic for interpolate a function here ***
RunWait,% GadWinExe()
sleep 5000

capturing:=true    


Return

; ~ means pass the click & position through to the system
; This allows drag screens to work, while Send LButton does not
; TBS look at MouseGetPos + MouseClickDrag
~LButton::
    Capture()
    ;Send {LButton}
    return

~RButton::
    Capture()
    ;Send {RButton}
    Return 

Capture()
{
    global capturing
    if (capturing)
    {
        ;ClipSaved:=ClipboardAll    ; Save the entire clipboard to a variable 

        ; this may be whacking the clipboard
        ; alt -prt scrn

        Send {PRINTSCREEN}

        ShowStatus("Captured to " GadWinDestinationFolder() "`nPress <Pause/Break> to toggle.", 3000)

        ;Clipboard:=ClipSaved   ; Restore the original clipboard. Note the use of Clipboard (not ClipboardAll).
        ;ClipSaved:=            ; Free the memory in case the clipboard was very large.
    }
    Else
    {
        dp("Capture is off`nPress <Pause/Break> to toggle.")
    }
    Return
}


PAUSE:: CaptureToggle(2000)

CaptureToggle(delay)
{
    global capturing

    Suspend OFF

    capturing:=!capturing

    If (capturing)
    {
        ShowStatus("Capture Enabled.", delay)
    }
    Else
    {
        ShowStatus("Capture Disabled.", delay)
        ;Suspend
    }

    Return
}   

GadWinExe()
{
    RegRead, exeFolder, HKLM, SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Gadwin PrintScreen, InstallLocation
    Return exeFolder "\PrintScreen.exe"
}

GadWinDestinationFolder()
{
    ; Gadwin specific
    RegRead, CaptureDir, HKEY_CURRENT_USER, Software\Gadwin Systems\PrintScreen\Destination, CaptureDir
    Return CaptureDir
}

ShowStatus(msg, time)
{
    ShowTrayTip("ClickScreen", msg, time)
}

; Generic Show and Remove Tray Tip
ShowTrayTip(title, msg, time)
{
    ; 7/7/2011 Win Server 2008 - 30 seems to have no effect
    TrayTip, %title%, %msg%, 30, 1 
    SetTimer, RemoveTrayTip, %time%         ; used to ensure tip is taken down
    dp(msg)
    Return

; The Traytip does not disappear quickly without this
; 7/7/2011 Win Server 2008 - tip disappears after 4 seconds anyway if the script continues to run
RemoveTrayTip:
    SetTimer, RemoveTrayTip, Off
    TrayTip
    dp("TrayTip off")
    Return
}   

FindAndRun(exeName)
{
    ; Here I get to define the folders to search
    ProgramFolders:="P:\Program Files,C:\Program Files,C:\Program Files (x86)"
    Loop, parse, ProgramFolders, `,
    {
        IfExist, %A_LoopField%\%exeName%
        {
            Run %A_LoopField%\%exeName%
            Return
        }
    }
    MsgBox File %exeName% not found
}

dp(Msg)
{
    OutputDebug %A_ScriptName% %Msg%  
}

C#

using System;    
using System.Drawing;    
using System.IO;    
using System.Drawing.Imaging;    
using System.Runtime.InteropServices;    

//Based on code of  Agha Ali Raza (http://www.csharphelp.com/archives2/archive393.html)    

namespace Script    
{    
    public class CaptureScreen    
    {    
        const string usage = "Usage: printScreen.cs [filename]\n"+    
            "Captures screen image and saves it to a file (default file: screen.gif)\n";    

        static public void Main(string[] args)    
        {    
            if (args.Length == 1 && (args[0] == "?" || args[0] == "/?" || args[0] == "-?" || args[0].ToLower() == "help"))    
            {    
                Console.WriteLine(usage);    
            }    
            else    
            {    
                try    
                {    
                    Bitmap capture = CaptureScreen.GetDesktopImage();    
                    string file = Path.Combine(Environment.CurrentDirectory, "screen.gif");    
                    ImageFormat format = ImageFormat.Gif;    

                    if (args.Length == 1)    
                    {    
                        file = args[0];    
                        if (args[0].ToUpper().EndsWith(".GIF"))     
                            format = ImageFormat.Gif;    
                        else if (args[0].ToUpper().EndsWith(".BMP"))     
                            format = ImageFormat.Bmp;    
                        else if (args[0].ToUpper().EndsWith(".JPEG"))     
                            format = ImageFormat.Jpeg;    
                        else if (args[0].ToUpper().EndsWith(".PNG"))     
                            format = ImageFormat.Png;    

                    }    
                    capture.Save(file, format);    
                }    
                catch (Exception e)    
                {    
                    Console.WriteLine(e);    
                }    
            }    
        }    

        public static Bitmap GetDesktopImage()    
        {    
            WIN32_API.SIZE size;    

            IntPtr  hDC = WIN32_API.GetDC(WIN32_API.GetDesktopWindow());     
            IntPtr hMemDC = WIN32_API.CreateCompatibleDC(hDC);    

            size.cx = WIN32_API.GetSystemMetrics(WIN32_API.SM_CXSCREEN);    
            size.cy = WIN32_API.GetSystemMetrics(WIN32_API.SM_CYSCREEN);    

            m_HBitmap = WIN32_API.CreateCompatibleBitmap(hDC, size.cx, size.cy);    

            if (m_HBitmap!=IntPtr.Zero)    
            {    
                IntPtr hOld = (IntPtr) WIN32_API.SelectObject(hMemDC, m_HBitmap);    
                WIN32_API.BitBlt(hMemDC, 0, 0,size.cx,size.cy, hDC, 0, 0, WIN32_API.SRCCOPY);    
                WIN32_API.SelectObject(hMemDC, hOld);    
                WIN32_API.DeleteDC(hMemDC);    
                WIN32_API.ReleaseDC(WIN32_API.GetDesktopWindow(), hDC);    
                return System.Drawing.Image.FromHbitmap(m_HBitmap);     
            }    
            return null;    
        }    

        protected static IntPtr m_HBitmap;    
    }    

    public class WIN32_API    
    {    
        public struct SIZE    
        {    
            public int cx;    
            public int cy;    
        }    
        public  const int SRCCOPY = 13369376;    
        public  const int SM_CXSCREEN=0;    
        public  const int SM_CYSCREEN=1;    

        [DllImport("gdi32.dll",EntryPoint="DeleteDC")]    
        public static extern IntPtr DeleteDC(IntPtr hDc);    

        [DllImport("gdi32.dll",EntryPoint="DeleteObject")]    
        public static extern IntPtr DeleteObject(IntPtr hDc);    

        [DllImport("gdi32.dll",EntryPoint="BitBlt")]    
        public static extern bool BitBlt(IntPtr hdcDest,int xDest,int yDest,int wDest,int hDest,IntPtr hdcSource,int xSrc,int ySrc,int RasterOp);    

        [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleBitmap")]    
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,  int nWidth, int nHeight);    

        [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleDC")]    
        public static extern IntPtr CreateCompatibleDC(IntPtr hdc);    

        [DllImport ("gdi32.dll",EntryPoint="SelectObject")]    
        public static extern IntPtr SelectObject(IntPtr hdc,IntPtr bmp);    

        [DllImport("user32.dll", EntryPoint="GetDesktopWindow")]    
        public static extern IntPtr GetDesktopWindow();    

        [DllImport("user32.dll",EntryPoint="GetDC")]    
        public static extern IntPtr GetDC(IntPtr ptr);    

        [DllImport("user32.dll",EntryPoint="GetSystemMetrics")]    
        public static extern int GetSystemMetrics(int abc);    

        [DllImport("user32.dll",EntryPoint="GetWindowDC")]    
        public static extern IntPtr GetWindowDC(Int32 ptr);    

        [DllImport("user32.dll",EntryPoint="ReleaseDC")]    
        public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDc);    
    }    

}    

希望这会让你开始