├── .gitignore
├── LICENSE.txt
├── README.md
├── SimpleScreenshotCapture.sln
├── docs
└── capture-screenshot-1c.png
├── nuget.config
└── src
├── AboutDialog.cs
├── AboutDialog.designer.cs
├── AboutDialog.resx
├── App.config
├── DesktopLayout.cs
├── GroupBox.cs
├── Line.cs
├── MainForm.Designer.cs
├── MainForm.cs
├── MainForm.resx
├── NativeMethods.cs
├── Program.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
└── Resources.resx
├── Resources
├── Camera-Photo.png
├── Copy.png
├── Save.png
├── Timer.png
└── fill.png
├── ScreenshotCapture.cs
├── SimpleScreenshotCapture.csproj
├── ToolStripColorPickerDropDown.cs
├── ToolStripColorPickerDropDown.resx
├── ToolStripColorPickerSplitButton.cs
├── app.manifest
└── packages.config
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | obj/
3 | .vs/
4 | packages/
5 |
6 | *.suo
7 | *.user
8 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017-2019 Cyotek Ltd.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Capturing screenshots using C# and p/invoke
2 |
3 | ![The sample application][screenshot]
4 |
5 | This repository contains a sample application showing the basics
6 | of capturing screenshots in your C# applications via the use of
7 | platform invoke.
8 |
9 | For more information, please see the following article on the
10 | Cyotek blog:
11 |
12 | * [Capturing screenshots using C# and p/invoke][bloglink]
13 |
14 | [screenshot]: docs/capture-screenshot-1c.png
15 | [bloglink]: https://devblog.cyotek.com/post/capturing-screenshots-using-csharp-and-p-invoke
16 |
--------------------------------------------------------------------------------
/SimpleScreenshotCapture.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26430.16
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleScreenshotCapture", "src\SimpleScreenshotCapture.csproj", "{EC728998-A741-4388-99E3-29C5F013E011}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {EC728998-A741-4388-99E3-29C5F013E011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {EC728998-A741-4388-99E3-29C5F013E011}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {EC728998-A741-4388-99E3-29C5F013E011}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {EC728998-A741-4388-99E3-29C5F013E011}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/docs/capture-screenshot-1c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyotek/SimpleScreenshotCapture/c5a0170adbfadf1437d798d0f9417870d0c82003/docs/capture-screenshot-1c.png
--------------------------------------------------------------------------------
/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/AboutDialog.cs:
--------------------------------------------------------------------------------
1 | // Capturing screenshots using C# and p/invoke
2 | // http://www.cyotek.com/blog/capturing-screenshots-using-csharp-and-p-invoke
3 | // Copyright © 2017 Cyotek Ltd. All Rights Reserved.
4 |
5 | // This work is licensed under the Creative Commons Attribution 4.0 International License.
6 | // To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
7 |
8 | using System;
9 | using System.Diagnostics;
10 | using System.Drawing;
11 | using System.Windows.Forms;
12 |
13 | namespace Cyotek.Demo.SimpleScreenshotCapture
14 | {
15 | internal partial class AboutDialog : Form
16 | {
17 | #region Constructors
18 |
19 | public AboutDialog()
20 | {
21 | this.InitializeComponent();
22 | }
23 |
24 | #endregion
25 |
26 | #region Methods
27 |
28 | protected override void OnLoad(EventArgs e)
29 | {
30 | FileVersionInfo versionInfo;
31 | Font font;
32 |
33 | versionInfo = FileVersionInfo.GetVersionInfo(typeof(MainForm).Assembly.Location);
34 | nameLabel.Text = versionInfo.ProductName;
35 | copyrightLabel.Text = versionInfo.LegalCopyright;
36 |
37 | font = SystemFonts.MessageBoxFont;
38 | this.Font = font;
39 | nameLabel.Font = new Font(font, FontStyle.Bold);
40 |
41 | base.OnLoad(e);
42 | }
43 |
44 | private void closeButton_Click(object sender, EventArgs e)
45 | {
46 | this.Close();
47 | }
48 |
49 | private void webLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
50 | {
51 | try
52 | {
53 | Process.Start("http://cyotek.com");
54 | }
55 | catch (Exception ex)
56 | {
57 | MessageBox.Show(ex.GetBaseException().Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
58 | }
59 | }
60 |
61 | #endregion
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/AboutDialog.designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cyotek.Demo.SimpleScreenshotCapture
2 | {
3 | partial class AboutDialog
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.nameLabel = new System.Windows.Forms.Label();
32 | this.copyrightLabel = new System.Windows.Forms.Label();
33 | this.webLinkLabel = new System.Windows.Forms.LinkLabel();
34 | this.closeButton = new System.Windows.Forms.Button();
35 | this.SuspendLayout();
36 | //
37 | // nameLabel
38 | //
39 | this.nameLabel.AutoSize = true;
40 | this.nameLabel.Location = new System.Drawing.Point(12, 9);
41 | this.nameLabel.Name = "nameLabel";
42 | this.nameLabel.Size = new System.Drawing.Size(54, 13);
43 | this.nameLabel.TabIndex = 1;
44 | this.nameLabel.Text = "AppName";
45 | //
46 | // copyrightLabel
47 | //
48 | this.copyrightLabel.AutoSize = true;
49 | this.copyrightLabel.Location = new System.Drawing.Point(12, 22);
50 | this.copyrightLabel.Name = "copyrightLabel";
51 | this.copyrightLabel.Size = new System.Drawing.Size(51, 13);
52 | this.copyrightLabel.TabIndex = 2;
53 | this.copyrightLabel.Text = "Copyright";
54 | //
55 | // webLinkLabel
56 | //
57 | this.webLinkLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
58 | this.webLinkLabel.AutoSize = true;
59 | this.webLinkLabel.Location = new System.Drawing.Point(12, 251);
60 | this.webLinkLabel.Name = "webLinkLabel";
61 | this.webLinkLabel.Size = new System.Drawing.Size(120, 13);
62 | this.webLinkLabel.TabIndex = 3;
63 | this.webLinkLabel.TabStop = true;
64 | this.webLinkLabel.Text = "http://www.cyotek.com";
65 | this.webLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.webLinkLabel_LinkClicked);
66 | //
67 | // closeButton
68 | //
69 | this.closeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
70 | this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
71 | this.closeButton.Location = new System.Drawing.Point(336, 246);
72 | this.closeButton.Name = "closeButton";
73 | this.closeButton.Size = new System.Drawing.Size(75, 23);
74 | this.closeButton.TabIndex = 0;
75 | this.closeButton.Text = "Close";
76 | this.closeButton.UseVisualStyleBackColor = true;
77 | this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
78 | //
79 | // AboutDialog
80 | //
81 | this.AcceptButton = this.closeButton;
82 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
83 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
84 | this.CancelButton = this.closeButton;
85 | this.ClientSize = new System.Drawing.Size(423, 281);
86 | this.Controls.Add(this.closeButton);
87 | this.Controls.Add(this.webLinkLabel);
88 | this.Controls.Add(this.copyrightLabel);
89 | this.Controls.Add(this.nameLabel);
90 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
91 | this.MaximizeBox = false;
92 | this.MinimizeBox = false;
93 | this.Name = "AboutDialog";
94 | this.ShowIcon = false;
95 | this.ShowInTaskbar = false;
96 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
97 | this.Text = "About";
98 | this.ResumeLayout(false);
99 | this.PerformLayout();
100 |
101 | }
102 |
103 | #endregion
104 |
105 | private System.Windows.Forms.Label nameLabel;
106 | private System.Windows.Forms.Label copyrightLabel;
107 | private System.Windows.Forms.LinkLabel webLinkLabel;
108 | private System.Windows.Forms.Button closeButton;
109 | }
110 | }
--------------------------------------------------------------------------------
/src/AboutDialog.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/src/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/DesktopLayout.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | // Capturing screenshots using C# and p/invoke
6 | // http://www.cyotek.com/blog/capturing-screenshots-using-csharp-and-p-invoke
7 | // Copyright © 2017-2019 Cyotek Ltd. All Rights Reserved.
8 |
9 | // This work is licensed under the Creative Commons Attribution 4.0 International License.
10 | // To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
11 |
12 | namespace Cyotek.Windows.Forms
13 | {
14 | internal sealed class DesktopLayout
15 | {
16 | #region Private Fields
17 |
18 | private Rectangle _bounds;
19 |
20 | private int _count;
21 |
22 | private Rectangle[] _displays;
23 |
24 | private bool _workingAreaOnly;
25 |
26 | #endregion Private Fields
27 |
28 | #region Public Constructors
29 |
30 | public DesktopLayout()
31 | {
32 | this.Initialize();
33 | }
34 |
35 | #endregion Public Constructors
36 |
37 | #region Public Properties
38 |
39 | public Rectangle Bounds
40 | { get { return _bounds; } }
41 |
42 | public int Count
43 | { get { return _count; } }
44 |
45 | public int Height
46 | { get { return _bounds.Height; } }
47 |
48 | public int Width
49 | { get { return _bounds.Width; } }
50 |
51 | public bool WorkingAreaOnly
52 | {
53 | get { return _workingAreaOnly; }
54 | set
55 | {
56 | if (_workingAreaOnly != value)
57 | {
58 | _workingAreaOnly = value;
59 |
60 | this.Initialize();
61 | }
62 | }
63 | }
64 |
65 | #endregion Public Properties
66 |
67 | #region Public Methods
68 |
69 | public Rectangle GetDisplayBounds(int index)
70 | {
71 | return _displays[index];
72 | }
73 |
74 | public Rectangle GetNormalizedDisplayBounds(int index)
75 | {
76 | return this.GetNormalizedDisplayBounds(_displays[index]);
77 | }
78 |
79 | public Rectangle GetNormalizedDisplayBounds(Rectangle bounds)
80 | {
81 | return new Rectangle(bounds.X - _bounds.X, bounds.Y - _bounds.Y, bounds.Width, bounds.Height);
82 | }
83 |
84 | #endregion Public Methods
85 |
86 | #region Private Methods
87 |
88 | private void Initialize()
89 | {
90 | Screen[] screens;
91 | int minX;
92 | int minY;
93 | int maxX;
94 | int maxY;
95 |
96 | screens = Screen.AllScreens;
97 | minX = 0;
98 | minY = 0;
99 | maxX = 0;
100 | maxY = 0;
101 |
102 | _count = screens.Length;
103 | _displays = new Rectangle[_count];
104 |
105 | for (int i = 0; i < _count; i++)
106 | {
107 | Screen screen;
108 | Rectangle bounds;
109 |
110 | screen = screens[i];
111 | bounds = _workingAreaOnly ? screen.WorkingArea : screen.Bounds;
112 |
113 | _displays[i] = bounds;
114 |
115 | minX = Math.Min(minX, bounds.X);
116 | minY = Math.Min(minY, bounds.Y);
117 | maxX = Math.Max(maxX, bounds.Right);
118 | maxY = Math.Max(maxY, bounds.Bottom);
119 | }
120 |
121 | _bounds = new Rectangle(minX, minY, maxX - minX, maxY - minY);
122 | }
123 |
124 | #endregion Private Methods
125 | }
126 | }
--------------------------------------------------------------------------------
/src/GroupBox.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyotek/SimpleScreenshotCapture/c5a0170adbfadf1437d798d0f9417870d0c82003/src/GroupBox.cs
--------------------------------------------------------------------------------
/src/Line.cs:
--------------------------------------------------------------------------------
1 | // Capturing screenshots using C# and p/invoke
2 | // http://www.cyotek.com/blog/capturing-screenshots-using-csharp-and-p-invoke
3 | // Copyright © 2017 Cyotek Ltd. All Rights Reserved.
4 |
5 | // This work is licensed under the Creative Commons Attribution 4.0 International License.
6 | // To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
7 |
8 | using System;
9 | using System.ComponentModel;
10 | using System.Drawing;
11 | using System.Windows.Forms;
12 |
13 | namespace Cyotek.Windows.Forms
14 | {
15 | #if PUBLICLIB
16 | [Designer(typeof(Design.LineDesigner))]
17 | public class Line : Control
18 | #else
19 | internal class Line : Control
20 | #endif
21 | {
22 | #region Constants
23 |
24 | private static readonly object _eventFlatStyleChanged = new object();
25 |
26 | private static readonly object _eventLineColorChanged = new object();
27 |
28 | private static readonly object _eventOrientationChanged = new object();
29 |
30 | #endregion
31 |
32 | #region Fields
33 |
34 | private FlatStyle _flatStyle = FlatStyle.Standard;
35 |
36 | private Color _lineColor;
37 |
38 | private Orientation _orientation;
39 |
40 | #endregion
41 |
42 | #region Constructors
43 |
44 | public Line()
45 | {
46 | this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
47 | this.SetStyle(ControlStyles.Selectable, false);
48 | this.LineColor = SystemColors.ControlDark;
49 | base.TabStop = false;
50 | base.TabIndex = 0;
51 | }
52 |
53 | #endregion
54 |
55 | #region Events
56 |
57 | [Category("Property Changed")]
58 | public event EventHandler FlatStyleChanged
59 | {
60 | add { this.Events.AddHandler(_eventFlatStyleChanged, value); }
61 | remove { this.Events.RemoveHandler(_eventFlatStyleChanged, value); }
62 | }
63 |
64 | [Category("Property Changed")]
65 | public event EventHandler LineColorChanged
66 | {
67 | add { this.Events.AddHandler(_eventLineColorChanged, value); }
68 | remove { this.Events.RemoveHandler(_eventLineColorChanged, value); }
69 | }
70 |
71 | [Category("Property Changed")]
72 | public event EventHandler OrientationChanged
73 | {
74 | add { this.Events.AddHandler(_eventOrientationChanged, value); }
75 | remove { this.Events.RemoveHandler(_eventOrientationChanged, value); }
76 | }
77 |
78 | #endregion
79 |
80 | #region Properties
81 |
82 | [Category("Appearance")]
83 | [DefaultValue(typeof(FlatStyle), "Standard")]
84 | public FlatStyle FlatStyle
85 | {
86 | get { return _flatStyle; }
87 | set
88 | {
89 | if (_flatStyle != value)
90 | {
91 | _flatStyle = value;
92 |
93 | this.OnFlatStyleChanged(EventArgs.Empty);
94 | }
95 | }
96 | }
97 |
98 | [Category("Appearance")]
99 | [DefaultValue(typeof(Color), "ControlDark")]
100 | public Color LineColor
101 | {
102 | get { return _lineColor; }
103 | set
104 | {
105 | if (this.LineColor != value)
106 | {
107 | _lineColor = value;
108 |
109 | this.OnLineColorChanged(EventArgs.Empty);
110 | }
111 | }
112 | }
113 |
114 | [Category("Appearance")]
115 | [DefaultValue(typeof(Orientation), "Horizontal")]
116 | public Orientation Orientation
117 | {
118 | get { return _orientation; }
119 | set
120 | {
121 | if (this.Orientation != value)
122 | {
123 | _orientation = value;
124 |
125 | this.OnOrientationChanged(EventArgs.Empty);
126 | }
127 | }
128 | }
129 |
130 | [DefaultValue(false)]
131 | [Browsable(false)]
132 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
133 | public new int TabIndex
134 | {
135 | get { return base.TabIndex; }
136 | set { base.TabIndex = value; }
137 | }
138 |
139 | [DefaultValue(false)]
140 | [Browsable(false)]
141 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
142 | public new bool TabStop
143 | {
144 | get { return base.TabStop; }
145 | set { base.TabStop = value; }
146 | }
147 |
148 | protected override Size DefaultSize
149 | {
150 | get { return new Size(100, 2); }
151 | }
152 |
153 | #endregion
154 |
155 | #region Methods
156 |
157 | ///
158 | /// Raises the event.
159 | ///
160 | /// The instance containing the event data.
161 | protected virtual void OnFlatStyleChanged(EventArgs e)
162 | {
163 | EventHandler handler;
164 |
165 | this.Invalidate();
166 |
167 | handler = (EventHandler)this.Events[_eventFlatStyleChanged];
168 |
169 | handler?.Invoke(this, e);
170 | }
171 |
172 | ///
173 | /// Raises the event.
174 | ///
175 | /// The instance containing the event data.
176 | protected virtual void OnLineColorChanged(EventArgs e)
177 | {
178 | EventHandler handler;
179 |
180 | this.Invalidate();
181 |
182 | handler = (EventHandler)this.Events[_eventLineColorChanged];
183 |
184 | handler?.Invoke(this, e);
185 | }
186 |
187 | ///
188 | /// Raises the event.
189 | ///
190 | /// The instance containing the event data.
191 | protected virtual void OnOrientationChanged(EventArgs e)
192 | {
193 | EventHandler handler;
194 |
195 | this.Invalidate();
196 |
197 | handler = (EventHandler)this.Events[_eventOrientationChanged];
198 |
199 | handler?.Invoke(this, e);
200 | }
201 |
202 | protected override void OnPaint(PaintEventArgs pe)
203 | {
204 | int x1;
205 | int y1;
206 | int x2;
207 | int y2;
208 | int xOffset;
209 | int yOffset;
210 |
211 | switch (this.Orientation)
212 | {
213 | case Orientation.Horizontal:
214 | x1 = 0;
215 | y1 = this.Height / 2 - 1;
216 | x2 = this.Width;
217 | y2 = y1;
218 | xOffset = 0;
219 | yOffset = 1;
220 | break;
221 | default:
222 | x1 = this.Width / 2 - 1;
223 | y1 = 0;
224 | x2 = x1;
225 | y2 = this.Height;
226 | xOffset = 1;
227 | yOffset = 0;
228 | break;
229 | }
230 |
231 | switch (this.FlatStyle)
232 | {
233 | case FlatStyle.System:
234 | using (Pen pen = new Pen(this.LineColor))
235 | {
236 | pe.Graphics.DrawLine(pen, x1, y1, x2, y2);
237 | }
238 | break;
239 | default:
240 | pe.Graphics.DrawLine(SystemPens.ControlDark, x1, y1, x2, y2);
241 | pe.Graphics.DrawLine(SystemPens.ControlLightLight, x1 + xOffset, y1 + yOffset, x2 + xOffset, y2 + yOffset);
242 | break;
243 | }
244 | }
245 |
246 | protected override void OnSystemColorsChanged(EventArgs e)
247 | {
248 | base.OnSystemColorsChanged(e);
249 |
250 | this.Invalidate();
251 | }
252 |
253 | #endregion
254 | }
255 | }
256 |
--------------------------------------------------------------------------------
/src/MainForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cyotek.Demo.SimpleScreenshotCapture
2 | {
3 | partial class MainForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.components = new System.ComponentModel.Container();
32 | this.menuStrip = new System.Windows.Forms.MenuStrip();
33 | this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
34 | this.captureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
35 | this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator();
36 | this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
37 | this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
38 | this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
39 | this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
40 | this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
41 | this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
42 | this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
43 | this.previewGroupBox = new Cyotek.Windows.Forms.GroupBox();
44 | this.previewImageBox = new Cyotek.Windows.Forms.ImageBox();
45 | this.setupGroupBox = new Cyotek.Windows.Forms.GroupBox();
46 | this.desktopScreensCheckedListBox = new System.Windows.Forms.CheckedListBox();
47 | this.line1 = new Cyotek.Windows.Forms.Line();
48 | this.workingAreaCheckBox = new System.Windows.Forms.CheckBox();
49 | this.line = new Cyotek.Windows.Forms.Line();
50 | this.desktopRadioButton = new System.Windows.Forms.RadioButton();
51 | this.monitorComboBox = new System.Windows.Forms.ComboBox();
52 | this.monitorRadioButton = new System.Windows.Forms.RadioButton();
53 | this.currentMonitorRadioButton = new System.Windows.Forms.RadioButton();
54 | this.currentWindowRadioButton = new System.Windows.Forms.RadioButton();
55 | this.label1 = new System.Windows.Forms.Label();
56 | this.splitContainer = new System.Windows.Forms.SplitContainer();
57 | this.toolStrip = new System.Windows.Forms.ToolStrip();
58 | this.saveToolStripButton = new System.Windows.Forms.ToolStripButton();
59 | this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
60 | this.copyToolStripButton = new System.Windows.Forms.ToolStripButton();
61 | this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
62 | this.captureToolStripButton = new System.Windows.Forms.ToolStripButton();
63 | this.delayCaptureToolStripButton = new System.Windows.Forms.ToolStripButton();
64 | this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
65 | this.fillToolStripColorPickerSplitButton = new Cyotek.Windows.Forms.ToolStripControllerHosts.ToolStripColorPickerSplitButton();
66 | this.delayCaptureTimer = new System.Windows.Forms.Timer(this.components);
67 | this.statusStrip = new System.Windows.Forms.StatusStrip();
68 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
69 | this.timerToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
70 | this.menuStrip.SuspendLayout();
71 | this.previewGroupBox.SuspendLayout();
72 | this.setupGroupBox.SuspendLayout();
73 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
74 | this.splitContainer.Panel1.SuspendLayout();
75 | this.splitContainer.Panel2.SuspendLayout();
76 | this.splitContainer.SuspendLayout();
77 | this.toolStrip.SuspendLayout();
78 | this.statusStrip.SuspendLayout();
79 | this.SuspendLayout();
80 | //
81 | // menuStrip
82 | //
83 | this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
84 | this.fileToolStripMenuItem,
85 | this.editToolStripMenuItem,
86 | this.helpToolStripMenuItem});
87 | this.menuStrip.Location = new System.Drawing.Point(0, 0);
88 | this.menuStrip.Name = "menuStrip";
89 | this.menuStrip.Size = new System.Drawing.Size(867, 24);
90 | this.menuStrip.TabIndex = 0;
91 | //
92 | // fileToolStripMenuItem
93 | //
94 | this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
95 | this.captureToolStripMenuItem,
96 | this.toolStripSeparator,
97 | this.saveToolStripMenuItem,
98 | this.toolStripSeparator1,
99 | this.exitToolStripMenuItem});
100 | this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
101 | this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
102 | this.fileToolStripMenuItem.Text = "&File";
103 | //
104 | // captureToolStripMenuItem
105 | //
106 | this.captureToolStripMenuItem.Image = global::Cyotek.Demo.SimpleScreenshotCapture.Properties.Resources.Capture;
107 | this.captureToolStripMenuItem.Name = "captureToolStripMenuItem";
108 | this.captureToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F9;
109 | this.captureToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
110 | this.captureToolStripMenuItem.Text = "&Capture";
111 | this.captureToolStripMenuItem.Click += new System.EventHandler(this.captureToolStripMenuItem_Click);
112 | //
113 | // toolStripSeparator
114 | //
115 | this.toolStripSeparator.Name = "toolStripSeparator";
116 | this.toolStripSeparator.Size = new System.Drawing.Size(144, 6);
117 | //
118 | // saveToolStripMenuItem
119 | //
120 | this.saveToolStripMenuItem.Image = global::Cyotek.Demo.SimpleScreenshotCapture.Properties.Resources.Save;
121 | this.saveToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta;
122 | this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
123 | this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
124 | this.saveToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
125 | this.saveToolStripMenuItem.Text = "&Save...";
126 | this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
127 | //
128 | // toolStripSeparator1
129 | //
130 | this.toolStripSeparator1.Name = "toolStripSeparator1";
131 | this.toolStripSeparator1.Size = new System.Drawing.Size(144, 6);
132 | //
133 | // exitToolStripMenuItem
134 | //
135 | this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
136 | this.exitToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
137 | this.exitToolStripMenuItem.Text = "E&xit";
138 | this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
139 | //
140 | // editToolStripMenuItem
141 | //
142 | this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
143 | this.copyToolStripMenuItem});
144 | this.editToolStripMenuItem.Name = "editToolStripMenuItem";
145 | this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20);
146 | this.editToolStripMenuItem.Text = "&Edit";
147 | //
148 | // copyToolStripMenuItem
149 | //
150 | this.copyToolStripMenuItem.Image = global::Cyotek.Demo.SimpleScreenshotCapture.Properties.Resources.Copy;
151 | this.copyToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta;
152 | this.copyToolStripMenuItem.Name = "copyToolStripMenuItem";
153 | this.copyToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
154 | this.copyToolStripMenuItem.Size = new System.Drawing.Size(144, 22);
155 | this.copyToolStripMenuItem.Text = "&Copy";
156 | this.copyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
157 | //
158 | // helpToolStripMenuItem
159 | //
160 | this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
161 | this.aboutToolStripMenuItem});
162 | this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
163 | this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
164 | this.helpToolStripMenuItem.Text = "&Help";
165 | //
166 | // aboutToolStripMenuItem
167 | //
168 | this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
169 | this.aboutToolStripMenuItem.Size = new System.Drawing.Size(107, 22);
170 | this.aboutToolStripMenuItem.Text = "&About";
171 | this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
172 | //
173 | // previewGroupBox
174 | //
175 | this.previewGroupBox.Controls.Add(this.previewImageBox);
176 | this.previewGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
177 | this.previewGroupBox.Location = new System.Drawing.Point(0, 0);
178 | this.previewGroupBox.Name = "previewGroupBox";
179 | this.previewGroupBox.Size = new System.Drawing.Size(558, 316);
180 | this.previewGroupBox.TabIndex = 0;
181 | this.previewGroupBox.TabStop = false;
182 | this.previewGroupBox.Text = "Preview";
183 | //
184 | // previewImageBox
185 | //
186 | this.previewImageBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
187 | | System.Windows.Forms.AnchorStyles.Left)
188 | | System.Windows.Forms.AnchorStyles.Right)));
189 | this.previewImageBox.Location = new System.Drawing.Point(6, 19);
190 | this.previewImageBox.Name = "previewImageBox";
191 | this.previewImageBox.Size = new System.Drawing.Size(546, 291);
192 | this.previewImageBox.TabIndex = 0;
193 | this.previewImageBox.TabStop = false;
194 | this.previewImageBox.Zoomed += new System.EventHandler(this.previewImageBox_Zoomed);
195 | //
196 | // setupGroupBox
197 | //
198 | this.setupGroupBox.Controls.Add(this.desktopScreensCheckedListBox);
199 | this.setupGroupBox.Controls.Add(this.line1);
200 | this.setupGroupBox.Controls.Add(this.workingAreaCheckBox);
201 | this.setupGroupBox.Controls.Add(this.line);
202 | this.setupGroupBox.Controls.Add(this.desktopRadioButton);
203 | this.setupGroupBox.Controls.Add(this.monitorComboBox);
204 | this.setupGroupBox.Controls.Add(this.monitorRadioButton);
205 | this.setupGroupBox.Controls.Add(this.currentMonitorRadioButton);
206 | this.setupGroupBox.Controls.Add(this.currentWindowRadioButton);
207 | this.setupGroupBox.Controls.Add(this.label1);
208 | this.setupGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
209 | this.setupGroupBox.Location = new System.Drawing.Point(0, 0);
210 | this.setupGroupBox.Name = "setupGroupBox";
211 | this.setupGroupBox.Size = new System.Drawing.Size(281, 316);
212 | this.setupGroupBox.TabIndex = 0;
213 | this.setupGroupBox.TabStop = false;
214 | this.setupGroupBox.Text = "Capture Setup";
215 | //
216 | // desktopScreensCheckedListBox
217 | //
218 | this.desktopScreensCheckedListBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
219 | | System.Windows.Forms.AnchorStyles.Left)
220 | | System.Windows.Forms.AnchorStyles.Right)));
221 | this.desktopScreensCheckedListBox.FormattingEnabled = true;
222 | this.desktopScreensCheckedListBox.IntegralHeight = false;
223 | this.desktopScreensCheckedListBox.Location = new System.Drawing.Point(6, 206);
224 | this.desktopScreensCheckedListBox.Name = "desktopScreensCheckedListBox";
225 | this.desktopScreensCheckedListBox.Size = new System.Drawing.Size(269, 104);
226 | this.desktopScreensCheckedListBox.TabIndex = 7;
227 | //
228 | // line1
229 | //
230 | this.line1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
231 | | System.Windows.Forms.AnchorStyles.Right)));
232 | this.line1.Location = new System.Drawing.Point(6, 190);
233 | this.line1.Name = "line1";
234 | this.line1.Size = new System.Drawing.Size(269, 10);
235 | this.line1.Text = "label2";
236 | //
237 | // workingAreaCheckBox
238 | //
239 | this.workingAreaCheckBox.AutoSize = true;
240 | this.workingAreaCheckBox.Location = new System.Drawing.Point(6, 167);
241 | this.workingAreaCheckBox.Name = "workingAreaCheckBox";
242 | this.workingAreaCheckBox.Size = new System.Drawing.Size(115, 17);
243 | this.workingAreaCheckBox.TabIndex = 6;
244 | this.workingAreaCheckBox.Text = "&Working Area Only";
245 | this.workingAreaCheckBox.UseVisualStyleBackColor = true;
246 | //
247 | // line
248 | //
249 | this.line.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
250 | | System.Windows.Forms.AnchorStyles.Right)));
251 | this.line.Location = new System.Drawing.Point(6, 151);
252 | this.line.Name = "line";
253 | this.line.Size = new System.Drawing.Size(269, 10);
254 | this.line.Text = "label2";
255 | //
256 | // desktopRadioButton
257 | //
258 | this.desktopRadioButton.AutoSize = true;
259 | this.desktopRadioButton.Location = new System.Drawing.Point(6, 128);
260 | this.desktopRadioButton.Name = "desktopRadioButton";
261 | this.desktopRadioButton.Size = new System.Drawing.Size(95, 17);
262 | this.desktopRadioButton.TabIndex = 5;
263 | this.desktopRadioButton.Text = "Entire &Desktop";
264 | this.desktopRadioButton.UseVisualStyleBackColor = true;
265 | //
266 | // monitorComboBox
267 | //
268 | this.monitorComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
269 | this.monitorComboBox.FormattingEnabled = true;
270 | this.monitorComboBox.Location = new System.Drawing.Point(22, 101);
271 | this.monitorComboBox.Name = "monitorComboBox";
272 | this.monitorComboBox.Size = new System.Drawing.Size(121, 21);
273 | this.monitorComboBox.TabIndex = 4;
274 | this.monitorComboBox.SelectedIndexChanged += new System.EventHandler(this.monitorComboBox_SelectedIndexChanged);
275 | //
276 | // monitorRadioButton
277 | //
278 | this.monitorRadioButton.AutoSize = true;
279 | this.monitorRadioButton.Location = new System.Drawing.Point(6, 78);
280 | this.monitorRadioButton.Name = "monitorRadioButton";
281 | this.monitorRadioButton.Size = new System.Drawing.Size(98, 17);
282 | this.monitorRadioButton.TabIndex = 3;
283 | this.monitorRadioButton.Text = "Custom M&onitor";
284 | this.monitorRadioButton.UseVisualStyleBackColor = true;
285 | //
286 | // currentMonitorRadioButton
287 | //
288 | this.currentMonitorRadioButton.AutoSize = true;
289 | this.currentMonitorRadioButton.Location = new System.Drawing.Point(6, 55);
290 | this.currentMonitorRadioButton.Name = "currentMonitorRadioButton";
291 | this.currentMonitorRadioButton.Size = new System.Drawing.Size(97, 17);
292 | this.currentMonitorRadioButton.TabIndex = 2;
293 | this.currentMonitorRadioButton.Text = "Current &Monitor";
294 | this.currentMonitorRadioButton.UseVisualStyleBackColor = true;
295 | //
296 | // currentWindowRadioButton
297 | //
298 | this.currentWindowRadioButton.AutoSize = true;
299 | this.currentWindowRadioButton.Checked = true;
300 | this.currentWindowRadioButton.Location = new System.Drawing.Point(6, 32);
301 | this.currentWindowRadioButton.Name = "currentWindowRadioButton";
302 | this.currentWindowRadioButton.Size = new System.Drawing.Size(101, 17);
303 | this.currentWindowRadioButton.TabIndex = 1;
304 | this.currentWindowRadioButton.TabStop = true;
305 | this.currentWindowRadioButton.Text = "Current &Window";
306 | this.currentWindowRadioButton.UseVisualStyleBackColor = true;
307 | //
308 | // label1
309 | //
310 | this.label1.AutoSize = true;
311 | this.label1.Location = new System.Drawing.Point(3, 16);
312 | this.label1.Name = "label1";
313 | this.label1.Size = new System.Drawing.Size(160, 13);
314 | this.label1.TabIndex = 0;
315 | this.label1.Text = "What would you like to capture?";
316 | //
317 | // splitContainer
318 | //
319 | this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
320 | | System.Windows.Forms.AnchorStyles.Left)
321 | | System.Windows.Forms.AnchorStyles.Right)));
322 | this.splitContainer.Location = new System.Drawing.Point(12, 52);
323 | this.splitContainer.Name = "splitContainer";
324 | //
325 | // splitContainer.Panel1
326 | //
327 | this.splitContainer.Panel1.Controls.Add(this.setupGroupBox);
328 | //
329 | // splitContainer.Panel2
330 | //
331 | this.splitContainer.Panel2.Controls.Add(this.previewGroupBox);
332 | this.splitContainer.Size = new System.Drawing.Size(843, 316);
333 | this.splitContainer.SplitterDistance = 281;
334 | this.splitContainer.TabIndex = 2;
335 | //
336 | // toolStrip
337 | //
338 | this.toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
339 | this.saveToolStripButton,
340 | this.toolStripSeparator6,
341 | this.copyToolStripButton,
342 | this.toolStripSeparator7,
343 | this.captureToolStripButton,
344 | this.delayCaptureToolStripButton,
345 | this.toolStripSeparator2,
346 | this.fillToolStripColorPickerSplitButton});
347 | this.toolStrip.Location = new System.Drawing.Point(0, 24);
348 | this.toolStrip.Name = "toolStrip";
349 | this.toolStrip.Size = new System.Drawing.Size(867, 25);
350 | this.toolStrip.TabIndex = 1;
351 | //
352 | // saveToolStripButton
353 | //
354 | this.saveToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
355 | this.saveToolStripButton.Image = global::Cyotek.Demo.SimpleScreenshotCapture.Properties.Resources.Save;
356 | this.saveToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
357 | this.saveToolStripButton.Name = "saveToolStripButton";
358 | this.saveToolStripButton.Size = new System.Drawing.Size(23, 22);
359 | this.saveToolStripButton.Text = "&Save";
360 | this.saveToolStripButton.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
361 | //
362 | // toolStripSeparator6
363 | //
364 | this.toolStripSeparator6.Name = "toolStripSeparator6";
365 | this.toolStripSeparator6.Size = new System.Drawing.Size(6, 25);
366 | //
367 | // copyToolStripButton
368 | //
369 | this.copyToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
370 | this.copyToolStripButton.Image = global::Cyotek.Demo.SimpleScreenshotCapture.Properties.Resources.Copy;
371 | this.copyToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
372 | this.copyToolStripButton.Name = "copyToolStripButton";
373 | this.copyToolStripButton.Size = new System.Drawing.Size(23, 22);
374 | this.copyToolStripButton.Text = "&Copy";
375 | this.copyToolStripButton.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
376 | //
377 | // toolStripSeparator7
378 | //
379 | this.toolStripSeparator7.Name = "toolStripSeparator7";
380 | this.toolStripSeparator7.Size = new System.Drawing.Size(6, 25);
381 | //
382 | // captureToolStripButton
383 | //
384 | this.captureToolStripButton.Image = global::Cyotek.Demo.SimpleScreenshotCapture.Properties.Resources.Capture;
385 | this.captureToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
386 | this.captureToolStripButton.Name = "captureToolStripButton";
387 | this.captureToolStripButton.Size = new System.Drawing.Size(69, 22);
388 | this.captureToolStripButton.Text = "&Capture";
389 | this.captureToolStripButton.Click += new System.EventHandler(this.captureToolStripMenuItem_Click);
390 | //
391 | // delayCaptureToolStripButton
392 | //
393 | this.delayCaptureToolStripButton.Image = global::Cyotek.Demo.SimpleScreenshotCapture.Properties.Resources.Timer;
394 | this.delayCaptureToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
395 | this.delayCaptureToolStripButton.Name = "delayCaptureToolStripButton";
396 | this.delayCaptureToolStripButton.Size = new System.Drawing.Size(101, 22);
397 | this.delayCaptureToolStripButton.Text = "&Delay Capture";
398 | this.delayCaptureToolStripButton.Click += new System.EventHandler(this.delayCaptureToolStripButton_Click);
399 | //
400 | // toolStripSeparator2
401 | //
402 | this.toolStripSeparator2.Name = "toolStripSeparator2";
403 | this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
404 | //
405 | // fillToolStripColorPickerSplitButton
406 | //
407 | this.fillToolStripColorPickerSplitButton.Color = System.Drawing.Color.White;
408 | this.fillToolStripColorPickerSplitButton.Image = global::Cyotek.Demo.SimpleScreenshotCapture.Properties.Resources.Fill;
409 | this.fillToolStripColorPickerSplitButton.Name = "fillToolStripColorPickerSplitButton";
410 | this.fillToolStripColorPickerSplitButton.Size = new System.Drawing.Size(32, 22);
411 | //
412 | // delayCaptureTimer
413 | //
414 | this.delayCaptureTimer.Interval = 1000;
415 | this.delayCaptureTimer.Tick += new System.EventHandler(this.delayCaptureTimer_Tick);
416 | //
417 | // statusStrip
418 | //
419 | this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
420 | this.toolStripStatusLabel1,
421 | this.timerToolStripStatusLabel});
422 | this.statusStrip.Location = new System.Drawing.Point(0, 371);
423 | this.statusStrip.Name = "statusStrip";
424 | this.statusStrip.Size = new System.Drawing.Size(867, 22);
425 | this.statusStrip.TabIndex = 3;
426 | //
427 | // toolStripStatusLabel1
428 | //
429 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
430 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(852, 17);
431 | this.toolStripStatusLabel1.Spring = true;
432 | this.toolStripStatusLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
433 | //
434 | // timerToolStripStatusLabel
435 | //
436 | this.timerToolStripStatusLabel.Name = "timerToolStripStatusLabel";
437 | this.timerToolStripStatusLabel.Size = new System.Drawing.Size(0, 17);
438 | //
439 | // MainForm
440 | //
441 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
442 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
443 | this.ClientSize = new System.Drawing.Size(867, 393);
444 | this.Controls.Add(this.statusStrip);
445 | this.Controls.Add(this.toolStrip);
446 | this.Controls.Add(this.splitContainer);
447 | this.Controls.Add(this.menuStrip);
448 | this.MainMenuStrip = this.menuStrip;
449 | this.Name = "MainForm";
450 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
451 | this.Text = "Simple Screenshot Capture";
452 | this.menuStrip.ResumeLayout(false);
453 | this.menuStrip.PerformLayout();
454 | this.previewGroupBox.ResumeLayout(false);
455 | this.setupGroupBox.ResumeLayout(false);
456 | this.setupGroupBox.PerformLayout();
457 | this.splitContainer.Panel1.ResumeLayout(false);
458 | this.splitContainer.Panel2.ResumeLayout(false);
459 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
460 | this.splitContainer.ResumeLayout(false);
461 | this.toolStrip.ResumeLayout(false);
462 | this.toolStrip.PerformLayout();
463 | this.statusStrip.ResumeLayout(false);
464 | this.statusStrip.PerformLayout();
465 | this.ResumeLayout(false);
466 | this.PerformLayout();
467 |
468 | }
469 |
470 | #endregion
471 | private Cyotek.Windows.Forms.ImageBox previewImageBox;
472 | private Cyotek.Windows.Forms.GroupBox setupGroupBox;
473 | private System.Windows.Forms.RadioButton desktopRadioButton;
474 | private System.Windows.Forms.ComboBox monitorComboBox;
475 | private System.Windows.Forms.RadioButton monitorRadioButton;
476 | private System.Windows.Forms.RadioButton currentMonitorRadioButton;
477 | private System.Windows.Forms.RadioButton currentWindowRadioButton;
478 | private System.Windows.Forms.Label label1;
479 | private Cyotek.Windows.Forms.GroupBox previewGroupBox;
480 | private Cyotek.Windows.Forms.Line line;
481 | private System.Windows.Forms.CheckBox workingAreaCheckBox;
482 | private System.Windows.Forms.MenuStrip menuStrip;
483 | private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
484 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator;
485 | private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem;
486 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
487 | private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
488 | private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem;
489 | private System.Windows.Forms.ToolStripMenuItem copyToolStripMenuItem;
490 | private System.Windows.Forms.SplitContainer splitContainer;
491 | private System.Windows.Forms.ToolStrip toolStrip;
492 | private System.Windows.Forms.ToolStripButton saveToolStripButton;
493 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
494 | private System.Windows.Forms.ToolStripButton copyToolStripButton;
495 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
496 | private System.Windows.Forms.ToolStripButton captureToolStripButton;
497 | private System.Windows.Forms.ToolStripMenuItem captureToolStripMenuItem;
498 | private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
499 | private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
500 | private System.Windows.Forms.ToolStripButton delayCaptureToolStripButton;
501 | private System.Windows.Forms.Timer delayCaptureTimer;
502 | private System.Windows.Forms.StatusStrip statusStrip;
503 | private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
504 | private System.Windows.Forms.ToolStripStatusLabel timerToolStripStatusLabel;
505 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
506 | private Cyotek.Windows.Forms.ToolStripControllerHosts.ToolStripColorPickerSplitButton fillToolStripColorPickerSplitButton;
507 | private System.Windows.Forms.CheckedListBox desktopScreensCheckedListBox;
508 | private Windows.Forms.Line line1;
509 | }
510 | }
511 |
512 |
--------------------------------------------------------------------------------
/src/MainForm.cs:
--------------------------------------------------------------------------------
1 | // Capturing screenshots using C# and p/invoke
2 | // http://www.cyotek.com/blog/capturing-screenshots-using-csharp-and-p-invoke
3 | // Copyright © 2017-2019 Cyotek Ltd. All Rights Reserved.
4 |
5 | // This work is licensed under the Creative Commons Attribution 4.0 International License.
6 | // To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
7 |
8 | using System;
9 | using System.Drawing;
10 | using System.Drawing.Drawing2D;
11 | using System.Drawing.Imaging;
12 | using System.Media;
13 | using System.Runtime.InteropServices;
14 | using System.Windows.Forms;
15 | using Cyotek.Windows.Forms;
16 |
17 | namespace Cyotek.Demo.SimpleScreenshotCapture
18 | {
19 | internal partial class MainForm : Form
20 | {
21 | #region Private Fields
22 |
23 | private Bitmap _preview;
24 |
25 | private int _timer;
26 |
27 | #endregion Private Fields
28 |
29 | #region Public Constructors
30 |
31 | public MainForm()
32 | {
33 | this.InitializeComponent();
34 | }
35 |
36 | #endregion Public Constructors
37 |
38 | #region Protected Methods
39 |
40 | protected override void OnShown(EventArgs e)
41 | {
42 | this.InitializeMonitorList();
43 |
44 | currentWindowRadioButton.Checked = true;
45 |
46 | base.OnShown(e);
47 | }
48 |
49 | #endregion Protected Methods
50 |
51 | #region Private Methods
52 |
53 | private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
54 | {
55 | using (AboutDialog dialog = new AboutDialog())
56 | {
57 | dialog.ShowDialog(this);
58 | }
59 | }
60 |
61 | private void CaptureImage()
62 | {
63 | Bitmap result;
64 | ScreenshotCapture capture;
65 | bool onlyCaptureWorkingArea;
66 |
67 | capture = new ScreenshotCapture();
68 |
69 | onlyCaptureWorkingArea = workingAreaCheckBox.Checked;
70 |
71 | if (currentWindowRadioButton.Checked)
72 | {
73 | result = capture.CaptureActiveWindow();
74 | }
75 | else if (currentMonitorRadioButton.Checked)
76 | {
77 | result = capture.CaptureMonitor(Screen.FromControl(this), onlyCaptureWorkingArea);
78 | }
79 | else if (monitorRadioButton.Checked)
80 | {
81 | result = capture.CaptureMonitor(monitorComboBox.SelectedIndex, onlyCaptureWorkingArea);
82 | }
83 | else
84 | {
85 | result = capture.CaptureDesktop(onlyCaptureWorkingArea, fillToolStripColorPickerSplitButton.Color, i => desktopScreensCheckedListBox.GetItemChecked(i));
86 | }
87 |
88 | this.UpdatePreview(result);
89 | }
90 |
91 | private void captureToolStripMenuItem_Click(object sender, EventArgs e)
92 | {
93 | this.CaptureImage();
94 | }
95 |
96 | private void copyToolStripMenuItem_Click(object sender, EventArgs e)
97 | {
98 | if (_preview == null)
99 | {
100 | SystemSounds.Beep.Play();
101 | }
102 | else
103 | {
104 | try
105 | {
106 | Clipboard.SetImage(_preview);
107 | }
108 | catch (ExternalException ex)
109 | {
110 | MessageBox.Show("Failed to copy image. " + ex.GetBaseException().Message, "Copy", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
111 | }
112 | }
113 | }
114 |
115 | private void delayCaptureTimer_Tick(object sender, EventArgs e)
116 | {
117 | _timer--;
118 |
119 | this.UpdateTimer();
120 |
121 | if (_timer < 0)
122 | {
123 | delayCaptureTimer.Stop();
124 |
125 | this.CaptureImage();
126 | }
127 | }
128 |
129 | private void delayCaptureToolStripButton_Click(object sender, EventArgs e)
130 | {
131 | this.DelayedCapture(3);
132 | }
133 |
134 | private void DelayedCapture(int seconds)
135 | {
136 | _timer = seconds;
137 |
138 | delayCaptureTimer.Stop();
139 | delayCaptureTimer.Start();
140 |
141 | this.UpdateTimer();
142 | }
143 |
144 | private void exitToolStripMenuItem_Click(object sender, EventArgs e)
145 | {
146 | this.Close();
147 | }
148 |
149 | private void InitializeMonitorList()
150 | {
151 | Screen[] screens;
152 |
153 | screens = Screen.AllScreens;
154 |
155 | for (int i = 0; i < screens.Length; i++)
156 | {
157 | string name;
158 |
159 | name = screens[i].DeviceName;
160 |
161 | monitorComboBox.Items.Add(name);
162 | desktopScreensCheckedListBox.Items.Add(name, true);
163 | }
164 |
165 | monitorComboBox.SelectedIndex = 0;
166 | }
167 |
168 | private void monitorComboBox_SelectedIndexChanged(object sender, EventArgs e)
169 | {
170 | monitorRadioButton.Checked = true;
171 | }
172 |
173 | private void previewImageBox_Zoomed(object sender, ImageBoxZoomEventArgs e)
174 | {
175 | previewImageBox.InterpolationMode = previewImageBox.Zoom < 100 ? InterpolationMode.HighQualityBicubic : InterpolationMode.NearestNeighbor;
176 | }
177 |
178 | private void SaveImage(string fileName)
179 | {
180 | try
181 | {
182 | _preview.Save(fileName, ImageFormat.Png);
183 | }
184 | catch (ExternalException ex)
185 | {
186 | MessageBox.Show("Failed to save image. " + ex.GetBaseException().Message, "Save", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
187 | }
188 | }
189 |
190 | private void saveToolStripMenuItem_Click(object sender, EventArgs e)
191 | {
192 | if (_preview == null)
193 | {
194 | MessageBox.Show("Nothing to save.", "Save", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
195 | }
196 | else
197 | {
198 | using (SaveFileDialog dialog = new SaveFileDialog
199 | {
200 | Title = "Save Image As",
201 | Filter = "PNG Files (*.png)|*.png",
202 | DefaultExt = "png"
203 | })
204 | {
205 | if (dialog.ShowDialog(this) == DialogResult.OK)
206 | {
207 | this.SaveImage(dialog.FileName);
208 | }
209 | }
210 | }
211 | }
212 |
213 | private void UpdatePreview(Bitmap capture)
214 | {
215 | if (_preview != null)
216 | {
217 | previewImageBox.Image = null;
218 | _preview.Dispose();
219 | _preview = null;
220 | }
221 |
222 | _preview = capture;
223 |
224 | previewImageBox.Image = capture;
225 | previewImageBox.ZoomToFit();
226 | }
227 |
228 | private void UpdateTimer()
229 | {
230 | timerToolStripStatusLabel.Text = _timer >= 0 ? _timer + "s" : string.Empty;
231 | }
232 |
233 | #endregion Private Methods
234 | }
235 | }
--------------------------------------------------------------------------------
/src/MainForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 | 137, 17
125 |
126 |
127 | 240, 17
128 |
129 |
130 | 403, 17
131 |
132 |
--------------------------------------------------------------------------------
/src/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | // Capturing screenshots using C# and p/invoke
2 | // http://www.cyotek.com/blog/capturing-screenshots-using-csharp-and-p-invoke
3 | // Copyright © 2017 Cyotek Ltd. All Rights Reserved.
4 |
5 | // This work is licensed under the Creative Commons Attribution 4.0 International License.
6 | // To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
7 |
8 | using System;
9 | using System.Runtime.InteropServices;
10 |
11 | // ReSharper disable FieldCanBeMadeReadOnly.Global
12 | // ReSharper disable InconsistentNaming
13 |
14 | namespace Cyotek.Demo.SimpleScreenshotCapture
15 | {
16 | internal static class NativeMethods
17 | {
18 | #region Externals
19 |
20 | [DllImport("gdi32.dll")]
21 | public static extern bool BitBlt(IntPtr hdcDest, int nxDest, int nyDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, RasterOperations dwRop);
22 |
23 | [DllImport("gdi32.dll")]
24 | public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
25 |
26 | [DllImport("gdi32.dll")]
27 | public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
28 |
29 | [DllImport("gdi32.dll")]
30 | public static extern IntPtr DeleteDC(IntPtr hdc);
31 |
32 | [DllImport("gdi32.dll")]
33 | public static extern IntPtr DeleteObject(IntPtr hObject);
34 |
35 | [DllImport("dwmapi.dll")]
36 | public static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out RECT pvAttribute, int cbAttribute);
37 |
38 | [DllImport("user32.dll")]
39 | public static extern IntPtr GetDesktopWindow();
40 |
41 | [DllImport("user32.dll")]
42 | public static extern IntPtr GetForegroundWindow();
43 |
44 | [DllImport("user32.dll")]
45 | public static extern IntPtr GetWindowDC(IntPtr hWnd);
46 |
47 | [DllImport("user32.dll", SetLastError = true)]
48 | public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
49 |
50 | [DllImport("user32.dll")]
51 | public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
52 |
53 | [DllImport("gdi32.dll")]
54 | public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);
55 |
56 | #endregion
57 |
58 | #region RasterOperations enum
59 |
60 | [Flags]
61 | public enum RasterOperations
62 | {
63 | SRCCOPY = 0x00CC0020,
64 |
65 | SRCPAINT = 0x00EE0086,
66 |
67 | SRCAND = 0x008800C6,
68 |
69 | SRCINVERT = 0x00660046,
70 |
71 | SRCERASE = 0x00440328,
72 |
73 | NOTSRCCOPY = 0x00330008,
74 |
75 | NOTSRCERASE = 0x001100A6,
76 |
77 | MERGECOPY = 0x00C000CA,
78 |
79 | MERGEPAINT = 0x00BB0226,
80 |
81 | PATCOPY = 0x00F00021,
82 |
83 | PATPAINT = 0x00FB0A09,
84 |
85 | PATINVERT = 0x005A0049,
86 |
87 | DSTINVERT = 0x00550009,
88 |
89 | BLACKNESS = 0x00000042,
90 |
91 | WHITENESS = 0x00FF0062,
92 |
93 | CAPTUREBLT = 0x40000000 //only if WinVer >= 5.0.0 (see wingdi.h)
94 | }
95 |
96 | #endregion
97 |
98 | #region Constants
99 |
100 | public const int DWMWA_EXTENDED_FRAME_BOUNDS = 9;
101 |
102 | #endregion
103 |
104 | #region Nested type: RECT
105 |
106 | [StructLayout(LayoutKind.Sequential)]
107 | public struct RECT
108 | {
109 | public int left;
110 |
111 | public int top;
112 |
113 | public int right;
114 |
115 | public int bottom;
116 | }
117 |
118 | #endregion
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/Program.cs:
--------------------------------------------------------------------------------
1 | // Capturing screenshots using C# and p/invoke
2 | // http://www.cyotek.com/blog/capturing-screenshots-using-csharp-and-p-invoke
3 | // Copyright © 2017 Cyotek Ltd. All Rights Reserved.
4 |
5 | // This work is licensed under the Creative Commons Attribution 4.0 International License.
6 | // To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
7 |
8 | using System;
9 | using System.Windows.Forms;
10 |
11 | namespace Cyotek.Demo.SimpleScreenshotCapture
12 | {
13 | internal static class Program
14 | {
15 | #region Static Methods
16 |
17 | ///
18 | /// The main entry point for the application.
19 | ///
20 | [STAThread]
21 | static void Main()
22 | {
23 | Application.EnableVisualStyles();
24 | Application.SetCompatibleTextRenderingDefault(false);
25 | Application.Run(new MainForm());
26 | }
27 |
28 | #endregion
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Capturing screenshots using C# and p/invoke
2 | // http://www.cyotek.com/blog/capturing-screenshots-using-csharp-and-p-invoke
3 | // Copyright © 2017-2019 Cyotek Ltd. All Rights Reserved.
4 |
5 | // This work is licensed under the Creative Commons Attribution 4.0 International License.
6 | // To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
7 |
8 | using System;
9 | using System.Reflection;
10 | using System.Runtime.InteropServices;
11 |
12 | [assembly: AssemblyTitle("Simple Screenshot Capture")]
13 | [assembly: AssemblyDescription("")]
14 | [assembly: AssemblyConfiguration("")]
15 | [assembly: AssemblyCompany("Cyotek Ltd")]
16 | [assembly: AssemblyProduct("Simple Screenshot Capture")]
17 | [assembly: AssemblyCopyright("Copyright © 2017-2019 Cyotek Ltd. All Rights Reserved.")]
18 | [assembly: AssemblyTrademark("")]
19 | [assembly: AssemblyCulture("")]
20 | [assembly: ComVisible(false)]
21 | [assembly: CLSCompliant(true)]
22 | [assembly: Guid("ec728998-a741-4388-99e3-29c5f013e011")]
23 | [assembly: AssemblyVersion("2.0.0.0")]
24 | [assembly: AssemblyFileVersion("2.0.0.0")]
25 |
--------------------------------------------------------------------------------
/src/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Cyotek.Demo.SimpleScreenshotCapture.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Cyotek.Demo.SimpleScreenshotCapture.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Drawing.Bitmap.
65 | ///
66 | internal static System.Drawing.Bitmap Capture {
67 | get {
68 | object obj = ResourceManager.GetObject("Capture", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized resource of type System.Drawing.Bitmap.
75 | ///
76 | internal static System.Drawing.Bitmap Copy {
77 | get {
78 | object obj = ResourceManager.GetObject("Copy", resourceCulture);
79 | return ((System.Drawing.Bitmap)(obj));
80 | }
81 | }
82 |
83 | ///
84 | /// Looks up a localized resource of type System.Drawing.Bitmap.
85 | ///
86 | internal static System.Drawing.Bitmap Fill {
87 | get {
88 | object obj = ResourceManager.GetObject("Fill", resourceCulture);
89 | return ((System.Drawing.Bitmap)(obj));
90 | }
91 | }
92 |
93 | ///
94 | /// Looks up a localized resource of type System.Drawing.Bitmap.
95 | ///
96 | internal static System.Drawing.Bitmap Save {
97 | get {
98 | object obj = ResourceManager.GetObject("Save", resourceCulture);
99 | return ((System.Drawing.Bitmap)(obj));
100 | }
101 | }
102 |
103 | ///
104 | /// Looks up a localized resource of type System.Drawing.Bitmap.
105 | ///
106 | internal static System.Drawing.Bitmap Timer {
107 | get {
108 | object obj = ResourceManager.GetObject("Timer", resourceCulture);
109 | return ((System.Drawing.Bitmap)(obj));
110 | }
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\Copy.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | ..\Resources\Save.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
128 | ..\Resources\Timer.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
129 |
130 |
131 | ..\Resources\Camera-Photo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
132 |
133 |
134 | ..\Resources\fill.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
135 |
136 |
--------------------------------------------------------------------------------
/src/Resources/Camera-Photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyotek/SimpleScreenshotCapture/c5a0170adbfadf1437d798d0f9417870d0c82003/src/Resources/Camera-Photo.png
--------------------------------------------------------------------------------
/src/Resources/Copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyotek/SimpleScreenshotCapture/c5a0170adbfadf1437d798d0f9417870d0c82003/src/Resources/Copy.png
--------------------------------------------------------------------------------
/src/Resources/Save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyotek/SimpleScreenshotCapture/c5a0170adbfadf1437d798d0f9417870d0c82003/src/Resources/Save.png
--------------------------------------------------------------------------------
/src/Resources/Timer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyotek/SimpleScreenshotCapture/c5a0170adbfadf1437d798d0f9417870d0c82003/src/Resources/Timer.png
--------------------------------------------------------------------------------
/src/Resources/fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyotek/SimpleScreenshotCapture/c5a0170adbfadf1437d798d0f9417870d0c82003/src/Resources/fill.png
--------------------------------------------------------------------------------
/src/ScreenshotCapture.cs:
--------------------------------------------------------------------------------
1 | // Capturing screenshots using C# and p/invoke
2 | // http://www.cyotek.com/blog/capturing-screenshots-using-csharp-and-p-invoke
3 | // Copyright © 2017-2019 Cyotek Ltd. All Rights Reserved.
4 |
5 | // This work is licensed under the Creative Commons Attribution 4.0 International License.
6 | // To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
7 |
8 | using System;
9 | using System.ComponentModel;
10 | using System.Drawing;
11 | using System.Drawing.Imaging;
12 | using System.Runtime.InteropServices;
13 | using System.Windows.Forms;
14 | using Cyotek.Windows.Forms;
15 |
16 | namespace Cyotek.Demo.SimpleScreenshotCapture
17 | {
18 | internal sealed class ScreenshotCapture
19 | {
20 | #region Public Methods
21 |
22 | public Bitmap CaptureActiveWindow()
23 | {
24 | return this.CaptureWindow(NativeMethods.GetForegroundWindow());
25 | }
26 |
27 | public Bitmap CaptureDesktop()
28 | {
29 | return this.CaptureDesktop(false);
30 | }
31 |
32 | public Bitmap CaptureDesktop(bool workingAreaOnly)
33 | {
34 | return this.CaptureDesktop(workingAreaOnly, Color.Transparent);
35 | }
36 |
37 | public Bitmap CaptureDesktop(Color invalidColor)
38 | {
39 | return this.CaptureDesktop(false, invalidColor);
40 | }
41 |
42 | public Bitmap CaptureDesktop(bool workingAreaOnly, Color invalidColor)
43 | {
44 | return CaptureDesktop(workingAreaOnly, invalidColor, index => true);
45 | }
46 |
47 | public Bitmap CaptureDesktop(Predicate includeScreen)
48 | {
49 | return CaptureDesktop(false, Color.Transparent, includeScreen);
50 | }
51 |
52 | public Bitmap CaptureDesktop(bool workingAreaOnly, Color invalidColor, Predicate includeScreen)
53 | {
54 | DesktopLayout layout;
55 | Bitmap bitmap;
56 |
57 | layout = new DesktopLayout
58 | {
59 | WorkingAreaOnly = workingAreaOnly
60 | };
61 |
62 | bitmap = new Bitmap(layout.Width, layout.Height, PixelFormat.Format32bppArgb);
63 |
64 | using (Graphics g = Graphics.FromImage(bitmap))
65 | {
66 | g.Clear(invalidColor);
67 |
68 | for (int i = 0; i < layout.Count; i++)
69 | {
70 | if (includeScreen(i))
71 | {
72 | Rectangle bounds;
73 |
74 | bounds = layout.GetDisplayBounds(i);
75 |
76 | using (Bitmap displayImage = CaptureRegion(bounds))
77 | {
78 | g.DrawImageUnscaled(displayImage, layout.GetNormalizedDisplayBounds(bounds));
79 | }
80 | }
81 | }
82 | }
83 |
84 | return bitmap;
85 | }
86 |
87 | public Bitmap CaptureMonitor(Screen monitor)
88 | {
89 | return this.CaptureMonitor(monitor, false);
90 | }
91 |
92 | public Bitmap CaptureMonitor(Screen monitor, bool workingAreaOnly)
93 | {
94 | Rectangle region;
95 |
96 | region = workingAreaOnly ? monitor.WorkingArea : monitor.Bounds;
97 |
98 | return this.CaptureRegion(region);
99 | }
100 |
101 | public Bitmap CaptureMonitor(int index)
102 | {
103 | return this.CaptureMonitor(index, false);
104 | }
105 |
106 | public Bitmap CaptureMonitor(int index, bool workingAreaOnly)
107 | {
108 | return this.CaptureMonitor(Screen.AllScreens[index], workingAreaOnly);
109 | }
110 |
111 | public Bitmap CaptureRegion(Rectangle region)
112 | {
113 | IntPtr desktophWnd;
114 | IntPtr desktopDc;
115 | IntPtr memoryDc;
116 | IntPtr bitmap;
117 | IntPtr oldBitmap;
118 | bool success;
119 | Bitmap result;
120 |
121 | desktophWnd = NativeMethods.GetDesktopWindow();
122 | desktopDc = NativeMethods.GetWindowDC(desktophWnd);
123 | memoryDc = NativeMethods.CreateCompatibleDC(desktopDc);
124 | bitmap = NativeMethods.CreateCompatibleBitmap(desktopDc, region.Width, region.Height);
125 | oldBitmap = NativeMethods.SelectObject(memoryDc, bitmap);
126 |
127 | success = NativeMethods.BitBlt(memoryDc, 0, 0, region.Width, region.Height, desktopDc, region.Left, region.Top, NativeMethods.RasterOperations.SRCCOPY | NativeMethods.RasterOperations.CAPTUREBLT);
128 |
129 | try
130 | {
131 | if (!success)
132 | {
133 | throw new Win32Exception();
134 | }
135 |
136 | result = Image.FromHbitmap(bitmap);
137 | }
138 | finally
139 | {
140 | NativeMethods.SelectObject(memoryDc, oldBitmap);
141 | NativeMethods.DeleteObject(bitmap);
142 | NativeMethods.DeleteDC(memoryDc);
143 | NativeMethods.ReleaseDC(desktophWnd, desktopDc);
144 | }
145 |
146 | return result;
147 | }
148 |
149 | public Bitmap CaptureWindow(IntPtr hWnd)
150 | {
151 | NativeMethods.RECT region;
152 |
153 | if (Environment.OSVersion.Version.Major < 6)
154 | {
155 | NativeMethods.GetWindowRect(hWnd, out region);
156 | }
157 | else
158 | {
159 | if (NativeMethods.DwmGetWindowAttribute(hWnd, NativeMethods.DWMWA_EXTENDED_FRAME_BOUNDS, out region, Marshal.SizeOf(typeof(NativeMethods.RECT))) != 0)
160 | {
161 | NativeMethods.GetWindowRect(hWnd, out region);
162 | }
163 | }
164 |
165 | return this.CaptureRegion(Rectangle.FromLTRB(region.left, region.top, region.right, region.bottom));
166 | }
167 |
168 | public Bitmap CaptureWindow(Form form)
169 | {
170 | return this.CaptureWindow(form.Handle);
171 | }
172 |
173 | #endregion Public Methods
174 | }
175 | }
--------------------------------------------------------------------------------
/src/SimpleScreenshotCapture.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {EC728998-A741-4388-99E3-29C5F013E011}
8 | WinExe
9 | Properties
10 | Cyotek.Demo.SimpleScreenshotCapture
11 | ssc
12 | v4.6
13 | 512
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | false
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 | app.manifest
38 |
39 |
40 |
41 | ..\packages\Cyotek.Windows.Forms.ColorPicker.1.7.2\lib\net35\Cyotek.Windows.Forms.ColorPicker.dll
42 |
43 |
44 | ..\packages\CyotekImageBox.1.2.1\lib\net20\Cyotek.Windows.Forms.ImageBox.dll
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Form
61 |
62 |
63 | AboutDialog.cs
64 |
65 |
66 |
67 | Component
68 |
69 |
70 | Component
71 |
72 |
73 | Form
74 |
75 |
76 | MainForm.cs
77 |
78 |
79 |
80 |
81 |
82 |
83 | Component
84 |
85 |
86 | Component
87 |
88 |
89 | AboutDialog.cs
90 |
91 |
92 | MainForm.cs
93 |
94 |
95 | ResXFileCodeGenerator
96 | Resources.Designer.cs
97 | Designer
98 |
99 |
100 | True
101 | Resources.resx
102 | True
103 |
104 |
105 | ToolStripColorPickerDropDown.cs
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
136 |
--------------------------------------------------------------------------------
/src/ToolStripColorPickerDropDown.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyotek/SimpleScreenshotCapture/c5a0170adbfadf1437d798d0f9417870d0c82003/src/ToolStripColorPickerDropDown.cs
--------------------------------------------------------------------------------
/src/ToolStripColorPickerDropDown.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | False
122 |
123 |
--------------------------------------------------------------------------------
/src/ToolStripColorPickerSplitButton.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 | using System.Windows.Forms.Design;
6 |
7 | // Cyotek Color Picker controls library
8 | // Copyright © 2013-2017 Cyotek Ltd.
9 | // http://cyotek.com/blog/tag/colorpicker
10 |
11 | // Licensed under the MIT License. See license.txt for the full text.
12 |
13 | // If you use this code in your applications, donations or attribution are welcome
14 |
15 | namespace Cyotek.Windows.Forms.ToolStripControllerHosts
16 | {
17 | [DefaultProperty("Color")]
18 | [DefaultEvent("ColorChanged")]
19 | [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
20 | public class ToolStripColorPickerSplitButton : ToolStripSplitButton
21 | {
22 | #region Constants
23 |
24 | private static readonly object _eventColorChanged = new object();
25 |
26 | #endregion
27 |
28 | #region Fields
29 |
30 | private Color _color;
31 |
32 | private ToolStripColorPickerDropDown _dropDown;
33 |
34 | #endregion
35 |
36 | #region Constructors
37 |
38 | public ToolStripColorPickerSplitButton()
39 | {
40 | this.Color = Color.Black;
41 | }
42 |
43 | #endregion
44 |
45 | #region Events
46 |
47 | [Category("Property Changed")]
48 | public event EventHandler ColorChanged
49 | {
50 | add { this.Events.AddHandler(_eventColorChanged, value); }
51 | remove { this.Events.RemoveHandler(_eventColorChanged, value); }
52 | }
53 |
54 | #endregion
55 |
56 | #region Properties
57 |
58 | [Category("Data")]
59 | [DefaultValue(typeof(Color), "Black")]
60 | public virtual Color Color
61 | {
62 | get { return _color; }
63 | set
64 | {
65 | if (this.Color != value)
66 | {
67 | _color = value;
68 |
69 | this.OnColorChanged(EventArgs.Empty);
70 | }
71 | }
72 | }
73 |
74 | [Browsable(false)]
75 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
76 | public new ToolStripDropDown DropDown
77 | {
78 | get { return base.DropDown; }
79 | set { base.DropDown = value; }
80 | }
81 |
82 | [Browsable(false)]
83 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
84 | public ColorGrid Host
85 | {
86 | get
87 | {
88 | this.EnsureDropDownIsCreated();
89 |
90 | return _dropDown.Host;
91 | }
92 | }
93 |
94 | #endregion
95 |
96 | #region Methods
97 |
98 | protected override ToolStripDropDown CreateDefaultDropDown()
99 | {
100 | this.EnsureDropDownIsCreated();
101 |
102 | return _dropDown;
103 | }
104 |
105 | ///
106 | /// Releases the unmanaged resources used by the and optionally releases the managed resources.
107 | ///
108 | /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
109 | protected override void Dispose(bool disposing)
110 | {
111 | if (disposing)
112 | {
113 | if (_dropDown != null)
114 | {
115 | this.DropDown = null;
116 | _dropDown.Dispose();
117 | _dropDown.ColorChanged -= this.DropDownColorChangedHandler;
118 | _dropDown = null;
119 | }
120 | }
121 |
122 | base.Dispose(disposing);
123 | }
124 |
125 | ///
126 | /// Raises the event.
127 | ///
128 | /// An that contains the event data.
129 | protected override void OnButtonClick(EventArgs e)
130 | {
131 | base.OnButtonClick(e);
132 |
133 | using (ColorPickerDialog dialog = new ColorPickerDialog())
134 | {
135 | dialog.Color = this.Color;
136 |
137 | if (dialog.ShowDialog(this.GetCurrentParent()) == DialogResult.OK)
138 | {
139 | this.Color = dialog.Color;
140 | }
141 | }
142 | }
143 |
144 | ///
145 | /// Raises the event.
146 | ///
147 | /// The instance containing the event data.
148 | protected virtual void OnColorChanged(EventArgs e)
149 | {
150 | EventHandler handler;
151 |
152 | this.Invalidate();
153 |
154 | if (_dropDown != null)
155 | {
156 | _dropDown.Color = this.Color;
157 | }
158 |
159 | handler = (EventHandler)this.Events[_eventColorChanged];
160 |
161 | handler?.Invoke(this, e);
162 | }
163 |
164 | ///
165 | /// Raised in response to the method.
166 | ///
167 | /// An that contains the event data.
168 | protected override void OnDropDownShow(EventArgs e)
169 | {
170 | this.EnsureDropDownIsCreated();
171 | base.OnDropDownShow(e);
172 | }
173 |
174 | /// A that contains the event data.
175 | protected override void OnPaint(PaintEventArgs e)
176 | {
177 | Rectangle underline;
178 |
179 | base.OnPaint(e);
180 |
181 | underline = this.GetUnderlineRectangle(e.Graphics);
182 |
183 | using (Brush brush = new SolidBrush(this.Color))
184 | {
185 | e.Graphics.FillRectangle(brush, underline);
186 | }
187 | }
188 |
189 | private void DropDownColorChangedHandler(object sender, EventArgs e)
190 | {
191 | this.Color = _dropDown.Color;
192 | }
193 |
194 | private void EnsureDropDownIsCreated()
195 | {
196 | if (_dropDown == null)
197 | {
198 | _dropDown = new ToolStripColorPickerDropDown();
199 | _dropDown.ColorChanged += this.DropDownColorChangedHandler;
200 | }
201 | }
202 |
203 | private Rectangle GetUnderlineRectangle(Graphics g)
204 | {
205 | int x;
206 | int y;
207 | int w;
208 | int h;
209 |
210 | // TODO: These are approximate values and may not work with different font sizes or image sizes etc
211 |
212 | h = 4; // static height!
213 | x = this.ContentRectangle.Left;
214 | y = this.ContentRectangle.Bottom - (h + 1);
215 |
216 | if (this.DisplayStyle == ToolStripItemDisplayStyle.ImageAndText && this.Image != null && !string.IsNullOrEmpty(this.Text))
217 | {
218 | int innerHeight;
219 |
220 | innerHeight = this.Image.Height - h;
221 |
222 | // got both an image and some text to deal with
223 | w = this.Image.Width;
224 | y = this.ButtonBounds.Top + innerHeight + (this.ButtonBounds.Height - this.Image.Height) / 2;
225 |
226 | switch (this.TextImageRelation)
227 | {
228 | case TextImageRelation.TextBeforeImage:
229 | x = this.ButtonBounds.Right - (w + this.ButtonBounds.Left + 2);
230 | break;
231 | case TextImageRelation.ImageAboveText:
232 | x = this.ButtonBounds.Left + (this.ButtonBounds.Width - this.Image.Width) / 2;
233 | y = this.ButtonBounds.Top + innerHeight + 2;
234 | break;
235 | case TextImageRelation.TextAboveImage:
236 | x = this.ButtonBounds.Left + (this.ButtonBounds.Width - this.Image.Width) / 2;
237 | y = this.ContentRectangle.Bottom - h;
238 | break;
239 | case TextImageRelation.Overlay:
240 | x = this.ButtonBounds.Left + (this.ButtonBounds.Width - this.Image.Width) / 2;
241 | y = this.ButtonBounds.Top + innerHeight + (this.ButtonBounds.Height - this.Image.Height) / 2;
242 | break;
243 | }
244 | }
245 | else if (this.DisplayStyle == ToolStripItemDisplayStyle.Image && this.Image != null)
246 | {
247 | // just the image
248 | w = this.Image.Width;
249 | }
250 | else if (this.DisplayStyle == ToolStripItemDisplayStyle.Text && !string.IsNullOrEmpty(this.Text))
251 | {
252 | // just the text
253 | w = TextRenderer.MeasureText(g, this.Text, this.Font).Width;
254 | }
255 | else
256 | {
257 | // who knows, use what we have
258 | // TODO: ButtonBounds (and SplitterBounds for that matter) seem to return the wrong
259 | // values when painting first occurs, so the line is too narrow until after you
260 | // hover the mouse over the button
261 | w = this.ButtonBounds.Width - this.ContentRectangle.Left * 2;
262 | }
263 |
264 | return new Rectangle(x, y, w, h);
265 | }
266 |
267 | #endregion
268 | }
269 | }
270 |
--------------------------------------------------------------------------------
/src/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | true/PM
7 |
8 |
9 |
10 |
11 |
12 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------