mirror of
https://github.com/greenshot/greenshot
synced 2025-07-30 11:40:40 -07:00
Fixed MAPI Recipient properties
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2488 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
442a978d13
commit
2b4df68c1f
2 changed files with 160 additions and 180 deletions
|
@ -46,7 +46,7 @@ namespace Greenshot.Helpers {
|
|||
public class MapiMailMessage {
|
||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(MapiMailMessage));
|
||||
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper Method for creating an Email with Attachment
|
||||
/// </summary>
|
||||
|
@ -61,12 +61,12 @@ namespace Greenshot.Helpers {
|
|||
if (!string.IsNullOrEmpty(conf.MailApiCC)) {
|
||||
message._recipientCollection.Add(new Recipient(conf.MailApiCC, RecipientType.CC));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(conf.MailApiTo)) {
|
||||
if (!string.IsNullOrEmpty(conf.MailApiBCC)) {
|
||||
message._recipientCollection.Add(new Recipient(conf.MailApiBCC, RecipientType.BCC));
|
||||
}
|
||||
message.ShowDialog();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper Method for creating an Email with Image Attachment
|
||||
|
@ -92,7 +92,7 @@ namespace Greenshot.Helpers {
|
|||
}
|
||||
}
|
||||
#region Private MapiFileDescriptor Class
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
private class MapiFileDescriptor {
|
||||
public int reserved = 0;
|
||||
|
@ -102,11 +102,11 @@ namespace Greenshot.Helpers {
|
|||
public string name = null;
|
||||
public IntPtr type = IntPtr.Zero;
|
||||
}
|
||||
|
||||
|
||||
#endregion Private MapiFileDescriptor Class
|
||||
|
||||
|
||||
#region Enums
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the valid RecipientTypes for a Recipient.
|
||||
/// </summary>
|
||||
|
@ -115,32 +115,32 @@ namespace Greenshot.Helpers {
|
|||
/// Recipient will be in the TO list.
|
||||
/// </summary>
|
||||
To = 1,
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Recipient will be in the CC list.
|
||||
/// </summary>
|
||||
CC = 2,
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Recipient will be in the BCC list.
|
||||
/// </summary>
|
||||
BCC = 3
|
||||
};
|
||||
|
||||
|
||||
#endregion Enums
|
||||
|
||||
|
||||
#region Member Variables
|
||||
|
||||
|
||||
private string _subject;
|
||||
private string _body;
|
||||
private RecipientCollection _recipientCollection;
|
||||
private List<string> _files;
|
||||
private ManualResetEvent _manualResetEvent;
|
||||
|
||||
|
||||
#endregion Member Variables
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a blank mail message.
|
||||
/// </summary>
|
||||
|
@ -149,14 +149,14 @@ namespace Greenshot.Helpers {
|
|||
_recipientCollection = new RecipientCollection();
|
||||
_manualResetEvent = new ManualResetEvent(false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new mail message with the specified subject.
|
||||
/// </summary>
|
||||
public MapiMailMessage(string subject) : this() {
|
||||
_subject = subject;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new mail message with the specified subject and body.
|
||||
/// </summary>
|
||||
|
@ -164,45 +164,57 @@ namespace Greenshot.Helpers {
|
|||
_subject = subject;
|
||||
_body = body;
|
||||
}
|
||||
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
|
||||
#region Public Properties
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the subject of this mail message.
|
||||
/// </summary>
|
||||
public string Subject {
|
||||
get { return _subject; }
|
||||
set { _subject = value; }
|
||||
get {
|
||||
return _subject;
|
||||
}
|
||||
set {
|
||||
_subject = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body of this mail message.
|
||||
/// </summary>
|
||||
public string Body {
|
||||
get { return _body; }
|
||||
set { _body = value; }
|
||||
get {
|
||||
return _body;
|
||||
}
|
||||
set {
|
||||
_body = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the recipient list for this mail message.
|
||||
/// </summary>
|
||||
public RecipientCollection Recipients {
|
||||
get { return _recipientCollection; }
|
||||
get {
|
||||
return _recipientCollection;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file list for this mail message.
|
||||
/// </summary>
|
||||
public List<string> Files {
|
||||
get { return _files; }
|
||||
get {
|
||||
return _files;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Displays the mail message dialog asynchronously.
|
||||
/// </summary>
|
||||
|
@ -213,42 +225,42 @@ namespace Greenshot.Helpers {
|
|||
t.Name = "Create MAPI mail";
|
||||
t.SetApartmentState(ApartmentState.STA);
|
||||
t.Start();
|
||||
|
||||
|
||||
// only return when the new thread has built it's interop representation
|
||||
_manualResetEvent.WaitOne();
|
||||
_manualResetEvent.Reset();
|
||||
}
|
||||
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
|
||||
#region Private Methods
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sends the mail message.
|
||||
/// </summary>
|
||||
private void _ShowMail() {
|
||||
MAPIHelperInterop.MapiMessage message = new MAPIHelperInterop.MapiMessage();
|
||||
|
||||
|
||||
using (RecipientCollection.InteropRecipientCollection interopRecipients = _recipientCollection.GetInteropRepresentation()) {
|
||||
message.Subject = _subject;
|
||||
message.NoteText = _body;
|
||||
|
||||
|
||||
message.Recipients = interopRecipients.Handle;
|
||||
message.RecipientCount = _recipientCollection.Count;
|
||||
|
||||
|
||||
// Check if we need to add attachments
|
||||
if (_files.Count > 0) {
|
||||
// Add attachments
|
||||
message.Files = _AllocAttachments(out message.FileCount);
|
||||
}
|
||||
|
||||
|
||||
// Signal the creating thread (make the remaining code async)
|
||||
_manualResetEvent.Set();
|
||||
|
||||
|
||||
const int MAPI_DIALOG = 0x8;
|
||||
//const int MAPI_LOGON_UI = 0x1;
|
||||
int error = MAPIHelperInterop.MAPISendMail(IntPtr.Zero, IntPtr.Zero, message, MAPI_DIALOG, 0);
|
||||
|
||||
|
||||
if (_files.Count > 0) {
|
||||
// Deallocate the files
|
||||
_DeallocFiles(message);
|
||||
|
@ -268,23 +280,20 @@ namespace Greenshot.Helpers {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Deallocates the files in a message.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to deallocate the files from.</param>
|
||||
private void _DeallocFiles(MAPIHelperInterop.MapiMessage message)
|
||||
{
|
||||
if (message.Files != IntPtr.Zero)
|
||||
{
|
||||
private void _DeallocFiles(MAPIHelperInterop.MapiMessage message) {
|
||||
if (message.Files != IntPtr.Zero) {
|
||||
Type fileDescType = typeof(MapiFileDescriptor);
|
||||
int fsize = Marshal.SizeOf(fileDescType);
|
||||
|
||||
|
||||
// Get the ptr to the files
|
||||
int runptr = (int)message.Files;
|
||||
// Release each file
|
||||
for (int i = 0; i < message.FileCount; i++)
|
||||
{
|
||||
for (int i = 0; i < message.FileCount; i++) {
|
||||
Marshal.DestroyStructure((IntPtr)runptr, fileDescType);
|
||||
runptr += fsize;
|
||||
}
|
||||
|
@ -292,44 +301,40 @@ namespace Greenshot.Helpers {
|
|||
Marshal.FreeHGlobal(message.Files);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Allocates the file attachments
|
||||
/// </summary>
|
||||
/// <param name="fileCount"></param>
|
||||
/// <returns></returns>
|
||||
private IntPtr _AllocAttachments(out int fileCount)
|
||||
{
|
||||
private IntPtr _AllocAttachments(out int fileCount) {
|
||||
fileCount = 0;
|
||||
if (_files == null)
|
||||
{
|
||||
if (_files == null) {
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
if ((_files.Count <= 0) || (_files.Count > 100))
|
||||
{
|
||||
if ((_files.Count <= 0) || (_files.Count > 100)) {
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
|
||||
Type atype = typeof(MapiFileDescriptor);
|
||||
int asize = Marshal.SizeOf(atype);
|
||||
IntPtr ptra = Marshal.AllocHGlobal(_files.Count * asize);
|
||||
|
||||
|
||||
MapiFileDescriptor mfd = new MapiFileDescriptor();
|
||||
mfd.position = -1;
|
||||
int runptr = (int)ptra;
|
||||
for (int i = 0; i < _files.Count; i++)
|
||||
{
|
||||
for (int i = 0; i < _files.Count; i++) {
|
||||
string path = _files[i] as string;
|
||||
mfd.name = Path.GetFileName(path);
|
||||
mfd.path = path;
|
||||
Marshal.StructureToPtr(mfd, (IntPtr)runptr, false);
|
||||
runptr += asize;
|
||||
}
|
||||
|
||||
|
||||
fileCount = _files.Count;
|
||||
return ptra;
|
||||
}
|
||||
|
||||
|
||||
private enum MAPI_CODES {
|
||||
SUCCESS = 0,
|
||||
USER_ABORT = 1,
|
||||
|
@ -364,9 +369,9 @@ namespace Greenshot.Helpers {
|
|||
/// Logs any Mapi errors.
|
||||
/// </summary>
|
||||
private string GetMapiError(MAPI_CODES errorCode) {
|
||||
|
||||
|
||||
string error = string.Empty;
|
||||
|
||||
|
||||
switch (errorCode) {
|
||||
case MAPI_CODES.USER_ABORT:
|
||||
error = "User Aborted.";
|
||||
|
@ -453,29 +458,27 @@ namespace Greenshot.Helpers {
|
|||
return error;
|
||||
}
|
||||
#endregion Private Methods
|
||||
|
||||
|
||||
#region Private MAPIHelperInterop Class
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Internal class for calling MAPI APIs
|
||||
/// </summary>
|
||||
internal class MAPIHelperInterop
|
||||
{
|
||||
internal class MAPIHelperInterop {
|
||||
#region Constructors
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Private constructor.
|
||||
/// </summary>
|
||||
private MAPIHelperInterop()
|
||||
{
|
||||
private MAPIHelperInterop() {
|
||||
// Intenationally blank
|
||||
}
|
||||
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
|
||||
#region Structs
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public class MapiMessage {
|
||||
public int Reserved = 0;
|
||||
|
@ -491,7 +494,7 @@ namespace Greenshot.Helpers {
|
|||
public int FileCount = 0;
|
||||
public IntPtr Files = IntPtr.Zero;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public class MapiRecipDesc {
|
||||
public int Reserved = 0;
|
||||
|
@ -501,263 +504,239 @@ namespace Greenshot.Helpers {
|
|||
public int eIDSize = 0;
|
||||
public IntPtr EntryID = IntPtr.Zero;
|
||||
}
|
||||
|
||||
|
||||
[DllImport("MAPI32.DLL", SetLastError = true)]
|
||||
public static extern int MAPISendMail(IntPtr session, IntPtr hwnd, MapiMessage message, int flg, int rsv);
|
||||
|
||||
|
||||
#endregion Structs
|
||||
}
|
||||
|
||||
|
||||
#endregion Private MAPIHelperInterop Class
|
||||
}
|
||||
|
||||
|
||||
#endregion Public MapiMailMessage Class
|
||||
|
||||
|
||||
#region Public Recipient Class
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Recipient for a MapiMailMessage.
|
||||
/// </summary>
|
||||
public class Recipient
|
||||
{
|
||||
public class Recipient {
|
||||
#region Public Properties
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The email address of this recipient.
|
||||
/// </summary>
|
||||
public string Address = null;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The display name of this recipient.
|
||||
/// </summary>
|
||||
public string DisplayName = null;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// How the recipient will receive this message (To, CC, BCC).
|
||||
/// </summary>
|
||||
public MapiMailMessage.RecipientType RecipientType = MapiMailMessage.RecipientType.To;
|
||||
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new recipient with the specified address.
|
||||
/// </summary>
|
||||
public Recipient(string address)
|
||||
{
|
||||
public Recipient(string address) {
|
||||
Address = address;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new recipient with the specified address and display name.
|
||||
/// </summary>
|
||||
public Recipient(string address, string displayName)
|
||||
{
|
||||
public Recipient(string address, string displayName) {
|
||||
Address = address;
|
||||
DisplayName = displayName;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new recipient with the specified address and recipient type.
|
||||
/// </summary>
|
||||
public Recipient(string address, MapiMailMessage.RecipientType recipientType)
|
||||
{
|
||||
public Recipient(string address, MapiMailMessage.RecipientType recipientType) {
|
||||
Address = address;
|
||||
RecipientType = recipientType;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new recipient with the specified address, display name and recipient type.
|
||||
/// </summary>
|
||||
public Recipient(string address, string displayName, MapiMailMessage.RecipientType recipientType)
|
||||
{
|
||||
public Recipient(string address, string displayName, MapiMailMessage.RecipientType recipientType) {
|
||||
Address = address;
|
||||
DisplayName = displayName;
|
||||
RecipientType = recipientType;
|
||||
}
|
||||
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns an interop representation of a recepient.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal MapiMailMessage.MAPIHelperInterop.MapiRecipDesc GetInteropRepresentation()
|
||||
{
|
||||
internal MapiMailMessage.MAPIHelperInterop.MapiRecipDesc GetInteropRepresentation() {
|
||||
MapiMailMessage.MAPIHelperInterop.MapiRecipDesc interop = new MapiMailMessage.MAPIHelperInterop.MapiRecipDesc();
|
||||
|
||||
if (DisplayName == null)
|
||||
{
|
||||
|
||||
if (DisplayName == null) {
|
||||
interop.Name = Address;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
interop.Name = DisplayName;
|
||||
interop.Address = Address;
|
||||
}
|
||||
|
||||
|
||||
interop.RecipientClass = (int)RecipientType;
|
||||
|
||||
|
||||
return interop;
|
||||
}
|
||||
|
||||
|
||||
#endregion Internal Methods
|
||||
}
|
||||
|
||||
|
||||
#endregion Public Recipient Class
|
||||
|
||||
|
||||
#region Public RecipientCollection Class
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a colleciton of recipients for a mail message.
|
||||
/// </summary>
|
||||
public class RecipientCollection : CollectionBase
|
||||
{
|
||||
public class RecipientCollection : CollectionBase {
|
||||
/// <summary>
|
||||
/// Adds the specified recipient to this collection.
|
||||
/// </summary>
|
||||
public void Add(Recipient value)
|
||||
{
|
||||
public void Add(Recipient value) {
|
||||
List.Add(value);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new recipient with the specified address to this collection.
|
||||
/// </summary>
|
||||
public void Add(string address)
|
||||
{
|
||||
public void Add(string address) {
|
||||
this.Add(new Recipient(address));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new recipient with the specified address and display name to this collection.
|
||||
/// </summary>
|
||||
public void Add(string address, string displayName)
|
||||
{
|
||||
public void Add(string address, string displayName) {
|
||||
this.Add(new Recipient(address, displayName));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new recipient with the specified address and recipient type to this collection.
|
||||
/// </summary>
|
||||
public void Add(string address, MapiMailMessage.RecipientType recipientType)
|
||||
{
|
||||
public void Add(string address, MapiMailMessage.RecipientType recipientType) {
|
||||
this.Add(new Recipient(address, recipientType));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new recipient with the specified address, display name and recipient type to this collection.
|
||||
/// </summary>
|
||||
public void Add(string address, string displayName, MapiMailMessage.RecipientType recipientType)
|
||||
{
|
||||
public void Add(string address, string displayName, MapiMailMessage.RecipientType recipientType) {
|
||||
this.Add(new Recipient(address, displayName, recipientType));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the recipient stored in this collection at the specified index.
|
||||
/// </summary>
|
||||
public Recipient this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
public Recipient this[int index] {
|
||||
get {
|
||||
return (Recipient)List[index];
|
||||
}
|
||||
}
|
||||
|
||||
internal InteropRecipientCollection GetInteropRepresentation()
|
||||
{
|
||||
|
||||
internal InteropRecipientCollection GetInteropRepresentation() {
|
||||
return new InteropRecipientCollection(this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Struct which contains an interop representation of a colleciton of recipients.
|
||||
/// </summary>
|
||||
internal struct InteropRecipientCollection : IDisposable
|
||||
{
|
||||
internal struct InteropRecipientCollection : IDisposable {
|
||||
#region Member Variables
|
||||
|
||||
|
||||
private IntPtr _handle;
|
||||
private int _count;
|
||||
|
||||
|
||||
#endregion Member Variables
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor for creating InteropRecipientCollection.
|
||||
/// </summary>
|
||||
/// <param name="outer"></param>
|
||||
public InteropRecipientCollection(RecipientCollection outer)
|
||||
{
|
||||
public InteropRecipientCollection(RecipientCollection outer) {
|
||||
_count = outer.Count;
|
||||
|
||||
if (_count == 0)
|
||||
{
|
||||
|
||||
if (_count == 0) {
|
||||
_handle = IntPtr.Zero;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// allocate enough memory to hold all recipients
|
||||
int size = Marshal.SizeOf(typeof(MapiMailMessage.MAPIHelperInterop.MapiRecipDesc));
|
||||
_handle = Marshal.AllocHGlobal(_count * size);
|
||||
|
||||
|
||||
// place all interop recipients into the memory just allocated
|
||||
int ptr = (int)_handle;
|
||||
foreach (Recipient native in outer)
|
||||
{
|
||||
foreach (Recipient native in outer) {
|
||||
MapiMailMessage.MAPIHelperInterop.MapiRecipDesc interop = native.GetInteropRepresentation();
|
||||
|
||||
|
||||
// stick it in the memory block
|
||||
Marshal.StructureToPtr(interop, (IntPtr)ptr, false);
|
||||
ptr += size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion Costructors
|
||||
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public IntPtr Handle
|
||||
{
|
||||
get { return _handle; }
|
||||
|
||||
public IntPtr Handle {
|
||||
get {
|
||||
return _handle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_handle != IntPtr.Zero)
|
||||
{
|
||||
public void Dispose() {
|
||||
if (_handle != IntPtr.Zero) {
|
||||
Type type = typeof(MapiMailMessage.MAPIHelperInterop.MapiRecipDesc);
|
||||
int size = Marshal.SizeOf(type);
|
||||
|
||||
|
||||
// destroy all the structures in the memory area
|
||||
int ptr = (int)_handle;
|
||||
for (int i = 0; i < _count; i++)
|
||||
{
|
||||
for (int i = 0; i < _count; i++) {
|
||||
Marshal.DestroyStructure((IntPtr)ptr, type);
|
||||
ptr += size;
|
||||
}
|
||||
|
||||
|
||||
// free the memory
|
||||
Marshal.FreeHGlobal(_handle);
|
||||
|
||||
|
||||
_handle = IntPtr.Zero;
|
||||
_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public RecipientCollection Class
|
||||
}
|
||||
|
||||
#endregion Public RecipientCollection Class
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue