C#:Excel 2007 Addin,如何挂钩Windows激活和取消激活事件

use*_*490 2 hook vba add-in dllimport excel-vba

我正在编写Excel 2007 Addin.使用VS2008和.net 3.5,C#.

我抓住了Microsoft.Office.Interop.Excel.Application的WindowActivate和WindowDeActivate事件.

令人惊讶的是,当我在两个Excel Windows之间切换时,WindowActivate和Deactivate仅触发.如果我切换到记事本,我希望触发Deactivate,但它没有发生.如果我切换到excel窗口,记事本的方式相同,我希望触发Activate但它没有发生.看起来行为表明窗口是MDI-Child窗口.

现在我要做的是获取Excel的Mainwindow的HWnd并使用dllimport功能挂钩Window Activate和Deactivates.

谁能指导我这个.

问候

Mic*_*hal 6

我在编写Excel插件时解决了类似的问题.不需要dll导入.我使用System.Windows.Forms.NativeWindow类解决了这个问题.

首先,我创建了自己的继承自NativeWindow类的类,并在其中声明了两个事件Activated和Deactivate,最后重写了WndProc()方法,以便在将消息WM_ACTIVATE传递给WndProc方法时引发这些事件.根据"消息"参数,WParm是Excel窗口激活或停用.

 public class ExcelWindow: NativeWindow
{
    public const int WM_ACTIVATED = 0x0006;

    public ExcelWindow():base(){}

    //events
    public event EventHandler Activated;
    public event EventHandler Deactivate;

    //catching windows messages
    protected override void WndProc(ref Message m)
    {
        if (m.Msg== WM_ACTIVATED)
        {
            if (m.WParam.ToInt32() == 1)
            {
                //raise activated event
                if (Activated!=null)
                {
                     Activated(this, new EventArgs());
                }
            }
            else if (m.WParam.ToInt32() == 0)
            {
                //raise deactivated event
                if (Deactivate!=null)
                {
                     Deactivate(this, new EventArgs());
                }
            }
        }
        base.WndProc(ref m);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我在我的addin类字段"ExcelWindow myExcelWindow"中添加了以下代码并添加到我的插件的OnConnection方法:

ExcelWindow myExcelWindow;
void Extensibility.IDTExtensibility2.OnConnection(object application, Extensibility.ext_ConnectMode ConnectMode, object AddInInst, ref Array custom)
{
    excel = application as Excel.Application;
    myExcelWindow = new ExcelWindow();
    myExcelWindow.AssignHandle(new IntPtr(excel.Hwnd));
    myExcelWindow.Activated += new EventHandler(myExcelWindow_Activated);
    myExcelWindow.Deactivate += new EventHandler(myExcelWindow_Deactivate);

    //addin code here

}

void myExcelWindow_Activated(object sender, EventArgs e)
{
    //do some stuff here
}
void myExcelWindow_Deactivate(object sender, EventArgs e)
{
    //do some stuff here
}
Run Code Online (Sandbox Code Playgroud)

我希望这能帮到您.