views:

777

answers:

2

I am writing an Excel 2007 Addin. using VS2008 and .net 3.5, C#.

I catched Microsoft.Office.Interop.Excel.Application's WindowActivate and WindowDeActivate events.

It was surprised to know that WindowActivate and Deactivate only triggers when i switch between two Excel Windows. if i switch to notepad, i expect Deactivate to be triggered, but its not happening. same way from notepad if i switch to excel window, i expect Activate to be triggered but its not happening. It looks like the behaviour indicates windows are MDI-Child windows.

Now what i want to do is get HWnd of Excel's Mainwindow and hook Window Activate and Deactivates using dllimport features.

Can anyone guide to me on this.

Regards

A: 

I have the same issue with Excel 2003. When switching between two excel windows, the event is fired. But not when switching between Excel and any other window..

Did you get a solution to this problem?

Magnus
+1  A: 

I solved similar problem when writing Excel addin. No dll import is needed. I solved this issue using System.Windows.Forms.NativeWindow class.

At first, I made my own class inherited from NativeWindow class and declared two events Activated and Deactivate in it and finaly overrided WndProc() method to rise these events when message WM_ACTIVATE is passed to the WndProc method. According to "Message" parameter WParm is Excel window activated or deactivated.

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

Then I made in my addin class field "ExcelWindow myExcelWindow" and added following code to OnConnection method of my addin:

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
}

I hope this will help you.

Michal