Merge pull request #1567 from campbeb/greenshotmerge21May

Merge Greenshot changes through 22 May 2016
This commit is contained in:
Jaex 2016-05-22 18:36:30 +03:00
commit c224117fe2
87 changed files with 1269 additions and 1130 deletions

View file

@ -205,6 +205,9 @@ public class CoreConfiguration : IniSection, INotifyPropertyChanged
[IniProperty("OptimizeForRDP", Description = "Make some optimizations for usage with remote desktop", DefaultValue = "False")] [IniProperty("OptimizeForRDP", Description = "Make some optimizations for usage with remote desktop", DefaultValue = "False")]
public bool OptimizeForRDP; public bool OptimizeForRDP;
[IniProperty("DisableRDPOptimizing", Description = "Disable all optimizations for usage with remote desktop", DefaultValue = "False")]
public bool DisableRDPOptimizing;
[IniProperty("MinimizeWorkingSetSize", Description = "Optimize memory footprint, but with a performance penalty!", DefaultValue = "False")] [IniProperty("MinimizeWorkingSetSize", Description = "Optimize memory footprint, but with a performance penalty!", DefaultValue = "False")]
public bool MinimizeWorkingSetSize; public bool MinimizeWorkingSetSize;

View file

@ -77,7 +77,7 @@ public override void AfterLoad()
/// <param name="requestingType">Type of the class for which to create the field</param> /// <param name="requestingType">Type of the class for which to create the field</param>
/// <param name="fieldType">FieldType of the field to construct</param> /// <param name="fieldType">FieldType of the field to construct</param>
/// <param name="scope">FieldType of the field to construct</param> /// <param name="preferredDefaultValue">FieldType of the field to construct</param>
/// <returns>a new Field of the given fieldType, with the scope of it's value being restricted to the Type scope</returns> /// <returns>a new Field of the given fieldType, with the scope of it's value being restricted to the Type scope</returns>
public Field CreateField(Type requestingType, FieldType fieldType, object preferredDefaultValue) public Field CreateField(Type requestingType, FieldType fieldType, object preferredDefaultValue)
{ {

View file

@ -32,7 +32,7 @@ namespace GreenshotPlugin.Controls
/// </summary> /// </summary>
internal partial class BackgroundForm : Form internal partial class BackgroundForm : Form
{ {
private volatile bool shouldClose = false; private volatile bool _shouldClose;
private void BackgroundShowDialog() private void BackgroundShowDialog()
{ {
@ -43,7 +43,7 @@ public static BackgroundForm ShowAndWait(string title, string text)
{ {
BackgroundForm backgroundForm = new BackgroundForm(title, text); BackgroundForm backgroundForm = new BackgroundForm(title, text);
// Show form in background thread // Show form in background thread
Thread backgroundTask = new Thread(new ThreadStart(backgroundForm.BackgroundShowDialog)); Thread backgroundTask = new Thread(backgroundForm.BackgroundShowDialog);
backgroundForm.Name = "Background form"; backgroundForm.Name = "Background form";
backgroundTask.IsBackground = true; backgroundTask.IsBackground = true;
backgroundTask.SetApartmentState(ApartmentState.STA); backgroundTask.SetApartmentState(ApartmentState.STA);
@ -58,7 +58,7 @@ public BackgroundForm(string title, string text)
// //
InitializeComponent(); InitializeComponent();
Icon = GreenshotResources.getGreenshotIcon(); Icon = GreenshotResources.getGreenshotIcon();
shouldClose = false; _shouldClose = false;
Text = title; Text = title;
label_pleasewait.Text = text; label_pleasewait.Text = text;
FormClosing += PreventFormClose; FormClosing += PreventFormClose;
@ -87,7 +87,7 @@ public new void Show()
private void PreventFormClose(object sender, FormClosingEventArgs e) private void PreventFormClose(object sender, FormClosingEventArgs e)
{ {
if (!shouldClose) if (!_shouldClose)
{ {
e.Cancel = true; e.Cancel = true;
} }
@ -95,7 +95,7 @@ private void PreventFormClose(object sender, FormClosingEventArgs e)
private void Timer_checkforcloseTick(object sender, EventArgs e) private void Timer_checkforcloseTick(object sender, EventArgs e)
{ {
if (shouldClose) if (_shouldClose)
{ {
timer_checkforclose.Stop(); timer_checkforclose.Stop();
BeginInvoke(new EventHandler(delegate { Close(); })); BeginInvoke(new EventHandler(delegate { Close(); }));
@ -104,7 +104,7 @@ private void Timer_checkforcloseTick(object sender, EventArgs e)
public void CloseDialog() public void CloseDialog()
{ {
shouldClose = true; _shouldClose = true;
Application.DoEvents(); Application.DoEvents();
} }

View file

@ -40,7 +40,7 @@ public string LanguageKey
set; set;
} }
public BindableToolStripButton() : base() public BindableToolStripButton()
{ {
CheckedChanged += BindableToolStripButton_CheckedChanged; CheckedChanged += BindableToolStripButton_CheckedChanged;
} }

View file

@ -40,7 +40,7 @@ public string LanguageKey
set; set;
} }
public BindableToolStripComboBox() : base() public BindableToolStripComboBox()
{ {
SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged; SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged;
} }

View file

@ -41,10 +41,6 @@ public string LanguageKey
set; set;
} }
public BindableToolStripDropDownButton()
{
}
public object SelectedTag public object SelectedTag
{ {
get { if (Tag == null && DropDownItems.Count > 0) Tag = DropDownItems[0].Tag; return Tag; } get { if (Tag == null && DropDownItems.Count > 0) Tag = DropDownItems[0].Tag; return Tag; }

View file

@ -51,11 +51,14 @@ public FontFamily FontFamily
public FontFamilyComboBox() : base() public FontFamilyComboBox() : base()
{ {
ComboBox.DataSource = FontFamily.Families; if (ComboBox != null)
ComboBox.DisplayMember = "Name"; {
SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged; ComboBox.DataSource = FontFamily.Families;
ComboBox.DrawMode = DrawMode.OwnerDrawFixed; ComboBox.DisplayMember = "Name";
ComboBox.DrawItem += ComboBox_DrawItem; SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged;
ComboBox.DrawMode = DrawMode.OwnerDrawFixed;
ComboBox.DrawItem += ComboBox_DrawItem;
}
} }
private void ComboBox_DrawItem(object sender, DrawItemEventArgs e) private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
@ -69,7 +72,7 @@ private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
{ {
FontFamily fontFamily = Items[e.Index] as FontFamily; FontFamily fontFamily = Items[e.Index] as FontFamily;
FontStyle fontStyle = FontStyle.Regular; FontStyle fontStyle = FontStyle.Regular;
if (!fontFamily.IsStyleAvailable(FontStyle.Regular)) if (fontFamily != null && !fontFamily.IsStyleAvailable(FontStyle.Regular))
{ {
if (fontFamily.IsStyleAvailable(FontStyle.Bold)) if (fontFamily.IsStyleAvailable(FontStyle.Bold))
{ {
@ -90,12 +93,18 @@ private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
} }
try try
{ {
DrawText(e.Graphics, fontFamily, fontStyle, e.Bounds, fontFamily.Name); if (fontFamily != null)
{
DrawText(e.Graphics, fontFamily, fontStyle, e.Bounds, fontFamily.Name);
}
} }
catch catch
{ {
// If the drawing failed, BUG-1770 seems to have a weird case that causes: Font 'Lucida Sans Typewriter' does not support style 'Regular' if (fontFamily != null)
DrawText(e.Graphics, FontFamily.GenericSansSerif, FontStyle.Regular, e.Bounds, fontFamily.Name); {
// If the drawing failed, BUG-1770 seems to have a weird case that causes: Font 'Lucida Sans Typewriter' does not support style 'Regular'
DrawText(e.Graphics, FontFamily.GenericSansSerif, FontStyle.Regular, e.Bounds, fontFamily.Name);
}
} }
} }
// Uncomment this if you actually like the way the focus rectangle looks // Uncomment this if you actually like the way the focus rectangle looks
@ -112,7 +121,7 @@ private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
/// <param name="text"></param> /// <param name="text"></param>
private void DrawText(Graphics graphics, FontFamily fontFamily, FontStyle fontStyle, Rectangle bounds, string text) private void DrawText(Graphics graphics, FontFamily fontFamily, FontStyle fontStyle, Rectangle bounds, string text)
{ {
using (Font font = new Font(fontFamily, this.Font.Size + 5, fontStyle, GraphicsUnit.Pixel)) using (Font font = new Font(fontFamily, Font.Size + 5, fontStyle, GraphicsUnit.Pixel))
{ {
// Make sure the text is visible by centering it in the line // Make sure the text is visible by centering it in the line
using (StringFormat stringFormat = new StringFormat()) using (StringFormat stringFormat = new StringFormat())

View file

@ -36,19 +36,8 @@ public string LanguageKey
set; set;
} }
private string sectionName = "Core";
[Category("Greenshot"), DefaultValue("Core"), Description("Specifies the Ini-Section to map this control with.")] [Category("Greenshot"), DefaultValue("Core"), Description("Specifies the Ini-Section to map this control with.")]
public string SectionName public string SectionName { get; set; } = "Core";
{
get
{
return sectionName;
}
set
{
sectionName = value;
}
}
[Category("Greenshot"), DefaultValue(null), Description("Specifies the property name to map the configuration.")] [Category("Greenshot"), DefaultValue(null), Description("Specifies the property name to map the configuration.")]
public string PropertyName public string PropertyName

View file

@ -32,15 +32,15 @@ internal class GreenshotColumnSorter : IComparer
/// <summary> /// <summary>
/// Specifies the column to be sorted /// Specifies the column to be sorted
/// </summary> /// </summary>
private int ColumnToSort; private int _columnToSort;
/// <summary> /// <summary>
/// Specifies the order in which to sort (i.e. 'Ascending'). /// Specifies the order in which to sort (i.e. 'Ascending').
/// </summary> /// </summary>
private SortOrder OrderOfSort; private SortOrder _orderOfSort;
/// <summary> /// <summary>
/// Case insensitive comparer object /// Case insensitive comparer object
/// </summary> /// </summary>
private CaseInsensitiveComparer ObjectCompare; private readonly CaseInsensitiveComparer _objectCompare;
/// <summary> /// <summary>
/// Class constructor. Initializes various elements /// Class constructor. Initializes various elements
@ -48,13 +48,13 @@ internal class GreenshotColumnSorter : IComparer
public GreenshotColumnSorter() public GreenshotColumnSorter()
{ {
// Initialize the column to '0' // Initialize the column to '0'
ColumnToSort = 0; _columnToSort = 0;
// Initialize the sort order to 'none' // Initialize the sort order to 'none'
OrderOfSort = SortOrder.None; _orderOfSort = SortOrder.None;
// Initialize the CaseInsensitiveComparer object // Initialize the CaseInsensitiveComparer object
ObjectCompare = new CaseInsensitiveComparer(); _objectCompare = new CaseInsensitiveComparer();
} }
/// <summary> /// <summary>
@ -65,44 +65,39 @@ public GreenshotColumnSorter()
/// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns> /// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
public int Compare(object x, object y) public int Compare(object x, object y)
{ {
int compareResult;
ListViewItem listviewX, listviewY;
if (x == null && y == null) if (x == null && y == null)
{ {
return 0; return 0;
} }
else if (x == null && y != null) if (x == null)
{ {
return -1; return -1;
} }
else if (x != null && y == null) if (y == null)
{ {
return 1; return 1;
} }
// Cast the objects to be compared to ListViewItem objects // Cast the objects to be compared to ListViewItem objects
listviewX = (ListViewItem)x; var listviewX = (ListViewItem)x;
listviewY = (ListViewItem)y; var listviewY = (ListViewItem)y;
// Compare the two items // Compare the two items
compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text); var compareResult = _objectCompare.Compare(listviewX.SubItems[_columnToSort].Text, listviewY.SubItems[_columnToSort].Text);
// Calculate correct return value based on object comparison // Calculate correct return value based on object comparison
if (OrderOfSort == SortOrder.Ascending) if (_orderOfSort == SortOrder.Ascending)
{ {
// Ascending sort is selected, return normal result of compare operation // Ascending sort is selected, return normal result of compare operation
return compareResult; return compareResult;
} }
else if (OrderOfSort == SortOrder.Descending) if (_orderOfSort == SortOrder.Descending)
{ {
// Descending sort is selected, return negative result of compare operation // Descending sort is selected, return negative result of compare operation
return (-compareResult); return (-compareResult);
} }
else
{ // Return '0' to indicate they are equal
// Return '0' to indicate they are equal return 0;
return 0;
}
} }
/// <summary> /// <summary>
@ -112,11 +107,11 @@ public int SortColumn
{ {
set set
{ {
ColumnToSort = value; _columnToSort = value;
} }
get get
{ {
return ColumnToSort; return _columnToSort;
} }
} }
@ -127,11 +122,11 @@ public SortOrder Order
{ {
set set
{ {
OrderOfSort = value; _orderOfSort = value;
} }
get get
{ {
return OrderOfSort; return _orderOfSort;
} }
} }
} }

View file

@ -27,21 +27,11 @@ namespace GreenshotPlugin.Controls
{ {
internal class GreenshotComboBox : ComboBox, IGreenshotConfigBindable internal class GreenshotComboBox : ComboBox, IGreenshotConfigBindable
{ {
private Type enumType = null; private Type _enumType = null;
private Enum selectedEnum = null; private Enum _selectedEnum = null;
private string sectionName = "Core";
[Category("Greenshot"), DefaultValue("Core"), Description("Specifies the Ini-Section to map this control with.")] [Category("Greenshot"), DefaultValue("Core"), Description("Specifies the Ini-Section to map this control with.")]
public string SectionName public string SectionName { get; set; } = "Core";
{
get
{
return sectionName;
}
set
{
sectionName = value;
}
}
[Category("Greenshot"), DefaultValue(null), Description("Specifies the property name to map the configuration.")] [Category("Greenshot"), DefaultValue(null), Description("Specifies the property name to map the configuration.")]
public string PropertyName public string PropertyName
@ -62,7 +52,7 @@ public void SetValue(Enum currentValue)
{ {
if (currentValue != null) if (currentValue != null)
{ {
selectedEnum = currentValue; _selectedEnum = currentValue;
SelectedItem = currentValue; SelectedItem = currentValue;
} }
} }
@ -75,11 +65,10 @@ public void SetValue(Enum currentValue)
public void Populate(Type enumType) public void Populate(Type enumType)
{ {
// Store the enum-type, so we can work with it // Store the enum-type, so we can work with it
this.enumType = enumType; _enumType = enumType;
var availableValues = Enum.GetValues(enumType); var availableValues = Enum.GetValues(enumType);
Items.Clear(); Items.Clear();
string enumTypeName = enumType.Name;
foreach (var enumValue in availableValues) foreach (var enumValue in availableValues)
{ {
Items.Add(enumValue); Items.Add(enumValue);
@ -91,20 +80,20 @@ public void Populate(Type enumType)
/// </summary> /// </summary>
private void StoreSelectedEnum() private void StoreSelectedEnum()
{ {
string enumTypeName = enumType.Name; string enumTypeName = _enumType.Name;
string selectedValue = SelectedItem as string; string selectedValue = SelectedItem as string;
var availableValues = Enum.GetValues(enumType); var availableValues = Enum.GetValues(_enumType);
object returnValue = null; object returnValue = null;
try try
{ {
returnValue = Enum.Parse(enumType, selectedValue); returnValue = Enum.Parse(_enumType, selectedValue);
} }
catch (Exception) catch (Exception)
{ {
} }
selectedEnum = (Enum)returnValue; _selectedEnum = (Enum)returnValue;
} }
/// <summary> /// <summary>
@ -113,7 +102,7 @@ private void StoreSelectedEnum()
/// <returns>The enum value of the combobox</returns> /// <returns>The enum value of the combobox</returns>
public Enum GetSelectedEnum() public Enum GetSelectedEnum()
{ {
return selectedEnum; return _selectedEnum;
} }
} }
} }

View file

@ -36,9 +36,9 @@ namespace GreenshotPlugin.Controls
public class GreenshotForm : Form, IGreenshotLanguageBindable public class GreenshotForm : Form, IGreenshotLanguageBindable
{ {
protected static CoreConfiguration coreConfiguration; protected static CoreConfiguration coreConfiguration;
private static IDictionary<Type, FieldInfo[]> reflectionCache = new Dictionary<Type, FieldInfo[]>(); private static readonly IDictionary<Type, FieldInfo[]> reflectionCache = new Dictionary<Type, FieldInfo[]>();
private IComponentChangeService m_changeService; private IComponentChangeService m_changeService;
private bool _storeFieldsManually = false; private bool _storeFieldsManually;
private IDictionary<string, Control> _designTimeControls; private IDictionary<string, Control> _designTimeControls;
private IDictionary<string, ToolStripItem> _designTimeToolStripItems; private IDictionary<string, ToolStripItem> _designTimeToolStripItems;
@ -184,7 +184,7 @@ private void ClearChangeNotifications()
// Clear our the component change events to prepare for re-siting. // Clear our the component change events to prepare for re-siting.
if (m_changeService != null) if (m_changeService != null)
{ {
m_changeService.ComponentAdded -= new ComponentEventHandler(OnComponentAdded); m_changeService.ComponentAdded -= OnComponentAdded;
} }
} }
@ -193,7 +193,7 @@ private void RegisterChangeNotifications()
// Register the event handlers for the IComponentChangeService events // Register the event handlers for the IComponentChangeService events
if (m_changeService != null) if (m_changeService != null)
{ {
m_changeService.ComponentAdded += new ComponentEventHandler(OnComponentAdded); m_changeService.ComponentAdded += OnComponentAdded;
} }
} }
@ -303,7 +303,6 @@ protected void FillFields()
comboxBox.Populate(iniValue.ValueType); comboxBox.Populate(iniValue.ValueType);
comboxBox.SetValue((Enum)iniValue.Value); comboxBox.SetValue((Enum)iniValue.Value);
comboxBox.Enabled = !iniValue.IsFixed; comboxBox.Enabled = !iniValue.IsFixed;
continue;
} }
} }
} }

View file

@ -26,19 +26,8 @@ namespace GreenshotPlugin.Controls
{ {
internal class GreenshotTextBox : TextBox, IGreenshotConfigBindable internal class GreenshotTextBox : TextBox, IGreenshotConfigBindable
{ {
private string sectionName = "Core";
[Category("Greenshot"), DefaultValue("Core"), Description("Specifies the Ini-Section to map this control with.")] [Category("Greenshot"), DefaultValue("Core"), Description("Specifies the Ini-Section to map this control with.")]
public string SectionName public string SectionName { get; set; } = "Core";
{
get
{
return sectionName;
}
set
{
sectionName = value;
}
}
[Category("Greenshot"), DefaultValue(null), Description("Specifies the property name to map the configuration.")] [Category("Greenshot"), DefaultValue(null), Description("Specifies the property name to map the configuration.")]
public string PropertyName public string PropertyName

View file

@ -36,11 +36,9 @@ private enum NativeConstants : uint
{ {
MA_ACTIVATE = 1, MA_ACTIVATE = 1,
MA_ACTIVATEANDEAT = 2, MA_ACTIVATEANDEAT = 2,
MA_NOACTIVATE = 3,
MA_NOACTIVATEANDEAT = 4,
} }
private bool clickThrough = false; private bool _clickThrough;
/// <summary> /// <summary>
/// Gets or sets whether the ToolStripEx honors item clicks when its containing form does not have input focus. /// Gets or sets whether the ToolStripEx honors item clicks when its containing form does not have input focus.
/// </summary> /// </summary>
@ -51,19 +49,19 @@ public bool ClickThrough
{ {
get get
{ {
return clickThrough; return _clickThrough;
} }
set set
{ {
clickThrough = value; _clickThrough = value;
} }
} }
protected override void WndProc(ref Message m) protected override void WndProc(ref Message m)
{ {
base.WndProc(ref m); base.WndProc(ref m);
if (clickThrough && m.Msg == WM_MOUSEACTIVATE && m.Result == (IntPtr)NativeConstants.MA_ACTIVATEANDEAT) if (_clickThrough && m.Msg == WM_MOUSEACTIVATE && m.Result == (IntPtr)NativeConstants.MA_ACTIVATEANDEAT)
{ {
m.Result = (IntPtr)NativeConstants.MA_ACTIVATE; m.Result = (IntPtr)NativeConstants.MA_ACTIVATE;
} }

View file

@ -19,15 +19,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/// <summary>
/// See: http://nickstips.wordpress.com/2010/03/03/c-panel-resets-scroll-position-after-focus-is-lost-and-regained/
/// </summary>
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace GreenshotPlugin.Controls namespace GreenshotPlugin.Controls
{ {
/// <summary>
/// See: http://nickstips.wordpress.com/2010/03/03/c-panel-resets-scroll-position-after-focus-is-lost-and-regained/
/// </summary>
internal class NonJumpingPanel : Panel internal class NonJumpingPanel : Panel
{ {
protected override Point ScrollToControl(Control activeControl) protected override Point ScrollToControl(Control activeControl)
@ -36,5 +35,23 @@ protected override Point ScrollToControl(Control activeControl)
// scrolling to the active control when the panel loses and regains focus // scrolling to the active control when the panel loses and regains focus
return DisplayRectangle.Location; return DisplayRectangle.Location;
} }
/// <summary>
/// Add horizontal scrolling to the panel, when using the wheel and the shift key is pressed
/// </summary>
/// <param name="e">MouseEventArgs</param>
protected override void OnMouseWheel(MouseEventArgs e)
{
if (VScroll && (ModifierKeys & Keys.Shift) == Keys.Shift)
{
VScroll = false;
base.OnMouseWheel(e);
VScroll = true;
}
else
{
base.OnMouseWheel(e);
}
}
} }
} }

View file

@ -37,7 +37,7 @@ internal class Pipette : Label, IMessageFilter, IDisposable
private MovableShowColorForm movableShowColorForm; private MovableShowColorForm movableShowColorForm;
private bool dragging; private bool dragging;
private Cursor _cursor; private Cursor _cursor;
private Bitmap _image; private readonly Bitmap _image;
private const int VK_ESC = 27; private const int VK_ESC = 27;
public event EventHandler<PipetteUsedArgs> PipetteUsed; public event EventHandler<PipetteUsedArgs> PipetteUsed;
@ -129,7 +129,10 @@ protected override void OnMouseUp(MouseEventArgs e)
{ {
//Release Capture should consume MouseUp when canceled with the escape key //Release Capture should consume MouseUp when canceled with the escape key
User32.ReleaseCapture(); User32.ReleaseCapture();
PipetteUsed(this, new PipetteUsedArgs(movableShowColorForm.color)); if (PipetteUsed != null)
{
PipetteUsed(this, new PipetteUsedArgs(movableShowColorForm.color));
}
} }
base.OnMouseUp(e); base.OnMouseUp(e);
} }

View file

@ -31,7 +31,7 @@ namespace GreenshotPlugin.Controls
/// </summary> /// </summary>
internal partial class PleaseWaitForm : Form internal partial class PleaseWaitForm : Form
{ {
private Thread waitFor = null; private Thread waitFor;
private string title; private string title;
public PleaseWaitForm() public PleaseWaitForm()

View file

@ -31,7 +31,7 @@ namespace GreenshotPlugin.Controls
/// </summary> /// </summary>
internal partial class QualityDialog : GreenshotForm internal partial class QualityDialog : GreenshotForm
{ {
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public SurfaceOutputSettings Settings public SurfaceOutputSettings Settings
{ {
get; get;

View file

@ -34,11 +34,11 @@ namespace GreenshotPlugin.Controls
/// </summary> /// </summary>
internal class SaveImageFileDialog : IDisposable internal class SaveImageFileDialog : IDisposable
{ {
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
protected SaveFileDialog saveFileDialog; protected SaveFileDialog SaveFileDialog;
private FilterOption[] filterOptions; private FilterOption[] _filterOptions;
private DirectoryInfo eagerlyCreatedDirectory; private DirectoryInfo _eagerlyCreatedDirectory;
private ICaptureDetails captureDetails = null; private readonly ICaptureDetails _captureDetails = null;
public void Dispose() public void Dispose()
{ {
@ -50,29 +50,29 @@ protected virtual void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {
if (saveFileDialog != null) if (SaveFileDialog != null)
{ {
saveFileDialog.Dispose(); SaveFileDialog.Dispose();
saveFileDialog = null; SaveFileDialog = null;
} }
} }
} }
public SaveImageFileDialog() public SaveImageFileDialog()
{ {
init(); Init();
} }
public SaveImageFileDialog(ICaptureDetails captureDetails) public SaveImageFileDialog(ICaptureDetails captureDetails)
{ {
this.captureDetails = captureDetails; _captureDetails = captureDetails;
init(); Init();
} }
private void init() private void Init()
{ {
saveFileDialog = new SaveFileDialog(); SaveFileDialog = new SaveFileDialog();
applyFilterOptions(); ApplyFilterOptions();
string initialDirectory = null; string initialDirectory = null;
try try
{ {
@ -85,50 +85,52 @@ private void init()
if (!string.IsNullOrEmpty(initialDirectory) && Directory.Exists(initialDirectory)) if (!string.IsNullOrEmpty(initialDirectory) && Directory.Exists(initialDirectory))
{ {
saveFileDialog.InitialDirectory = initialDirectory; SaveFileDialog.InitialDirectory = initialDirectory;
} }
else if (Directory.Exists(conf.OutputFilePath)) else if (Directory.Exists(conf.OutputFilePath))
{ {
saveFileDialog.InitialDirectory = conf.OutputFilePath; SaveFileDialog.InitialDirectory = conf.OutputFilePath;
} }
// The following property fixes a problem that the directory where we save is locked (bug #2899790) // The following property fixes a problem that the directory where we save is locked (bug #2899790)
saveFileDialog.RestoreDirectory = true; SaveFileDialog.RestoreDirectory = true;
saveFileDialog.OverwritePrompt = true; SaveFileDialog.OverwritePrompt = true;
saveFileDialog.CheckPathExists = false; SaveFileDialog.CheckPathExists = false;
saveFileDialog.AddExtension = true; SaveFileDialog.AddExtension = true;
ApplySuggestedValues(); ApplySuggestedValues();
} }
private void applyFilterOptions() private void ApplyFilterOptions()
{ {
prepareFilterOptions(); PrepareFilterOptions();
string fdf = ""; string fdf = "";
int preselect = 0; int preselect = 0;
var outputFileFormatAsString = Enum.GetName(typeof(OutputFormat), conf.OutputFileFormat); var outputFileFormatAsString = Enum.GetName(typeof(OutputFormat), conf.OutputFileFormat);
for (int i = 0; i < filterOptions.Length; i++) for (int i = 0; i < _filterOptions.Length; i++)
{ {
FilterOption fo = filterOptions[i]; FilterOption fo = _filterOptions[i];
fdf += fo.Label + "|*." + fo.Extension + "|"; fdf += fo.Label + "|*." + fo.Extension + "|";
if (outputFileFormatAsString == fo.Extension) if (outputFileFormatAsString == fo.Extension)
preselect = i; preselect = i;
} }
fdf = fdf.Substring(0, fdf.Length - 1); fdf = fdf.Substring(0, fdf.Length - 1);
saveFileDialog.Filter = fdf; SaveFileDialog.Filter = fdf;
saveFileDialog.FilterIndex = preselect + 1; SaveFileDialog.FilterIndex = preselect + 1;
} }
private void prepareFilterOptions() private void PrepareFilterOptions()
{ {
OutputFormat[] supportedImageFormats = (OutputFormat[])Enum.GetValues(typeof(OutputFormat)); OutputFormat[] supportedImageFormats = (OutputFormat[])Enum.GetValues(typeof(OutputFormat));
filterOptions = new FilterOption[supportedImageFormats.Length]; _filterOptions = new FilterOption[supportedImageFormats.Length];
for (int i = 0; i < filterOptions.Length; i++) for (int i = 0; i < _filterOptions.Length; i++)
{ {
string ifo = supportedImageFormats[i].ToString(); string ifo = supportedImageFormats[i].ToString();
if (ifo.ToLower().Equals("jpeg")) ifo = "Jpg"; // we dont want no jpeg files, so let the dialog check for jpg if (ifo.ToLower().Equals("jpeg")) ifo = "Jpg"; // we dont want no jpeg files, so let the dialog check for jpg
FilterOption fo = new FilterOption(); FilterOption fo = new FilterOption
fo.Label = ifo.ToUpper(); {
fo.Extension = ifo.ToLower(); Label = ifo.ToUpper(),
filterOptions.SetValue(fo, i); Extension = ifo.ToLower()
};
_filterOptions.SetValue(fo, i);
} }
} }
@ -137,8 +139,8 @@ private void prepareFilterOptions()
/// </summary> /// </summary>
public string FileName public string FileName
{ {
get { return saveFileDialog.FileName; } get { return SaveFileDialog.FileName; }
set { saveFileDialog.FileName = value; } set { SaveFileDialog.FileName = value; }
} }
/// <summary> /// <summary>
@ -146,8 +148,8 @@ public string FileName
/// </summary> /// </summary>
public string InitialDirectory public string InitialDirectory
{ {
get { return saveFileDialog.InitialDirectory; } get { return SaveFileDialog.InitialDirectory; }
set { saveFileDialog.InitialDirectory = value; } set { SaveFileDialog.InitialDirectory = value; }
} }
/// <summary> /// <summary>
@ -159,7 +161,7 @@ public string FileNameWithExtension
{ {
get get
{ {
string fn = saveFileDialog.FileName; string fn = SaveFileDialog.FileName;
// if the filename contains a valid extension, which is the same like the selected filter item's extension, the filename is okay // if the filename contains a valid extension, which is the same like the selected filter item's extension, the filename is okay
if (fn.EndsWith(Extension, StringComparison.CurrentCultureIgnoreCase)) return fn; if (fn.EndsWith(Extension, StringComparison.CurrentCultureIgnoreCase)) return fn;
// otherwise we just add the selected filter item's extension // otherwise we just add the selected filter item's extension
@ -179,15 +181,15 @@ public string Extension
{ {
get get
{ {
return filterOptions[saveFileDialog.FilterIndex - 1].Extension; return _filterOptions[SaveFileDialog.FilterIndex - 1].Extension;
} }
set set
{ {
for (int i = 0; i < filterOptions.Length; i++) for (int i = 0; i < _filterOptions.Length; i++)
{ {
if (value.Equals(filterOptions[i].Extension, StringComparison.CurrentCultureIgnoreCase)) if (value.Equals(_filterOptions[i].Extension, StringComparison.CurrentCultureIgnoreCase))
{ {
saveFileDialog.FilterIndex = i + 1; SaveFileDialog.FilterIndex = i + 1;
} }
} }
} }
@ -195,7 +197,7 @@ public string Extension
public DialogResult ShowDialog() public DialogResult ShowDialog()
{ {
DialogResult ret = saveFileDialog.ShowDialog(); DialogResult ret = SaveFileDialog.ShowDialog();
CleanUp(); CleanUp();
return ret; return ret;
} }
@ -203,18 +205,10 @@ public DialogResult ShowDialog()
/// <summary> /// <summary>
/// sets InitialDirectory and FileName property of a SaveFileDialog smartly, considering default pattern and last used path /// sets InitialDirectory and FileName property of a SaveFileDialog smartly, considering default pattern and last used path
/// </summary> /// </summary>
/// <param name="sfd">a SaveFileDialog instance</param>
private void ApplySuggestedValues() private void ApplySuggestedValues()
{ {
// build the full path and set dialog properties // build the full path and set dialog properties
FileName = FilenameHelper.GetFilenameWithoutExtensionFromPattern(conf.OutputFileFilenamePattern, captureDetails); FileName = FilenameHelper.GetFilenameWithoutExtensionFromPattern(conf.OutputFileFilenamePattern, _captureDetails);
}
private string GetRootDirFromConfig()
{
string rootDir = conf.OutputFilePath;
rootDir = FilenameHelper.FillVariables(rootDir, false);
return rootDir;
} }
private class FilterOption private class FilterOption
@ -228,37 +222,18 @@ private void CleanUp()
// fix for bug #3379053 // fix for bug #3379053
try try
{ {
if (eagerlyCreatedDirectory != null && eagerlyCreatedDirectory.GetFiles().Length == 0 && eagerlyCreatedDirectory.GetDirectories().Length == 0) if (_eagerlyCreatedDirectory != null && _eagerlyCreatedDirectory.GetFiles().Length == 0 && _eagerlyCreatedDirectory.GetDirectories().Length == 0)
{ {
eagerlyCreatedDirectory.Delete(); _eagerlyCreatedDirectory.Delete();
eagerlyCreatedDirectory = null; _eagerlyCreatedDirectory = null;
} }
} }
catch (Exception e) catch (Exception e)
{ {
LOG.WarnFormat("Couldn't cleanup directory due to: {0}", e.Message); LOG.WarnFormat("Couldn't cleanup directory due to: {0}", e.Message);
eagerlyCreatedDirectory = null; _eagerlyCreatedDirectory = null;
} }
} }
private string CreateDirectoryIfNotExists(string fullPath)
{
string dirName = null;
try
{
dirName = Path.GetDirectoryName(fullPath);
DirectoryInfo di = new DirectoryInfo(dirName);
if (!di.Exists)
{
di = Directory.CreateDirectory(dirName);
eagerlyCreatedDirectory = di;
}
}
catch (Exception e)
{
LOG.Error("Error in CreateDirectoryIfNotExists", e);
}
return dirName;
}
} }
} }

View file

@ -36,11 +36,9 @@ private enum NativeConstants : uint
{ {
MA_ACTIVATE = 1, MA_ACTIVATE = 1,
MA_ACTIVATEANDEAT = 2, MA_ACTIVATEANDEAT = 2,
MA_NOACTIVATE = 3,
MA_NOACTIVATEANDEAT = 4,
} }
private bool clickThrough = false; private bool _clickThrough = false;
/// <summary> /// <summary>
/// Gets or sets whether the ToolStripEx honors item clicks when its containing form does not have input focus. /// Gets or sets whether the ToolStripEx honors item clicks when its containing form does not have input focus.
/// </summary> /// </summary>
@ -52,19 +50,19 @@ public bool ClickThrough
{ {
get get
{ {
return clickThrough; return _clickThrough;
} }
set set
{ {
clickThrough = value; _clickThrough = value;
} }
} }
protected override void WndProc(ref Message m) protected override void WndProc(ref Message m)
{ {
base.WndProc(ref m); base.WndProc(ref m);
if (clickThrough && m.Msg == WM_MOUSEACTIVATE && m.Result == (IntPtr)NativeConstants.MA_ACTIVATEANDEAT) if (_clickThrough && m.Msg == WM_MOUSEACTIVATE && m.Result == (IntPtr)NativeConstants.MA_ACTIVATEANDEAT)
{ {
m.Result = (IntPtr)NativeConstants.MA_ACTIVATE; m.Result = (IntPtr)NativeConstants.MA_ACTIVATE;
} }

View file

@ -32,10 +32,10 @@ namespace GreenshotPlugin.Core
/// <typeparam name="TV">Type of value</typeparam> /// <typeparam name="TV">Type of value</typeparam>
public class Cache<TK, TV> public class Cache<TK, TV>
{ {
private IDictionary<TK, TV> internalCache = new Dictionary<TK, TV>(); private readonly IDictionary<TK, TV> internalCache = new Dictionary<TK, TV>();
private object lockObject = new object(); private readonly object lockObject = new object();
private int secondsToExpire = 10; private readonly int secondsToExpire = 10;
private CacheObjectExpired expiredCallback = null; private readonly CacheObjectExpired expiredCallback = null;
public delegate void CacheObjectExpired(TK key, TV cacheValue); public delegate void CacheObjectExpired(TK key, TV cacheValue);
/// <summary> /// <summary>
@ -82,9 +82,12 @@ public IEnumerable<TV> Elements
{ {
List<TV> elements = new List<TV>(); List<TV> elements = new List<TV>();
foreach (TV element in internalCache.Values) lock (lockObject)
{ {
elements.Add(element); foreach (TV element in internalCache.Values)
{
elements.Add(element);
}
} }
foreach (TV element in elements) foreach (TV element in elements)
{ {
@ -121,7 +124,10 @@ public IEnumerable<TV> Elements
/// <returns>true if the cache contains the key</returns> /// <returns>true if the cache contains the key</returns>
public bool Contains(TK key) public bool Contains(TK key)
{ {
return internalCache.ContainsKey(key); lock (lockObject)
{
return internalCache.ContainsKey(key);
}
} }
/// <summary> /// <summary>
@ -198,7 +204,7 @@ public void Remove(TK key)
private class CachedItem private class CachedItem
{ {
public event CacheObjectExpired Expired; public event CacheObjectExpired Expired;
private int secondsToExpire; private readonly int secondsToExpire;
private readonly Timer _timerEvent; private readonly Timer _timerEvent;
public CachedItem(TK key, TV item, int secondsToExpire) public CachedItem(TK key, TV item, int secondsToExpire)

View file

@ -396,11 +396,11 @@ private static Image GetImage(IDataObject dataObject)
{ {
// Outlook ?? // Outlook ??
LOG.Info("Most likely the current clipboard contents come from Outlook, as this has a problem with PNG and others we place the DIB format to the front..."); LOG.Info("Most likely the current clipboard contents come from Outlook, as this has a problem with PNG and others we place the DIB format to the front...");
retrieveFormats = new string[] { DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JFIF, DataFormats.Tiff, FORMAT_GIF }; retrieveFormats = new[] { DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JFIF, DataFormats.Tiff, FORMAT_GIF };
} }
else else
{ {
retrieveFormats = new string[] { FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_17, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JFIF, DataFormats.Tiff, DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_GIF }; retrieveFormats = new[] { FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_17, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JFIF, DataFormats.Tiff, DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_GIF };
} }
foreach (string currentFormat in retrieveFormats) foreach (string currentFormat in retrieveFormats)
{ {
@ -867,7 +867,7 @@ public static List<string> GetFormats(IDataObject dataObj)
/// <returns>true if one the format is found</returns> /// <returns>true if one the format is found</returns>
public static bool ContainsFormat(string format) public static bool ContainsFormat(string format)
{ {
return ContainsFormat(GetDataObject(), new string[] { format }); return ContainsFormat(GetDataObject(), new[] { format });
} }
/// <summary> /// <summary>
@ -877,7 +877,7 @@ public static bool ContainsFormat(string format)
/// <returns>true if one the format is found</returns> /// <returns>true if one the format is found</returns>
public static bool ContainsFormat(IDataObject dataObject, string format) public static bool ContainsFormat(IDataObject dataObject, string format)
{ {
return ContainsFormat(dataObject, new string[] { format }); return ContainsFormat(dataObject, new[] { format });
} }
/// <summary> /// <summary>

View file

@ -97,7 +97,7 @@ public virtual Image Apply(Image sourceImage, Matrix matrix)
[TypeConverter(typeof(EffectConverter))] [TypeConverter(typeof(EffectConverter))]
public class TornEdgeEffect : DropShadowEffect public class TornEdgeEffect : DropShadowEffect
{ {
public TornEdgeEffect() : base() public TornEdgeEffect()
{ {
Reset(); Reset();
} }
@ -135,7 +135,7 @@ public override void Reset()
ToothHeight = 12; ToothHeight = 12;
HorizontalToothRange = 20; HorizontalToothRange = 20;
VerticalToothRange = 20; VerticalToothRange = 20;
Edges = new bool[] { true, true, true, true }; Edges = new[] { true, true, true, true };
GenerateShadow = true; GenerateShadow = true;
} }
@ -174,12 +174,12 @@ public void Reset()
/// </summary> /// </summary>
public class MonochromeEffect : IEffect public class MonochromeEffect : IEffect
{ {
private byte threshold; private readonly byte _threshold;
/// <param name="threshold">Threshold for monochrome filter (0 - 255), lower value means less black</param> /// <param name="threshold">Threshold for monochrome filter (0 - 255), lower value means less black</param>
public MonochromeEffect(byte threshold) public MonochromeEffect(byte threshold)
{ {
this.threshold = threshold; _threshold = threshold;
} }
public void Reset() public void Reset()
@ -189,7 +189,7 @@ public void Reset()
public Image Apply(Image sourceImage, Matrix matrix) public Image Apply(Image sourceImage, Matrix matrix)
{ {
return ImageHelper.CreateMonochrome(sourceImage, threshold); return ImageHelper.CreateMonochrome(sourceImage, _threshold);
} }
} }
@ -198,7 +198,7 @@ public Image Apply(Image sourceImage, Matrix matrix)
/// </summary> /// </summary>
public class AdjustEffect : IEffect public class AdjustEffect : IEffect
{ {
public AdjustEffect() : base() public AdjustEffect()
{ {
Reset(); Reset();
} }
@ -237,7 +237,7 @@ public Image Apply(Image sourceImage, Matrix matrix)
/// </summary> /// </summary>
public class ReduceColorsEffect : IEffect public class ReduceColorsEffect : IEffect
{ {
public ReduceColorsEffect() : base() public ReduceColorsEffect()
{ {
Reset(); Reset();
} }
@ -460,9 +460,9 @@ public Image Apply(Image sourceImage, Matrix matrix)
public class EffectConverter : TypeConverter public class EffectConverter : TypeConverter
{ {
// Fix to prevent BUG-1753 // Fix to prevent BUG-1753
private NumberFormatInfo numberFormatInfo = new NumberFormatInfo(); private readonly NumberFormatInfo numberFormatInfo = new NumberFormatInfo();
public EffectConverter() : base() public EffectConverter()
{ {
numberFormatInfo.NumberDecimalSeparator = "."; numberFormatInfo.NumberDecimalSeparator = ".";
numberFormatInfo.NumberGroupSeparator = ","; numberFormatInfo.NumberGroupSeparator = ",";
@ -494,7 +494,7 @@ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinati
return base.CanConvertTo(context, destinationType); return base.CanConvertTo(context, destinationType);
} }
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{ {
// to string // to string
if (destinationType == typeof(string)) if (destinationType == typeof(string))
@ -516,7 +516,7 @@ public override object ConvertTo(ITypeDescriptorContext context, System.Globaliz
} }
} }
// from string // from string
if (value.GetType() == typeof(string)) if (value is string)
{ {
string settings = value as string; string settings = value as string;
if (destinationType == typeof(DropShadowEffect)) if (destinationType == typeof(DropShadowEffect))
@ -536,19 +536,16 @@ public override object ConvertTo(ITypeDescriptorContext context, System.Globaliz
return base.ConvertTo(context, culture, value, destinationType); return base.ConvertTo(context, culture, value, destinationType);
} }
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{ {
if (value != null && value.GetType() == typeof(string)) if (value != null && value is string)
{ {
string settings = value as string; string settings = value as string;
if (settings.Contains("ToothHeight")) if (settings.Contains("ToothHeight"))
{ {
return ConvertTo(context, culture, value, typeof(TornEdgeEffect)); return ConvertTo(context, culture, value, typeof(TornEdgeEffect));
} }
else return ConvertTo(context, culture, value, typeof(DropShadowEffect));
{
return ConvertTo(context, culture, value, typeof(DropShadowEffect));
}
} }
return base.ConvertFrom(context, culture, value); return base.ConvertFrom(context, culture, value);
} }

View file

@ -25,12 +25,12 @@ namespace GreenshotPlugin.Core
{ {
public class EventDelay public class EventDelay
{ {
private long lastCheck = 0; private long lastCheck;
private long waitTime; private readonly long waitTime;
public EventDelay(long ticks) public EventDelay(long ticks)
{ {
this.waitTime = ticks; waitTime = ticks;
} }
public bool Check() public bool Check()

View file

@ -343,7 +343,7 @@ public bool InvertClip
protected BitmapData bmData; protected BitmapData bmData;
protected int stride; /* bytes per pixel row */ protected int stride; /* bytes per pixel row */
protected bool bitsLocked = false; protected bool bitsLocked;
protected byte* pointer; protected byte* pointer;
public static IFastBitmap Create(Bitmap source) public static IFastBitmap Create(Bitmap source)
@ -825,8 +825,8 @@ void IFastBitmapWithOffset.SetColorAt(int x, int y, Color color)
public unsafe class FastChunkyBitmap : FastBitmap public unsafe class FastChunkyBitmap : FastBitmap
{ {
// Used for indexed images // Used for indexed images
private Color[] colorEntries; private readonly Color[] colorEntries;
private Dictionary<Color, byte> colorCache = new Dictionary<Color, byte>(); private readonly Dictionary<Color, byte> colorCache = new Dictionary<Color, byte>();
public FastChunkyBitmap(Bitmap source, Rectangle area) : base(source, area) public FastChunkyBitmap(Bitmap source, Rectangle area) : base(source, area)
{ {

View file

@ -39,10 +39,11 @@ public static class FilenameHelper
// The parameter format is a single alpha followed by the value belonging to the parameter, e.g. : // The parameter format is a single alpha followed by the value belonging to the parameter, e.g. :
// ${capturetime:d"yyyy-MM-dd HH_mm_ss"} // ${capturetime:d"yyyy-MM-dd HH_mm_ss"}
private static readonly Regex VAR_REGEXP = new Regex(@"\${(?<variable>[^:}]+)[:]?(?<parameters>[^}]*)}", RegexOptions.Compiled); private static readonly Regex VAR_REGEXP = new Regex(@"\${(?<variable>[^:}]+)[:]?(?<parameters>[^}]*)}", RegexOptions.Compiled);
private static readonly Regex CMD_VAR_REGEXP = new Regex(@"%(?<variable>[^%]+)%", RegexOptions.Compiled);
private static readonly Regex SPLIT_REGEXP = new Regex(";(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", RegexOptions.Compiled); private static readonly Regex SPLIT_REGEXP = new Regex(";(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", RegexOptions.Compiled);
private const int MAX_TITLE_LENGTH = 80; private const int MAX_TITLE_LENGTH = 80;
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private const string UNSAFE_REPLACEMENT = "_"; private const string UNSAFE_REPLACEMENT = "_";
/// <summary> /// <summary>
@ -79,7 +80,7 @@ public static string MakeFilenameSafe(string filename)
/// <summary> /// <summary>
/// Remove invalid characters from the path /// Remove invalid characters from the path
/// </summary> /// </summary>
/// <param name="fullpath">string with the full path to a file</param> /// <param name="path">string with the full path to a file</param>
/// <returns>string with the full path to a file, without invalid characters</returns> /// <returns>string with the full path to a file, without invalid characters</returns>
public static string MakePathSafe(string path) public static string MakePathSafe(string path)
{ {
@ -180,7 +181,7 @@ private static string MatchVarEvaluatorInternal(Match match, ICaptureDetails cap
{ {
// Padding p<width>[,pad-character] // Padding p<width>[,pad-character]
case "p": case "p":
string[] padParams = parameter.Substring(1).Split(new char[] { ',' }); string[] padParams = parameter.Substring(1).Split(new[] { ',' });
try try
{ {
padWidth = int.Parse(padParams[0]); padWidth = int.Parse(padParams[0]);
@ -196,7 +197,7 @@ private static string MatchVarEvaluatorInternal(Match match, ICaptureDetails cap
// replace // replace
// r<old string>,<new string> // r<old string>,<new string>
case "r": case "r":
string[] replaceParameters = parameter.Substring(1).Split(new char[] { ',' }); string[] replaceParameters = parameter.Substring(1).Split(new[] { ',' });
if (replaceParameters != null && replaceParameters.Length == 2) if (replaceParameters != null && replaceParameters.Length == 2)
{ {
replacements.Add(replaceParameters[0], replaceParameters[1]); replacements.Add(replaceParameters[0], replaceParameters[1]);
@ -219,7 +220,7 @@ private static string MatchVarEvaluatorInternal(Match match, ICaptureDetails cap
// s<start>[,length] // s<start>[,length]
case "s": case "s":
string range = parameter.Substring(1); string range = parameter.Substring(1);
string[] rangelist = range.Split(new char[] { ',' }); string[] rangelist = range.Split(new[] { ',' });
if (rangelist.Length > 0) if (rangelist.Length > 0)
{ {
try try
@ -469,6 +470,51 @@ private static string MatchVarEvaluatorInternal(Match match, ICaptureDetails cap
return replaceValue; return replaceValue;
} }
/// <summary>
/// "Simply" fill the pattern with environment variables
/// </summary>
/// <param name="pattern">String with pattern %var%</param>
/// <param name="filenameSafeMode">true to make sure everything is filenamesafe</param>
/// <returns>Filled string</returns>
public static string FillCmdVariables(string pattern, bool filenameSafeMode)
{
IDictionary processVars = null;
IDictionary userVars = null;
IDictionary machineVars = null;
try
{
processVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process);
}
catch (Exception e)
{
LOG.Error("Error retrieving EnvironmentVariableTarget.Process", e);
}
try
{
userVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User);
}
catch (Exception e)
{
LOG.Error("Error retrieving EnvironmentVariableTarget.User", e);
}
try
{
machineVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine);
}
catch (Exception e)
{
LOG.Error("Error retrieving EnvironmentVariableTarget.Machine", e);
}
return CMD_VAR_REGEXP.Replace(pattern,
delegate (Match m) {
return MatchVarEvaluator(m, null, processVars, userVars, machineVars, filenameSafeMode);
}
);
}
/// <summary> /// <summary>
/// "Simply" fill the pattern with environment variables /// "Simply" fill the pattern with environment variables
/// </summary> /// </summary>
@ -508,10 +554,10 @@ public static string FillVariables(string pattern, bool filenameSafeMode)
} }
return VAR_REGEXP.Replace(pattern, return VAR_REGEXP.Replace(pattern,
new MatchEvaluator(delegate (Match m) delegate (Match m)
{ {
return MatchVarEvaluator(m, null, processVars, userVars, machineVars, filenameSafeMode); return MatchVarEvaluator(m, null, processVars, userVars, machineVars, filenameSafeMode);
}) }
); );
} }
@ -557,10 +603,10 @@ public static string FillPattern(string pattern, ICaptureDetails captureDetails,
try try
{ {
return VAR_REGEXP.Replace(pattern, return VAR_REGEXP.Replace(pattern,
new MatchEvaluator(delegate (Match m) delegate (Match m)
{ {
return MatchVarEvaluator(m, captureDetails, processVars, userVars, machineVars, filenameSafeMode); return MatchVarEvaluator(m, captureDetails, processVars, userVars, machineVars, filenameSafeMode);
}) }
); );
} }
catch (Exception e) catch (Exception e)

View file

@ -29,7 +29,7 @@ namespace GreenshotPlugin.Core
/// </summary> /// </summary>
public static class GreenshotResources public static class GreenshotResources
{ {
private static ComponentResourceManager greenshotResources = new ComponentResourceManager(typeof(GreenshotResources)); private static readonly ComponentResourceManager greenshotResources = new ComponentResourceManager(typeof(GreenshotResources));
public static Image getImage(string imageName) public static Image getImage(string imageName)
{ {

View file

@ -972,7 +972,7 @@ public static Bitmap CreateShadow(Image sourceBitmap, float darkness, int shadow
{ {
shadowSize++; shadowSize++;
} }
bool useGDIBlur = GDIplus.isBlurPossible(shadowSize); bool useGDIBlur = GDIplus.IsBlurPossible(shadowSize);
// Create "mask" for the shadow // Create "mask" for the shadow
ColorMatrix maskMatrix = new ColorMatrix(); ColorMatrix maskMatrix = new ColorMatrix();
maskMatrix.Matrix00 = 0; maskMatrix.Matrix00 = 0;
@ -1195,12 +1195,12 @@ public static ImageAttributes CreateAdjustAttributes(float brightness, float con
{ {
float adjustedBrightness = brightness - 1.0f; float adjustedBrightness = brightness - 1.0f;
ColorMatrix applyColorMatrix = new ColorMatrix( ColorMatrix applyColorMatrix = new ColorMatrix(
new float[][] { new [] {
new float[] {contrast, 0, 0, 0, 0}, // scale red new[] {contrast, 0, 0, 0, 0}, // scale red
new float[] {0, contrast, 0, 0, 0}, // scale green new[] {0, contrast, 0, 0, 0}, // scale green
new float[] {0, 0, contrast, 0, 0}, // scale blue new[] {0, 0, contrast, 0, 0}, // scale blue
new float[] {0, 0, 0, 1.0f, 0}, // don't scale alpha new[] {0, 0, 0, 1.0f, 0}, // don't scale alpha
new float[] {adjustedBrightness, adjustedBrightness, adjustedBrightness, 0, 1} new[] {adjustedBrightness, adjustedBrightness, adjustedBrightness, 0, 1}
}); });
//create some image attributes //create some image attributes
@ -1240,10 +1240,10 @@ public static Image Adjust(Image sourceImage, float brightness, float contrast,
public static Image CreateGrayscale(Image sourceImage) public static Image CreateGrayscale(Image sourceImage)
{ {
Bitmap clone = (Bitmap)Clone(sourceImage); Bitmap clone = (Bitmap)Clone(sourceImage);
ColorMatrix grayscaleMatrix = new ColorMatrix(new float[][] { ColorMatrix grayscaleMatrix = new ColorMatrix(new[] {
new float[] {.3f, .3f, .3f, 0, 0}, new[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0}, new[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0}, new[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0}, new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1} new float[] {0, 0, 0, 0, 1}
}); });

View file

@ -44,7 +44,7 @@ public static class ImageOutput
{ {
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly int PROPERTY_TAG_SOFTWARE_USED = 0x0131; private static readonly int PROPERTY_TAG_SOFTWARE_USED = 0x0131;
private static Cache<string, string> tmpFileCache = new Cache<string, string>(10 * 60 * 60, RemoveExpiredTmpFile); private static readonly Cache<string, string> tmpFileCache = new Cache<string, string>(10 * 60 * 60, RemoveExpiredTmpFile);
/// <summary> /// <summary>
/// Creates a PropertyItem (Metadata) to store with the image. /// Creates a PropertyItem (Metadata) to store with the image.

View file

@ -54,12 +54,17 @@ public static class NetworkHelper
static NetworkHelper() static NetworkHelper()
{ {
// Disable certificate checking try
ServicePointManager.ServerCertificateValidationCallback +=
delegate
{ {
return true; // Disable certificate checking
}; ServicePointManager.ServerCertificateValidationCallback += delegate {
return true;
};
}
catch (Exception ex)
{
LOG.Warn("An error has occured while allowing self-signed certificates:", ex);
}
} }
/// <summary> /// <summary>
@ -157,15 +162,18 @@ public static Image DownloadImage(string url)
{ {
content = streamReader.ReadLine(); content = streamReader.ReadLine();
} }
Regex imageUrlRegex = new Regex(@"(http|https)://.*(\.png|\.gif|\.jpg|\.tiff|\.jpeg|\.bmp)"); if (!string.IsNullOrEmpty(content))
Match match = imageUrlRegex.Match(content);
if (match.Success)
{ {
using (MemoryStream memoryStream2 = GetAsMemoryStream(match.Value)) Regex imageUrlRegex = new Regex(@"(http|https)://.*(\.png|\.gif|\.jpg|\.tiff|\.jpeg|\.bmp)");
Match match = imageUrlRegex.Match(content);
if (match.Success)
{ {
using (Image image = Image.FromStream(memoryStream2)) using (MemoryStream memoryStream2 = GetAsMemoryStream(match.Value))
{ {
return ImageHelper.Clone(image, PixelFormat.Format32bppArgb); using (Image image = Image.FromStream(memoryStream2))
{
return ImageHelper.Clone(image, PixelFormat.Format32bppArgb);
}
} }
} }
} }
@ -222,15 +230,7 @@ public static HttpWebRequest CreateWebRequest(Uri uri, HTTPMethod method)
public static HttpWebRequest CreateWebRequest(Uri uri) public static HttpWebRequest CreateWebRequest(Uri uri)
{ {
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
if (Config.UseProxy) webRequest.Proxy = Config.UseProxy ? CreateProxy(uri) : null;
{
webRequest.Proxy = CreateProxy(uri);
}
else
{
// BUG-1655: Fix that Greenshot always uses the default proxy even if the "use default proxy" checkbox is unset
webRequest.Proxy = null;
}
// Make sure the default credentials are available // Make sure the default credentials are available
webRequest.Credentials = CredentialCache.DefaultCredentials; webRequest.Credentials = CredentialCache.DefaultCredentials;
@ -463,10 +463,11 @@ public static void WriteMultipartFormData(Stream formDataStream, string boundary
/// Post the parameters "x-www-form-urlencoded" /// Post the parameters "x-www-form-urlencoded"
/// </summary> /// </summary>
/// <param name="webRequest"></param> /// <param name="webRequest"></param>
/// <param name="parameters"></param>
public static void UploadFormUrlEncoded(HttpWebRequest webRequest, IDictionary<string, object> parameters) public static void UploadFormUrlEncoded(HttpWebRequest webRequest, IDictionary<string, object> parameters)
{ {
webRequest.ContentType = "application/x-www-form-urlencoded"; webRequest.ContentType = "application/x-www-form-urlencoded";
string urlEncoded = NetworkHelper.GenerateQueryParameters(parameters); string urlEncoded = GenerateQueryParameters(parameters);
byte[] data = Encoding.UTF8.GetBytes(urlEncoded); byte[] data = Encoding.UTF8.GetBytes(urlEncoded);
using (var requestStream = webRequest.GetRequestStream()) using (var requestStream = webRequest.GetRequestStream())
@ -533,6 +534,7 @@ private static string GetResponseAsString(HttpWebResponse response)
/// ///
/// </summary> /// </summary>
/// <param name="webRequest"></param> /// <param name="webRequest"></param>
/// <param name="alsoReturnContentOnError"></param>
/// <returns></returns> /// <returns></returns>
public static string GetResponseAsString(HttpWebRequest webRequest, bool alsoReturnContentOnError) public static string GetResponseAsString(HttpWebRequest webRequest, bool alsoReturnContentOnError)
{ {
@ -639,10 +641,10 @@ public interface IBinaryContainer
/// </summary> /// </summary>
public class ByteContainer : IBinaryContainer public class ByteContainer : IBinaryContainer
{ {
private byte[] file; private readonly byte[] _file;
private string fileName; private readonly string _fileName;
private string contentType; private readonly string _contentType;
private int fileSize; private readonly int _fileSize;
public ByteContainer(byte[] file) : this(file, null) public ByteContainer(byte[] file) : this(file, null)
{ {
@ -658,17 +660,10 @@ public ByteContainer(byte[] file, string filename, string contenttype) : this(fi
public ByteContainer(byte[] file, string filename, string contenttype, int filesize) public ByteContainer(byte[] file, string filename, string contenttype, int filesize)
{ {
this.file = file; _file = file;
fileName = filename; _fileName = filename;
contentType = contenttype; _contentType = contenttype;
if (filesize == 0) _fileSize = filesize == 0 ? file.Length : filesize;
{
fileSize = file.Length;
}
else
{
fileSize = filesize;
}
} }
/// <summary> /// <summary>
@ -677,7 +672,7 @@ public ByteContainer(byte[] file, string filename, string contenttype, int files
/// <returns>string</returns> /// <returns>string</returns>
public string ToBase64String(Base64FormattingOptions formattingOptions) public string ToBase64String(Base64FormattingOptions formattingOptions)
{ {
return Convert.ToBase64String(file, 0, fileSize, formattingOptions); return Convert.ToBase64String(_file, 0, _fileSize, formattingOptions);
} }
/// <summary> /// <summary>
@ -686,7 +681,7 @@ public string ToBase64String(Base64FormattingOptions formattingOptions)
/// <returns>byte[]</returns> /// <returns>byte[]</returns>
public byte[] ToByteArray() public byte[] ToByteArray()
{ {
return file; return _file;
} }
/// <summary> /// <summary>
@ -701,13 +696,13 @@ public void WriteFormDataToStream(string boundary, string name, Stream formDataS
string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n", string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
boundary, boundary,
name, name,
fileName ?? name, _fileName ?? name,
contentType ?? "application/octet-stream"); _contentType ?? "application/octet-stream");
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header)); formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
// Write the file data directly to the Stream, rather than serializing it to a string. // Write the file data directly to the Stream, rather than serializing it to a string.
formDataStream.Write(file, 0, fileSize); formDataStream.Write(_file, 0, _fileSize);
} }
/// <summary> /// <summary>
@ -717,7 +712,7 @@ public void WriteFormDataToStream(string boundary, string name, Stream formDataS
public void WriteToStream(Stream dataStream) public void WriteToStream(Stream dataStream)
{ {
// Write the file data directly to the Stream, rather than serializing it to a string. // Write the file data directly to the Stream, rather than serializing it to a string.
dataStream.Write(file, 0, fileSize); dataStream.Write(_file, 0, _fileSize);
} }
/// <summary> /// <summary>
@ -726,8 +721,8 @@ public void WriteToStream(Stream dataStream)
/// <param name="webRequest"></param> /// <param name="webRequest"></param>
public void Upload(HttpWebRequest webRequest) public void Upload(HttpWebRequest webRequest)
{ {
webRequest.ContentType = contentType; webRequest.ContentType = _contentType;
webRequest.ContentLength = fileSize; webRequest.ContentLength = _fileSize;
using (var requestStream = webRequest.GetRequestStream()) using (var requestStream = webRequest.GetRequestStream())
{ {
WriteToStream(requestStream); WriteToStream(requestStream);
@ -740,15 +735,15 @@ public void Upload(HttpWebRequest webRequest)
/// </summary> /// </summary>
public class BitmapContainer : IBinaryContainer public class BitmapContainer : IBinaryContainer
{ {
private Bitmap bitmap; private readonly Bitmap _bitmap;
private SurfaceOutputSettings outputSettings; private readonly SurfaceOutputSettings _outputSettings;
private string fileName; private readonly string _fileName;
public BitmapContainer(Bitmap bitmap, SurfaceOutputSettings outputSettings, string filename) public BitmapContainer(Bitmap bitmap, SurfaceOutputSettings outputSettings, string filename)
{ {
this.bitmap = bitmap; _bitmap = bitmap;
this.outputSettings = outputSettings; _outputSettings = outputSettings;
fileName = filename; _fileName = filename;
} }
/// <summary> /// <summary>
@ -760,7 +755,7 @@ public string ToBase64String(Base64FormattingOptions formattingOptions)
{ {
using (MemoryStream stream = new MemoryStream()) using (MemoryStream stream = new MemoryStream())
{ {
ImageOutput.SaveToStream(bitmap, null, stream, outputSettings); ImageOutput.SaveToStream(_bitmap, null, stream, _outputSettings);
return Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length, formattingOptions); return Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length, formattingOptions);
} }
} }
@ -774,7 +769,7 @@ public byte[] ToByteArray()
{ {
using (MemoryStream stream = new MemoryStream()) using (MemoryStream stream = new MemoryStream())
{ {
ImageOutput.SaveToStream(bitmap, null, stream, outputSettings); ImageOutput.SaveToStream(_bitmap, null, stream, _outputSettings);
return stream.ToArray(); return stream.ToArray();
} }
} }
@ -791,11 +786,11 @@ public void WriteFormDataToStream(string boundary, string name, Stream formDataS
string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n", string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
boundary, boundary,
name, name,
fileName ?? name, _fileName ?? name,
"image/" + outputSettings.Format.ToString()); "image/" + _outputSettings.Format);
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header)); formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
ImageOutput.SaveToStream(bitmap, null, formDataStream, outputSettings); ImageOutput.SaveToStream(_bitmap, null, formDataStream, _outputSettings);
} }
/// <summary> /// <summary>
@ -805,7 +800,7 @@ public void WriteFormDataToStream(string boundary, string name, Stream formDataS
public void WriteToStream(Stream dataStream) public void WriteToStream(Stream dataStream)
{ {
// Write the file data directly to the Stream, rather than serializing it to a string. // Write the file data directly to the Stream, rather than serializing it to a string.
ImageOutput.SaveToStream(bitmap, null, dataStream, outputSettings); ImageOutput.SaveToStream(_bitmap, null, dataStream, _outputSettings);
} }
/// <summary> /// <summary>
@ -814,7 +809,7 @@ public void WriteToStream(Stream dataStream)
/// <param name="webRequest"></param> /// <param name="webRequest"></param>
public void Upload(HttpWebRequest webRequest) public void Upload(HttpWebRequest webRequest)
{ {
webRequest.ContentType = "image/" + outputSettings.Format.ToString(); webRequest.ContentType = "image/" + _outputSettings.Format;
using (var requestStream = webRequest.GetRequestStream()) using (var requestStream = webRequest.GetRequestStream())
{ {
WriteToStream(requestStream); WriteToStream(requestStream);
@ -827,15 +822,15 @@ public void Upload(HttpWebRequest webRequest)
/// </summary> /// </summary>
public class SurfaceContainer : IBinaryContainer public class SurfaceContainer : IBinaryContainer
{ {
private ISurface surface; private readonly ISurface _surface;
private SurfaceOutputSettings outputSettings; private readonly SurfaceOutputSettings _outputSettings;
private string fileName; private readonly string _fileName;
public SurfaceContainer(ISurface surface, SurfaceOutputSettings outputSettings, string filename) public SurfaceContainer(ISurface surface, SurfaceOutputSettings outputSettings, string filename)
{ {
this.surface = surface; _surface = surface;
this.outputSettings = outputSettings; _outputSettings = outputSettings;
fileName = filename; _fileName = filename;
} }
/// <summary> /// <summary>
@ -847,7 +842,7 @@ public string ToBase64String(Base64FormattingOptions formattingOptions)
{ {
using (MemoryStream stream = new MemoryStream()) using (MemoryStream stream = new MemoryStream())
{ {
ImageOutput.SaveToStream(surface, stream, outputSettings); ImageOutput.SaveToStream(_surface, stream, _outputSettings);
return Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length, formattingOptions); return Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length, formattingOptions);
} }
} }
@ -861,7 +856,7 @@ public byte[] ToByteArray()
{ {
using (MemoryStream stream = new MemoryStream()) using (MemoryStream stream = new MemoryStream())
{ {
ImageOutput.SaveToStream(surface, stream, outputSettings); ImageOutput.SaveToStream(_surface, stream, _outputSettings);
return stream.ToArray(); return stream.ToArray();
} }
} }
@ -878,11 +873,11 @@ public void WriteFormDataToStream(string boundary, string name, Stream formDataS
string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n", string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
boundary, boundary,
name, name,
fileName ?? name, _fileName ?? name,
"image/" + outputSettings.Format); "image/" + _outputSettings.Format);
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header)); formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
ImageOutput.SaveToStream(surface, formDataStream, outputSettings); ImageOutput.SaveToStream(_surface, formDataStream, _outputSettings);
} }
/// <summary> /// <summary>
@ -892,7 +887,7 @@ public void WriteFormDataToStream(string boundary, string name, Stream formDataS
public void WriteToStream(Stream dataStream) public void WriteToStream(Stream dataStream)
{ {
// Write the file data directly to the Stream, rather than serializing it to a string. // Write the file data directly to the Stream, rather than serializing it to a string.
ImageOutput.SaveToStream(surface, dataStream, outputSettings); ImageOutput.SaveToStream(_surface, dataStream, _outputSettings);
} }
/// <summary> /// <summary>
@ -901,7 +896,7 @@ public void WriteToStream(Stream dataStream)
/// <param name="webRequest"></param> /// <param name="webRequest"></param>
public void Upload(HttpWebRequest webRequest) public void Upload(HttpWebRequest webRequest)
{ {
webRequest.ContentType = "image/" + outputSettings.Format.ToString(); webRequest.ContentType = "image/" + _outputSettings.Format.ToString();
using (var requestStream = webRequest.GetRequestStream()) using (var requestStream = webRequest.GetRequestStream())
{ {
WriteToStream(requestStream); WriteToStream(requestStream);

View file

@ -0,0 +1,92 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2016 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub: https://github.com/greenshot
*
* This program 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 1 of the License, or
* (at your option) any later version.
*
* This program 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 <http://www.gnu.org/licenses/>.
*/
using System;
namespace GreenshotPlugin.Core
{
/// <summary>
/// Extensions to help with querying the Operating System
/// </summary>
public static class OperatingSystemExtensions
{
/// <summary>
/// Test if the current OS is Windows 10
/// </summary>
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
/// <returns>true if we are running on Windows 10</returns>
public static bool IsWindows10(this OperatingSystem operatingSystem)
{
return operatingSystem.Version.Major == 10;
}
/// <summary>
/// Test if the current OS is Windows 8(.1)
/// </summary>
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
/// <returns>true if we are running on Windows 8(.1)</returns>
public static bool IsWindows8(this OperatingSystem operatingSystem)
{
return operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 2;
}
/// <summary>
/// Test if the current OS is Windows 8 or later
/// </summary>
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
/// <returns>true if we are running on Windows 8 or later</returns>
public static bool IsWindows8OrLater(this OperatingSystem operatingSystem)
{
return (operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 2) || operatingSystem.Version.Major >= 6;
}
/// <summary>
/// Test if the current OS is Windows 7 or later
/// </summary>
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
/// <returns>true if we are running on Windows 7 or later</returns>
public static bool IsWindows7OrLater(this OperatingSystem operatingSystem)
{
return (operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 1) || operatingSystem.Version.Major >= 6;
}
/// <summary>
/// Test if the current OS is Windows Vista or later
/// </summary>
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
/// <returns>true if we are running on Windows Vista or later</returns>
public static bool IsWindowsVistaOrLater(this OperatingSystem operatingSystem)
{
return operatingSystem.Version.Major >= 6;
}
/// <summary>
/// Test if the current OS is Windows XP or later
/// </summary>
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
/// <returns>true if we are running on Windows XP or later</returns>
public static bool IsWindowsXpOrLater(this OperatingSystem operatingSystem)
{
// Windows 2000 is Major 5 minor 0
return Environment.OSVersion.Version.Major > 5 || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1);
}
}
}

View file

@ -37,9 +37,9 @@ namespace GreenshotPlugin.Core
/// </summary> /// </summary>
public static class PluginUtils public static class PluginUtils
{ {
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private const string PATH_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\"; private const string PATH_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\";
private static IDictionary<string, Image> exeIconCache = new Dictionary<string, Image>(); private static readonly IDictionary<string, Image> exeIconCache = new Dictionary<string, Image>();
static PluginUtils() static PluginUtils()
{ {
@ -126,16 +126,19 @@ public static Image GetCachedExeIcon(string path, int index)
{ {
string cacheKey = string.Format("{0}:{1}", path, index); string cacheKey = string.Format("{0}:{1}", path, index);
Image returnValue; Image returnValue;
if (!exeIconCache.TryGetValue(cacheKey, out returnValue)) lock (exeIconCache)
{ {
lock (exeIconCache) if (!exeIconCache.TryGetValue(cacheKey, out returnValue))
{ {
if (!exeIconCache.TryGetValue(cacheKey, out returnValue)) lock (exeIconCache)
{ {
returnValue = GetExeIcon(path, index); if (!exeIconCache.TryGetValue(cacheKey, out returnValue))
if (returnValue != null)
{ {
exeIconCache.Add(cacheKey, returnValue); returnValue = GetExeIcon(path, index);
if (returnValue != null)
{
exeIconCache.Add(cacheKey, returnValue);
}
} }
} }
} }

View file

@ -83,23 +83,23 @@ public class WuQuantizer : IDisposable
private const Int32 MAXVOLUME = SIDESIZE * SIDESIZE * SIDESIZE; private const Int32 MAXVOLUME = SIDESIZE * SIDESIZE * SIDESIZE;
// To count the colors // To count the colors
private int colorCount = 0; private readonly int colorCount;
private Int32[] reds; private Int32[] reds;
private Int32[] greens; private Int32[] greens;
private Int32[] blues; private Int32[] blues;
private Int32[] sums; private Int32[] sums;
private Int64[,,] weights; private readonly Int64[,,] weights;
private Int64[,,] momentsRed; private readonly Int64[,,] momentsRed;
private Int64[,,] momentsGreen; private readonly Int64[,,] momentsGreen;
private Int64[,,] momentsBlue; private readonly Int64[,,] momentsBlue;
private Single[,,] moments; private readonly Single[,,] moments;
private byte[] tag; private byte[] tag;
private WuColorCube[] cubes; private readonly WuColorCube[] cubes;
private Bitmap sourceBitmap; private readonly Bitmap sourceBitmap;
private Bitmap resultBitmap; private Bitmap resultBitmap;
public void Dispose() public void Dispose()

View file

@ -68,7 +68,7 @@ public float DpiY
set; set;
} }
private Dictionary<string, string> metaData = new Dictionary<string, string>(); private readonly Dictionary<string, string> metaData = new Dictionary<string, string>();
public Dictionary<string, string> MetaData public Dictionary<string, string> MetaData
{ {
get { return metaData; } get { return metaData; }
@ -503,6 +503,7 @@ public class WindowCapture
/// <param name="hObject"></param> /// <param name="hObject"></param>
/// <returns></returns> /// <returns></returns>
[DllImport("gdi32", SetLastError = true)] [DllImport("gdi32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteObject(IntPtr hObject); private static extern bool DeleteObject(IntPtr hObject);
private WindowCapture() private WindowCapture()
@ -766,7 +767,7 @@ public static Bitmap CaptureRectangle(Rectangle captureBounds)
// capture.Image = capturedBitmap; // capture.Image = capturedBitmap;
// capture.Location = captureBounds.Location; // capture.Location = captureBounds.Location;
using (SafeWindowDCHandle desktopDCHandle = SafeWindowDCHandle.fromDesktop()) using (SafeWindowDCHandle desktopDCHandle = SafeWindowDCHandle.FromDesktop())
{ {
if (desktopDCHandle.IsInvalid) if (desktopDCHandle.IsInvalid)
{ {

View file

@ -33,12 +33,6 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Windows.Forms; using System.Windows.Forms;
/// <summary>
/// Code for handling with "windows"
/// Main code is taken from vbAccelerator, location:
/// http://www.vbaccelerator.com/home/NET/Code/Libraries/Windows/Enumerating_Windows/article.asp
/// but a LOT of changes/enhancements were made to adapt it for Greenshot.
/// </summary>
namespace GreenshotPlugin.Core namespace GreenshotPlugin.Core
{ {
#region EnumWindows #region EnumWindows
@ -50,7 +44,7 @@ public class WindowsEnumerator
{ {
#region Member Variables #region Member Variables
private List<WindowDetails> items = null; private List<WindowDetails> items;
#endregion Member Variables #endregion Member Variables
@ -101,7 +95,7 @@ public WindowsEnumerator GetWindows(IntPtr hWndParent, string classname)
{ {
items = new List<WindowDetails>(); items = new List<WindowDetails>();
List<WindowDetails> windows = new List<WindowDetails>(); List<WindowDetails> windows = new List<WindowDetails>();
User32.EnumChildWindows(hWndParent, new EnumWindowsProc(WindowEnum), IntPtr.Zero); User32.EnumChildWindows(hWndParent, WindowEnum, IntPtr.Zero);
bool hasParent = !IntPtr.Zero.Equals(hWndParent); bool hasParent = !IntPtr.Zero.Equals(hWndParent);
string parentText = null; string parentText = null;
@ -162,7 +156,7 @@ private int WindowEnum(IntPtr hWnd, int lParam)
/// <returns>True to continue enumeration, False to stop</returns> /// <returns>True to continue enumeration, False to stop</returns>
protected virtual bool OnWindowEnum(IntPtr hWnd) protected virtual bool OnWindowEnum(IntPtr hWnd)
{ {
if (!WindowDetails.isIgnoreHandle(hWnd)) if (!WindowDetails.IsIgnoreHandle(hWnd))
{ {
items.Add(new WindowDetails(hWnd)); items.Add(new WindowDetails(hWnd));
} }
@ -186,19 +180,24 @@ public WindowsEnumerator()
#region WindowDetails #region WindowDetails
/// <summary> /// <summary>
/// Code for handling with "windows"
/// Main code is taken from vbAccelerator, location:
/// http://www.vbaccelerator.com/home/NET/Code/Libraries/Windows/Enumerating_Windows/article.asp
/// but a LOT of changes/enhancements were made to adapt it for Greenshot.
/// <summary>
/// Provides details about a Window returned by the /// Provides details about a Window returned by the
/// enumeration /// enumeration
/// </summary> /// </summary>
public class WindowDetails : IEquatable<WindowDetails> public class WindowDetails : IEquatable<WindowDetails>
{ {
private const string METRO_WINDOWS_CLASS = "Windows.UI.Core.CoreWindow"; private const string METRO_WINDOWS_CLASS = "Windows.UI.Core.CoreWindow"; // Windows 10 uses ApplicationFrameWindow
private const string METRO_APPLAUNCHER_CLASS = "ImmersiveLauncher"; private const string METRO_APPLAUNCHER_CLASS = "ImmersiveLauncher";
private const string METRO_GUTTER_CLASS = "ImmersiveGutter"; private const string METRO_GUTTER_CLASS = "ImmersiveGutter";
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration Conf = IniConfig.GetIniSection<CoreConfiguration>();
private static List<IntPtr> ignoreHandles = new List<IntPtr>(); private static readonly List<IntPtr> IgnoreHandles = new List<IntPtr>();
private static List<string> excludeProcessesFromFreeze = new List<string>(); private static readonly List<string> ExcludeProcessesFromFreeze = new List<string>();
private static IAppVisibility appVisibility = null; private static readonly IAppVisibility appVisibility;
static WindowDetails() static WindowDetails()
{ {
@ -215,23 +214,27 @@ static WindowDetails()
public static void AddProcessToExcludeFromFreeze(string processname) public static void AddProcessToExcludeFromFreeze(string processname)
{ {
if (!excludeProcessesFromFreeze.Contains(processname)) if (!ExcludeProcessesFromFreeze.Contains(processname))
{ {
excludeProcessesFromFreeze.Add(processname); ExcludeProcessesFromFreeze.Add(processname);
} }
} }
internal static bool isIgnoreHandle(IntPtr handle) internal static bool IsIgnoreHandle(IntPtr handle)
{ {
return ignoreHandles.Contains(handle); return IgnoreHandles.Contains(handle);
} }
private List<WindowDetails> childWindows = null; private List<WindowDetails> _childWindows;
private IntPtr parentHandle = IntPtr.Zero; private IntPtr _parentHandle = IntPtr.Zero;
private WindowDetails parent = null; private WindowDetails _parent;
private bool frozen = false; private bool _frozen;
public bool isApp /// <summary>
/// This checks if the window is a Windows 8 App
/// For Windows 10 most normal code works, as it's hosted inside "ApplicationFrameWindow"
/// </summary>
public bool IsApp
{ {
get get
{ {
@ -239,7 +242,7 @@ public bool isApp
} }
} }
public bool isGutter public bool IsGutter
{ {
get get
{ {
@ -247,7 +250,7 @@ public bool isGutter
} }
} }
public bool isAppLauncher public bool IsAppLauncher
{ {
get get
{ {
@ -258,18 +261,18 @@ public bool isAppLauncher
/// <summary> /// <summary>
/// Check if this window is the window of a metro app /// Check if this window is the window of a metro app
/// </summary> /// </summary>
public bool isMetroApp public bool IsMetroApp
{ {
get get
{ {
return isAppLauncher || isApp; return IsAppLauncher || IsApp;
} }
} }
/// <summary> /// <summary>
/// The window handle. /// The window handle.
/// </summary> /// </summary>
private IntPtr hWnd = IntPtr.Zero; private IntPtr _hWnd = IntPtr.Zero;
/// <summary> /// <summary>
/// To allow items to be compared, the hash code /// To allow items to be compared, the hash code
@ -310,18 +313,18 @@ public bool HasChildren
{ {
get get
{ {
return (childWindows != null) && (childWindows.Count > 0); return (_childWindows != null) && (_childWindows.Count > 0);
} }
} }
public void FreezeDetails() public void FreezeDetails()
{ {
frozen = true; _frozen = true;
} }
public void UnfreezeDetails() public void UnfreezeDetails()
{ {
frozen = false; _frozen = false;
} }
public string ProcessPath public string ProcessPath
@ -362,7 +365,7 @@ public Image DisplayIcon
LOG.WarnFormat("Couldn't get icon for window {0} due to: {1}", Text, ex.Message); LOG.WarnFormat("Couldn't get icon for window {0} due to: {1}", Text, ex.Message);
LOG.Warn(ex); LOG.Warn(ex);
} }
if (isMetroApp) if (IsMetroApp)
{ {
// No method yet to get the metro icon // No method yet to get the metro icon
return null; return null;
@ -391,8 +394,8 @@ private static Icon GetAppIcon(IntPtr hwnd)
IntPtr ICON_BIG = new IntPtr(1); IntPtr ICON_BIG = new IntPtr(1);
IntPtr ICON_SMALL2 = new IntPtr(2); IntPtr ICON_SMALL2 = new IntPtr(2);
IntPtr iconHandle = User32.SendMessage(hwnd, (int)WindowsMessages.WM_GETICON, ICON_BIG, IntPtr.Zero); IntPtr iconHandle;
if (conf.UseLargeIcons) if (Conf.UseLargeIcons)
{ {
iconHandle = User32.SendMessage(hwnd, (int)WindowsMessages.WM_GETICON, ICON_BIG, IntPtr.Zero); iconHandle = User32.SendMessage(hwnd, (int)WindowsMessages.WM_GETICON, ICON_BIG, IntPtr.Zero);
if (iconHandle == IntPtr.Zero) if (iconHandle == IntPtr.Zero)
@ -437,7 +440,7 @@ private static Icon GetAppIcon(IntPtr hwnd)
/// <param name="ignoreHandle"></param> /// <param name="ignoreHandle"></param>
public static void RegisterIgnoreHandle(IntPtr ignoreHandle) public static void RegisterIgnoreHandle(IntPtr ignoreHandle)
{ {
ignoreHandles.Add(ignoreHandle); IgnoreHandles.Add(ignoreHandle);
} }
/// <summary> /// <summary>
@ -446,24 +449,25 @@ public static void RegisterIgnoreHandle(IntPtr ignoreHandle)
/// <param name="ignoreHandle"></param> /// <param name="ignoreHandle"></param>
public static void UnregisterIgnoreHandle(IntPtr ignoreHandle) public static void UnregisterIgnoreHandle(IntPtr ignoreHandle)
{ {
ignoreHandles.Remove(ignoreHandle); IgnoreHandles.Remove(ignoreHandle);
} }
public List<WindowDetails> Children public List<WindowDetails> Children
{ {
get get
{ {
if (childWindows == null) if (_childWindows == null)
{ {
GetChildren(); GetChildren();
} }
return childWindows; return _childWindows;
} }
} }
/// <summary> /// <summary>
/// Retrieve all windows with a certain title or classname /// Retrieve all windows with a certain title or classname
/// </summary> /// </summary>
/// <param name="windows"></param>
/// <param name="titlePattern">The regexp to look for in the title</param> /// <param name="titlePattern">The regexp to look for in the title</param>
/// <param name="classnamePattern">The regexp to look for in the classname</param> /// <param name="classnamePattern">The regexp to look for in the classname</param>
/// <returns>List<WindowDetails> with all the found windows</returns> /// <returns>List<WindowDetails> with all the found windows</returns>
@ -529,19 +533,19 @@ public IntPtr ParentHandle
{ {
get get
{ {
if (parentHandle == IntPtr.Zero) if (_parentHandle == IntPtr.Zero)
{ {
parentHandle = User32.GetParent(Handle); _parentHandle = User32.GetParent(Handle);
parent = null; _parent = null;
} }
return parentHandle; return _parentHandle;
} }
set set
{ {
if (parentHandle != value) if (_parentHandle != value)
{ {
parentHandle = value; _parentHandle = value;
parent = null; _parent = null;
} }
} }
} }
@ -552,18 +556,18 @@ public IntPtr ParentHandle
/// <returns>WindowDetails of the parent, or null if none</returns> /// <returns>WindowDetails of the parent, or null if none</returns>
public WindowDetails GetParent() public WindowDetails GetParent()
{ {
if (parent == null) if (_parent == null)
{ {
if (parentHandle == IntPtr.Zero) if (_parentHandle == IntPtr.Zero)
{ {
parentHandle = User32.GetParent(Handle); _parentHandle = User32.GetParent(Handle);
} }
if (parentHandle != IntPtr.Zero) if (_parentHandle != IntPtr.Zero)
{ {
parent = new WindowDetails(parentHandle); _parent = new WindowDetails(_parentHandle);
} }
} }
return parent; return _parent;
} }
/// <summary> /// <summary>
@ -572,11 +576,11 @@ public WindowDetails GetParent()
/// </summary> /// </summary>
public List<WindowDetails> GetChildren() public List<WindowDetails> GetChildren()
{ {
if (childWindows == null) if (_childWindows == null)
{ {
return GetChildren(0); return GetChildren(0);
} }
return childWindows; return _childWindows;
} }
/// <summary> /// <summary>
@ -585,19 +589,19 @@ public List<WindowDetails> GetChildren()
/// <param name="levelsToGo">Specify how many levels we go in</param> /// <param name="levelsToGo">Specify how many levels we go in</param>
public List<WindowDetails> GetChildren(int levelsToGo) public List<WindowDetails> GetChildren(int levelsToGo)
{ {
if (childWindows == null) if (_childWindows == null)
{ {
childWindows = new List<WindowDetails>(); _childWindows = new List<WindowDetails>();
foreach (WindowDetails childWindow in new WindowsEnumerator().GetWindows(hWnd, null).Items) foreach (WindowDetails childWindow in new WindowsEnumerator().GetWindows(_hWnd, null).Items)
{ {
childWindows.Add(childWindow); _childWindows.Add(childWindow);
if (levelsToGo > 0) if (levelsToGo > 0)
{ {
childWindow.GetChildren(levelsToGo - 1); childWindow.GetChildren(levelsToGo - 1);
} }
} }
} }
return childWindows; return _childWindows;
} }
/// <summary> /// <summary>
@ -605,7 +609,7 @@ public List<WindowDetails> GetChildren(int levelsToGo)
/// </summary> /// </summary>
/// <param name="titlePattern">The regexp to look for in the title</param> /// <param name="titlePattern">The regexp to look for in the title</param>
/// <param name="classnamePattern">The regexp to look for in the classname</param> /// <param name="classnamePattern">The regexp to look for in the classname</param>
/// <returns>List<WindowDetails> with all the found windows, or an empty list</returns> /// <returns>List WindowDetails with all the found windows, or an empty list</returns>
public List<WindowDetails> FindChildren(string titlePattern, string classnamePattern) public List<WindowDetails> FindChildren(string titlePattern, string classnamePattern)
{ {
return FindWindow(Children, titlePattern, classnamePattern); return FindWindow(Children, titlePattern, classnamePattern);
@ -646,7 +650,7 @@ private WindowDetails FindPath(List<string> classnames, int index)
/// This method will find the child window according to a path of classnames. /// This method will find the child window according to a path of classnames.
/// Usually used for finding a certain "content" window like for the IE Browser /// Usually used for finding a certain "content" window like for the IE Browser
/// </summary> /// </summary>
/// <param name="classnames">List<string> with classname "path"</param> /// <param name="classnames">List string with classname "path"</param>
/// <param name="allowSkip">true allows the search to skip a classname of the path</param> /// <param name="allowSkip">true allows the search to skip a classname of the path</param>
/// <returns>WindowDetails if found</returns> /// <returns>WindowDetails if found</returns>
public WindowDetails FindPath(List<string> classnames, bool allowSkip) public WindowDetails FindPath(List<string> classnames, bool allowSkip)
@ -707,7 +711,7 @@ public WindowDetails GetWindow(GetWindowCommand gwCommand)
return null; return null;
} }
WindowDetails windowDetails = new WindowDetails(tmphWnd); WindowDetails windowDetails = new WindowDetails(tmphWnd);
windowDetails.parent = this; windowDetails._parent = this;
return windowDetails; return windowDetails;
} }
@ -718,11 +722,11 @@ public IntPtr Handle
{ {
get get
{ {
return hWnd; return _hWnd;
} }
} }
private string text = null; private string _text;
/// <summary> /// <summary>
/// Gets the window's title (caption) /// Gets the window's title (caption)
/// </summary> /// </summary>
@ -730,21 +734,21 @@ public string Text
{ {
set set
{ {
text = value; _text = value;
} }
get get
{ {
if (text == null) if (_text == null)
{ {
StringBuilder title = new StringBuilder(260, 260); StringBuilder title = new StringBuilder(260, 260);
User32.GetWindowText(hWnd, title, title.Capacity); User32.GetWindowText(_hWnd, title, title.Capacity);
text = title.ToString(); _text = title.ToString();
} }
return text; return _text;
} }
} }
private string className = null; private string _className;
/// <summary> /// <summary>
/// Gets the window's class name. /// Gets the window's class name.
/// </summary> /// </summary>
@ -752,11 +756,11 @@ public string ClassName
{ {
get get
{ {
if (className == null) if (_className == null)
{ {
className = GetClassName(hWnd); _className = GetClassName(_hWnd);
} }
return className; return _className;
} }
} }
@ -767,21 +771,21 @@ public bool Iconic
{ {
get get
{ {
if (isMetroApp) if (IsMetroApp)
{ {
return !Visible; return !Visible;
} }
return User32.IsIconic(hWnd) || Location.X <= -32000; return User32.IsIconic(_hWnd) || Location.X <= -32000;
} }
set set
{ {
if (value) if (value)
{ {
User32.SendMessage(hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_MINIMIZE, IntPtr.Zero); User32.SendMessage(_hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_MINIMIZE, IntPtr.Zero);
} }
else else
{ {
User32.SendMessage(hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_RESTORE, IntPtr.Zero); User32.SendMessage(_hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_RESTORE, IntPtr.Zero);
} }
} }
} }
@ -793,7 +797,7 @@ public bool Maximised
{ {
get get
{ {
if (isApp) if (IsApp)
{ {
if (Visible) if (Visible)
{ {
@ -811,17 +815,17 @@ public bool Maximised
} }
return false; return false;
} }
return User32.IsZoomed(hWnd); return User32.IsZoomed(_hWnd);
} }
set set
{ {
if (value) if (value)
{ {
User32.SendMessage(hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_MAXIMIZE, IntPtr.Zero); User32.SendMessage(_hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_MAXIMIZE, IntPtr.Zero);
} }
else else
{ {
User32.SendMessage(hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_MINIMIZE, IntPtr.Zero); User32.SendMessage(_hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_MINIMIZE, IntPtr.Zero);
} }
} }
} }
@ -841,7 +845,7 @@ public bool Visible
{ {
get get
{ {
if (isApp) if (IsApp)
{ {
Rectangle windowRectangle = WindowRectangle; Rectangle windowRectangle = WindowRectangle;
foreach (Screen screen in Screen.AllScreens) foreach (Screen screen in Screen.AllScreens)
@ -876,16 +880,16 @@ public bool Visible
} }
return false; return false;
} }
if (isGutter) if (IsGutter)
{ {
// gutter is only made available when it's visible // gutter is only made available when it's visible
return true; return true;
} }
if (isAppLauncher) if (IsAppLauncher)
{ {
return IsAppLauncherVisible; return IsAppLauncherVisible;
} }
return User32.IsWindowVisible(hWnd); return User32.IsWindowVisible(_hWnd);
} }
} }
@ -894,7 +898,7 @@ public bool HasParent
get get
{ {
GetParent(); GetParent();
return parentHandle != IntPtr.Zero; return _parentHandle != IntPtr.Zero;
} }
} }
@ -935,12 +939,12 @@ public Process Process
/// </summary> /// </summary>
public void Reset() public void Reset()
{ {
previousWindowRectangle = Rectangle.Empty; _previousWindowRectangle = Rectangle.Empty;
} }
private Rectangle previousWindowRectangle = Rectangle.Empty; private Rectangle _previousWindowRectangle = Rectangle.Empty;
private long lastWindowRectangleRetrieveTime = 0; private long _lastWindowRectangleRetrieveTime;
private const long CACHE_TIME = TimeSpan.TicksPerSecond * 2; private const long CacheTime = TimeSpan.TicksPerSecond * 2;
/// <summary> /// <summary>
/// Gets the bounding rectangle of the window /// Gets the bounding rectangle of the window
/// </summary> /// </summary>
@ -950,39 +954,64 @@ public Rectangle WindowRectangle
{ {
// Try to return a cached value // Try to return a cached value
long now = DateTime.Now.Ticks; long now = DateTime.Now.Ticks;
if (previousWindowRectangle.IsEmpty || !frozen) if (_previousWindowRectangle.IsEmpty || !_frozen)
{ {
if (previousWindowRectangle.IsEmpty || now - lastWindowRectangleRetrieveTime > CACHE_TIME) if (_previousWindowRectangle.IsEmpty || now - _lastWindowRectangleRetrieveTime > CacheTime)
{ {
Rectangle windowRect = Rectangle.Empty; Rectangle windowRect = Rectangle.Empty;
if (DWM.isDWMEnabled()) if (DWM.IsDwmEnabled())
{ {
GetExtendedFrameBounds(out windowRect); bool gotFrameBounds = GetExtendedFrameBounds(out windowRect);
if (IsApp)
{
// Pre-Cache for Maximised call, this is only on Windows 8 apps (full screen)
if (gotFrameBounds)
{
_previousWindowRectangle = windowRect;
_lastWindowRectangleRetrieveTime = now;
}
}
if (gotFrameBounds && Environment.OSVersion.IsWindows10() && !Maximised)
{
// Somehow DWM doesn't calculate it corectly, there is a 1 pixel border around the capture
// Remove this border, currently it's fixed but TODO: Make it depend on the OS?
windowRect.Inflate(-1, -1);
_previousWindowRectangle = windowRect;
_lastWindowRectangleRetrieveTime = now;
return windowRect;
}
} }
if (windowRect.IsEmpty) if (windowRect.IsEmpty)
{ {
GetWindowRect(out windowRect); if (GetWindowRect(out windowRect))
{
Win32Error error = Win32.GetLastErrorCode();
LOG.WarnFormat("Couldn't retrieve the windows rectangle: {0}", Win32.GetMessage(error));
}
} }
// Correction for maximized windows, only if it's not an app // Correction for maximized windows, only if it's not an app
if (!HasParent && !isApp && Maximised) if (!HasParent && !IsApp && Maximised)
{ {
Size size = Size.Empty; Size size;
GetBorderSize(out size); // Only if the border size can be retrieved
windowRect = new Rectangle(windowRect.X + size.Width, windowRect.Y + size.Height, windowRect.Width - (2 * size.Width), windowRect.Height - (2 * size.Height)); if (GetBorderSize(out size))
{
windowRect = new Rectangle(windowRect.X + size.Width, windowRect.Y + size.Height, windowRect.Width - (2 * size.Width), windowRect.Height - (2 * size.Height));
}
} }
lastWindowRectangleRetrieveTime = now; _lastWindowRectangleRetrieveTime = now;
// Try to return something valid, by getting returning the previous size if the window doesn't have a Rectangle anymore // Try to return something valid, by getting returning the previous size if the window doesn't have a Rectangle anymore
if (windowRect.IsEmpty) if (windowRect.IsEmpty)
{ {
return previousWindowRectangle; return _previousWindowRectangle;
} }
previousWindowRectangle = windowRect; _previousWindowRectangle = windowRect;
return windowRect; return windowRect;
} }
} }
return previousWindowRectangle; return _previousWindowRectangle;
} }
} }
@ -1017,8 +1046,12 @@ public Rectangle ClientRectangle
{ {
get get
{ {
Rectangle clientRect = Rectangle.Empty; Rectangle clientRect;
GetClientRect(out clientRect); if (GetClientRect(out clientRect))
{
Win32Error error = Win32.GetLastErrorCode();
LOG.WarnFormat("Couldn't retrieve the client rectangle: {0}", Win32.GetMessage(error));
}
return clientRect; return clientRect;
} }
} }
@ -1041,10 +1074,10 @@ public void Restore()
{ {
if (Iconic) if (Iconic)
{ {
User32.SendMessage(hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_RESTORE, IntPtr.Zero); User32.SendMessage(_hWnd, (int)WindowsMessages.WM_SYSCOMMAND, (IntPtr)User32.SC_RESTORE, IntPtr.Zero);
} }
User32.BringWindowToTop(hWnd); User32.BringWindowToTop(_hWnd);
User32.SetForegroundWindow(hWnd); User32.SetForegroundWindow(_hWnd);
// Make sure windows has time to perform the action // Make sure windows has time to perform the action
while (Iconic) while (Iconic)
{ {
@ -1059,11 +1092,11 @@ public WindowStyleFlags WindowStyle
{ {
get get
{ {
return (WindowStyleFlags)User32.GetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_STYLE); return (WindowStyleFlags)User32.GetWindowLongWrapper(_hWnd, (int)WindowLongIndex.GWL_STYLE);
} }
set set
{ {
User32.SetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_STYLE, new IntPtr((long)value)); User32.SetWindowLongWrapper(_hWnd, (int)WindowLongIndex.GWL_STYLE, new IntPtr((long)value));
} }
} }
@ -1091,11 +1124,11 @@ public ExtendedWindowStyleFlags ExtendedWindowStyle
{ {
get get
{ {
return (ExtendedWindowStyleFlags)User32.GetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_EXSTYLE); return (ExtendedWindowStyleFlags)User32.GetWindowLongWrapper(_hWnd, (int)WindowLongIndex.GWL_EXSTYLE);
} }
set set
{ {
User32.SetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_EXSTYLE, new IntPtr((uint)value)); User32.SetWindowLongWrapper(_hWnd, (int)WindowLongIndex.GWL_EXSTYLE, new IntPtr((uint)value));
} }
} }
@ -1104,7 +1137,7 @@ public ExtendedWindowStyleFlags ExtendedWindowStyle
/// </summary> /// </summary>
/// <param name="capture">The capture to fill</param> /// <param name="capture">The capture to fill</param>
/// <returns>ICapture</returns> /// <returns>ICapture</returns>
public ICapture CaptureGDIWindow(ICapture capture) public ICapture CaptureGdiWindow(ICapture capture)
{ {
Image capturedImage = PrintWindow(); Image capturedImage = PrintWindow();
if (capturedImage != null) if (capturedImage != null)
@ -1123,17 +1156,19 @@ public ICapture CaptureGDIWindow(ICapture capture)
/// <param name="windowCaptureMode">Wanted WindowCaptureMode</param> /// <param name="windowCaptureMode">Wanted WindowCaptureMode</param>
/// <param name="autoMode">True if auto modus is used</param> /// <param name="autoMode">True if auto modus is used</param>
/// <returns>ICapture with the capture</returns> /// <returns>ICapture with the capture</returns>
public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptureMode, bool autoMode) public ICapture CaptureDwmWindow(ICapture capture, WindowCaptureMode windowCaptureMode, bool autoMode)
{ {
IntPtr thumbnailHandle = IntPtr.Zero; IntPtr thumbnailHandle = IntPtr.Zero;
Form tempForm = null; Form tempForm = null;
bool tempFormShown = false; bool tempFormShown = false;
try try
{ {
tempForm = new Form(); tempForm = new Form
tempForm.ShowInTaskbar = false; {
tempForm.FormBorderStyle = FormBorderStyle.None; ShowInTaskbar = false,
tempForm.TopMost = true; FormBorderStyle = FormBorderStyle.None,
TopMost = true
};
// Register the Thumbnail // Register the Thumbnail
DWM.DwmRegisterThumbnail(tempForm.Handle, Handle, out thumbnailHandle); DWM.DwmRegisterThumbnail(tempForm.Handle, Handle, out thumbnailHandle);
@ -1142,14 +1177,14 @@ public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptu
SIZE sourceSize; SIZE sourceSize;
DWM.DwmQueryThumbnailSourceSize(thumbnailHandle, out sourceSize); DWM.DwmQueryThumbnailSourceSize(thumbnailHandle, out sourceSize);
if (sourceSize.width <= 0 || sourceSize.height <= 0) if (sourceSize.Width <= 0 || sourceSize.Height <= 0)
{ {
return null; return null;
} }
// Calculate the location of the temp form // Calculate the location of the temp form
Point formLocation;
Rectangle windowRectangle = WindowRectangle; Rectangle windowRectangle = WindowRectangle;
Point formLocation = windowRectangle.Location;
Size borderSize = new Size(); Size borderSize = new Size();
bool doesCaptureFit = false; bool doesCaptureFit = false;
if (!Maximised) if (!Maximised)
@ -1161,7 +1196,7 @@ public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptu
// Find the screen where the window is and check if it fits // Find the screen where the window is and check if it fits
foreach (Screen screen in Screen.AllScreens) foreach (Screen screen in Screen.AllScreens)
{ {
if (screen != Screen.PrimaryScreen) if (!Equals(screen, Screen.PrimaryScreen))
{ {
workingArea.Union(screen.Bounds); workingArea.Union(screen.Bounds);
} }
@ -1188,7 +1223,7 @@ public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptu
} }
} }
} }
else else if (!Environment.OSVersion.IsWindows8OrLater())
{ {
//GetClientRect(out windowRectangle); //GetClientRect(out windowRectangle);
GetBorderSize(out borderSize); GetBorderSize(out borderSize);
@ -1199,38 +1234,42 @@ public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptu
tempForm.Size = sourceSize.ToSize(); tempForm.Size = sourceSize.ToSize();
// Prepare rectangle to capture from the screen. // Prepare rectangle to capture from the screen.
Rectangle captureRectangle = new Rectangle(formLocation.X, formLocation.Y, sourceSize.width, sourceSize.height); Rectangle captureRectangle = new Rectangle(formLocation.X, formLocation.Y, sourceSize.Width, sourceSize.Height);
if (Maximised) if (Maximised)
{ {
// Correct capture size for maximized window by offsetting the X,Y with the border size // Correct capture size for maximized window by offsetting the X,Y with the border size
captureRectangle.X += borderSize.Width;
captureRectangle.Y += borderSize.Height;
// and subtracting the border from the size (2 times, as we move right/down for the capture without resizing) // and subtracting the border from the size (2 times, as we move right/down for the capture without resizing)
captureRectangle.Width -= 2 * borderSize.Width; captureRectangle.Inflate(borderSize.Width, borderSize.Height);
captureRectangle.Height -= 2 * borderSize.Height;
} }
else if (autoMode) else
{ {
// check if the capture fits captureRectangle.Inflate(-1, -1);
if (!doesCaptureFit)
if (autoMode)
{ {
// if GDI is allowed.. (a screenshot won't be better than we comes if we continue) // check if the capture fits
using (Process thisWindowProcess = Process) if (!doesCaptureFit)
{ {
if (!isMetroApp && WindowCapture.IsGdiAllowed(thisWindowProcess)) // if GDI is allowed.. (a screenshot won't be better than we comes if we continue)
using (Process thisWindowProcess = Process)
{ {
// we return null which causes the capturing code to try another method. if (!IsMetroApp && WindowCapture.IsGdiAllowed(thisWindowProcess))
return null; {
// we return null which causes the capturing code to try another method.
return null;
}
} }
} }
} }
} }
// Prepare the displaying of the Thumbnail // Prepare the displaying of the Thumbnail
DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES(); DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES
props.Opacity = (byte)255; {
props.Visible = true; Opacity = 255,
props.Destination = new RECT(0, 0, sourceSize.width, sourceSize.height); Visible = true,
Destination = new RECT(0, 0, sourceSize.Width, sourceSize.Height)
};
DWM.DwmUpdateThumbnailProperties(thumbnailHandle, ref props); DWM.DwmUpdateThumbnailProperties(thumbnailHandle, ref props);
tempForm.Show(); tempForm.Show();
tempFormShown = true; tempFormShown = true;
@ -1261,7 +1300,7 @@ public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptu
tempForm.BackColor = Color.Black; tempForm.BackColor = Color.Black;
// Make sure everything is visible // Make sure everything is visible
tempForm.Refresh(); tempForm.Refresh();
if (!isMetroApp) if (!IsMetroApp)
{ {
// Make sure the application window is active, so the colors & buttons are right // Make sure the application window is active, so the colors & buttons are right
ToForeground(); ToForeground();
@ -1291,7 +1330,7 @@ public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptu
// Remove transparency, this will break the capturing // Remove transparency, this will break the capturing
if (!autoMode) if (!autoMode)
{ {
tempForm.BackColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B); tempForm.BackColor = Color.FromArgb(255, Conf.DWMBackgroundColor.R, Conf.DWMBackgroundColor.G, Conf.DWMBackgroundColor.B);
} }
else else
{ {
@ -1302,7 +1341,7 @@ public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptu
} }
// Make sure everything is visible // Make sure everything is visible
tempForm.Refresh(); tempForm.Refresh();
if (!isMetroApp) if (!IsMetroApp)
{ {
// Make sure the application window is active, so the colors & buttons are right // Make sure the application window is active, so the colors & buttons are right
ToForeground(); ToForeground();
@ -1315,10 +1354,10 @@ public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptu
if (capturedBitmap != null) if (capturedBitmap != null)
{ {
// Not needed for Windows 8 // Not needed for Windows 8
if (!(Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2)) if (!Environment.OSVersion.IsWindows8OrLater())
{ {
// Only if the Inivalue is set, not maximized and it's not a tool window. // Only if the Inivalue is set, not maximized and it's not a tool window.
if (conf.WindowCaptureRemoveCorners && !Maximised && (ExtendedWindowStyle & ExtendedWindowStyleFlags.WS_EX_TOOLWINDOW) == 0) if (Conf.WindowCaptureRemoveCorners && !Maximised && (ExtendedWindowStyle & ExtendedWindowStyleFlags.WS_EX_TOOLWINDOW) == 0)
{ {
// Remove corners // Remove corners
if (!Image.IsAlphaPixelFormat(capturedBitmap.PixelFormat)) if (!Image.IsAlphaPixelFormat(capturedBitmap.PixelFormat))
@ -1375,9 +1414,9 @@ private void RemoveCorners(Bitmap image)
{ {
using (IFastBitmap fastBitmap = FastBitmap.Create(image)) using (IFastBitmap fastBitmap = FastBitmap.Create(image))
{ {
for (int y = 0; y < conf.WindowCornerCutShape.Count; y++) for (int y = 0; y < Conf.WindowCornerCutShape.Count; y++)
{ {
for (int x = 0; x < conf.WindowCornerCutShape[y]; x++) for (int x = 0; x < Conf.WindowCornerCutShape[y]; x++)
{ {
fastBitmap.SetColorAt(x, y, Color.Transparent); fastBitmap.SetColorAt(x, y, Color.Transparent);
fastBitmap.SetColorAt(image.Width - 1 - x, y, Color.Transparent); fastBitmap.SetColorAt(image.Width - 1 - x, y, Color.Transparent);
@ -1506,7 +1545,7 @@ private bool GetWindowRect(out Rectangle rectangle)
/// <summary> /// <summary>
/// Helper method to get the Border size for GDI Windows /// Helper method to get the Border size for GDI Windows
/// </summary> /// </summary>
/// <param name="rectangle">out Rectangle</param> /// <param name="size">out Size</param>
/// <returns>bool true if it worked</returns> /// <returns>bool true if it worked</returns>
private bool GetBorderSize(out Size size) private bool GetBorderSize(out Size size)
{ {
@ -1570,7 +1609,7 @@ private bool CanFreezeOrUnfreeze(string titleOrProcessname)
return false; return false;
} }
foreach (string excludeProcess in excludeProcessesFromFreeze) foreach (string excludeProcess in ExcludeProcessesFromFreeze)
{ {
if (titleOrProcessname.ToLower().Contains(excludeProcess)) if (titleOrProcessname.ToLower().Contains(excludeProcess))
{ {
@ -1722,7 +1761,7 @@ public Image PrintWindow()
/// <param name="hWnd">The Window Handle</param> /// <param name="hWnd">The Window Handle</param>
public WindowDetails(IntPtr hWnd) public WindowDetails(IntPtr hWnd)
{ {
this.hWnd = hWnd; this._hWnd = hWnd;
} }
/// <summary> /// <summary>
@ -1734,7 +1773,7 @@ public static WindowDetails GetActiveWindow()
IntPtr hWnd = User32.GetForegroundWindow(); IntPtr hWnd = User32.GetForegroundWindow();
if (hWnd != null && hWnd != IntPtr.Zero) if (hWnd != null && hWnd != IntPtr.Zero)
{ {
if (ignoreHandles.Contains(hWnd)) if (IgnoreHandles.Contains(hWnd))
{ {
return GetDesktopWindow(); return GetDesktopWindow();
} }
@ -1759,7 +1798,7 @@ public bool IsGreenshot
{ {
try try
{ {
if (!isMetroApp) if (!IsMetroApp)
{ {
using (Process thisWindowProcess = Process) using (Process thisWindowProcess = Process)
{ {
@ -1796,7 +1835,7 @@ public static List<WindowDetails> GetAllWindows()
/// <summary> /// <summary>
/// Get all the top level windows, with matching classname /// Get all the top level windows, with matching classname
/// </summary> /// </summary>
/// <returns>List<WindowDetails> with all the top level windows</returns> /// <returns>List WindowDetails with all the top level windows</returns>
public static List<WindowDetails> GetAllWindows(string classname) public static List<WindowDetails> GetAllWindows(string classname)
{ {
return new WindowsEnumerator().GetWindows(IntPtr.Zero, classname).Items; return new WindowsEnumerator().GetWindows(IntPtr.Zero, classname).Items;
@ -1805,7 +1844,6 @@ public static List<WindowDetails> GetAllWindows(string classname)
/// <summary> /// <summary>
/// Recursive "find children which" /// Recursive "find children which"
/// </summary> /// </summary>
/// <param name="window">Window to look into</param>
/// <param name="point">point to check for</param> /// <param name="point">point to check for</param>
/// <returns></returns> /// <returns></returns>
public WindowDetails FindChildUnderPoint(Point point) public WindowDetails FindChildUnderPoint(Point point)
@ -1839,7 +1877,7 @@ public static string GetClassName(IntPtr hWnd)
/// <summary> /// <summary>
/// Get all the visible top level windows /// Get all the visible top level windows
/// </summary> /// </summary>
/// <returns>List<WindowDetails> with all the visible top level windows</returns> /// <returns>List WindowDetails with all the visible top level windows</returns>
public static List<WindowDetails> GetVisibleWindows() public static List<WindowDetails> GetVisibleWindows()
{ {
List<WindowDetails> windows = new List<WindowDetails>(); List<WindowDetails> windows = new List<WindowDetails>();
@ -1859,7 +1897,7 @@ public static List<WindowDetails> GetVisibleWindows()
continue; continue;
} }
// Ignore some classes // Ignore some classes
List<string> ignoreClasses = new List<string>(new string[] { "Progman", "XLMAIN", "Button", "Dwm" }); //"MS-SDIa" List<string> ignoreClasses = new List<string>(new[] { "Progman", "XLMAIN", "Button", "Dwm" }); //"MS-SDIa"
if (ignoreClasses.Contains(window.ClassName)) if (ignoreClasses.Contains(window.ClassName))
{ {
continue; continue;
@ -1880,7 +1918,7 @@ public static List<WindowDetails> GetVisibleWindows()
/// Get the WindowDetails for all Metro Apps /// Get the WindowDetails for all Metro Apps
/// These are all Windows with Classname "Windows.UI.Core.CoreWindow" /// These are all Windows with Classname "Windows.UI.Core.CoreWindow"
/// </summary> /// </summary>
/// <returns>List<WindowDetails> with visible metro apps</returns> /// <returns>List WindowDetails with visible metro apps</returns>
public static List<WindowDetails> GetMetroApps() public static List<WindowDetails> GetMetroApps()
{ {
List<WindowDetails> metroApps = new List<WindowDetails>(); List<WindowDetails> metroApps = new List<WindowDetails>();
@ -1939,7 +1977,7 @@ public static List<WindowDetails> GetTopLevelWindows()
continue; continue;
} }
// Ignore some classes // Ignore some classes
List<string> ignoreClasses = new List<string>(new string[] { "Progman", "XLMAIN", "Button", "Dwm" }); //"MS-SDIa" List<string> ignoreClasses = new List<string>(new[] { "Progman", "XLMAIN", "Button", "Dwm" }); //"MS-SDIa"
if (ignoreClasses.Contains(window.ClassName)) if (ignoreClasses.Contains(window.ClassName))
{ {
continue; continue;
@ -2020,7 +2058,7 @@ public static WindowDetails GetLinkedWindow(WindowDetails windowToLinkTo)
/// Helper method to "active" all windows that are not in the supplied list. /// Helper method to "active" all windows that are not in the supplied list.
/// One should preferably call "GetVisibleWindows" for the oldWindows. /// One should preferably call "GetVisibleWindows" for the oldWindows.
/// </summary> /// </summary>
/// <param name="oldWindows">List<WindowDetails> with old windows</param> /// <param name="oldWindows">List WindowDetails with old windows</param>
public static void ActiveNewerWindows(List<WindowDetails> oldWindows) public static void ActiveNewerWindows(List<WindowDetails> oldWindows)
{ {
List<WindowDetails> windowsAfter = GetVisibleWindows(); List<WindowDetails> windowsAfter = GetVisibleWindows();

View file

@ -89,7 +89,7 @@ public override void Draw(Graphics graphics, RenderMode rm)
Top + currentStep + Height); Top + currentStep + Height);
currentStep++; currentStep++;
alpha = alpha - (basealpha / steps); alpha = alpha - basealpha / steps;
} }
} }
} }

View file

@ -50,10 +50,8 @@ public abstract class DrawableContainer : AbstractFieldHolderWithChildren, IDraw
protected static readonly Color DefaultLineColor = Color.FromArgb(0, 150, 255); protected static readonly Color DefaultLineColor = Color.FromArgb(0, 150, 255);
private bool isMadeUndoable; private bool _isMadeUndoable;
private const int M11 = 0; private const int M11 = 0;
private const int M12 = 1;
private const int M21 = 2;
private const int M22 = 3; private const int M22 = 3;
protected EditStatus _defaultEditMode = EditStatus.DRAWING; protected EditStatus _defaultEditMode = EditStatus.DRAWING;
@ -383,7 +381,7 @@ public void AlignToParent(HorizontalAlignment horizontalAlignment, VerticalAlign
} }
if (horizontalAlignment == HorizontalAlignment.Center) if (horizontalAlignment == HorizontalAlignment.Center)
{ {
Left = (_parent.Width / 2) - (Width / 2) - lineThickness / 2; Left = _parent.Width / 2 - Width / 2 - lineThickness / 2;
} }
if (verticalAlignment == VerticalAlignment.TOP) if (verticalAlignment == VerticalAlignment.TOP)
@ -396,7 +394,7 @@ public void AlignToParent(HorizontalAlignment horizontalAlignment, VerticalAlign
} }
if (verticalAlignment == VerticalAlignment.CENTER) if (verticalAlignment == VerticalAlignment.CENTER)
{ {
Top = (_parent.Height / 2) - (Height / 2) - lineThickness / 2; Top = _parent.Height / 2 - Height / 2 - lineThickness / 2;
} }
} }
@ -569,7 +567,7 @@ private void GripperMouseDown(object sender, MouseEventArgs e)
{ {
Status = EditStatus.MOVING; Status = EditStatus.MOVING;
} }
isMadeUndoable = false; _isMadeUndoable = false;
} }
private void GripperMouseUp(object sender, MouseEventArgs e) private void GripperMouseUp(object sender, MouseEventArgs e)
@ -579,7 +577,7 @@ private void GripperMouseUp(object sender, MouseEventArgs e)
{ {
_boundsBeforeResize = Rectangle.Empty; _boundsBeforeResize = Rectangle.Empty;
_boundsAfterResize = RectangleF.Empty; _boundsAfterResize = RectangleF.Empty;
isMadeUndoable = false; _isMadeUndoable = false;
} }
Status = EditStatus.IDLE; Status = EditStatus.IDLE;
Invalidate(); Invalidate();
@ -598,10 +596,10 @@ private void GripperMouseMove(object sender, MouseEventArgs e)
else if (Status.Equals(EditStatus.RESIZING)) else if (Status.Equals(EditStatus.RESIZING))
{ {
// check if we already made this undoable // check if we already made this undoable
if (!isMadeUndoable) if (!_isMadeUndoable)
{ {
// don't allow another undo until we are finished with this move // don't allow another undo until we are finished with this move
isMadeUndoable = true; _isMadeUndoable = true;
// Make undo-able // Make undo-able
MakeBoundsChangeUndoable(false); MakeBoundsChangeUndoable(false);
} }
@ -871,6 +869,8 @@ public override bool Equals(object obj)
public override int GetHashCode() public override int GetHashCode()
{ {
// TODO: This actually doesn't make sense...
// Place the container in a list, and you can't find it :)
return left.GetHashCode() ^ top.GetHashCode() ^ width.GetHashCode() ^ height.GetHashCode() ^ GetFields().GetHashCode(); return left.GetHashCode() ^ top.GetHashCode() ^ width.GetHashCode() ^ height.GetHashCode() ^ GetFields().GetHashCode();
} }

View file

@ -383,7 +383,7 @@ public void PullElementsUp(DrawableContainerList elements)
{ {
continue; continue;
} }
if (Count > (i + 1) && !elements.Contains(this[i + 1])) if (Count > i + 1 && !elements.Contains(this[i + 1]))
{ {
SwapElements(i, i + 1); SwapElements(i, i + 1);
} }
@ -554,7 +554,7 @@ public virtual void AddContextMenuItems(ContextMenuStrip menu, Surface surface)
// Copy // Copy
item = new ToolStripMenuItem("Copy"); item = new ToolStripMenuItem("Copy");
item.Image = ((Image)(editorFormResources.GetObject("copyToolStripMenuItem.Image"))); item.Image = (Image)editorFormResources.GetObject("copyToolStripMenuItem.Image");
item.Click += delegate item.Click += delegate
{ {
ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), this); ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), this);
@ -563,7 +563,7 @@ public virtual void AddContextMenuItems(ContextMenuStrip menu, Surface surface)
// Cut // Cut
item = new ToolStripMenuItem("Cut"); item = new ToolStripMenuItem("Cut");
item.Image = ((Image)(editorFormResources.GetObject("btnCut.Image"))); item.Image = (Image)editorFormResources.GetObject("btnCut.Image");
item.Click += delegate item.Click += delegate
{ {
ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), this); ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), this);
@ -582,7 +582,7 @@ public virtual void AddContextMenuItems(ContextMenuStrip menu, Surface surface)
// Delete // Delete
item = new ToolStripMenuItem("Delete"); item = new ToolStripMenuItem("Delete");
item.Image = ((Image)(editorFormResources.GetObject("removeObjectToolStripMenuItem.Image"))); item.Image = (Image)editorFormResources.GetObject("removeObjectToolStripMenuItem.Image");
item.Click += delegate item.Click += delegate
{ {
List<DrawableContainer> containersToDelete = new List<DrawableContainer>(); List<DrawableContainer> containersToDelete = new List<DrawableContainer>();

View file

@ -65,11 +65,16 @@ public override void Draw(Graphics graphics, RenderMode renderMode)
/// This allows another container to draw an ellipse /// This allows another container to draw an ellipse
/// </summary> /// </summary>
/// <param name="caller"></param> /// <param name="caller"></param>
/// <param name="rect"></param>
/// <param name="graphics"></param> /// <param name="graphics"></param>
/// <param name="renderMode"></param> /// <param name="renderMode"></param>
/// <param name="lineThickness"></param>
/// <param name="lineColor"></param>
/// <param name="fillColor"></param>
/// <param name="shadow"></param>
public static void DrawEllipse(Rectangle rect, Graphics graphics, RenderMode renderMode, int lineThickness, Color lineColor, Color fillColor, bool shadow) public static void DrawEllipse(Rectangle rect, Graphics graphics, RenderMode renderMode, int lineThickness, Color lineColor, Color fillColor, bool shadow)
{ {
bool lineVisible = (lineThickness > 0 && Colors.IsVisible(lineColor)); bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor);
// draw shadow before anything else // draw shadow before anything else
if (shadow && (lineVisible || Colors.IsVisible(fillColor))) if (shadow && (lineVisible || Colors.IsVisible(fillColor)))
{ {

View file

@ -35,7 +35,7 @@ namespace Greenshot.Drawing.Fields
[Serializable] [Serializable]
public abstract class AbstractFieldHolder : IFieldHolder public abstract class AbstractFieldHolder : IFieldHolder
{ {
private static EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>(); private static readonly EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
/// <summary> /// <summary>
/// called when a field's value has changed /// called when a field's value has changed
@ -52,11 +52,7 @@ public abstract class AbstractFieldHolder : IFieldHolder
// this allows us to use default serialization // this allows us to use default serialization
[NonSerialized] [NonSerialized]
private Dictionary<FieldType, Field> fieldsByType = new Dictionary<FieldType, Field>(); private Dictionary<FieldType, Field> fieldsByType = new Dictionary<FieldType, Field>();
private List<Field> fields = new List<Field>(); private readonly List<Field> fields = new List<Field>();
public AbstractFieldHolder()
{
}
[OnDeserialized] [OnDeserialized]
private void OnDeserialized(StreamingContext context) private void OnDeserialized(StreamingContext context)

View file

@ -33,7 +33,7 @@ namespace Greenshot.Drawing.Fields
[Serializable()] [Serializable()]
public abstract class AbstractFieldHolderWithChildren : AbstractFieldHolder public abstract class AbstractFieldHolderWithChildren : AbstractFieldHolder
{ {
private FieldChangedEventHandler fieldChangedEventHandler; private readonly FieldChangedEventHandler fieldChangedEventHandler;
[NonSerialized] [NonSerialized]
private EventHandler childrenChanged; private EventHandler childrenChanged;

View file

@ -28,10 +28,6 @@ namespace Greenshot.Drawing.Fields.Binding
/// </summary> /// </summary>
public abstract class AbstractBindingConverter<T1, T2> : IBindingConverter public abstract class AbstractBindingConverter<T1, T2> : IBindingConverter
{ {
public AbstractBindingConverter()
{
}
public object convert(object o) public object convert(object o)
{ {
if (o == null) if (o == null)

View file

@ -32,14 +32,14 @@ namespace Greenshot.Drawing.Fields.Binding
/// </summary> /// </summary>
public class BidirectionalBinding public class BidirectionalBinding
{ {
private INotifyPropertyChanged controlObject; private readonly INotifyPropertyChanged _controlObject;
private INotifyPropertyChanged fieldObject; private readonly INotifyPropertyChanged _fieldObject;
private string controlPropertyName; private readonly string _controlPropertyName;
private string fieldPropertyName; private readonly string _fieldPropertyName;
private bool updatingControl = false; private bool _updatingControl = false;
private bool updatingField = false; private bool _updatingField = false;
private IBindingConverter converter; private IBindingConverter _converter;
private IBindingValidator validator; private readonly IBindingValidator _validator;
/// <summary> /// <summary>
/// Whether or not null values are passed on to the other object. /// Whether or not null values are passed on to the other object.
@ -49,19 +49,19 @@ public class BidirectionalBinding
/// <summary> /// <summary>
/// Bind properties of two objects bidirectionally /// Bind properties of two objects bidirectionally
/// </summary> /// </summary>
/// <param name="object1">Object containing 1st property to bind</param> /// <param name="controlObject">Object containing 1st property to bind</param>
/// <param name="property1">Property of 1st object to bind</param> /// <param name="controlPropertyName">Property of 1st object to bind</param>
/// <param name="object2">Object containing 2nd property to bind</param> /// <param name="fieldObject">Object containing 2nd property to bind</param>
/// <param name="property2">Property of 2nd object to bind</param> /// <param name="fieldPropertyName">Property of 2nd object to bind</param>
public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName) public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName)
{ {
this.controlObject = controlObject; _controlObject = controlObject;
this.fieldObject = fieldObject; _fieldObject = fieldObject;
this.controlPropertyName = controlPropertyName; _controlPropertyName = controlPropertyName;
this.fieldPropertyName = fieldPropertyName; _fieldPropertyName = fieldPropertyName;
this.controlObject.PropertyChanged += ControlPropertyChanged; _controlObject.PropertyChanged += ControlPropertyChanged;
this.fieldObject.PropertyChanged += FieldPropertyChanged; _fieldObject.PropertyChanged += FieldPropertyChanged;
} }
/// <summary> /// <summary>
@ -74,7 +74,7 @@ public BidirectionalBinding(INotifyPropertyChanged controlObject, string control
/// <param name="converter">taking care of converting the synchronized value to the correct target format and back</param> /// <param name="converter">taking care of converting the synchronized value to the correct target format and back</param>
public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName, IBindingConverter converter) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName) public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName, IBindingConverter converter) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName)
{ {
this.converter = converter; _converter = converter;
} }
/// <summary> /// <summary>
@ -88,7 +88,7 @@ public BidirectionalBinding(INotifyPropertyChanged controlObject, string control
/// <param name="validator">validator to intercept synchronization if the value does not match certain criteria</param> /// <param name="validator">validator to intercept synchronization if the value does not match certain criteria</param>
public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName, IBindingValidator validator) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName) public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName, IBindingValidator validator) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName)
{ {
this.validator = validator; _validator = validator;
} }
/// <summary> /// <summary>
@ -103,56 +103,56 @@ public BidirectionalBinding(INotifyPropertyChanged controlObject, string control
/// <param name="validator">validator to intercept synchronization if the value does not match certain criteria</param> /// <param name="validator">validator to intercept synchronization if the value does not match certain criteria</param>
public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName, IBindingConverter converter, IBindingValidator validator) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName, converter) public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName, IBindingConverter converter, IBindingValidator validator) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName, converter)
{ {
this.validator = validator; _validator = validator;
} }
public void ControlPropertyChanged(object sender, PropertyChangedEventArgs e) public void ControlPropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
if (!updatingControl && e.PropertyName.Equals(controlPropertyName)) if (!_updatingControl && e.PropertyName.Equals(_controlPropertyName))
{ {
updatingField = true; _updatingField = true;
synchronize(controlObject, controlPropertyName, fieldObject, fieldPropertyName); Synchronize(_controlObject, _controlPropertyName, _fieldObject, _fieldPropertyName);
updatingField = false; _updatingField = false;
} }
} }
public void FieldPropertyChanged(object sender, PropertyChangedEventArgs e) public void FieldPropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
if (!updatingField && e.PropertyName.Equals(fieldPropertyName)) if (!_updatingField && e.PropertyName.Equals(_fieldPropertyName))
{ {
updatingControl = true; _updatingControl = true;
synchronize(fieldObject, fieldPropertyName, controlObject, controlPropertyName); Synchronize(_fieldObject, _fieldPropertyName, _controlObject, _controlPropertyName);
updatingControl = false; _updatingControl = false;
} }
} }
private void synchronize(INotifyPropertyChanged sourceObject, string sourceProperty, INotifyPropertyChanged targetObject, string targetProperty) private void Synchronize(INotifyPropertyChanged sourceObject, string sourceProperty, INotifyPropertyChanged targetObject, string targetProperty)
{ {
PropertyInfo targetPropertyInfo = resolvePropertyInfo(targetObject, targetProperty); PropertyInfo targetPropertyInfo = ResolvePropertyInfo(targetObject, targetProperty);
PropertyInfo sourcePropertyInfo = resolvePropertyInfo(sourceObject, sourceProperty); PropertyInfo sourcePropertyInfo = ResolvePropertyInfo(sourceObject, sourceProperty);
if (sourcePropertyInfo != null && targetPropertyInfo != null && targetPropertyInfo.CanWrite) if (sourcePropertyInfo != null && targetPropertyInfo != null && targetPropertyInfo.CanWrite)
{ {
object bValue = sourcePropertyInfo.GetValue(sourceObject, null); object bValue = sourcePropertyInfo.GetValue(sourceObject, null);
if (converter != null && bValue != null) if (_converter != null && bValue != null)
{ {
bValue = converter.convert(bValue); bValue = _converter.convert(bValue);
} }
try try
{ {
if (validator == null || validator.validate(bValue)) if (_validator == null || _validator.validate(bValue))
{ {
targetPropertyInfo.SetValue(targetObject, bValue, null); targetPropertyInfo.SetValue(targetObject, bValue, null);
} }
} }
catch (Exception e) catch (Exception e)
{ {
throw new MemberAccessException("Could not set property '" + targetProperty + "' to '" + bValue + "' [" + ((bValue != null) ? bValue.GetType().Name : "") + "] on " + targetObject + ". Probably other type than expected, IBindingCoverter to the rescue.", e); throw new MemberAccessException("Could not set property '" + targetProperty + "' to '" + bValue + "' [" + (bValue != null ? bValue.GetType().Name : "") + "] on " + targetObject + ". Probably other type than expected, IBindingCoverter to the rescue.", e);
} }
} }
} }
private PropertyInfo resolvePropertyInfo(object obj, string property) private static PropertyInfo ResolvePropertyInfo(object obj, string property)
{ {
PropertyInfo ret = null; PropertyInfo ret = null;
string[] properties = property.Split(".".ToCharArray()); string[] properties = property.Split(".".ToCharArray());
@ -170,8 +170,8 @@ private PropertyInfo resolvePropertyInfo(object obj, string property)
public IBindingConverter Converter public IBindingConverter Converter
{ {
get { return converter; } get { return _converter; }
set { converter = value; } set { _converter = value; }
} }
} }
} }

View file

@ -40,13 +40,10 @@ namespace Greenshot.Drawing.Fields
/// </summary> /// </summary>
public class FieldAggregator : AbstractFieldHolder public class FieldAggregator : AbstractFieldHolder
{ {
private List<IDrawableContainer> boundContainers; private readonly List<IDrawableContainer> boundContainers;
private bool internalUpdateRunning = false; private bool internalUpdateRunning;
private enum Status private static readonly EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
{ IDLE, BINDING, UPDATING };
private static EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
public FieldAggregator() public FieldAggregator()
{ {

View file

@ -58,7 +58,7 @@ public override void Draw(Graphics graphics, RenderMode rm)
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
bool lineVisible = (lineThickness > 0 && Colors.IsVisible(lineColor)); bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor);
if (lineVisible) if (lineVisible)
{ {
graphics.SmoothingMode = SmoothingMode.HighSpeed; graphics.SmoothingMode = SmoothingMode.HighSpeed;
@ -79,7 +79,7 @@ public override void Draw(Graphics graphics, RenderMode rm)
Rectangle shadowRect = GuiRectangle.GetGuiRectangle(Left + currentStep, Top + currentStep, Width, Height); Rectangle shadowRect = GuiRectangle.GetGuiRectangle(Left + currentStep, Top + currentStep, Width, Height);
graphics.DrawRectangle(shadowPen, shadowRect); graphics.DrawRectangle(shadowPen, shadowRect);
currentStep++; currentStep++;
alpha = alpha - (basealpha / steps); alpha = alpha - basealpha / steps;
} }
} }
} }

View file

@ -43,7 +43,7 @@ public abstract class AbstractFilter : AbstractFieldHolder, IFilter
remove { propertyChanged -= value; } remove { propertyChanged -= value; }
} }
private bool invert = false; private bool invert;
public bool Invert public bool Invert
{ {
get get

View file

@ -45,7 +45,7 @@ public BlurFilter(DrawableContainer parent) : base(parent)
AddField(GetType(), FieldType.PREVIEW_QUALITY, 1.0d); AddField(GetType(), FieldType.PREVIEW_QUALITY, 1.0d);
} }
public unsafe override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
{ {
int blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS); int blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS);
Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert); Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);
@ -59,7 +59,7 @@ public unsafe override void Apply(Graphics graphics, Bitmap applyBitmap, Rectang
graphics.SetClip(applyRect); graphics.SetClip(applyRect);
graphics.ExcludeClip(rect); graphics.ExcludeClip(rect);
} }
if (GDIplus.isBlurPossible(blurRadius)) if (GDIplus.IsBlurPossible(blurRadius))
{ {
GDIplus.DrawWithBlur(graphics, applyBitmap, applyRect, null, null, blurRadius, false); GDIplus.DrawWithBlur(graphics, applyBitmap, applyRect, null, null, blurRadius, false);
} }
@ -72,7 +72,6 @@ public unsafe override void Apply(Graphics graphics, Bitmap applyBitmap, Rectang
} }
} }
graphics.Restore(state); graphics.Restore(state);
return;
} }
} }
} }

View file

@ -60,7 +60,7 @@ public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect
int halfHeight = rect.Height / 2; int halfHeight = rect.Height / 2;
int newWidth = rect.Width / magnificationFactor; int newWidth = rect.Width / magnificationFactor;
int newHeight = rect.Height / magnificationFactor; int newHeight = rect.Height / magnificationFactor;
Rectangle source = new Rectangle(rect.X + halfWidth - (newWidth / 2), rect.Y + halfHeight - (newHeight / 2), newWidth, newHeight); Rectangle source = new Rectangle(rect.X + halfWidth - newWidth / 2, rect.Y + halfHeight - newHeight / 2, newWidth, newHeight);
graphics.DrawImage(applyBitmap, rect, source, GraphicsUnit.Pixel); graphics.DrawImage(applyBitmap, rect, source, GraphicsUnit.Pixel);
graphics.Restore(state); graphics.Restore(state);
} }

View file

@ -40,7 +40,7 @@ public PixelizationFilter(DrawableContainer parent) : base(parent)
public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
{ {
int pixelSize = GetFieldValueAsInt(FieldType.PIXEL_SIZE); int pixelSize = GetFieldValueAsInt(FieldType.PIXEL_SIZE);
Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert); ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);
if (pixelSize <= 1 || rect.Width == 0 || rect.Height == 0) if (pixelSize <= 1 || rect.Width == 0 || rect.Height == 0)
{ {
// Nothing to do // Nothing to do

View file

@ -42,8 +42,8 @@ public class FreehandContainer : DrawableContainer
private GraphicsPath freehandPath = new GraphicsPath(); private GraphicsPath freehandPath = new GraphicsPath();
private Rectangle myBounds = Rectangle.Empty; private Rectangle myBounds = Rectangle.Empty;
private Point lastMouse = Point.Empty; private Point lastMouse = Point.Empty;
private List<Point> capturePoints = new List<Point>(); private readonly List<Point> capturePoints = new List<Point>();
private bool isRecalculated = false; private bool isRecalculated;
/// <summary> /// <summary>
/// Constructor /// Constructor
@ -130,7 +130,7 @@ public override bool HandleMouseMove(int mouseX, int mouseY)
{ {
Point previousPoint = capturePoints[capturePoints.Count - 1]; Point previousPoint = capturePoints[capturePoints.Count - 1];
if (GeometryHelper.Distance2D(previousPoint.X, previousPoint.Y, mouseX, mouseY) >= (2 * EditorConfig.FreehandSensitivity)) if (GeometryHelper.Distance2D(previousPoint.X, previousPoint.Y, mouseX, mouseY) >= 2 * EditorConfig.FreehandSensitivity)
{ {
capturePoints.Add(new Point(mouseX, mouseY)); capturePoints.Add(new Point(mouseX, mouseY));
} }
@ -263,7 +263,7 @@ public override Rectangle DrawingBounds
{ {
int lineThickness = Math.Max(10, GetFieldValueAsInt(FieldType.LINE_THICKNESS)); int lineThickness = Math.Max(10, GetFieldValueAsInt(FieldType.LINE_THICKNESS));
int safetymargin = 10; int safetymargin = 10;
return new Rectangle((myBounds.Left + Left) - (safetymargin + lineThickness), (myBounds.Top + Top) - (safetymargin + lineThickness), myBounds.Width + (2 * (lineThickness + safetymargin)), myBounds.Height + (2 * (lineThickness + safetymargin))); return new Rectangle(myBounds.Left + Left - (safetymargin + lineThickness), myBounds.Top + Top - (safetymargin + lineThickness), myBounds.Width + 2 * (lineThickness + safetymargin), myBounds.Height + 2 * (lineThickness + safetymargin));
} }
return new Rectangle(0, 0, _parent.Width, _parent.Height); return new Rectangle(0, 0, _parent.Width, _parent.Height);
} }

View file

@ -99,7 +99,7 @@ public override void Draw(Graphics graphics, RenderMode rm)
Top + currentStep + Height); Top + currentStep + Height);
currentStep++; currentStep++;
alpha = alpha - (basealpha / steps); alpha = alpha - basealpha / steps;
} }
} }
} }

View file

@ -74,7 +74,7 @@ public static void DrawRectangle(Rectangle rect, Graphics graphics, RenderMode r
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.None; graphics.PixelOffsetMode = PixelOffsetMode.None;
bool lineVisible = (lineThickness > 0 && Colors.IsVisible(lineColor)); bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor);
if (shadow && (lineVisible || Colors.IsVisible(fillColor))) if (shadow && (lineVisible || Colors.IsVisible(fillColor)))
{ {
//draw shadow first //draw shadow first
@ -94,7 +94,7 @@ public static void DrawRectangle(Rectangle rect, Graphics graphics, RenderMode r
rect.Height); rect.Height);
graphics.DrawRectangle(shadowPen, shadowRect); graphics.DrawRectangle(shadowPen, shadowRect);
currentStep++; currentStep++;
alpha = alpha - (basealpha / steps); alpha = alpha - basealpha / steps;
} }
} }
} }

View file

@ -200,7 +200,7 @@ private GraphicsPath CreateTail()
{ {
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top); int tailLength = GeometryHelper.Distance2D(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, TargetGripper.Left, TargetGripper.Top);
int tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20; int tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20;
// This should fix a problem with the tail being to wide // This should fix a problem with the tail being to wide
@ -212,11 +212,11 @@ private GraphicsPath CreateTail()
tail.AddLine(tailWidth, 0, 0, -tailLength); tail.AddLine(tailWidth, 0, 0, -tailLength);
tail.CloseFigure(); tail.CloseFigure();
int tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top); int tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, TargetGripper.Left, TargetGripper.Top);
using (Matrix tailMatrix = new Matrix()) using (Matrix tailMatrix = new Matrix())
{ {
tailMatrix.Translate(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2)); tailMatrix.Translate(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2);
tailMatrix.Rotate(tailAngle); tailMatrix.Rotate(tailAngle);
tail.Transform(tailMatrix); tail.Transform(tailMatrix);
} }
@ -246,7 +246,7 @@ public override void Draw(Graphics graphics, RenderMode renderMode)
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
bool lineVisible = (lineThickness > 0 && Colors.IsVisible(lineColor)); bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor);
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
if (Selected && renderMode == RenderMode.EDIT) if (Selected && renderMode == RenderMode.EDIT)
@ -281,7 +281,7 @@ public override void Draw(Graphics graphics, RenderMode renderMode)
graphics.DrawPath(shadowPen, bubbleClone); graphics.DrawPath(shadowPen, bubbleClone);
} }
currentStep++; currentStep++;
alpha = alpha - (basealpha / steps); alpha = alpha - basealpha / steps;
} }
} }
} }

View file

@ -136,7 +136,7 @@ public override bool InitContent()
/// </summary> /// </summary>
public override bool HandleMouseDown(int mouseX, int mouseY) public override bool HandleMouseDown(int mouseX, int mouseY)
{ {
return base.HandleMouseDown(mouseX - (Width / 2), mouseY - (Height / 2)); return base.HandleMouseDown(mouseX - Width / 2, mouseY - Height / 2);
} }
/// <summary> /// <summary>
@ -169,8 +169,8 @@ protected override void Dispose(bool disposing)
public override bool HandleMouseMove(int x, int y) public override bool HandleMouseMove(int x, int y)
{ {
Invalidate(); Invalidate();
Left = x - (Width / 2); Left = x - Width / 2;
Top = y - (Height / 2); Top = y - Height / 2;
Invalidate(); Invalidate();
return true; return true;
} }
@ -191,7 +191,7 @@ public override void Transform(Matrix matrix)
int widthAfter = rect.Width; int widthAfter = rect.Width;
int heightAfter = rect.Height; int heightAfter = rect.Height;
float factor = (((float)widthAfter / widthBefore) + ((float)heightAfter / heightBefore)) / 2; float factor = ((float)widthAfter / widthBefore + (float)heightAfter / heightBefore) / 2;
fontSize *= factor; fontSize *= factor;
} }

View file

@ -46,8 +46,8 @@ namespace Greenshot.Drawing
/// </summary> /// </summary>
public class Surface : Control, ISurface public class Surface : Control, ISurface
{ {
public static int Count = 0; public static int Count;
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
// Property to identify the Surface ID // Property to identify the Surface ID
private Guid _uniqueId = Guid.NewGuid(); private Guid _uniqueId = Guid.NewGuid();
@ -183,7 +183,7 @@ public Guid ID
/// all selected elements, do not serialize /// all selected elements, do not serialize
/// </summary> /// </summary>
[NonSerialized] [NonSerialized]
private DrawableContainerList selectedElements; private readonly DrawableContainerList selectedElements;
/// <summary> /// <summary>
/// the element we are drawing with, do not serialize /// the element we are drawing with, do not serialize
@ -222,7 +222,7 @@ public Guid ID
/// <summary> /// <summary>
/// all stepLabels for the surface, needed with serialization /// all stepLabels for the surface, needed with serialization
/// </summary> /// </summary>
private List<StepLabelContainer> _stepLabels = new List<StepLabelContainer>(); private readonly List<StepLabelContainer> _stepLabels = new List<StepLabelContainer>();
public void AddStepLabel(StepLabelContainer stepLabel) public void AddStepLabel(StepLabelContainer stepLabel)
{ {
@ -244,7 +244,7 @@ public int CountStepLabels(IDrawableContainer stopAtContainer)
int number = 1; int number = 1;
foreach (var possibleThis in _stepLabels) foreach (var possibleThis in _stepLabels)
{ {
if (possibleThis == stopAtContainer) if (possibleThis.Equals(stopAtContainer))
{ {
break; break;
} }
@ -1180,7 +1180,10 @@ private void SurfaceMouseDown(object sender, MouseEventArgs e)
// if a new element has been drawn, set location and register it // if a new element has been drawn, set location and register it
if (_drawingElement != null) if (_drawingElement != null)
{ {
_drawingElement.Status = _undrawnElement.DefaultEditMode; if (_undrawnElement != null)
{
_drawingElement.Status = _undrawnElement.DefaultEditMode;
}
_drawingElement.PropertyChanged += ElementPropertyChanged; _drawingElement.PropertyChanged += ElementPropertyChanged;
if (!_drawingElement.HandleMouseDown(_mouseStart.X, _mouseStart.Y)) if (!_drawingElement.HandleMouseDown(_mouseStart.X, _mouseStart.Y))
{ {
@ -1540,7 +1543,7 @@ public bool HasSelectedElements
{ {
get get
{ {
return (selectedElements != null && selectedElements.Count > 0); return selectedElements != null && selectedElements.Count > 0;
} }
} }
@ -1606,6 +1609,10 @@ public void ConfirmSelectedConfirmableElements(bool confirm)
{ {
// create new collection so that we can iterate safely (selectedElements might change due with confirm/cancel) // create new collection so that we can iterate safely (selectedElements might change due with confirm/cancel)
List<IDrawableContainer> selectedDCs = new List<IDrawableContainer>(selectedElements); List<IDrawableContainer> selectedDCs = new List<IDrawableContainer>(selectedElements);
if (_cropContainer == null)
{
return;
}
foreach (IDrawableContainer dc in selectedDCs) foreach (IDrawableContainer dc in selectedDCs)
{ {
if (dc.Equals(_cropContainer)) if (dc.Equals(_cropContainer))
@ -1619,6 +1626,7 @@ public void ConfirmSelectedConfirmableElements(bool confirm)
} }
_cropContainer.Dispose(); _cropContainer.Dispose();
_cropContainer = null; _cropContainer = null;
break;
} }
} }
} }
@ -1652,7 +1660,7 @@ public void PasteElementFromClipboard()
{ {
// Make element(s) only move 10,10 if the surface is the same // Make element(s) only move 10,10 if the surface is the same
Point moveOffset; Point moveOffset;
bool isSameSurface = (dcs.ParentID == _uniqueId); bool isSameSurface = dcs.ParentID == _uniqueId;
dcs.Parent = this; dcs.Parent = this;
if (isSameSurface) if (isSameSurface)
{ {

View file

@ -77,7 +77,7 @@ public string Text
internal void ChangeText(string newText, bool allowUndoable) internal void ChangeText(string newText, bool allowUndoable)
{ {
if ((text == null && newText != null) || (text != null && !text.Equals(newText))) if ((text == null && newText != null) || (text != null && !string.Equals(text, newText)))
{ {
if (makeUndoable && allowUndoable) if (makeUndoable && allowUndoable)
{ {
@ -139,8 +139,10 @@ protected override void Dispose(bool disposing)
private void Init() private void Init()
{ {
_stringFormat = new StringFormat(); _stringFormat = new StringFormat
_stringFormat.Trimming = StringTrimming.EllipsisWord; {
Trimming = StringTrimming.EllipsisWord
};
CreateTextBox(); CreateTextBox();
@ -208,8 +210,11 @@ private void TextContainer_FieldChanged(object sender, FieldChangedEventArgs e)
// Only dispose the font, and re-create it, when a font field has changed. // Only dispose the font, and re-create it, when a font field has changed.
if (e.Field.FieldType.Name.StartsWith("FONT")) if (e.Field.FieldType.Name.StartsWith("FONT"))
{ {
_font.Dispose(); if (_font != null)
_font = null; {
_font.Dispose();
_font = null;
}
UpdateFormat(); UpdateFormat();
} }
else else
@ -218,7 +223,7 @@ private void TextContainer_FieldChanged(object sender, FieldChangedEventArgs e)
} }
UpdateTextBoxFormat(); UpdateTextBoxFormat();
if (_textBox.Visible) if (_textBox != null && _textBox.Visible)
{ {
_textBox.Invalidate(); _textBox.Invalidate();
} }
@ -231,17 +236,19 @@ public override void OnDoubleClick()
private void CreateTextBox() private void CreateTextBox()
{ {
_textBox = new TextBox(); _textBox = new TextBox
{
ImeMode = ImeMode.On,
Multiline = true,
AcceptsTab = true,
AcceptsReturn = true,
BorderStyle = BorderStyle.None,
Visible = false
};
_textBox.ImeMode = ImeMode.On;
_textBox.Multiline = true;
_textBox.AcceptsTab = true;
_textBox.AcceptsReturn = true;
_textBox.DataBindings.Add("Text", this, "Text", false, DataSourceUpdateMode.OnPropertyChanged); _textBox.DataBindings.Add("Text", this, "Text", false, DataSourceUpdateMode.OnPropertyChanged);
_textBox.LostFocus += textBox_LostFocus; _textBox.LostFocus += textBox_LostFocus;
_textBox.KeyDown += textBox_KeyDown; _textBox.KeyDown += textBox_KeyDown;
_textBox.BorderStyle = BorderStyle.None;
_textBox.Visible = false;
} }
private void ShowTextBox() private void ShowTextBox()
@ -348,6 +355,7 @@ protected void UpdateFormat()
} }
} }
} }
_font?.Dispose();
_font = new Font(fam, fontSize, fs, GraphicsUnit.Pixel); _font = new Font(fam, fontSize, fs, GraphicsUnit.Pixel);
_textBox.Font = _font; _textBox.Font = _font;
} }
@ -392,8 +400,8 @@ private void UpdateTextBoxPosition()
{ {
lineWidth = 0; lineWidth = 0;
} }
_textBox.Width = absRectangle.Width - (2 * lineWidth) + correction; _textBox.Width = absRectangle.Width - 2 * lineWidth + correction;
_textBox.Height = absRectangle.Height - (2 * lineWidth) + correction; _textBox.Height = absRectangle.Height - 2 * lineWidth + correction;
} }
public override void ApplyBounds(RectangleF newBounds) public override void ApplyBounds(RectangleF newBounds)
@ -459,7 +467,7 @@ public override void Draw(Graphics graphics, RenderMode rm)
DrawSelectionBorder(graphics, rect); DrawSelectionBorder(graphics, rect);
} }
if (text == null || text.Length == 0) if (string.IsNullOrEmpty(text))
{ {
return; return;
} }
@ -481,12 +489,13 @@ public override void Draw(Graphics graphics, RenderMode rm)
/// <param name="drawingRectange"></param> /// <param name="drawingRectange"></param>
/// <param name="lineThickness"></param> /// <param name="lineThickness"></param>
/// <param name="fontColor"></param> /// <param name="fontColor"></param>
/// <param name="drawShadow"></param>
/// <param name="stringFormat"></param> /// <param name="stringFormat"></param>
/// <param name="text"></param> /// <param name="text"></param>
/// <param name="font"></param> /// <param name="font"></param>
public static void DrawText(Graphics graphics, Rectangle drawingRectange, int lineThickness, Color fontColor, bool drawShadow, StringFormat stringFormat, string text, Font font) public static void DrawText(Graphics graphics, Rectangle drawingRectange, int lineThickness, Color fontColor, bool drawShadow, StringFormat stringFormat, string text, Font font)
{ {
int textOffset = (lineThickness > 0) ? (int)Math.Ceiling(lineThickness / 2d) : 0; int textOffset = lineThickness > 0 ? (int)Math.Ceiling(lineThickness / 2d) : 0;
// draw shadow before anything else // draw shadow before anything else
if (drawShadow) if (drawShadow)
{ {

View file

@ -37,7 +37,7 @@ namespace Greenshot
public partial class ColorDialog : BaseForm public partial class ColorDialog : BaseForm
{ {
private static ColorDialog uniqueInstance; private static ColorDialog uniqueInstance;
private static EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>(); private static readonly EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
private ColorDialog() private ColorDialog()
{ {
@ -62,7 +62,7 @@ public static ColorDialog GetInstance()
private readonly List<Button> _colorButtons = new List<Button>(); private readonly List<Button> _colorButtons = new List<Button>();
private readonly List<Button> _recentColorButtons = new List<Button>(); private readonly List<Button> _recentColorButtons = new List<Button>();
private readonly ToolTip _toolTip = new ToolTip(); private readonly ToolTip _toolTip = new ToolTip();
private bool _updateInProgress = false; private bool _updateInProgress;
public Color Color public Color Color
{ {

View file

@ -29,7 +29,7 @@ namespace Greenshot.Forms
{ {
public partial class DropShadowSettingsForm : BaseForm public partial class DropShadowSettingsForm : BaseForm
{ {
private DropShadowEffect effect; private readonly DropShadowEffect effect;
public DropShadowSettingsForm(DropShadowEffect effect) public DropShadowSettingsForm(DropShadowEffect effect)
{ {

View file

@ -505,7 +505,7 @@ protected override void Dispose(bool disposing)
this.propertiesToolStrip.Renderer = new CustomToolStripProfessionalRenderer(); this.propertiesToolStrip.Renderer = new CustomToolStripProfessionalRenderer();
this.propertiesToolStrip.BackColor = System.Drawing.SystemColors.Control; this.propertiesToolStrip.BackColor = System.Drawing.SystemColors.Control;
this.propertiesToolStrip.OverflowButton.DropDown.BackColor = System.Drawing.SystemColors.Control; this.propertiesToolStrip.OverflowButton.DropDown.BackColor = System.Drawing.SystemColors.Control;
this.propertiesToolStrip.Paint += propertiesToolStrip_Paint; this.propertiesToolStrip.Paint += PropertiesToolStrip_Paint;
this.propertiesToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.propertiesToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsbSaveClose, this.tsbSaveClose,
this.tsbClose, this.tsbClose,

File diff suppressed because it is too large Load diff

View file

@ -100,9 +100,9 @@ public void MoveTo(Point screenCoordinates)
/// </summary> /// </summary>
/// <param name="screenCoordinates">Point with the coordinates</param> /// <param name="screenCoordinates">Point with the coordinates</param>
/// <returns>Color at the specified screenCoordinates</returns> /// <returns>Color at the specified screenCoordinates</returns>
static private Color GetPixelColor(Point screenCoordinates) private static Color GetPixelColor(Point screenCoordinates)
{ {
using (SafeWindowDCHandle screenDC = SafeWindowDCHandle.fromDesktop()) using (SafeWindowDCHandle screenDC = SafeWindowDCHandle.FromDesktop())
{ {
try try
{ {

View file

@ -32,9 +32,9 @@ namespace Greenshot
/// </summary> /// </summary>
public partial class ResizeSettingsForm : BaseForm public partial class ResizeSettingsForm : BaseForm
{ {
private ResizeEffect effect; private readonly ResizeEffect effect;
private string value_pixel; private readonly string value_pixel;
private string value_percent; private readonly string value_percent;
private double newWidth, newHeight; private double newWidth, newHeight;
public ResizeSettingsForm(ResizeEffect effect) public ResizeSettingsForm(ResizeEffect effect)
@ -55,8 +55,8 @@ public ResizeSettingsForm(ResizeEffect effect)
textbox_height.Text = effect.Height.ToString(); textbox_height.Text = effect.Height.ToString();
newWidth = effect.Width; newWidth = effect.Width;
newHeight = effect.Height; newHeight = effect.Height;
combobox_width.SelectedIndexChanged += new System.EventHandler(this.combobox_SelectedIndexChanged); combobox_width.SelectedIndexChanged += new EventHandler(combobox_SelectedIndexChanged);
combobox_height.SelectedIndexChanged += new System.EventHandler(this.combobox_SelectedIndexChanged); combobox_height.SelectedIndexChanged += new EventHandler(combobox_SelectedIndexChanged);
checkbox_aspectratio.Checked = effect.MaintainAspectRatio; checkbox_aspectratio.Checked = effect.MaintainAspectRatio;
} }
@ -96,7 +96,7 @@ private void displayWidth()
double displayValue; double displayValue;
if (value_percent.Equals(combobox_width.SelectedItem)) if (value_percent.Equals(combobox_width.SelectedItem))
{ {
displayValue = ((double)newWidth / (double)effect.Width) * 100d; displayValue = (double)newWidth / (double)effect.Width * 100d;
} }
else else
{ {
@ -110,7 +110,7 @@ private void displayHeight()
double displayValue; double displayValue;
if (value_percent.Equals(combobox_height.SelectedItem)) if (value_percent.Equals(combobox_height.SelectedItem))
{ {
displayValue = ((double)newHeight / (double)effect.Height) * 100d; displayValue = (double)newHeight / (double)effect.Height * 100d;
} }
else else
{ {
@ -158,16 +158,16 @@ private void textbox_KeyUp(object sender, KeyEventArgs e)
if (isPercent) if (isPercent)
{ {
percent = double.Parse(textbox_width.Text); percent = double.Parse(textbox_width.Text);
newWidth = ((double)effect.Width / 100d) * percent; newWidth = (double)effect.Width / 100d * percent;
} }
else else
{ {
newWidth = double.Parse(textbox_width.Text); newWidth = double.Parse(textbox_width.Text);
percent = ((double)double.Parse(textbox_width.Text) / (double)effect.Width) * 100d; percent = (double)double.Parse(textbox_width.Text) / (double)effect.Width * 100d;
} }
if (checkbox_aspectratio.Checked) if (checkbox_aspectratio.Checked)
{ {
newHeight = ((double)effect.Height / 100d) * percent; newHeight = (double)effect.Height / 100d * percent;
displayHeight(); displayHeight();
} }
} }
@ -176,16 +176,16 @@ private void textbox_KeyUp(object sender, KeyEventArgs e)
if (isPercent) if (isPercent)
{ {
percent = double.Parse(textbox_height.Text); percent = double.Parse(textbox_height.Text);
newHeight = ((double)effect.Height / 100d) * percent; newHeight = (double)effect.Height / 100d * percent;
} }
else else
{ {
newHeight = double.Parse(textbox_height.Text); newHeight = double.Parse(textbox_height.Text);
percent = ((double)double.Parse(textbox_height.Text) / (double)effect.Height) * 100d; percent = (double)double.Parse(textbox_height.Text) / (double)effect.Height * 100d;
} }
if (checkbox_aspectratio.Checked) if (checkbox_aspectratio.Checked)
{ {
newWidth = ((double)effect.Width / 100d) * percent; newWidth = (double)effect.Width / 100d * percent;
displayWidth(); displayWidth();
} }
} }

View file

@ -29,7 +29,7 @@ namespace Greenshot.Forms
{ {
public partial class TornEdgeSettingsForm : BaseForm public partial class TornEdgeSettingsForm : BaseForm
{ {
private TornEdgeEffect effect; private readonly TornEdgeEffect effect;
public TornEdgeSettingsForm(TornEdgeEffect effect) public TornEdgeSettingsForm(TornEdgeEffect effect)
{ {

View file

@ -168,6 +168,7 @@
<Compile Include="Controls\Pipette.cs"> <Compile Include="Controls\Pipette.cs">
<SubType>Component</SubType> <SubType>Component</SubType>
</Compile> </Compile>
<Compile Include="Core\OperatingSystemExtensions.cs" />
<Compile Include="Core\WindowsHelper.cs" /> <Compile Include="Core\WindowsHelper.cs" />
<Compile Include="Core\BinaryStructHelper.cs" /> <Compile Include="Core\BinaryStructHelper.cs" />
<Compile Include="Core\Cache.cs" /> <Compile Include="Core\Cache.cs" />

View file

@ -41,9 +41,9 @@ public static int Distance2D(int x1, int y1, int x2, int y2)
//Our end result //Our end result
int result = 0; int result = 0;
//Take x2-x1, then square it //Take x2-x1, then square it
double part1 = Math.Pow((x2 - x1), 2); double part1 = Math.Pow(x2 - x1, 2);
//Take y2-y1, then square it //Take y2-y1, then square it
double part2 = Math.Pow((y2 - y1), 2); double part2 = Math.Pow(y2 - y1, 2);
//Add both of the parts together //Add both of the parts together
double underRadical = part1 + part2; double underRadical = part1 + part2;
//Get the square root of the parts //Get the square root of the parts

View file

@ -80,7 +80,7 @@ public static RectangleF GetAlignedRectangle(RectangleF currentRect, RectangleF
newRect.X = (targetRect.Width - currentRect.Width) / 2; newRect.X = (targetRect.Width - currentRect.Width) / 2;
break; break;
case ContentAlignment.TopRight: case ContentAlignment.TopRight:
newRect.X = (targetRect.Width - currentRect.Width); newRect.X = targetRect.Width - currentRect.Width;
break; break;
case ContentAlignment.MiddleLeft: case ContentAlignment.MiddleLeft:
newRect.Y = (targetRect.Height - currentRect.Height) / 2; newRect.Y = (targetRect.Height - currentRect.Height) / 2;
@ -91,18 +91,18 @@ public static RectangleF GetAlignedRectangle(RectangleF currentRect, RectangleF
break; break;
case ContentAlignment.MiddleRight: case ContentAlignment.MiddleRight:
newRect.Y = (targetRect.Height - currentRect.Height) / 2; newRect.Y = (targetRect.Height - currentRect.Height) / 2;
newRect.X = (targetRect.Width - currentRect.Width); newRect.X = targetRect.Width - currentRect.Width;
break; break;
case ContentAlignment.BottomLeft: case ContentAlignment.BottomLeft:
newRect.Y = (targetRect.Height - currentRect.Height); newRect.Y = targetRect.Height - currentRect.Height;
break; break;
case ContentAlignment.BottomCenter: case ContentAlignment.BottomCenter:
newRect.Y = (targetRect.Height - currentRect.Height); newRect.Y = targetRect.Height - currentRect.Height;
newRect.X = (targetRect.Width - currentRect.Width) / 2; newRect.X = (targetRect.Width - currentRect.Width) / 2;
break; break;
case ContentAlignment.BottomRight: case ContentAlignment.BottomRight:
newRect.Y = (targetRect.Height - currentRect.Height); newRect.Y = targetRect.Height - currentRect.Height;
newRect.X = (targetRect.Width - currentRect.Width); newRect.X = targetRect.Width - currentRect.Width;
break; break;
} }
return newRect; return newRect;
@ -351,7 +351,7 @@ public static void Scale(Rectangle boundsBeforeResize, int gripperPosition, int
public static ScaleOptions GetScaleOptions() public static ScaleOptions GetScaleOptions()
{ {
bool anchorAtCenter = (Control.ModifierKeys & Keys.Control) != 0; bool anchorAtCenter = (Control.ModifierKeys & Keys.Control) != 0;
bool maintainAspectRatio = ((Control.ModifierKeys & Keys.Shift) != 0); bool maintainAspectRatio = (Control.ModifierKeys & Keys.Shift) != 0;
ScaleOptions opts = ScaleOptions.Default; ScaleOptions opts = ScaleOptions.Default;
if (anchorAtCenter) opts |= ScaleOptions.Centered; if (anchorAtCenter) opts |= ScaleOptions.Centered;
if (maintainAspectRatio) opts |= ScaleOptions.Rational; if (maintainAspectRatio) opts |= ScaleOptions.Rational;
@ -393,7 +393,7 @@ public double Process(double angle)
public class FixedAngleRoundBehavior : IDoubleProcessor public class FixedAngleRoundBehavior : IDoubleProcessor
{ {
private double fixedAngle; private readonly double fixedAngle;
public FixedAngleRoundBehavior(double fixedAngle) public FixedAngleRoundBehavior(double fixedAngle)
{ {

View file

@ -38,24 +38,24 @@ public class IniConfig
/// <summary> /// <summary>
/// A lock object for the ini file saving /// A lock object for the ini file saving
/// </summary> /// </summary>
private static object iniLock = new object(); private static readonly object iniLock = new object();
/// <summary> /// <summary>
/// As the ini implementation is kept someone generic, for reusing, this holds the name of the application /// As the ini implementation is kept someone generic, for reusing, this holds the name of the application
/// </summary> /// </summary>
private static string applicationName = null; private static string applicationName;
/// <summary> /// <summary>
/// As the ini implementation is kept someone generic, for reusing, this holds the name of the configuration /// As the ini implementation is kept someone generic, for reusing, this holds the name of the configuration
/// </summary> /// </summary>
private static string configName = null; private static string configName;
private static string configFolderPath = null; private static string configFolderPath = null;
/// <summary> /// <summary>
/// A Dictionary with all the sections stored by section name /// A Dictionary with all the sections stored by section name
/// </summary> /// </summary>
private static Dictionary<string, IniSection> sectionMap = new Dictionary<string, IniSection>(); private static readonly Dictionary<string, IniSection> sectionMap = new Dictionary<string, IniSection>();
/// <summary> /// <summary>
/// A Dictionary with the properties for a section stored by section name /// A Dictionary with the properties for a section stored by section name
@ -65,7 +65,7 @@ public class IniConfig
/// <summary> /// <summary>
/// A Dictionary with the fixed-properties for a section stored by section name /// A Dictionary with the fixed-properties for a section stored by section name
/// </summary> /// </summary>
private static Dictionary<string, Dictionary<string, string>> fixedProperties = null; private static Dictionary<string, Dictionary<string, string>> fixedProperties;
/// <summary> /// <summary>
/// Is the configuration portable (meaning we don't store it in the AppData directory) /// Is the configuration portable (meaning we don't store it in the AppData directory)

View file

@ -30,7 +30,7 @@ public static class IniReader
private const string SECTION_START = "["; private const string SECTION_START = "[";
private const string SECTION_END = "]"; private const string SECTION_END = "]";
private const string COMMENT = ";"; private const string COMMENT = ";";
private static char[] ASSIGNMENT = new char[] { '=' }; private static readonly char[] ASSIGNMENT = new[] { '=' };
/** /**
* Read an ini file to a Dictionary, each key is a section and the value is a Dictionary with name and values. * Read an ini file to a Dictionary, each key is a section and the value is a Dictionary with name and values.

View file

@ -35,9 +35,9 @@ namespace Greenshot.IniFile
public abstract class IniSection public abstract class IniSection
{ {
[NonSerialized] [NonSerialized]
private IDictionary<string, IniValue> values = new Dictionary<string, IniValue>(); private readonly IDictionary<string, IniValue> values = new Dictionary<string, IniValue>();
[NonSerialized] [NonSerialized]
private IniSectionAttribute iniSectionAttribute = null; private IniSectionAttribute iniSectionAttribute;
public IniSectionAttribute IniSectionAttribute public IniSectionAttribute IniSectionAttribute
{ {
get get

View file

@ -34,10 +34,10 @@ namespace Greenshot.IniFile
/// </summary> /// </summary>
public class IniValue public class IniValue
{ {
private PropertyInfo propertyInfo; private readonly PropertyInfo propertyInfo;
private FieldInfo fieldInfo; private readonly FieldInfo fieldInfo;
private IniSection containingIniSection; private readonly IniSection containingIniSection;
private IniPropertyAttribute attributes; private readonly IniPropertyAttribute attributes;
public IniValue(IniSection containingIniSection, PropertyInfo propertyInfo, IniPropertyAttribute iniPropertyAttribute) public IniValue(IniSection containingIniSection, PropertyInfo propertyInfo, IniPropertyAttribute iniPropertyAttribute)
{ {
@ -226,7 +226,7 @@ public void Write(TextWriter writer, bool onlyProperties)
while ((bool)moveNext.Invoke(enumerator, null)) while ((bool)moveNext.Invoke(enumerator, null))
{ {
var key = current.Invoke(enumerator, null); var key = current.Invoke(enumerator, null);
var valueObject = item.GetValue(myValue, new object[] { key }); var valueObject = item.GetValue(myValue, new[] { key });
// Write to ini file! // Write to ini file!
writer.WriteLine("{0}.{1}={2}", attributes.Name, ConvertValueToString(valueType1, key, attributes.Separator), ConvertValueToString(valueType2, valueObject, attributes.Separator)); writer.WriteLine("{0}.{1}={2}", attributes.Name, ConvertValueToString(valueType1, key, attributes.Separator), ConvertValueToString(valueType2, valueObject, attributes.Separator));
} }
@ -324,7 +324,7 @@ public void UseValueOrDefault(string propertyValue)
LOG.Warn(ex); LOG.Warn(ex);
//LOG.Error("Problem converting " + stringValue + " to type " + type2.FullName, e); //LOG.Error("Problem converting " + stringValue + " to type " + type2.FullName, e);
} }
addMethodInfo.Invoke(dictionary, new object[] { newValue1, newValue2 }); addMethodInfo.Invoke(dictionary, new[] { newValue1, newValue2 });
addedElements = true; addedElements = true;
} }
} }
@ -428,7 +428,7 @@ private static object ConvertStringToValueType(Type valueType, string valueStrin
string arraySeparator = separator; string arraySeparator = separator;
object list = Activator.CreateInstance(valueType); object list = Activator.CreateInstance(valueType);
// Logic for List<> // Logic for List<>
string[] arrayValues = valueString.Split(new string[] { arraySeparator }, StringSplitOptions.None); string[] arrayValues = valueString.Split(new[] { arraySeparator }, StringSplitOptions.None);
if (arrayValues == null || arrayValues.Length == 0) if (arrayValues == null || arrayValues.Length == 0)
{ {
return list; return list;
@ -450,7 +450,7 @@ private static object ConvertStringToValueType(Type valueType, string valueStrin
} }
if (newValue != null) if (newValue != null)
{ {
addMethodInfo.Invoke(list, new object[] { newValue }); addMethodInfo.Invoke(list, new[] { newValue });
} }
} }
} }
@ -460,7 +460,7 @@ private static object ConvertStringToValueType(Type valueType, string valueStrin
if (valueType == typeof(object) && valueString.Length > 0) if (valueType == typeof(object) && valueString.Length > 0)
{ {
//LOG.Debug("Parsing: " + valueString); //LOG.Debug("Parsing: " + valueString);
string[] values = valueString.Split(new Char[] { ':' }); string[] values = valueString.Split(new[] { ':' });
//LOG.Debug("Type: " + values[0]); //LOG.Debug("Type: " + values[0]);
//LOG.Debug("Value: " + values[1]); //LOG.Debug("Value: " + values[1]);
Type fieldTypeForValue = Type.GetType(values[0], true); Type fieldTypeForValue = Type.GetType(values[0], true);

View file

@ -28,14 +28,14 @@ namespace Greenshot.Plugin
{ {
public class ExportInformation public class ExportInformation
{ {
private string uri = null; private string uri;
private string filepath = null; private string filepath;
private bool exportMade = false; private bool exportMade;
private string destinationDesignation = null; private readonly string destinationDesignation;
private string destinationDescription = null; private string destinationDescription;
private string errorMessage = null; private string errorMessage;
public ExportInformation(string destinationDesignation, string destinationDescription) public ExportInformation(string destinationDesignation, string destinationDescription)
{ {

View file

@ -87,10 +87,10 @@ public int CompareTo(object obj)
public class SurfaceOutputSettings public class SurfaceOutputSettings
{ {
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private bool reduceColors; private bool reduceColors;
private bool disableReduceColors; private bool disableReduceColors;
private List<IEffect> effects = new List<IEffect>(); private readonly List<IEffect> effects = new List<IEffect>();
public SurfaceOutputSettings() public SurfaceOutputSettings()
{ {

View file

@ -55,12 +55,12 @@ public sealed class COMWrapper : RealProxy, IDisposable, IRemotingTypeInfo
/// <summary> /// <summary>
/// The type of which method calls are intercepted and executed on the COM object. /// The type of which method calls are intercepted and executed on the COM object.
/// </summary> /// </summary>
private Type _InterceptType; private Type _interceptType;
/// <summary> /// <summary>
/// The humanly readable target name /// The humanly readable target name
/// </summary> /// </summary>
private string _TargetName; private string _targetName;
#endregion Private Data #endregion Private Data
@ -437,8 +437,8 @@ private COMWrapper(object comObject, Type type, string targetName)
{ {
_COMObject = comObject; _COMObject = comObject;
_COMType = comObject.GetType(); _COMType = comObject.GetType();
_InterceptType = type; _interceptType = type;
_TargetName = targetName; _targetName = targetName;
} }
#endregion Construction #endregion Construction
@ -451,7 +451,7 @@ private COMWrapper(object comObject, Type type, string targetName)
/// </summary> /// </summary>
~COMWrapper() ~COMWrapper()
{ {
LOG.DebugFormat("Finalize {0}", _InterceptType.ToString()); LOG.DebugFormat("Finalize {0}", _interceptType);
Dispose(false); Dispose(false);
} }
@ -475,7 +475,7 @@ private void Dispose(bool disposing)
{ {
if (null != _COMObject) if (null != _COMObject)
{ {
LOG.DebugFormat("Disposing {0}", _InterceptType.ToString()); LOG.DebugFormat("Disposing {0}", _interceptType);
if (Marshal.IsComObject(_COMObject)) if (Marshal.IsComObject(_COMObject))
{ {
try try
@ -484,7 +484,7 @@ private void Dispose(bool disposing)
do do
{ {
count = Marshal.ReleaseComObject(_COMObject); count = Marshal.ReleaseComObject(_COMObject);
LOG.DebugFormat("RCW count for {0} now is {1}", _InterceptType.ToString(), count); LOG.DebugFormat("RCW count for {0} now is {1}", _interceptType, count);
} while (count > 0); } while (count > 0);
} }
catch (Exception ex) catch (Exception ex)
@ -514,7 +514,7 @@ private void Dispose(bool disposing)
/// </returns> /// </returns>
public override string ToString() public override string ToString()
{ {
return _InterceptType.FullName; return _interceptType.FullName;
} }
/// <summary> /// <summary>
@ -603,12 +603,12 @@ public static T Cast<T>(object wrapperProxy)
{ {
throw new ArgumentException("wrapper proxy was no COMWrapper"); throw new ArgumentException("wrapper proxy was no COMWrapper");
} }
if (oldWrapper._InterceptType.IsAssignableFrom(newType)) if (oldWrapper._interceptType.IsAssignableFrom(newType))
{ {
COMWrapper newWrapper = new COMWrapper(oldWrapper._COMObject, newType, oldWrapper._TargetName); COMWrapper newWrapper = new COMWrapper(oldWrapper._COMObject, newType, oldWrapper._targetName);
return (T)newWrapper.GetTransparentProxy(); return (T)newWrapper.GetTransparentProxy();
} }
throw new InvalidCastException(string.Format("{0} is not assignable from {1}", oldWrapper._InterceptType, newType)); throw new InvalidCastException(string.Format("{0} is not assignable from {1}", oldWrapper._interceptType, newType));
} }
/// <summary> /// <summary>
@ -665,7 +665,7 @@ public static void DumpTypeInfo(Type type)
{ {
foreach (MemberInfo memberInfo in type.GetMembers()) foreach (MemberInfo memberInfo in type.GetMembers())
{ {
LOG.InfoFormat("Member: {0};", memberInfo.ToString()); LOG.InfoFormat("Member: {0};", memberInfo);
} }
} }
catch (Exception memberException) catch (Exception memberException)
@ -676,7 +676,7 @@ public static void DumpTypeInfo(Type type)
{ {
foreach (PropertyInfo propertyInfo in type.GetProperties()) foreach (PropertyInfo propertyInfo in type.GetProperties())
{ {
LOG.InfoFormat("Property: {0};", propertyInfo.ToString()); LOG.InfoFormat("Property: {0};", propertyInfo);
} }
} }
catch (Exception propertyException) catch (Exception propertyException)
@ -687,7 +687,7 @@ public static void DumpTypeInfo(Type type)
{ {
foreach (FieldInfo fieldInfo in type.GetFields()) foreach (FieldInfo fieldInfo in type.GetFields())
{ {
LOG.InfoFormat("Field: {0};", fieldInfo.ToString()); LOG.InfoFormat("Field: {0};", fieldInfo);
} }
} }
catch (Exception fieldException) catch (Exception fieldException)
@ -711,14 +711,14 @@ public override IMessage Invoke(IMessage myMessage)
IMethodCallMessage callMessage = myMessage as IMethodCallMessage; IMethodCallMessage callMessage = myMessage as IMethodCallMessage;
if (null == callMessage) if (null == callMessage)
{ {
LOG.DebugFormat("Message type not implemented: {0}", myMessage.GetType().ToString()); LOG.DebugFormat("Message type not implemented: {0}", myMessage.GetType());
return null; return null;
} }
MethodInfo method = callMessage.MethodBase as MethodInfo; MethodInfo method = callMessage.MethodBase as MethodInfo;
if (null == method) if (null == method)
{ {
LOG.DebugFormat("Unrecognized Invoke call: {0}", callMessage.MethodBase.ToString()); LOG.DebugFormat("Unrecognized Invoke call: {0}", callMessage.MethodBase);
return null; return null;
} }
@ -731,18 +731,8 @@ public override IMessage Invoke(IMessage myMessage)
BindingFlags flags = BindingFlags.InvokeMethod; BindingFlags flags = BindingFlags.InvokeMethod;
int argCount = callMessage.ArgCount; int argCount = callMessage.ArgCount;
object invokeObject;
Type invokeType;
Type byValType;
object[] args;
object arg;
COMWrapper[] originalArgs;
COMWrapper wrapper;
ParameterModifier[] argModifiers = null; ParameterModifier[] argModifiers = null;
ParameterInfo[] parameters = null; ParameterInfo[] parameters = null;
ParameterInfo parameter;
if ("Dispose" == methodName && 0 == argCount && typeof(void) == returnType) if ("Dispose" == methodName && 0 == argCount && typeof(void) == returnType)
{ {
@ -754,7 +744,7 @@ public override IMessage Invoke(IMessage myMessage)
} }
else if ("GetType" == methodName && 0 == argCount && typeof(Type) == returnType) else if ("GetType" == methodName && 0 == argCount && typeof(Type) == returnType)
{ {
returnValue = _InterceptType; returnValue = _interceptType;
} }
else if ("GetHashCode" == methodName && 0 == argCount && typeof(int) == returnType) else if ("GetHashCode" == methodName && 0 == argCount && typeof(int) == returnType)
{ {
@ -777,9 +767,11 @@ public override IMessage Invoke(IMessage myMessage)
} }
else else
{ {
invokeObject = _COMObject; var invokeObject = _COMObject;
invokeType = _COMType; var invokeType = _COMType;
object[] args;
ParameterInfo parameter;
if (methodName.StartsWith("get_")) if (methodName.StartsWith("get_"))
{ {
// Property Get // Property Get
@ -822,6 +814,9 @@ public override IMessage Invoke(IMessage myMessage)
} }
// Un-wrap wrapped COM objects before passing to the method // Un-wrap wrapped COM objects before passing to the method
Type byValType;
COMWrapper wrapper;
COMWrapper[] originalArgs;
if (null == args || 0 == args.Length) if (null == args || 0 == args.Length)
{ {
originalArgs = null; originalArgs = null;
@ -853,7 +848,7 @@ public override IMessage Invoke(IMessage myMessage)
args[i] = new DispatchWrapper(null); args[i] = new DispatchWrapper(null);
} }
} }
else if (typeof(Decimal) == byValType) else if (typeof(decimal) == byValType)
{ {
// If we're passing a decimal value by reference, // If we're passing a decimal value by reference,
// we need to pass a CurrencyWrapper to avoid a // we need to pass a CurrencyWrapper to avoid a
@ -875,7 +870,7 @@ public override IMessage Invoke(IMessage myMessage)
catch (InvalidComObjectException icoEx) catch (InvalidComObjectException icoEx)
{ {
// Should assist BUG-1616 and others // Should assist BUG-1616 and others
LOG.WarnFormat("COM object {0} has been separated from its underlying RCW cannot be used. The COM object was released while it was still in use on another thread.", _InterceptType.FullName); LOG.WarnFormat("COM object {0} has been separated from its underlying RCW cannot be used. The COM object was released while it was still in use on another thread.", _interceptType.FullName);
return new ReturnMessage(icoEx, callMessage); return new ReturnMessage(icoEx, callMessage);
} }
catch (Exception ex) catch (Exception ex)
@ -888,7 +883,7 @@ public override IMessage Invoke(IMessage myMessage)
} }
if (comEx != null && (comEx.ErrorCode == RPC_E_CALL_REJECTED || comEx.ErrorCode == RPC_E_FAIL)) if (comEx != null && (comEx.ErrorCode == RPC_E_CALL_REJECTED || comEx.ErrorCode == RPC_E_FAIL))
{ {
string destinationName = _TargetName; string destinationName = _targetName;
// Try to find a "catchy" name for the rejecting application // Try to find a "catchy" name for the rejecting application
if (destinationName != null && destinationName.Contains(".")) if (destinationName != null && destinationName.Contains("."))
{ {
@ -896,7 +891,7 @@ public override IMessage Invoke(IMessage myMessage)
} }
if (destinationName == null) if (destinationName == null)
{ {
destinationName = _InterceptType.FullName; destinationName = _interceptType.FullName;
} }
DialogResult result = MessageBox.Show(string.Format("The destination {0} rejected Greenshot access, probably a dialog is open. Close the dialog and try again.", DialogResult result = MessageBox.Show(string.Format("The destination {0} rejected Greenshot access, probably a dialog is open. Close the dialog and try again.",
destinationName), "Greenshot access rejected", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); destinationName), "Greenshot access rejected", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
@ -918,7 +913,7 @@ public override IMessage Invoke(IMessage myMessage)
// Wrap the returned value in an intercepting COM wrapper // Wrap the returned value in an intercepting COM wrapper
if (Marshal.IsComObject(returnValue)) if (Marshal.IsComObject(returnValue))
{ {
returnValue = Wrap(returnValue, returnType, _TargetName); returnValue = Wrap(returnValue, returnType, _targetName);
} }
} }
else if (returnType.IsEnum) else if (returnType.IsEnum)
@ -939,7 +934,7 @@ public override IMessage Invoke(IMessage myMessage)
continue; continue;
} }
arg = args[i]; var arg = args[i];
if (null == arg) if (null == arg)
{ {
continue; continue;
@ -949,7 +944,7 @@ public override IMessage Invoke(IMessage myMessage)
wrapper = null; wrapper = null;
byValType = GetByValType(parameter.ParameterType); byValType = GetByValType(parameter.ParameterType);
if (typeof(Decimal) == byValType) if (typeof(decimal) == byValType)
{ {
if (arg is CurrencyWrapper) if (arg is CurrencyWrapper)
{ {
@ -973,7 +968,7 @@ public override IMessage Invoke(IMessage myMessage)
if (null == wrapper) if (null == wrapper)
{ {
wrapper = new COMWrapper(arg, byValType, _TargetName); wrapper = new COMWrapper(arg, byValType, _targetName);
} }
arg = wrapper.GetTransparentProxy(); arg = wrapper.GetTransparentProxy();
} }
@ -995,7 +990,7 @@ public override IMessage Invoke(IMessage myMessage)
/// <returns></returns> /// <returns></returns>
public bool CanCastTo(Type toType, object o) public bool CanCastTo(Type toType, object o)
{ {
bool returnValue = _InterceptType.IsAssignableFrom(toType); bool returnValue = _interceptType.IsAssignableFrom(toType);
return returnValue; return returnValue;
} }

View file

@ -29,7 +29,7 @@ namespace Greenshot.Interop
[AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] [AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
public sealed class ComProgIdAttribute : Attribute public sealed class ComProgIdAttribute : Attribute
{ {
private string _value; private readonly string _value;
/// <summary> /// <summary>
/// Extracts the attribute from the specified type. /// Extracts the attribute from the specified type.

View file

@ -30,13 +30,13 @@ namespace Greenshot.Memento
/// </summary> /// </summary>
public class AddElementMemento : IMemento public class AddElementMemento : IMemento
{ {
private IDrawableContainer drawableContainer; private IDrawableContainer _drawableContainer;
private Surface surface; private Surface _surface;
public AddElementMemento(Surface surface, IDrawableContainer drawableContainer) public AddElementMemento(Surface surface, IDrawableContainer drawableContainer)
{ {
this.surface = surface; _surface = surface;
this.drawableContainer = drawableContainer; _drawableContainer = drawableContainer;
} }
public void Dispose() public void Dispose()
@ -48,8 +48,8 @@ public void Dispose()
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
//if (disposing) { } //if (disposing) { }
drawableContainer = null; _drawableContainer = null;
surface = null; _surface = null;
} }
public bool Merge(IMemento otherMemento) public bool Merge(IMemento otherMemento)
@ -60,16 +60,15 @@ public bool Merge(IMemento otherMemento)
public IMemento Restore() public IMemento Restore()
{ {
// Before // Before
drawableContainer.Invalidate(); _drawableContainer.Invalidate();
// Store the selected state, as it's overwritten by the RemoveElement // Store the selected state, as it's overwritten by the RemoveElement
bool selected = drawableContainer.Selected;
DeleteElementMemento oldState = new DeleteElementMemento(surface, drawableContainer); DeleteElementMemento oldState = new DeleteElementMemento(_surface, _drawableContainer);
surface.RemoveElement(drawableContainer, false); _surface.RemoveElement(_drawableContainer, false);
drawableContainer.Selected = true; _drawableContainer.Selected = true;
// After // After
drawableContainer.Invalidate(); _drawableContainer.Invalidate();
return oldState; return oldState;
} }
} }

View file

@ -31,8 +31,8 @@ namespace Greenshot.Memento
public class ChangeFieldHolderMemento : IMemento public class ChangeFieldHolderMemento : IMemento
{ {
private IDrawableContainer drawableContainer; private IDrawableContainer drawableContainer;
private Field fieldToBeChanged; private readonly Field fieldToBeChanged;
private object oldValue; private readonly object oldValue;
public ChangeFieldHolderMemento(IDrawableContainer drawableContainer, Field fieldToBeChanged) public ChangeFieldHolderMemento(IDrawableContainer drawableContainer, Field fieldToBeChanged)
{ {

View file

@ -31,7 +31,7 @@ namespace Greenshot.Memento
public class DeleteElementMemento : IMemento public class DeleteElementMemento : IMemento
{ {
private IDrawableContainer drawableContainer; private IDrawableContainer drawableContainer;
private Surface surface; private readonly Surface surface;
public DeleteElementMemento(Surface surface, IDrawableContainer drawableContainer) public DeleteElementMemento(Surface surface, IDrawableContainer drawableContainer)
{ {

View file

@ -32,8 +32,8 @@ namespace Greenshot.Memento
/// </summary> /// </summary>
public class DrawableContainerBoundsChangeMemento : IMemento public class DrawableContainerBoundsChangeMemento : IMemento
{ {
private List<Point> points = new List<Point>(); private readonly List<Point> points = new List<Point>();
private List<Size> sizes = new List<Size>(); private readonly List<Size> sizes = new List<Size>();
private List<IDrawableContainer> listOfdrawableContainer; private List<IDrawableContainer> listOfdrawableContainer;
private void StoreBounds() private void StoreBounds()

View file

@ -30,7 +30,7 @@ namespace Greenshot.Memento
public class TextChangeMemento : IMemento public class TextChangeMemento : IMemento
{ {
private TextContainer textContainer; private TextContainer textContainer;
private string oldText; private readonly string oldText;
public TextChangeMemento(TextContainer textContainer) public TextChangeMemento(TextContainer textContainer)
{ {

View file

@ -154,7 +154,7 @@ public static void DisableComposition()
/// Helper method for an easy DWM check /// Helper method for an easy DWM check
/// </summary> /// </summary>
/// <returns>bool true if DWM is available AND active</returns> /// <returns>bool true if DWM is available AND active</returns>
public static bool isDWMEnabled() public static bool IsDwmEnabled()
{ {
// According to: http://technet.microsoft.com/en-us/subscriptions/aa969538%28v=vs.85%29.aspx // According to: http://technet.microsoft.com/en-us/subscriptions/aa969538%28v=vs.85%29.aspx
// And: http://msdn.microsoft.com/en-us/library/windows/desktop/aa969510%28v=vs.85%29.aspx // And: http://msdn.microsoft.com/en-us/library/windows/desktop/aa969510%28v=vs.85%29.aspx

View file

@ -20,6 +20,7 @@
*/ */
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace GreenshotPlugin.UnmanagedHelpers namespace GreenshotPlugin.UnmanagedHelpers
{ {
@ -27,6 +28,7 @@ namespace GreenshotPlugin.UnmanagedHelpers
/// Window Style Flags /// Window Style Flags
/// </summary> /// </summary>
[Flags] [Flags]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum WindowStyleFlags : long public enum WindowStyleFlags : long
{ {
//WS_OVERLAPPED = 0x00000000, //WS_OVERLAPPED = 0x00000000,
@ -79,6 +81,7 @@ public enum WindowStyleFlags : long
} }
[Flags] [Flags]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum ExtendedWindowStyleFlags : uint public enum ExtendedWindowStyleFlags : uint
{ {
WS_EX_DLGMODALFRAME = 0x00000001, WS_EX_DLGMODALFRAME = 0x00000001,
@ -116,6 +119,7 @@ public enum ExtendedWindowStyleFlags : uint
} }
[Flags] [Flags]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum WindowPlacementFlags : uint public enum WindowPlacementFlags : uint
{ {
// The coordinates of the minimized window may be specified. // The coordinates of the minimized window may be specified.
@ -128,6 +132,7 @@ public enum WindowPlacementFlags : uint
WPF_RESTORETOMAXIMIZED = 0x0002 WPF_RESTORETOMAXIMIZED = 0x0002
} }
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum ShowWindowCommand : uint public enum ShowWindowCommand : uint
{ {
/// <summary> /// <summary>
@ -155,7 +160,7 @@ public enum ShowWindowCommand : uint
ShowMaximized = 3, ShowMaximized = 3,
/// <summary> /// <summary>
/// Displays a window in its most recent size and position. This value /// Displays a window in its most recent size and position. This value
/// is similar to <see cref="Win32.ShowWindowCommand.Normal"/>, except /// is similar to <see cref="ShowWindowCommand.Normal"/>, except
/// the window is not actived. /// the window is not actived.
/// </summary> /// </summary>
ShowNoActivate = 4, ShowNoActivate = 4,
@ -170,13 +175,13 @@ public enum ShowWindowCommand : uint
Minimize = 6, Minimize = 6,
/// <summary> /// <summary>
/// Displays the window as a minimized window. This value is similar to /// Displays the window as a minimized window. This value is similar to
/// <see cref="Win32.ShowWindowCommand.ShowMinimized"/>, except the /// <see cref="ShowWindowCommand.ShowMinimized"/>, except the
/// window is not activated. /// window is not activated.
/// </summary> /// </summary>
ShowMinNoActive = 7, ShowMinNoActive = 7,
/// <summary> /// <summary>
/// Displays the window in its current size and position. This value is /// Displays the window in its current size and position. This value is
/// similar to <see cref="Win32.ShowWindowCommand.Show"/>, except the /// similar to <see cref="ShowWindowCommand.Show"/>, except the
/// window is not activated. /// window is not activated.
/// </summary> /// </summary>
ShowNA = 8, ShowNA = 8,
@ -200,7 +205,8 @@ public enum ShowWindowCommand : uint
ForceMinimize = 11 ForceMinimize = 11
} }
public enum SYSCOLOR : int [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum SYSCOLOR
{ {
SCROLLBAR = 0, SCROLLBAR = 0,
BACKGROUND = 1, BACKGROUND = 1,
@ -241,7 +247,8 @@ public enum SYSCOLOR : int
/// ai_productions@verizon.net or osirisgothra@hotmail.com /// ai_productions@verizon.net or osirisgothra@hotmail.com
/// Obtained on pinvoke.net, please contribute your code to support the wiki! /// Obtained on pinvoke.net, please contribute your code to support the wiki!
/// </summary> /// </summary>
public enum SystemMetric : int [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum SystemMetric
{ {
/// <summary> /// <summary>
/// Width of the screen of the primary display monitor, in pixels. This is the same values obtained by calling GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, HORZRES). /// Width of the screen of the primary display monitor, in pixels. This is the same values obtained by calling GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, HORZRES).
@ -621,6 +628,7 @@ public enum SystemMetric : int
SM_REMOTECONTROL = 0x2001 SM_REMOTECONTROL = 0x2001
} }
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum RegionResult public enum RegionResult
{ {
REGION_ERROR = 0, REGION_ERROR = 0,
@ -630,6 +638,7 @@ public enum RegionResult
} }
// See http://msdn.microsoft.com/en-us/library/aa969530(v=vs.85).aspx // See http://msdn.microsoft.com/en-us/library/aa969530(v=vs.85).aspx
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum DWMWINDOWATTRIBUTE public enum DWMWINDOWATTRIBUTE
{ {
DWMWA_NCRENDERING_ENABLED = 1, DWMWA_NCRENDERING_ENABLED = 1,
@ -650,6 +659,7 @@ public enum DWMWINDOWATTRIBUTE
DWMWA_LAST DWMWA_LAST
} }
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum GetWindowCommand : uint public enum GetWindowCommand : uint
{ {
GW_HWNDFIRST = 0, GW_HWNDFIRST = 0,
@ -662,6 +672,7 @@ public enum GetWindowCommand : uint
} }
[Flags] [Flags]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum DWM_BB public enum DWM_BB
{ {
Enable = 1, Enable = 1,
@ -669,7 +680,8 @@ public enum DWM_BB
TransitionMaximized = 4 TransitionMaximized = 4
} }
public enum ClassLongIndex : int [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum ClassLongIndex
{ {
GCL_CBCLSEXTRA = -20, // the size, in bytes, of the extra memory associated with the class. Setting this value does not change the number of extra bytes already allocated. GCL_CBCLSEXTRA = -20, // the size, in bytes, of the extra memory associated with the class. Setting this value does not change the number of extra bytes already allocated.
GCL_CBWNDEXTRA = -18, // the size, in bytes, of the extra window memory associated with each window in the class. Setting this value does not change the number of extra bytes already allocated. For information on how to access this memory, see SetWindowLong. GCL_CBWNDEXTRA = -18, // the size, in bytes, of the extra window memory associated with each window in the class. Setting this value does not change the number of extra bytes already allocated. For information on how to access this memory, see SetWindowLong.
@ -683,7 +695,8 @@ public enum ClassLongIndex : int
GCL_WNDPROC = -24, // the address of the window procedure, or a handle representing the address of the window procedure. You must use the CallWindowProc function to call the window procedure. GCL_WNDPROC = -24, // the address of the window procedure, or a handle representing the address of the window procedure. You must use the CallWindowProc function to call the window procedure.
} }
public enum WindowsMessages : int [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum WindowsMessages
{ {
WM_NULL = 0x0000, WM_NULL = 0x0000,
WM_CREATE = 0x0001, WM_CREATE = 0x0001,
@ -891,7 +904,8 @@ public enum WindowsMessages : int
} }
// Get/Set WindowLong Enum See: http://msdn.microsoft.com/en-us/library/ms633591.aspx // Get/Set WindowLong Enum See: http://msdn.microsoft.com/en-us/library/ms633591.aspx
public enum WindowLongIndex : int [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum WindowLongIndex
{ {
GWL_EXSTYLE = -20, // Sets a new extended window style. GWL_EXSTYLE = -20, // Sets a new extended window style.
GWL_HINSTANCE = -6, // Sets a new application instance handle. GWL_HINSTANCE = -6, // Sets a new application instance handle.
@ -903,7 +917,8 @@ public enum WindowLongIndex : int
// See: http://msdn.microsoft.com/en-us/library/ms633545.aspx // See: http://msdn.microsoft.com/en-us/library/ms633545.aspx
[Flags] [Flags]
public enum WindowPos : int [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum WindowPos
{ {
SWP_ASYNCWINDOWPOS = 0x4000, // If the calling thread and the thread that owns the window are attached to different input queues, the system posts the request to the thread that owns the window. This prevents the calling thread from blocking its execution while other threads process the request. SWP_ASYNCWINDOWPOS = 0x4000, // If the calling thread and the thread that owns the window are attached to different input queues, the system posts the request to the thread that owns the window. This prevents the calling thread from blocking its execution while other threads process the request.
SWP_DEFERERASE = 0x2000, // Prevents generation of the WM_SYNCPAINT message. SWP_DEFERERASE = 0x2000, // Prevents generation of the WM_SYNCPAINT message.
@ -922,14 +937,17 @@ public enum WindowPos : int
SWP_SHOWWINDOW = 0x0040 //Displays the window. SWP_SHOWWINDOW = 0x0040 //Displays the window.
} }
public enum ScrollBarDirection : int [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum ScrollBarDirection
{ {
SB_HORZ = 0, SB_HORZ = 0,
SB_VERT = 1, SB_VERT = 1,
SB_CTL = 2, SB_CTL = 2,
SB_BOTH = 3 SB_BOTH = 3
} }
public enum ScrollbarCommand : int
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum ScrollbarCommand
{ {
SB_LINEUP = 0, // Scrolls one line up. SB_LINEUP = 0, // Scrolls one line up.
SB_LINEDOWN = 1, // Scrolls one line down. SB_LINEDOWN = 1, // Scrolls one line down.
@ -942,6 +960,7 @@ public enum ScrollbarCommand : int
SB_ENDSCROLL = 8 // Ends scroll. SB_ENDSCROLL = 8 // Ends scroll.
} }
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum ScrollInfoMask public enum ScrollInfoMask
{ {
SIF_RANGE = 0x1, SIF_RANGE = 0x1,
@ -956,6 +975,7 @@ public enum ScrollInfoMask
/// See: http://www.pinvoke.net/default.aspx/Enums/SendMessageTimeoutFlags.html /// See: http://www.pinvoke.net/default.aspx/Enums/SendMessageTimeoutFlags.html
/// </summary> /// </summary>
[Flags] [Flags]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum SendMessageTimeoutFlags : uint public enum SendMessageTimeoutFlags : uint
{ {
SMTO_NORMAL = 0x0, SMTO_NORMAL = 0x0,
@ -965,6 +985,7 @@ public enum SendMessageTimeoutFlags : uint
} }
[Flags] [Flags]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum ProcessAccessFlags : uint public enum ProcessAccessFlags : uint
{ {
All = 0x001F0FFF, All = 0x001F0FFF,
@ -983,7 +1004,8 @@ public enum ProcessAccessFlags : uint
/// See: http://msdn.microsoft.com/en-us/library/aa909766.aspx /// See: http://msdn.microsoft.com/en-us/library/aa909766.aspx
/// </summary> /// </summary>
[Flags] [Flags]
public enum SoundFlags : int [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum SoundFlags
{ {
SND_SYNC = 0x0000, // play synchronously (default) SND_SYNC = 0x0000, // play synchronously (default)
SND_ASYNC = 0x0001, // play asynchronously SND_ASYNC = 0x0001, // play asynchronously
@ -1001,6 +1023,7 @@ public enum SoundFlags : int
/// Used by GDI32.GetDeviceCaps /// Used by GDI32.GetDeviceCaps
/// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dd144877%28v=vs.85%29.aspx /// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dd144877%28v=vs.85%29.aspx
/// </summary> /// </summary>
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum DeviceCaps public enum DeviceCaps
{ {
/// <summary> /// <summary>
@ -1170,7 +1193,8 @@ public enum DeviceCaps
/// Used for User32.SetWinEventHook /// Used for User32.SetWinEventHook
/// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dd373640%28v=vs.85%29.aspx /// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dd373640%28v=vs.85%29.aspx
/// </summary> /// </summary>
public enum WinEventHookFlags : int [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum WinEventHookFlags
{ {
WINEVENT_SKIPOWNTHREAD = 1, WINEVENT_SKIPOWNTHREAD = 1,
WINEVENT_SKIPOWNPROCESS = 2, WINEVENT_SKIPOWNPROCESS = 2,
@ -1182,6 +1206,7 @@ public enum WinEventHookFlags : int
/// Used for User32.SetWinEventHook /// Used for User32.SetWinEventHook
/// See MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/dd318066%28v=vs.85%29.aspx /// See MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/dd318066%28v=vs.85%29.aspx
/// </summary> /// </summary>
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum WinEvent : uint public enum WinEvent : uint
{ {
EVENT_OBJECT_ACCELERATORCHANGE = 32786, EVENT_OBJECT_ACCELERATORCHANGE = 32786,
@ -1232,7 +1257,8 @@ public enum WinEvent : uint
/// Used for User32.SetWinEventHook /// Used for User32.SetWinEventHook
/// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dd373606%28v=vs.85%29.aspx#OBJID_WINDOW /// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dd373606%28v=vs.85%29.aspx#OBJID_WINDOW
/// </summary> /// </summary>
public enum EventObjects : int [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum EventObjects
{ {
OBJID_ALERT = -10, OBJID_ALERT = -10,
OBJID_CARET = -8, OBJID_CARET = -8,
@ -1249,6 +1275,7 @@ public enum EventObjects : int
} }
[Flags] [Flags]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum DesktopAccessRight : uint public enum DesktopAccessRight : uint
{ {
DESKTOP_READOBJECTS = 0x00000001, DESKTOP_READOBJECTS = 0x00000001,

View file

@ -57,7 +57,7 @@ public static bool AreRectangleCornersVisisble(this Region region, Rectangle rec
/// <returns>SafeDeviceContextHandle</returns> /// <returns>SafeDeviceContextHandle</returns>
public static SafeDeviceContextHandle GetSafeDeviceContext(this Graphics graphics) public static SafeDeviceContextHandle GetSafeDeviceContext(this Graphics graphics)
{ {
return SafeDeviceContextHandle.fromGraphics(graphics); return SafeDeviceContextHandle.FromGraphics(graphics);
} }
} }
@ -67,6 +67,7 @@ public static SafeDeviceContextHandle GetSafeDeviceContext(this Graphics graphic
public abstract class SafeObjectHandle : SafeHandleZeroOrMinusOneIsInvalid public abstract class SafeObjectHandle : SafeHandleZeroOrMinusOneIsInvalid
{ {
[DllImport("gdi32", SetLastError = true)] [DllImport("gdi32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteObject(IntPtr hObject); private static extern bool DeleteObject(IntPtr hObject);
protected SafeObjectHandle(bool ownsHandle) : base(ownsHandle) protected SafeObjectHandle(bool ownsHandle) : base(ownsHandle)
@ -84,9 +85,13 @@ protected override bool ReleaseHandle()
/// </summary> /// </summary>
public class SafeHBitmapHandle : SafeObjectHandle public class SafeHBitmapHandle : SafeObjectHandle
{ {
/// <summary>
/// Needed for marshalling return values
/// </summary>
[SecurityCritical] [SecurityCritical]
private SafeHBitmapHandle() : base(true) public SafeHBitmapHandle() : base(true)
{ {
} }
[SecurityCritical] [SecurityCritical]
@ -101,8 +106,11 @@ public SafeHBitmapHandle(IntPtr preexistingHandle) : base(true)
/// </summary> /// </summary>
public class SafeRegionHandle : SafeObjectHandle public class SafeRegionHandle : SafeObjectHandle
{ {
/// <summary>
/// Needed for marshalling return values
/// </summary>
[SecurityCritical] [SecurityCritical]
private SafeRegionHandle() : base(true) public SafeRegionHandle() : base(true)
{ {
} }
@ -118,8 +126,11 @@ public SafeRegionHandle(IntPtr preexistingHandle) : base(true)
/// </summary> /// </summary>
public class SafeDibSectionHandle : SafeObjectHandle public class SafeDibSectionHandle : SafeObjectHandle
{ {
/// <summary>
/// Needed for marshalling return values
/// </summary>
[SecurityCritical] [SecurityCritical]
private SafeDibSectionHandle() : base(true) public SafeDibSectionHandle() : base(true)
{ {
} }
@ -139,23 +150,26 @@ public class SafeSelectObjectHandle : SafeHandleZeroOrMinusOneIsInvalid
[DllImport("gdi32", SetLastError = true)] [DllImport("gdi32", SetLastError = true)]
private static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); private static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
private SafeHandle hdc; private readonly SafeHandle _hdc;
/// <summary>
/// Needed for marshalling return values
/// </summary>
[SecurityCritical] [SecurityCritical]
private SafeSelectObjectHandle() : base(true) public SafeSelectObjectHandle() : base(true)
{ {
} }
[SecurityCritical] [SecurityCritical]
public SafeSelectObjectHandle(SafeDCHandle hdc, SafeHandle newHandle) : base(true) public SafeSelectObjectHandle(SafeDCHandle hdc, SafeHandle newHandle) : base(true)
{ {
this.hdc = hdc; _hdc = hdc;
SetHandle(SelectObject(hdc.DangerousGetHandle(), newHandle.DangerousGetHandle())); SetHandle(SelectObject(hdc.DangerousGetHandle(), newHandle.DangerousGetHandle()));
} }
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
SelectObject(hdc.DangerousGetHandle(), handle); SelectObject(_hdc.DangerousGetHandle(), handle);
return true; return true;
} }
} }
@ -173,10 +187,14 @@ protected SafeDCHandle(bool ownsHandle) : base(ownsHandle)
public class SafeCompatibleDCHandle : SafeDCHandle public class SafeCompatibleDCHandle : SafeDCHandle
{ {
[DllImport("gdi32", SetLastError = true)] [DllImport("gdi32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteDC(IntPtr hDC); private static extern bool DeleteDC(IntPtr hDC);
/// <summary>
/// Needed for marshalling return values
/// </summary>
[SecurityCritical] [SecurityCritical]
private SafeCompatibleDCHandle() : base(true) public SafeCompatibleDCHandle() : base(true)
{ {
} }
@ -202,23 +220,26 @@ protected override bool ReleaseHandle()
/// </summary> /// </summary>
public class SafeDeviceContextHandle : SafeDCHandle public class SafeDeviceContextHandle : SafeDCHandle
{ {
private Graphics graphics = null; private readonly Graphics _graphics;
/// <summary>
/// Needed for marshalling return values
/// </summary>
[SecurityCritical] [SecurityCritical]
private SafeDeviceContextHandle() : base(true) public SafeDeviceContextHandle() : base(true)
{ {
} }
[SecurityCritical] [SecurityCritical]
public SafeDeviceContextHandle(Graphics graphics, IntPtr preexistingHandle) : base(true) public SafeDeviceContextHandle(Graphics graphics, IntPtr preexistingHandle) : base(true)
{ {
this.graphics = graphics; _graphics = graphics;
SetHandle(preexistingHandle); SetHandle(preexistingHandle);
} }
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
graphics.ReleaseHdc(handle); _graphics.ReleaseHdc(handle);
return true; return true;
} }
@ -227,7 +248,7 @@ public SafeSelectObjectHandle SelectObject(SafeHandle newHandle)
return new SafeSelectObjectHandle(this, newHandle); return new SafeSelectObjectHandle(this, newHandle);
} }
public static SafeDeviceContextHandle fromGraphics(Graphics graphics) public static SafeDeviceContextHandle FromGraphics(Graphics graphics)
{ {
return new SafeDeviceContextHandle(graphics, graphics.GetHdc()); return new SafeDeviceContextHandle(graphics, graphics.GetHdc());
} }
@ -261,51 +282,6 @@ public static class GDI32
[DllImport("gdi32", SetLastError = true)] [DllImport("gdi32", SetLastError = true)]
public static extern int GetDeviceCaps(SafeHandle hdc, DeviceCaps nIndex); public static extern int GetDeviceCaps(SafeHandle hdc, DeviceCaps nIndex);
/// <summary>
/// StretchBlt extension for the graphics object
/// Doesn't work?
/// </summary>
/// <param name="target"></param>
/// <param name="source"></param>
public static void StretchBlt(this Graphics target, Bitmap sourceBitmap, Rectangle source, Rectangle destination)
{
using (SafeDeviceContextHandle targetDC = target.GetSafeDeviceContext())
{
using (SafeCompatibleDCHandle safeCompatibleDCHandle = CreateCompatibleDC(targetDC))
{
using (SafeHBitmapHandle hBitmapHandle = new SafeHBitmapHandle(sourceBitmap.GetHbitmap()))
{
using (safeCompatibleDCHandle.SelectObject(hBitmapHandle))
{
StretchBlt(targetDC, destination.X, destination.Y, destination.Width, destination.Height, safeCompatibleDCHandle, source.Left, source.Top, source.Width, source.Height, CopyPixelOperation.SourceCopy);
}
}
}
}
}
/// <summary>
/// Bitblt extension for the graphics object
/// </summary>
/// <param name="target"></param>
/// <param name="source"></param>
public static void BitBlt(this Graphics target, Bitmap sourceBitmap, Rectangle source, Point destination, CopyPixelOperation rop)
{
using (SafeDeviceContextHandle targetDC = target.GetSafeDeviceContext())
{
using (SafeCompatibleDCHandle safeCompatibleDCHandle = CreateCompatibleDC(targetDC))
{
using (SafeHBitmapHandle hBitmapHandle = new SafeHBitmapHandle(sourceBitmap.GetHbitmap()))
{
using (safeCompatibleDCHandle.SelectObject(hBitmapHandle))
{
BitBlt(targetDC, destination.X, destination.Y, source.Width, source.Height, safeCompatibleDCHandle, source.Left, source.Top, rop);
}
}
}
}
}
} }
[StructLayout(LayoutKind.Sequential, Pack = 2)] [StructLayout(LayoutKind.Sequential, Pack = 2)]
@ -441,10 +417,12 @@ public BITMAPINFOHEADER(int width, int height, ushort bpp)
bV5BlueMask = (uint)255; bV5BlueMask = (uint)255;
bV5AlphaMask = (uint)255 << 24; bV5AlphaMask = (uint)255 << 24;
bV5CSType = 1934772034; // sRGB bV5CSType = 1934772034; // sRGB
bV5Endpoints = new CIEXYZTRIPLE(); bV5Endpoints = new CIEXYZTRIPLE
bV5Endpoints.ciexyzBlue = new CIEXYZ(0); {
bV5Endpoints.ciexyzGreen = new CIEXYZ(0); ciexyzBlue = new CIEXYZ(0),
bV5Endpoints.ciexyzRed = new CIEXYZ(0); ciexyzGreen = new CIEXYZ(0),
ciexyzRed = new CIEXYZ(0)
};
bV5GammaRed = 0; bV5GammaRed = 0;
bV5GammaGreen = 0; bV5GammaGreen = 0;
bV5GammaBlue = 0; bV5GammaBlue = 0;

View file

@ -111,7 +111,7 @@ public static class GDIplus
[DllImport("gdiplus.dll", SetLastError = true, ExactSpelling = true)] [DllImport("gdiplus.dll", SetLastError = true, ExactSpelling = true)]
private static extern int GdipDeleteEffect(IntPtr effect); private static extern int GdipDeleteEffect(IntPtr effect);
private static Guid BlurEffectGuid = new Guid("{633C80A4-1843-482B-9EF2-BE2834C5FDD4}"); private static readonly Guid BlurEffectGuid = new Guid("{633C80A4-1843-482B-9EF2-BE2834C5FDD4}");
// Constant "FieldInfo" for getting the nativeImage from the Bitmap // Constant "FieldInfo" for getting the nativeImage from the Bitmap
private static readonly FieldInfo FIELD_INFO_NATIVE_IMAGE = typeof(Bitmap).GetField("nativeImage", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FIELD_INFO_NATIVE_IMAGE = typeof(Bitmap).GetField("nativeImage", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic);
@ -122,7 +122,7 @@ public static class GDIplus
// Constant "FieldInfo" for getting the nativeImageAttributes from the ImageAttributes // Constant "FieldInfo" for getting the nativeImageAttributes from the ImageAttributes
private static readonly FieldInfo FIELD_INFO_NATIVE_IMAGEATTRIBUTES = typeof(ImageAttributes).GetField("nativeImageAttributes", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FIELD_INFO_NATIVE_IMAGEATTRIBUTES = typeof(ImageAttributes).GetField("nativeImageAttributes", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic);
private static bool isBlurEnabled = Environment.OSVersion.Version.Major >= 6; private static bool _isBlurEnabled = Environment.OSVersion.Version.Major >= 6;
/// <summary> /// <summary>
/// Get the nativeImage field from the bitmap /// Get the nativeImage field from the bitmap
@ -186,9 +186,9 @@ private static IntPtr GetNativeImageAttributes(ImageAttributes imageAttributes)
/// </summary> /// </summary>
/// <param name="radius"></param> /// <param name="radius"></param>
/// <returns></returns> /// <returns></returns>
public static bool isBlurPossible(int radius) public static bool IsBlurPossible(int radius)
{ {
if (!isBlurEnabled) if (!_isBlurEnabled)
{ {
return false; return false;
} }
@ -209,7 +209,7 @@ public static bool isBlurPossible(int radius)
/// <returns>false if there is no GDI+ available or an exception occured</returns> /// <returns>false if there is no GDI+ available or an exception occured</returns>
public static bool ApplyBlur(Bitmap destinationBitmap, Rectangle area, int radius, bool expandEdges) public static bool ApplyBlur(Bitmap destinationBitmap, Rectangle area, int radius, bool expandEdges)
{ {
if (!isBlurPossible(radius)) if (!IsBlurPossible(radius))
{ {
return false; return false;
} }
@ -248,7 +248,7 @@ public static bool ApplyBlur(Bitmap destinationBitmap, Rectangle area, int radiu
} }
catch (Exception ex) catch (Exception ex)
{ {
isBlurEnabled = false; _isBlurEnabled = false;
LOG.Error("Problem using GdipBitmapApplyEffect: ", ex); LOG.Error("Problem using GdipBitmapApplyEffect: ", ex);
return false; return false;
} }
@ -269,7 +269,7 @@ public static bool ApplyBlur(Bitmap destinationBitmap, Rectangle area, int radiu
} }
catch (Exception ex) catch (Exception ex)
{ {
isBlurEnabled = false; _isBlurEnabled = false;
LOG.Error("Problem cleaning up ApplyBlur: ", ex); LOG.Error("Problem cleaning up ApplyBlur: ", ex);
} }
} }
@ -281,7 +281,7 @@ public static bool ApplyBlur(Bitmap destinationBitmap, Rectangle area, int radiu
/// <returns>false if there is no GDI+ available or an exception occured</returns> /// <returns>false if there is no GDI+ available or an exception occured</returns>
public static bool DrawWithBlur(Graphics graphics, Bitmap image, Rectangle source, Matrix transform, ImageAttributes imageAttributes, int radius, bool expandEdges) public static bool DrawWithBlur(Graphics graphics, Bitmap image, Rectangle source, Matrix transform, ImageAttributes imageAttributes, int radius, bool expandEdges)
{ {
if (!isBlurPossible(radius)) if (!IsBlurPossible(radius))
{ {
return false; return false;
} }
@ -325,7 +325,7 @@ public static bool DrawWithBlur(Graphics graphics, Bitmap image, Rectangle sourc
} }
catch (Exception ex) catch (Exception ex)
{ {
isBlurEnabled = false; _isBlurEnabled = false;
LOG.Error("Problem using GdipDrawImageFX: ", ex); LOG.Error("Problem using GdipDrawImageFX: ", ex);
return false; return false;
} }
@ -346,7 +346,7 @@ public static bool DrawWithBlur(Graphics graphics, Bitmap image, Rectangle sourc
} }
catch (Exception ex) catch (Exception ex)
{ {
isBlurEnabled = false; _isBlurEnabled = false;
LOG.Error("Problem cleaning up DrawWithBlur: ", ex); LOG.Error("Problem cleaning up DrawWithBlur: ", ex);
} }
} }

View file

@ -67,6 +67,7 @@ public class Kernel32
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId); public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)] [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool QueryFullProcessImageName(IntPtr hProcess, uint dwFlags, StringBuilder lpExeName, ref uint lpdwSize); public static extern bool QueryFullProcessImageName(IntPtr hProcess, uint dwFlags, StringBuilder lpExeName, ref uint lpdwSize);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)] [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
@ -76,6 +77,7 @@ public class Kernel32
public static extern IntPtr GetModuleHandle(string lpModuleName); public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32", SetLastError = true)] [DllImport("kernel32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject); public static extern bool CloseHandle(IntPtr hObject);
/// <summary> /// <summary>

View file

@ -43,44 +43,16 @@ public static class Shell32
#region Structs #region Structs
[StructLayout(LayoutKind.Sequential)]
private struct SHITEMID
{
public ushort cb;
[MarshalAs(UnmanagedType.LPArray)]
public byte[] abID;
}
[StructLayout(LayoutKind.Sequential)]
private struct ITEMIDLIST
{
public SHITEMID mkid;
}
[StructLayout(LayoutKind.Sequential)]
private struct BROWSEINFO
{
public IntPtr hwndOwner;
public IntPtr pidlRoot;
public IntPtr pszDisplayName;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpszTitle;
public uint ulFlags;
public IntPtr lpfn;
public int lParam;
public IntPtr iImage;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct SHFILEINFO private struct SHFILEINFO
{ {
public IntPtr hIcon; public readonly IntPtr hIcon;
public int iIcon; public readonly int iIcon;
public uint dwAttributes; public readonly uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName; public readonly string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName; public readonly string szTypeName;
}; };
#endregion Structs #endregion Structs
@ -160,7 +132,7 @@ public enum FolderType
/// Returns an icon for a given file extension - indicated by the name parameter. /// Returns an icon for a given file extension - indicated by the name parameter.
/// See: http://msdn.microsoft.com/en-us/library/windows/desktop/bb762179(v=vs.85).aspx /// See: http://msdn.microsoft.com/en-us/library/windows/desktop/bb762179(v=vs.85).aspx
/// </summary> /// </summary>
/// <param name="name">Filename</param> /// <param name="filename">Filename</param>
/// <param name="size">Large or small</param> /// <param name="size">Large or small</param>
/// <param name="linkOverlay">Whether to include the link icon</param> /// <param name="linkOverlay">Whether to include the link icon</param>
/// <returns>System.Drawing.Icon</returns> /// <returns>System.Drawing.Icon</returns>
@ -168,24 +140,24 @@ public static Icon GetFileIcon(string filename, IconSize size, bool linkOverlay)
{ {
SHFILEINFO shfi = new SHFILEINFO(); SHFILEINFO shfi = new SHFILEINFO();
// SHGFI_USEFILEATTRIBUTES makes it simulate, just gets the icon for the extension // SHGFI_USEFILEATTRIBUTES makes it simulate, just gets the icon for the extension
uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES; uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
if (true == linkOverlay) if (linkOverlay)
{ {
flags += Shell32.SHGFI_LINKOVERLAY; flags += SHGFI_LINKOVERLAY;
} }
// Check the size specified for return. // Check the size specified for return.
if (IconSize.Small == size) if (IconSize.Small == size)
{ {
flags += Shell32.SHGFI_SMALLICON; flags += SHGFI_SMALLICON;
} }
else else
{ {
flags += Shell32.SHGFI_LARGEICON; flags += SHGFI_LARGEICON;
} }
SHGetFileInfo(Path.GetFileName(filename), Shell32.FILE_ATTRIBUTE_NORMAL, ref shfi, (uint)Marshal.SizeOf(shfi), flags); SHGetFileInfo(Path.GetFileName(filename), FILE_ATTRIBUTE_NORMAL, ref shfi, (uint)Marshal.SizeOf(shfi), flags);
// Only return an icon if we really got one // Only return an icon if we really got one
if (shfi.hIcon != IntPtr.Zero) if (shfi.hIcon != IntPtr.Zero)

View file

@ -28,8 +28,8 @@ namespace GreenshotPlugin.UnmanagedHelpers
[StructLayout(LayoutKind.Sequential), Serializable()] [StructLayout(LayoutKind.Sequential), Serializable()]
public struct SIZE public struct SIZE
{ {
public int width; public int Width;
public int height; public int Height;
public SIZE(Size size) : this(size.Width, size.Height) public SIZE(Size size) : this(size.Width, size.Height)
{ {
@ -37,13 +37,13 @@ public SIZE(Size size) : this(size.Width, size.Height)
public SIZE(int width, int height) public SIZE(int width, int height)
{ {
this.width = width; Width = width;
this.height = height; Height = height;
} }
public Size ToSize() public Size ToSize()
{ {
return new Size(width, height); return new Size(Width, Height);
} }
} }

View file

@ -64,7 +64,7 @@ public static class User32
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public extern static bool IsWindowVisible(IntPtr hWnd); public static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId); public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId);
@ -82,10 +82,10 @@ public static class User32
public static extern int ShowWindow(IntPtr hWnd, ShowWindowCommand nCmdShow); public static extern int ShowWindow(IntPtr hWnd, ShowWindowCommand nCmdShow);
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
public extern static int GetWindowText(IntPtr hWnd, StringBuilder lpString, int cch); public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int cch);
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
public extern static int GetWindowTextLength(IntPtr hWnd); public static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern uint GetSysColor(int nIndex); public static extern uint GetSysColor(int nIndex);
@ -114,16 +114,16 @@ public static class User32
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public extern static bool IsIconic(IntPtr hWnd); public static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public extern static bool IsZoomed(IntPtr hwnd); public static extern bool IsZoomed(IntPtr hwnd);
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
public extern static int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32", SetLastError = true)] [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern uint GetClassLong(IntPtr hWnd, int nIndex); public static extern uint GetClassLong(IntPtr hWnd, int nIndex);
[DllImport("user32", SetLastError = true, EntryPoint = "GetClassLongPtr")] [DllImport("user32", SetLastError = true, EntryPoint = "GetClassLongPtr")]
@ -133,17 +133,17 @@ public static class User32
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags); public static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
[DllImport("user32", SetLastError = true)] [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
public extern static IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam); public static extern IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public extern static IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); public static extern IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
[DllImport("user32", SetLastError = true, EntryPoint = "GetWindowLong")] [DllImport("user32", SetLastError = true, EntryPoint = "GetWindowLong")]
public extern static int GetWindowLong(IntPtr hwnd, int index); public static extern int GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32", SetLastError = true, EntryPoint = "GetWindowLongPtr")] [DllImport("user32", SetLastError = true, EntryPoint = "GetWindowLongPtr")]
public extern static IntPtr GetWindowLongPtr(IntPtr hwnd, int nIndex); public static extern IntPtr GetWindowLongPtr(IntPtr hwnd, int nIndex);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern int SetWindowLong(IntPtr hWnd, int index, int styleFlags); public static extern int SetWindowLong(IntPtr hWnd, int index, int styleFlags);
@ -162,10 +162,10 @@ public static class User32
public static extern bool GetWindowInfo(IntPtr hwnd, ref WindowInfo pwi); public static extern bool GetWindowInfo(IntPtr hwnd, ref WindowInfo pwi);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public extern static int EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); public static extern int EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public extern static int EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam); public static extern int EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
@ -173,10 +173,10 @@ public static class User32
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowScrollBar(IntPtr hwnd, ScrollBarDirection scrollBar, bool show); public static extern bool ShowScrollBar(IntPtr hwnd, ScrollBarDirection scrollBar, [MarshalAs(UnmanagedType.Bool)] bool show);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern int SetScrollPos(IntPtr hWnd, Orientation nBar, int nPos, bool bRedraw); public static extern int SetScrollPos(IntPtr hWnd, Orientation nBar, int nPos, [MarshalAs(UnmanagedType.Bool)] bool bRedraw);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern RegionResult GetWindowRgn(IntPtr hWnd, SafeHandle hRgn); public static extern RegionResult GetWindowRgn(IntPtr hWnd, SafeHandle hRgn);
@ -231,7 +231,7 @@ public static class User32
public static extern uint RegisterWindowMessage(string lpString); public static extern uint RegisterWindowMessage(string lpString);
[DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)] [DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult); public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
private static extern bool GetPhysicalCursorPos(out POINT cursorLocation); private static extern bool GetPhysicalCursorPos(out POINT cursorLocation);
@ -446,7 +446,11 @@ protected override bool ReleaseHandle()
/// </summary> /// </summary>
public class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid public class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid
{ {
private SafeIconHandle() : base(true) /// <summary>
/// Needed for marshalling return values
/// </summary>
[SecurityCritical]
public SafeIconHandle() : base(true)
{ {
} }
@ -473,28 +477,30 @@ public class SafeWindowDCHandle : SafeHandleZeroOrMinusOneIsInvalid
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
private static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC); private static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
private IntPtr hWnd; private readonly IntPtr _hWnd;
[SecurityCritical] /// <summary>
private SafeWindowDCHandle() : base(true) /// Needed for marshalling return values
/// </summary>
public SafeWindowDCHandle() : base(true)
{ {
} }
[SecurityCritical] [SecurityCritical]
public SafeWindowDCHandle(IntPtr hWnd, IntPtr preexistingHandle) : base(true) public SafeWindowDCHandle(IntPtr hWnd, IntPtr preexistingHandle) : base(true)
{ {
this.hWnd = hWnd; _hWnd = hWnd;
SetHandle(preexistingHandle); SetHandle(preexistingHandle);
} }
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
bool returnValue = ReleaseDC(hWnd, handle); bool returnValue = ReleaseDC(_hWnd, handle);
return returnValue; return returnValue;
} }
public static SafeWindowDCHandle fromDesktop() public static SafeWindowDCHandle FromDesktop()
{ {
IntPtr hWndDesktop = User32.GetDesktopWindow(); IntPtr hWndDesktop = User32.GetDesktopWindow();
IntPtr hDCDesktop = GetWindowDC(hWndDesktop); IntPtr hDCDesktop = GetWindowDC(hWndDesktop);

View file

@ -853,7 +853,7 @@ public static Bitmap AddShadow(Image sourceImage, float opacity, int size, float
public static void Blur(Bitmap sourceImage, int radius) public static void Blur(Bitmap sourceImage, int radius)
{ {
if (GDIplus.isBlurPossible(radius)) if (GDIplus.IsBlurPossible(radius))
{ {
GDIplus.ApplyBlur(sourceImage, new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), radius, false); GDIplus.ApplyBlur(sourceImage, new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), radius, false);
} }