Code quality changes

This commit is contained in:
Robin 2016-09-22 20:40:13 +02:00
commit 610f45d082
189 changed files with 4609 additions and 5203 deletions

View file

@ -41,8 +41,8 @@ namespace Greenshot.Helpers {
/// CaptureHelper contains all the capture logic
/// </summary>
public class CaptureHelper : IDisposable {
private static readonly ILog LOG = LogManager.GetLogger(typeof(CaptureHelper));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly ILog Log = LogManager.GetLogger(typeof(CaptureHelper));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
// TODO: when we get the screen capture code working correctly, this needs to be enabled
//private static ScreenCaptureHelper screenCapture = null;
private List<WindowDetails> _windows = new List<WindowDetails>();
@ -78,7 +78,7 @@ namespace Greenshot.Helpers {
_selectedCaptureWindow = null;
_capture = null;
// Empty working set after capturing
if (conf.MinimizeWorkingSetSize) {
if (CoreConfig.MinimizeWorkingSetSize) {
PsAPI.EmptyWorkingSet();
}
}
@ -114,7 +114,7 @@ namespace Greenshot.Helpers {
}
}
public static void CaptureIE(bool captureMouse, WindowDetails windowToCapture) {
public static void CaptureIe(bool captureMouse, WindowDetails windowToCapture) {
using (CaptureHelper captureHelper = new CaptureHelper(CaptureMode.IE, captureMouse)) {
captureHelper.SelectedCaptureWindow = windowToCapture;
captureHelper.MakeCapture();
@ -192,7 +192,7 @@ namespace Greenshot.Helpers {
}
private void DoCaptureFeedback() {
if(conf.PlayCameraSound) {
if(CoreConfig.PlayCameraSound) {
SoundHelper.Play();
}
}
@ -224,11 +224,11 @@ namespace Greenshot.Helpers {
// This fixes a problem when a balloon is still visible and a capture needs to be taken
// forcefully removes the balloon!
if (!conf.HideTrayicon) {
if (!CoreConfig.HideTrayicon) {
MainForm.Instance.NotifyIcon.Visible = false;
MainForm.Instance.NotifyIcon.Visible = true;
}
LOG.Debug(String.Format("Capturing with mode {0} and using Cursor {1}", _captureMode, _captureMouseCursor));
Log.Debug($"Capturing with mode {_captureMode} and using Cursor {_captureMouseCursor}");
_capture.CaptureDetails.CaptureMode = _captureMode;
// Get the windows details in a seperate thread, only for those captures that have a Feedback
@ -251,27 +251,24 @@ namespace Greenshot.Helpers {
}
// Delay for the Context menu
if (conf.CaptureDelay > 0) {
Thread.Sleep(conf.CaptureDelay);
if (CoreConfig.CaptureDelay > 0) {
Thread.Sleep(CoreConfig.CaptureDelay);
} else {
conf.CaptureDelay = 0;
CoreConfig.CaptureDelay = 0;
}
// Capture Mousecursor if we are not loading from file or clipboard, only show when needed
if (_captureMode != CaptureMode.File && _captureMode != CaptureMode.Clipboard) {
if (_captureMode != CaptureMode.File && _captureMode != CaptureMode.Clipboard)
{
_capture = WindowCapture.CaptureCursor(_capture);
if (_captureMouseCursor) {
_capture.CursorVisible = conf.CaptureMousepointer;
} else {
_capture.CursorVisible = false;
}
_capture.CursorVisible = _captureMouseCursor && CoreConfig.CaptureMousepointer;
}
switch(_captureMode) {
case CaptureMode.Window:
_capture = WindowCapture.CaptureScreen(_capture);
_capture.CaptureDetails.AddMetaData("source", "Screen");
SetDPI();
SetDpi();
CaptureWithFeedback();
break;
case CaptureMode.ActiveWindow:
@ -285,13 +282,13 @@ namespace Greenshot.Helpers {
_capture.CaptureDetails.AddMetaData("source", "Screen");
_capture.CaptureDetails.Title = "Screen";
}
SetDPI();
SetDpi();
HandleCapture();
break;
case CaptureMode.IE:
if (IECaptureHelper.CaptureIE(_capture, SelectedCaptureWindow) != null) {
if (IeCaptureHelper.CaptureIe(_capture, SelectedCaptureWindow) != null) {
_capture.CaptureDetails.AddMetaData("source", "Internet Explorer");
SetDPI();
SetDpi();
HandleCapture();
}
break;
@ -310,8 +307,8 @@ namespace Greenshot.Helpers {
}
break;
case ScreenCaptureMode.Fixed:
if (conf.ScreenToCapture > 0 && conf.ScreenToCapture <= Screen.AllScreens.Length) {
_capture = WindowCapture.CaptureRectangle(_capture, Screen.AllScreens[conf.ScreenToCapture].Bounds);
if (CoreConfig.ScreenToCapture > 0 && CoreConfig.ScreenToCapture <= Screen.AllScreens.Length) {
_capture = WindowCapture.CaptureRectangle(_capture, Screen.AllScreens[CoreConfig.ScreenToCapture].Bounds);
captureTaken = true;
}
break;
@ -322,7 +319,7 @@ namespace Greenshot.Helpers {
if (!captureTaken) {
_capture = WindowCapture.CaptureScreen(_capture);
}
SetDPI();
SetDpi();
HandleCapture();
break;
case CaptureMode.Clipboard:
@ -363,13 +360,13 @@ namespace Greenshot.Helpers {
break;
}
} catch (Exception e) {
LOG.Error(e.Message, e);
Log.Error(e.Message, e);
MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename));
}
try {
fileImage = ImageHelper.LoadImage(filename);
} catch (Exception e) {
LOG.Error(e.Message, e);
Log.Error(e.Message, e);
MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename));
}
}
@ -395,8 +392,8 @@ namespace Greenshot.Helpers {
}
break;
case CaptureMode.LastRegion:
if (!conf.LastCapturedRegion.IsEmpty) {
_capture = WindowCapture.CaptureRectangle(_capture, conf.LastCapturedRegion);
if (!CoreConfig.LastCapturedRegion.IsEmpty) {
_capture = WindowCapture.CaptureRectangle(_capture, CoreConfig.LastCapturedRegion);
// TODO: Reactive / check if the elements code is activated
//if (windowDetailsThread != null) {
// windowDetailsThread.Join();
@ -404,7 +401,7 @@ namespace Greenshot.Helpers {
// Set capture title, fixing bug #3569703
foreach (WindowDetails window in WindowDetails.GetVisibleWindows()) {
Point estimatedLocation = new Point(conf.LastCapturedRegion.X + conf.LastCapturedRegion.Width / 2, conf.LastCapturedRegion.Y + conf.LastCapturedRegion.Height / 2);
Point estimatedLocation = new Point(CoreConfig.LastCapturedRegion.X + CoreConfig.LastCapturedRegion.Width / 2, CoreConfig.LastCapturedRegion.Y + CoreConfig.LastCapturedRegion.Height / 2);
if (window.Contains(estimatedLocation)) {
_selectedCaptureWindow = window;
_capture.CaptureDetails.Title = _selectedCaptureWindow.Text;
@ -416,7 +413,7 @@ namespace Greenshot.Helpers {
//capture.MoveElements(capture.ScreenBounds.Location.X - capture.Location.X, capture.ScreenBounds.Location.Y - capture.Location.Y);
_capture.CaptureDetails.AddMetaData("source", "screen");
SetDPI();
SetDpi();
HandleCapture();
}
break;
@ -425,25 +422,23 @@ namespace Greenshot.Helpers {
if (Rectangle.Empty.Equals(_captureRect)) {
_capture = WindowCapture.CaptureScreen(_capture);
_capture.CaptureDetails.AddMetaData("source", "screen");
SetDPI();
SetDpi();
CaptureWithFeedback();
} else {
_capture = WindowCapture.CaptureRectangle(_capture, _captureRect);
_capture.CaptureDetails.AddMetaData("source", "screen");
SetDPI();
SetDpi();
HandleCapture();
}
break;
default:
LOG.Warn("Unknown capture mode: " + _captureMode);
Log.Warn("Unknown capture mode: " + _captureMode);
break;
}
// Wait for thread, otherwise we can't dipose the CaptureHelper
if (retrieveWindowDetailsThread != null) {
retrieveWindowDetailsThread.Join();
}
retrieveWindowDetailsThread?.Join();
if (_capture != null) {
LOG.Debug("Disposing capture");
Log.Debug("Disposing capture");
_capture.Dispose();
}
}
@ -471,7 +466,7 @@ namespace Greenshot.Helpers {
}
private void RetrieveWindowDetails() {
LOG.Debug("start RetrieveWindowDetails");
Log.Debug("start RetrieveWindowDetails");
// Start Enumeration of "active" windows
foreach (var window in WindowDetails.GetVisibleWindows()) {
// Make sure the details are retrieved once
@ -479,7 +474,7 @@ namespace Greenshot.Helpers {
// Force children retrieval, sometimes windows close on losing focus and this is solved by caching
int goLevelDeep = 3;
if (conf.WindowCaptureAllChildLocations) {
if (CoreConfig.WindowCaptureAllChildLocations) {
goLevelDeep = 20;
}
window.GetChildren(goLevelDeep);
@ -487,11 +482,11 @@ namespace Greenshot.Helpers {
_windows.Add(window);
}
}
LOG.Debug("end RetrieveWindowDetails");
Log.Debug("end RetrieveWindowDetails");
}
private void AddConfiguredDestination() {
foreach(string destinationDesignation in conf.OutputDestinations) {
foreach(string destinationDesignation in CoreConfig.OutputDestinations) {
IDestination destination = DestinationHelper.GetDestination(destinationDesignation);
if (destination != null) {
_capture.CaptureDetails.AddDestination(destination);
@ -507,7 +502,7 @@ namespace Greenshot.Helpers {
private void OpenCaptureOnClick(object sender, EventArgs e) {
SurfaceMessageEventArgs eventArgs = MainForm.Instance.NotifyIcon.Tag as SurfaceMessageEventArgs;
if (eventArgs == null) {
LOG.Warn("OpenCaptureOnClick called without SurfaceMessageEventArgs");
Log.Warn("OpenCaptureOnClick called without SurfaceMessageEventArgs");
RemoveEventHandler(sender, e);
return;
}
@ -515,14 +510,19 @@ namespace Greenshot.Helpers {
if (surface != null && eventArgs.MessageType == SurfaceMessageTyp.FileSaved) {
if (!string.IsNullOrEmpty(surface.LastSaveFullPath)) {
string errorMessage = null;
var path = Path.GetDirectoryName(surface.LastSaveFullPath);
try {
ProcessStartInfo psi = new ProcessStartInfo("explorer.exe");
psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath);
psi.UseShellExecute = false;
using (Process p = new Process()) {
p.StartInfo = psi;
p.Start();
if (path != null)
{
var processStartInfo = new ProcessStartInfo("explorer.exe")
{
Arguments = path,
UseShellExecute = false
};
using (var process = new Process()) {
process.StartInfo = processStartInfo;
process.Start();
}
}
} catch (Exception ex) {
errorMessage = ex.Message;
@ -531,28 +531,41 @@ namespace Greenshot.Helpers {
if (errorMessage != null) {
try {
string windowsPath = Environment.GetEnvironmentVariable("SYSTEMROOT");
string explorerPath = Path.Combine(windowsPath, "explorer.exe");
if (File.Exists(explorerPath)) {
ProcessStartInfo psi = new ProcessStartInfo(explorerPath);
psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath);
psi.UseShellExecute = false;
using (Process p = new Process()) {
p.StartInfo = psi;
p.Start();
if (windowsPath != null)
{
string explorerPath = Path.Combine(windowsPath, "explorer.exe");
if (File.Exists(explorerPath))
{
var lastSaveDirectory = Path.GetDirectoryName(surface.LastSaveFullPath);
if (lastSaveDirectory != null)
{
var processStartInfo = new ProcessStartInfo(explorerPath)
{
Arguments = lastSaveDirectory,
UseShellExecute = false
};
using (var process = new Process()) {
process.StartInfo = processStartInfo;
process.Start();
}
}
errorMessage = null;
}
errorMessage = null;
}
} catch {
}
catch
{
// ignored
}
}
if (errorMessage != null) {
MessageBox.Show(string.Format("{0}\r\nexplorer.exe {1}", errorMessage, surface.LastSaveFullPath), "explorer.exe", MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show($"{errorMessage}\r\nexplorer.exe {surface.LastSaveFullPath}", "explorer.exe", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
} else if (surface != null && !string.IsNullOrEmpty(surface.UploadUrl)) {
} else if (!string.IsNullOrEmpty(surface?.UploadUrl)) {
Process.Start(surface.UploadUrl);
}
LOG.DebugFormat("Deregistering the BalloonTipClicked");
Log.DebugFormat("Deregistering the BalloonTipClicked");
RemoveEventHandler(sender, e);
}
@ -568,7 +581,11 @@ namespace Greenshot.Helpers {
/// <param name="sender"></param>
/// <param name="eventArgs"></param>
private void SurfaceMessageReceived(object sender, SurfaceMessageEventArgs eventArgs) {
if (eventArgs == null || string.IsNullOrEmpty(eventArgs.Message)) {
if (string.IsNullOrEmpty(eventArgs?.Message)) {
return;
}
if (MainForm.Instance == null)
{
return;
}
switch (eventArgs.MessageType) {
@ -602,13 +619,13 @@ namespace Greenshot.Helpers {
outputMade = true;
} else {
// Make sure the resolution is set correctly!
if (_capture.CaptureDetails != null && _capture.Image != null) {
((Bitmap)_capture.Image).SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY);
if (_capture.CaptureDetails != null) {
((Bitmap) _capture.Image)?.SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY);
}
DoCaptureFeedback();
}
LOG.Debug("A capture of: " + _capture.CaptureDetails.Title);
Log.Debug("A capture of: " + _capture.CaptureDetails.Title);
// check if someone has passed a destination
if (_capture.CaptureDetails.CaptureDestinations == null || _capture.CaptureDetails.CaptureDestinations.Count == 0) {
@ -616,18 +633,20 @@ namespace Greenshot.Helpers {
}
// Create Surface with capture, this way elements can be added automatically (like the mouse cursor)
Surface surface = new Surface(_capture);
surface.Modified = !outputMade;
Surface surface = new Surface(_capture)
{
Modified = !outputMade
};
// Register notify events if this is wanted
if (conf.ShowTrayNotification && !conf.HideTrayicon) {
if (CoreConfig.ShowTrayNotification && !CoreConfig.HideTrayicon) {
surface.SurfaceMessage += SurfaceMessageReceived;
}
// Let the processors do their job
foreach(IProcessor processor in ProcessorHelper.GetAllProcessors()) {
if (processor.isActive) {
LOG.InfoFormat("Calling processor {0}", processor.Description);
Log.InfoFormat("Calling processor {0}", processor.Description);
processor.ProcessCapture(surface, _capture.CaptureDetails);
}
}
@ -659,7 +678,7 @@ namespace Greenshot.Helpers {
if (PickerDestination.DESIGNATION.Equals(destination.Designation)) {
continue;
}
LOG.InfoFormat("Calling destination {0}", destination.Description);
Log.InfoFormat("Calling destination {0}", destination.Description);
ExportInformation exportInformation = destination.ExportCapture(false, surface, captureDetails);
if (EditorDestination.DESIGNATION.Equals(destination.Designation) && exportInformation.ExportMade) {
@ -674,21 +693,21 @@ namespace Greenshot.Helpers {
private bool CaptureActiveWindow() {
bool presupplied = false;
LOG.Debug("CaptureActiveWindow");
Log.Debug("CaptureActiveWindow");
if (_selectedCaptureWindow != null) {
LOG.Debug("Using supplied window");
Log.Debug("Using supplied window");
presupplied = true;
} else {
_selectedCaptureWindow = WindowDetails.GetActiveWindow();
if (_selectedCaptureWindow != null) {
if (LOG.IsDebugEnabled)
if (Log.IsDebugEnabled)
{
LOG.DebugFormat("Capturing window: {0} with {1}", _selectedCaptureWindow.Text, _selectedCaptureWindow.WindowRectangle);
Log.DebugFormat("Capturing window: {0} with {1}", _selectedCaptureWindow.Text, _selectedCaptureWindow.WindowRectangle);
}
}
}
if (_selectedCaptureWindow == null || (!presupplied && _selectedCaptureWindow.Iconic)) {
LOG.Warn("No window to capture!");
Log.Warn("No window to capture!");
// Nothing to capture, code up in the stack will capture the full screen
return false;
}
@ -699,13 +718,13 @@ namespace Greenshot.Helpers {
}
_selectedCaptureWindow = SelectCaptureWindow(_selectedCaptureWindow);
if (_selectedCaptureWindow == null) {
LOG.Warn("No window to capture, after SelectCaptureWindow!");
Log.Warn("No window to capture, after SelectCaptureWindow!");
// Nothing to capture, code up in the stack will capture the full screen
return false;
}
// Fix for Bug #3430560
conf.LastCapturedRegion = _selectedCaptureWindow.WindowRectangle;
bool returnValue = CaptureWindow(_selectedCaptureWindow, _capture, conf.WindowCaptureMode) != null;
CoreConfig.LastCapturedRegion = _selectedCaptureWindow.WindowRectangle;
bool returnValue = CaptureWindow(_selectedCaptureWindow, _capture, CoreConfig.WindowCaptureMode) != null;
return returnValue;
}
@ -718,7 +737,7 @@ namespace Greenshot.Helpers {
public static WindowDetails SelectCaptureWindow(WindowDetails windowToCapture) {
Rectangle windowRectangle = windowToCapture.WindowRectangle;
if (windowRectangle.Width == 0 || windowRectangle.Height == 0) {
LOG.WarnFormat("Window {0} has nothing to capture, using workaround to find other window of same process.", windowToCapture.Text);
Log.WarnFormat("Window {0} has nothing to capture, using workaround to find other window of same process.", windowToCapture.Text);
// Trying workaround, the size 0 arrises with e.g. Toad.exe, has a different Window when minimized
WindowDetails linkedWindow = WindowDetails.GetLinkedWindow(windowToCapture);
if (linkedWindow != null) {
@ -735,18 +754,18 @@ namespace Greenshot.Helpers {
/// </summary>
/// <param name="process">Proces to check for the presentation framework</param>
/// <returns>true if the process uses WPF</returns>
private static bool isWPF(Process process) {
private static bool IsWpf(Process process) {
if (process != null) {
try {
foreach (ProcessModule module in process.Modules) {
if (module.ModuleName.StartsWith("PresentationFramework")) {
LOG.InfoFormat("Found that Process {0} uses {1}, assuming it's using WPF", process.ProcessName, module.FileName);
Log.InfoFormat("Found that Process {0} uses {1}, assuming it's using WPF", process.ProcessName, module.FileName);
return true;
}
}
} catch (Exception) {
// Access denied on the modules
LOG.WarnFormat("No access on the modules from process {0}, assuming WPF is used.", process.ProcessName);
Log.WarnFormat("No access on the modules from process {0}, assuming WPF is used.", process.ProcessName);
return true;
}
}
@ -776,14 +795,14 @@ namespace Greenshot.Helpers {
// 2) Is Windows >= Vista & DWM enabled: use DWM
// 3) Otherwise use GDI (Screen might be also okay but might lose content)
if (isAutoMode) {
if (conf.IECapture && IECaptureHelper.IsIEWindow(windowToCapture)) {
if (CoreConfig.IECapture && IeCaptureHelper.IsIeWindow(windowToCapture)) {
try {
ICapture ieCapture = IECaptureHelper.CaptureIE(captureForWindow, windowToCapture);
ICapture ieCapture = IeCaptureHelper.CaptureIe(captureForWindow, windowToCapture);
if (ieCapture != null) {
return ieCapture;
}
} catch (Exception ex) {
LOG.WarnFormat("Problem capturing IE, skipping to normal capture. Exception message was: {0}", ex.Message);
Log.WarnFormat("Problem capturing IE, skipping to normal capture. Exception message was: {0}", ex.Message);
}
}
@ -792,9 +811,9 @@ namespace Greenshot.Helpers {
// Change to GDI, if allowed
if (!windowToCapture.IsMetroApp && WindowCapture.IsGdiAllowed(process)) {
if (!dwmEnabled && isWPF(process)) {
if (!dwmEnabled && IsWpf(process)) {
// do not use GDI, as DWM is not enabled and the application uses PresentationFramework.dll -> isWPF
LOG.InfoFormat("Not using GDI for windows of process {0}, as the process uses WPF", process.ProcessName);
Log.InfoFormat("Not using GDI for windows of process {0}, as the process uses WPF", process.ProcessName);
} else {
windowCaptureMode = WindowCaptureMode.GDI;
}
@ -820,7 +839,7 @@ namespace Greenshot.Helpers {
windowCaptureMode = WindowCaptureMode.Screen;
}
LOG.InfoFormat("Capturing window with mode {0}", windowCaptureMode);
Log.InfoFormat("Capturing window with mode {0}", windowCaptureMode);
bool captureTaken = false;
windowRectangle.Intersect(captureForWindow.ScreenBounds);
// Try to capture
@ -852,7 +871,7 @@ namespace Greenshot.Helpers {
// "easy compare", both have the same size
// If GDI has more black, use the screen capture.
if (blackPercentageGdi > blackPercentageScreen) {
LOG.Debug("Using screen capture, as GDI had additional black.");
Log.Debug("Using screen capture, as GDI had additional black.");
// changeing the image will automatically dispose the previous
tmpCapture.Image = screenCapture.Image;
// Make sure it's not disposed, else the picture is gone!
@ -861,7 +880,7 @@ namespace Greenshot.Helpers {
} else if (screenPixels < gdiPixels) {
// Screen capture is cropped, window is outside of screen
if (blackPercentageGdi > 50 && blackPercentageGdi > blackPercentageScreen) {
LOG.Debug("Using screen capture, as GDI had additional black.");
Log.Debug("Using screen capture, as GDI had additional black.");
// changeing the image will automatically dispose the previous
tmpCapture.Image = screenCapture.Image;
// Make sure it's not disposed, else the picture is gone!
@ -869,7 +888,7 @@ namespace Greenshot.Helpers {
}
} else {
// Use the GDI capture by doing nothing
LOG.Debug("This should not happen, how can there be more screen as GDI pixels?");
Log.Debug("This should not happen, how can there be more screen as GDI pixels?");
}
}
}
@ -910,7 +929,7 @@ namespace Greenshot.Helpers {
captureForWindow = WindowCapture.CaptureRectangleFromDesktopScreen(captureForWindow, windowRectangle);
captureTaken = true;
} catch (Exception e) {
LOG.Error("Problem capturing", e);
Log.Error("Problem capturing", e);
return null;
}
break;
@ -918,16 +937,15 @@ namespace Greenshot.Helpers {
}
}
if (captureForWindow != null) {
if (windowToCapture != null) {
captureForWindow.CaptureDetails.Title = windowToCapture.Text;
}
if (captureForWindow != null)
{
captureForWindow.CaptureDetails.Title = windowToCapture.Text;
}
return captureForWindow;
}
private void SetDPI() {
private void SetDpi() {
// Workaround for proble with DPI retrieval, the FromHwnd activates the window...
WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow();
// Workaround for changed DPI settings in Windows 7
@ -935,12 +953,10 @@ namespace Greenshot.Helpers {
_capture.CaptureDetails.DpiX = graphics.DpiX;
_capture.CaptureDetails.DpiY = graphics.DpiY;
}
if (previouslyActiveWindow != null) {
// Set previouslyActiveWindow as foreground window
previouslyActiveWindow.ToForeground();
}
if (_capture.CaptureDetails != null && _capture.Image != null) {
((Bitmap)_capture.Image).SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY);
// Set previouslyActiveWindow as foreground window
previouslyActiveWindow?.ToForeground();
if (_capture.CaptureDetails != null) {
((Bitmap) _capture.Image)?.SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY);
}
}
@ -958,7 +974,7 @@ namespace Greenshot.Helpers {
using (CaptureForm captureForm = new CaptureForm(_capture, _windows)) {
// Make sure the form is hidden after showing, even if an exception occurs, so all errors will be shown
DialogResult result = DialogResult.Cancel;
DialogResult result;
try {
result = captureForm.ShowDialog(MainForm.Instance);
} finally {
@ -980,7 +996,7 @@ namespace Greenshot.Helpers {
// Important here is that the location needs to be offsetted back to screen coordinates!
Rectangle tmpRectangle = _captureRect;
tmpRectangle.Offset(_capture.ScreenBounds.Location.X, _capture.ScreenBounds.Location.Y);
conf.LastCapturedRegion = tmpRectangle;
CoreConfig.LastCapturedRegion = tmpRectangle;
HandleCapture();
}
}

View file

@ -39,9 +39,8 @@ namespace Greenshot.Helpers {
[Serializable()]
public class CopyDataTransport {
private readonly List<KeyValuePair<CommandEnum, string>> _commands;
public List<KeyValuePair<CommandEnum, string>> Commands {
get {return _commands;}
}
public List<KeyValuePair<CommandEnum, string>> Commands => _commands;
public CopyDataTransport() {
_commands = new List<KeyValuePair<CommandEnum, string>>();
}
@ -100,9 +99,9 @@ namespace Greenshot.Helpers {
/// </summary>
/// <param name="m">The Windows Message information.</param>
protected override void WndProc (ref Message m ) {
if (m.Msg == WM_COPYDATA) {
COPYDATASTRUCT cds = new COPYDATASTRUCT();
cds = (COPYDATASTRUCT) Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
if (m.Msg == WM_COPYDATA)
{
var cds = (COPYDATASTRUCT) Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
if (cds.cbData > 0) {
byte[] data = new byte[cds.cbData];
Marshal.Copy(cds.lpData, data, 0, cds.cbData);
@ -120,9 +119,7 @@ namespace Greenshot.Helpers {
// WM_DESTROY fires before OnHandleChanged and is
// a better place to ensure that we've cleared
// everything up.
if (_channels != null) {
_channels.OnHandleChange();
}
_channels?.OnHandleChange();
base.OnHandleChange();
}
base.WndProc(ref m);
@ -134,10 +131,7 @@ namespace Greenshot.Helpers {
/// <param name="e">The data which has been received.</param>
protected void OnCopyDataReceived(CopyDataReceivedEventArgs e)
{
if (CopyDataReceived != null)
{
CopyDataReceived(this, e);
}
CopyDataReceived?.Invoke(this, e);
}
/// <summary>
@ -149,20 +143,14 @@ namespace Greenshot.Helpers {
/// </summary>
protected override void OnHandleChange () {
// need to clear up everything we had set.
if (_channels != null) {
_channels.OnHandleChange();
}
_channels?.OnHandleChange();
base.OnHandleChange();
}
/// <summary>
/// Gets the collection of channels.
/// </summary>
public CopyDataChannels Channels {
get {
return _channels;
}
}
public CopyDataChannels Channels => _channels;
public void Dispose() {
Dispose(true);
@ -204,7 +192,7 @@ namespace Greenshot.Helpers {
/// <summary>
/// Gets the channel name that this data was sent on.
/// </summary>
public string ChannelName { get; } = "";
public string ChannelName { get; }
/// <summary>
/// Gets the data object which was sent.
@ -274,11 +262,8 @@ namespace Greenshot.Helpers {
/// <summary>
/// Returns the CopyDataChannel for the specified channelName
/// </summary>
public CopyDataChannel this[string channelName] {
get {
return (CopyDataChannel) Dictionary[channelName];
}
}
public CopyDataChannel this[string channelName] => (CopyDataChannel) Dictionary[channelName];
/// <summary>
/// Adds a new channel on which this application can send and
/// receive messages.
@ -320,7 +305,7 @@ namespace Greenshot.Helpers {
/// <param name="key">The channelName</param>
/// <param name="data">The CopyDataChannel object which has
/// just been removed</param>
protected override void OnRemoveComplete ( Object key , Object data ) {
protected override void OnRemoveComplete ( object key , object data ) {
( (CopyDataChannel) data).Dispose();
OnRemove(key, data);
}

View file

@ -31,9 +31,9 @@ namespace Greenshot.Helpers {
/// Description of DestinationHelper.
/// </summary>
public static class DestinationHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(DestinationHelper));
private static readonly ILog Log = LogManager.GetLogger(typeof(DestinationHelper));
private static readonly Dictionary<string, IDestination> RegisteredDestinations = new Dictionary<string, IDestination>();
private static readonly CoreConfiguration coreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
/// Initialize the destinations
static DestinationHelper() {
@ -47,15 +47,15 @@ namespace Greenshot.Helpers {
try {
destination = (IDestination)Activator.CreateInstance(destinationType);
} catch (Exception e) {
LOG.ErrorFormat("Can't create instance of {0}", destinationType);
LOG.Error(e);
Log.ErrorFormat("Can't create instance of {0}", destinationType);
Log.Error(e);
continue;
}
if (destination.isActive) {
LOG.DebugFormat("Found destination {0} with designation {1}", destinationType.Name, destination.Designation);
if (destination.IsActive) {
Log.DebugFormat("Found destination {0} with designation {1}", destinationType.Name, destination.Designation);
RegisterDestination(destination);
} else {
LOG.DebugFormat("Ignoring destination {0} with designation {1}", destinationType.Name, destination.Designation);
Log.DebugFormat("Ignoring destination {0} with designation {1}", destinationType.Name, destination.Designation);
}
}
}
@ -66,7 +66,7 @@ namespace Greenshot.Helpers {
/// </summary>
/// <param name="destination"></param>
public static void RegisterDestination(IDestination destination) {
if (coreConfig.ExcludeDestinations == null || !coreConfig.ExcludeDestinations.Contains(destination.Designation)) {
if (CoreConfig.ExcludeDestinations == null || !CoreConfig.ExcludeDestinations.Contains(destination.Designation)) {
// don't test the key, an exception should happen wenn it's not unique
RegisteredDestinations.Add(destination.Designation, destination);
}
@ -82,13 +82,13 @@ namespace Greenshot.Helpers {
IGreenshotPlugin plugin = PluginHelper.Instance.Plugins[pluginAttribute];
try {
foreach (IDestination destination in plugin.Destinations()) {
if (coreConfig.ExcludeDestinations == null || !coreConfig.ExcludeDestinations.Contains(destination.Designation)) {
if (CoreConfig.ExcludeDestinations == null || !CoreConfig.ExcludeDestinations.Contains(destination.Designation)) {
destinations.Add(destination);
}
}
} catch (Exception ex) {
LOG.ErrorFormat("Couldn't get destinations from the plugin {0}", pluginAttribute.Name);
LOG.Error(ex);
Log.ErrorFormat("Couldn't get destinations from the plugin {0}", pluginAttribute.Name);
Log.Error(ex);
}
}
destinations.Sort();
@ -136,7 +136,7 @@ namespace Greenshot.Helpers {
/// <param name="captureDetails"></param>
public static ExportInformation ExportCapture(bool manuallyInitiated, string designation, ISurface surface, ICaptureDetails captureDetails) {
IDestination destination = GetDestination(designation);
if (destination != null && destination.isActive) {
if (destination != null && destination.IsActive) {
return destination.ExportCapture(manuallyInitiated, surface, captureDetails);
}
return null;

View file

@ -62,7 +62,7 @@ namespace Greenshot.Helpers
if (IniConfig.IsPortable) {
environment.Append(" Portable");
}
environment.Append(" (" + OSInfo.Bits + " bit)");
environment.Append(" (" + OsInfo.Bits + " bit)");
if (newline)
{
@ -98,7 +98,7 @@ namespace Greenshot.Helpers
{
environment.Append(", ");
}
environment.Append(string.Format("OS: {0} {1} {2} (x{3}) {4}", OSInfo.Name, OSInfo.Edition, OSInfo.ServicePack, OSInfo.Bits, OSInfo.VersionString));
environment.Append(string.Format("OS: {0} {1} {2} (x{3}) {4}", OsInfo.Name, OsInfo.Edition, OsInfo.ServicePack, OsInfo.Bits, OsInfo.VersionString));
if (newline)
{
environment.AppendLine();
@ -152,9 +152,9 @@ namespace Greenshot.Helpers
StringBuilder report = new StringBuilder();
report.AppendLine("Exception: " + ex.GetType().ToString());
report.AppendLine("Exception: " + ex.GetType());
report.AppendLine("Message: " + ex.Message);
if (ex.Data != null && ex.Data.Count > 0)
if (ex.Data.Count > 0)
{
report.AppendLine();
report.AppendLine("Additional Information:");
@ -207,7 +207,7 @@ namespace Greenshot.Helpers
/// Provides detailed information about the host operating system.
/// Code is available at: http://www.csharp411.com/determine-windows-version-and-edition-with-c/
/// </summary>
public static class OSInfo
public static class OsInfo
{
#region BITS
/// <summary>
@ -261,16 +261,7 @@ namespace Greenshot.Helpers
}
else if (productType == VER_NT_SERVER)
{
if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
{
// Windows NT 4.0 Server Enterprise
edition = "Enterprise Server";
}
else
{
// Windows NT 4.0 Server
edition = "Standard Server";
}
edition = (suiteMask & VER_SUITE_ENTERPRISE) != 0 ? "Enterprise Server" : "Standard Server";
}
}
#endregion VERSION 4
@ -470,7 +461,7 @@ namespace Greenshot.Helpers
#endregion EDITION
#region NAME
private static string s_Name;
private static string _name;
/// <summary>
/// Gets the name of the operating system running on this computer.
/// </summary>
@ -478,16 +469,18 @@ namespace Greenshot.Helpers
{
get
{
if (s_Name != null)
if (_name != null)
{
return s_Name; //***** RETURN *****//
return _name; //***** RETURN *****//
}
string name = "unknown";
OperatingSystem osVersion = Environment.OSVersion;
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX));
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX
{
dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX))
};
if (GetVersionEx(ref osVersionInfo))
{
@ -514,14 +507,7 @@ namespace Greenshot.Helpers
}
break;
case 10:
if (csdVersion == "A")
{
name = "Windows 98 Second Edition";
}
else
{
name = "Windows 98";
}
name = csdVersion == "A" ? "Windows 98 Second Edition" : "Windows 98";
break;
case 90:
name = "Windows Me";
@ -629,7 +615,7 @@ namespace Greenshot.Helpers
}
}
s_Name = name;
_name = name;
return name;
}
}
@ -735,9 +721,11 @@ namespace Greenshot.Helpers
get
{
string servicePack = string.Empty;
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX
{
dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX))
};
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX));
if (GetVersionEx(ref osVersionInfo))
{
@ -754,13 +742,8 @@ namespace Greenshot.Helpers
/// <summary>
/// Gets the build version number of the operating system running on this computer.
/// </summary>
public static int BuildVersion
{
get
{
return Environment.OSVersion.Version.Build;
}
}
public static int BuildVersion => Environment.OSVersion.Version.Build;
#endregion BUILD
#region FULL

View file

@ -34,8 +34,6 @@ namespace Greenshot.Helpers {
/// <param name="y2">The point on the y-axis of the second point</param>
/// <returns></returns>
public static int Distance2D(int x1, int y1, int x2, int y2) {
//Our end result
int result = 0;
//Take x2-x1, then square it
double part1 = Math.Pow(x2 - x1, 2);
//Take y2-y1, then square it
@ -43,9 +41,7 @@ namespace Greenshot.Helpers {
//Add both of the parts together
double underRadical = part1 + part2;
//Get the square root of the parts
result = (int)Math.Sqrt(underRadical);
//Return our result
return result;
return (int)Math.Sqrt(underRadical);
}
/// <summary>

View file

@ -22,6 +22,7 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using Greenshot.Configuration;
using Greenshot.Helpers.IEInterop;
@ -41,18 +42,18 @@ namespace Greenshot.Helpers {
/// On top I modified it to use the already available code in Greenshot.
/// Many thanks to all the people who contributed here!
/// </summary>
public static class IECaptureHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(IECaptureHelper));
private static readonly CoreConfiguration configuration = IniConfig.GetIniSection<CoreConfiguration>();
public static class IeCaptureHelper {
private static readonly ILog Log = LogManager.GetLogger(typeof(IeCaptureHelper));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
// Helper method to activate a certain IE Tab
public static void ActivateIETab(WindowDetails ieWindowDetails, int tabIndex) {
WindowDetails directUIWindowDetails = IEHelper.GetDirectUI(ieWindowDetails);
if(directUIWindowDetails != null) {
public static void ActivateIeTab(WindowDetails ieWindowDetails, int tabIndex) {
WindowDetails directUiWindowDetails = IEHelper.GetDirectUI(ieWindowDetails);
if(directUiWindowDetails != null) {
// Bring window to the front
ieWindowDetails.Restore();
// Get accessible
Accessible ieAccessible = new Accessible(directUIWindowDetails.Handle);
Accessible ieAccessible = new Accessible(directUiWindowDetails.Handle);
// Activate Tab
ieAccessible.ActivateIETab(tabIndex);
}
@ -64,13 +65,13 @@ namespace Greenshot.Helpers {
/// <param name="someWindow">WindowDetails to check</param>
/// <param name="minimumPercentage">min percentage</param>
/// <returns></returns>
public static bool IsMostlyIEWindow(WindowDetails someWindow, int minimumPercentage) {
public static bool IsMostlyIeWindow(WindowDetails someWindow, int minimumPercentage) {
WindowDetails ieWindow = someWindow.GetChild("Internet Explorer_Server");
if (ieWindow != null) {
Rectangle wholeClient = someWindow.ClientRectangle;
Rectangle partClient = ieWindow.ClientRectangle;
int percentage = (int)(100*(float)(partClient.Width * partClient.Height) / (float)(wholeClient.Width * wholeClient.Height));
LOG.InfoFormat("Window {0}, ie part {1}, percentage {2}", wholeClient, partClient, percentage);
int percentage = (int)(100*(float)(partClient.Width * partClient.Height) / (wholeClient.Width * wholeClient.Height));
Log.InfoFormat("Window {0}, ie part {1}, percentage {2}", wholeClient, partClient, percentage);
if (percentage > minimumPercentage) {
return true;
}
@ -83,11 +84,11 @@ namespace Greenshot.Helpers {
/// </summary>
/// <param name="someWindow"></param>
/// <returns></returns>
public static bool IsIEWindow(WindowDetails someWindow) {
public static bool IsIeWindow(WindowDetails someWindow) {
if ("IEFrame".Equals(someWindow.ClassName)) {
return true;
}
if (configuration.WindowClassesToCheckForIE != null && configuration.WindowClassesToCheckForIE.Contains(someWindow.ClassName)) {
if (CoreConfig.WindowClassesToCheckForIE != null && CoreConfig.WindowClassesToCheckForIE.Contains(someWindow.ClassName)) {
return someWindow.GetChild("Internet Explorer_Server") != null;
}
return false;
@ -97,16 +98,16 @@ namespace Greenshot.Helpers {
/// Get Windows displaying an IE
/// </summary>
/// <returns>IEnumerable WindowDetails</returns>
public static IEnumerable<WindowDetails> GetIEWindows() {
foreach (WindowDetails possibleIEWindow in WindowDetails.GetAllWindows()) {
if (possibleIEWindow.Text.Length == 0) {
public static IEnumerable<WindowDetails> GetIeWindows() {
foreach (var possibleIeWindow in WindowDetails.GetAllWindows()) {
if (possibleIeWindow.Text.Length == 0) {
continue;
}
if (possibleIEWindow.ClientRectangle.IsEmpty) {
if (possibleIeWindow.ClientRectangle.IsEmpty) {
continue;
}
if (IsIEWindow(possibleIEWindow)) {
yield return possibleIEWindow;
if (IsIeWindow(possibleIeWindow)) {
yield return possibleIeWindow;
}
}
}
@ -115,11 +116,9 @@ namespace Greenshot.Helpers {
/// Simple check if IE is running
/// </summary>
/// <returns>bool</returns>
public static bool IsIERunning() {
foreach (WindowDetails ieWindow in GetIEWindows()) {
return true;
}
return false;
public static bool IsIeRunning()
{
return GetIeWindows().Any();
}
/// <summary>
@ -127,44 +126,46 @@ namespace Greenshot.Helpers {
/// </summary>
/// <returns>List with KeyValuePair of WindowDetails and string</returns>
public static List<KeyValuePair<WindowDetails, string>> GetBrowserTabs() {
List<IntPtr> ieHandleList = new List<IntPtr>();
Dictionary<WindowDetails, List<string>> browserWindows = new Dictionary<WindowDetails, List<string>>();
var ieHandleList = new List<IntPtr>();
var browserWindows = new Dictionary<WindowDetails, List<string>>();
// Find the IE windows
foreach (WindowDetails ieWindow in GetIEWindows()) {
foreach (var ieWindow in GetIeWindows()) {
try {
if (!ieHandleList.Contains(ieWindow.Handle)) {
if ("IEFrame".Equals(ieWindow.ClassName)) {
WindowDetails directUIWD = IEHelper.GetDirectUI(ieWindow);
if (directUIWD != null) {
Accessible accessible = new Accessible(directUIWD.Handle);
browserWindows.Add(ieWindow, accessible.IETabCaptions);
}
} else if (configuration.WindowClassesToCheckForIE != null && configuration.WindowClassesToCheckForIE.Contains(ieWindow.ClassName)) {
List<string> singleWindowText = new List<string>();
try {
IHTMLDocument2 document2 = GetHtmlDocument(ieWindow);
string title = document2.title;
Marshal.ReleaseComObject(document2);
if (string.IsNullOrEmpty(title)) {
singleWindowText.Add(ieWindow.Text);
} else {
singleWindowText.Add(ieWindow.Text + " - " + title);
}
} catch {
singleWindowText.Add(ieWindow.Text);
}
browserWindows.Add(ieWindow, singleWindowText);
}
ieHandleList.Add(ieWindow.Handle);
if (ieHandleList.Contains(ieWindow.Handle))
{
continue;
}
if ("IEFrame".Equals(ieWindow.ClassName)) {
var directUiwd = IEHelper.GetDirectUI(ieWindow);
if (directUiwd != null) {
var accessible = new Accessible(directUiwd.Handle);
browserWindows.Add(ieWindow, accessible.IETabCaptions);
}
} else if (CoreConfig.WindowClassesToCheckForIE != null && CoreConfig.WindowClassesToCheckForIE.Contains(ieWindow.ClassName)) {
var singleWindowText = new List<string>();
try {
var document2 = GetHtmlDocument(ieWindow);
string title = document2.title;
Marshal.ReleaseComObject(document2);
if (string.IsNullOrEmpty(title)) {
singleWindowText.Add(ieWindow.Text);
} else {
singleWindowText.Add(ieWindow.Text + " - " + title);
}
} catch {
singleWindowText.Add(ieWindow.Text);
}
browserWindows.Add(ieWindow, singleWindowText);
}
ieHandleList.Add(ieWindow.Handle);
} catch (Exception) {
LOG.Warn("Can't get Info from " + ieWindow.ClassName);
Log.Warn("Can't get Info from " + ieWindow.ClassName);
}
}
List<KeyValuePair<WindowDetails, string>> returnList = new List<KeyValuePair<WindowDetails, string>>();
foreach(WindowDetails windowDetails in browserWindows.Keys) {
var returnList = new List<KeyValuePair<WindowDetails, string>>();
foreach(var windowDetails in browserWindows.Keys) {
foreach(string tab in browserWindows[windowDetails]) {
returnList.Add(new KeyValuePair<WindowDetails, string>(windowDetails, tab));
}
@ -178,35 +179,30 @@ namespace Greenshot.Helpers {
/// <param name="mainWindow"></param>
/// <returns></returns>
private static IHTMLDocument2 GetHtmlDocument(WindowDetails mainWindow) {
WindowDetails ieServer;
if ("Internet Explorer_Server".Equals(mainWindow.ClassName)) {
ieServer = mainWindow;
} else {
ieServer = mainWindow.GetChild("Internet Explorer_Server");
}
var ieServer = "Internet Explorer_Server".Equals(mainWindow.ClassName) ? mainWindow : mainWindow.GetChild("Internet Explorer_Server");
if (ieServer == null) {
LOG.WarnFormat("No Internet Explorer_Server for {0}", mainWindow.Text);
Log.WarnFormat("No Internet Explorer_Server for {0}", mainWindow.Text);
return null;
}
IHTMLDocument2 document2 = null;
uint windowMessage = User32.RegisterWindowMessage("WM_HTML_GETOBJECT");
if (windowMessage == 0) {
LOG.WarnFormat("Couldn't register WM_HTML_GETOBJECT");
Log.WarnFormat("Couldn't register WM_HTML_GETOBJECT");
return null;
}
LOG.DebugFormat("Trying WM_HTML_GETOBJECT on {0}", ieServer.ClassName);
Log.DebugFormat("Trying WM_HTML_GETOBJECT on {0}", ieServer.ClassName);
UIntPtr response;
User32.SendMessageTimeout(ieServer.Handle, windowMessage, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 5000, out response);
IHTMLDocument2 document2;
if (response != UIntPtr.Zero) {
document2 = (IHTMLDocument2)Accessible.ObjectFromLresult(response, typeof(IHTMLDocument).GUID, IntPtr.Zero);
if (document2 == null) {
LOG.Error("No IHTMLDocument2 found");
Log.Error("No IHTMLDocument2 found");
return null;
}
} else {
LOG.Error("No answer on WM_HTML_GETOBJECT.");
Log.Error("No answer on WM_HTML_GETOBJECT.");
return null;
}
return document2;
@ -227,23 +223,23 @@ namespace Greenshot.Helpers {
IHTMLDocument2 alternativeReturnDocument2 = null;
// Find the IE windows
foreach (WindowDetails ieWindow in GetIEWindows()) {
LOG.DebugFormat("Processing {0} - {1}", ieWindow.ClassName, ieWindow.Text);
foreach (WindowDetails ieWindow in GetIeWindows()) {
Log.DebugFormat("Processing {0} - {1}", ieWindow.ClassName, ieWindow.Text);
Accessible ieAccessible = null;
WindowDetails directUIWD = IEHelper.GetDirectUI(ieWindow);
if (directUIWD != null) {
ieAccessible = new Accessible(directUIWD.Handle);
WindowDetails directUiwd = IEHelper.GetDirectUI(ieWindow);
if (directUiwd != null) {
ieAccessible = new Accessible(directUiwd.Handle);
}
if (ieAccessible == null) {
if (browserWindow != null) {
LOG.InfoFormat("Active Window is {0}", browserWindow.Text);
Log.InfoFormat("Active Window is {0}", browserWindow.Text);
}
if (!ieWindow.Equals(browserWindow)) {
LOG.WarnFormat("No ieAccessible for {0}", ieWindow.Text);
Log.WarnFormat("No ieAccessible for {0}", ieWindow.Text);
continue;
}
LOG.DebugFormat("No ieAccessible, but the active window is an IE window: {0}, ", ieWindow.Text);
Log.DebugFormat("No ieAccessible, but the active window is an IE window: {0}, ", ieWindow.Text);
}
try {
@ -256,9 +252,7 @@ namespace Greenshot.Helpers {
// Get the content window handle for the shellWindow.Document
IOleWindow oleWindow = (IOleWindow)document2;
IntPtr contentWindowHandle = IntPtr.Zero;
if (oleWindow != null) {
oleWindow.GetWindow(out contentWindowHandle);
}
oleWindow?.GetWindow(out contentWindowHandle);
if (contentWindowHandle != IntPtr.Zero) {
// Get the HTMLDocument to check the hasFocus
@ -266,7 +260,7 @@ namespace Greenshot.Helpers {
IHTMLDocument4 document4 = (IHTMLDocument4)document2;
if (document4.hasFocus()) {
LOG.DebugFormat("Matched focused document: {0}", document2.title);
Log.DebugFormat("Matched focused document: {0}", document2.title);
// Look no further, we got what we wanted!
returnDocument2 = document2;
returnWindow = new WindowDetails(contentWindowHandle);
@ -279,7 +273,7 @@ namespace Greenshot.Helpers {
break;
}
if (ieAccessible != null && returnWindow == null && document2.title.Equals(ieAccessible.IEActiveTabCaption) ) {
LOG.DebugFormat("Title: {0}", document2.title);
Log.DebugFormat("Title: {0}", document2.title);
returnDocument2 = document2;
returnWindow = new WindowDetails(contentWindowHandle);
} else {
@ -292,8 +286,8 @@ namespace Greenshot.Helpers {
}
}
} catch (Exception e) {
LOG.ErrorFormat("Major problem: Problem retrieving Document from {0}", ieWindow.Text);
LOG.Error(e);
Log.ErrorFormat("Major problem: Problem retrieving Document from {0}", ieWindow.Text);
Log.Error(e);
}
}
@ -307,8 +301,8 @@ namespace Greenshot.Helpers {
try {
returnDocumentContainer = new DocumentContainer(returnDocument2, returnWindow);
} catch (Exception e) {
LOG.Error("Major problem: Problem retrieving Document.");
LOG.Error(e);
Log.Error("Major problem: Problem retrieving Document.");
Log.Error(e);
}
}
@ -320,8 +314,8 @@ namespace Greenshot.Helpers {
try {
returnDocumentContainer = new DocumentContainer(alternativeReturnDocument2, alternativeReturnWindow);
} catch (Exception e) {
LOG.Error("Major problem: Problem retrieving Document.");
LOG.Error(e);
Log.Error("Major problem: Problem retrieving Document.");
Log.Error(e);
}
}
return returnDocumentContainer;
@ -332,8 +326,8 @@ namespace Greenshot.Helpers {
/// </summary>
/// <param name="capture">ICapture where the capture needs to be stored</param>
/// <returns>ICapture with the content (if any)</returns>
public static ICapture CaptureIE(ICapture capture) {
return CaptureIE(capture, WindowDetails.GetActiveWindow());
public static ICapture CaptureIe(ICapture capture) {
return CaptureIe(capture, WindowDetails.GetActiveWindow());
}
/// <summary>
/// Here the logic for capturing the IE Content is located
@ -341,7 +335,7 @@ namespace Greenshot.Helpers {
/// <param name="capture">ICapture where the capture needs to be stored</param>
/// <param name="windowToCapture">window to use</param>
/// <returns>ICapture with the content (if any)</returns>
public static ICapture CaptureIE(ICapture capture, WindowDetails windowToCapture) {
public static ICapture CaptureIe(ICapture capture, WindowDetails windowToCapture) {
if (windowToCapture == null) {
windowToCapture = WindowDetails.GetActiveWindow();
}
@ -355,15 +349,15 @@ namespace Greenshot.Helpers {
// Nothing found
if (documentContainer == null) {
LOG.Debug("Nothing to capture found");
Log.Debug("Nothing to capture found");
return null;
}
try {
LOG.DebugFormat("Window class {0}", documentContainer.ContentWindow.ClassName);
LOG.DebugFormat("Window location {0}", documentContainer.ContentWindow.Location);
Log.DebugFormat("Window class {0}", documentContainer.ContentWindow.ClassName);
Log.DebugFormat("Window location {0}", documentContainer.ContentWindow.Location);
} catch (Exception ex) {
LOG.Warn("Error while logging information.", ex);
Log.Warn("Error while logging information.", ex);
}
// bitmap to return
@ -372,12 +366,12 @@ namespace Greenshot.Helpers {
Size pageSize = PrepareCapture(documentContainer, capture);
returnBitmap = CapturePage(documentContainer, pageSize);
} catch (Exception captureException) {
LOG.Error("Exception found, ignoring and returning nothing! Error was: ", captureException);
Log.Error("Exception found, ignoring and returning nothing! Error was: ", captureException);
}
// TODO: Enable when the elements are usable again.
// Capture the element on the page
//try {
// if (configuration.IEFieldCapture && capture.CaptureDetails.HasDestination("Editor")) {
// if (CoreConfig.IEFieldCapture && capture.CaptureDetails.HasDestination("Editor")) {
// // clear the current elements, as they are for the window itself
// capture.Elements.Clear();
// CaptureElement documentCaptureElement = documentContainer.CreateCaptureElements(pageSize);
@ -414,13 +408,9 @@ namespace Greenshot.Helpers {
// The URL is available unter "document2.url" and can be used to enhance the meta-data etc.
capture.CaptureDetails.AddMetaData("url", documentContainer.Url);
// Store the title of the page
if (documentContainer.Name != null) {
capture.CaptureDetails.Title = documentContainer.Name;
} else {
capture.CaptureDetails.Title = windowToCapture.Text;
}
capture.CaptureDetails.Title = documentContainer.Name ?? windowToCapture.Text;
} catch (Exception ex) {
LOG.Warn("Problems getting some attributes...", ex);
Log.Warn("Problems getting some attributes...", ex);
}
// Store the URL of the page
@ -446,7 +436,7 @@ namespace Greenshot.Helpers {
}
capture.CaptureDetails.AddMetaData("URL_PORT", uri.Port.ToString());
} catch(Exception e) {
LOG.Warn("Exception when trying to use url in metadata "+documentContainer.Url,e);
Log.Warn("Exception when trying to use url in metadata "+documentContainer.Url,e);
}
}
try {
@ -454,7 +444,7 @@ namespace Greenshot.Helpers {
capture.MoveMouseLocation(-documentContainer.ViewportRectangle.X, -documentContainer.ViewportRectangle.Y);
// Used to be: capture.MoveMouseLocation(-(capture.Location.X + documentContainer.CaptureOffset.X), -(capture.Location.Y + documentContainer.CaptureOffset.Y));
} catch (Exception ex) {
LOG.Warn("Error while correcting the mouse offset.", ex);
Log.Warn("Error while correcting the mouse offset.", ex);
}
} finally {
// Always close the background form
@ -480,7 +470,7 @@ namespace Greenshot.Helpers {
movedFrame = false;
foreach(DocumentContainer currentFrame in documentContainer.Frames) {
foreach(DocumentContainer otherFrame in documentContainer.Frames) {
if (otherFrame.ID == currentFrame.ID) {
if (otherFrame.Id == currentFrame.Id) {
continue;
}
// check if we need to move
@ -494,16 +484,16 @@ namespace Greenshot.Helpers {
if ((horizalResize || horizalMove) && leftOf) {
// Current frame resized horizontally, so move other horizontally
LOG.DebugFormat("Moving Frame {0} horizontally to the right of {1}", otherFrame.Name, currentFrame.Name);
Log.DebugFormat("Moving Frame {0} horizontally to the right of {1}", otherFrame.Name, currentFrame.Name);
otherFrame.DestinationLeft = currentFrame.DestinationRight;
movedFrame = true;
} else if ((verticalResize || verticalMove) && belowOf){
// Current frame resized vertically, so move other vertically
LOG.DebugFormat("Moving Frame {0} vertically to the bottom of {1}", otherFrame.Name, currentFrame.Name);
Log.DebugFormat("Moving Frame {0} vertically to the bottom of {1}", otherFrame.Name, currentFrame.Name);
otherFrame.DestinationTop = currentFrame.DestinationBottom;
movedFrame = true;
} else {
LOG.DebugFormat("Frame {0} intersects with {1}", otherFrame.Name, currentFrame.Name);
Log.DebugFormat("Frame {0} intersects with {1}", otherFrame.Name, currentFrame.Name);
}
}
}
@ -539,11 +529,11 @@ namespace Greenshot.Helpers {
// Limit the size as the editor currently can't work with sizes > short.MaxValue
if (pageWidth > short.MaxValue) {
LOG.WarnFormat("Capture has a width of {0} which bigger than the maximum supported {1}, cutting width to the maxium.", pageWidth, short.MaxValue);
Log.WarnFormat("Capture has a width of {0} which bigger than the maximum supported {1}, cutting width to the maxium.", pageWidth, short.MaxValue);
pageWidth = Math.Min(pageWidth, short.MaxValue);
}
if (pageHeight > short.MaxValue) {
LOG.WarnFormat("Capture has a height of {0} which bigger than the maximum supported {1}, cutting height to the maxium", pageHeight, short.MaxValue);
Log.WarnFormat("Capture has a height of {0} which bigger than the maximum supported {1}, cutting height to the maxium", pageHeight, short.MaxValue);
pageHeight = Math.Min(pageHeight, short.MaxValue);
}
return new Size(pageWidth, pageHeight);
@ -563,7 +553,7 @@ namespace Greenshot.Helpers {
using (Graphics graphicsTarget = Graphics.FromImage(returnBitmap)) {
// Clear the target with the backgroundcolor
Color clearColor = documentContainer.BackgroundColor;
LOG.DebugFormat("Clear color: {0}", clearColor);
Log.DebugFormat("Clear color: {0}", clearColor);
graphicsTarget.Clear(clearColor);
// Get the base document & draw it
@ -597,7 +587,7 @@ namespace Greenshot.Helpers {
int pageWidth = documentContainer.ScrollWidth;
int pageHeight = documentContainer.ScrollHeight;
if (pageWidth * pageHeight == 0) {
LOG.WarnFormat("Empty page for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url);
Log.WarnFormat("Empty page for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url);
return;
}
@ -605,7 +595,7 @@ namespace Greenshot.Helpers {
int viewportWidth = documentContainer.ClientWidth;
int viewportHeight = documentContainer.ClientHeight;
if (viewportWidth * viewportHeight == 0) {
LOG.WarnFormat("Empty viewport for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url);
Log.WarnFormat("Empty viewport for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url);
return;
}
@ -613,7 +603,7 @@ namespace Greenshot.Helpers {
int startLeft = documentContainer.ScrollLeft;
int startTop = documentContainer.ScrollTop;
LOG.DebugFormat("Capturing {4} with total size {0},{1} displayed with size {2},{3}", pageWidth, pageHeight, viewportWidth, viewportHeight, documentContainer.Name);
Log.DebugFormat("Capturing {4} with total size {0},{1} displayed with size {2},{3}", pageWidth, pageHeight, viewportWidth, viewportHeight, documentContainer.Name);
// Variable used for looping horizontally
int horizontalPage = 0;
@ -640,34 +630,34 @@ namespace Greenshot.Helpers {
Rectangle clientRectangle = new Rectangle(documentContainer.SourceLocation, viewPortSize);
Image fragment = contentWindowDetails.PrintWindow();
if (fragment != null) {
LOG.DebugFormat("Captured fragment size: {0}x{1}", fragment.Width, fragment.Height);
Log.DebugFormat("Captured fragment size: {0}x{1}", fragment.Width, fragment.Height);
try {
// cut all junk, due to IE "border" we need to remove some parts
Rectangle viewportRect = documentContainer.ViewportRectangle;
if (!viewportRect.IsEmpty) {
LOG.DebugFormat("Cropping to viewport: {0}", viewportRect);
Log.DebugFormat("Cropping to viewport: {0}", viewportRect);
ImageHelper.Crop(ref fragment, ref viewportRect);
}
LOG.DebugFormat("Cropping to clientRectangle: {0}", clientRectangle);
Log.DebugFormat("Cropping to clientRectangle: {0}", clientRectangle);
// Crop to clientRectangle
if (ImageHelper.Crop(ref fragment, ref clientRectangle)) {
Point targetLocation = new Point(documentContainer.DestinationLocation.X, documentContainer.DestinationLocation.Y);
LOG.DebugFormat("Fragment targetLocation is {0}", targetLocation);
Log.DebugFormat("Fragment targetLocation is {0}", targetLocation);
targetLocation.Offset(targetOffset);
LOG.DebugFormat("After offsetting the fragment targetLocation is {0}", targetLocation);
LOG.DebugFormat("Drawing fragment of size {0} to {1}", fragment.Size, targetLocation);
Log.DebugFormat("After offsetting the fragment targetLocation is {0}", targetLocation);
Log.DebugFormat("Drawing fragment of size {0} to {1}", fragment.Size, targetLocation);
graphicsTarget.DrawImage(fragment, targetLocation);
graphicsTarget.Flush();
} else {
// somehow we are capturing nothing!?
LOG.WarnFormat("Crop of {0} failed?", documentContainer.Name);
Log.WarnFormat("Crop of {0} failed?", documentContainer.Name);
break;
}
} finally {
fragment.Dispose();
}
} else {
LOG.WarnFormat("Capture of {0} failed!", documentContainer.Name);
Log.WarnFormat("Capture of {0} failed!", documentContainer.Name);
}
verticalPage++;
}

View file

@ -36,15 +36,12 @@ namespace Greenshot.Helpers.IEInterop {
private static readonly Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
private static readonly Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E");
private static int _counter;
private readonly int _id = _counter++;
private IHTMLDocument2 _document2;
private IHTMLDocument3 _document3;
private Point _sourceLocation;
private Point _destinationLocation;
private Point _startLocation = Point.Empty;
private Rectangle _viewportRectangle = Rectangle.Empty;
private string _name;
private string _url;
private bool _isDtd;
private DocumentContainer _parent;
private WindowDetails _contentWindow;
@ -58,7 +55,7 @@ namespace Greenshot.Helpers.IEInterop {
IHTMLDocument2 document2 = GetDocumentFromWindow(frameWindow);
try {
LOG.DebugFormat("frameWindow.name {0}", frameWindow.name);
_name = frameWindow.name;
Name = frameWindow.name;
} catch {
// Ignore
}
@ -91,7 +88,7 @@ namespace Greenshot.Helpers.IEInterop {
public DocumentContainer(IHTMLDocument2 document2, WindowDetails contentWindow) {
Init(document2, contentWindow);
LOG.DebugFormat("Creating DocumentContainer for Document {0} found in window with rectangle {1}", _name, SourceRectangle);
LOG.DebugFormat("Creating DocumentContainer for Document {0} found in window with rectangle {1}", Name, SourceRectangle);
}
/// <summary>
@ -119,7 +116,7 @@ namespace Greenshot.Helpers.IEInterop {
//compatibility mode affects how height is computed
_isDtd = false;
try {
if (_document3 != null && (_document3.documentElement != null) && !document5.compatMode.Equals("BackCompat")) {
if (_document3?.documentElement != null && !document5.compatMode.Equals("BackCompat")) {
_isDtd = true;
}
} catch (Exception ex) {
@ -176,15 +173,15 @@ namespace Greenshot.Helpers.IEInterop {
try {
LOG.DebugFormat("Calculated location {0} for {1}", _startLocation, document2.title);
if (_name == null) {
_name = document2.title;
if (Name == null) {
Name = document2.title;
}
} catch (Exception e) {
LOG.Warn("Problem while trying to get document title!", e);
}
try {
_url = document2.url;
Url = document2.url;
} catch (Exception e) {
LOG.Warn("Problem while trying to get document url!", e);
}
@ -202,7 +199,7 @@ namespace Greenshot.Helpers.IEInterop {
DocumentContainer frameData = new DocumentContainer(frameWindow, contentWindow, this);
// check if frame is hidden
if (!frameData.IsHidden) {
LOG.DebugFormat("Creating DocumentContainer for Frame {0} found in window with rectangle {1}", frameData._name, frameData.SourceRectangle);
LOG.DebugFormat("Creating DocumentContainer for Frame {0} found in window with rectangle {1}", frameData.Name, frameData.SourceRectangle);
_frames.Add(frameData);
} else {
LOG.DebugFormat("Skipping frame {0}", frameData.Name);
@ -341,18 +338,10 @@ namespace Greenshot.Helpers.IEInterop {
}
}
public Rectangle ViewportRectangle {
get {
return _viewportRectangle;
}
}
public Rectangle ViewportRectangle => _viewportRectangle;
public WindowDetails ContentWindow => _contentWindow;
public WindowDetails ContentWindow {
get {
return _contentWindow;
}
}
public DocumentContainer Parent {
get {
return _parent;
@ -391,12 +380,7 @@ namespace Greenshot.Helpers.IEInterop {
/// <param name="attribute">Attribute to set</param>
/// <param name="value">Value to set</param>
public void SetAttribute(string attribute, string value) {
IHTMLElement element = null;
if (!_isDtd) {
element = _document2.body;
} else {
element = _document3.documentElement;
}
var element = !_isDtd ? _document2.body : _document3.documentElement;
element.setAttribute(attribute, value, 1);
// Release IHTMLElement com object
releaseCom(element);
@ -408,12 +392,7 @@ namespace Greenshot.Helpers.IEInterop {
/// <param name="attribute">Attribute to get</param>
/// <returns>object with the attribute value</returns>
public object GetAttribute(string attribute) {
IHTMLElement element;
if (!_isDtd) {
element = _document2.body;
} else {
element = _document3.documentElement;
}
var element = !_isDtd ? _document2.body : _document3.documentElement;
var retVal = element.getAttribute(attribute, 1);
// Release IHTMLElement com object
releaseCom(element);
@ -428,53 +407,21 @@ namespace Greenshot.Helpers.IEInterop {
return retVal;
}
public int ID {
get {
return _id;
}
}
public int Id { get; } = _counter++;
public string Name {
get {
return _name;
}
}
public string Name { get; private set; }
public string Url {
get {
return _url;
}
}
public string Url { get; private set; }
public bool IsHidden {
get {
return ClientWidth == 0 || ClientHeight == 0;
}
}
public bool IsHidden => ClientWidth == 0 || ClientHeight == 0;
public int ClientWidth {
get {
return ScaleX(GetAttributeAsInt("clientWidth"));
}
}
public int ClientWidth => ScaleX(GetAttributeAsInt("clientWidth"));
public int ClientHeight {
get {
return ScaleY(GetAttributeAsInt("clientHeight"));
}
}
public int ClientHeight => ScaleY(GetAttributeAsInt("clientHeight"));
public int ScrollWidth {
get {
return ScaleX(GetAttributeAsInt("scrollWidth"));
}
}
public int ScrollWidth => ScaleX(GetAttributeAsInt("scrollWidth"));
public int ScrollHeight {
get {
return ScaleY(GetAttributeAsInt("scrollHeight"));
}
}
public int ScrollHeight => ScaleY(GetAttributeAsInt("scrollHeight"));
public Point SourceLocation {
get {
@ -485,41 +432,17 @@ namespace Greenshot.Helpers.IEInterop {
}
}
public Size SourceSize {
get {
return new Size(ClientWidth, ClientHeight);
}
}
public Size SourceSize => new Size(ClientWidth, ClientHeight);
public Rectangle SourceRectangle {
get {
return new Rectangle(SourceLocation, SourceSize);
}
}
public Rectangle SourceRectangle => new Rectangle(SourceLocation, SourceSize);
public int SourceLeft {
get {
return _sourceLocation.X;
}
}
public int SourceLeft => _sourceLocation.X;
public int SourceTop {
get {
return _sourceLocation.Y;
}
}
public int SourceTop => _sourceLocation.Y;
public int SourceRight {
get {
return _sourceLocation.X + ClientWidth;
}
}
public int SourceRight => _sourceLocation.X + ClientWidth;
public int SourceBottom {
get {
return _sourceLocation.Y + ClientHeight;
}
}
public int SourceBottom => _sourceLocation.Y + ClientHeight;
public Point DestinationLocation {
get {
@ -531,17 +454,9 @@ namespace Greenshot.Helpers.IEInterop {
}
public Size DestinationSize {
get {
return new Size(ScrollWidth, ScrollHeight);
}
}
public Rectangle DestinationRectangle {
get {
return new Rectangle(DestinationLocation, DestinationSize);
}
}
public Size DestinationSize => new Size(ScrollWidth, ScrollHeight);
public Rectangle DestinationRectangle => new Rectangle(DestinationLocation, DestinationSize);
public int DestinationLeft {
get {
@ -561,17 +476,9 @@ namespace Greenshot.Helpers.IEInterop {
}
}
public int DestinationRight {
get {
return _destinationLocation.X + ScrollWidth;
}
}
public int DestinationRight => _destinationLocation.X + ScrollWidth;
public int DestinationBottom {
get {
return _destinationLocation.Y + ScrollHeight;
}
}
public int DestinationBottom => _destinationLocation.Y + ScrollHeight;
public int ScrollLeft {
get{
@ -591,10 +498,6 @@ namespace Greenshot.Helpers.IEInterop {
}
}
public IList<DocumentContainer> Frames {
get {
return _frames;
}
}
public IList<DocumentContainer> Frames => _frames;
}
}

View file

@ -43,8 +43,8 @@ namespace Greenshot.Helpers {
/// Represents an email message to be sent through MAPI.
/// </summary>
public class MapiMailMessage : IDisposable {
private static readonly ILog LOG = LogManager.GetLogger(typeof(MapiMailMessage));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly ILog Log = LogManager.GetLogger(typeof(MapiMailMessage));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
/// <summary>
/// Helper Method for creating an Email with Attachment
@ -54,14 +54,14 @@ namespace Greenshot.Helpers {
public static void SendImage(string fullPath, string title) {
using (MapiMailMessage message = new MapiMailMessage(title, null)) {
message.Files.Add(fullPath);
if (!string.IsNullOrEmpty(conf.MailApiTo)) {
message._recipientCollection.Add(new Recipient(conf.MailApiTo, RecipientType.To));
if (!string.IsNullOrEmpty(CoreConfig.MailApiTo)) {
message.Recipients.Add(new Recipient(CoreConfig.MailApiTo, RecipientType.To));
}
if (!string.IsNullOrEmpty(conf.MailApiCC)) {
message._recipientCollection.Add(new Recipient(conf.MailApiCC, RecipientType.CC));
if (!string.IsNullOrEmpty(CoreConfig.MailApiCC)) {
message.Recipients.Add(new Recipient(CoreConfig.MailApiCC, RecipientType.CC));
}
if (!string.IsNullOrEmpty(conf.MailApiBCC)) {
message._recipientCollection.Add(new Recipient(conf.MailApiBCC, RecipientType.BCC));
if (!string.IsNullOrEmpty(CoreConfig.MailApiBCC)) {
message.Recipients.Add(new Recipient(CoreConfig.MailApiBCC, RecipientType.BCC));
}
message.ShowDialog();
}
@ -80,10 +80,10 @@ namespace Greenshot.Helpers {
// Store the list of currently active windows, so we can make sure we show the email window later!
var windowsBefore = WindowDetails.GetVisibleWindows();
//bool isEmailSend = false;
//if (EmailConfigHelper.HasOutlook() && (conf.OutputEMailFormat == EmailFormat.OUTLOOK_HTML || conf.OutputEMailFormat == EmailFormat.OUTLOOK_TXT)) {
//if (EmailConfigHelper.HasOutlook() && (CoreConfig.OutputEMailFormat == EmailFormat.OUTLOOK_HTML || CoreConfig.OutputEMailFormat == EmailFormat.OUTLOOK_TXT)) {
// isEmailSend = OutlookExporter.ExportToOutlook(tmpFile, captureDetails);
//}
if (/*!isEmailSend &&*/ EmailConfigHelper.HasMAPI()) {
if (/*!isEmailSend &&*/ EmailConfigHelper.HasMapi()) {
// Fallback to MAPI
// Send the email
SendImage(tmpFile, captureDetails.Title);
@ -132,9 +132,6 @@ namespace Greenshot.Helpers {
#region Member Variables
private string _subject;
private string _body;
private RecipientCollection _recipientCollection;
private readonly ManualResetEvent _manualResetEvent;
#endregion Member Variables
@ -146,7 +143,7 @@ namespace Greenshot.Helpers {
/// </summary>
public MapiMailMessage() {
Files = new List<string>();
_recipientCollection = new RecipientCollection();
Recipients = new RecipientCollection();
_manualResetEvent = new ManualResetEvent(false);
}
@ -154,15 +151,15 @@ namespace Greenshot.Helpers {
/// Creates a new mail message with the specified subject.
/// </summary>
public MapiMailMessage(string subject) : this() {
_subject = subject;
Subject = subject;
}
/// <summary>
/// Creates a new mail message with the specified subject and body.
/// </summary>
public MapiMailMessage(string subject, string body) : this() {
_subject = subject;
_body = body;
Subject = subject;
Body = body;
}
#endregion Constructors
@ -172,35 +169,17 @@ namespace Greenshot.Helpers {
/// <summary>
/// Gets or sets the subject of this mail message.
/// </summary>
public string Subject {
get {
return _subject;
}
set {
_subject = value;
}
}
public string Subject { get; set; }
/// <summary>
/// Gets or sets the body of this mail message.
/// </summary>
public string Body {
get {
return _body;
}
set {
_body = value;
}
}
public string Body { get; set; }
/// <summary>
/// Gets the recipient list for this mail message.
/// </summary>
public RecipientCollection Recipients {
get {
return _recipientCollection;
}
}
public RecipientCollection Recipients { get; private set; }
/// <summary>
/// Gets the file list for this mail message.
@ -216,11 +195,13 @@ namespace Greenshot.Helpers {
/// </summary>
public void ShowDialog() {
// Create the mail message in an STA thread
Thread t = new Thread(_ShowMail);
t.IsBackground = true;
t.Name = "Create MAPI mail";
t.SetApartmentState(ApartmentState.STA);
t.Start();
var thread = new Thread(_ShowMail)
{
IsBackground = true,
Name = "Create MAPI mail"
};
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
// only return when the new thread has built it's interop representation
_manualResetEvent.WaitOne();
@ -240,10 +221,7 @@ namespace Greenshot.Helpers {
if (!disposing) {
return;
}
if (_manualResetEvent != null) {
_manualResetEvent.Close();
}
_manualResetEvent?.Close();
}
/// <summary>
@ -252,12 +230,12 @@ namespace Greenshot.Helpers {
private void _ShowMail() {
var message = new MapiHelperInterop.MapiMessage();
using (var interopRecipients = _recipientCollection.GetInteropRepresentation()) {
message.Subject = _subject;
message.NoteText = _body;
using (var interopRecipients = Recipients.GetInteropRepresentation()) {
message.Subject = Subject;
message.NoteText = Body;
message.Recipients = interopRecipients.Handle;
message.RecipientCount = _recipientCollection.Count;
message.RecipientCount = Recipients.Count;
// Check if we need to add attachments
if (Files.Count > 0) {
@ -284,14 +262,14 @@ namespace Greenshot.Helpers {
return;
}
string errorText = GetMapiError(errorCode);
LOG.Error("Error sending MAPI Email. Error: " + errorText + " (code = " + errorCode + ").");
Log.Error("Error sending MAPI Email. Error: " + errorText + " (code = " + errorCode + ").");
MessageBox.Show(errorText, "Mail (MAPI) destination", MessageBoxButtons.OK, MessageBoxIcon.Error);
// Recover from bad settings, show again
if (errorCode != MAPI_CODES.INVALID_RECIPS)
{
return;
}
_recipientCollection = new RecipientCollection();
Recipients = new RecipientCollection();
_ShowMail();
}
}
@ -340,8 +318,8 @@ namespace Greenshot.Helpers {
position = -1
};
IntPtr runptr = ptra;
for (int i = 0; i < Files.Count; i++) {
string path = Files[i];
foreach (string path in Files)
{
mfd.name = Path.GetFileName(path);
mfd.path = path;
Marshal.StructureToPtr(mfd, runptr, false);
@ -664,11 +642,7 @@ namespace Greenshot.Helpers {
/// <summary>
/// Returns the recipient stored in this collection at the specified index.
/// </summary>
public Recipient this[int index] {
get {
return (Recipient)List[index];
}
}
public Recipient this[int index] => (Recipient)List[index];
internal InteropRecipientCollection GetInteropRepresentation() {
return new InteropRecipientCollection(this);
@ -680,7 +654,6 @@ namespace Greenshot.Helpers {
internal struct InteropRecipientCollection : IDisposable {
#region Member Variables
private IntPtr _handle;
private int _count;
#endregion Member Variables
@ -695,16 +668,16 @@ namespace Greenshot.Helpers {
_count = outer.Count;
if (_count == 0) {
_handle = IntPtr.Zero;
Handle = IntPtr.Zero;
return;
}
// allocate enough memory to hold all recipients
int size = Marshal.SizeOf(typeof(MapiMailMessage.MapiHelperInterop.MapiRecipDesc));
_handle = Marshal.AllocHGlobal(_count * size);
Handle = Marshal.AllocHGlobal(_count * size);
// place all interop recipients into the memory just allocated
IntPtr ptr = _handle;
IntPtr ptr = Handle;
foreach (Recipient native in outer) {
MapiMailMessage.MapiHelperInterop.MapiRecipDesc interop = native.GetInteropRepresentation();
@ -718,11 +691,7 @@ namespace Greenshot.Helpers {
#region Public Properties
public IntPtr Handle {
get {
return _handle;
}
}
public IntPtr Handle { get; private set; }
#endregion Public Properties
@ -732,21 +701,21 @@ namespace Greenshot.Helpers {
/// Disposes of resources.
/// </summary>
public void Dispose() {
if (_handle != IntPtr.Zero) {
if (Handle != IntPtr.Zero) {
Type type = typeof(MapiMailMessage.MapiHelperInterop.MapiRecipDesc);
int size = Marshal.SizeOf(type);
// destroy all the structures in the memory area
IntPtr ptr = _handle;
IntPtr ptr = Handle;
for (int i = 0; i < _count; i++) {
Marshal.DestroyStructure(ptr, type);
ptr = new IntPtr(ptr.ToInt64() + size);
}
// free the memory
Marshal.FreeHGlobal(_handle);
Marshal.FreeHGlobal(Handle);
_handle = IntPtr.Zero;
Handle = IntPtr.Zero;
_count = 0;
}
}

View file

@ -35,42 +35,31 @@ namespace Greenshot.Helpers {
/// </summary>
[Serializable]
public class PluginHelper : IGreenshotHost {
private static readonly ILog LOG = LogManager.GetLogger(typeof(PluginHelper));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly ILog Log = LogManager.GetLogger(typeof(PluginHelper));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly string pluginPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),Application.ProductName);
private static readonly string applicationPath = Path.GetDirectoryName(Application.ExecutablePath);
private static readonly string pafPath = Path.Combine(Application.StartupPath, @"App\Greenshot");
private static readonly string PluginPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),Application.ProductName);
private static readonly string ApplicationPath = Path.GetDirectoryName(Application.ExecutablePath);
private static readonly string PafPath = Path.Combine(Application.StartupPath, @"App\Greenshot");
private static readonly IDictionary<PluginAttribute, IGreenshotPlugin> plugins = new SortedDictionary<PluginAttribute, IGreenshotPlugin>();
private static readonly PluginHelper instance = new PluginHelper();
public static PluginHelper Instance {
get {
return instance;
}
}
public static PluginHelper Instance => instance;
private PluginHelper() {
PluginUtils.Host = this;
}
public Form GreenshotForm {
get {
return MainForm.Instance;
}
}
public Form GreenshotForm => MainForm.Instance;
public NotifyIcon NotifyIcon {
get {
return MainForm.Instance.NotifyIcon;
}
}
public NotifyIcon NotifyIcon => MainForm.Instance.NotifyIcon;
public bool HasPlugins() {
return plugins != null && plugins.Count > 0;
}
public void Shutdown() {
foreach(IGreenshotPlugin plugin in plugins.Values) {
foreach(var plugin in plugins.Values) {
plugin.Shutdown();
plugin.Dispose();
}
@ -79,42 +68,49 @@ namespace Greenshot.Helpers {
// Add plugins to the Listview
public void FillListview(ListView listview) {
foreach(PluginAttribute pluginAttribute in plugins.Keys) {
ListViewItem item = new ListViewItem(pluginAttribute.Name);
foreach(var pluginAttribute in plugins.Keys) {
var item = new ListViewItem(pluginAttribute.Name)
{
Tag = pluginAttribute
};
item.SubItems.Add(pluginAttribute.Version);
item.SubItems.Add(pluginAttribute.CreatedBy);
item.SubItems.Add(pluginAttribute.DllFile);
item.Tag = pluginAttribute;
listview.Items.Add(item);
}
}
public bool isSelectedItemConfigurable(ListView listview) {
if (listview.SelectedItems.Count > 0) {
PluginAttribute pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag;
if (pluginAttribute != null) {
return pluginAttribute.Configurable;
}
public bool IsSelectedItemConfigurable(ListView listview) {
if (listview.SelectedItems.Count <= 0)
{
return false;
}
return false;
var pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag;
return pluginAttribute != null && pluginAttribute.Configurable;
}
public void ConfigureSelectedItem(ListView listview) {
if (listview.SelectedItems.Count > 0) {
PluginAttribute pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag;
if (pluginAttribute != null) {
IGreenshotPlugin plugin = plugins[pluginAttribute];
plugin.Configure();
}
if (listview.SelectedItems.Count <= 0)
{
return;
}
var pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag;
if (pluginAttribute == null)
{
return;
}
var plugin = plugins[pluginAttribute];
plugin.Configure();
}
#region Implementation of IGreenshotPluginHost
/// <summary>
/// Create a Thumbnail
/// </summary>
/// <param name="image">Image of which we need a Thumbnail</param>
/// <param name="width">Thumbnail width</param>
/// <param name="height">Thumbnail height</param>
/// <returns>Image with Thumbnail</returns>
public Image GetThumbnail(Image image, int width, int height) {
return image.GetThumbnailImage(width, height, ThumbnailCallback, IntPtr.Zero);
@ -128,15 +124,9 @@ namespace Greenshot.Helpers {
return true;
}
public ContextMenuStrip MainMenu {
get {
return MainForm.Instance.MainMenu;
}
}
public IDictionary<PluginAttribute, IGreenshotPlugin> Plugins {
get {return plugins;}
}
public ContextMenuStrip MainMenu => MainForm.Instance.MainMenu;
public IDictionary<PluginAttribute, IGreenshotPlugin> Plugins => plugins;
public IDestination GetDestination(string designation) {
return DestinationHelper.GetDestination(designation);
@ -161,7 +151,7 @@ namespace Greenshot.Helpers {
/// <summary>
/// Use the supplied image, and handle it as if it's captured.
/// </summary>
/// <param name="imageToImport">Image to handle</param>
/// <param name="captureToImport">Image to handle</param>
public void ImportCapture(ICapture captureToImport) {
MainForm.Instance.BeginInvoke((MethodInvoker)delegate {
CaptureHelper.ImportCapture(captureToImport);
@ -173,10 +163,14 @@ namespace Greenshot.Helpers {
/// </summary>
/// <returns></returns>
public ICapture GetCapture(Image imageToCapture) {
Capture capture = new Capture(imageToCapture);
capture.CaptureDetails = new CaptureDetails();
capture.CaptureDetails.CaptureMode = CaptureMode.Import;
capture.CaptureDetails.Title = "Imported";
var capture = new Capture(imageToCapture)
{
CaptureDetails = new CaptureDetails
{
CaptureMode = CaptureMode.Import,
Title = "Imported"
}
};
return capture;
}
#endregion
@ -220,9 +214,8 @@ namespace Greenshot.Helpers {
pluginFiles.Add(pluginFile);
}
} catch (UnauthorizedAccessException) {
return;
} catch (Exception ex) {
LOG.Error("Error loading plugin: ", ex);
Log.Error("Error loading plugin: ", ex);
}
}
}
@ -234,10 +227,10 @@ namespace Greenshot.Helpers {
List<string> pluginFiles = new List<string>();
if (IniConfig.IsPortable) {
findPluginsOnPath(pluginFiles, pafPath);
findPluginsOnPath(pluginFiles, PafPath);
} else {
findPluginsOnPath(pluginFiles, pluginPath);
findPluginsOnPath(pluginFiles, applicationPath);
findPluginsOnPath(pluginFiles, PluginPath);
findPluginsOnPath(pluginFiles, ApplicationPath);
}
Dictionary<string, PluginAttribute> tmpAttributes = new Dictionary<string, PluginAttribute>();
@ -277,36 +270,36 @@ namespace Greenshot.Helpers {
}
if (checkPluginAttribute != null) {
LOG.WarnFormat("Duplicate plugin {0} found", pluginAttribute.Name);
Log.WarnFormat("Duplicate plugin {0} found", pluginAttribute.Name);
if (isNewer(pluginAttribute.Version, checkPluginAttribute.Version)) {
// Found is newer
tmpAttributes[pluginAttribute.Name] = pluginAttribute;
tmpAssemblies[pluginAttribute.Name] = assembly;
LOG.InfoFormat("Loading the newer plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
Log.InfoFormat("Loading the newer plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
} else {
LOG.InfoFormat("Skipping (as the duplicate is newer or same version) the plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
Log.InfoFormat("Skipping (as the duplicate is newer or same version) the plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
}
continue;
}
if (conf.ExcludePlugins != null && conf.ExcludePlugins.Contains(pluginAttribute.Name)) {
LOG.WarnFormat("Exclude list: {0}", conf.ExcludePlugins.ToArray());
LOG.WarnFormat("Skipping the excluded plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
if (CoreConfig.ExcludePlugins != null && CoreConfig.ExcludePlugins.Contains(pluginAttribute.Name)) {
Log.WarnFormat("Exclude list: {0}", CoreConfig.ExcludePlugins.ToArray());
Log.WarnFormat("Skipping the excluded plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
continue;
}
if (conf.IncludePlugins != null && conf.IncludePlugins.Count > 0 && !conf.IncludePlugins.Contains(pluginAttribute.Name)) {
if (CoreConfig.IncludePlugins != null && CoreConfig.IncludePlugins.Count > 0 && !CoreConfig.IncludePlugins.Contains(pluginAttribute.Name)) {
// Whitelist is set
LOG.WarnFormat("Include list: {0}", conf.IncludePlugins.ToArray());
LOG.WarnFormat("Skipping the not included plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
Log.WarnFormat("Include list: {0}", CoreConfig.IncludePlugins.ToArray());
Log.WarnFormat("Skipping the not included plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
continue;
}
LOG.InfoFormat("Loading the plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
Log.InfoFormat("Loading the plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
tmpAttributes[pluginAttribute.Name] = pluginAttribute;
tmpAssemblies[pluginAttribute.Name] = assembly;
} else {
LOG.ErrorFormat("Can't find the needed Plugin Attribute ({0}) in the assembly of the file \"{1}\", skipping this file.", typeof(PluginAttribute), pluginFile);
Log.ErrorFormat("Can't find the needed Plugin Attribute ({0}) in the assembly of the file \"{1}\", skipping this file.", typeof(PluginAttribute), pluginFile);
}
} catch (Exception e) {
LOG.Warn("Can't load file: " + pluginFile, e);
Log.Warn("Can't load file: " + pluginFile, e);
}
}
foreach(string pluginName in tmpAttributes.Keys) {
@ -315,7 +308,7 @@ namespace Greenshot.Helpers {
Assembly assembly = tmpAssemblies[pluginName];
Type entryType = assembly.GetType(pluginAttribute.EntryType);
if (entryType == null) {
LOG.ErrorFormat("Can't find the in the PluginAttribute referenced type {0} in \"{1}\"", pluginAttribute.EntryType, pluginAttribute.DllFile);
Log.ErrorFormat("Can't find the in the PluginAttribute referenced type {0} in \"{1}\"", pluginAttribute.EntryType, pluginAttribute.DllFile);
continue;
}
try {
@ -324,16 +317,16 @@ namespace Greenshot.Helpers {
if (plugin.Initialize(this, pluginAttribute)) {
plugins.Add(pluginAttribute, plugin);
} else {
LOG.InfoFormat("Plugin {0} not initialized!", pluginAttribute.Name);
Log.InfoFormat("Plugin {0} not initialized!", pluginAttribute.Name);
}
} else {
LOG.ErrorFormat("Can't create an instance of the in the PluginAttribute referenced type {0} from \"{1}\"", pluginAttribute.EntryType, pluginAttribute.DllFile);
Log.ErrorFormat("Can't create an instance of the in the PluginAttribute referenced type {0} from \"{1}\"", pluginAttribute.EntryType, pluginAttribute.DllFile);
}
} catch(Exception e) {
LOG.Error("Can't load Plugin: " + pluginAttribute.Name, e);
Log.Error("Can't load Plugin: " + pluginAttribute.Name, e);
}
} catch(Exception e) {
LOG.Error("Can't load Plugin: " + pluginName, e);
Log.Error("Can't load Plugin: " + pluginName, e);
}
}
}

View file

@ -28,7 +28,7 @@ using Greenshot.Forms;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using Greenshot.IniFile;
using Greenshot.Core;
using GreenshotPlugin.Effects;
using log4net;
namespace Greenshot.Helpers {
@ -36,21 +36,21 @@ namespace Greenshot.Helpers {
/// Description of PrintHelper.
/// </summary>
public class PrintHelper : IDisposable {
private static readonly ILog LOG = LogManager.GetLogger(typeof(PrintHelper));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly ILog Log = LogManager.GetLogger(typeof(PrintHelper));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private ISurface surface;
private readonly ICaptureDetails captureDetails;
private PrintDocument printDocument = new PrintDocument();
private PrintDialog printDialog = new PrintDialog();
private ISurface _surface;
private readonly ICaptureDetails _captureDetails;
private PrintDocument _printDocument = new PrintDocument();
private PrintDialog _printDialog = new PrintDialog();
public PrintHelper(ISurface surface, ICaptureDetails captureDetails) {
this.surface = surface;
this.captureDetails = captureDetails;
printDialog.UseEXDialog = true;
printDocument.DocumentName = FilenameHelper.GetFilenameWithoutExtensionFromPattern(conf.OutputFileFilenamePattern, captureDetails);
printDocument.PrintPage += DrawImageForPrint;
printDialog.Document = printDocument;
_surface = surface;
_captureDetails = captureDetails;
_printDialog.UseEXDialog = true;
_printDocument.DocumentName = FilenameHelper.GetFilenameWithoutExtensionFromPattern(CoreConfig.OutputFileFilenamePattern, captureDetails);
_printDocument.PrintPage += DrawImageForPrint;
_printDialog.Document = _printDocument;
}
/**
@ -75,16 +75,12 @@ namespace Greenshot.Helpers {
*/
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (printDocument != null) {
printDocument.Dispose();
}
if (printDialog != null) {
printDialog.Dispose();
}
_printDocument?.Dispose();
_printDialog?.Dispose();
}
surface = null;
printDocument = null;
printDialog = null;
_surface = null;
_printDocument = null;
_printDialog = null;
}
/// <summary>
@ -97,15 +93,15 @@ namespace Greenshot.Helpers {
DialogResult? printOptionsResult = ShowPrintOptionsDialog();
try {
if (printOptionsResult == null || printOptionsResult == DialogResult.OK) {
printDocument.PrinterSettings.PrinterName = printerName;
_printDocument.PrinterSettings.PrinterName = printerName;
if (!IsColorPrint()) {
printDocument.DefaultPageSettings.Color = false;
_printDocument.DefaultPageSettings.Color = false;
}
printDocument.Print();
returnPrinterSettings = printDocument.PrinterSettings;
_printDocument.Print();
returnPrinterSettings = _printDocument.PrinterSettings;
}
} catch (Exception e) {
LOG.Error("An error ocurred while trying to print", e);
Log.Error("An error ocurred while trying to print", e);
MessageBox.Show(Language.GetString(LangKey.print_error), Language.GetString(LangKey.error));
}
return returnPrinterSettings;
@ -118,18 +114,18 @@ namespace Greenshot.Helpers {
/// <returns>printer settings if actually printed, or null if print was cancelled or has failed</returns>
public PrinterSettings PrintWithDialog() {
PrinterSettings returnPrinterSettings = null;
if (printDialog.ShowDialog() == DialogResult.OK) {
if (_printDialog.ShowDialog() == DialogResult.OK) {
DialogResult? printOptionsResult = ShowPrintOptionsDialog();
try {
if (printOptionsResult == null || printOptionsResult == DialogResult.OK) {
if (!IsColorPrint()) {
printDocument.DefaultPageSettings.Color = false;
_printDocument.DefaultPageSettings.Color = false;
}
printDocument.Print();
returnPrinterSettings = printDialog.PrinterSettings;
_printDocument.Print();
returnPrinterSettings = _printDialog.PrinterSettings;
}
} catch (Exception e) {
LOG.Error("An error ocurred while trying to print", e);
Log.Error("An error ocurred while trying to print", e);
MessageBox.Show(Language.GetString(LangKey.print_error), Language.GetString(LangKey.error));
}
@ -138,7 +134,7 @@ namespace Greenshot.Helpers {
}
private bool IsColorPrint() {
return !conf.OutputPrintGrayscale && !conf.OutputPrintMonochrome;
return !CoreConfig.OutputPrintGrayscale && !CoreConfig.OutputPrintMonochrome;
}
/// <summary>
@ -147,7 +143,7 @@ namespace Greenshot.Helpers {
/// <returns>result of the print dialog, or null if the dialog has not been displayed by config</returns>
private DialogResult? ShowPrintOptionsDialog() {
DialogResult? ret = null;
if (conf.OutputPrintPromptOptions) {
if (CoreConfig.OutputPrintPromptOptions) {
using (PrintOptionsDialog printOptionsDialog = new PrintOptionsDialog()) {
ret = printOptionsDialog.ShowDialog();
}
@ -164,16 +160,16 @@ namespace Greenshot.Helpers {
ApplyEffects(printOutputSettings);
Image image;
bool disposeImage = ImageOutput.CreateImageFromSurface(surface, printOutputSettings, out image);
bool disposeImage = ImageOutput.CreateImageFromSurface(_surface, printOutputSettings, out image);
try {
ContentAlignment alignment = conf.OutputPrintCenter ? ContentAlignment.MiddleCenter : ContentAlignment.TopLeft;
ContentAlignment alignment = CoreConfig.OutputPrintCenter ? ContentAlignment.MiddleCenter : ContentAlignment.TopLeft;
// prepare timestamp
float footerStringWidth = 0;
float footerStringHeight = 0;
string footerString = null; //DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString();
if (conf.OutputPrintFooter) {
footerString = FilenameHelper.FillPattern(conf.OutputPrintFooterPattern, captureDetails, false);
if (CoreConfig.OutputPrintFooter) {
footerString = FilenameHelper.FillPattern(CoreConfig.OutputPrintFooterPattern, _captureDetails, false);
using (Font f = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular)) {
footerStringWidth = e.Graphics.MeasureString(footerString, f).Width;
footerStringHeight = e.Graphics.MeasureString(footerString, f).Height;
@ -194,7 +190,7 @@ namespace Greenshot.Helpers {
GraphicsUnit gu = GraphicsUnit.Pixel;
RectangleF imageRect = image.GetBounds(ref gu);
// rotate the image if it fits the page better
if (conf.OutputPrintAllowRotate) {
if (CoreConfig.OutputPrintAllowRotate) {
if ((pageRect.Width > pageRect.Height && imageRect.Width < imageRect.Height) || (pageRect.Width < pageRect.Height && imageRect.Width > imageRect.Height)) {
image.RotateFlip(RotateFlipType.Rotate270FlipNone);
imageRect = image.GetBounds(ref gu);
@ -206,16 +202,16 @@ namespace Greenshot.Helpers {
RectangleF printRect = new RectangleF(0, 0, imageRect.Width, imageRect.Height);
// scale the image to fit the page better
if (conf.OutputPrintAllowEnlarge || conf.OutputPrintAllowShrink) {
if (CoreConfig.OutputPrintAllowEnlarge || CoreConfig.OutputPrintAllowShrink) {
SizeF resizedRect = ScaleHelper.GetScaledSize(imageRect.Size, pageRect.Size, false);
if ((conf.OutputPrintAllowShrink && resizedRect.Width < printRect.Width) || conf.OutputPrintAllowEnlarge && resizedRect.Width > printRect.Width) {
if ((CoreConfig.OutputPrintAllowShrink && resizedRect.Width < printRect.Width) || CoreConfig.OutputPrintAllowEnlarge && resizedRect.Width > printRect.Width) {
printRect.Size = resizedRect;
}
}
// align the image
printRect = ScaleHelper.GetAlignedRectangle(printRect, new RectangleF(0, 0, pageRect.Width, pageRect.Height), alignment);
if (conf.OutputPrintFooter) {
if (CoreConfig.OutputPrintFooter) {
//printRect = new RectangleF(0, 0, printRect.Width, printRect.Height - (dateStringHeight * 2));
using (Font f = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular)) {
e.Graphics.DrawString(footerString, f, Brushes.Black, pageRect.Width / 2 - footerStringWidth / 2, pageRect.Height);
@ -224,9 +220,8 @@ namespace Greenshot.Helpers {
e.Graphics.DrawImage(image, printRect, imageRect, GraphicsUnit.Pixel);
} finally {
if (disposeImage && image != null) {
image.Dispose();
image = null;
if (disposeImage) {
image?.Dispose();
}
}
}
@ -234,14 +229,14 @@ namespace Greenshot.Helpers {
private void ApplyEffects(SurfaceOutputSettings printOutputSettings) {
// TODO:
// add effects here
if (conf.OutputPrintMonochrome) {
byte threshold = conf.OutputPrintMonochromeThreshold;
if (CoreConfig.OutputPrintMonochrome) {
byte threshold = CoreConfig.OutputPrintMonochromeThreshold;
printOutputSettings.Effects.Add(new MonochromeEffect(threshold));
printOutputSettings.ReduceColors = true;
}
// the invert effect should probably be the last
if (conf.OutputPrintInverted) {
if (CoreConfig.OutputPrintInverted) {
printOutputSettings.Effects.Add(new InvertEffect());
}
}

View file

@ -36,10 +36,10 @@ namespace Greenshot.Helpers {
/// See: http://www.codeproject.com/KB/audio-video/soundplayerbug.aspx?msg=2487569
/// </summary>
public static class SoundHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(SoundHelper));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly ILog Log = LogManager.GetLogger(typeof(SoundHelper));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private static GCHandle? _gcHandle;
private static byte[] _soundBuffer;
private static byte[] _soundBuffer;
public static void Initialize() {
if (_gcHandle == null) {
@ -47,49 +47,49 @@ namespace Greenshot.Helpers {
ResourceManager resources = new ResourceManager("Greenshot.Sounds", Assembly.GetExecutingAssembly());
_soundBuffer = (byte[])resources.GetObject("camera");
if (conf.NotificationSound != null && conf.NotificationSound.EndsWith(".wav")) {
if (CoreConfig.NotificationSound != null && CoreConfig.NotificationSound.EndsWith(".wav")) {
try {
if (File.Exists(conf.NotificationSound)) {
_soundBuffer = File.ReadAllBytes(conf.NotificationSound);
if (File.Exists(CoreConfig.NotificationSound)) {
_soundBuffer = File.ReadAllBytes(CoreConfig.NotificationSound);
}
} catch (Exception ex) {
LOG.WarnFormat("couldn't load {0}: {1}", conf.NotificationSound, ex.Message);
Log.WarnFormat("couldn't load {0}: {1}", CoreConfig.NotificationSound, ex.Message);
}
}
// Pin sound so it can't be moved by the Garbage Collector, this was the cause for the bad sound
_gcHandle = GCHandle.Alloc(_soundBuffer, GCHandleType.Pinned);
} catch (Exception e) {
LOG.Error("Error initializing.", e);
Log.Error("Error initializing.", e);
}
}
}
public static void Play() {
if (_soundBuffer != null) {
//Thread playSoundThread = new Thread(delegate() {
SoundFlags flags = SoundFlags.SND_ASYNC | SoundFlags.SND_MEMORY | SoundFlags.SND_NOWAIT | SoundFlags.SND_NOSTOP;
try {
WinMM.PlaySound(_gcHandle.Value.AddrOfPinnedObject(), (UIntPtr)0, (uint)flags);
} catch (Exception e) {
LOG.Error("Error in play.", e);
}
//});
//playSoundThread.Name = "Play camera sound";
//playSoundThread.IsBackground = true;
//playSoundThread.Start();
}
}
if (_soundBuffer != null) {
//Thread playSoundThread = new Thread(delegate() {
SoundFlags flags = SoundFlags.SND_ASYNC | SoundFlags.SND_MEMORY | SoundFlags.SND_NOWAIT | SoundFlags.SND_NOSTOP;
try {
if (_gcHandle != null) WinMM.PlaySound(_gcHandle.Value.AddrOfPinnedObject(), (UIntPtr)0, (uint)flags);
} catch (Exception e) {
Log.Error("Error in play.", e);
}
//});
//playSoundThread.Name = "Play camera sound";
//playSoundThread.IsBackground = true;
//playSoundThread.Start();
}
}
public static void Deinitialize() {
try {
public static void Deinitialize() {
try {
if (_gcHandle != null) {
WinMM.PlaySound((byte[])null, (UIntPtr)0, (uint)0);
WinMM.PlaySound(null, (UIntPtr)0, 0);
_gcHandle.Value.Free();
_gcHandle = null;
}
} catch (Exception e) {
LOG.Error("Error in deinitialize.", e);
}
}
} catch (Exception e) {
Log.Error("Error in deinitialize.", e);
}
}
}
}

View file

@ -29,12 +29,12 @@ namespace Greenshot.Helpers {
/// A helper class for the startup registry
/// </summary>
public static class StartupHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(StartupHelper));
private static readonly ILog Log = LogManager.GetLogger(typeof(StartupHelper));
private const string RUNKEY6432 = @"Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run";
private const string RUNKEY = @"Software\Microsoft\Windows\CurrentVersion\Run";
private const string RunKey6432 = @"Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run";
private const string RunKey = @"Software\Microsoft\Windows\CurrentVersion\Run";
private const string APPLICATIONNAME = "Greenshot";
private const string ApplicationName = "Greenshot";
private static string GetExecutablePath() {
return "\"" + Application.ExecutablePath + "\"";
@ -46,7 +46,8 @@ namespace Greenshot.Helpers {
/// <returns>true if Greenshot can write key</returns>
public static bool CanWriteRunAll() {
try {
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(RUNKEY, true)) {
using (Registry.LocalMachine.OpenSubKey(RunKey, true))
{
}
} catch {
return false;
@ -60,7 +61,8 @@ namespace Greenshot.Helpers {
/// <returns>true if Greenshot can write key</returns>
public static bool CanWriteRunUser() {
try {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY, true)) {
using (Registry.CurrentUser.OpenSubKey(RunKey, true))
{
}
} catch {
return false;
@ -72,24 +74,27 @@ namespace Greenshot.Helpers {
/// Return the RUN key value of the local machine
/// </summary>
/// <returns>the RUN key value of the local machine</returns>
public static Object GetRunAllValue() {
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(RUNKEY, false)) {
if (key != null) {
object runValue = key.GetValue(APPLICATIONNAME);
if (runValue != null) {
return runValue;
}
public static object GetRunAllValue()
{
using (var key = Registry.LocalMachine.OpenSubKey(RunKey, false))
{
object runValue = key?.GetValue(ApplicationName);
if (runValue != null)
{
return runValue;
}
}
// for 64-bit systems we need to check the 32-bit keys too
if (IntPtr.Size == 8) {
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(RUNKEY6432, false)) {
if (key != null) {
object runValue = key.GetValue(APPLICATIONNAME);
if (runValue != null) {
return runValue;
}
}
if (IntPtr.Size != 8)
{
return null;
}
using (var key = Registry.LocalMachine.OpenSubKey(RunKey6432, false))
{
object runValue = key?.GetValue(ApplicationName);
if (runValue != null)
{
return runValue;
}
}
return null;
@ -99,24 +104,22 @@ namespace Greenshot.Helpers {
/// Return the RUN key value of the current user
/// </summary>
/// <returns>the RUN key value of the current user</returns>
public static Object GetRunUserValue() {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY, false)) {
if (key != null) {
object runValue = key.GetValue(APPLICATIONNAME);
if (runValue != null) {
return runValue;
}
public static object GetRunUserValue() {
using (var key = Registry.CurrentUser.OpenSubKey(RunKey, false)) {
object runValue = key?.GetValue(ApplicationName);
if (runValue != null) {
return runValue;
}
}
// for 64-bit systems we need to check the 32-bit keys too
if (IntPtr.Size == 8) {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY6432, false)) {
if (key != null) {
object runValue = key.GetValue(APPLICATIONNAME);
if (runValue != null) {
return runValue;
}
}
if (IntPtr.Size != 8)
{
return null;
}
using (var key = Registry.CurrentUser.OpenSubKey(RunKey6432, false)) {
object runValue = key?.GetValue(ApplicationName);
if (runValue != null) {
return runValue;
}
}
return null;
@ -130,7 +133,7 @@ namespace Greenshot.Helpers {
try {
return GetRunAllValue() != null;
} catch (Exception e) {
LOG.Error("Error retrieving RunAllValue", e);
Log.Error("Error retrieving RunAllValue", e);
}
return false;
}
@ -140,11 +143,11 @@ namespace Greenshot.Helpers {
/// </summary>
/// <returns>true if there is a run key</returns>
public static bool HasRunUser() {
Object runValue = null;
object runValue = null;
try {
runValue = GetRunUserValue();
} catch (Exception e) {
LOG.Error("Error retrieving RunUserValue", e);
Log.Error("Error retrieving RunUserValue", e);
}
return runValue != null;
}
@ -153,24 +156,29 @@ namespace Greenshot.Helpers {
/// Delete the RUN key for the localmachine ("ALL")
/// </summary>
public static void DeleteRunAll() {
if (HasRunAll()) {
try {
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(RUNKEY, true)) {
key.DeleteValue(APPLICATIONNAME);
}
} catch (Exception e) {
LOG.Error("Error in deleteRunAll.", e);
if (!HasRunAll())
{
return;
}
try {
using (var key = Registry.LocalMachine.OpenSubKey(RunKey, true)) {
key?.DeleteValue(ApplicationName);
}
try {
// for 64-bit systems we need to delete the 32-bit keys too
if (IntPtr.Size == 8) {
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(RUNKEY6432, false)) {
key.DeleteValue(APPLICATIONNAME);
}
}
} catch (Exception e) {
LOG.Error("Error in deleteRunAll.", e);
} catch (Exception e) {
Log.Error("Error in deleteRunAll.", e);
}
try
{
// for 64-bit systems we need to delete the 32-bit keys too
if (IntPtr.Size != 8)
{
return;
}
using (var key = Registry.LocalMachine.OpenSubKey(RunKey6432, false)) {
key?.DeleteValue(ApplicationName);
}
} catch (Exception e) {
Log.Error("Error in deleteRunAll.", e);
}
}
@ -178,24 +186,29 @@ namespace Greenshot.Helpers {
/// Delete the RUN key for the current user
/// </summary>
public static void DeleteRunUser() {
if (HasRunUser()) {
try {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY, true)) {
key.DeleteValue(APPLICATIONNAME);
}
} catch (Exception e) {
LOG.Error("Error in deleteRunUser.", e);
if (!HasRunUser())
{
return;
}
try {
using (var key = Registry.CurrentUser.OpenSubKey(RunKey, true)) {
key?.DeleteValue(ApplicationName);
}
try {
// for 64-bit systems we need to delete the 32-bit keys too
if (IntPtr.Size == 8) {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY6432, false)) {
key.DeleteValue(APPLICATIONNAME);
}
}
} catch (Exception e) {
LOG.Error("Error in deleteRunUser.", e);
} catch (Exception e) {
Log.Error("Error in deleteRunUser.", e);
}
try
{
// for 64-bit systems we need to delete the 32-bit keys too
if (IntPtr.Size != 8)
{
return;
}
using (var key = Registry.CurrentUser.OpenSubKey(RunKey6432, false)) {
key?.DeleteValue(ApplicationName);
}
} catch (Exception e) {
Log.Error("Error in deleteRunUser.", e);
}
}
@ -204,11 +217,12 @@ namespace Greenshot.Helpers {
/// </summary>
public static void SetRunUser() {
try {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY, true)) {
key.SetValue(APPLICATIONNAME, GetExecutablePath());
using (var key = Registry.CurrentUser.OpenSubKey(RunKey, true))
{
key?.SetValue(ApplicationName, GetExecutablePath());
}
} catch (Exception e) {
LOG.Error("Error in setRunUser.", e);
Log.Error("Error in setRunUser.", e);
}
}
@ -221,19 +235,22 @@ namespace Greenshot.Helpers {
string lnkName = Path.GetFileNameWithoutExtension(Application.ExecutablePath) + ".lnk";
string startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
if (Directory.Exists(startupPath)) {
LOG.DebugFormat("Startup path: {0}", startupPath);
Log.DebugFormat("Startup path: {0}", startupPath);
if (File.Exists(Path.Combine(startupPath, lnkName))) {
return true;
}
}
string startupAll = Environment.GetEnvironmentVariable("ALLUSERSPROFILE") + @"\Microsoft\Windows\Start Menu\Programs\Startup";
if (Directory.Exists(startupAll)) {
LOG.DebugFormat("Startup all path: {0}", startupAll);
Log.DebugFormat("Startup all path: {0}", startupAll);
if (File.Exists(Path.Combine(startupAll, lnkName))) {
return true;
}
}
} catch {
}
catch
{
// ignored
}
return false;
}

View file

@ -34,35 +34,37 @@ namespace Greenshot.Experimental {
/// Description of RssFeedHelper.
/// </summary>
public static class UpdateHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(UpdateHelper));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private const string STABLE_DOWNLOAD_LINK = "http://getgreenshot.org/downloads/";
private const string VERSION_HISTORY_LINK = "http://getgreenshot.org/version-history/";
private static readonly ILog Log = LogManager.GetLogger(typeof(UpdateHelper));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private const string StableDownloadLink = "http://getgreenshot.org/downloads/";
private const string VersionHistoryLink = "http://getgreenshot.org/version-history/";
private static readonly object LockObject = new object();
private static RssFile _latestGreenshot;
private static string _downloadLink = STABLE_DOWNLOAD_LINK;
private static string _downloadLink = StableDownloadLink;
/// <summary>
/// Is an update check needed?
/// </summary>
/// <returns>bool true if yes</returns>
public static bool IsUpdateCheckNeeded() {
lock (LockObject) {
if (conf.UpdateCheckInterval == 0) {
lock (LockObject)
{
if (CoreConfig.UpdateCheckInterval == 0)
{
return false;
}
if (conf.LastUpdateCheck != null) {
DateTime checkTime = conf.LastUpdateCheck;
checkTime = checkTime.AddDays(conf.UpdateCheckInterval);
if (DateTime.Now.CompareTo(checkTime) < 0) {
LOG.DebugFormat("No need to check RSS feed for updates, feed check will be after {0}", checkTime);
return false;
}
LOG.DebugFormat("Update check is due, last check was {0} check needs to be made after {1} (which is one {2} later)", conf.LastUpdateCheck, checkTime, conf.UpdateCheckInterval);
if (!RssHelper.IsRSSModifiedAfter(conf.LastUpdateCheck)) {
LOG.DebugFormat("RSS feed has not been updated since after {0}", conf.LastUpdateCheck);
return false;
}
DateTime checkTime = CoreConfig.LastUpdateCheck;
checkTime = checkTime.AddDays(CoreConfig.UpdateCheckInterval);
if (DateTime.Now.CompareTo(checkTime) < 0)
{
Log.DebugFormat("No need to check RSS feed for updates, feed check will be after {0}", checkTime);
return false;
}
Log.DebugFormat("Update check is due, last check was {0} check needs to be made after {1} (which is one {2} later)", CoreConfig.LastUpdateCheck, checkTime, CoreConfig.UpdateCheckInterval);
if (!RssHelper.IsRssModifiedAfter(CoreConfig.LastUpdateCheck))
{
Log.DebugFormat("RSS feed has not been updated since after {0}", CoreConfig.LastUpdateCheck);
return false;
}
}
return true;
@ -79,15 +81,15 @@ namespace Greenshot.Experimental {
try {
_latestGreenshot = null;
ProcessRSSInfo(currentVersion);
ProcessRssInfo(currentVersion);
if (_latestGreenshot != null) {
MainForm.Instance.NotifyIcon.BalloonTipClicked += HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, "'" + _latestGreenshot.File + "'"), ToolTipIcon.Info);
}
conf.LastUpdateCheck = DateTime.Now;
CoreConfig.LastUpdateCheck = DateTime.Now;
} catch (Exception e) {
LOG.Error("An error occured while checking for updates, the error will be ignored: ", e);
Log.Error("An error occured while checking for updates, the error will be ignored: ", e);
}
}
}
@ -112,9 +114,9 @@ namespace Greenshot.Experimental {
}
}
private static void ProcessRSSInfo(Version currentVersion) {
private static void ProcessRssInfo(Version currentVersion) {
// Reset latest Greenshot
IList<RssFile> rssFiles = RssHelper.readRSS();
IList<RssFile> rssFiles = RssHelper.ReadRss();
if (rssFiles == null) {
return;
@ -124,29 +126,29 @@ namespace Greenshot.Experimental {
foreach(RssFile rssFile in rssFiles) {
if (rssFile.File.StartsWith("Greenshot")) {
// check for exe
if (!rssFile.isExe) {
if (!rssFile.IsExe) {
continue;
}
// do we have a version?
if (rssFile.Version == null) {
LOG.DebugFormat("Skipping unversioned exe {0} which is published at {1} : {2}", rssFile.File, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
Log.DebugFormat("Skipping unversioned exe {0} which is published at {1} : {2}", rssFile.File, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
continue;
}
// if the file is unstable, we will skip it when:
// the current version is a release or release candidate AND check unstable is turned off.
if (rssFile.isUnstable) {
if (rssFile.IsUnstable) {
// Skip if we shouldn't check unstables
if ((conf.BuildState == BuildStates.RELEASE) && !conf.CheckForUnstable) {
if ((CoreConfig.BuildState == BuildStates.RELEASE) && !CoreConfig.CheckForUnstable) {
continue;
}
}
// if the file is a release candidate, we will skip it when:
// the current version is a release AND check unstable is turned off.
if (rssFile.isReleaseCandidate) {
if (conf.BuildState == BuildStates.RELEASE && !conf.CheckForUnstable) {
if (rssFile.IsReleaseCandidate) {
if (CoreConfig.BuildState == BuildStates.RELEASE && !CoreConfig.CheckForUnstable) {
continue;
}
}
@ -154,19 +156,19 @@ namespace Greenshot.Experimental {
// Compare versions
int versionCompare = rssFile.Version.CompareTo(currentVersion);
if (versionCompare > 0) {
LOG.DebugFormat("Found newer Greenshot '{0}' with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
Log.DebugFormat("Found newer Greenshot '{0}' with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
if (_latestGreenshot == null || rssFile.Version.CompareTo(_latestGreenshot.Version) > 0) {
_latestGreenshot = rssFile;
if (rssFile.isReleaseCandidate || rssFile.isUnstable) {
_downloadLink = VERSION_HISTORY_LINK;
if (rssFile.IsReleaseCandidate || rssFile.IsUnstable) {
_downloadLink = VersionHistoryLink;
} else {
_downloadLink = STABLE_DOWNLOAD_LINK;
_downloadLink = StableDownloadLink;
}
}
} else if (versionCompare < 0) {
LOG.DebugFormat("Skipping older greenshot with version {0}", rssFile.Version);
Log.DebugFormat("Skipping older greenshot with version {0}", rssFile.Version);
} else if (versionCompare == 0) {
LOG.DebugFormat("Found current version as exe {0} with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
Log.DebugFormat("Found current version as exe {0} with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
}
}
}

View file

@ -24,13 +24,9 @@ using System.Windows.Forms;
namespace Greenshot.Helpers {
public class WindowWrapper : IWin32Window {
public WindowWrapper(IntPtr handle) {
_hwnd = handle;
Handle = handle;
}
public IntPtr Handle {
get { return _hwnd; }
}
private readonly IntPtr _hwnd;
public IntPtr Handle { get; }
}
}