本文介绍了是否在Outlook 2007/2010的“待办事项"栏中添加了部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Outlook 2010(或2007)的待办事项栏"中添加一个新部分.我找到了一些代码来创建一个新的可折叠任务窗格,有人声称您不能修改待办事项栏,但我还发现了一个名为Add-In Express的产品声称可以做到(尽管349美元的价格不值得)一次性项目).

I would like to add a new section to the To-Do Bar in Outlook 2010 (or 2007). I found some code to create a new collapsible task pane and someone claiming you can't modify the To-Do bar, but I also found a product called Add-In Express that claims it can do it (although at $349 it's not worth it for a one-off project).

可以这样做吗?

推荐答案

经过一番研究(并查看了Add-in Express的产品文档),我发现可以在Outlook中自定义待办事项栏2007年.

After some research (and after having seen the product documentation of Add-in Express), I figured that it is possible to customize the To-Do Bar in Outlook 2007.

在CodeProject上有一个证明概念,该概念将自定义"(自读的)窗格嵌入到Outlooks主窗口中.该文章由Lukas Neumann撰写,可以在这里找到:

There is a proof-poof-concept on CodeProject that embeds a "custom" (read self-written) pane into Outlooks main window. The article has been written by Lukas Neumann and is available here:

原理如下:

  1. 在Outlook窗口中搜索要放置自己的窗口(即待办事项栏"子窗口)的子窗口
  2. 调整该窗口的内容大小以为控件留出一些空间
  3. 添加自己的窗口作为孩子
  4. 将待办事项栏"窗口子类化,以挂接到该窗口的消息循环中

基本上只需要进行两次修改即可调整示例代码:

There is basically only two modifications that need to be done to adjust the sample code:

  1. 获取正确的子窗口句柄:待办事项栏的窗口类称为"WUNDERBAR".此类用于多个子窗口,因此请确保还检查正确的窗口标题("ToDoBar")或仅按窗口标题进行搜索.
  2. 正确调整面板的大小(简单但并不总是容易;-).

(如果未找到待办事项栏等,并添加一些适当的错误处理).

(And add some proper error handling if the To-Do Bar is not found etc).

如果您熟悉Spy ++,这是一个不错的选择,因为它需要找出Outlook子窗口的类名和窗口标题.

It's a strong plus if you are familiar with Spy++ as it is needed to find out the class names and window titles of Outlook's child windows.

我建议您下载示例代码并进行以下修改:

I suggest you to download the sample code and apply the following modifications:

在Connect.cs中:

In 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中:

In 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;
    }
}

概念验证是一个托管的COM加载项,并且不使用VSTO,但是非常相似的方法也适用于VSTO.如果您需要进一步的帮助,请告诉我,因为概念验证已经需要有关子类化和Office加载项体系结构(IDTExtensibility2)的知识.

The proof-of-concept is a managed COM Add-in and not using VSTO, but a very similar approach should also work for VSTO. Let me know in case you need any further help, as the proof-of-concept already requires some knowledge about subclassing and the Office add-in architecture (IDTExtensibility2).

也请考虑这只是概念验证,它显示了如何自定义Outlook UI的基本技术.而且我的编辑远非精美的代码;-)

Please also consider that this is just a proof-of-concept showing the basic technique how to customize the Outlook UI. And my edits are far from beautiful code ;-)

这篇关于是否在Outlook 2007/2010的“待办事项"栏中添加了部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 20:53