You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VSTO Outlook插件:如何检测自定义任务窗格的手动高度调整

检测VSTO Outlook自定义任务窗格的高度调整

方案1:监听任务窗格内容控件的SizeChanged事件

自定义任务窗格本身没有直接暴露尺寸变化的事件,但你可以给窗格内的宿主WinForms控件添加SizeChanged事件。当用户拖动拆分器或通过菜单调整窗格高度时,控件尺寸会同步变化,触发该事件。

示例代码:

// 创建自定义任务窗格时绑定事件
var customTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(new YourUserControl(), "自定义窗格");
((YourUserControl)customTaskPane.Control).SizeChanged += TaskPaneContent_SizeChanged;

// 事件处理逻辑
private void TaskPaneContent_SizeChanged(object sender, EventArgs e)
{
    var userControl = sender as YourUserControl;
    if (userControl != null)
    {
        int currentHeight = userControl.Height;
        // 这里可对比历史高度、执行后续业务逻辑
    }
}

方案2:通过Windows API监听窗口大小变化

自定义任务窗格本质是Windows窗口,可获取它的句柄,通过API监听WM_SIZE消息捕捉尺寸变化。

示例代码:

using System.Runtime.InteropServices;

// 定义Windows API相关常量与方法
private const int WM_SIZE = 0x0005;
private const int WH_CALLWNDPROC = 4;
private static IntPtr hookId = IntPtr.Zero;
private static IntPtr targetPaneHandle;

private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private static HookProc hookProc = HookCallback;

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId);

// 用于解析消息的结构体
private struct CWPSTRUCT
{
    public IntPtr lParam;
    public IntPtr wParam;
    public uint message;
    public IntPtr hwnd;
}

// 初始化钩子(任务窗格创建后调用)
targetPaneHandle = customTaskPane.WindowHandle;
uint threadId = GetWindowThreadProcessId(targetPaneHandle, IntPtr.Zero);
hookId = SetWindowsHookEx(WH_CALLWNDPROC, hookProc, GetModuleHandle(null), threadId);

// 钩子回调逻辑
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0)
    {
        var msg = Marshal.PtrToStructure<CWPSTRUCT>(lParam);
        if (msg.message == WM_SIZE && msg.hwnd == targetPaneHandle)
        {
            // 检测到任务窗格尺寸变化,执行逻辑
        }
    }
    return CallNextHookEx(hookId, nCode, wParam, lParam);
}

// 插件卸载时移除钩子
private void ThisAddIn_Shutdown(object sender, EventArgs e)
{
    UnhookWindowsHookEx(hookId);
}

方案3:定时轮询检测高度变化

如果前两种方案适配复杂,可采用简单的定时轮询:记录任务窗格初始高度,每隔固定时间对比当前高度是否变化。

示例代码:

private int lastPaneHeight;
private System.Windows.Forms.Timer heightCheckTimer;

// 任务窗格初始化时启动定时器
var customTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(new YourUserControl(), "自定义窗格");
lastPaneHeight = customTaskPane.Height;
heightCheckTimer = new System.Windows.Forms.Timer { Interval = 100 };
heightCheckTimer.Tick += HeightCheckTimer_Tick;
heightCheckTimer.Start();

// 定时器触发逻辑
private void HeightCheckTimer_Tick(object sender, EventArgs e)
{
    var currentHeight = customTaskPane.Height;
    if (currentHeight != lastPaneHeight)
    {
        // 高度变化,执行业务逻辑
        lastPaneHeight = currentHeight;
    }
}

// 插件关闭时清理定时器
private void ThisAddIn_Shutdown(object sender, EventArgs e)
{
    heightCheckTimer?.Stop();
    heightCheckTimer?.Dispose();
}

内容的提问来源于stack exchange,提问作者Willy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:50:25