Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否在Outlook 2007/2010的“待办事项”栏中添加一个部分?_C#_.net_Outlook_Vsto - Fatal编程技术网

C# 是否在Outlook 2007/2010的“待办事项”栏中添加一个部分?

C# 是否在Outlook 2007/2010的“待办事项”栏中添加一个部分?,c#,.net,outlook,vsto,C#,.net,Outlook,Vsto,我想在Outlook 2010(或2007)的待办事项栏中添加一个新的部分。我找到了一些代码来创建一个新的可折叠任务窗格,有人声称你不能修改待办事项栏,但我还发现了一个名为Add-In Express的产品,声称它可以做到这一点(尽管349美元的价格不值得一次过的项目) 有可能做到吗?迈克尔 查看Outlook表单区域。 您可以使用VSTO加载项添加它们。 尽管外接程序express还有一些选项可供添加。 网上也有不少教程 Marcus您要查找的是任务窗格,而不完全是表单区域。任务窗格的工作方式

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

有可能做到吗?迈克尔

查看Outlook表单区域。 您可以使用VSTO加载项添加它们。 尽管外接程序express还有一些选项可供添加。 网上也有不少教程


Marcus

您要查找的是任务窗格,而不完全是表单区域。任务窗格的工作方式与表单区域稍有不同,它们仅在Office 2007及更高版本中可用(这看起来对您来说不是问题,因为您在2007-2010年需要它)。如果没有其他事情的话,至少知道正确的术语可能会让谷歌在这方面更容易一些

这是一个例子

现在,就向现有任务窗格添加一个部分而言,我还不能确定。但希望这能让你更接近

顺便说一句,外接程序Express库非常棒。让这类事情成为2分钟的任务。强烈推荐-这可能是您将再次使用的东西,因为它们使工作变得如此简单。

经过一些研究(以及看过外接程序Express的产品文档后),我认为可以在Outlook 2007中自定义“待办事项”栏

CodeProject中有一个proof-poof概念,它在Outlooks主窗口中嵌入了一个“自定义”(读写)窗格。本文由Lukas Neumann撰写,可在以下网址查阅:

原则如下:

  • 在Outlook窗口中搜索要放置自己窗口的子窗口(即待办事项栏子窗口)
  • 调整窗口内容的大小,为控件留出一些空间
  • 将自己的窗口作为子窗口添加
  • 子类化To Do Bar窗口,以钩住该窗口的消息循环
  • 调整示例代码基本上只需要做两个修改:

  • 获取正确的子窗口句柄:待办事项栏的窗口类称为“WUNDERBAR”。此类用于多个子窗口,因此请确保同时检查正确的窗口标题(“ToDoBar”)或仅按窗口标题搜索
  • 正确调整面板的大小(简单但并不总是容易;-)
  • (如果未找到待办事项栏,请添加一些适当的错误处理等)

    如果您熟悉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;
        }
    }
    
    概念证明是一个托管COM插件,不使用VSTO,但是一个非常类似的方法也应该适用于VSTO。如果您需要任何进一步的帮助,请告诉我,因为概念验证已经需要一些关于子类化和Office插件体系结构(IDTExtensibility2)的知识


    也请考虑这只是一个概念的证明,显示了如何定制Outlook UI的基本技术。而且我的编辑远远不是漂亮的代码;-)

    问题在于将新窗体区域附着/邻接到待办事项栏。我知道如何将其附加到邮件窗口和许多“标准”表单,但似乎没有正式的方法将其附加到待办事项栏?您从哪里发现可以使用Add-in Express自定义待办事项栏的说法?我在产品描述中找不到类似的内容,据我所知,这是不可能的。它在这里:(区域6)@divo,我已经广泛使用外接程序Express,可以确认它确实允许您向待办事项栏添加新的部分(我有生活在待办事项栏中的生产外接程序)。感谢链接,知道这一点很有意思。经过一些调整后,这一点很有效,尽管现在我意识到它相当丑陋和粗糙,所以我不得不考虑我最终是否真的想要它。谢谢你的努力,也谢谢你。事实上,这是相当丑陋和黑客,它直接导致了问题,如果几个插件竞争的空间在待办事项栏。在受控(公司)环境中这样做可能是安全的,但在野外。。。