첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
0.02MB

▶ ConstantHelper.cs

namespace TestProject
{
    /// <summary>
    /// 상수 헬퍼
    /// </summary>
    public static class ConstantHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// Sales Force 폴더명
        /// </summary>
        public static readonly string SalesForceFolderName = "Sales Force";

        #endregion
    }
}

 

728x90

 

▶ SessionExtensions.cs

using Microsoft.Office.Interop.Outlook;

namespace TestProject
{
    /// <summary>
    /// 세션 확장
    /// </summary>
    public static class SessionExtensions
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region Sales Force 폴더 생성하기 - CreatSalesForceFolders(session)

        /// <summary>
        /// Sales Force 폴더 생성하기
        /// </summary>
        /// <param name="session">세션</param>
        public static void CreatSalesForceFolders(this NameSpace session)
        {
            foreach(Folder rootFolder in session.Folders)
            {
                if(!rootFolder.HasFolder(ConstantHelper.SalesForceFolderName))
                {
                    rootFolder.AddFolder(ConstantHelper.SalesForceFolderName);
                }
            }
        }

        #endregion
    }
}

 

300x250

 

▶ MAPIFolderExtensions.cs

using Microsoft.Office.Interop.Outlook;

namespace TestProject
{
    /// <summary>
    /// MAPI 폴더 확장
    /// </summary>
    public static class MAPIFolderExtensions
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 폴더 소유 여부 구하기 - HasFolder(rootFolder, targetFolderName)

        /// <summary>
        /// 폴더 소유 여부 구하기
        /// </summary>
        /// <param name="rootFolder">루트 폴더</param>
        /// <param name="targetFolderName">타겟 폴더명</param>
        /// <returns>폴더 소유 여부</returns>
        public static bool HasFolder(this MAPIFolder rootFolder, string targetFolderName)
        {
            foreach(Folder folder in rootFolder.Folders)
            {
                if(folder.Name == targetFolderName)
                {
                    return true;
                }
            }

            return false;
        }

        #endregion
        #region 폴더 구하기 - GetFolder(rootFolder, targetFolderName)

        /// <summary>
        /// 폴더 구하기
        /// </summary>
        /// <param name="rootFolder">루트 폴더</param>
        /// <param name="targetFolderName">타겟 폴더명</param>
        /// <returns>폴더</returns>
        public static Folder GetFolder(this MAPIFolder rootFolder, string targetFolderName)
        {
            foreach(Folder folder in rootFolder.Folders)
            {
                if(folder.Name == targetFolderName)
                {
                    return folder;
                }
            }

            return null;
        }

        #endregion
        #region 폴더 추가하기 - AddFolder(parentFolder, folderName)

        /// <summary>
        /// 폴더 추가하기
        /// </summary>
        /// <param name="parentFolder">부모 폴더</param>
        /// <param name="folderName">폴더명</param>
        /// <returns>MAPI 폴더</returns>
        public static MAPIFolder AddFolder(this MAPIFolder parentFolder, string folderName)
        {
            MAPIFolder folder = parentFolder.Folders.Add(folderName, OlDefaultFolders.olFolderInbox);

            return folder;
        }

        #endregion
    }
}

 

▶ FolderContainer.cs

using Microsoft.Office.Interop.Outlook;
using System.Collections.Generic;

namespace TestProject
{
    /// <summary>
    /// 폴더 컨테이너
    /// </summary>
    public class FolderContainer
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 부모 폴더 컨테이너 - Parent

        /// <summary>
        /// 부모 폴더 컨테이너
        /// </summary>
        public FolderContainer Parent { get; set; }

        #endregion
        #region 소스 키 - SourceKey

        /// <summary>
        /// 소스 키
        /// </summary>
        public string SourceKey { get; set; }

        #endregion
        #region 소스 폴더 - SourceFolder

        /// <summary>
        /// 소스 폴더
        /// </summary>
        public Folder SourceFolder { get; set; }

        #endregion
        #region 소스 폴더 컬렉션 - SourceFolders

        /// <summary>
        /// 소스 폴더 컬렉션
        /// </summary>
        public Folders SourceFolders { get; set; }

        #endregion
        #region 자식 리스트 - ChildList

        /// <summary>
        /// 자식 리스트
        /// </summary>
        public List<FolderContainer> ChildList { get; set; } = new List<FolderContainer>();

        #endregion
    }
}

 

▶ FolderContainerManager.cs

using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;

namespace TestProject
{
    /// <summary>
    /// 폴더 컨테이너 관리자
    /// </summary>
    public class FolderContainerManager : IDisposable
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Event
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 폴더 삭제시 이벤트 - FolderRemove

        /// <summary>
        /// 폴더 삭제시 이벤트
        /// </summary>
        public event EventHandler FolderRemove;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 세션
        /// </summary>
        private NameSpace session;

        /// <summary>
        /// 폴더 컨테이너 딕셔너리
        /// </summary>
        private Dictionary<string, FolderContainer> folderContainerDictionary = new Dictionary<string, FolderContainer>();

        /// <summary>
        /// 마지막 폴더 삭제 시간
        /// </summary>
        private DateTime lastFolderRemoveTime = DateTime.Now;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - FolderContainerManager(session)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="session">세션</param>
        public FolderContainerManager(NameSpace session)
        {
            this.session = session;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public
        //////////////////////////////////////////////////////////////////////////////// Function

        #region 폴더 컨테이너 딕셔너리 데이터 지우기 - ClearFolderContainerDictionaryData()

        /// <summary>
        /// 폴더 컨테이너 딕셔너리 데이터 지우기
        /// </summary>
        public void ClearFolderContainerDictionaryData()
        {
            foreach(KeyValuePair<string, FolderContainer> keyValuePair in this.folderContainerDictionary)
            {
                string          sourceKey = keyValuePair.Key;
                FolderContainer container = keyValuePair.Value;

                try
                {
                    container.SourceFolder.BeforeFolderMove -= sourceFolder_BeforeFolderMove;
                    container.SourceFolder.BeforeItemMove   -= sourceFolder_BeforeItemMove;
                    container.SourceFolders.FolderAdd       -= sourceFolders_FolderAdd;
                    container.SourceFolders.FolderChange    -= sourceFolders_FolderChange;
                }
                catch
                {
                }

                container.Parent        = null;
                container.SourceKey     = null;
                container.SourceFolder  = null;
                container.SourceFolders = null;

                container.ChildList.Clear();
            }

            this.folderContainerDictionary.Clear();
        }

        #endregion
        #region 폴더 컨테이너 딕셔너리 구축하기 - BuildFolderContainerDictionary()

        /// <summary>
        /// 폴더 컨테이너 딕셔너리 구축하기
        /// </summary>
        public void BuildFolderContainerDictionary()
        {
            foreach(Folder rootfolder in this.session.Folders)
            {
                Folder salesForceFolder = rootfolder.GetFolder(ConstantHelper.SalesForceFolderName);

                if(salesForceFolder == null)
                {
                    continue;
                }

                AddFolderContainer(null, salesForceFolder);
            }
        }

        #endregion

        #region 리소스 해제하기 - Dispose()

        /// <summary>
        /// 리소스 해제하기
        /// </summary>
        public void Dispose()
        {
            ClearFolderContainerDictionaryData();

            this.session = null;
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 소스 폴더 폴더 이동 전 처리하기 - sourceFolder_BeforeFolderMove(targetFolder, cancel)

        /// <summary>
        /// 소스 폴더 폴더 이동 전 처리하기
        /// </summary>
        /// <param name="targetFolder">타겟 폴더</param>
        /// <param name="cancel">취소 여부</param>
        private void sourceFolder_BeforeFolderMove(MAPIFolder targetFolder, ref bool cancel)
        {
            if(targetFolder.Name != "Deleted Items")
            {
                cancel = true;
            }
        }

        #endregion
        #region 소스 폴더 항목 이동 전 처리하기 - sourceFolder_BeforeItemMove(sourceItem, targetFolder, cancel)

        /// <summary>
        /// 소스 폴더 항목 이동 전 처리하기
        /// </summary>
        /// <param name="sourceItem">소스 항목</param>
        /// <param name="targetFolder">타겟 폴더</param>
        /// <param name="cancel">취소 여부</param>
        private void sourceFolder_BeforeItemMove(object sourceItem, MAPIFolder targetFolder, ref bool cancel)
        {
            if(targetFolder.Name != "Deleted Items")
            {
                cancel = true;
            }
        }

        #endregion
        #region 소스 폴더 컬렉션 폴더 추가시 처리하기 - sourceFolders_FolderAdd(folder)

        /// <summary>
        /// 소스 폴더 컬렉션 폴더 추가시 처리하기
        /// </summary>
        /// <param name="folder">폴더</param>
        private void sourceFolders_FolderAdd(MAPIFolder folder)
        {
            try
            {
                ClearFolderContainerDictionaryData();

                BuildFolderContainerDictionary();
            }
            catch(System.Exception)
            {
                return;
            }
        }

        #endregion
        #region 소스 폴더 컬렉션 폴더 변경시 처리하기 - sourceFolders_FolderChange(folder)

        /// <summary>
        /// 소스 폴더 컬렉션 폴더 변경시 처리하기
        /// </summary>
        /// <param name="folder">폴더</param>
        private void sourceFolders_FolderChange(MAPIFolder folder)
        {
            try
            {
                ClearFolderContainerDictionaryData();

                BuildFolderContainerDictionary();
            }
            catch(System.Exception)
            {
                return;
            }
        }

        #endregion
        #region 소스 폴더 컬렉션 폴더 삭제시 처리하기 - sourceFolders_FolderRemove()

        /// <summary>
        /// 소스 폴더 컬렉션 폴더 삭제시 처리하기
        /// </summary>
        private void sourceFolders_FolderRemove()
        {
            TimeSpan timeSpan = DateTime.Now - this.lastFolderRemoveTime;

            if(timeSpan.Milliseconds < 500)
            {
                return;
            }

            FolderRemove?.Invoke(this, EventArgs.Empty);

            this.lastFolderRemoveTime = DateTime.Now;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 폴더 컨테이너 추가하기 - AddFolderContainer(parentContainer, folder)

        /// <summary>
        /// 폴더 컨테이너 추가하기
        /// </summary>
        /// <param name="parentContainer">부모 컨테이너</param>
        /// <param name="folder">폴더</param>
        private void AddFolderContainer(FolderContainer parentContainer, Folder folder)
        {
            string sourceKey = folder.FullFolderPath.Substring(2);

            string[] sourceKeyItemArray = sourceKey.Split('\\');

            if(sourceKeyItemArray.Length < 2 || sourceKeyItemArray[1] != ConstantHelper.SalesForceFolderName)
            {
                return;
            }

            FolderContainer container = new FolderContainer();

            container.Parent        = parentContainer;
            container.SourceKey     = sourceKey;
            container.SourceFolder  = folder;
            container.SourceFolders = folder.Folders;

            container.SourceFolder.BeforeFolderMove -= sourceFolder_BeforeFolderMove;
            container.SourceFolder.BeforeItemMove   -= sourceFolder_BeforeItemMove;
            container.SourceFolders.FolderAdd       -= sourceFolders_FolderAdd;
            container.SourceFolders.FolderChange    -= sourceFolders_FolderChange;
            container.SourceFolders.FolderRemove    -= sourceFolders_FolderRemove;

            container.SourceFolder.BeforeFolderMove += sourceFolder_BeforeFolderMove;
            container.SourceFolder.BeforeItemMove   += sourceFolder_BeforeItemMove;
            container.SourceFolders.FolderAdd       += sourceFolders_FolderAdd;
            container.SourceFolders.FolderChange    += sourceFolders_FolderChange;
            container.SourceFolders.FolderRemove    += sourceFolders_FolderRemove;

            if(parentContainer != null)
            {
                parentContainer.ChildList.Add(container);
            }

            this.folderContainerDictionary.Add(container.SourceKey, container);

            //Debug.WriteLine(container.SourceKey);

            foreach(Folder childFolder in folder.Folders)
            {
                AddFolderContainer(container, childFolder);
            }
        }

        #endregion
    }
}

 

▶ CustomAddIn.cs

using Microsoft.Office.Interop.Outlook;
using System;

namespace TestProject
{
    /// <summary>
    /// 커스텀 애드인
    /// </summary>
    public partial class CustomAddIn
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 폴더 컨테이너 관리자
        /// </summary>
        private FolderContainerManager folderContainerManager = null;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 커스텀 애드인 시작시 처리하기 - CustomAddIn_Startup(sender, e)

        /// <summary>
        /// 커스텀 애드인 시작시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void CustomAddIn_Startup(object sender, EventArgs e)
        {
            Application.Session.CreatSalesForceFolders();

            this.folderContainerManager = new FolderContainerManager(Application.Session);

            this.folderContainerManager.FolderRemove += folderContainerManager_FolderRemove;

            this.folderContainerManager.BuildFolderContainerDictionary();

            (Application as ApplicationEvents_11_Event).Quit += application_Quit;
        }

        #endregion
        #region 커스텀 애드인 셧다운시 처리하기 - CustomAddIn_Shutdown(sender, e)

        /// <summary>
        /// 커스텀 애드인 셧다운시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void CustomAddIn_Shutdown(object sender, EventArgs e)
        {
        }

        #endregion

        #region 애플리케이션 종료시 처리하기 - application_Quit()

        /// <summary>
        /// 애플리케이션 종료시 처리하기
        /// </summary>
        private void application_Quit()
        {
            this.folderContainerManager.Dispose();

            this.folderContainerManager = null;
        }

        #endregion

        #region 폴더 컨테이너 관리자 폴더 삭제시 처리하기 - folderContainerManager_FolderRemove(sender, e)

        /// <summary>
        /// 폴더 컨테이너 관리자 폴더 삭제시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void folderContainerManager_FolderRemove(object sender, EventArgs e)
        {
            System.Windows.Forms.MessageBox.Show("폴더가 삭제되었습니다.");
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region VSTO에서 생성한 코드

        /// <summary>
        /// 디자이너 지원에 필요한 메서드입니다. 
        /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup  += new System.EventHandler(CustomAddIn_Startup );
            this.Shutdown += new System.EventHandler(CustomAddIn_Shutdown);
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요