关于winapi:单击时捕获并保存屏幕截图 – Windows C#

Capture and save screenshot as you click - Windows C#

首先,对于这个冗长的问题,我很抱歉,但我想确保我包含了我迄今为止遇到并完成的所有内容。

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

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

我遇到了这篇文章,其中包含使用 Win32 API 捕获和保存屏幕截图的详细信息。这篇文章和这篇文章讨论了通过仅使用 .NET Framework 来保存桌面的一部分,它运行良好,但这并不是我所需要的。我确实遇到了一些免费软件和其他商业软件,它们也能做更多和一点点,但我更喜欢做一些简单和定制的东西。

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

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

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


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

1
2
3
4
5
6
7
8
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


我使用自动热键脚本来触发 GadWin (http://www.gadwin.com/printscreen/) 解决了类似的问题 注意 Gadwin 仅供个人免费使用。可以购买商业许可证 ($25)

我还有一些你可能喜欢的 C# 代码,那是免费的。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
; 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#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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]\
"
+    
           "Captures screen image and saves it to a file (default file: screen.gif)\
"
;    

        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);    
    }    

}

希望这能让你开始