Small fixes, working on tests to display the capture performance & memory usage.

This commit is contained in:
Robin 2019-01-14 15:48:03 +01:00
commit 08e68ad61d
20 changed files with 332 additions and 124 deletions

View file

@ -24,59 +24,64 @@
#region Usings #region Usings
using System; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop; using System.Windows.Interop;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Dapplo.Log; using Dapplo.Log;
using Dapplo.Windows.Common;
using Dapplo.Windows.Common.Extensions;
using Dapplo.Windows.Common.Structs; using Dapplo.Windows.Common.Structs;
using Dapplo.Windows.Gdi32; using Dapplo.Windows.Gdi32;
using Dapplo.Windows.Gdi32.Enums; using Dapplo.Windows.Gdi32.Enums;
using Dapplo.Windows.Gdi32.SafeHandles; using Dapplo.Windows.Gdi32.SafeHandles;
using Dapplo.Windows.Gdi32.Structs; using Dapplo.Windows.Gdi32.Structs;
using Dapplo.Windows.Icons; using Greenshot.Addons.Core;
using Dapplo.Windows.User32;
using Dapplo.Windows.User32.Enums;
using Dapplo.Windows.User32.Structs;
using Greenshot.Addons.Config.Impl;
using Greenshot.Addons.Interfaces;
using Greenshot.Gfx;
#endregion #endregion
namespace Greenshot.Addons.Core namespace Greenshot.PerformanceTests.Capture
{ {
/// <summary> /// <summary>
/// The screen Capture code /// The screen Capture code
/// </summary> /// </summary>
public class ScreenCapture : IDisposable public class ScreenCapture : IDisposable
{ {
private static readonly LogSource Log = new LogSource();
private readonly ICoreConfiguration _coreConfiguration;
private readonly NativeRect _captureBounds;
private readonly SafeWindowDcHandle _desktopDcHandle; private readonly SafeWindowDcHandle _desktopDcHandle;
private readonly SafeCompatibleDcHandle _safeCompatibleDcHandle; private readonly SafeCompatibleDcHandle _safeCompatibleDcHandle;
private readonly BitmapInfoHeader _bitmapInfoHeader; private readonly bool _useStretch;
private readonly SafeDibSectionHandle _safeDibSectionHandle; private readonly SafeDibSectionHandle _safeDibSectionHandle;
private readonly SafeSelectObjectHandle _safeSelectObjectHandle; private readonly SafeSelectObjectHandle _safeSelectObjectHandle;
public ScreenCapture(ICoreConfiguration coreConfiguration, NativeRect captureBounds) /// <summary>
/// Return the source rectangle
/// </summary>
public NativeRect SourceRect { get; }
/// <summary>
/// Return the source rectangle
/// </summary>
public NativeSize DestinationSize { get; }
public ScreenCapture(NativeRect sourceCaptureBounds, NativeSize? requestedSize = null)
{ {
_coreConfiguration = coreConfiguration; SourceRect = sourceCaptureBounds;
_captureBounds = captureBounds;
if (requestedSize.HasValue && requestedSize.Value != SourceRect.Size)
{
DestinationSize = requestedSize.Value;
_useStretch = true;
}
else
{
DestinationSize = SourceRect.Size;
_useStretch = false;
}
_desktopDcHandle = SafeWindowDcHandle.FromDesktop(); _desktopDcHandle = SafeWindowDcHandle.FromDesktop();
_safeCompatibleDcHandle = Gdi32Api.CreateCompatibleDC(_desktopDcHandle); _safeCompatibleDcHandle = Gdi32Api.CreateCompatibleDC(_desktopDcHandle);
// Create BitmapInfoHeader for CreateDIBSection // Create BitmapInfoHeader for CreateDIBSection
_bitmapInfoHeader = BitmapInfoHeader.Create(captureBounds.Width, captureBounds.Height, 24); var bitmapInfoHeader = BitmapInfoHeader.Create(DestinationSize.Width, DestinationSize.Height, 32);
_safeDibSectionHandle = Gdi32Api.CreateDIBSection(_desktopDcHandle, ref _bitmapInfoHeader, DibColors.PalColors, out _, IntPtr.Zero, 0); _safeDibSectionHandle = Gdi32Api.CreateDIBSection(_desktopDcHandle, ref bitmapInfoHeader, DibColors.PalColors, out _, IntPtr.Zero, 0);
// select the bitmap object and store the old handle // select the bitmap object and store the old handle
_safeSelectObjectHandle = _safeCompatibleDcHandle.SelectObject(_safeDibSectionHandle); _safeSelectObjectHandle = _safeCompatibleDcHandle.SelectObject(_safeDibSectionHandle);
@ -84,12 +89,40 @@ namespace Greenshot.Addons.Core
public void CaptureFrame() public void CaptureFrame()
{ {
// bit-blt over (make copy) if (_useStretch)
// ReSharper disable once BitwiseOperatorOnEnumWithoutFlags {
Gdi32Api.BitBlt(_safeCompatibleDcHandle, 0, 0, _captureBounds.Width, _captureBounds.Height, _desktopDcHandle, _captureBounds.X, _captureBounds.Y, // capture & blt over (make copy)
Gdi32Api.StretchBlt(
_safeCompatibleDcHandle, 0, 0, DestinationSize.Width, DestinationSize.Height, // Destination
_desktopDcHandle, SourceRect.X, SourceRect.Y, SourceRect.Width, SourceRect.Height, // source
RasterOperations.SourceCopy | RasterOperations.CaptureBlt); RasterOperations.SourceCopy | RasterOperations.CaptureBlt);
}
else
{
// capture & blt over (make copy)
Gdi32Api.BitBlt(
_safeCompatibleDcHandle, 0, 0, DestinationSize.Width, DestinationSize.Height, // Destination
_desktopDcHandle, SourceRect.X, SourceRect.Y, // Source
RasterOperations.SourceCopy | RasterOperations.CaptureBlt);
}
}
//return Imaging.CreateBitmapSourceFromHBitmap(_safeDibSectionHandle.DangerousGetHandle(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); /// <summary>
/// Get the current frame as BitmapSource
/// </summary>
/// <returns>BitmapSource</returns>
public BitmapSource CurrentFrameAsBitmapSource()
{
return Imaging.CreateBitmapSourceFromHBitmap(_safeDibSectionHandle.DangerousGetHandle(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
/// <summary>
/// Get the current frame as Bitmap
/// </summary>
/// <returns>Bitmap</returns>
public Bitmap CurrentFrameAsBitmap()
{
return Image.FromHbitmap(_safeDibSectionHandle.DangerousGetHandle());
} }
public void Dispose() public void Dispose()

View file

@ -1,7 +1,32 @@
using System; #region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using Dapplo.Windows.Common.Structs;
using Dapplo.Windows.User32; using Dapplo.Windows.User32;
using Greenshot.Addons.Core; using Greenshot.Addons.Core;
using Greenshot.PerformanceTests.Capture;
namespace Greenshot.PerformanceTests namespace Greenshot.PerformanceTests
{ {
@ -11,9 +36,15 @@ namespace Greenshot.PerformanceTests
[MinColumn, MaxColumn, MemoryDiagnoser] [MinColumn, MaxColumn, MemoryDiagnoser]
public class CapturePerformance public class CapturePerformance
{ {
private readonly ScreenCapture _screenCapture = new ScreenCapture(null, DisplayInfo.ScreenBounds); // A ScreenCapture which captures the whole screen (multi-monitor)
private readonly ScreenCapture _screenCapture = new ScreenCapture(DisplayInfo.ScreenBounds);
// A ScreenCapture which captures the whole screen (multi-monitor) but with half the destination size, uses stretch-blt
private readonly ScreenCapture _screenCaptureResized = new ScreenCapture(DisplayInfo.ScreenBounds, new NativeSize(DisplayInfo.ScreenBounds.Width / 2, DisplayInfo.ScreenBounds.Height / 2));
//[Benchmark] /// <summary>
/// This benchmarks a screen capture which does a lot of additional work
/// </summary>
[Benchmark]
public void Capture() public void Capture()
{ {
using (var capture = WindowCapture.CaptureScreen()) using (var capture = WindowCapture.CaptureScreen())
@ -28,14 +59,25 @@ namespace Greenshot.PerformanceTests
} }
} }
} }
/// <summary>
/// Capture the screen with buffered settings
/// </summary>
[Benchmark] [Benchmark]
public void CaptureBuffered() public void CaptureBuffered()
{ {
_screenCapture.CaptureFrame(); _screenCapture.CaptureFrame();
} }
/// <summary>
/// Capture the screen with buffered settings, but resized (smaller) destination
/// </summary>
[Benchmark]
public void CaptureBufferedResized()
{
_screenCaptureResized.CaptureFrame();
}
[GlobalCleanup] [GlobalCleanup]
public void Cleanup() public void Cleanup()
{ {

View file

@ -1,4 +1,27 @@
using System; #region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using BenchmarkDotNet.Configs; using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments; using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Jobs;

View file

@ -6,13 +6,14 @@ using Greenshot.Addons.Interfaces;
namespace Greenshot.Components namespace Greenshot.Components
{ {
/// <summary> /// <summary>
/// This is the information which is needed for making captures possible. /// This is the bundled information which is needed for making captures possible.
/// </summary> /// </summary>
public class CaptureSupportInfo public class CaptureSupportInfo
{ {
/// <summary> /// <summary>
/// Constructor for DI /// Constructor for DI
/// </summary> /// </summary>
/// <param name="coreConfiguration">ICoreConfiguration</param>
/// <param name="internetExplorerCaptureHelper">InternetExplorerCaptureHelper</param> /// <param name="internetExplorerCaptureHelper">InternetExplorerCaptureHelper</param>
/// <param name="formEnhancers">IEnumerable with IFormEnhancer</param> /// <param name="formEnhancers">IEnumerable with IFormEnhancer</param>
public CaptureSupportInfo( public CaptureSupportInfo(

View file

@ -26,7 +26,6 @@
#region Usings #region Usings
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security.Principal; using System.Security.Principal;

View file

@ -22,14 +22,12 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.Reactive.Linq; using System.Reactive.Linq;
using Caliburn.Micro; using Caliburn.Micro;
using Dapplo.Addons; using Dapplo.Addons;
using Dapplo.Log; using Dapplo.Log;
using Dapplo.Windows.Input.Keyboard; using Dapplo.Windows.Input.Keyboard;
using Greenshot.Addons.Core; using Greenshot.Addons.Core;
using Greenshot.Addons.Interfaces;
using Greenshot.Helpers; using Greenshot.Helpers;
namespace Greenshot.Components namespace Greenshot.Components

View file

@ -99,7 +99,7 @@ namespace Greenshot.Components
/// <inheritdoc /> /// <inheritdoc />
public void Startup() public void Startup()
{ {
var ignore = BackgroundTask(() => TimeSpan.FromDays(_coreConfiguration.UpdateCheckInterval), UpdateCheck, _cancellationTokenSource.Token); _ = BackgroundTask(() => TimeSpan.FromDays(_coreConfiguration.UpdateCheckInterval), UpdateCheck, _cancellationTokenSource.Token);
} }
/// <inheritdoc /> /// <inheritdoc />

View file

@ -47,8 +47,7 @@ namespace Greenshot.Destinations
public PickerDestination( public PickerDestination(
DestinationHolder destinationHolder, DestinationHolder destinationHolder,
ICoreConfiguration coreConfiguration, ICoreConfiguration coreConfiguration,
IGreenshotLanguage greenshotLanguage, IGreenshotLanguage greenshotLanguage
ExportNotification exportNotification
) : base(coreConfiguration, greenshotLanguage) ) : base(coreConfiguration, greenshotLanguage)
{ {
_destinationHolder = destinationHolder; _destinationHolder = destinationHolder;

View file

@ -95,6 +95,7 @@ namespace Greenshot.Forms
/// <param name="coreConfiguration">ICoreConfiguration</param> /// <param name="coreConfiguration">ICoreConfiguration</param>
/// <param name="capture">ICapture</param> /// <param name="capture">ICapture</param>
/// <param name="windows">IList of IInteropWindow</param> /// <param name="windows">IList of IInteropWindow</param>
/// <param name="formEnhancers">IEnumerable with IFormEnhancer</param>
public CaptureForm(ICoreConfiguration coreConfiguration, ICapture capture, IList<IInteropWindow> windows, IEnumerable<IFormEnhancer> formEnhancers) : base(coreConfiguration, null) public CaptureForm(ICoreConfiguration coreConfiguration, ICapture capture, IList<IInteropWindow> windows, IEnumerable<IFormEnhancer> formEnhancers) : base(coreConfiguration, null)
{ {
_isZoomerTransparent = _coreConfiguration.ZoomerOpacity < 1; _isZoomerTransparent = _coreConfiguration.ZoomerOpacity < 1;

View file

@ -62,7 +62,6 @@ using Screen = System.Windows.Forms.Screen;
using Dapplo.Config.Ini; using Dapplo.Config.Ini;
using Dapplo.Windows.User32; using Dapplo.Windows.User32;
using Greenshot.Addons.Resources; using Greenshot.Addons.Resources;
using Greenshot.Addons.Interfaces;
using Greenshot.Components; using Greenshot.Components;
#endregion #endregion
@ -97,7 +96,6 @@ namespace Greenshot.Forms
IWindowManager windowManager, IWindowManager windowManager,
IGreenshotLanguage greenshotLanguage, IGreenshotLanguage greenshotLanguage,
InternetExplorerCaptureHelper internetExplorerCaptureHelper, InternetExplorerCaptureHelper internetExplorerCaptureHelper,
GreenshotResources greenshotResources,
Func<Owned<ConfigViewModel>> configViewModelFactory, Func<Owned<ConfigViewModel>> configViewModelFactory,
Func<Owned<AboutForm>> aboutFormFactory, Func<Owned<AboutForm>> aboutFormFactory,
DestinationHolder destinationHolder, DestinationHolder destinationHolder,

View file

@ -30,7 +30,6 @@ using System.Drawing.Imaging;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Gfx; using Greenshot.Gfx;
using Greenshot.Addons.Core; using Greenshot.Addons.Core;
using Greenshot.Addons.Config.Impl;
#endregion #endregion

View file

@ -41,7 +41,6 @@ using Dapplo.Windows.Common.Structs;
using Dapplo.Windows.DesktopWindowsManager; using Dapplo.Windows.DesktopWindowsManager;
using Dapplo.Windows.Kernel32; using Dapplo.Windows.Kernel32;
using Dapplo.Windows.User32; using Dapplo.Windows.User32;
using Greenshot.Addon.InternetExplorer;
using Greenshot.Addons.Components; using Greenshot.Addons.Components;
using Greenshot.Addons.Core; using Greenshot.Addons.Core;
using Greenshot.Addons.Extensions; using Greenshot.Addons.Extensions;
@ -49,7 +48,6 @@ using Greenshot.Addons.Interfaces;
using Greenshot.Components; using Greenshot.Components;
using Greenshot.Core.Enums; using Greenshot.Core.Enums;
using Greenshot.Gfx; using Greenshot.Gfx;
using Greenshot.Addons.Config.Impl;
#endregion #endregion

View file

@ -58,7 +58,7 @@ namespace Greenshot.Helpers.Mapi
} }
// allocate enough memory to hold all recipients // allocate enough memory to hold all recipients
var size = Marshal.SizeOf(typeof(MapiMailMessage.MapiHelperInterop.MapiRecipDesc)); var size = Marshal.SizeOf(typeof(MapiRecipDesc));
Handle = Marshal.AllocHGlobal(_count * size); Handle = Marshal.AllocHGlobal(_count * size);
// place all interop recipients into the memory just allocated // place all interop recipients into the memory just allocated
@ -90,7 +90,7 @@ namespace Greenshot.Helpers.Mapi
{ {
if (Handle != IntPtr.Zero) if (Handle != IntPtr.Zero)
{ {
var type = typeof(MapiMailMessage.MapiHelperInterop.MapiRecipDesc); var type = typeof(MapiRecipDesc);
var size = Marshal.SizeOf(type); var size = Marshal.SizeOf(type);
// destroy all the structures in the memory area // destroy all the structures in the memory area

View file

@ -0,0 +1,43 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
#region Usings
using System;
using System.Runtime.InteropServices;
#endregion
namespace Greenshot.Helpers.Mapi
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class MapiFileDescriptor
{
public int flags = 0;
public string name;
public string path;
public int position;
public int reserved = 0;
public IntPtr type = IntPtr.Zero;
}
}

View file

@ -0,0 +1,54 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
#region Usings
using System;
using System.Runtime.InteropServices;
#endregion
namespace Greenshot.Helpers.Mapi
{
/// <summary>
/// Internal class for calling MAPI APIs
/// </summary>
internal class MapiHelperInterop
{
#region Constructors
/// <summary>
/// Private constructor.
/// </summary>
private MapiHelperInterop()
{
// Intenationally blank
}
#endregion Constructors
[DllImport("MAPI32.DLL", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern int MAPISendMail(IntPtr session, IntPtr hwnd, MapiMessage message, int flg, int rsv);
}
}

View file

@ -114,78 +114,6 @@ namespace Greenshot.Helpers.Mapi
} }
} }
#region Private MapiFileDescriptor Class
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
private class MapiFileDescriptor
{
public int flags = 0;
public string name;
public string path;
public int position;
public int reserved = 0;
public IntPtr type = IntPtr.Zero;
}
#endregion Private MapiFileDescriptor Class
#region Private MAPIHelperInterop Class
/// <summary>
/// Internal class for calling MAPI APIs
/// </summary>
internal class MapiHelperInterop
{
#region Constructors
/// <summary>
/// Private constructor.
/// </summary>
private MapiHelperInterop()
{
// Intenationally blank
}
#endregion Constructors
#region Structs
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiMessage
{
public string ConversationID = null;
public string DateReceived = null;
public int FileCount;
public IntPtr Files = IntPtr.Zero;
public int Flags = 0;
public string MessageType = null;
public string NoteText;
public IntPtr Originator = IntPtr.Zero;
public int RecipientCount;
public IntPtr Recipients = IntPtr.Zero;
public int Reserved = 0;
public string Subject;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiRecipDesc
{
public string Address;
public int eIDSize = 0;
public IntPtr EntryID = IntPtr.Zero;
public string Name;
public int RecipientClass;
public int Reserved = 0;
}
[DllImport("MAPI32.DLL", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern int MAPISendMail(IntPtr session, IntPtr hwnd, MapiMessage message, int flg, int rsv);
#endregion Structs
}
#endregion Private MAPIHelperInterop Class
#region Constructors #region Constructors
/// <summary> /// <summary>
@ -286,7 +214,7 @@ namespace Greenshot.Helpers.Mapi
/// </summary> /// </summary>
private void _ShowMail() private void _ShowMail()
{ {
var message = new MapiHelperInterop.MapiMessage(); var message = new MapiMessage();
using (var interopRecipients = Recipients.GetInteropRepresentation()) using (var interopRecipients = Recipients.GetInteropRepresentation())
{ {
@ -339,7 +267,7 @@ namespace Greenshot.Helpers.Mapi
/// Deallocates the files in a message. /// Deallocates the files in a message.
/// </summary> /// </summary>
/// <param name="message">The message to deallocate the files from.</param> /// <param name="message">The message to deallocate the files from.</param>
private void _DeallocFiles(MapiHelperInterop.MapiMessage message) private void _DeallocFiles(MapiMessage message)
{ {
if (message.Files != IntPtr.Zero) if (message.Files != IntPtr.Zero)
{ {

View file

@ -0,0 +1,49 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
#region Usings
using System;
using System.Runtime.InteropServices;
#endregion
namespace Greenshot.Helpers.Mapi
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class MapiMessage
{
public string ConversationID = null;
public string DateReceived = null;
public int FileCount;
public IntPtr Files = IntPtr.Zero;
public int Flags = 0;
public string MessageType = null;
public string NoteText;
public IntPtr Originator = IntPtr.Zero;
public int RecipientCount;
public IntPtr Recipients = IntPtr.Zero;
public int Reserved = 0;
public string Subject;
}
}

View file

@ -0,0 +1,43 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
#region Usings
using System;
using System.Runtime.InteropServices;
#endregion
namespace Greenshot.Helpers.Mapi
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class MapiRecipDesc
{
public string Address;
public int eIDSize = 0;
public IntPtr EntryID = IntPtr.Zero;
public string Name;
public int RecipientClass;
public int Reserved = 0;
}
}

View file

@ -41,9 +41,9 @@ namespace Greenshot.Helpers.Mapi
/// Returns an interop representation of a recepient. /// Returns an interop representation of a recepient.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
internal MapiMailMessage.MapiHelperInterop.MapiRecipDesc GetInteropRepresentation() internal MapiRecipDesc GetInteropRepresentation()
{ {
var interop = new MapiMailMessage.MapiHelperInterop.MapiRecipDesc(); var interop = new MapiRecipDesc();
if (DisplayName == null) if (DisplayName == null)
{ {

View file

@ -32,7 +32,7 @@ namespace Greenshot.Helpers.Mapi
/// <summary> /// <summary>
/// Represents a colleciton of recipients for a mail message. /// Represents a colleciton of recipients for a mail message.
/// </summary> /// </summary>
public partial class RecipientCollection : CollectionBase public class RecipientCollection : CollectionBase
{ {
/// <summary> /// <summary>
/// Returns the recipient stored in this collection at the specified index. /// Returns the recipient stored in this collection at the specified index.