The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Need a trigger from Excel on activating a workbook

We are running an Excel workbook straight from our app using WithEvents. 

The two (our app and the Excel workbook) should be linked in the user's mind.  I need to find whenever this workbook gets focus (say, after reading JoelOnSoftware).  When the workbook gets focus, I want to bring our app to second place on the desktop.

There is a workbook_activate event but it seems to be triggered only when switching between workbooks in one Excel instance.
Any ideas?
Bankstrong Send private email
Tuesday, April 26, 2005
There is a Window Activate event in the Application object events ...

A quick google came up with this ...

Robert French Send private email
Tuesday, April 26, 2005
Robert -

Thank you - the link is great.

However, you need to be in Excel to trigger these events.  That's one case I want to trap; the other is when you are outside Excel and you click on the workbook.  I don't believe this triggers an event.

Bankstrong Send private email
Tuesday, April 26, 2005
Hi Mike,

Marcus again. From what we discussed in the other thread I can't think a clean solution that is contained completely within your App or Excel. However, what if you use a middle man - a separate utility app which gets loaded on startup and 'watches' to see when the Excel App is loaded, receives focus, losses focus etc. As Excel exposes a Hwnd, this shouldn't be too painful to achive. If you can get the utilty app to determine which is the active workbook then your job is almost done - send a message to your main app to do whatever it needs to do.

If you can't get the active workbooks win handle or determine if it is one of your workbooks, then utilse the Excel add-in functionality I mentioned in the other thread. When the Workbook_Activate or Workbook_Dectivate event is fired, record the status somewhere your app can pick it up.

So you're now using two mechanisms: the first simply to detect whether Excel has focus: Yes or No. The second should answer the question: "The last time Excel did have focus, was one of my spreadsheets the active workbooks?".
So if Excel was too get focus again, if your workbook was active then, it should still be active now.

Any thoughts?
Marcus from Melbourne
Tuesday, April 26, 2005

Some of the Excel events seem worthless, don't they (i.e., they never seem to trigger).

One way you can do this is by getting a handle to the Excel window at startup.  Then using a timer in your app, poll the GetForegroundWindow Win32 API function to check the handle of the active window versus the Excel window handle.
Cowboy coder
Wednesday, April 27, 2005
Marcus, Cowboy -

That's exactly what I was looking for - someone to confirm that I wasn't ignoring the easy way and that I need to mess with api.

Next question: I plan to experiment with combinations of what you guys have suggested.  I'd rather not constantly run code in my app (to say poll every .5 seconds), but I don't want to wait too long to sense the change either. 

What happens in VB if the program is busy and an event is raised (obviously, I don't have a great comprehension of threading)?  I ask because I wonder if there's a big difference in taking advantage of a separate app as Marcus suggests.

Bankstrong Send private email
Wednesday, April 27, 2005
Since Windows (and VB) uses a cooperative tasking model, I would guess the event could not be generated by the second app unless VB had done a 'DoEvents' to give the Windows run-time a chance to run.

Coming out of the 'DoEvents', if the second app had generated an event for the VB program, the VB program's event handler would now run, in the VB program's context.

This means you can't really "interrupt" the VB program like you could a micro-processor with an external interrupt signal.  What you can do is get the VB program to 'allow' (through DoEvents) some other task the chance to send it a message -- which then will be read by the VB program next time it gets a chance to run.
Wednesday, April 27, 2005
AllanL5 -

Thank you - that's exactly what I needed to round out my knowledge in this area.

Bankstrong Send private email
Friday, April 29, 2005

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz