2009-12-09 64 views
3

我想在Outlook 2010(或2007)中的待辦事項欄中添加一個新的部分。我發現了一些代碼來創建一個新的可摺疊的任務窗格,有人聲稱你不能修改任務欄,但我還發現一個名爲Add-In Express的產品聲稱它可以做到這一點(儘管在349美元這是不值得的爲一次性項目)。在Outlook 2007/2010中的待辦事項欄中添加一節?

可以做到這一點嗎?

+0

你在哪裏發現聲稱使用Add-in Express可以自定義待辦事項欄?我無法從產品說明中找到類似的東西,據我所知這是不可能的。 – 2009-12-15 00:16:14

+0

它在這裏:http://www.add-in-express.com/outlook-extension/office-2007.php#NEWEXPERIENCE(區域6) – 2009-12-15 00:44:29

+0

@divo,我已經廣泛地使用了插件快速並可以確認它確實可以讓你在待辦事項欄中添加新的部分(我的生產插件位於待辦事項欄中)。 – 2009-12-15 22:20:31

回答

3

經過一番研究(後看過的產品文檔加載快遞),我想這是可以自定義待辦事項欄在Outlook 2007中

還有就是證明poof-在CodeProject上嵌入一個「自定義」(讀自寫)窗格到Outlook主窗口中的概念。該文章已被寫入由盧卡斯諾伊曼和可以在這裏找到:

Additional custom panel in Microsoft Outlook

的原理如下:

  1. 搜索Outlook窗口的子窗口要放置自己的窗口(即To-Do Bar子窗口)
  2. 調整窗口的內容以爲控件創建一些空間
  3. 添加您自己的窗口,作爲一個孩子
  4. 子類中的待辦事項欄窗口掛接到該窗口的消息循環

目前基本上只有兩個需要做調整的示例代碼修改:

  1. 獲取正確的子窗口句柄:待辦事項欄的窗口類稱爲「WUNDERBAR」。此類用於多個子窗口,因此請確保也檢查正確的窗口標題(「ToDoBar」)或僅通過窗口標題進行搜索。
  2. 獲得調整面板的權利(簡單但並不總是容易;-)。

(並添加一些適當的錯誤處理,如果沒有找到待辦事項等)。

如果您熟悉Spy ++,這是一個強大的優勢,因爲需要找到Outlook的子窗口的類名和窗口標題。

我建議你下載示例代碼,並應用了以下修改:

在Connect.cs:

private const string SIBLING_WINDOW_CLASS = "NetUINativeHWNDHost"; 
public delegate bool EnumChildCallback(IntPtr hwnd, ref IntPtr lParam); 

[DllImport("User32.dll")] 
public static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildCallback lpEnumFunc, ref IntPtr lParam); 

[DllImport("User32.dll")] 
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); 

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); 

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
static extern int GetWindowTextLength(IntPtr hWnd); 

public static bool EnumChildProc(IntPtr hwndChild, ref IntPtr lParam) 
{ 
    StringBuilder className = new StringBuilder(128); 
    GetClassName(hwndChild, className, 128); 

    int length = GetWindowTextLength(hwndChild); 
    StringBuilder windowText = new StringBuilder(length + 1); 
    GetWindowText(hwndChild, windowText, windowText.Capacity); 

    if (className.ToString() == "WUNDERBAR" && windowText.ToString() == "ToDoBar") 
    { 
     lParam = hwndChild; 
     return false; 
    } 
    return true; 
} 

public void OnStartupComplete(ref System.Array custom) 
{ 
    if (_outlookApplication == null) 
     return; //We were not loaded into Outlook, so do nothing 

    //Get the instance of Outlook active explorer (= the main window) and start capturing selection changes 
    _outlookExplorer = _outlookApplication.ActiveExplorer(); 
    _outlookExplorer.SelectionChange += new ExplorerEvents_10_SelectionChangeEventHandler(outlookExplorer_SelectionChange); 

    //Find Outlook window handle (HWND) 
    IntPtr outlookWindow = FindOutlookWindow(); 

    if (outlookWindow == IntPtr.Zero) 
     return; 

    // Find ToDoBar window handle 
    IntPtr todoBarWindow = IntPtr.Zero; 
    EnumChildCallback cb = new EnumChildCallback(EnumChildProc); 
    EnumChildWindows(outlookWindow, cb, ref todoBarWindow); 

    if (todoBarWindow == IntPtr.Zero) 
     return; 

    //Find sibling window handle (HWND) 
    //Sibling window is the window which we are going to "cut" to make space for our own window 
    IntPtr siblingWindow = SafeNativeMethods.FindWindowEx(todoBarWindow, IntPtr.Zero, SIBLING_WINDOW_CLASS, null); 
    if (siblingWindow == IntPtr.Zero) 
     return; 

    //Initialise PanelManager and assign own panel to it 
    _panelManager = new PanelManager(outlookWindow, siblingWindow); 
    _customPanel = new MyPanel(); 
    _panelManager.ShowBarControl(_customPanel); 
} 

在PanelManager.cs:

private void ResizePanels() 
{ 
    if (_changingSize) 
     return; //Prevent infinite loops 

    _changingSize = true; 

    try 
    { 
     //Get size of the sibling window and main parent window 
     Rectangle siblingRect = SafeNativeMethods.GetWindowRectangle(this.SiblingWindow); 
     Rectangle parentRect = SafeNativeMethods.GetWindowRectangle(this.ParentWindow); 

     //Calculate position of sibling window in screen coordinates 
     SafeNativeMethods.POINT topLeft = new SafeNativeMethods.POINT(siblingRect.Left, siblingRect.Top); 
     SafeNativeMethods.ScreenToClient(this.ParentWindow, ref topLeft); 

     //Decrease size of the sibling window 
     int newHeight = parentRect.Height - topLeft.Y - _panelContainer.Height; 
     SafeNativeMethods.SetWindowPos(this.SiblingWindow, IntPtr.Zero, 0, 0, siblingRect.Width, newHeight, SafeNativeMethods.SWP_NOMOVE | SafeNativeMethods.SWP_NOZORDER); 

     //Move the bar to correct position 
     _panelContainer.Left = topLeft.X; 
     _panelContainer.Top = topLeft.Y + newHeight; 

     //Set correct height of the panel container 
     _panelContainer.Width = siblingRect.Width; 
    } 
    finally 
    { 
     _changingSize = false; 
    } 
} 

證明-的-concept是一個託管的COM插件,不使用VSTO,但類似的方法也適用於VSTO。如果您需要任何進一步幫助,請告知我們,因爲概念證明已經需要有關子類和Office附加體系結構(IDTExtensibility2)的一些知識。

另請注意,這只是一個概念驗證,顯示瞭如何自定義Outlook用戶界面的基本技巧。而我的編輯遠不是美麗的代碼;-)

+0

經過一些調整後,這種方法很有效,但現在我意識到這很醜陋,很難受,所以我不得不考慮如果我真的想要這樣。感謝您的努力。 – 2009-12-21 04:12:21

+0

也謝謝。事實上,這是相當醜陋和不安的,如果幾個插件在ToDo欄中爭奪空間,它會直接導致問題。在受控(企業)環境中做可能是安全的,但在野外...... – 2009-12-21 10:33:23

0

Michael,

看看Outlook窗體區域。 http://msdn.microsoft.com/en-us/library/bb386301.aspx 您可以使用VSTO插件添加它們。 雖然加載項express有幾個選項可供添加。 網上也有不少教程。

馬庫斯

+0

問題在於將新的表單區域附加到/連接到ToDo欄。我知道如何將它附加到郵件窗口和許多「標準」表單上,但似乎沒有正式的方法將它附加到「待辦事項欄」上? – 2009-12-14 19:50:59

2

什麼你正在尋找被稱爲TaskPane,不完全是一個窗體區域。 TaskPanes的工作方式與「表單區域」稍有不同,它們僅在Office 2007及更高版本中可用(對於2007-2010而言,這看起來不會對您造成問題)。如果沒有其他知識至少知道正確的術語可能會讓Google更容易一點。

這是Custom Task Panes Overview on MSDN

現在,就添加一個節到現有的TaskPane中,我不確定。但希望能讓你更接近一點。

順便說一下,附加的Express庫非常棒。使這種事情成爲2分鐘的任務。強烈建議 - 這可能是你會再次使用的東西,因爲他們讓工作變得如此簡單。