diff --git a/.gitignore b/.gitignore index 0a37a27..6a528ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ bin/ obj/ +packages/ *.userprefs *.suo \ No newline at end of file diff --git a/AeroShot.csproj b/AeroShot.csproj index 52443ae..5340dd9 100644 --- a/AeroShot.csproj +++ b/AeroShot.csproj @@ -10,7 +10,7 @@ Properties AeroShot AeroShot - v2.0 + v3.5 512 icon.ico AeroShot.Program @@ -33,6 +33,7 @@ false false true + Client true @@ -56,6 +57,8 @@ AnyCPU + + Form @@ -72,6 +75,7 @@ Form + @@ -95,5 +99,9 @@ true + + + + \ No newline at end of file diff --git a/App_Packages/Gini/Ini.cs b/App_Packages/Gini/Ini.cs new file mode 100644 index 0000000..67241dd --- /dev/null +++ b/App_Packages/Gini/Ini.cs @@ -0,0 +1,391 @@ +#region The MIT License (MIT) +// +// Copyright (c) 2013 Atif Aziz. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +#endregion + +namespace Gini +{ + #region Imports + + using System; + using System.Collections; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Diagnostics; + using System.Linq; + using System.Text.RegularExpressions; + + #endregion + + #if GINI_PUBLIC + public partial class Ini { } + #endif + + static partial class Ini + { + static class Parser + { + static readonly Regex Regex; + static readonly int SectionNumber; + static readonly int KeyNumber; + static readonly int ValueNumber; + + static Parser() + { + var re = Regex = + new Regex(@"^ *(\[(?[a-z0-9-._][a-z0-9-._ ]*)\]|(?[a-z0-9-._][a-z0-9-._ ]*)= *(?[^\r\n]*))\s*$", + RegexOptions.Multiline + | RegexOptions.IgnoreCase + | RegexOptions.CultureInvariant); + SectionNumber = re.GroupNumberFromName("s"); + KeyNumber = re.GroupNumberFromName("k"); + ValueNumber = re.GroupNumberFromName("v"); + } + + // ReSharper disable once MemberHidesStaticFromOuterClass + public static IEnumerable Parse(string ini, Func selector) + { + return from Match m in Regex.Matches(ini ?? string.Empty) + select m.Groups into g + select selector(g[SectionNumber].Value.TrimEnd(), + g[KeyNumber].Value.TrimEnd(), + g[ValueNumber].Value.TrimEnd()); + } + } + + public static IEnumerable>> Parse(string ini) + { + return Parse(ini, KeyValuePair.Create); + } + + public static IEnumerable> Parse(string ini, Func settingSelector) + { + return Parse(ini, (_, k, v) => settingSelector(k, v)); + } + + public static IEnumerable> Parse(string ini, Func settingSelector) + { + if (settingSelector == null) throw new ArgumentNullException("settingSelector"); + + ini = ini.Trim(); + if (string.IsNullOrEmpty(ini)) + return Enumerable.Empty>(); + + var entries = + from ms in new[] + { + Parser.Parse(ini, (s, k, v) => new + { + Section = s, + Setting = KeyValuePair.Create(k, v) + }) + } + from p in Enumerable.Repeat(new { Section = (string) null, + Setting = KeyValuePair.Create(string.Empty, string.Empty) }, 1) + .Concat(ms) + .GroupAdjacent(s => s.Section == null || s.Section.Length > 0) + .Pairwise((prev, curr) => new { Prev = prev, Curr = curr }) + where p.Prev.Key + select KeyValuePair.Create(p.Prev.Last().Section, p.Curr) into e + from s in e.Value + select KeyValuePair.Create(e.Key, settingSelector(e.Key, s.Setting.Key, s.Setting.Value)); + + return entries.GroupAdjacent(e => e.Key, e => e.Value); + } + + public static IDictionary> ParseHash(string ini) + { + return ParseHash(ini, null); + } + + public static IDictionary> ParseHash(string ini, IEqualityComparer comparer) + { + comparer = comparer ?? StringComparer.OrdinalIgnoreCase; + var sections = Parse(ini); + return sections.GroupBy(g => g.Key ?? string.Empty, comparer) + .ToDictionary(g => g.Key, + g => (IDictionary) g.SelectMany(e => e) + .GroupBy(e => e.Key, comparer) + .ToDictionary(e => e.Key, e => e.Last().Value, comparer), + comparer); + } + + public static IDictionary ParseFlatHash(string ini, Func keyMerger) + { + return ParseFlatHash(ini, keyMerger, null); + } + + public static IDictionary ParseFlatHash(string ini, Func keyMerger, IEqualityComparer comparer) + { + if (keyMerger == null) throw new ArgumentNullException("keyMerger"); + + var settings = new Dictionary(comparer ?? StringComparer.OrdinalIgnoreCase); + foreach (var setting in from section in Parse(ini) + from setting in section + select KeyValuePair.Create(keyMerger(section.Key, setting.Key), setting.Value)) + { + settings[setting.Key] = setting.Value; + } + return settings; + } + + static class KeyValuePair + { + public static KeyValuePair Create(TKey key, TValue value) + { + return new KeyValuePair(key, value); + } + } + + #region MoreLINQ + + // MoreLINQ - Extensions to LINQ to Objects + // Copyright (c) 2008 Jonathan Skeet. All rights reserved. + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + + static IEnumerable Pairwise(this IEnumerable source, Func resultSelector) + { + if (source == null) throw new ArgumentNullException("source"); + if (resultSelector == null) throw new ArgumentNullException("resultSelector"); + return PairwiseImpl(source, resultSelector); + } + + static IEnumerable PairwiseImpl(this IEnumerable source, Func resultSelector) + { + Debug.Assert(source != null); + Debug.Assert(resultSelector != null); + + using (var e = source.GetEnumerator()) + { + if (!e.MoveNext()) + yield break; + + var previous = e.Current; + while (e.MoveNext()) + { + yield return resultSelector(previous, e.Current); + previous = e.Current; + } + } + } + + static IEnumerable> GroupAdjacent( + this IEnumerable source, + Func keySelector) + { + // ReSharper disable once IntroduceOptionalParameters.Local + return GroupAdjacent(source, keySelector, null); + } + + static IEnumerable> GroupAdjacent( + this IEnumerable source, + Func keySelector, + IEqualityComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + + return GroupAdjacent(source, keySelector, e => e, comparer); + } + + static IEnumerable> GroupAdjacent( + this IEnumerable source, + Func keySelector, + Func elementSelector) + { + // ReSharper disable once IntroduceOptionalParameters.Local + return GroupAdjacent(source, keySelector, elementSelector, null); + } + + static IEnumerable> GroupAdjacent( + this IEnumerable source, + Func keySelector, + Func elementSelector, + IEqualityComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + if (elementSelector == null) throw new ArgumentNullException("elementSelector"); + + return GroupAdjacentImpl(source, keySelector, elementSelector, + comparer ?? EqualityComparer.Default); + } + + static IEnumerable> GroupAdjacentImpl( + this IEnumerable source, + Func keySelector, + Func elementSelector, + IEqualityComparer comparer) + { + Debug.Assert(source != null); + Debug.Assert(keySelector != null); + Debug.Assert(elementSelector != null); + Debug.Assert(comparer != null); + + using (var iterator = source.Select(item => KeyValuePair.Create(keySelector(item), elementSelector(item))) + .GetEnumerator()) + { + var group = default(TKey); + var members = (List) null; + + while (iterator.MoveNext()) + { + var item = iterator.Current; + if (members != null && comparer.Equals(group, item.Key)) + { + members.Add(item.Value); + } + else + { + if (members != null) + yield return CreateGroupAdjacentGrouping(group, members); + group = item.Key; + members = new List { item.Value }; + } + } + + if (members != null) + yield return CreateGroupAdjacentGrouping(group, members); + } + } + + static Grouping CreateGroupAdjacentGrouping(TKey key, IList members) + { + Debug.Assert(members != null); + return new Grouping(key, members.IsReadOnly ? members : new ReadOnlyCollection(members)); + } + + sealed class Grouping : IGrouping + { + readonly IEnumerable _members; + + public Grouping(TKey key, IEnumerable members) + { + Debug.Assert(members != null); + Key = key; + _members = members; + } + + public TKey Key { get; private set; } + + public IEnumerator GetEnumerator() { return _members.GetEnumerator(); } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + } + + #endregion + } +} + +#if GINI_DYNAMIC + +namespace Gini +{ + #region Imports + + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Dynamic; + using System.Globalization; + using System.Linq; + + #endregion + + static partial class Ini + { + public static dynamic ParseObject(string ini) + { + return ParseObject(ini, null); + } + + public static dynamic ParseObject(string ini, IEqualityComparer comparer) + { + comparer = comparer ?? StringComparer.OrdinalIgnoreCase; + var config = new Dictionary>(comparer); + foreach (var section in from g in Parse(ini).GroupBy(e => e.Key ?? string.Empty, comparer) + select KeyValuePair.Create(g.Key, g.SelectMany(e => e))) + { + var settings = new Dictionary(comparer); + foreach (var setting in section.Value) + settings[setting.Key] = setting.Value; + config[section.Key] = new Config(settings); + } + return new Config>(config); + } + + public static dynamic ParseFlatObject(string ini, Func keyMerger) + { + return ParseFlatObject(ini, keyMerger, null); + } + + public static dynamic ParseFlatObject(string ini, Func keyMerger, IEqualityComparer comparer) + { + if (keyMerger == null) throw new ArgumentNullException("keyMerger"); + return new Config(ParseFlatHash(ini, keyMerger, comparer)); + } + + sealed class Config : DynamicObject + { + readonly IDictionary _entries; + + public Config(IDictionary entries) + { + Debug.Assert(entries != null); + _entries = entries; + } + + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + if (binder == null) throw new ArgumentNullException("binder"); + result = Find(binder.Name); + return true; + } + + public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length != 1) throw new ArgumentException("Too many indexes supplied."); + var index = indexes[0]; + result = Find(index == null ? null : Convert.ToString(index, CultureInfo.InvariantCulture)); + return true; + } + + object Find(string name) + { + T value; + return _entries.TryGetValue(name, out value) ? value : default(T); + } + } + } +} + +#endif diff --git a/Gini.cs b/Gini.cs new file mode 100644 index 0000000..013da8e --- /dev/null +++ b/Gini.cs @@ -0,0 +1,64 @@ +#region The MIT License (MIT) +// +// Copyright (c) 2015 Atif Aziz. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +#endregion + +namespace Gini +{ + using System; + using System.Collections.Generic; + using System.Linq; + + partial class Ini + { + public static IEnumerable Format( + IEnumerable sections, + Func sectionNameSelector, + Func> entriesSelector, + Func> entrySelector) + { + if (sections == null) throw new ArgumentNullException("sections"); + if (sectionNameSelector == null) throw new ArgumentNullException("sectionNameSelector"); + if (entriesSelector == null) throw new ArgumentNullException("entriesSelector"); + if (entrySelector == null) throw new ArgumentNullException("entrySelector"); + + return + from section in sections + select new + { + Name = sectionNameSelector(section), + Entries = entriesSelector(section), + } + into section + from lines in new[] + { + new[] { !string.IsNullOrEmpty(section.Name) ? "[" + section.Name + "]" : null }, + from entry in section.Entries + select entrySelector(entry) into entry + select entry.Key + "=" + entry.Value, + new[] { string.Empty }, + } + from line in lines + where line != null + select line; + } + } +} \ No newline at end of file diff --git a/Hotkeys.cs b/Hotkeys.cs index 4b65a0f..44fab50 100644 --- a/Hotkeys.cs +++ b/Hotkeys.cs @@ -1,4 +1,4 @@ -/* AeroShot - Transparent screenshot utility for Windows +/* AeroShot - Transparent screenshot utility for Windows Copyright (C) 2015 toe_head2001 Copyright (C) 2012 Caleb Joseph @@ -30,7 +30,6 @@ public class Hotkeys : Form private readonly int[] _windowId; private Thread _worker; private bool _busyCapturing; - Settings _settings; public Hotkeys() { @@ -52,62 +51,51 @@ private void FormClose(object sender, FormClosingEventArgs e) protected override void WndProc(ref Message m) { base.WndProc(ref m); - if (m.Msg == WM_HOTKEY) - { - _settings = new Settings(); - - if (_busyCapturing) - return; - ScreenshotTask info = GetParamteresFromUI(); - var CtrlAlt = (m.LParam.ToInt32() & (MOD_ALT | MOD_CONTROL)) == (MOD_ALT | MOD_CONTROL); - _busyCapturing = true; - _worker = new Thread(() => - { - if (CtrlAlt) - Thread.Sleep(TimeSpan.FromSeconds(3)); - else if (_settings.delayCheckbox) - Thread.Sleep(TimeSpan.FromSeconds(_settings.delaySeconds)); - try - { - Screenshot.CaptureWindow(ref info); - } - finally - { - _busyCapturing = false; - } - }) - { - IsBackground = true - }; - _worker.SetApartmentState(ApartmentState.STA); - _worker.Start(); - } + OnHotKey(m); } - private ScreenshotTask GetParamteresFromUI() + void OnHotKey(Message message) { - var type = ScreenshotTask.BackgroundType.Transparent; - if (_settings.opaqueCheckbox && _settings.opaqueType == 0) - type = ScreenshotTask.BackgroundType.Checkerboard; - else if (_settings.opaqueCheckbox && _settings.opaqueType == 1) - type = ScreenshotTask.BackgroundType.SolidColor; + if (_busyCapturing) + return; + + var settings = Settings.LoadSettings(); - return - new ScreenshotTask( - WindowsApi.GetForegroundWindow(), - _settings.clipboardButton, - _settings.folderTextBox, - _settings.resizeCheckbox, - _settings.windowWidth, - _settings.windowHeight, - type, - Color.FromArgb(Convert.ToInt32("FF" + _settings.opaqueColorHexBox, 16)), - _settings.checkerValue, - _settings.aeroColorCheckbox, - Color.FromArgb(Convert.ToInt32("FF" + _settings.aeroColorHexBox, 16)), - _settings.mouseCheckbox, - _settings.clearTypeCheckbox); + var info = new ScreenshotTask( + WindowsApi.GetForegroundWindow(), + settings.UseClipboard, + settings.FolderPath, + settings.ResizeDimensions.Convert(v => (Size?) v), + settings.OpaqueBackgroundType.GetValueOrDefault(), + settings.SolidBackgroundColor, + settings.CheckerboardBackgroundCheckerSize, + settings.AeroColor.Convert(v => (Color?) v), + settings.CaputreMouse, + settings.DisableClearType); + + var CtrlAlt = (message.LParam.ToInt32() & (MOD_ALT | MOD_CONTROL)) == (MOD_ALT | MOD_CONTROL); + _busyCapturing = true; + _worker = new Thread(() => + { + if (CtrlAlt) + Thread.Sleep(TimeSpan.FromSeconds(3)); + else + settings.DelayCaptureDuration.WhenOnThen(Thread.Sleep); + try + { + Screenshot.CaptureWindow(ref info); + } + finally + { + _busyCapturing = false; + } + }) + { + IsBackground = true + }; + _worker.SetApartmentState(ApartmentState.STA); + _worker.Start(); } } } \ No newline at end of file diff --git a/Main.Designer.cs b/Main.Designer.cs index 1c2ab35..a092047 100644 --- a/Main.Designer.cs +++ b/Main.Designer.cs @@ -1,4 +1,4 @@ -/* AeroShot - Transparent screenshot utility for Windows +/* AeroShot - Transparent screenshot utility for Windows Copyright (C) 2015 toe_head2001 Copyright (C) 2012 Caleb Joseph @@ -702,7 +702,7 @@ private void InitializeComponent() this.Name = "MainForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "AeroShot Mini v1.5.0 - Settings"; + this.Text = "{0} {1} - Settings"; ((System.ComponentModel.ISupportInitialize)(this.windowHeight)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.windowWidth)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.checkerValue)).EndInit(); diff --git a/Main.cs b/Main.cs index fb2a33d..9a40d2d 100644 --- a/Main.cs +++ b/Main.cs @@ -19,7 +19,6 @@ You should have received a copy of the GNU General Public License using System.Drawing; using System.Text; using System.Windows.Forms; -using Microsoft.Win32; namespace AeroShot { @@ -28,31 +27,34 @@ public sealed partial class MainForm : Form private const uint SPI_GETFONTSMOOTHING = 0x004A; private const uint SPI_GETFONTSMOOTHINGTYPE = 0x200A; - private readonly RegistryKey _registryKey; - Settings _settings = new Settings(); - public MainForm() { DoubleBuffered = true; Icon = new Icon(typeof(MainForm), "icon.ico"); InitializeComponent(); - folderTextBox.Text = _settings.folderTextBox; - clipboardButton.Checked = _settings.clipboardButton; - diskButton.Checked = _settings.diskButton; - resizeCheckbox.Checked = _settings.resizeCheckbox; - windowWidth.Value = _settings.windowWidth; - windowHeight.Value = _settings.windowHeight; - opaqueCheckbox.Checked = _settings.opaqueCheckbox; - opaqueType.SelectedIndex = _settings.opaqueType; - checkerValue.Value = _settings.checkerValue; - opaqueColorHexBox.Text = _settings.opaqueColorHexBox; - aeroColorCheckbox.Checked = _settings.aeroColorCheckbox; - aeroColorHexBox.Text = _settings.aeroColorHexBox; - mouseCheckbox.Checked = _settings.mouseCheckbox; - delayCheckbox.Checked = _settings.delayCheckbox; - delaySeconds.Value = _settings.delaySeconds; - clearTypeCheckbox.Checked = _settings.clearTypeCheckbox; + Text = string.Format(Text, Application.ProductName, Application.ProductVersion); + + var settings = Settings.LoadSettings(); + + folderTextBox.Text = settings.FolderPath; + clipboardButton.Checked = settings.UseClipboard; + diskButton.Checked = settings.UseDisk; + resizeCheckbox.Checked = settings.ResizeDimensions.On; + windowWidth.Value = settings.ResizeDimensions.Value.Width; + windowHeight.Value = settings.ResizeDimensions.Value.Height; + opaqueCheckbox.Checked = settings.OpaqueBackgroundType.On; + opaqueType.SelectedIndex = ScreenshotBackgroundType.Checkerboard == settings.OpaqueBackgroundType.Value ? 0 + : ScreenshotBackgroundType.SolidColor == settings.OpaqueBackgroundType.Value ? 1 + : -1; + checkerValue.Value = settings.CheckerboardBackgroundCheckerSize; + opaqueColorHexBox.Text = HexColor.Encode(settings.SolidBackgroundColor); + aeroColorCheckbox.Checked = settings.AeroColor.On; + aeroColorHexBox.Text = HexColor.Encode(settings.AeroColor.Value); + mouseCheckbox.Checked = settings.CaputreMouse; + delayCheckbox.Checked = settings.DelayCaptureDuration.On; + delaySeconds.Value = (decimal) settings.DelayCaptureDuration.Value.TotalSeconds; + clearTypeCheckbox.Checked = settings.DisableClearType; if (!GlassAvailable()) { @@ -72,8 +74,6 @@ public MainForm() delayGroupBox.Enabled = delayCheckbox.Checked; clearTypeGroupBox.Enabled = clearTypeCheckbox.Checked; aeroColorGroupBox.Enabled = aeroColorCheckbox.Checked; - - _registryKey = Registry.CurrentUser.CreateSubKey(@"Software\AeroShot"); } private static bool GlassAvailable() @@ -279,67 +279,23 @@ private void AeroColorTextboxTextChange(object sender, EventArgs e) private void OkButtonClick(object sender, EventArgs e) { - if (clipboardButton.Checked) - _registryKey.SetValue("LastPath", "*" + folderTextBox.Text); - else - _registryKey.SetValue("LastPath", folderTextBox.Text); - - // Save resizing settings in an 8-byte long - var b = new byte[8]; - b[0] = (byte)(resizeCheckbox.Checked ? 1 : 0); - - b[3] = (byte)((int)windowWidth.Value & 0xff); - b[2] = (byte)(((int)windowWidth.Value >> 8) & 0xff); - b[1] = (byte)(((int)windowWidth.Value >> 16) & 0xff); - - b[6] = (byte)((int)windowHeight.Value & 0xff); - b[5] = (byte)(((int)windowHeight.Value >> 8) & 0xff); - b[4] = (byte)(((int)windowHeight.Value >> 16) & 0xff); - - long data = BitConverter.ToInt64(b, 0); - _registryKey.SetValue("WindowSize", data, RegistryValueKind.QWord); - - // Save background color settings in an 8-byte long - b = new byte[8]; - b[0] = (byte)(opaqueCheckbox.Checked ? 1 : 0); - b[0] += (byte)Math.Pow(2, opaqueType.SelectedIndex + 1); - - b[1] = (byte)(checkerValue.Value - 2); - - b[2] = opaqueColorDialog.Color.R; - b[3] = opaqueColorDialog.Color.G; - b[4] = opaqueColorDialog.Color.B; - - data = BitConverter.ToInt64(b, 0); - _registryKey.SetValue("Opaque", data, RegistryValueKind.QWord); - - // Save background color settings in an 8-byte long - b = new byte[8]; - b[0] = (byte)(aeroColorCheckbox.Checked ? 1 : 0); - - b[1] = aeroColorDialog.Color.R; - b[2] = aeroColorDialog.Color.G; - b[3] = aeroColorDialog.Color.B; - - data = BitConverter.ToInt64(b, 0); - _registryKey.SetValue("AeroColor", data, RegistryValueKind.QWord); - - _registryKey.SetValue("CapturePointer", - mouseCheckbox.Checked ? 1 : 0, - RegistryValueKind.DWord); - - _registryKey.SetValue("ClearType", - clearTypeCheckbox.Checked ? 1 : 0, - RegistryValueKind.DWord); - - // Save delay settings in an 8-byte long - b = new byte[8]; - b[0] = (byte)(delayCheckbox.Checked ? 1 : 0); - - b[1] = (byte)(((int)delaySeconds.Value) & 0xff); - - data = BitConverter.ToInt64(b, 0); - _registryKey.SetValue("Delay", data, RegistryValueKind.QWord); + Settings.SaveSettings(new Settings + { + UseClipboard = clipboardButton.Checked, + FolderPath = folderTextBox.Text, + ResizeDimensions = Switch.Create(resizeCheckbox.Checked, + new Size((int) windowWidth.Value, + (int) windowHeight.Value)), + OpaqueBackgroundType = Switch.Create(opaqueCheckbox.Checked, + opaqueType.SelectedIndex == 1 + ? ScreenshotBackgroundType.SolidColor + : ScreenshotBackgroundType.Checkerboard), + SolidBackgroundColor = opaqueColorDialog.Color, + AeroColor = Switch.Create(aeroColorCheckbox.Checked, aeroColorDialog.Color), + CaputreMouse = mouseCheckbox.Checked, + DisableClearType = clearTypeCheckbox.Checked, + DelayCaptureDuration = Switch.Create(delayCheckbox.Checked, TimeSpan.FromSeconds((int) delaySeconds.Value)), + }); this.Close(); } diff --git a/Program.cs b/Program.cs index 6148c76..00752ff 100644 --- a/Program.cs +++ b/Program.cs @@ -1,4 +1,4 @@ -/* AeroShot - Transparent screenshot utility for Windows +/* AeroShot - Transparent screenshot utility for Windows Copyright (C) 2015 toe_head2001 Copyright (C) 2012 Caleb Joseph @@ -23,7 +23,7 @@ You should have received a copy of the GNU General Public License [assembly: AssemblyTitle("AeroShot Mini")] [assembly: AssemblyProduct("AeroShot Mini")] [assembly: AssemblyDescription("Screenshot capture utility for Windows Aero")] -[assembly: AssemblyCopyright("© 2015 toe_head2001")] +[assembly: AssemblyCopyright("\u00a9 2015 toe_head2001")] [assembly: AssemblyVersion("1.5.0.0")] [assembly: AssemblyFileVersion("1.5.0.0")] [assembly: ComVisible(false)] @@ -37,7 +37,7 @@ private static void Main() { if (Environment.OSVersion.Version.Major < 6) { - MessageBox.Show("Windows Vista or newer is required.", "AeroShot"); + MessageBox.Show("Windows Vista or newer is required.", Application.ProductName); return; } diff --git a/Screenshot.cs b/Screenshot.cs index d338308..41e9b3a 100644 --- a/Screenshot.cs +++ b/Screenshot.cs @@ -1,4 +1,4 @@ -/* AeroShot - Transparent screenshot utility for Windows +/* AeroShot - Transparent screenshot utility for Windows Copyright (C) 2015 toe_head2001 Copyright (C) 2012 Caleb Joseph @@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; +using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; @@ -26,52 +27,46 @@ You should have received a copy of the GNU General Public License namespace AeroShot { - internal struct ScreenshotTask + internal struct ScreenshotTask { - public enum BackgroundType - { - Transparent, - Checkerboard, - SolidColor - } - - public BackgroundType Background; - public Color BackgroundColor; - public bool CaptureMouse; - public bool DisableClearType; - public int CheckerboardSize; - public bool CustomGlass; - public Color AeroColor; - public bool ClipboardNotDisk; - public string DiskSaveDirectory; - public bool DoResize; - public int ResizeX; - public int ResizeY; - public IntPtr WindowHandle; + public readonly ScreenshotBackgroundType Background; + public readonly Color BackgroundColor; + public readonly bool CaptureMouse; + public readonly bool DisableClearType; + public readonly int CheckerboardSize; + public readonly Color? AeroColor; + public readonly bool ClipboardNotDisk; + public readonly string DiskSaveDirectory; + public readonly Size? Resize; + public readonly IntPtr WindowHandle; public ScreenshotTask(IntPtr window, bool clipboard, string file, - bool resize, int resizeX, int resizeY, - BackgroundType backType, Color backColor, - int checkerSize, bool customGlass, Color aeroColor, + Size? resize, + ScreenshotBackgroundType backType, Color backColor, + int checkerSize, Color? aeroColor, bool mouse, bool clearType) { WindowHandle = window; ClipboardNotDisk = clipboard; DiskSaveDirectory = file; - DoResize = resize; - ResizeX = resizeX; - ResizeY = resizeY; + Resize = resize.HasValue && resize.Value.IsEmpty ? null : resize; Background = backType; BackgroundColor = backColor; CheckerboardSize = checkerSize; - CustomGlass = customGlass; - AeroColor = aeroColor; + AeroColor = aeroColor.HasValue && aeroColor.Value.IsEmpty ? null : aeroColor; CaptureMouse = mouse; DisableClearType = clearType; } } - internal static class Screenshot + enum ScreenshotBackgroundType + { + Transparent, + Checkerboard, + SolidColor + } + + internal static class Screenshot { private const uint SWP_NOACTIVATE = 0x0010; private const int GWL_STYLE = -16; @@ -120,7 +115,7 @@ internal static void CaptureWindow(ref ScreenshotTask data) bool AeroColorToggled = false; WindowsApi.DWM_COLORIZATION_PARAMS originalParameters; WindowsApi.DwmGetColorizationParameters(out originalParameters); - if (data.CustomGlass && AeroEnabled()) + if (data.AeroColor != null && AeroEnabled()) { // Original colorization parameters originalParameters.clrGlassReflectionIntensity = 50; @@ -130,7 +125,7 @@ internal static void CaptureWindow(ref ScreenshotTask data) WindowsApi.DwmGetColorizationParameters(out parameters); parameters.clrAfterGlowBalance = 2; parameters.clrBlurBalance = 29; - parameters.clrColor = ColorToBgra(data.AeroColor); + parameters.clrColor = ColorToBgra(data.AeroColor.Value); parameters.nIntensity = 69; // Call the DwmSetColorizationParameters to make the change take effect. @@ -139,7 +134,7 @@ internal static void CaptureWindow(ref ScreenshotTask data) } var r = new WindowsRect(0); - if (data.DoResize) + if (data.Resize != null) { SmartResizeWindow(ref data, out r); Thread.Sleep(100); @@ -186,7 +181,7 @@ internal static void CaptureWindow(ref ScreenshotTask data) { if (data.ClipboardNotDisk && data.Background != - ScreenshotTask.BackgroundType.Transparent) + ScreenshotBackgroundType.Transparent) // Screenshot is already opaque, don't need to modify it Clipboard.SetImage(s); else if (data.ClipboardNotDisk) @@ -237,7 +232,7 @@ internal static void CaptureWindow(ref ScreenshotTask data) s.Dispose(); } - if (data.DoResize) + if (data.Resize != null) { if ( (WindowsApi.GetWindowLong(data.WindowHandle, @@ -309,6 +304,9 @@ private static bool ClearTypeEnabled() private static void SmartResizeWindow(ref ScreenshotTask data, out WindowsRect oldWindowSize) { + Debug.Assert(data.Resize != null); + var dim = data.Resize.Value; + oldWindowSize = new WindowsRect(0); if ((WindowsApi.GetWindowLong(data.WindowHandle, GWL_STYLE) & WS_SIZEBOX) != WS_SIZEBOX) @@ -323,9 +321,9 @@ private static void SmartResizeWindow(ref ScreenshotTask data, { WindowsApi.SetWindowPos(data.WindowHandle, (IntPtr)0, r.Left, r.Top, - data.ResizeX - + dim.Width - (f.Width - (r.Right - r.Left)), - data.ResizeY - + dim.Height - (f.Height - (r.Bottom - r.Top)), SWP_SHOWWINDOW); f.Dispose(); @@ -333,7 +331,7 @@ private static void SmartResizeWindow(ref ScreenshotTask data, else { WindowsApi.SetWindowPos(data.WindowHandle, (IntPtr)0, r.Left, - r.Top, data.ResizeX, data.ResizeY, + r.Top, dim.Width, dim.Height, SWP_SHOWWINDOW); } } @@ -342,8 +340,8 @@ private static unsafe Bitmap CaptureCompositeScreenshot( ref ScreenshotTask data) { Color tmpColor = data.BackgroundColor; - if (data.Background == ScreenshotTask.BackgroundType.Transparent || - data.Background == ScreenshotTask.BackgroundType.Checkerboard) + if (data.Background == ScreenshotBackgroundType.Transparent || + data.Background == ScreenshotBackgroundType.Checkerboard) tmpColor = Color.White; var backdrop = new Form { @@ -401,7 +399,7 @@ private static unsafe Bitmap CaptureCompositeScreenshot( rct.Right - rct.Left, rct.Bottom - rct.Top)); - if (data.Background == ScreenshotTask.BackgroundType.SolidColor) + if (data.Background == ScreenshotBackgroundType.SolidColor) { backdrop.Dispose(); if (data.CaptureMouse) @@ -432,7 +430,7 @@ private static unsafe Bitmap CaptureCompositeScreenshot( whiteShot.Dispose(); blackShot.Dispose(); - if (data.Background == ScreenshotTask.BackgroundType.Checkerboard) + if (data.Background == ScreenshotBackgroundType.Checkerboard) { var final = new Bitmap(transparentImage.Width, transparentImage.Height, diff --git a/Settings.cs b/Settings.cs index db33354..267d12c 100644 --- a/Settings.cs +++ b/Settings.cs @@ -1,4 +1,4 @@ -/* AeroShot - Transparent screenshot utility for Windows +/* AeroShot - Transparent screenshot utility for Windows Copyright (C) 2015 toe_head2001 Copyright (C) 2012 Caleb Joseph @@ -15,133 +15,306 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the You should have received a copy of the GNU General Public License along with this program. If not, see . */ -using System; -using System.Text; -using Microsoft.Win32; - namespace AeroShot { - public class Settings + using System; + using System.Collections.Generic; + using System.Drawing; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Text.RegularExpressions; + using System.Windows.Forms; + using Microsoft.Win32; + using Gini; + + sealed class Settings { - public bool firstRun; - public int checkerValue = 8; - public string opaqueColorHexBox; - public string folderTextBox; - public bool opaqueCheckbox; - public byte opaqueType; - public bool aeroColorCheckbox; - public string aeroColorHexBox; - public bool resizeCheckbox; - public int windowHeight = 640; - public int windowWidth = 480; - public bool diskButton; - public bool clipboardButton; - public bool mouseCheckbox; - public bool delayCheckbox; - public byte delaySeconds = 3; - public bool clearTypeCheckbox; - private readonly RegistryKey _registryKey; - - - public Settings() - { - object value; - _registryKey = Registry.CurrentUser.CreateSubKey(@"Software\AeroShot"); - - if ((value = _registryKey.GetValue("FirstRun")) == null) - { - firstRun = true; - } + public bool UseDisk { get; set; } + public bool UseClipboard { get { return !UseDisk; } set { UseDisk = !value; } } + public string FolderPath { get; set; } + public Switch OpaqueBackgroundType { get; set; } + public Color SolidBackgroundColor { get; set; } + public int CheckerboardBackgroundCheckerSize { get; set; } + public Switch AeroColor { get; set; } + public Switch ResizeDimensions { get; set; } + public bool CaputreMouse { get; set; } + public Switch DelayCaptureDuration { get; set; } + public bool DisableClearType { get; set; } + public Settings() + { + OpaqueBackgroundType = Switch.Off(ScreenshotBackgroundType.Checkerboard); + CheckerboardBackgroundCheckerSize = 8; + AeroColor = Switch.Off(Color.White); + ResizeDimensions = Switch.Off(new Size(640, 480)); + DelayCaptureDuration = Switch.Off(TimeSpan.FromSeconds(3)); + } - if ((value = _registryKey.GetValue("LastPath")) != null && - value.GetType() == (typeof(string))) - { - if (((string)value).Substring(0, 1) == "*") + static string _iniFilePath; + + static string IniFilePath + { + get { return _iniFilePath ?? (_iniFilePath = Path.Combine(Application.StartupPath, "AeroShot.ini")); } + } + + public static Settings LoadSettings() + { + return File.Exists(IniFilePath) + ? LoadSettingsFromIniFile(IniFilePath) + : LoadSettingsFromRegistry(); + } + + static class IniKey + { + public const string AppVersion = "app-version"; + public const string SaveDevice = "save-device"; + public const string SaveFilePath = "save-file-path"; + public const string UseOpaqueBackground = "use-opaque-background"; + public const string OpaqueBackgroundType = "opaque-background-type"; + public const string SolidBackgroundColor = "solid-background-color"; + public const string CheckerboardBackgroundCheckerSize = "checkerboard-background-checker-size"; + public const string UseAeroColor = "use-aero-color"; + public const string AeroColor = "aero-color"; + public const string UseWindowResizeDimensions = "use-window-resize-dimensions"; + public const string ResizeWindowWidth = "resize-window-width"; + public const string ResizeWindowHeight = "resize-window-height"; + public const string UseDelayCapture = "use-delay-capture"; + public const string DelayCaptureSeconds = "delay-capture-seconds"; + public const string CapturePointer = "capture-pointer"; + public const string DisableClearType = "disable-clear-type"; + } + + static class IniWord + { + public const string File = "file"; + public const string Solid = "solid"; + public const string Clipboard = "clipboard"; + public const string Checkerboard = "checkerboard"; + } + + static Settings LoadSettingsFromIniFile(string path) + { + return LoadSettingsFromIni(File.ReadAllText(path)); + } + + static Settings LoadSettingsFromIni(string source) + { + var settings = new Settings(); + + var ini = Ini.Parse(source) + .Where(s => string.IsNullOrEmpty(s.Key)) + .Select(s => s.ToDictionary(e => e.Key, e => e.Value, StringComparer.OrdinalIgnoreCase)) + .FirstOrDefault(); + + if (ini != null) + { + settings.UseDisk = ReadSetting(ini, IniKey.SaveDevice, v => IniWord.File.Equals(v, StringComparison.OrdinalIgnoreCase)); + settings.FolderPath = ReadSetting(ini, IniKey.SaveFilePath, Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), s => s); + settings.OpaqueBackgroundType + = Switch.Create(ReadSetting(ini, IniKey.UseOpaqueBackground, Truthy.Parse), + ReadSetting(ini, IniKey.OpaqueBackgroundType, v => IniWord.Solid.Equals(v, StringComparison.OrdinalIgnoreCase) + ? ScreenshotBackgroundType.SolidColor + : ScreenshotBackgroundType.Checkerboard)); + settings.SolidBackgroundColor + = ReadSetting(ini, IniKey.SolidBackgroundColor, settings.SolidBackgroundColor, ColorTranslator.FromHtml); + settings.CheckerboardBackgroundCheckerSize + = ReadSetting(ini, IniKey.CheckerboardBackgroundCheckerSize, settings.CheckerboardBackgroundCheckerSize, ParseInt); + settings.AeroColor = Switch.Create(ReadSetting(ini, IniKey.UseAeroColor, Truthy.Parse), + ReadSetting(ini, IniKey.AeroColor, settings.AeroColor.Value, ColorTranslator.FromHtml)); + settings.ResizeDimensions = Switch.Create(ReadSetting(ini, IniKey.UseWindowResizeDimensions, Truthy.Parse), + new Size(ReadSetting(ini, IniKey.ResizeWindowWidth, settings.ResizeDimensions.Value.Width, ParseInt), + ReadSetting(ini, IniKey.ResizeWindowHeight, settings.ResizeDimensions.Value.Height, ParseInt))); + settings.DelayCaptureDuration + = Switch.Create(ReadSetting(ini, IniKey.UseDelayCapture, Truthy.Parse), + ReadSetting(ini, IniKey.DelayCaptureSeconds, settings.DelayCaptureDuration.Value, v => TimeSpan.FromSeconds(ParseInt(v)))); + settings.CaputreMouse = ReadSetting(ini, IniKey.CapturePointer, Truthy.Parse); + settings.DisableClearType = ReadSetting(ini, IniKey.DisableClearType, Truthy.Parse); + } + + return settings; + } + + static T ReadSetting(IDictionary section, string key, Func selector) + { + return ReadSetting(section, key, default(T), selector); + } + + static T ReadSetting(IDictionary section, string key, T defaultValue, Func selector) + { + string value; + if (section.TryGetValue(key, out value)) + value = value.Trim(); + return !string.IsNullOrEmpty(value) ? selector(value) : defaultValue; + } + + static int ParseInt(string s) { return int.Parse(s, NumberStyles.None, CultureInfo.InvariantCulture); } + + static class Truthy + { + static readonly Regex Regex = new Regex(@"^\s*(true|yes|on|1)\s*$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + public static bool Parse(string s) { return Regex.IsMatch(s); } + } + + public static void SaveSettings(Settings settings) + { + File.WriteAllText(IniFilePath, SettingsIni(settings)); + // TODO Handle UnauthorizedAccessException + } + + static string SettingsIni(Settings settings) + { + var section = new[] + { + Setting(IniKey.AppVersion , Application.ProductVersion), + Setting(IniKey.SaveDevice , settings.UseClipboard ? IniWord.Clipboard : IniWord.File), + Setting(IniKey.SaveFilePath , settings.FolderPath), + Setting(IniKey.UseOpaqueBackground , settings.OpaqueBackgroundType.Convert(_ => true)), + Setting(IniKey.OpaqueBackgroundType , settings.OpaqueBackgroundType.Value == ScreenshotBackgroundType.SolidColor ? IniWord.Solid : IniWord.Checkerboard), + Setting(IniKey.SolidBackgroundColor , ColorTranslator.ToHtml(settings.SolidBackgroundColor)), + Setting(IniKey.CheckerboardBackgroundCheckerSize, settings.CheckerboardBackgroundCheckerSize), + Setting(IniKey.UseAeroColor , settings.AeroColor.Convert(_ => true)), + Setting(IniKey.AeroColor , ColorTranslator.ToHtml(settings.AeroColor.Value)), + Setting(IniKey.UseWindowResizeDimensions , settings.ResizeDimensions.Convert(_ => true)), + Setting(IniKey.ResizeWindowWidth , settings.ResizeDimensions.Value.Width), + Setting(IniKey.ResizeWindowHeight , settings.ResizeDimensions.Value.Height), + Setting(IniKey.CapturePointer , settings.CaputreMouse), + Setting(IniKey.UseDelayCapture , settings.DelayCaptureDuration.Convert(_ => true)), + Setting(IniKey.DelayCaptureSeconds , settings.DelayCaptureDuration.Value.TotalSeconds), + Setting(IniKey.DisableClearType , settings.DisableClearType), + }; + + return string.Join(Environment.NewLine, + Ini.Format(new[] { section }, e => null, e => e, e => e) + .ToArray()); + } + + static KeyValuePair Setting(string key, string value) + { + return KeyValuePair.Create(key, value ?? string.Empty); + } + + static KeyValuePair Setting(string key, bool value) + { + return KeyValuePair.Create(key, value ? "true" : "false"); + } + + static KeyValuePair Setting(string key, object value) + { + return Setting(key, value == null + ? string.Empty + : Convert.ToString(value, CultureInfo.InvariantCulture)); + } + + public static Settings LoadSettingsFromRegistry() + { + using (var registryKey = Registry.CurrentUser.OpenSubKey(@"Software\AeroShot")) + return LoadSettings(registryKey); + } + + public static Settings LoadSettings(RegistryKey registryKey) + { + var settings = new Settings(); + + if (registryKey == null) + return settings; + + object value; + + if ((value = registryKey.GetValue("LastPath")) is string) + { + var str = value.ToString(); + if (str.Substring(0, 1) == "*") { - folderTextBox = ((string)value).Substring(1); - clipboardButton = true; + settings.FolderPath = str.Substring(1); + settings.UseClipboard = true; } else { - folderTextBox = (string)value; - diskButton = true; + settings.FolderPath = str; + settings.UseDisk = true; } } else { - folderTextBox = + settings.FolderPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); } - if ((value = _registryKey.GetValue("WindowSize")) != null && - value.GetType() == (typeof(long))) + if ((value = registryKey.GetValue("WindowSize")) is long) { var b = new byte[8]; for (int i = 0; i < 8; i++) b[i] = (byte)(((long)value >> (i * 8)) & 0xff); - resizeCheckbox = (b[0] & 1) == 1; - windowWidth = b[1] << 16 | b[2] << 8 | b[3]; - windowHeight = b[4] << 16 | b[5] << 8 | b[6]; + var use = (b[0] & 1) == 1; + var width = b[1] << 16 | b[2] << 8 | b[3]; + var height = b[4] << 16 | b[5] << 8 | b[6]; + settings.ResizeDimensions = Switch.Create(use, new Size(width, height)); } - if ((value = _registryKey.GetValue("Opaque")) != null && - value.GetType() == (typeof(long))) + var defaultOpaqueBackgroundType = Switch.Off(ScreenshotBackgroundType.Checkerboard); + + if ((value = registryKey.GetValue("Opaque")) is long) { var b = new byte[8]; for (int i = 0; i < 8; i++) b[i] = (byte)(((long)value >> (i * 8)) & 0xff); - opaqueCheckbox = (b[0] & 1) == 1; - if ((b[0] & 2) == 2) - opaqueType = 0; - if ((b[0] & 4) == 4) - opaqueType = 1; - - checkerValue = b[1] + 2; - - var hex = new StringBuilder(6); - hex.AppendFormat("{0:X2}", b[2]); - hex.AppendFormat("{0:X2}", b[3]); - hex.AppendFormat("{0:X2}", b[4]); - opaqueColorHexBox = hex.ToString(); + var use = (b[0] & 1) == 1; + var type = (b[0] & 2) == 2 ? ScreenshotBackgroundType.Checkerboard + : (b[0] & 4) == 4 ? ScreenshotBackgroundType.SolidColor + : ScreenshotBackgroundType.Transparent; + settings.OpaqueBackgroundType = Switch.Create(use, type); + settings.CheckerboardBackgroundCheckerSize = b[1] + 2; + settings.SolidBackgroundColor = Color.FromArgb(b[2], b[3], b[4]); } else - opaqueType = 0; + settings.OpaqueBackgroundType = defaultOpaqueBackgroundType; - if ((value = _registryKey.GetValue("AeroColor")) != null && - value.GetType() == (typeof(long))) + if ((value = registryKey.GetValue("AeroColor")) is long) { var b = new byte[8]; for (int i = 0; i < 8; i++) b[i] = (byte)(((long)value >> (i * 8)) & 0xff); - aeroColorCheckbox = (b[0] & 1) == 1; - - var hex = new StringBuilder(6); - hex.AppendFormat("{0:X2}", b[1]); - hex.AppendFormat("{0:X2}", b[2]); - hex.AppendFormat("{0:X2}", b[3]); - aeroColorHexBox = hex.ToString(); + var use = (b[0] & 1) == 1; + settings.AeroColor = Switch.Create(use, Color.FromArgb(b[1], b[2], b[3])); } else - opaqueType = 0; + settings.OpaqueBackgroundType = defaultOpaqueBackgroundType; - if ((value = _registryKey.GetValue("CapturePointer")) != null && - value.GetType() == (typeof(int))) - mouseCheckbox = ((int)value & 1) == 1; + if ((value = registryKey.GetValue("CapturePointer")) is int) + settings.CaputreMouse = ((int)value & 1) == 1; - if ((value = _registryKey.GetValue("ClearType")) != null && - value.GetType() == (typeof(int))) - clearTypeCheckbox = ((int)value & 1) == 1; + if ((value = registryKey.GetValue("ClearType")) is int) + settings.DisableClearType = ((int)value & 1) == 1; - if ((value = _registryKey.GetValue("Delay")) != null && - value.GetType() == (typeof(long))) + if ((value = registryKey.GetValue("Delay")) is long) { var b = new byte[8]; for (int i = 0; i < 8; i++) b[i] = (byte)(((long)value >> (i * 8)) & 0xff); - delayCheckbox = (b[0] & 1) == 1; - delaySeconds = b[1]; + var use = (b[0] & 1) == 1; + settings.DelayCaptureDuration = Switch.Create(use, TimeSpan.FromSeconds(b[1])); } + + return settings; } } + + static class KeyValuePair + { + public static KeyValuePair Create(TKey key, TValue value) + { + return new KeyValuePair(key, value); + } + } + + static class HexColor + { + public static string Encode(Color color) + { + if (color.IsEmpty) return null; + color = Color.FromArgb(color.ToArgb()); + return ColorTranslator.ToHtml(color).Substring(1); // remove # + } + } } \ No newline at end of file diff --git a/Switch.cs b/Switch.cs new file mode 100644 index 0000000..affe9c1 --- /dev/null +++ b/Switch.cs @@ -0,0 +1,47 @@ +/* AeroShot - Transparent screenshot utility for Windows + Copyright (C) 2015 toe_head2001 + Copyright (C) 2012 Caleb Joseph + + AeroShot is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + AeroShot is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +namespace AeroShot +{ + using System; + + static class Switch + { + public static Switch On(T value) { return Create(true, value); } + public static Switch Off(T value) { return Create(false, value); } + public static Switch Create(bool on, T value) { return new Switch(on, value); } + } + + sealed class Switch + { + public bool On { get; private set; } + public T Value { get; private set; } + + public Switch(bool on, T value) { On = on; Value = value; } + + public T GetValueOrDefault() { return On ? Value : default(T); } + + public TResult Convert(Converter onSelector, TResult offValue = default(TResult)) + { + return On ? onSelector(Value) : offValue; + } + + public void WhenOnThen(Action then) { if (On) then(Value); } + + public override string ToString() { return string.Format("{0}", Value); } + } +} \ No newline at end of file diff --git a/Tray.cs b/Tray.cs index ad876ee..ff577dc 100644 --- a/Tray.cs +++ b/Tray.cs @@ -1,4 +1,4 @@ -/* AeroShot - Transparent screenshot utility for Windows +/* AeroShot - Transparent screenshot utility for Windows Copyright (C) 2015 toe_head2001 AeroShot is free software: you can redistribute it and/or modify @@ -27,7 +27,7 @@ public class SysTray : Form MainForm _window = new MainForm(); Hotkeys _hotkeys = new Hotkeys(); - Settings _settings = new Settings(); + Settings _settings = Settings.LoadSettings(); public SysTray() { @@ -57,9 +57,9 @@ protected override void OnLoad(EventArgs e) base.OnLoad(e); string saveLocation; - if (_settings.diskButton) + if (_settings.UseDisk) { - saveLocation = "\"" + _settings.folderTextBox + "\""; + saveLocation = "\"" + _settings.FolderPath + "\""; } else { diff --git a/UnsafeBitmap.cs b/UnsafeBitmap.cs index 6a9acae..eb5f661 100644 --- a/UnsafeBitmap.cs +++ b/UnsafeBitmap.cs @@ -1,4 +1,4 @@ -/* AeroShot - Transparent screenshot utility for Windows +/* AeroShot - Transparent screenshot utility for Windows Copyright (C) 2012 Caleb Joseph AeroShot is free software: you can redistribute it and/or modify diff --git a/WindowsAPI.cs b/WindowsAPI.cs index 7b92b12..73042d4 100644 --- a/WindowsAPI.cs +++ b/WindowsAPI.cs @@ -1,4 +1,4 @@ -/* AeroShot - Transparent screenshot utility for Windows +/* AeroShot - Transparent screenshot utility for Windows Copyright (C) 2015 toe_head2001 Copyright (C) 2012 Caleb Joseph diff --git a/app.config b/app.config new file mode 100644 index 0000000..ce099b3 --- /dev/null +++ b/app.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages.config b/packages.config new file mode 100644 index 0000000..926cb52 --- /dev/null +++ b/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file