none
【VSTO】Outlook 連絡先カードについて RRS feed

  • 質問

  • お世話になっております。

    Outlook2016の既存アドレス帳とは別に、独自にアドレス帳を作成しております。

    アドレス帳の情報(名刺情報)は、社内SQLServerより取得しています。

    既存アドレス帳から送信相手を選択すると、選択した人の連絡先カードが表示できると思いますが、

    独自に作成しているアドレス帳から送信相手を選択した場合、連絡先カードを表示すると、電子メールの送信先・インスタントメッセージ

    にメールアドレスが表示されるだけで、他の項目が表示されません。当たり前と言えば当たり前なのですが。。。

    C#にて開発しており、以前このフォーラムにてご教授頂いた方法で、作成しており宛先は、MailItem.Recipientsへセットしております。

    連絡先カードへ表示したい項目は、会社名になります。どのような項目?へセットすれば良いのかご教授頂けると助かります。

    よろしくお願い致します。

    2017年11月2日 1:28

すべての返信

  • すみません。検証等は行っていないのですが、

    MailItem の Companies プロパティ が会社名を表すプロパティとなっているようですが、参考になりますでしょうか?

    参考サイト: https://msdn.microsoft.com/ja-jp/library/microsoft.office.interop.outlook._mailitem.companies.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
    2017年11月2日 1:55
  • kenjinote様

    情報ありがとうございます。

    私の方で、実装へ試みましたが、連絡先カードへは表示されませんでした。

    おそらく、私の実装方法が悪いのかと思います。

    因みに、実装したのは、

    MailItem.Companies = "会社名";

    と単純にセットしただけです。

    実際はRecipientsに指定されているアドレス(人)と会社名を連動させる必要があるので、

    配列などでセットするようになるのか。。。?

    Recipientsのプロパティ(?)にセットするようなのがあると良いのですが、、、、

    まだ、良く分かっていないので、再チャレンジしてみます。

    取り急ぎ、お礼まで。


    • 編集済み Mitakana 2017年11月2日 7:14
    2017年11月2日 7:13
  • #SQLServerからローカルのアドレス帳に情報をコピーしてやるのが楽だとは思いますが…

    以下、まともじゃない方法で表示だけならできるかもしれない

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;
    using Outlook = Microsoft.Office.Interop.Outlook;
    using Office = Microsoft.Office.Core;
    
    namespace OutlookAddIn1
    {
        public partial class ThisAddIn
        {
            private Test test;
    
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                test = new Test();
                test.Start();
    
                ((Outlook.ApplicationEvents_11_Event)Application).Quit += ThisAddIn_Quit;
            }
    
            private void ThisAddIn_Quit()
            {
                if (test != null) { test.Stop(); test = null; }
            }
    
            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
            {
                if (test != null) { test.Stop(); test = null; }
            }
    
            private void InternalStartup()
            {
                this.Startup += new System.EventHandler(ThisAddIn_Startup);
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
            }
        }
    }
    
    namespace OutlookAddIn1
    {
        using System.Runtime.InteropServices;
        using System.Windows.Forms;
    
        class Test
        {
            private System.Windows.Forms.Timer timer;
            private int processID;
            public Test()
            {
                timer = new System.Windows.Forms.Timer();
                timer.Interval = 1000;
                timer.Tick += timer_Tick;
    
                var process = System.Diagnostics.Process.GetCurrentProcess();
                processID = process.Id;
            }
    
            void timer_Tick(object sender, EventArgs e)
            {
                var list = Win32API.EnumWindows((h) =>
                {
                    uint pid;
                    Win32API.GetWindowThreadProcessId(h, out pid);
                    if (pid == processID)
                    {
                        string className = Win32API.GetClassName(h);
                        return className.StartsWith("NET UI TOOL WINDOW LAYERED", StringComparison.InvariantCultureIgnoreCase);
    
                    }
                    return false; ;
                });
                ContactCardWindow.TryAttach(list);
            }
    
            public void Start()
            {
                if (!timer.Enabled)
                {
                    timer.Enabled = true;
                    timer.Start();
                }
            }
            public void Stop()
            {
                timer.Stop();
                timer.Enabled = false;
            }
        }
    
        class ContactCardWindow : System.Windows.Forms.NativeWindow
        {
            private static readonly Dictionary<IntPtr, ContactCardWindow> exsists = new Dictionary<IntPtr, ContactCardWindow>();
    
            public static void TryAttach(IEnumerable<IntPtr> hwnds)
            {
                lock (exsists)
                {
                    foreach (IntPtr hwnd in hwnds)
                    {
                        if (!exsists.ContainsKey(hwnd))
                        {
                            var list = GetRICHEDIT60W(hwnd);
                            if (list.Count > 0)
                            {
                                var n = new ContactCardWindow(hwnd);
                                n.SetText();
                            }
                        }
                    }
                }
            }
    
            private ContactCardWindow(IntPtr hwnd)
            {
                AssignHandle(hwnd);
                lock (exsists)
                {
                    exsists.Add(hwnd, this);
                }
    
            }
    
    
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
                switch ((Win32API.WM)m.Msg)
                {
                    case Win32API.WM.WM_DESTROY:
                        OnDestroy();
                        break;
                    case Win32API.WM.WM_PAINT:
                        SetText();
                        break;
                }
            }
    
            private void OnDestroy()
            {
                lock (exsists)
                {
                    exsists.Remove(this.Handle);
                }
            }
    
            public void SetText()
            {
                var richedits = GetRICHEDIT60W(this.Handle);
                if (richedits.Count > 0)
                {
                    IntPtr hmem = System.Runtime.InteropServices.Marshal.StringToHGlobalUni("てすと");
                    try
                    {
                        foreach (IntPtr hwndRich in richedits)
                        {
                            string text = Win32API.GetText(hwndRich);
                            System.Diagnostics.Debug.WriteLine(text);
                            if (string.IsNullOrEmpty(text))
                            {
                                Win32API.SendMessage(hwndRich, (int)Win32API.EM.EM_SETSEL, IntPtr.Zero, IntPtr.Zero);
                                Win32API.SendMessage(hwndRich, (int)Win32API.EM.EM_REPLACESEL, IntPtr.Zero, hmem);
                            }
                        }
                    }
                    finally
                    {
                        System.Runtime.InteropServices.Marshal.FreeHGlobal(hmem);
                    }
                }
            }
    
            public static List<IntPtr> GetRICHEDIT60W(IntPtr hwnd)
            {
                List<IntPtr> retval = new List<IntPtr>();
    
                List<IntPtr> listNetUICtrlNotirySink = Win32API.EnumChildWindows(hwnd, (h) =>
                {
                    string className = Win32API.GetClassName(h);
                    return string.Equals(className, "NetUICtrlNotifySink");
                });
    
    
                foreach (IntPtr hwndUICtrl in listNetUICtrlNotirySink)
                {
                    List<IntPtr> listRICHEDIT60W = Win32API.EnumChildWindows(hwndUICtrl, (h) =>
                    {
                        string className = Win32API.GetClassName(h);
                        return string.Equals(className, "RICHEDIT60W", StringComparison.InvariantCultureIgnoreCase);
                    });
    
                    retval.AddRange(listRICHEDIT60W);
                }
    
                return retval;
            }
    
    
        }
    
        class Win32API
        {
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private extern static bool EnumWindows(EnumWindowsDelegate lpEnumFunc, IntPtr lparam);
            private delegate bool EnumWindowsDelegate(IntPtr hWnd, IntPtr lparam);
    
    
            public static List<IntPtr> EnumWindows(Func<IntPtr, bool> filter = null)
            {
                List<IntPtr> list = new List<IntPtr>();
                if (filter == null)
                {
                    EnumWindows((h, p) => { list.Add(h); return true; }, IntPtr.Zero);
                }
                else
                {
                    EnumWindows((h, p) => { if (filter(h)) { list.Add(h); } return true; }, IntPtr.Zero);
                }
                return list;
            }
    
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
            private delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);
    
            public static List<IntPtr> EnumChildWindows(IntPtr hwndParent, Func<IntPtr, bool> filter = null)
            {
                List<IntPtr> list = new List<IntPtr>();
                if (filter == null)
                {
                    EnumChildWindows(hwndParent, (h, p) => { list.Add(h); return true; }, IntPtr.Zero);
                }
                else
                {
                    EnumChildWindows(hwndParent, (h, p) => { if (filter(h)) { list.Add(h); } return true; }, IntPtr.Zero);
                }
                return list;
            }
    
            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
    
            public static string GetClassName(IntPtr hwnd)
            {
                System.Text.StringBuilder sb = new StringBuilder(256);
                int count = GetClassName(hwnd, sb, 1000);
                return sb.ToString(0, count);
            }
    
            [DllImport("user32.dll", SetLastError = true)]
            public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    
    
            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
    
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, StringBuilder lParam);
            public static string GetText(IntPtr hwnd)
            {
                int len = SendMessage(hwnd, (int)WM.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
                if (len == 0)
                {
                    return string.Empty;
                }
                else
                {
                    System.Text.StringBuilder sb = new StringBuilder(len);
                    SendMessage(hwnd, (int)WM.WM_GETTEXT, len, sb);
                    return sb.ToString();
                }
    
            }
    
            public enum WM : int
            {
                WM_DESTROY = 0x0002,
                WM_PAINT = 0x000F,
                WM_GETTEXT = 0x00d,
                WM_GETTEXTLENGTH = 0x00e,
            }
            public enum EM : int
            {
                EM_SETSEL = 0x00b1,
                EM_REPLACESEL = 0x00c2,
            }
        }
    }

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2017年11月3日 1:54
  • gekka様

    返信が遅くなり済みませんでした。

    ご丁寧にロジックをありがとうございます。

    頂いたロジックを理解するのに時間が掛かりそうですが、サンプルを作成してみたいと思います。

    時間はかかってしまいますが、実装してみた結果をお知らせ致します。

    2017年11月7日 9:45
  • Mitakana さん、こんにちは
    フォーラム オペレーターの立花楓です。

    本件について、その後はいかがでしょうか。
    何か進展がございましたらこちらのスレッドへご返信いただけますと幸いです。
    また、参考になる情報がありましたら、質問者からの [回答としてマーク] をお願いします。
     
    よろしくお願いします。


    MSDN/TechNet Community Support 立花楓

    2017年11月29日 2:33
    モデレータ