Code quality changes [skip ci]

This commit is contained in:
Robin 2016-08-16 10:37:55 +02:00
commit 798ca503a5
108 changed files with 1981 additions and 2258 deletions

View file

@ -28,7 +28,7 @@ namespace GreenshotPlugin.Controls {
/// <summary>
/// Description of PleaseWaitForm.
/// </summary>
public partial class BackgroundForm : Form {
public sealed partial class BackgroundForm : Form {
private volatile bool _shouldClose;
private void BackgroundShowDialog() {

View file

@ -457,7 +457,6 @@ namespace GreenshotPlugin.Controls {
/// <summary>
/// Register a hotkey
/// </summary>
/// <param name="hWnd">The window which will get the event</param>
/// <param name="modifierKeyCode">The modifier, e.g.: Modifiers.CTRL, Modifiers.NONE or Modifiers.ALT</param>
/// <param name="virtualKeyCode">The virtual key code</param>
/// <param name="handler">A HotKeyHandler, this will be called to handle the hotkey press</param>

View file

@ -299,14 +299,17 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Return a menu item
/// </summary>
/// <param name="menu"></param>
/// <param name="addDynamics"></param>
/// <param name="destinationClickHandler"></param>
/// <returns>ToolStripMenuItem</returns>
public virtual ToolStripMenuItem GetMenuItem(bool addDynamics, ContextMenuStrip menu, EventHandler destinationClickHandler) {
ToolStripMenuItem basisMenuItem;
basisMenuItem = new ToolStripMenuItem(Description);
basisMenuItem.Image = DisplayIcon;
basisMenuItem.Tag = this;
basisMenuItem.Text = Description;
var basisMenuItem = new ToolStripMenuItem(Description)
{
Image = DisplayIcon,
Tag = this,
Text = Description
};
AddTagEvents(basisMenuItem, menu, Description);
basisMenuItem.Click -= destinationClickHandler;
basisMenuItem.Click += destinationClickHandler;

View file

@ -50,7 +50,7 @@ namespace GreenshotPlugin.Core {
/// Get a struct from a byte array
/// </summary>
/// <typeparam name="T">typeof struct</typeparam>
/// <param name="bytes">byte[]</param>
/// <param name="intPtr">Pointer to the structor to return</param>
/// <returns>struct</returns>
public static T FromIntPtr<T>(IntPtr intPtr) where T : struct {
object obj = Marshal.PtrToStructure(intPtr, typeof(T));

View file

@ -304,7 +304,7 @@ EndSelection:<<<<<<<4
/// Returned images must be disposed by the calling code!
/// </summary>
/// <param name="dataObject"></param>
/// <returns>IEnumerable<Image></returns>
/// <returns>IEnumerable of Image</returns>
public static IEnumerable<Image> GetImages(IDataObject dataObject) {
// Get single image, this takes the "best" match
Image singleImage = GetImage(dataObject);
@ -708,7 +708,7 @@ EndSelection:<<<<<<<4
/// <summary>
/// Retrieve a list of all formats currently on the clipboard
/// </summary>
/// <returns>List<string> with the current formats</returns>
/// <returns>List of strings with the current formats</returns>
public static List<string> GetFormats() {
return GetFormats(GetDataObject());
}
@ -716,7 +716,7 @@ EndSelection:<<<<<<<4
/// <summary>
/// Retrieve a list of all formats currently in the IDataObject
/// </summary>
/// <returns>List<string> with the current formats</returns>
/// <returns>List of string with the current formats</returns>
public static List<string> GetFormats(IDataObject dataObj) {
string[] formats = null;
@ -733,7 +733,6 @@ EndSelection:<<<<<<<4
/// <summary>
/// Check if there is currently something in the dataObject which has the supplied format
/// </summary>
/// <param name="dataObject">IDataObject</param>
/// <param name="format">string with format</param>
/// <returns>true if one the format is found</returns>
public static bool ContainsFormat(string format) {
@ -743,6 +742,7 @@ EndSelection:<<<<<<<4
/// <summary>
/// Check if there is currently something on the clipboard which has the supplied format
/// </summary>
/// <param name="dataObject">IDataObject</param>
/// <param name="format">string with format</param>
/// <returns>true if one the format is found</returns>
public static bool ContainsFormat(IDataObject dataObject, string format) {

View file

@ -62,206 +62,206 @@ namespace GreenshotPlugin.Core {
public event PropertyChangedEventHandler PropertyChanged;
[IniProperty("Language", Description = "The language in IETF format (e.g. en-US)")]
public string Language;
public string Language { get; set; }
[IniProperty("RegionHotkey", Description="Hotkey for starting the region capture", DefaultValue="PrintScreen")]
public string RegionHotkey;
public string RegionHotkey { get; set; }
[IniProperty("WindowHotkey", Description="Hotkey for starting the window capture", DefaultValue="Alt + PrintScreen")]
public string WindowHotkey;
public string WindowHotkey { get; set; }
[IniProperty("FullscreenHotkey", Description="Hotkey for starting the fullscreen capture", DefaultValue="Ctrl + PrintScreen")]
public string FullscreenHotkey;
public string FullscreenHotkey { get; set; }
[IniProperty("LastregionHotkey", Description="Hotkey for starting the last region capture", DefaultValue="Shift + PrintScreen")]
public string LastregionHotkey;
public string LastregionHotkey { get; set; }
[IniProperty("IEHotkey", Description="Hotkey for starting the IE capture", DefaultValue="Shift + Ctrl + PrintScreen")]
public string IEHotkey;
public string IEHotkey { get; set; }
[IniProperty("IsFirstLaunch", Description="Is this the first time launch?", DefaultValue="true")]
public bool IsFirstLaunch;
public bool IsFirstLaunch { get; set; }
[IniProperty("Destinations", Separator=",", Description="Which destinations? Possible options (more might be added by plugins) are: Editor, FileDefault, FileWithDialog, Clipboard, Printer, EMail, Picker", DefaultValue="Picker")]
public List<string> OutputDestinations = new List<string>();
public List<string> OutputDestinations { get; set; } = new List<string>();
[IniProperty("ClipboardFormats", Separator=",", Description="Specify which formats we copy on the clipboard? Options are: PNG, HTML, HTMLDATAURL and DIB", DefaultValue="PNG,DIB")]
public List<ClipboardFormat> ClipboardFormats = new List<ClipboardFormat>();
public List<ClipboardFormat> ClipboardFormats { get; set; } = new List<ClipboardFormat>();
[IniProperty("CaptureMousepointer", Description="Should the mouse be captured?", DefaultValue="true")]
public bool CaptureMousepointer;
public bool CaptureMousepointer { get; set; }
[IniProperty("CaptureWindowsInteractive", Description="Use interactive window selection to capture? (false=Capture active window)", DefaultValue="false")]
public bool CaptureWindowsInteractive;
public bool CaptureWindowsInteractive { get; set; }
[IniProperty("CaptureDelay", Description="Capture delay in millseconds.", DefaultValue="100")]
public int CaptureDelay;
public int CaptureDelay { get; set; }
[IniProperty("ScreenCaptureMode", Description = "The capture mode used to capture a screen. (Auto, FullScreen, Fixed)", DefaultValue = "Auto")]
public ScreenCaptureMode ScreenCaptureMode;
public ScreenCaptureMode ScreenCaptureMode { get; set; }
[IniProperty("ScreenToCapture", Description = "The screen number to capture when using ScreenCaptureMode Fixed.", DefaultValue = "1")]
public int ScreenToCapture;
public int ScreenToCapture { get; set; }
[IniProperty("WindowCaptureMode", Description = "The capture mode used to capture a Window (Screen, GDI, Aero, AeroTransparent, Auto).", DefaultValue = "Auto")]
public WindowCaptureMode WindowCaptureMode;
public WindowCaptureMode WindowCaptureMode { get; set; }
[IniProperty("WindowCaptureAllChildLocations", Description="Enable/disable capture all children, very slow but will make it possible to use this information in the editor.", DefaultValue="False")]
public bool WindowCaptureAllChildLocations;
public bool WindowCaptureAllChildLocations { get; set; }
[IniProperty("DWMBackgroundColor", Description="The background color for a DWM window capture.")]
public Color DWMBackgroundColor;
public Color DWMBackgroundColor { get; set; }
[IniProperty("PlayCameraSound", LanguageKey="settings_playsound",Description="Play a camera sound after taking a capture.", DefaultValue="false")]
public bool PlayCameraSound = false;
public bool PlayCameraSound { get; set; } = false;
[IniProperty("ShowTrayNotification", LanguageKey="settings_shownotify",Description="Show a notification from the systray when a capture is taken.", DefaultValue="true")]
public bool ShowTrayNotification = true;
public bool ShowTrayNotification { get; set; } = true;
[IniProperty("OutputFilePath", Description="Output file path.")]
public string OutputFilePath;
public string OutputFilePath { get; set; }
[IniProperty("OutputFileAllowOverwrite", Description = "If the target file already exists True will make Greenshot always overwrite and False will display a 'Save-As' dialog.", DefaultValue = "true")]
public bool OutputFileAllowOverwrite;
public bool OutputFileAllowOverwrite { get; set; }
[IniProperty("OutputFileFilenamePattern", Description = "Filename pattern for screenshot.", DefaultValue = "${capturetime:d\"yyyy-MM-dd HH_mm_ss\"}-${title}")]
public string OutputFileFilenamePattern;
public string OutputFileFilenamePattern { get; set; }
[IniProperty("OutputFileFormat", Description="Default file type for writing screenshots. (bmp, gif, jpg, png, tiff)", DefaultValue="png")]
public OutputFormat OutputFileFormat = OutputFormat.png;
public OutputFormat OutputFileFormat { get; set; } = OutputFormat.png;
[IniProperty("OutputFileReduceColors", Description="If set to true, than the colors of the output file are reduced to 256 (8-bit) colors", DefaultValue="false")]
public bool OutputFileReduceColors;
public bool OutputFileReduceColors { get; set; }
[IniProperty("OutputFileAutoReduceColors", Description = "If set to true the amount of colors is counted and if smaller than 256 the color reduction is automatically used.", DefaultValue = "false")]
public bool OutputFileAutoReduceColors;
public bool OutputFileAutoReduceColors { get; set; }
[IniProperty("OutputFileReduceColorsTo", Description = "Amount of colors to reduce to, when reducing", DefaultValue = "256")]
public int OutputFileReduceColorsTo;
public int OutputFileReduceColorsTo { get; set; }
[IniProperty("OutputFileCopyPathToClipboard", Description="When saving a screenshot, copy the path to the clipboard?", DefaultValue="true")]
public bool OutputFileCopyPathToClipboard;
public bool OutputFileCopyPathToClipboard { get; set; }
[IniProperty("OutputFileAsFullpath", Description="SaveAs Full path?")]
public string OutputFileAsFullpath;
public string OutputFileAsFullpath { get; set; }
[IniProperty("OutputFileJpegQuality", Description="JPEG file save quality in %.", DefaultValue="80")]
public int OutputFileJpegQuality;
public int OutputFileJpegQuality { get; set; }
[IniProperty("OutputFilePromptQuality", Description="Ask for the quality before saving?", DefaultValue="false")]
public bool OutputFilePromptQuality;
public bool OutputFilePromptQuality { get; set; }
[IniProperty("OutputFileIncrementingNumber", Description="The number for the ${NUM} in the filename pattern, is increased automatically after each save.", DefaultValue="1")]
public uint OutputFileIncrementingNumber;
public uint OutputFileIncrementingNumber { get; set; }
[IniProperty("OutputPrintPromptOptions", LanguageKey="settings_alwaysshowprintoptionsdialog", Description="Ask for print options when printing?", DefaultValue="true")]
public bool OutputPrintPromptOptions;
public bool OutputPrintPromptOptions { get; set; }
[IniProperty("OutputPrintAllowRotate", LanguageKey="printoptions_allowrotate", Description="Allow rotating the picture for fitting on paper?", DefaultValue="false")]
public bool OutputPrintAllowRotate;
public bool OutputPrintAllowRotate { get; set; }
[IniProperty("OutputPrintAllowEnlarge", LanguageKey="printoptions_allowenlarge", Description="Allow growing the picture for fitting on paper?", DefaultValue="false")]
public bool OutputPrintAllowEnlarge;
public bool OutputPrintAllowEnlarge { get; set; }
[IniProperty("OutputPrintAllowShrink", LanguageKey="printoptions_allowshrink", Description="Allow shrinking the picture for fitting on paper?", DefaultValue="true")]
public bool OutputPrintAllowShrink;
public bool OutputPrintAllowShrink { get; set; }
[IniProperty("OutputPrintCenter", LanguageKey="printoptions_allowcenter", Description="Center image when printing?", DefaultValue="true")]
public bool OutputPrintCenter;
public bool OutputPrintCenter { get; set; }
[IniProperty("OutputPrintInverted", LanguageKey="printoptions_inverted", Description="Print image inverted (use e.g. for console captures)", DefaultValue="false")]
public bool OutputPrintInverted;
public bool OutputPrintInverted { get; set; }
[IniProperty("OutputPrintGrayscale", LanguageKey = "printoptions_printgrayscale", Description = "Force grayscale printing", DefaultValue = "false")]
public bool OutputPrintGrayscale;
public bool OutputPrintGrayscale { get; set; }
[IniProperty("OutputPrintMonochrome", LanguageKey = "printoptions_printmonochrome", Description = "Force monorchrome printing", DefaultValue = "false")]
public bool OutputPrintMonochrome;
public bool OutputPrintMonochrome { get; set; }
[IniProperty("OutputPrintMonochromeThreshold", Description = "Threshold for monochrome filter (0 - 255), lower value means less black", DefaultValue = "127")]
public byte OutputPrintMonochromeThreshold;
public byte OutputPrintMonochromeThreshold { get; set; }
[IniProperty("OutputPrintFooter", LanguageKey = "printoptions_timestamp", Description = "Print footer on print?", DefaultValue = "true")]
public bool OutputPrintFooter;
public bool OutputPrintFooter { get; set; }
[IniProperty("OutputPrintFooterPattern", Description = "Footer pattern", DefaultValue = "${capturetime:d\"D\"} ${capturetime:d\"T\"} - ${title}")]
public string OutputPrintFooterPattern;
public string OutputPrintFooterPattern { get; set; }
[IniProperty("NotificationSound", Description = "The wav-file to play when a capture is taken, loaded only once at the Greenshot startup", DefaultValue="default")]
public string NotificationSound;
public string NotificationSound { get; set; }
[IniProperty("UseProxy", Description="Use your global proxy?", DefaultValue="True")]
public bool UseProxy;
public bool UseProxy { get; set; }
[IniProperty("IECapture", Description="Enable/disable IE capture", DefaultValue="True")]
public bool IECapture;
public bool IECapture { get; set; }
[IniProperty("IEFieldCapture", Description="Enable/disable IE field capture, very slow but will make it possible to annotate the fields of a capture in the editor.", DefaultValue="False")]
public bool IEFieldCapture;
public bool IEFieldCapture { get; set; }
[IniProperty("WindowClassesToCheckForIE", Description = "Comma separated list of Window-Classes which need to be checked for a IE instance!", DefaultValue = "AfxFrameOrView70,IMWindowClass")]
public List<string> WindowClassesToCheckForIE;
public List<string> WindowClassesToCheckForIE { get; set; }
[IniProperty("AutoCropDifference", Description="Sets how to compare the colors for the autocrop detection, the higher the more is 'selected'. Possible values are from 0 to 255, where everything above ~150 doesn't make much sense!", DefaultValue="10")]
public int AutoCropDifference;
public int AutoCropDifference { get; set; }
[IniProperty("IncludePlugins", Description="Comma separated list of Plugins which are allowed. If something in the list, than every plugin not in the list will not be loaded!")]
public List<string> IncludePlugins;
public List<string> IncludePlugins { get; set; }
[IniProperty("ExcludePlugins", Description="Comma separated list of Plugins which are NOT allowed.")]
public List<string> ExcludePlugins;
public List<string> ExcludePlugins { get; set; }
[IniProperty("ExcludeDestinations", Description = "Comma separated list of destinations which should be disabled.")]
public List<string> ExcludeDestinations;
public List<string> ExcludeDestinations { get; set; }
[IniProperty("UpdateCheckInterval", Description="How many days between every update check? (0=no checks)", DefaultValue="1")]
public int UpdateCheckInterval;
public int UpdateCheckInterval { get; set; }
[IniProperty("LastUpdateCheck", Description="Last update check")]
public DateTime LastUpdateCheck;
public DateTime LastUpdateCheck { get; set; }
[IniProperty("DisableSettings", Description = "Enable/disable the access to the settings, can only be changed manually in this .ini", DefaultValue = "False")]
public bool DisableSettings;
public bool DisableSettings { get; set; }
[IniProperty("DisableQuickSettings", Description = "Enable/disable the access to the quick settings, can only be changed manually in this .ini", DefaultValue = "False")]
public bool DisableQuickSettings;
public bool DisableQuickSettings { get; set; }
[IniProperty("DisableTrayicon", Description = "Disable the trayicon, can only be changed manually in this .ini", DefaultValue = "False")]
public bool HideTrayicon;
public bool HideTrayicon { get; set; }
[IniProperty("HideExpertSettings", Description = "Hide expert tab in the settings, can only be changed manually in this .ini", DefaultValue = "False")]
public bool HideExpertSettings;
public bool HideExpertSettings { get; set; }
[IniProperty("ThumnailPreview", Description="Enable/disable thumbnail previews", DefaultValue="True")]
public bool ThumnailPreview;
public bool ThumnailPreview { get; set; }
[IniProperty("NoGDICaptureForProduct", Description = "List of productnames for which GDI capturing is skipped (using fallback).", DefaultValue = "IntelliJ IDEA")]
public List<string> NoGDICaptureForProduct;
public List<string> NoGDICaptureForProduct { get; set; }
[IniProperty("NoDWMCaptureForProduct", Description = "List of productnames for which DWM capturing is skipped (using fallback).", DefaultValue = "Citrix ICA Client")]
public List<string> NoDWMCaptureForProduct;
public List<string> NoDWMCaptureForProduct { get; set; }
[IniProperty("OptimizeForRDP", Description="Make some optimizations for usage with remote desktop", DefaultValue="False")]
public bool OptimizeForRDP;
public bool OptimizeForRDP { get; set; }
[IniProperty("DisableRDPOptimizing", Description = "Disable all optimizations for usage with remote desktop", DefaultValue = "False")]
public bool DisableRDPOptimizing;
public bool DisableRDPOptimizing { get; set; }
[IniProperty("MinimizeWorkingSetSize", Description="Optimize memory footprint, but with a performance penalty!", DefaultValue="False")]
public bool MinimizeWorkingSetSize;
public bool MinimizeWorkingSetSize { get; set; }
[IniProperty("WindowCaptureRemoveCorners", Description = "Remove the corners from a window capture", DefaultValue = "True")]
public bool WindowCaptureRemoveCorners;
public bool WindowCaptureRemoveCorners { get; set; }
[IniProperty("CheckForUnstable", Description = "Also check for unstable version updates", DefaultValue = "False")]
public bool CheckForUnstable;
public bool CheckForUnstable { get; set; }
[IniProperty("ActiveTitleFixes", Description="The fixes that are active.")]
public List<string> ActiveTitleFixes;
public List<string> ActiveTitleFixes { get; set; }
[IniProperty("TitleFixMatcher", Description="The regular expressions to match the title with.")]
public Dictionary<string, string> TitleFixMatcher;
public Dictionary<string, string> TitleFixMatcher { get; set; }
[IniProperty("TitleFixReplacer", Description="The replacements for the matchers.")]
public Dictionary<string, string> TitleFixReplacer;
public Dictionary<string, string> TitleFixReplacer { get; set; }
[IniProperty("ExperimentalFeatures", Description="A list of experimental features, this allows us to test certain features before releasing them.", ExcludeIfNull=true)]
public List<string> ExperimentalFeatures;
public List<string> ExperimentalFeatures { get; set; }
[IniProperty("EnableSpecialDIBClipboardReader", Description = "Enable a special DIB clipboard reader", DefaultValue="True")]
public bool EnableSpecialDIBClipboardReader;
public bool EnableSpecialDIBClipboardReader { get; set; }
[IniProperty("WindowCornerCutShape", Description = "The cutshape which is used to remove the window corners, is mirrorred for all corners", DefaultValue = "5,3,2,1,1")]
public List<int> WindowCornerCutShape;
public List<int> WindowCornerCutShape { get; set; }
[IniProperty("LeftClickAction", Description = "Specify what action is made if the tray icon is left clicked, if a double-click action is specified this action is initiated after a delay (configurable via the windows double-click speed)", DefaultValue = "SHOW_CONTEXT_MENU")]
public ClickActions LeftClickAction;
public ClickActions LeftClickAction { get; set; }
[IniProperty("DoubleClickAction", Description = "Specify what action is made if the tray icon is double clicked", DefaultValue = "OPEN_LAST_IN_EXPLORER")]
public ClickActions DoubleClickAction;
public ClickActions DoubleClickAction { get; set; }
[IniProperty("ZoomerEnabled", Description = "Sets if the zoomer is enabled", DefaultValue = "True")]
public bool ZoomerEnabled;
public bool ZoomerEnabled { get; set; }
[IniProperty("ZoomerOpacity", Description = "Specify the transparency for the zoomer, from 0-1 (where 1 is no transparency and 0 is complete transparent. An usefull setting would be 0.7)", DefaultValue = "1")]
public float ZoomerOpacity;
public float ZoomerOpacity { get; set; }
[IniProperty("MaxMenuItemLength", Description = "Maximum length of submenu items in the context menu, making this longer might cause context menu issues on dual screen systems.", DefaultValue = "25")]
public int MaxMenuItemLength;
public int MaxMenuItemLength { get; set; }
[IniProperty("MailApiTo", Description = "The 'to' field for the email destination (settings for Outlook can be found under the Office section)", DefaultValue = "")]
public string MailApiTo;
public string MailApiTo { get; set; }
[IniProperty("MailApiCC", Description = "The 'CC' field for the email destination (settings for Outlook can be found under the Office section)", DefaultValue = "")]
public string MailApiCC;
public string MailApiCC { get; set; }
[IniProperty("MailApiBCC", Description = "The 'BCC' field for the email destination (settings for Outlook can be found under the Office section)", DefaultValue = "")]
public string MailApiBCC;
public string MailApiBCC { get; set; }
[IniProperty("OptimizePNGCommand", Description = "Optional command to execute on a temporary PNG file, the command should overwrite the file and Greenshot will read it back. Note: this command is also executed when uploading PNG's!", DefaultValue = "")]
public string OptimizePNGCommand;
public string OptimizePNGCommand { get; set; }
[IniProperty("OptimizePNGCommandArguments", Description = "Arguments for the optional command to execute on a PNG, {0} is replaced by the temp-filename from Greenshot. Note: Temp-file is deleted afterwards by Greenshot.", DefaultValue = "\"{0}\"")]
public string OptimizePNGCommandArguments;
public string OptimizePNGCommandArguments { get; set; }
[IniProperty("LastSaveWithVersion", Description = "Version of Greenshot which created this .ini")]
public string LastSaveWithVersion;
public string LastSaveWithVersion { get; set; }
[IniProperty("ProcessEXIFOrientation", Description = "When reading images from files or clipboard, use the EXIF information to correct the orientation", DefaultValue = "True")]
public bool ProcessEXIFOrientation;
public bool ProcessEXIFOrientation { get; set; }
[IniProperty("LastCapturedRegion", Description = "The last used region, for reuse in the capture last region")]
public Rectangle LastCapturedRegion;
public Rectangle LastCapturedRegion { get; set; }
private Size _iconSize;
[IniProperty("IconSize", Description = "Defines the size of the icons (e.g. for the buttons in the editor), default value 16,16 anything bigger will cause scaling", DefaultValue = "16,16")]
@ -295,9 +295,9 @@ namespace GreenshotPlugin.Core {
}
[IniProperty("WebRequestTimeout", Description = "The connect timeout value for webrequets, these are seconds", DefaultValue = "100")]
public int WebRequestTimeout;
public int WebRequestTimeout { get; set; }
[IniProperty("WebRequestReadWriteTimeout", Description = "The read/write timeout value for webrequets, these are seconds", DefaultValue = "100")]
public int WebRequestReadWriteTimeout;
public int WebRequestReadWriteTimeout { get; set; }
/// <summary>
/// Specifies what THIS build is

View file

@ -25,37 +25,37 @@ using System.Text;
using System.Threading;
using System.Windows.Forms;
/// <summary>
/// The following code comes from: http://www.developerfusion.com/code/4693/using-the-credential-management-api/
/// and is slightly modified so it works for us.
/// As the "Stored usernames and passwords" which can be accessed by: Start-> Run and type "Control keymgr.dll"
/// doesn't show all credentials use the tool here: http://www.microsoft.com/indonesia/msdn/credmgmt.aspx
/// The following code is an example for a login, it will call the Authenticate with user/password
/// which should return true if the login worked, false if not.
/// private static bool Login(string system, string name) {
/// try {
/// CredentialsDialog dialog = new CredentialsDialog(system);
/// dialog.Name = name;
/// while (dialog.Show(dialog.Name) == DialogResult.OK) {
/// if (Authenticate(dialog.Name, dialog.Password)) {
/// if (dialog.SaveChecked) dialog.Confirm(true);
/// return true;
/// } else {
/// try {
/// dialog.Confirm(false);
/// } catch (ApplicationException) {
/// // exception handling ...
/// }
/// dialog.IncorrectPassword = true;
/// }
/// }
/// } catch (ApplicationException) {
/// // exception handling ...
/// }
/// return false;
/// }
/// </summary>
namespace GreenshotPlugin.Core {
/// <summary>
/// The following code comes from: http://www.developerfusion.com/code/4693/using-the-credential-management-api/
/// and is slightly modified so it works for us.
/// As the "Stored usernames and passwords" which can be accessed by: Start-> Run and type "Control keymgr.dll"
/// doesn't show all credentials use the tool here: http://www.microsoft.com/indonesia/msdn/credmgmt.aspx
/// The following code is an example for a login, it will call the Authenticate with user/password
/// which should return true if the login worked, false if not.
/// private static bool Login(string system, string name) {
/// try {
/// CredentialsDialog dialog = new CredentialsDialog(system);
/// dialog.Name = name;
/// while (dialog.Show(dialog.Name) == DialogResult.OK) {
/// if (Authenticate(dialog.Name, dialog.Password)) {
/// if (dialog.SaveChecked) dialog.Confirm(true);
/// return true;
/// } else {
/// try {
/// dialog.Confirm(false);
/// } catch (ApplicationException) {
/// // exception handling ...
/// }
/// dialog.IncorrectPassword = true;
/// }
/// }
/// } catch (ApplicationException) {
/// // exception handling ...
/// }
/// return false;
/// }
/// </summary>
/// <summary>Encapsulates dialog functionality from the Credential Management API.</summary>
public sealed class CredentialsDialog {
[DllImport("gdi32.dll", SetLastError=true)]

View file

@ -52,7 +52,8 @@ namespace GreenshotPlugin.Core {
/// The returned byte[] color depends on the underlying pixel format
/// </summary>
/// <param name="x">int x</param>
/// <param name="y">int y</par
/// <param name="y">int y</param>
/// <param name="color">byte array</param>
void GetColorAt(int x, int y, byte[] color);
/// <summary>
@ -139,7 +140,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Returns if this FastBitmap has an alpha channel
/// </summary>
bool hasAlphaChannel {
bool HasAlphaChannel {
get;
}
@ -216,7 +217,8 @@ namespace GreenshotPlugin.Core {
/// The returned byte[] color depends on the underlying pixel format
/// </summary>
/// <param name="x">int x</param>
/// <param name="y">int y</par
/// <param name="y">int y</param>
/// <param name="color">byte array</param>
new void GetColorAt(int x, int y, byte[] color);
new int Left {
@ -283,20 +285,20 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// The base class for the fast bitmap implementation
/// </summary>
public unsafe abstract class FastBitmap : IFastBitmap, IFastBitmapWithClip, IFastBitmapWithOffset {
private static ILog LOG = LogManager.GetLogger(typeof(FastBitmap));
public abstract unsafe class FastBitmap : IFastBitmap, IFastBitmapWithClip, IFastBitmapWithOffset {
private static ILog _log = LogManager.GetLogger(typeof(FastBitmap));
protected const int PIXELFORMAT_INDEX_A = 3;
protected const int PIXELFORMAT_INDEX_R = 2;
protected const int PIXELFORMAT_INDEX_G = 1;
protected const int PIXELFORMAT_INDEX_B = 0;
protected const int PixelformatIndexA = 3;
protected const int PixelformatIndexR = 2;
protected const int PixelformatIndexG = 1;
protected const int PixelformatIndexB = 0;
public const int COLOR_INDEX_R = 0;
public const int COLOR_INDEX_G = 1;
public const int COLOR_INDEX_B = 2;
public const int COLOR_INDEX_A = 3;
public const int ColorIndexR = 0;
public const int ColorIndexG = 1;
public const int ColorIndexB = 2;
public const int ColorIndexA = 3;
protected Rectangle area = Rectangle.Empty;
protected Rectangle Area = Rectangle.Empty;
/// <summary>
/// If this is set to true, the bitmap will be disposed when disposing the IFastBitmap
/// </summary>
@ -318,19 +320,19 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// The bitmap for which the FastBitmap is creating access
/// </summary>
protected Bitmap bitmap;
protected Bitmap Bitmap;
protected BitmapData bmData;
protected int stride; /* bytes per pixel row */
protected bool bitsLocked;
protected byte* pointer;
protected BitmapData BmData;
protected int Stride; /* bytes per pixel row */
protected bool BitsLocked;
protected byte* Pointer;
public static IFastBitmap Create(Bitmap source) {
return Create(source, Rectangle.Empty);
}
public void SetResolution(float horizontal, float vertical) {
bitmap.SetResolution(horizontal, vertical);
Bitmap.SetResolution(horizontal, vertical);
}
/// <summary>
@ -345,12 +347,12 @@ namespace GreenshotPlugin.Core {
case PixelFormat.Format8bppIndexed:
return new FastChunkyBitmap(source, area);
case PixelFormat.Format24bppRgb:
return new Fast24RGBBitmap(source, area);
return new Fast24RgbBitmap(source, area);
case PixelFormat.Format32bppRgb:
return new Fast32RGBBitmap(source, area);
return new Fast32RgbBitmap(source, area);
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
return new Fast32ARGBBitmap(source, area);
return new Fast32ArgbBitmap(source, area);
default:
throw new NotSupportedException(string.Format("Not supported Pixelformat {0}", source.PixelFormat));
}
@ -417,21 +419,22 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Constructor which stores the image and locks it when called
/// </summary>
/// <param name="bitmap"></param>
/// <param name="bitmap">Bitmap</param>
/// <param name="area">Rectangle</param>
protected FastBitmap(Bitmap bitmap, Rectangle area) {
this.bitmap = bitmap;
Bitmap = bitmap;
Rectangle bitmapArea = new Rectangle(Point.Empty, bitmap.Size);
if (area != Rectangle.Empty) {
area.Intersect(bitmapArea);
this.area = area;
Area = area;
} else {
this.area = bitmapArea;
Area = bitmapArea;
}
// As the lock takes care that only the specified area is made available we need to calculate the offset
Left = area.Left;
Top = area.Top;
// Default cliping is done to the area without invert
Clip = this.area;
Clip = Area;
InvertClip = false;
// Always lock, so we don't need to do this ourselves
Lock();
@ -442,10 +445,10 @@ namespace GreenshotPlugin.Core {
/// </summary>
public Size Size {
get {
if (area == Rectangle.Empty) {
return bitmap.Size;
if (Area == Rectangle.Empty) {
return Bitmap.Size;
}
return area.Size;
return Area.Size;
}
}
@ -454,10 +457,10 @@ namespace GreenshotPlugin.Core {
/// </summary>
public int Width {
get {
if (area == Rectangle.Empty) {
return bitmap.Width;
if (Area == Rectangle.Empty) {
return Bitmap.Width;
}
return area.Width;
return Area.Width;
}
}
@ -466,14 +469,14 @@ namespace GreenshotPlugin.Core {
/// </summary>
public int Height {
get {
if (area == Rectangle.Empty) {
return bitmap.Height;
if (Area == Rectangle.Empty) {
return Bitmap.Height;
}
return area.Height;
return Area.Height;
}
}
private int left;
private int _left;
/// <summary>
/// Return the left of the fastbitmap, this is also used as an offset
/// </summary>
@ -482,7 +485,7 @@ namespace GreenshotPlugin.Core {
return 0;
}
set {
left = value;
_left = value;
}
}
@ -491,14 +494,14 @@ namespace GreenshotPlugin.Core {
/// </summary>
int IFastBitmapWithOffset.Left {
get {
return left;
return _left;
}
set {
left = value;
_left = value;
}
}
private int top;
private int _top;
/// <summary>
/// Return the top of the fastbitmap, this is also used as an offset
/// </summary>
@ -507,7 +510,7 @@ namespace GreenshotPlugin.Core {
return 0;
}
set {
top = value;
_top = value;
}
}
@ -516,10 +519,10 @@ namespace GreenshotPlugin.Core {
/// </summary>
int IFastBitmapWithOffset.Top {
get {
return top;
return _top;
}
set {
top = value;
_top = value;
}
}
@ -545,14 +548,14 @@ namespace GreenshotPlugin.Core {
/// Returns the underlying bitmap, unlocks it and prevents that it will be disposed
/// </summary>
public Bitmap UnlockAndReturnBitmap() {
if (bitsLocked) {
if (BitsLocked) {
Unlock();
}
NeedsDispose = false;
return bitmap;
return Bitmap;
}
public virtual bool hasAlphaChannel {
public virtual bool HasAlphaChannel {
get {
return false;
}
@ -584,26 +587,26 @@ namespace GreenshotPlugin.Core {
protected virtual void Dispose(bool disposing) {
Unlock();
if (disposing) {
if (bitmap != null && NeedsDispose) {
bitmap.Dispose();
if (Bitmap != null && NeedsDispose) {
Bitmap.Dispose();
}
}
bitmap = null;
bmData = null;
pointer = null;
Bitmap = null;
BmData = null;
Pointer = null;
}
/// <summary>
/// Lock the bitmap so we have direct access to the memory
/// </summary>
public void Lock() {
if (Width > 0 && Height > 0 && !bitsLocked) {
bmData = bitmap.LockBits(area, ImageLockMode.ReadWrite, bitmap.PixelFormat);
bitsLocked = true;
if (Width > 0 && Height > 0 && !BitsLocked) {
BmData = Bitmap.LockBits(Area, ImageLockMode.ReadWrite, Bitmap.PixelFormat);
BitsLocked = true;
IntPtr Scan0 = bmData.Scan0;
pointer = (byte*)(void*)Scan0;
stride = bmData.Stride;
IntPtr scan0 = BmData.Scan0;
Pointer = (byte*)(void*)scan0;
Stride = BmData.Stride;
}
}
@ -611,9 +614,9 @@ namespace GreenshotPlugin.Core {
/// Unlock the System Memory
/// </summary>
public void Unlock() {
if (bitsLocked) {
bitmap.UnlockBits(bmData);
bitsLocked = false;
if (BitsLocked) {
Bitmap.UnlockBits(BmData);
BitsLocked = false;
}
}
@ -623,7 +626,7 @@ namespace GreenshotPlugin.Core {
/// <param name="graphics"></param>
/// <param name="destination"></param>
public void DrawTo(Graphics graphics, Point destination) {
DrawTo(graphics, new Rectangle(destination, area.Size));
DrawTo(graphics, new Rectangle(destination, Area.Size));
}
/// <summary>
@ -635,12 +638,12 @@ namespace GreenshotPlugin.Core {
/// <param name="destination"></param>
public void DrawTo(Graphics graphics, Rectangle destinationRect) {
// Make sure this.bitmap is unlocked, if it was locked
bool isLocked = bitsLocked;
bool isLocked = BitsLocked;
if (isLocked) {
Unlock();
}
graphics.DrawImage(bitmap, destinationRect, area, GraphicsUnit.Pixel);
graphics.DrawImage(Bitmap, destinationRect, Area, GraphicsUnit.Pixel);
}
/// <summary>
@ -650,7 +653,7 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <returns>true if x & y are inside the FastBitmap</returns>
public bool Contains(int x, int y) {
return area.Contains(x - Left, y - Top);
return Area.Contains(x - Left, y - Top);
}
public abstract Color GetColorAt(int x, int y);
@ -693,29 +696,29 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <returns>true if x & y are inside the FastBitmap</returns>
bool IFastBitmapWithOffset.Contains(int x, int y) {
return area.Contains(x - Left, y - Top);
return Area.Contains(x - Left, y - Top);
}
Color IFastBitmapWithOffset.GetColorAt(int x, int y) {
x -= left;
y -= top;
x -= _left;
y -= _top;
return GetColorAt(x, y);
}
void IFastBitmapWithOffset.GetColorAt(int x, int y, byte[] color) {
x -= left;
y -= top;
x -= _left;
y -= _top;
GetColorAt(x, y, color);
}
void IFastBitmapWithOffset.SetColorAt(int x, int y, byte[] color) {
x -= left;
y -= top;
x -= _left;
y -= _top;
SetColorAt(x, y, color);
}
void IFastBitmapWithOffset.SetColorAt(int x, int y, Color color) {
x -= left;
y -= top;
x -= _left;
y -= _top;
SetColorAt(x, y, color);
}
#endregion
@ -726,11 +729,11 @@ namespace GreenshotPlugin.Core {
/// </summary>
public unsafe class FastChunkyBitmap : FastBitmap {
// Used for indexed images
private readonly Color[] colorEntries;
private readonly Dictionary<Color, byte> colorCache = new Dictionary<Color, byte>();
private readonly Color[] _colorEntries;
private readonly Dictionary<Color, byte> _colorCache = new Dictionary<Color, byte>();
public FastChunkyBitmap(Bitmap source, Rectangle area) : base(source, area) {
colorEntries = bitmap.Palette.Entries;
_colorEntries = Bitmap.Palette.Entries;
}
/// <summary>
@ -740,9 +743,9 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <returns>Color</returns>
public override Color GetColorAt(int x, int y) {
int offset = x + (y * stride);
byte colorIndex = pointer[offset];
return colorEntries[colorIndex];
int offset = x + (y * Stride);
byte colorIndex = Pointer[offset];
return _colorEntries[colorIndex];
}
/// <summary>
@ -772,8 +775,8 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <returns>byte with index</returns>
public byte GetColorIndexAt(int x, int y) {
int offset = x + (y * stride);
return pointer[offset];
int offset = x + (y * Stride);
return Pointer[offset];
}
/// <summary>
@ -781,10 +784,10 @@ namespace GreenshotPlugin.Core {
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="color-index"></param>
/// <param name="colorIndex"></param>
public void SetColorIndexAt(int x, int y, byte colorIndex) {
int offset = x + (y * stride);
pointer[offset] = colorIndex;
int offset = x + (y * Stride);
Pointer[offset] = colorIndex;
}
/// <summary>
@ -795,13 +798,13 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <param name="color">Color to set</param>
public override void SetColorAt(int x, int y, Color color) {
int offset = x + (y * stride);
int offset = x + (y * Stride);
byte colorIndex;
if (!colorCache.TryGetValue(color, out colorIndex)) {
if (!_colorCache.TryGetValue(color, out colorIndex)) {
bool foundColor = false;
for (colorIndex = 0; colorIndex < colorEntries.Length; colorIndex++) {
if (color == colorEntries[colorIndex]) {
colorCache.Add(color, colorIndex);
for (colorIndex = 0; colorIndex < _colorEntries.Length; colorIndex++) {
if (color == _colorEntries[colorIndex]) {
_colorCache.Add(color, colorIndex);
foundColor = true;
break;
}
@ -810,16 +813,16 @@ namespace GreenshotPlugin.Core {
throw new ArgumentException("No such color!");
}
}
pointer[offset] = colorIndex;
Pointer[offset] = colorIndex;
}
}
/// <summary>
/// This is the implementation of the IFastBitmap for 24 bit images (no Alpha)
/// </summary>
public unsafe class Fast24RGBBitmap : FastBitmap {
public unsafe class Fast24RgbBitmap : FastBitmap {
public Fast24RGBBitmap(Bitmap source, Rectangle area) : base(source, area) {
public Fast24RgbBitmap(Bitmap source, Rectangle area) : base(source, area) {
}
/// <summary>
@ -830,8 +833,8 @@ namespace GreenshotPlugin.Core {
/// <param name="y">Y Coordinate</param>
/// <returns>Color</returns>
public override Color GetColorAt(int x, int y) {
int offset = (x * 3) + (y * stride);
return Color.FromArgb(255, pointer[PIXELFORMAT_INDEX_R + offset], pointer[PIXELFORMAT_INDEX_G + offset], pointer[PIXELFORMAT_INDEX_B + offset]);
int offset = (x * 3) + (y * Stride);
return Color.FromArgb(255, Pointer[PixelformatIndexR + offset], Pointer[PixelformatIndexG + offset], Pointer[PixelformatIndexB + offset]);
}
/// <summary>
@ -842,10 +845,10 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <param name="color"></param>
public override void SetColorAt(int x, int y, Color color) {
int offset = (x * 3) + (y * stride);
pointer[PIXELFORMAT_INDEX_R + offset] = color.R;
pointer[PIXELFORMAT_INDEX_G + offset] = color.G;
pointer[PIXELFORMAT_INDEX_B + offset] = color.B;
int offset = (x * 3) + (y * Stride);
Pointer[PixelformatIndexR + offset] = color.R;
Pointer[PixelformatIndexG + offset] = color.G;
Pointer[PixelformatIndexB + offset] = color.B;
}
/// <summary>
@ -855,10 +858,10 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <param name="color">byte[4] as reference (r,g,b)</param>
public override void GetColorAt(int x, int y, byte[] color) {
int offset = (x * 3) + (y * stride);
color[PIXELFORMAT_INDEX_R] = pointer[PIXELFORMAT_INDEX_R + offset];
color[PIXELFORMAT_INDEX_G] = pointer[PIXELFORMAT_INDEX_G + offset];
color[PIXELFORMAT_INDEX_B] = pointer[PIXELFORMAT_INDEX_B + offset];
int offset = (x * 3) + (y * Stride);
color[PixelformatIndexR] = Pointer[PixelformatIndexR + offset];
color[PixelformatIndexG] = Pointer[PixelformatIndexG + offset];
color[PixelformatIndexB] = Pointer[PixelformatIndexB + offset];
}
/// <summary>
@ -868,10 +871,10 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <param name="color">byte[4] as reference (r,g,b)</param>
public override void SetColorAt(int x, int y, byte[] color) {
int offset = (x * 3) + (y * stride);
pointer[PIXELFORMAT_INDEX_R + offset] = color[PIXELFORMAT_INDEX_R];
pointer[PIXELFORMAT_INDEX_G + offset] = color[PIXELFORMAT_INDEX_G];
pointer[PIXELFORMAT_INDEX_B + offset] = color[PIXELFORMAT_INDEX_B];
int offset = (x * 3) + (y * Stride);
Pointer[PixelformatIndexR + offset] = color[PixelformatIndexR];
Pointer[PixelformatIndexG + offset] = color[PixelformatIndexG];
Pointer[PixelformatIndexB + offset] = color[PixelformatIndexB];
}
}
@ -879,8 +882,8 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// This is the implementation of the IFastBitmap for 32 bit images (no Alpha)
/// </summary>
public unsafe class Fast32RGBBitmap : FastBitmap {
public Fast32RGBBitmap(Bitmap source, Rectangle area) : base(source, area) {
public unsafe class Fast32RgbBitmap : FastBitmap {
public Fast32RgbBitmap(Bitmap source, Rectangle area) : base(source, area) {
}
@ -892,8 +895,8 @@ namespace GreenshotPlugin.Core {
/// <param name="y">Y Coordinate</param>
/// <returns>Color</returns>
public override Color GetColorAt(int x, int y) {
int offset = (x * 4) + (y * stride);
return Color.FromArgb(255, pointer[PIXELFORMAT_INDEX_R + offset], pointer[PIXELFORMAT_INDEX_G + offset], pointer[PIXELFORMAT_INDEX_B + offset]);
int offset = (x * 4) + (y * Stride);
return Color.FromArgb(255, Pointer[PixelformatIndexR + offset], Pointer[PixelformatIndexG + offset], Pointer[PixelformatIndexB + offset]);
}
/// <summary>
@ -904,10 +907,10 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <param name="color"></param>
public override void SetColorAt(int x, int y, Color color) {
int offset = (x * 4) + (y * stride);
pointer[PIXELFORMAT_INDEX_R + offset] = color.R;
pointer[PIXELFORMAT_INDEX_G + offset] = color.G;
pointer[PIXELFORMAT_INDEX_B + offset] = color.B;
int offset = (x * 4) + (y * Stride);
Pointer[PixelformatIndexR + offset] = color.R;
Pointer[PixelformatIndexG + offset] = color.G;
Pointer[PixelformatIndexB + offset] = color.B;
}
/// <summary>
@ -917,10 +920,10 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <param name="color">byte[4] as reference (a,r,g,b)</param>
public override void GetColorAt(int x, int y, byte[] color) {
int offset = (x * 4) + (y * stride);
color[COLOR_INDEX_R] = pointer[PIXELFORMAT_INDEX_R + offset];
color[COLOR_INDEX_G] = pointer[PIXELFORMAT_INDEX_G + offset];
color[COLOR_INDEX_B] = pointer[PIXELFORMAT_INDEX_B + offset];
int offset = (x * 4) + (y * Stride);
color[ColorIndexR] = Pointer[PixelformatIndexR + offset];
color[ColorIndexG] = Pointer[PixelformatIndexG + offset];
color[ColorIndexB] = Pointer[PixelformatIndexB + offset];
}
/// <summary>
@ -930,18 +933,18 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <param name="color">byte[4] as reference (r,g,b)</param>
public override void SetColorAt(int x, int y, byte[] color) {
int offset = (x * 4) + (y * stride);
pointer[PIXELFORMAT_INDEX_R + offset] = color[COLOR_INDEX_R]; // R
pointer[PIXELFORMAT_INDEX_G + offset] = color[COLOR_INDEX_G];
pointer[PIXELFORMAT_INDEX_B + offset] = color[COLOR_INDEX_B];
int offset = (x * 4) + (y * Stride);
Pointer[PixelformatIndexR + offset] = color[ColorIndexR]; // R
Pointer[PixelformatIndexG + offset] = color[ColorIndexG];
Pointer[PixelformatIndexB + offset] = color[ColorIndexB];
}
}
/// <summary>
/// This is the implementation of the IFastBitmap for 32 bit images with Alpha
/// </summary>
public unsafe class Fast32ARGBBitmap : FastBitmap, IFastBitmapWithBlend {
public override bool hasAlphaChannel {
public unsafe class Fast32ArgbBitmap : FastBitmap, IFastBitmapWithBlend {
public override bool HasAlphaChannel {
get {
return true;
}
@ -951,7 +954,7 @@ namespace GreenshotPlugin.Core {
get;
set;
}
public Fast32ARGBBitmap(Bitmap source, Rectangle area) : base(source, area) {
public Fast32ArgbBitmap(Bitmap source, Rectangle area) : base(source, area) {
BackgroundBlendColor = Color.White;
}
@ -962,8 +965,8 @@ namespace GreenshotPlugin.Core {
/// <param name="y">Y Coordinate</param>
/// <returns>Color</returns>
public override Color GetColorAt(int x, int y) {
int offset = (x * 4) + (y * stride);
return Color.FromArgb(pointer[PIXELFORMAT_INDEX_A + offset], pointer[PIXELFORMAT_INDEX_R + offset], pointer[PIXELFORMAT_INDEX_G + offset], pointer[PIXELFORMAT_INDEX_B + offset]);
int offset = (x * 4) + (y * Stride);
return Color.FromArgb(Pointer[PixelformatIndexA + offset], Pointer[PixelformatIndexR + offset], Pointer[PixelformatIndexG + offset], Pointer[PixelformatIndexB + offset]);
}
/// <summary>
@ -974,11 +977,11 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <param name="color"></param>
public override void SetColorAt(int x, int y, Color color) {
int offset = (x * 4) + (y * stride);
pointer[PIXELFORMAT_INDEX_A + offset] = color.A;
pointer[PIXELFORMAT_INDEX_R + offset] = color.R;
pointer[PIXELFORMAT_INDEX_G + offset] = color.G;
pointer[PIXELFORMAT_INDEX_B + offset] = color.B;
int offset = (x * 4) + (y * Stride);
Pointer[PixelformatIndexA + offset] = color.A;
Pointer[PixelformatIndexR + offset] = color.R;
Pointer[PixelformatIndexG + offset] = color.G;
Pointer[PixelformatIndexB + offset] = color.B;
}
/// <summary>
@ -988,11 +991,11 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <param name="color">byte[4] as reference (r,g,b,a)</param>
public override void GetColorAt(int x, int y, byte[] color) {
int offset = (x * 4) + (y * stride);
color[COLOR_INDEX_R] = pointer[PIXELFORMAT_INDEX_R + offset];
color[COLOR_INDEX_G] = pointer[PIXELFORMAT_INDEX_G + offset];
color[COLOR_INDEX_B] = pointer[PIXELFORMAT_INDEX_B + offset];
color[COLOR_INDEX_A] = pointer[PIXELFORMAT_INDEX_A + offset];
int offset = (x * 4) + (y * Stride);
color[ColorIndexR] = Pointer[PixelformatIndexR + offset];
color[ColorIndexG] = Pointer[PixelformatIndexG + offset];
color[ColorIndexB] = Pointer[PixelformatIndexB + offset];
color[ColorIndexA] = Pointer[PixelformatIndexA + offset];
}
/// <summary>
@ -1002,11 +1005,11 @@ namespace GreenshotPlugin.Core {
/// <param name="y"></param>
/// <param name="color">byte[4] as reference (r,g,b,a)</param>
public override void SetColorAt(int x, int y, byte[] color) {
int offset = (x * 4) + (y * stride);
pointer[PIXELFORMAT_INDEX_R + offset] = color[COLOR_INDEX_R]; // R
pointer[PIXELFORMAT_INDEX_G + offset] = color[COLOR_INDEX_G];
pointer[PIXELFORMAT_INDEX_B + offset] = color[COLOR_INDEX_B];
pointer[PIXELFORMAT_INDEX_A + offset] = color[COLOR_INDEX_A];
int offset = (x * 4) + (y * Stride);
Pointer[PixelformatIndexR + offset] = color[ColorIndexR]; // R
Pointer[PixelformatIndexG + offset] = color[ColorIndexG];
Pointer[PixelformatIndexB + offset] = color[ColorIndexB];
Pointer[PixelformatIndexA + offset] = color[ColorIndexA];
}
/// <summary>
@ -1017,11 +1020,11 @@ namespace GreenshotPlugin.Core {
/// <param name="y">Y Coordinate</param>
/// <returns>Color</returns>
public Color GetBlendedColorAt(int x, int y) {
int offset = (x * 4) + (y * stride);
int a = pointer[PIXELFORMAT_INDEX_A + offset];
int red = pointer[PIXELFORMAT_INDEX_R + offset];
int green = pointer[PIXELFORMAT_INDEX_G + offset];
int blue = pointer[PIXELFORMAT_INDEX_B + offset];
int offset = (x * 4) + (y * Stride);
int a = Pointer[PixelformatIndexA + offset];
int red = Pointer[PixelformatIndexR + offset];
int green = Pointer[PixelformatIndexG + offset];
int blue = Pointer[PixelformatIndexB + offset];
if (a < 255) {
// As the request is to get without alpha, we blend.

View file

@ -48,7 +48,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Remove invalid characters from the fully qualified filename
/// </summary>
/// <param name="fullpath">string with the full path to a file</param>
/// <param name="fullPath">string with the full path to a file</param>
/// <returns>string with the full path to a file, without invalid characters</returns>
public static string MakeFQFilenameSafe(string fullPath) {
string path = MakePathSafe(Path.GetDirectoryName(fullPath));
@ -60,7 +60,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Remove invalid characters from the filename
/// </summary>
/// <param name="fullpath">string with the full path to a file</param>
/// <param name="filename">string with the full path to a file</param>
/// <returns>string with the full path to a file, without invalid characters</returns>
public static string MakeFilenameSafe(string filename) {
// Make the filename save!
@ -121,6 +121,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// This method will be called by the regexp.replace as a MatchEvaluator delegate!
/// Will delegate this to the MatchVarEvaluatorInternal and catch any exceptions
/// </summary>
/// <param name="match">What are we matching?</param>
/// <param name="captureDetails">The detail, can be null</param>
/// <param name="processVars">Variables from the process</param>
@ -141,6 +142,10 @@ namespace GreenshotPlugin.Core {
/// </summary>
/// <param name="match">What are we matching?</param>
/// <param name="captureDetails">The detail, can be null</param>
/// <param name="processVars"></param>
/// <param name="userVars"></param>
/// <param name="machineVars"></param>
/// <param name="filenameSafeMode"></param>
/// <returns></returns>
private static string MatchVarEvaluatorInternal(Match match, ICaptureDetails captureDetails, IDictionary processVars, IDictionary userVars, IDictionary machineVars, bool filenameSafeMode) {
// some defaults

View file

@ -356,7 +356,6 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648069%28v=vs.85%29.aspx
/// </summary>
/// <param name="icon">The icon to </param>
/// <param name="location">The file (EXE or DLL) to get the icon from</param>
/// <param name="index">Index of the icon</param>
/// <param name="takeLarge">true if the large icon is wanted</param>
@ -409,8 +408,7 @@ namespace GreenshotPlugin.Core {
/// <param name="matrix"></param>
/// <returns>Bitmap</returns>
public static Image ApplyEffect(Image sourceImage, IEffect effect, Matrix matrix) {
List<IEffect> effects = new List<IEffect>();
effects.Add(effect);
List<IEffect> effects = new List<IEffect> {effect};
return ApplyEffects(sourceImage, effects, matrix);
}
@ -418,7 +416,7 @@ namespace GreenshotPlugin.Core {
/// Apply the effects in the supplied order to the bitmap
/// </summary>
/// <param name="sourceImage">Bitmap</param>
/// <param name="effects">List<IEffect></param>
/// <param name="effects">List of IEffect</param>
/// <param name="matrix"></param>
/// <returns>Bitmap</returns>
public static Image ApplyEffects(Image sourceImage, List<IEffect> effects, Matrix matrix) {
@ -577,7 +575,7 @@ namespace GreenshotPlugin.Core {
// By the central limit theorem, if applied 3 times on the same image, a box blur approximates the Gaussian kernel to within about 3%, yielding the same result as a quadratic convolution kernel.
// This might be true, but the GDI+ BlurEffect doesn't look the same, a 2x blur is more simular and we only make 2x Box-Blur.
// (Might also be a mistake in our blur, but for now it looks great)
if (fastBitmap.hasAlphaChannel) {
if (fastBitmap.HasAlphaChannel) {
BoxBlurHorizontalAlpha(fastBitmap, range);
BoxBlurVerticalAlpha(fastBitmap, range);
BoxBlurHorizontalAlpha(fastBitmap, range);
@ -596,7 +594,7 @@ namespace GreenshotPlugin.Core {
/// <param name="targetFastBitmap">Target BitmapBuffer</param>
/// <param name="range">Range must be odd!</param>
private static void BoxBlurHorizontal(IFastBitmap targetFastBitmap, int range) {
if (targetFastBitmap.hasAlphaChannel) {
if (targetFastBitmap.HasAlphaChannel) {
throw new NotSupportedException("BoxBlurHorizontal should NOT be called for bitmaps with alpha channel");
}
int halfRange = range / 2;
@ -611,18 +609,18 @@ namespace GreenshotPlugin.Core {
int oldPixel = x - halfRange - 1;
if (oldPixel >= targetFastBitmap.Left) {
targetFastBitmap.GetColorAt(oldPixel, y, tmpColor);
r -= tmpColor[FastBitmap.COLOR_INDEX_R];
g -= tmpColor[FastBitmap.COLOR_INDEX_G];
b -= tmpColor[FastBitmap.COLOR_INDEX_B];
r -= tmpColor[FastBitmap.ColorIndexR];
g -= tmpColor[FastBitmap.ColorIndexG];
b -= tmpColor[FastBitmap.ColorIndexB];
hits--;
}
int newPixel = x + halfRange;
if (newPixel < targetFastBitmap.Right) {
targetFastBitmap.GetColorAt(newPixel, y, tmpColor);
r += tmpColor[FastBitmap.COLOR_INDEX_R];
g += tmpColor[FastBitmap.COLOR_INDEX_G];
b += tmpColor[FastBitmap.COLOR_INDEX_B];
r += tmpColor[FastBitmap.ColorIndexR];
g += tmpColor[FastBitmap.ColorIndexG];
b += tmpColor[FastBitmap.ColorIndexB];
hits++;
}
@ -641,7 +639,7 @@ namespace GreenshotPlugin.Core {
/// <param name="targetFastBitmap">Target BitmapBuffer</param>
/// <param name="range">Range must be odd!</param>
private static void BoxBlurHorizontalAlpha(IFastBitmap targetFastBitmap, int range) {
if (!targetFastBitmap.hasAlphaChannel) {
if (!targetFastBitmap.HasAlphaChannel) {
throw new NotSupportedException("BoxBlurHorizontalAlpha should be called for bitmaps with alpha channel");
}
int halfRange = range / 2;
@ -657,20 +655,20 @@ namespace GreenshotPlugin.Core {
int oldPixel = x - halfRange - 1;
if (oldPixel >= targetFastBitmap.Left) {
targetFastBitmap.GetColorAt(oldPixel, y, tmpColor);
a -= tmpColor[FastBitmap.COLOR_INDEX_A];
r -= tmpColor[FastBitmap.COLOR_INDEX_R];
g -= tmpColor[FastBitmap.COLOR_INDEX_G];
b -= tmpColor[FastBitmap.COLOR_INDEX_B];
a -= tmpColor[FastBitmap.ColorIndexA];
r -= tmpColor[FastBitmap.ColorIndexR];
g -= tmpColor[FastBitmap.ColorIndexG];
b -= tmpColor[FastBitmap.ColorIndexB];
hits--;
}
int newPixel = x + halfRange;
if (newPixel < targetFastBitmap.Right) {
targetFastBitmap.GetColorAt(newPixel, y, tmpColor);
a += tmpColor[FastBitmap.COLOR_INDEX_A];
r += tmpColor[FastBitmap.COLOR_INDEX_R];
g += tmpColor[FastBitmap.COLOR_INDEX_G];
b += tmpColor[FastBitmap.COLOR_INDEX_B];
a += tmpColor[FastBitmap.ColorIndexA];
r += tmpColor[FastBitmap.ColorIndexR];
g += tmpColor[FastBitmap.ColorIndexG];
b += tmpColor[FastBitmap.ColorIndexB];
hits++;
}
@ -690,7 +688,7 @@ namespace GreenshotPlugin.Core {
/// <param name="targetFastBitmap">BitmapBuffer which previously was created with BoxBlurHorizontal</param>
/// <param name="range">Range must be odd!</param>
private static void BoxBlurVertical(IFastBitmap targetFastBitmap, int range) {
if (targetFastBitmap.hasAlphaChannel) {
if (targetFastBitmap.HasAlphaChannel) {
throw new NotSupportedException("BoxBlurVertical should NOT be called for bitmaps with alpha channel");
}
int halfRange = range / 2;
@ -705,18 +703,18 @@ namespace GreenshotPlugin.Core {
int oldPixel = y - halfRange - 1;
if (oldPixel >= targetFastBitmap.Top) {
targetFastBitmap.GetColorAt(x, oldPixel, tmpColor);
r -= tmpColor[FastBitmap.COLOR_INDEX_R];
g -= tmpColor[FastBitmap.COLOR_INDEX_G];
b -= tmpColor[FastBitmap.COLOR_INDEX_B];
r -= tmpColor[FastBitmap.ColorIndexR];
g -= tmpColor[FastBitmap.ColorIndexG];
b -= tmpColor[FastBitmap.ColorIndexB];
hits--;
}
int newPixel = y + halfRange;
if (newPixel < targetFastBitmap.Bottom) {
targetFastBitmap.GetColorAt(x, newPixel, tmpColor);
r += tmpColor[FastBitmap.COLOR_INDEX_R];
g += tmpColor[FastBitmap.COLOR_INDEX_G];
b += tmpColor[FastBitmap.COLOR_INDEX_B];
r += tmpColor[FastBitmap.ColorIndexR];
g += tmpColor[FastBitmap.ColorIndexG];
b += tmpColor[FastBitmap.ColorIndexB];
hits++;
}
@ -737,7 +735,7 @@ namespace GreenshotPlugin.Core {
/// <param name="targetFastBitmap">BitmapBuffer which previously was created with BoxBlurHorizontal</param>
/// <param name="range">Range must be odd!</param>
private static void BoxBlurVerticalAlpha(IFastBitmap targetFastBitmap, int range) {
if (!targetFastBitmap.hasAlphaChannel) {
if (!targetFastBitmap.HasAlphaChannel) {
throw new NotSupportedException("BoxBlurVerticalAlpha should be called for bitmaps with alpha channel");
}
@ -754,10 +752,10 @@ namespace GreenshotPlugin.Core {
int oldPixel = y - halfRange - 1;
if (oldPixel >= targetFastBitmap.Top) {
targetFastBitmap.GetColorAt(x, oldPixel, tmpColor);
a -= tmpColor[FastBitmap.COLOR_INDEX_A];
r -= tmpColor[FastBitmap.COLOR_INDEX_R];
g -= tmpColor[FastBitmap.COLOR_INDEX_G];
b -= tmpColor[FastBitmap.COLOR_INDEX_B];
a -= tmpColor[FastBitmap.ColorIndexA];
r -= tmpColor[FastBitmap.ColorIndexR];
g -= tmpColor[FastBitmap.ColorIndexG];
b -= tmpColor[FastBitmap.ColorIndexB];
hits--;
}
@ -765,10 +763,10 @@ namespace GreenshotPlugin.Core {
if (newPixel < targetFastBitmap.Bottom) {
//int colorg = pixels[index + newPixelOffset];
targetFastBitmap.GetColorAt(x, newPixel, tmpColor);
a += tmpColor[FastBitmap.COLOR_INDEX_A];
r += tmpColor[FastBitmap.COLOR_INDEX_R];
g += tmpColor[FastBitmap.COLOR_INDEX_G];
b += tmpColor[FastBitmap.COLOR_INDEX_B];
a += tmpColor[FastBitmap.ColorIndexA];
r += tmpColor[FastBitmap.ColorIndexR];
g += tmpColor[FastBitmap.ColorIndexG];
b += tmpColor[FastBitmap.ColorIndexB];
hits++;
}

View file

@ -474,7 +474,7 @@ namespace GreenshotPlugin.Core {
if (key == null) {
return false;
}
return hasKey(prefix + "." + key.ToString());
return hasKey(prefix + "." + key);
}
/// <summary>
@ -534,7 +534,7 @@ namespace GreenshotPlugin.Core {
public static string Translate(object key) {
string typename = key.GetType().Name;
string enumKey = typename + "." + key.ToString();
string enumKey = typename + "." + key;
if (hasKey(enumKey)) {
return GetString(enumKey);
}
@ -563,7 +563,7 @@ namespace GreenshotPlugin.Core {
if (key == null) {
return null;
}
return GetString(prefix + "." + key.ToString());
return GetString(prefix + "." + key);
}
/// <summary>
@ -596,6 +596,7 @@ namespace GreenshotPlugin.Core {
/// Get the resource for key, format with with string.format an supply the parameters
/// </summary>
/// <param name="key"></param>
/// <param name="param"></param>
/// <returns>formatted resource or a "string ###key### not found"</returns>
public static string GetFormattedString(Enum key, object param) {
return GetFormattedString(key.ToString(), param);
@ -604,7 +605,9 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Get the resource for prefix.key, format with with string.format an supply the parameters
/// </summary>
/// <param name="prefix"></param>
/// <param name="key"></param>
/// <param name="param"></param>
/// <returns>formatted resource or a "string ###prefix.key### not found"</returns>
public static string GetFormattedString(string prefix, Enum key, object param) {
return GetFormattedString(prefix, key.ToString(), param);
@ -613,7 +616,9 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Get the resource for prefix.key, format with with string.format an supply the parameters
/// </summary>
/// <param name="prefix"></param>
/// <param name="key"></param>
/// <param name="param"></param>
/// <returns>formatted resource or a "string ###prefix.key### not found"</returns>
public static string GetFormattedString(string prefix, string key, object param) {
return GetFormattedString(prefix + "." + key, param);
@ -623,6 +628,7 @@ namespace GreenshotPlugin.Core {
/// Get the resource for key, format with with string.format an supply the parameters
/// </summary>
/// <param name="key"></param>
/// <param name="param"></param>
/// <returns>formatted resource or a "string ###key### not found"</returns>
public static string GetFormattedString(string key, object param) {
string returnValue;

View file

@ -709,20 +709,20 @@ namespace GreenshotPlugin.Core {
/// And additionally a signature is added.
/// </summary>
/// <param name="method">Method (POST,PUT,GET)</param>
/// <param name="requestURL">Url to call</param>
/// <param name="parameters">IDictionary<string, string></param>
private void Sign(HTTPMethod method, string requestURL, IDictionary<string, object> parameters) {
/// <param name="requestUrl">Url to call</param>
/// <param name="parameters">IDictionary of string and string</param>
private void Sign(HTTPMethod method, string requestUrl, IDictionary<string, object> parameters) {
if (parameters == null) {
throw new ArgumentNullException("parameters");
throw new ArgumentNullException(nameof(parameters));
}
// Build the signature base
StringBuilder signatureBase = new StringBuilder();
// Add Method to signature base
signatureBase.Append(method.ToString()).Append("&");
signatureBase.Append(method).Append("&");
// Add normalized URL
Uri url = new Uri(requestURL);
Uri url = new Uri(requestUrl);
string normalizedUrl = string.Format(CultureInfo.InvariantCulture, "{0}://{1}", url.Scheme, url.Host);
if (!((url.Scheme == "http" && url.Port == 80) || (url.Scheme == "https" && url.Port == 443))) {
normalizedUrl += ":" + url.Port;
@ -747,7 +747,7 @@ namespace GreenshotPlugin.Core {
break;
}
parameters.Add(OAUTH_CONSUMER_KEY_KEY, _consumerKey);
if (CallbackUrl != null && RequestTokenUrl != null && requestURL.StartsWith(RequestTokenUrl)) {
if (CallbackUrl != null && RequestTokenUrl != null && requestUrl.StartsWith(RequestTokenUrl)) {
parameters.Add(OAUTH_CALLBACK_KEY, CallbackUrl);
}
if (!string.IsNullOrEmpty(Verifier)) {
@ -810,7 +810,7 @@ namespace GreenshotPlugin.Core {
/// <returns>Response from server</returns>
private string MakeRequest(HTTPMethod method, string requestURL, IDictionary<string, string> headers, IDictionary<string, object> parameters, IBinaryContainer postData) {
if (parameters == null) {
throw new ArgumentNullException("parameters");
throw new ArgumentNullException(nameof(parameters));
}
IDictionary<string, object> requestParameters;
// Add oAuth values as HTTP headers, if this is allowed
@ -1085,7 +1085,6 @@ Greenshot received information from CloudServiceName. You can close this browser
/// <summary>
/// Generate an OAuth 2 Token by using the supplied code
/// </summary>
/// <param name="code">Code to get the RefreshToken</param>
/// <param name="settings">OAuth2Settings to update with the information that was retrieved</param>
public static void GenerateRefreshToken(OAuth2Settings settings) {
IDictionary<string, object> data = new Dictionary<string, object>();

View file

@ -156,6 +156,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Helper method to add a MenuItem to the File MenuItem of an ImageEditor
/// </summary>
/// <param name="imageEditor"></param>
/// <param name="image">Image to display in the menu</param>
/// <param name="text">Text to display in the menu</param>
/// <param name="tag">The TAG value</param>
@ -215,8 +216,8 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Helper method to add a plugin MenuItem to the Greenshot context menu
/// </summary>
/// <param name="imageEditor"></param>
/// <param name="item"></param>
/// <param name="host">IGreenshotHost</param>
/// <param name="item">ToolStripMenuItem</param>
public static void AddToContextMenu(IGreenshotHost host, ToolStripMenuItem item) {
// Here we can hang ourselves to the main context menu!
ContextMenuStrip contextMenu = host.MainMenu;

View file

@ -31,69 +31,69 @@ namespace GreenshotPlugin.Core {
/// Gets or sets the red minimum.
/// </summary>
/// <value>The red minimum.</value>
public Int32 RedMinimum { get; set; }
public int RedMinimum { get; set; }
/// <summary>
/// Gets or sets the red maximum.
/// </summary>
/// <value>The red maximum.</value>
public Int32 RedMaximum { get; set; }
public int RedMaximum { get; set; }
/// <summary>
/// Gets or sets the green minimum.
/// </summary>
/// <value>The green minimum.</value>
public Int32 GreenMinimum { get; set; }
public int GreenMinimum { get; set; }
/// <summary>
/// Gets or sets the green maximum.
/// </summary>
/// <value>The green maximum.</value>
public Int32 GreenMaximum { get; set; }
public int GreenMaximum { get; set; }
/// <summary>
/// Gets or sets the blue minimum.
/// </summary>
/// <value>The blue minimum.</value>
public Int32 BlueMinimum { get; set; }
public int BlueMinimum { get; set; }
/// <summary>
/// Gets or sets the blue maximum.
/// </summary>
/// <value>The blue maximum.</value>
public Int32 BlueMaximum { get; set; }
public int BlueMaximum { get; set; }
/// <summary>
/// Gets or sets the cube volume.
/// </summary>
/// <value>The volume.</value>
public Int32 Volume { get; set; }
public int Volume { get; set; }
}
public class WuQuantizer : IDisposable {
private static readonly ILog LOG = LogManager.GetLogger(typeof(WuQuantizer));
private const Int32 MAXCOLOR = 512;
private const Int32 RED = 2;
private const Int32 GREEN = 1;
private const Int32 BLUE = 0;
private const Int32 SIDESIZE = 33;
private const Int32 MAXSIDEINDEX = 32;
private const Int32 MAXVOLUME = SIDESIZE * SIDESIZE * SIDESIZE;
private const int MAXCOLOR = 512;
private const int RED = 2;
private const int GREEN = 1;
private const int BLUE = 0;
private const int SIDESIZE = 33;
private const int MAXSIDEINDEX = 32;
private const int MAXVOLUME = SIDESIZE * SIDESIZE * SIDESIZE;
// To count the colors
private readonly int colorCount;
private Int32[] reds;
private Int32[] greens;
private Int32[] blues;
private Int32[] sums;
private int[] reds;
private int[] greens;
private int[] blues;
private int[] sums;
private readonly Int64[, ,] weights;
private readonly Int64[, ,] momentsRed;
private readonly Int64[, ,] momentsGreen;
private readonly Int64[, ,] momentsBlue;
private readonly Single[, ,] moments;
private readonly long[,,] weights;
private readonly long[,,] momentsRed;
private readonly long[,,] momentsGreen;
private readonly long[,,] momentsBlue;
private readonly float[,,] moments;
private byte[] tag;
@ -128,7 +128,7 @@ namespace GreenshotPlugin.Core {
cubes = new WuColorCube[MAXCOLOR];
// initializes all the cubes
for (Int32 cubeIndex = 0; cubeIndex < MAXCOLOR; cubeIndex++) {
for (int cubeIndex = 0; cubeIndex < MAXCOLOR; cubeIndex++) {
cubes[cubeIndex] = new WuColorCube();
}
@ -142,15 +142,15 @@ namespace GreenshotPlugin.Core {
cubes[0].GreenMaximum = MAXSIDEINDEX;
cubes[0].BlueMaximum = MAXSIDEINDEX;
weights = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
momentsRed = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
momentsGreen = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
momentsBlue = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
moments = new Single[SIDESIZE, SIDESIZE, SIDESIZE];
weights = new long[SIDESIZE, SIDESIZE, SIDESIZE];
momentsRed = new long[SIDESIZE, SIDESIZE, SIDESIZE];
momentsGreen = new long[SIDESIZE, SIDESIZE, SIDESIZE];
momentsBlue = new long[SIDESIZE, SIDESIZE, SIDESIZE];
moments = new float[SIDESIZE, SIDESIZE, SIDESIZE];
Int32[] table = new Int32[256];
int[] table = new int[256];
for (Int32 tableIndex = 0; tableIndex < 256; ++tableIndex) {
for (int tableIndex = 0; tableIndex < 256; ++tableIndex) {
table[tableIndex] = tableIndex * tableIndex;
}
@ -177,9 +177,9 @@ namespace GreenshotPlugin.Core {
bitArray.Set(index, true);
}
Int32 indexRed = (color.R >> 3) + 1;
Int32 indexGreen = (color.G >> 3) + 1;
Int32 indexBlue = (color.B >> 3) + 1;
int indexRed = (color.R >> 3) + 1;
int indexGreen = (color.G >> 3) + 1;
int indexBlue = (color.B >> 3) + 1;
weights[indexRed, indexGreen, indexBlue]++;
momentsRed[indexRed, indexGreen, indexBlue] += color.R;
@ -188,7 +188,7 @@ namespace GreenshotPlugin.Core {
moments[indexRed, indexGreen, indexBlue] += table[color.R] + table[color.G] + table[color.B];
// Store the initial "match"
Int32 paletteIndex = (indexRed << 10) + (indexRed << 6) + indexRed + (indexGreen << 5) + indexGreen + indexBlue;
int paletteIndex = (indexRed << 10) + (indexRed << 6) + indexRed + (indexGreen << 5) + indexGreen + indexBlue;
destinationFastBitmap.SetColorIndexAt(x, y, (byte)(paletteIndex & 0xff));
}
}
@ -200,7 +200,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// See <see cref="IColorQuantizer.Prepare"/> for more details.
/// </summary>
public Int32 GetColorCount() {
public int GetColorCount() {
return colorCount;
}
@ -242,7 +242,7 @@ namespace GreenshotPlugin.Core {
// generates palette
ColorPalette imagePalette = resultBitmap.Palette;
Color[] entries = imagePalette.Entries;
for (Int32 paletteIndex = 0; paletteIndex < 256; paletteIndex++) {
for (int paletteIndex = 0; paletteIndex < 256; paletteIndex++) {
if (paletteIndex < colorCount) {
entries[paletteIndex] = colors[paletteIndex];
} else {
@ -262,7 +262,7 @@ namespace GreenshotPlugin.Core {
/// </summary>
public Bitmap GetQuantizedImage(int allowedColorCount) {
if (allowedColorCount > 256) {
throw new ArgumentOutOfRangeException("Quantizing muss be done to get less than 256 colors");
throw new ArgumentOutOfRangeException(nameof(allowedColorCount), "Quantizing muss be done to get less than 256 colors");
}
if (colorCount < allowedColorCount) {
// Simple logic to reduce to 8 bit
@ -272,11 +272,11 @@ namespace GreenshotPlugin.Core {
// preprocess the colors
CalculateMoments();
LOG.Info("Calculated the moments...");
Int32 next = 0;
Single[] volumeVariance = new Single[MAXCOLOR];
int next = 0;
float[] volumeVariance = new float[MAXCOLOR];
// processes the cubes
for (Int32 cubeIndex = 1; cubeIndex < allowedColorCount; ++cubeIndex) {
for (int cubeIndex = 1; cubeIndex < allowedColorCount; ++cubeIndex) {
// if cut is possible; make it
if (Cut(cubes[next], cubes[cubeIndex])) {
volumeVariance[next] = cubes[next].Volume > 1 ? CalculateVariance(cubes[next]) : 0.0f;
@ -288,9 +288,9 @@ namespace GreenshotPlugin.Core {
}
next = 0;
Single temp = volumeVariance[0];
float temp = volumeVariance[0];
for (Int32 index = 1; index <= cubeIndex; ++index) {
for (int index = 1; index <= cubeIndex; ++index) {
if (volumeVariance[index] > temp) {
temp = volumeVariance[index];
next = index;
@ -303,9 +303,9 @@ namespace GreenshotPlugin.Core {
}
}
Int32[] lookupRed = new Int32[MAXCOLOR];
Int32[] lookupGreen = new Int32[MAXCOLOR];
Int32[] lookupBlue = new Int32[MAXCOLOR];
int[] lookupRed = new int[MAXCOLOR];
int[] lookupGreen = new int[MAXCOLOR];
int[] lookupBlue = new int[MAXCOLOR];
tag = new byte[MAXVOLUME];
@ -326,10 +326,10 @@ namespace GreenshotPlugin.Core {
}
}
reds = new Int32[allowedColorCount + 1];
greens = new Int32[allowedColorCount + 1];
blues = new Int32[allowedColorCount + 1];
sums = new Int32[allowedColorCount + 1];
reds = new int[allowedColorCount + 1];
greens = new int[allowedColorCount + 1];
blues = new int[allowedColorCount + 1];
sums = new int[allowedColorCount + 1];
LOG.Info("Starting bitmap reconstruction...");
@ -356,16 +356,16 @@ namespace GreenshotPlugin.Core {
bestMatch = dest.GetColorIndexAt(x, y);
bestMatch = tag[bestMatch];
Int32 bestDistance = 100000000;
int bestDistance = 100000000;
for (int lookupIndex = 0; lookupIndex < allowedColorCount; lookupIndex++) {
Int32 foundRed = lookupRed[lookupIndex];
Int32 foundGreen = lookupGreen[lookupIndex];
Int32 foundBlue = lookupBlue[lookupIndex];
Int32 deltaRed = color.R - foundRed;
Int32 deltaGreen = color.G - foundGreen;
Int32 deltaBlue = color.B - foundBlue;
int foundRed = lookupRed[lookupIndex];
int foundGreen = lookupGreen[lookupIndex];
int foundBlue = lookupBlue[lookupIndex];
int deltaRed = color.R - foundRed;
int deltaGreen = color.G - foundGreen;
int deltaBlue = color.B - foundBlue;
Int32 distance = deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue;
int distance = deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue;
if (distance < bestDistance) {
bestDistance = distance;
@ -393,7 +393,7 @@ namespace GreenshotPlugin.Core {
// generates palette
ColorPalette imagePalette = resultBitmap.Palette;
Color[] entries = imagePalette.Entries;
for (Int32 paletteIndex = 0; paletteIndex < allowedColorCount; paletteIndex++) {
for (int paletteIndex = 0; paletteIndex < allowedColorCount; paletteIndex++) {
if (sums[paletteIndex] > 0) {
reds[paletteIndex] /= sums[paletteIndex];
greens[paletteIndex] /= sums[paletteIndex];
@ -414,14 +414,14 @@ namespace GreenshotPlugin.Core {
/// Converts the histogram to a series of moments.
/// </summary>
private void CalculateMoments() {
Int64[] area = new Int64[SIDESIZE];
Int64[] areaRed = new Int64[SIDESIZE];
Int64[] areaGreen = new Int64[SIDESIZE];
Int64[] areaBlue = new Int64[SIDESIZE];
Single[] area2 = new Single[SIDESIZE];
long[] area = new long[SIDESIZE];
long[] areaRed = new long[SIDESIZE];
long[] areaGreen = new long[SIDESIZE];
long[] areaBlue = new long[SIDESIZE];
float[] area2 = new float[SIDESIZE];
for (Int32 redIndex = 1; redIndex <= MAXSIDEINDEX; ++redIndex) {
for (Int32 index = 0; index <= MAXSIDEINDEX; ++index) {
for (int redIndex = 1; redIndex <= MAXSIDEINDEX; ++redIndex) {
for (int index = 0; index <= MAXSIDEINDEX; ++index) {
area[index] = 0;
areaRed[index] = 0;
areaGreen[index] = 0;
@ -429,14 +429,14 @@ namespace GreenshotPlugin.Core {
area2[index] = 0;
}
for (Int32 greenIndex = 1; greenIndex <= MAXSIDEINDEX; ++greenIndex) {
Int64 line = 0;
Int64 lineRed = 0;
Int64 lineGreen = 0;
Int64 lineBlue = 0;
Single line2 = 0.0f;
for (int greenIndex = 1; greenIndex <= MAXSIDEINDEX; ++greenIndex) {
long line = 0;
long lineRed = 0;
long lineGreen = 0;
long lineBlue = 0;
float line2 = 0.0f;
for (Int32 blueIndex = 1; blueIndex <= MAXSIDEINDEX; ++blueIndex) {
for (int blueIndex = 1; blueIndex <= MAXSIDEINDEX; ++blueIndex) {
line += weights[redIndex, greenIndex, blueIndex];
lineRed += momentsRed[redIndex, greenIndex, blueIndex];
lineGreen += momentsGreen[redIndex, greenIndex, blueIndex];
@ -462,7 +462,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Computes the volume of the cube in a specific moment.
/// </summary>
private static Int64 Volume(WuColorCube cube, Int64[, ,] moment) {
private static long Volume(WuColorCube cube, long[,,] moment) {
return moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMaximum] -
moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] -
moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] +
@ -476,7 +476,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Computes the volume of the cube in a specific moment. For the floating-point values.
/// </summary>
private static Single VolumeFloat(WuColorCube cube, Single[, ,] moment) {
private static float VolumeFloat(WuColorCube cube, float[,,] moment) {
return moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMaximum] -
moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] -
moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] +
@ -490,7 +490,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Splits the cube in given position, and color direction.
/// </summary>
private static Int64 Top(WuColorCube cube, Int32 direction, Int32 position, Int64[, ,] moment) {
private static long Top(WuColorCube cube, int direction, int position, long[,,] moment) {
switch (direction) {
case RED:
return (moment[position, cube.GreenMaximum, cube.BlueMaximum] -
@ -518,7 +518,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Splits the cube in a given color direction at its minimum.
/// </summary>
private static Int64 Bottom(WuColorCube cube, Int32 direction, Int64[, ,] moment) {
private static long Bottom(WuColorCube cube, int direction, long[,,] moment) {
switch (direction) {
case RED:
return (-moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] +
@ -545,14 +545,14 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Calculates statistical variance for a given cube.
/// </summary>
private Single CalculateVariance(WuColorCube cube) {
Single volumeRed = Volume(cube, momentsRed);
Single volumeGreen = Volume(cube, momentsGreen);
Single volumeBlue = Volume(cube, momentsBlue);
Single volumeMoment = VolumeFloat(cube, moments);
Single volumeWeight = Volume(cube, weights);
private float CalculateVariance(WuColorCube cube) {
float volumeRed = Volume(cube, momentsRed);
float volumeGreen = Volume(cube, momentsGreen);
float volumeBlue = Volume(cube, momentsBlue);
float volumeMoment = VolumeFloat(cube, moments);
float volumeWeight = Volume(cube, weights);
Single distance = volumeRed * volumeRed + volumeGreen * volumeGreen + volumeBlue * volumeBlue;
float distance = volumeRed * volumeRed + volumeGreen * volumeGreen + volumeBlue * volumeBlue;
return volumeMoment - (distance / volumeWeight);
}
@ -560,26 +560,26 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Finds the optimal (maximal) position for the cut.
/// </summary>
private Single Maximize(WuColorCube cube, Int32 direction, Int32 first, Int32 last, Int32[] cut, Int64 wholeRed, Int64 wholeGreen, Int64 wholeBlue, Int64 wholeWeight) {
Int64 bottomRed = Bottom(cube, direction, momentsRed);
Int64 bottomGreen = Bottom(cube, direction, momentsGreen);
Int64 bottomBlue = Bottom(cube, direction, momentsBlue);
Int64 bottomWeight = Bottom(cube, direction, weights);
private float Maximize(WuColorCube cube, int direction, int first, int last, int[] cut, long wholeRed, long wholeGreen, long wholeBlue, long wholeWeight) {
long bottomRed = Bottom(cube, direction, momentsRed);
long bottomGreen = Bottom(cube, direction, momentsGreen);
long bottomBlue = Bottom(cube, direction, momentsBlue);
long bottomWeight = Bottom(cube, direction, weights);
Single result = 0.0f;
float result = 0.0f;
cut[0] = -1;
for (Int32 position = first; position < last; ++position) {
for (int position = first; position < last; ++position) {
// determines the cube cut at a certain position
Int64 halfRed = bottomRed + Top(cube, direction, position, momentsRed);
Int64 halfGreen = bottomGreen + Top(cube, direction, position, momentsGreen);
Int64 halfBlue = bottomBlue + Top(cube, direction, position, momentsBlue);
Int64 halfWeight = bottomWeight + Top(cube, direction, position, weights);
long halfRed = bottomRed + Top(cube, direction, position, momentsRed);
long halfGreen = bottomGreen + Top(cube, direction, position, momentsGreen);
long halfBlue = bottomBlue + Top(cube, direction, position, momentsBlue);
long halfWeight = bottomWeight + Top(cube, direction, position, weights);
// the cube cannot be cut at bottom (this would lead to empty cube)
if (halfWeight != 0) {
Single halfDistance = (Single)halfRed * halfRed + (Single)halfGreen * halfGreen + (Single)halfBlue * halfBlue;
Single temp = halfDistance / halfWeight;
float halfDistance = (float)halfRed * halfRed + (float)halfGreen * halfGreen + (float)halfBlue * halfBlue;
float temp = halfDistance / halfWeight;
halfRed = wholeRed - halfRed;
halfGreen = wholeGreen - halfGreen;
@ -587,7 +587,7 @@ namespace GreenshotPlugin.Core {
halfWeight = wholeWeight - halfWeight;
if (halfWeight != 0) {
halfDistance = (Single)halfRed * halfRed + (Single)halfGreen * halfGreen + (Single)halfBlue * halfBlue;
halfDistance = (float)halfRed * halfRed + (float)halfGreen * halfGreen + (float)halfBlue * halfBlue;
temp += halfDistance / halfWeight;
if (temp > result) {
@ -604,21 +604,21 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Cuts a cube with another one.
/// </summary>
private Boolean Cut(WuColorCube first, WuColorCube second) {
Int32 direction;
private bool Cut(WuColorCube first, WuColorCube second) {
int direction;
Int32[] cutRed = { 0 };
Int32[] cutGreen = { 0 };
Int32[] cutBlue = { 0 };
int[] cutRed = { 0 };
int[] cutGreen = { 0 };
int[] cutBlue = { 0 };
Int64 wholeRed = Volume(first, momentsRed);
Int64 wholeGreen = Volume(first, momentsGreen);
Int64 wholeBlue = Volume(first, momentsBlue);
Int64 wholeWeight = Volume(first, weights);
long wholeRed = Volume(first, momentsRed);
long wholeGreen = Volume(first, momentsGreen);
long wholeBlue = Volume(first, momentsBlue);
long wholeWeight = Volume(first, weights);
Single maxRed = Maximize(first, RED, first.RedMinimum + 1, first.RedMaximum, cutRed, wholeRed, wholeGreen, wholeBlue, wholeWeight);
Single maxGreen = Maximize(first, GREEN, first.GreenMinimum + 1, first.GreenMaximum, cutGreen, wholeRed, wholeGreen, wholeBlue, wholeWeight);
Single maxBlue = Maximize(first, BLUE, first.BlueMinimum + 1, first.BlueMaximum, cutBlue, wholeRed, wholeGreen, wholeBlue, wholeWeight);
float maxRed = Maximize(first, RED, first.RedMinimum + 1, first.RedMaximum, cutRed, wholeRed, wholeGreen, wholeBlue, wholeWeight);
float maxGreen = Maximize(first, GREEN, first.GreenMinimum + 1, first.GreenMaximum, cutGreen, wholeRed, wholeGreen, wholeBlue, wholeWeight);
float maxBlue = Maximize(first, BLUE, first.BlueMinimum + 1, first.BlueMaximum, cutBlue, wholeRed, wholeGreen, wholeBlue, wholeWeight);
if ((maxRed >= maxGreen) && (maxRed >= maxBlue)) {
direction = RED;
@ -669,10 +669,10 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Marks all the tags with a given label.
/// </summary>
private void Mark(WuColorCube cube, Int32 label, byte[] tag) {
for (Int32 redIndex = cube.RedMinimum + 1; redIndex <= cube.RedMaximum; ++redIndex) {
for (Int32 greenIndex = cube.GreenMinimum + 1; greenIndex <= cube.GreenMaximum; ++greenIndex) {
for (Int32 blueIndex = cube.BlueMinimum + 1; blueIndex <= cube.BlueMaximum; ++blueIndex) {
private void Mark(WuColorCube cube, int label, byte[] tag) {
for (int redIndex = cube.RedMinimum + 1; redIndex <= cube.RedMaximum; ++redIndex) {
for (int greenIndex = cube.GreenMinimum + 1; greenIndex <= cube.GreenMaximum; ++greenIndex) {
for (int blueIndex = cube.BlueMinimum + 1; blueIndex <= cube.BlueMaximum; ++blueIndex) {
tag[(redIndex << 10) + (redIndex << 6) + redIndex + (greenIndex << 5) + greenIndex + blueIndex] = (byte)label;
}
}

View file

@ -26,7 +26,6 @@ using GreenshotPlugin.UnmanagedHelpers;
using log4net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
@ -154,9 +153,8 @@ namespace GreenshotPlugin.Core {
/// 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
/// enumeration
///
/// Provides details about a Window returned by the enumeration
/// </summary>
public class WindowDetails : IEquatable<WindowDetails>{
private const string METRO_WINDOWS_CLASS = "Windows.UI.Core.CoreWindow"; // Windows 10 uses ApplicationFrameWindow
@ -167,15 +165,21 @@ namespace GreenshotPlugin.Core {
private static readonly CoreConfiguration Conf = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly List<IntPtr> IgnoreHandles = new List<IntPtr>();
private static readonly List<string> ExcludeProcessesFromFreeze = new List<string>();
private static readonly IAppVisibility appVisibility;
private static readonly IAppVisibility AppVisibility;
static WindowDetails() {
try {
try
{
// Only try to instantiate when Windows 8 or later.
if (Environment.OSVersion.Version.Major >= 6 && Environment.OSVersion.Version.Minor >= 2) {
appVisibility = COMWrapper.CreateInstance<IAppVisibility>();
if (Environment.OSVersion.Version.Major >= 6 && Environment.OSVersion.Version.Minor >= 2)
{
AppVisibility = COMWrapper.CreateInstance<IAppVisibility>();
}
} catch {}
}
catch (Exception ex)
{
LOG.WarnFormat("Couldn't create instance of IAppVisibility: {0}", ex.Message);
}
}
public static void AddProcessToExcludeFromFreeze(string processname) {
@ -529,7 +533,7 @@ namespace GreenshotPlugin.Core {
/// 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
/// </summary>
/// <param name="classnames">List<string> with classname "path"</param>
/// <param name="classnames">List of string with classname "path"</param>
/// <param name="allowSkip">true allows the search to skip a classname of the path</param>
/// <returns>WindowDetails if found</returns>
public WindowDetails FindPath(List<string> classnames, bool allowSkip) {
@ -695,8 +699,8 @@ namespace GreenshotPlugin.Core {
RECT rect = new RECT(screen.Bounds);
IntPtr monitor = User32.MonitorFromRect(ref rect, User32.MONITOR_DEFAULTTONULL);
if (monitor != IntPtr.Zero) {
if (appVisibility != null) {
MONITOR_APP_VISIBILITY monitorAppVisibility = appVisibility.GetAppVisibilityOnMonitor(monitor);
if (AppVisibility != null) {
MONITOR_APP_VISIBILITY monitorAppVisibility = AppVisibility.GetAppVisibilityOnMonitor(monitor);
//LOG.DebugFormat("App {0} visible: {1} on {2}", Text, monitorAppVisibility, screen.Bounds);
if (monitorAppVisibility == MONITOR_APP_VISIBILITY.MAV_APP_VISIBLE) {
return true;
@ -1395,7 +1399,7 @@ namespace GreenshotPlugin.Core {
Rectangle windowRect = WindowRectangle;
// Start the capture
Exception exceptionOccured = null;
Image returnImage = null;
Image returnImage;
using (Region region = GetRegion()) {
PixelFormat pixelFormat = PixelFormat.Format24bppRgb;
// Only use 32 bpp ARGB when the window has a region
@ -1446,7 +1450,7 @@ namespace GreenshotPlugin.Core {
/// </summary>
/// <param name="hWnd">The Window Handle</param>
public WindowDetails(IntPtr hWnd) {
this._hWnd = hWnd;
_hWnd = hWnd;
}
/// <summary>
@ -1455,7 +1459,7 @@ namespace GreenshotPlugin.Core {
/// <returns>WindowDetails of the current window</returns>
public static WindowDetails GetActiveWindow() {
IntPtr hWnd = User32.GetForegroundWindow();
if (hWnd != null && hWnd != IntPtr.Zero) {
if (hWnd != IntPtr.Zero) {
if (IgnoreHandles.Contains(hWnd)) {
return GetDesktopWindow();
}
@ -1499,7 +1503,7 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Get all the top level windows
/// </summary>
/// <returns>List<WindowDetails> with all the top level windows</returns>
/// <returns>List of WindowDetails with all the top level windows</returns>
public static List<WindowDetails> GetAllWindows() {
return GetAllWindows(null);
}
@ -1582,7 +1586,7 @@ namespace GreenshotPlugin.Core {
public static List<WindowDetails> GetMetroApps() {
List<WindowDetails> metroApps = new List<WindowDetails>();
// if the appVisibility != null we have Windows 8.
if (appVisibility == null) {
if (AppVisibility == null) {
return metroApps;
}
//string[] wcs = {"ImmersiveGutter", "Snapped Desktop", "ImmersiveBackgroundWindow","ImmersiveLauncher","Windows.UI.Core.CoreWindow","ApplicationManager_ImmersiveShellWindow","SearchPane","MetroGhostWindow","EdgeUiInputWndClass", "NativeHWNDHost", "Shell_CharmWindow"};
@ -1712,7 +1716,7 @@ namespace GreenshotPlugin.Core {
/// <returns></returns>
public static WindowDetails GetAppLauncher() {
// Only if Windows 8 (or higher)
if (appVisibility == null) {
if (AppVisibility == null) {
return null;
}
IntPtr appLauncher = User32.FindWindow(METRO_APPLAUNCHER_CLASS, null);
@ -1728,8 +1732,8 @@ namespace GreenshotPlugin.Core {
/// <returns></returns>
public static bool IsAppLauncherVisible {
get {
if (appVisibility != null) {
return appVisibility.IsLauncherVisible;
if (AppVisibility != null) {
return AppVisibility.IsLauncherVisible;
}
return false;
}

View file

@ -89,11 +89,11 @@ namespace Greenshot.IniFile {
/// <summary>
/// Initialize the ini config
/// </summary>
/// <param name="applicationName"></param>
/// <param name="appName"></param>
/// <param name="configName"></param>
public static void Init(string appName, string confName) {
public static void Init(string appName, string configName) {
applicationName = appName;
configName = confName;
IniConfig.configName = configName;
Reload();
}
@ -320,7 +320,7 @@ namespace Greenshot.IniFile {
/// <param name="sectionName"></param>
/// <returns></returns>
public static IniSection GetIniSection(string sectionName) {
IniSection returnValue = null;
IniSection returnValue;
sectionMap.TryGetValue(sectionName, out returnValue);
return returnValue;
}
@ -369,11 +369,10 @@ namespace Greenshot.IniFile {
/// </summary>
/// <param name="section"></param>
/// <returns></returns>
public static Dictionary<string, string> PropertiesForSection(IniSection section) {
Type iniSectionType = section.GetType();
public static IDictionary<string, string> PropertiesForSection(IniSection section) {
string sectionName = section.IniSectionAttribute.Name;
// Get the properties for the section
Dictionary<string, string> properties = null;
IDictionary<string, string> properties;
if (sections.ContainsKey(sectionName)) {
properties = sections[sectionName];
} else {

View file

@ -120,7 +120,7 @@ namespace Greenshot.IniFile {
/// Fill the section with the supplied properties
/// </summary>
/// <param name="properties"></param>
public void Fill(Dictionary<string, string> properties) {
public void Fill(IDictionary<string, string> properties) {
Type iniSectionType = GetType();
// Iterate over the members and create IniValueContainers

View file

@ -229,9 +229,8 @@ namespace Greenshot.IniFile {
/// Set the value to the value in the ini file, or default
/// </summary>
/// <returns></returns>
public void SetValueFromProperties(Dictionary<string, string> properties) {
public void SetValueFromProperties(IDictionary<string, string> properties) {
string propertyName = attributes.Name;
string defaultValue = attributes.DefaultValue;
string propertyValue = null;
if (properties.ContainsKey(propertyName) && properties[propertyName] != null) {
propertyValue = containingIniSection.PreCheckValue(propertyName, properties[propertyName]);
@ -273,7 +272,7 @@ namespace Greenshot.IniFile {
object dictionary = Activator.CreateInstance(valueType);
MethodInfo addMethodInfo = valueType.GetMethod("Add");
bool addedElements = false;
Dictionary<string, string> properties = IniConfig.PropertiesForSection(containingIniSection);
IDictionary<string, string> properties = IniConfig.PropertiesForSection(containingIniSection);
foreach (string key in properties.Keys) {
if (key != null && key.StartsWith(propertyName + ".")) {
// What "key" do we need to store it under?
@ -354,6 +353,7 @@ namespace Greenshot.IniFile {
/// </summary>
/// <param name="valueType">Type to convert tp</param>
/// <param name="valueString">string to convert from</param>
/// <param name="separator"></param>
/// <returns>Value</returns>
private static object ConvertStringToValueType(Type valueType, string valueString, string separator) {
if (valueString == null) {
@ -460,7 +460,8 @@ namespace Greenshot.IniFile {
}
}
return stringBuilder.ToString();
} else if (valueType == typeof(object)) {
}
if (valueType == typeof(object)) {
// object to String, this is the hardest
// Format will be "FQTypename[,Assemblyname]:Value"
@ -478,12 +479,11 @@ namespace Greenshot.IniFile {
if (assemblyName.StartsWith("Green")) {
assemblyName = assemblyName.Substring(0, assemblyName.IndexOf(','));
}
return String.Format("{0},{1}:{2}", valueTypeName, assemblyName, ourValue);
} else {
TypeConverter converter = TypeDescriptor.GetConverter(valueType);
if (converter != null) {
return converter.ConvertToInvariantString(valueObject);
}
return string.Format("{0},{1}:{2}", valueTypeName, assemblyName, ourValue);
}
TypeConverter converter = TypeDescriptor.GetConverter(valueType);
if (converter != null) {
return converter.ConvertToInvariantString(valueObject);
}
// All other types
return valueObject.ToString();

View file

@ -21,7 +21,6 @@
using Greenshot.Core;
using Greenshot.Memento;
using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Interfaces.Drawing;
using System;
using System.Drawing;
using System.IO;
@ -207,6 +206,7 @@ namespace Greenshot.Plugin
/// </summary>
/// <param name="container">IDrawableContainer</param>
/// <param name="invalidate">false to skip invalidation</param>
/// <param name="generateEvents">false to skip event generation</param>
void SelectElement(IDrawableContainer container, bool invalidate = true, bool generateEvents = true);
/// <summary>
/// Is the supplied container "on" the surface?

View file

@ -139,7 +139,7 @@ namespace Greenshot.Plugin {
/// Return a menu item
/// </summary>
/// <param name="addDynamics">Resolve the dynamic destinations too?</param>
/// <param name="ContextMenuStrip">The menu for which the item is created</param>
/// <param name="menu">The menu for which the item is created</param>
/// <param name="destinationClickHandler">Handler which is called when clicked</param>
/// <returns>ToolStripMenuItem</returns>
ToolStripMenuItem GetMenuItem(bool addDynamics, ContextMenuStrip menu, EventHandler destinationClickHandler);

View file

@ -30,7 +30,7 @@ using Greenshot.Core;
namespace Greenshot.Plugin {
[Serializable]
[AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)]
sealed public class PluginAttribute : Attribute, IComparable {
public sealed class PluginAttribute : Attribute, IComparable {
public string Name {
get;
set;
@ -173,10 +173,13 @@ namespace Greenshot.Plugin {
NotifyIcon NotifyIcon {
get;
}
/// <summary>
/// Create a Thumbnail
/// </summary>
/// <param name="image">Image of which we need a Thumbnail</param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns>Image with Thumbnail</returns>
Image GetThumbnail(Image image, int width, int height);
@ -191,14 +194,14 @@ namespace Greenshot.Plugin {
/// <summary>
/// Get a destination by it's designation
/// </summary>
/// <param name="destination"></param>
/// <param name="designation"></param>
/// <returns>IDestination</returns>
IDestination GetDestination(string designation);
/// <summary>
/// Get a list of all available destinations
/// </summary>
/// <returns>List<IDestination></returns>
/// <returns>List of IDestination</returns>
List<IDestination> GetAllDestinations();
/// <summary>

View file

@ -45,12 +45,12 @@ namespace Greenshot.Interop {
/// <summary>
/// Holds reference to the actual COM object which is wrapped by this proxy
/// </summary>
private object _COMObject;
private readonly object _comObject;
/// <summary>
/// Type of the COM object, set on constructor after getting the COM reference
/// </summary>
private readonly Type _COMType;
private readonly Type _comType;
/// <summary>
/// The type of which method calls are intercepted and executed on the COM object.
@ -64,33 +64,33 @@ namespace Greenshot.Interop {
#endregion
[DllImport("ole32.dll")]
static extern int ProgIDFromCLSID([In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgID);
static extern int ProgIDFromCLSID([In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgId);
// Converts failure HRESULTs to exceptions:
[DllImport("oleaut32", PreserveSig=false)]
static extern void GetActiveObject(ref Guid rclsid, IntPtr pvReserved, [MarshalAs(UnmanagedType.IUnknown)] out Object ppunk);
static extern void GetActiveObject(ref Guid rclsid, IntPtr pvReserved, [MarshalAs(UnmanagedType.IUnknown)] out object ppunk);
#region Construction
/// <summary>
/// Gets a COM object and returns the transparent proxy which intercepts all calls to the object
/// </summary>
/// <param name="T">Interface which defines the method and properties to intercept</param>
/// <typeparam name="T">Interface which defines the method and properties to intercept</typeparam>
/// <returns>Transparent proxy to the real proxy for the object</returns>
/// <remarks>The <paramref name="type"/> must be an interface decorated with the <see cref="ComProgIdAttribute"/>attribute.</remarks>
/// <remarks>T must be an interface decorated with the <see cref="ComProgIdAttribute"/>attribute.</remarks>
public static T GetInstance<T>() {
Type type = typeof(T);
if (null == type) {
throw new ArgumentNullException("type");
throw new ArgumentNullException(nameof(T));
}
if (!type.IsInterface) {
throw new ArgumentException("The specified type must be an interface.", "type");
throw new ArgumentException("The specified type must be an interface.", nameof(T));
}
ComProgIdAttribute progIDAttribute = ComProgIdAttribute.GetAttribute(type);
if (null == progIDAttribute || null == progIDAttribute.Value || 0 == progIDAttribute.Value.Length) {
throw new ArgumentException("The specified type must define a ComProgId attribute.", "type");
var progIdAttribute = ComProgIdAttribute.GetAttribute(type);
if (string.IsNullOrEmpty(progIdAttribute?.Value)) {
throw new ArgumentException("The specified type must define a ComProgId attribute.", nameof(T));
}
string progId = progIDAttribute.Value;
string progId = progIdAttribute.Value;
object comObject = null;
@ -100,18 +100,18 @@ namespace Greenshot.Interop {
int result = ProgIDFromCLSID(ref guid, out progId);
if (result != 0) {
// Restore progId, as it's overwritten
progId = progIDAttribute.Value;
progId = progIdAttribute.Value;
try {
GetActiveObject(ref guid, IntPtr.Zero, out comObject);
} catch (Exception) {
LOG.WarnFormat("Error {0} getting instance for class id {1}", result, progIDAttribute.Value);
LOG.WarnFormat("Error {0} getting instance for class id {1}", result, progIdAttribute.Value);
}
if (comObject == null) {
LOG.WarnFormat("Error {0} getting progId {1}", result, progIDAttribute.Value);
LOG.WarnFormat("Error {0} getting progId {1}", result, progIdAttribute.Value);
}
} else {
LOG.InfoFormat("Mapped {0} to progId {1}", progIDAttribute.Value, progId);
LOG.InfoFormat("Mapped {0} to progId {1}", progIdAttribute.Value, progId);
}
}
@ -124,16 +124,16 @@ namespace Greenshot.Interop {
} else if (comE.ErrorCode == CO_E_CLASSSTRING) {
LOG.WarnFormat("Unknown progId {0}", progId);
} else {
LOG.Warn("Error getting active object for " + progIDAttribute.Value, comE);
LOG.Warn("Error getting active object for " + progIdAttribute.Value, comE);
}
} catch (Exception e) {
LOG.Warn("Error getting active object for " + progIDAttribute.Value, e);
LOG.Warn("Error getting active object for " + progIdAttribute.Value, e);
}
}
if (comObject != null) {
if (comObject is IDispatch) {
COMWrapper wrapper = new COMWrapper(comObject, type, progIDAttribute.Value);
COMWrapper wrapper = new COMWrapper(comObject, type, progIdAttribute.Value);
return (T)wrapper.GetTransparentProxy();
} else {
return (T)comObject;
@ -149,17 +149,17 @@ namespace Greenshot.Interop {
public static T CreateInstance<T>() {
Type type = typeof(T);
if (null == type) {
throw new ArgumentNullException("type");
throw new ArgumentNullException(nameof(T));
}
if (!type.IsInterface) {
throw new ArgumentException("The specified type must be an interface.", "type");
throw new ArgumentException("The specified type must be an interface.", nameof(T));
}
ComProgIdAttribute progIDAttribute = ComProgIdAttribute.GetAttribute(type);
if (null == progIDAttribute || null == progIDAttribute.Value || 0 == progIDAttribute.Value.Length) {
throw new ArgumentException("The specified type must define a ComProgId attribute.", "type");
ComProgIdAttribute progIdAttribute = ComProgIdAttribute.GetAttribute(type);
if (string.IsNullOrEmpty(progIdAttribute?.Value)) {
throw new ArgumentException("The specified type must define a ComProgId attribute.", nameof(T));
}
string progId = progIDAttribute.Value;
string progId = progIdAttribute.Value;
Type comType = null;
if (progId.StartsWith("clsid:")) {
Guid guid = new Guid(progId.Substring(6));
@ -197,26 +197,26 @@ namespace Greenshot.Interop {
/// Gets or creates a COM object and returns the transparent proxy which intercepts all calls to the object
/// The ComProgId can be a normal ComProgId or a GUID prefixed with "clsid:"
/// </summary>
/// <param name="type">Interface which defines the method and properties to intercept</param>
/// <typeparam name="T">Interface which defines the method and properties to intercept</typeparam>
/// <returns>Transparent proxy to the real proxy for the object</returns>
/// <remarks>The <paramref name="type"/> must be an interface decorated with the <see cref="ComProgIdAttribute"/>attribute.</remarks>
/// <remarks>T must be an interface decorated with the <see cref="ComProgIdAttribute"/>attribute.</remarks>
public static T GetOrCreateInstance<T>() {
Type type = typeof(T);
if (null == type) {
throw new ArgumentNullException("type");
throw new ArgumentNullException(nameof(T));
}
if (!type.IsInterface) {
throw new ArgumentException("The specified type must be an interface.", "type");
throw new ArgumentException("The specified type must be an interface.", nameof(T));
}
ComProgIdAttribute progIDAttribute = ComProgIdAttribute.GetAttribute(type);
if (null == progIDAttribute || null == progIDAttribute.Value || 0 == progIDAttribute.Value.Length) {
throw new ArgumentException("The specified type must define a ComProgId attribute.", "type");
var progIdAttribute = ComProgIdAttribute.GetAttribute(type);
if (string.IsNullOrEmpty(progIdAttribute?.Value)) {
throw new ArgumentException("The specified type must define a ComProgId attribute.", nameof(T));
}
object comObject = null;
Type comType = null;
string progId = progIDAttribute.Value;
string progId = progIdAttribute.Value;
Guid guid = Guid.Empty;
// Convert from clsid to Prog ID, if needed
@ -225,17 +225,17 @@ namespace Greenshot.Interop {
int result = ProgIDFromCLSID(ref guid, out progId);
if (result != 0) {
// Restore progId, as it's overwritten
progId = progIDAttribute.Value;
progId = progIdAttribute.Value;
try {
GetActiveObject(ref guid, IntPtr.Zero, out comObject);
} catch (Exception) {
LOG.WarnFormat("Error {0} getting instance for class id {1}", result, progIDAttribute.Value);
LOG.WarnFormat("Error {0} getting instance for class id {1}", result, progIdAttribute.Value);
}
if (comObject == null) {
LOG.WarnFormat("Error {0} getting progId {1}", result, progIDAttribute.Value);
LOG.WarnFormat("Error {0} getting progId {1}", result, progIdAttribute.Value);
}
} else {
LOG.InfoFormat("Mapped {0} to progId {1}", progIDAttribute.Value, progId);
LOG.InfoFormat("Mapped {0} to progId {1}", progIdAttribute.Value, progId);
}
}
@ -283,7 +283,7 @@ namespace Greenshot.Interop {
}
if (comObject != null) {
if (comObject is IDispatch) {
COMWrapper wrapper = new COMWrapper(comObject, type, progIDAttribute.Value);
COMWrapper wrapper = new COMWrapper(comObject, type, progIdAttribute.Value);
return (T)wrapper.GetTransparentProxy();
} else {
return (T)comObject;
@ -295,16 +295,16 @@ namespace Greenshot.Interop {
/// <summary>
/// Wrap a com object as COMWrapper
/// </summary>
/// <typeparam name="T">Interface which defines the method and properties to intercept</typeparam>
/// <param name="comObject">An object to intercept</param>
/// <param name="T">Interface which defines the method and properties to intercept</param>
/// <returns>Transparent proxy to the real proxy for the object</returns>
public static T Wrap<T>(object comObject) {
Type type = typeof (T);
if (null == comObject) {
throw new ArgumentNullException("comObject");
throw new ArgumentNullException(nameof(comObject));
}
if (null == type) {
throw new ArgumentNullException("type");
throw new ArgumentNullException(nameof(T));
}
COMWrapper wrapper = new COMWrapper(comObject, type, type.FullName);
@ -316,13 +316,14 @@ namespace Greenshot.Interop {
/// </summary>
/// <param name="comObject">An object to intercept</param>
/// <param name="type">Interface which defines the method and properties to intercept</param>
/// <param name="targetName"></param>
/// <returns>Transparent proxy to the real proxy for the object</returns>
private static object Wrap(object comObject, Type type, string targetName) {
if (null == comObject) {
throw new ArgumentNullException("comObject");
throw new ArgumentNullException(nameof(comObject));
}
if (null == type) {
throw new ArgumentNullException("type");
throw new ArgumentNullException(nameof(type));
}
COMWrapper wrapper = new COMWrapper(comObject, type, targetName);
@ -338,9 +339,10 @@ namespace Greenshot.Interop {
/// <param name="type">
/// The interface type to impersonate.
/// </param>
/// <param name="targetName"></param>
private COMWrapper(object comObject, Type type, string targetName) : base(type) {
_COMObject = comObject;
_COMType = comObject.GetType();
_comObject = comObject;
_comType = comObject.GetType();
_interceptType = type;
_targetName = targetName;
}
@ -374,24 +376,22 @@ namespace Greenshot.Interop {
/// <see cref="IDisposable"/> interface.
/// </param>
private void Dispose(bool disposing) {
if (null != _COMObject) {
if (null != _comObject) {
LOG.DebugFormat("Disposing {0}", _interceptType);
if (Marshal.IsComObject(_COMObject)) {
if (Marshal.IsComObject(_comObject)) {
try {
int count;
do {
count = Marshal.ReleaseComObject(_COMObject);
count = Marshal.ReleaseComObject(_comObject);
LOG.DebugFormat("RCW count for {0} now is {1}", _interceptType, count);
} while (count > 0);
} catch (Exception ex) {
LOG.WarnFormat("Problem releasing COM object {0}", _COMType);
LOG.WarnFormat("Problem releasing COM object {0}", _comType);
LOG.Warn("Error: ", ex);
}
} else {
LOG.WarnFormat("{0} is not a COM object", _COMType);
LOG.WarnFormat("{0} is not a COM object", _comType);
}
_COMObject = null;
}
}
@ -416,7 +416,7 @@ namespace Greenshot.Interop {
/// The hash code of the wrapped object.
/// </returns>
public override int GetHashCode() {
return _COMObject.GetHashCode();
return _comObject.GetHashCode();
}
/// <summary>
@ -432,7 +432,7 @@ namespace Greenshot.Interop {
if (null != value && RemotingServices.IsTransparentProxy(value)) {
COMWrapper wrapper = RemotingServices.GetRealProxy(value) as COMWrapper;
if (null != wrapper) {
return _COMObject == wrapper._COMObject;
return _comObject == wrapper._comObject;
}
}
@ -453,7 +453,7 @@ namespace Greenshot.Interop {
/// </exception>
private static Type GetByValType(Type byRefType) {
if (null == byRefType) {
throw new ArgumentNullException("byRefType");
throw new ArgumentNullException(nameof(byRefType));
}
if (byRefType.IsByRef) {
@ -467,97 +467,6 @@ namespace Greenshot.Interop {
#endregion
/// <summary>
/// Use this static method to cast a wrapped proxy to a new wrapper proxy of the supplied type.
/// In English, use this to cast you base "COM" interface to a specialized interface.
/// E.G. Outlook Item -> MailItem
/// </summary>
/// <typeparam name="T">the type you want to cast to</typeparam>
/// <param name="wrapperProxy">The wrapper interface, e.g. something you got back from calling GetItem</param>
/// <returns>A new wrapper proxy for the specified type</returns>
public static T Cast<T>(object wrapperProxy) {
if (wrapperProxy == null) {
return default(T);
}
Type newType = typeof(T);
COMWrapper oldWrapper = RemotingServices.GetRealProxy(wrapperProxy) as COMWrapper;
if (oldWrapper == null) {
throw new ArgumentException("wrapper proxy was no COMWrapper");
}
if (oldWrapper._interceptType.IsAssignableFrom(newType)) {
COMWrapper newWrapper = new COMWrapper(oldWrapper._COMObject, newType, oldWrapper._targetName);
return (T)newWrapper.GetTransparentProxy();
}
throw new InvalidCastException(string.Format("{0} is not assignable from {1}", oldWrapper._interceptType, newType));
}
/// <summary>
/// Returns the "com" type of the wrapperproxy, making it possible to perform reflection on it.
/// </summary>
/// <param name="wrapperProxy">wrapperProxy to get the type from</param>
/// <returns>Type</returns>
public static Type GetUnderlyingTypeForWrapper(object wrapperProxy) {
Type returnType = null;
COMWrapper wrapper = RemotingServices.GetRealProxy(wrapperProxy) as COMWrapper;
if (wrapper != null) {
IDispatch dispatch = wrapper._COMObject as IDispatch;
if (dispatch != null) {
int result = dispatch.GetTypeInfo(0, 0, out returnType);
if (result != 0) {
LOG.DebugFormat("GetTypeInfo : 0x{0} ({1})", result.ToString("X"), result);
}
}
}
return returnType;
}
/// <summary>
/// Return the Type of a IDispatch
/// </summary>
/// <param name="dispatch">IDispatch to get the type object for</param>
/// <returns>Type of the IDispatch</returns>
public static Type GetUnderlyingType(IDispatch dispatch) {
Type returnType = null;
if (dispatch != null) {
int result = dispatch.GetTypeInfo(0, 0, out returnType);
if (result != 0) {
LOG.DebugFormat("GetTypeInfo : 0x{0} ({1})", result.ToString("X"), result);
}
}
return returnType;
}
/// <summary>
/// Dump the Type-Information for the Type to the log, this uses reflection
/// </summary>
/// <param name="type">Type to inspect</param>
public static void DumpTypeInfo(Type type) {
LOG.InfoFormat("Type information for Type with name: {0}", type.Name);
try {
foreach (MemberInfo memberInfo in type.GetMembers()) {
LOG.InfoFormat("Member: {0};", memberInfo);
}
} catch (Exception memberException) {
LOG.Error(memberException);
}
try {
foreach (PropertyInfo propertyInfo in type.GetProperties()) {
LOG.InfoFormat("Property: {0};", propertyInfo);
}
} catch (Exception propertyException) {
LOG.Error(propertyException);
}
try {
foreach (FieldInfo fieldInfo in type.GetFields()) {
LOG.InfoFormat("Field: {0};", fieldInfo);
}
} catch (Exception fieldException) {
LOG.Error(fieldException);
}
LOG.InfoFormat("Type information end.");
}
/// <summary>
/// Intercept method calls
/// </summary>
@ -605,14 +514,14 @@ namespace Greenshot.Interop {
} else if (1 == argCount && typeof(void) == returnType && (methodName.StartsWith("add_") || methodName.StartsWith("remove_"))) {
bool removeHandler = methodName.StartsWith("remove_");
methodName = methodName.Substring(removeHandler ? 7 : 4);
// TODO: Something is missing here
Delegate handler = callMessage.InArgs[0] as Delegate;
if (null == handler) {
return new ReturnMessage(new ArgumentNullException("handler"), callMessage);
return new ReturnMessage(new ArgumentNullException(nameof(handler)), callMessage);
}
} else {
var invokeObject = _COMObject;
var invokeType = _COMType;
var invokeObject = _comObject;
var invokeType = _comType;
object[] args;
ParameterInfo parameter;
@ -661,7 +570,7 @@ namespace Greenshot.Interop {
wrapper = RemotingServices.GetRealProxy(args[i]) as COMWrapper;
if (null != wrapper) {
originalArgs[i] = wrapper;
args[i] = wrapper._COMObject;
args[i] = wrapper._comObject;
}
} else if (0 != outArgsCount && argModifiers[0][i]) {
byValType = GetByValType(parameters[i].ParameterType);
@ -755,7 +664,7 @@ namespace Greenshot.Interop {
} else if (byValType.IsInterface) {
if (Marshal.IsComObject(arg)) {
wrapper = originalArgs[i];
if (null != wrapper && wrapper._COMObject != arg) {
if (null != wrapper && wrapper._comObject != arg) {
wrapper.Dispose();
wrapper = null;
}

View file

@ -64,7 +64,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
return new Point(X, Y);
}
override public string ToString() {
public override string ToString() {
return X + "," + Y;
}
}

View file

@ -22,9 +22,6 @@ using System;
using System.Runtime.InteropServices;
using System.Text;
/// <summary>
/// Win32 error codes
/// </summary>
namespace GreenshotPlugin.UnmanagedHelpers {
/// <summary>
/// A Win32 error code.