gpt4 book ai didi

c# - 在 Outlook 2007/2010 的待办事项栏中添加一个部分?

转载 作者:行者123 更新时间:2023-11-30 15:11:51 26 4
gpt4 key购买 nike

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

有可能吗?

最佳答案

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

CodeProject 上有一个验证概念,将“自定义”(阅读自写) Pane 嵌入到 Outlook 主窗口中。该文章由 Lukas Neumann 撰写,可在此处获取:

Additional custom panel in Microsoft Outlook

原理如下:

  1. 在 Outlook 窗口中搜索您要放置自己的窗口的子窗口(即待办事项栏子窗口)
  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;
}
}

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

另请注意,这只是概念验证,展示了如何自定义 Outlook UI 的基本技术。而且我的编辑远非漂亮的代码 ;-)

关于c# - 在 Outlook 2007/2010 的待办事项栏中添加一个部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1871272/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com