Discussion:
Capturing events with an XLL
(too old to reply)
Don H
2004-07-06 19:12:02 UTC
Permalink
Hello All,

I'm an expert VBA developer for Excel, but I'm new to C++ and building XLLs. I've learned to build an XLL that makes custom worksheet functions available in Excel, but I'm having trouble capturing events. Can anyone help me write the C++ equivalent of this VBA code in my XLL?

Public WithEvents xlApp As Application
Option Explicit
Private Sub xlApp_NewWorkbook(ByVal Wb As Workbook)
MsgBox "NewWorkbook event"
End Sub
--
Don H
Steve Dalton
2004-07-07 19:28:17 UTC
Permalink
Hi Don

Sadly, the C API doesn't provide access to all the events that VB does. The
only events that you can capture using the C API are

1. data coming in from an external DDE source
2. the user double-clicking on a cell in a worksheet
3. the user entering data into a cell in a worksheet
4. the user presses a certain key combination
5. the user or the system initiates a recalculation
6. the user selects a new worksheet window
7. the system clock reaching a specified time

The C API command functions are xlcOnData, xlcOnDoubleclick, xlcOnEntry,
xlcOnKey, xlcOnRecalc, xlcOnWindow, xlcOnTime respectively. You can find
out more about the syntax by checking the XLM macro language equivalents of
these functions.

Steve
Post by Don H
Hello All,
I'm an expert VBA developer for Excel, but I'm new to C++ and building
XLLs. I've learned to build an XLL that makes custom worksheet functions
available in Excel, but I'm having trouble capturing events. Can anyone help
me write the C++ equivalent of this VBA code in my XLL?
Post by Don H
Public WithEvents xlApp As Application
Option Explicit
Private Sub xlApp_NewWorkbook(ByVal Wb As Workbook)
MsgBox "NewWorkbook event"
End Sub
--
Don H
Steve Dalton
2004-07-08 19:48:40 UTC
Permalink
Hi Don

The answers to both questions are yes, although the ins and outs aren't
always that straightforward and there's some mixing of C API and COM which
is almost guaranteed to crash Excel. The official MS line is, perhaps
rightly, quite conservative (see KBA 301443 for example). The Excel 97 SDK
book has some limited guidance and if you look hard enough you can find a
few things on the internet and in other KBAs. (The SDK text is online on
the MS site). I might be breaking protocol to mention this, but I have a
book coming out in October which has a short section (really just an
introduction) on this subject.

Steve
Steve,
Thanks for the help. I'm glad I could confirm that, and I'll try to make
the events you've outlined work for me. I noticed all the events seem to be
exposed in OLE View. Can I make an XLL using automation that doesn't use
MFC? (Based on my reading I think the answer is yes) Also, can I combine use
of automation and the C API in the same XLL? (Again, I think this is yes).
Thanks again!
Don H
Post by Steve Dalton
Hi Don
Sadly, the C API doesn't provide access to all the events that VB does.
The
Post by Steve Dalton
only events that you can capture using the C API are
1. data coming in from an external DDE source
2. the user double-clicking on a cell in a worksheet
3. the user entering data into a cell in a worksheet
4. the user presses a certain key combination
5. the user or the system initiates a recalculation
6. the user selects a new worksheet window
7. the system clock reaching a specified time
The C API command functions are xlcOnData, xlcOnDoubleclick, xlcOnEntry,
xlcOnKey, xlcOnRecalc, xlcOnWindow, xlcOnTime respectively. You can find
out more about the syntax by checking the XLM macro language equivalents of
these functions.
Steve
Post by Don H
Hello All,
I'm an expert VBA developer for Excel, but I'm new to C++ and building
XLLs. I've learned to build an XLL that makes custom worksheet functions
available in Excel, but I'm having trouble capturing events. Can anyone help
me write the C++ equivalent of this VBA code in my XLL?
Post by Don H
Public WithEvents xlApp As Application
Option Explicit
Private Sub xlApp_NewWorkbook(ByVal Wb As Workbook)
MsgBox "NewWorkbook event"
End Sub
--
Don H
Don H
2004-07-09 19:14:02 UTC
Permalink
Thanks Steve! You just sold a book! I found it online and will definately order it (unless you can get me an advance copy:). I work for a major fixed income firm in NY and this book is perfect for me. Can't wait to get it. In the meantime, I have 2 other books on order, one of which is the SDK. I've been reading that online, but the book will have the CDROM.

I've got this code working almost perfectly. The one problem I have is that when I double click a cell in excel I get an error message that The macro 'xlCmdOnDoubleClick' cannot be found. If I'm interpreting xResult correctly after the call to xlfRegister I'm getting a stack overflow error, but I'm not sure about that. I think I might just have a simple syntax issue, but I haven't been able to resolve it. Any hints? Anyone?


__declspec(dllexport) void xlCmdOnDoubleClick(void)
{
Excel(xlcAlert, 0, 2, TempStr(" Doubleclick event"), TempInt(2));
}

__declspec(dllexport) short int xlAutoOpen(void)
{
static XLOPER xDLL;
XLOPER xResult;
int i, nSuccess;

Excel(xlcAlert, 0, 2, TempStr(" xlAutoOpen event"), TempInt(2));
Excel(xlGetName, &xDLL, 0);
for (i=0; i<rgFuncsRows; i++) {
Excel(xlfRegister, 0, 15,
(LPXLOPER) &xDLL,
(LPXLOPER) TempStr(rgFuncs[i][0]),
(LPXLOPER) TempStr(rgFuncs[i][1]),
(LPXLOPER) TempStr(rgFuncs[i][2]),
(LPXLOPER) TempStr(rgFuncs[i][3]),
(LPXLOPER) TempStr(rgFuncs[i][4]),
(LPXLOPER) TempStr(rgFuncs[i][5]),
(LPXLOPER) TempStr(rgFuncs[i][6]),
(LPXLOPER) TempStr(rgFuncs[i][7]),
(LPXLOPER) TempStr(rgFuncs[i][8]),
(LPXLOPER) TempStr(rgFuncs[i][9]),
(LPXLOPER) TempStr(rgFuncs[i][10]),
(LPXLOPER) TempStr(rgFuncs[i][11]),
(LPXLOPER) TempStr(rgFuncs[i][12]),
(LPXLOPER) TempStr(rgFuncs[i][13]));
}

//Register function for double click event
nSuccess = Excel(xlfRegister, (LPXLOPER) &xResult, 2,
TempStr(" C:\\CPP\\Don_XLLs\\xllEvents\\Debug\\xllEvents.xll"),
TempStr(" xlCmdOnDoubleClick"));
if (nSuccess != xlretSuccess) //Excel() returned an error
{Excel(xlcMessage, 0, 2, TempBool(1), TempStr(" xlAutoOpen event: DblClick assignment failed"));}

//Attach xlCmdOnDoubleClick to double click event
nSuccess = Excel(xlcOnDoubleclick, (LPXLOPER) &xResult, 2, TempMissing(), TempStr(" xlCmdOnDoubleClick"));
if (nSuccess != xlretSuccess)
{Excel(xlcMessage, 0, 2, TempBool(1), TempStr(" xlAutoOpen event: DblClick assignment failed") ); }
else
{Excel(xlcMessage, 0, 2, TempBool(1), TempStr(" xlAutoOpen event: DblClick is on") );}

return 1;
}
--
Don H
Post by Steve Dalton
Hi Don
The answers to both questions are yes, although the ins and outs aren't
always that straightforward and there's some mixing of C API and COM which
is almost guaranteed to crash Excel. The official MS line is, perhaps
rightly, quite conservative (see KBA 301443 for example). The Excel 97 SDK
book has some limited guidance and if you look hard enough you can find a
few things on the internet and in other KBAs. (The SDK text is online on
the MS site). I might be breaking protocol to mention this, but I have a
book coming out in October which has a short section (really just an
introduction) on this subject.
Steve
Steve,
Thanks for the help. I'm glad I could confirm that, and I'll try to make
the events you've outlined work for me. I noticed all the events seem to be
exposed in OLE View. Can I make an XLL using automation that doesn't use
MFC? (Based on my reading I think the answer is yes) Also, can I combine use
of automation and the C API in the same XLL? (Again, I think this is yes).
Thanks again!
Don H
Post by Steve Dalton
Hi Don
Sadly, the C API doesn't provide access to all the events that VB does.
The
Post by Steve Dalton
only events that you can capture using the C API are
1. data coming in from an external DDE source
2. the user double-clicking on a cell in a worksheet
3. the user entering data into a cell in a worksheet
4. the user presses a certain key combination
5. the user or the system initiates a recalculation
6. the user selects a new worksheet window
7. the system clock reaching a specified time
The C API command functions are xlcOnData, xlcOnDoubleclick, xlcOnEntry,
xlcOnKey, xlcOnRecalc, xlcOnWindow, xlcOnTime respectively. You can
find
Post by Steve Dalton
out more about the syntax by checking the XLM macro language equivalents
of
Post by Steve Dalton
these functions.
Steve
Post by Don H
Hello All,
I'm an expert VBA developer for Excel, but I'm new to C++ and building
XLLs. I've learned to build an XLL that makes custom worksheet functions
available in Excel, but I'm having trouble capturing events. Can anyone
help
Post by Steve Dalton
me write the C++ equivalent of this VBA code in my XLL?
Post by Don H
Public WithEvents xlApp As Application
Option Explicit
Private Sub xlApp_NewWorkbook(ByVal Wb As Workbook)
MsgBox "NewWorkbook event"
End Sub
--
Don H
Steve Dalton
2004-07-10 09:58:18 UTC
Permalink
Hi Don

At first glance you appear to have ommitted the 6th argument to xlfRegister.
If omitted, this defaults to assuming that you are registering a function,
not a command. You should try passing the value 2 explicitly. Excel seems
to be complaining that it can't find the 'command' xlCmdOnDoubleClick.
(Sorry if my quick glance has missed the real problem here).

Best regards

Steve

P.S. Very happy to hear you'll buy the book. The book won't be available in
the US till perhaps Jan 05, but I think you'll be able to ship from the UK.
Post by Don H
Thanks Steve! You just sold a book! I found it online and will definately
order it (unless you can get me an advance copy:). I work for a major fixed
income firm in NY and this book is perfect for me. Can't wait to get it. In
the meantime, I have 2 other books on order, one of which is the SDK. I've
been reading that online, but the book will have the CDROM.
Post by Don H
I've got this code working almost perfectly. The one problem I have is
that when I double click a cell in excel I get an error message that The
macro 'xlCmdOnDoubleClick' cannot be found. If I'm interpreting xResult
correctly after the call to xlfRegister I'm getting a stack overflow error,
but I'm not sure about that. I think I might just have a simple syntax
issue, but I haven't been able to resolve it. Any hints? Anyone?
Post by Don H
__declspec(dllexport) void xlCmdOnDoubleClick(void)
{
Excel(xlcAlert, 0, 2, TempStr(" Doubleclick event"), TempInt(2));
}
__declspec(dllexport) short int xlAutoOpen(void)
{
static XLOPER xDLL;
XLOPER xResult;
int i, nSuccess;
Excel(xlcAlert, 0, 2, TempStr(" xlAutoOpen event"), TempInt(2));
Excel(xlGetName, &xDLL, 0);
for (i=0; i<rgFuncsRows; i++) {
Excel(xlfRegister, 0, 15,
(LPXLOPER) &xDLL,
(LPXLOPER) TempStr(rgFuncs[i][0]),
(LPXLOPER) TempStr(rgFuncs[i][1]),
(LPXLOPER) TempStr(rgFuncs[i][2]),
(LPXLOPER) TempStr(rgFuncs[i][3]),
(LPXLOPER) TempStr(rgFuncs[i][4]),
(LPXLOPER) TempStr(rgFuncs[i][5]),
(LPXLOPER) TempStr(rgFuncs[i][6]),
(LPXLOPER) TempStr(rgFuncs[i][7]),
(LPXLOPER) TempStr(rgFuncs[i][8]),
(LPXLOPER) TempStr(rgFuncs[i][9]),
(LPXLOPER) TempStr(rgFuncs[i][10]),
(LPXLOPER) TempStr(rgFuncs[i][11]),
(LPXLOPER) TempStr(rgFuncs[i][12]),
(LPXLOPER) TempStr(rgFuncs[i][13]));
}
//Register function for double click event
nSuccess = Excel(xlfRegister, (LPXLOPER) &xResult, 2,
TempStr("
C:\\CPP\\Don_XLLs\\xllEvents\\Debug\\xllEvents.xll"),
Post by Don H
TempStr(" xlCmdOnDoubleClick"));
if (nSuccess != xlretSuccess) //Excel() returned an error
DblClick assignment failed"));}
Post by Don H
//Attach xlCmdOnDoubleClick to double click event
nSuccess = Excel(xlcOnDoubleclick, (LPXLOPER) &xResult, 2,
TempMissing(), TempStr(" xlCmdOnDoubleClick"));
Post by Don H
if (nSuccess != xlretSuccess)
DblClick assignment failed") ); }
Post by Don H
else
DblClick is on") );}
Post by Don H
return 1;
}
--
Don H
Post by Steve Dalton
Hi Don
The answers to both questions are yes, although the ins and outs aren't
always that straightforward and there's some mixing of C API and COM which
is almost guaranteed to crash Excel. The official MS line is, perhaps
rightly, quite conservative (see KBA 301443 for example). The Excel 97 SDK
book has some limited guidance and if you look hard enough you can find a
few things on the internet and in other KBAs. (The SDK text is online on
the MS site). I might be breaking protocol to mention this, but I have a
book coming out in October which has a short section (really just an
introduction) on this subject.
Steve
Steve,
Thanks for the help. I'm glad I could confirm that, and I'll try to make
the events you've outlined work for me. I noticed all the events seem to be
exposed in OLE View. Can I make an XLL using automation that doesn't use
MFC? (Based on my reading I think the answer is yes) Also, can I combine use
of automation and the C API in the same XLL? (Again, I think this is yes).
Thanks again!
Don H
Post by Steve Dalton
Hi Don
Sadly, the C API doesn't provide access to all the events that VB does.
The
Post by Steve Dalton
only events that you can capture using the C API are
1. data coming in from an external DDE source
2. the user double-clicking on a cell in a worksheet
3. the user entering data into a cell in a worksheet
4. the user presses a certain key combination
5. the user or the system initiates a recalculation
6. the user selects a new worksheet window
7. the system clock reaching a specified time
The C API command functions are xlcOnData, xlcOnDoubleclick, xlcOnEntry,
xlcOnKey, xlcOnRecalc, xlcOnWindow, xlcOnTime respectively. You can
find
Post by Steve Dalton
out more about the syntax by checking the XLM macro language equivalents
of
Post by Steve Dalton
these functions.
Steve
Post by Don H
Hello All,
I'm an expert VBA developer for Excel, but I'm new to C++ and building
XLLs. I've learned to build an XLL that makes custom worksheet functions
available in Excel, but I'm having trouble capturing events. Can anyone
help
Post by Steve Dalton
me write the C++ equivalent of this VBA code in my XLL?
Post by Don H
Public WithEvents xlApp As Application
Option Explicit
Private Sub xlApp_NewWorkbook(ByVal Wb As Workbook)
MsgBox "NewWorkbook event"
End Sub
--
Don H
Jens Thiel
2004-07-18 11:20:56 UTC
Permalink
Post by Don H
In the meantime, I have 2 other books on order, one
of which is the SDK. I've been reading that online, but
the book will have the CDROM.
The CDROM is not worth the book. The only thing the book has is a
description of the Excel 97 netive file format.


Jens.
--
http://ManagedXLL.net/
Replace MSDN with my first name when replying to my email address!
Roger
2009-07-30 16:36:02 UTC
Permalink
I discovered that this code almost worked but one change was required. The
call to setup the callback command needed to take the result of the register
function as the second argument:

// Original
nSuccess = Excel(xlcOnDoubleclick, (LPXLOPER) &xResult, 2, TempMissing(),
TempStr(" xlCmdOnDoubleClick"));

// Fix
nSuccess = Excel(xlcOnDoubleclick, (LPXLOPER) &xResult2, 2, TempMissing(),
&xResult);

Where the xResult parameter was filled in by the call to the xlfRegister
function.
Post by Don H
Thanks Steve! You just sold a book! I found it online and will definately order it (unless you can get me an advance copy:). I work for a major fixed income firm in NY and this book is perfect for me. Can't wait to get it. In the meantime, I have 2 other books on order, one of which is the SDK. I've been reading that online, but the book will have the CDROM.
I've got this code working almost perfectly. The one problem I have is that when I double click a cell in excel I get an error message that The macro 'xlCmdOnDoubleClick' cannot be found. If I'm interpreting xResult correctly after the call to xlfRegister I'm getting a stack overflow error, but I'm not sure about that. I think I might just have a simple syntax issue, but I haven't been able to resolve it. Any hints? Anyone?
__declspec(dllexport) void xlCmdOnDoubleClick(void)
{
Excel(xlcAlert, 0, 2, TempStr(" Doubleclick event"), TempInt(2));
}
__declspec(dllexport) short int xlAutoOpen(void)
{
static XLOPER xDLL;
XLOPER xResult;
int i, nSuccess;
Excel(xlcAlert, 0, 2, TempStr(" xlAutoOpen event"), TempInt(2));
Excel(xlGetName, &xDLL, 0);
for (i=0; i<rgFuncsRows; i++) {
Excel(xlfRegister, 0, 15,
(LPXLOPER) &xDLL,
(LPXLOPER) TempStr(rgFuncs[i][0]),
(LPXLOPER) TempStr(rgFuncs[i][1]),
(LPXLOPER) TempStr(rgFuncs[i][2]),
(LPXLOPER) TempStr(rgFuncs[i][3]),
(LPXLOPER) TempStr(rgFuncs[i][4]),
(LPXLOPER) TempStr(rgFuncs[i][5]),
(LPXLOPER) TempStr(rgFuncs[i][6]),
(LPXLOPER) TempStr(rgFuncs[i][7]),
(LPXLOPER) TempStr(rgFuncs[i][8]),
(LPXLOPER) TempStr(rgFuncs[i][9]),
(LPXLOPER) TempStr(rgFuncs[i][10]),
(LPXLOPER) TempStr(rgFuncs[i][11]),
(LPXLOPER) TempStr(rgFuncs[i][12]),
(LPXLOPER) TempStr(rgFuncs[i][13]));
}
//Register function for double click event
nSuccess = Excel(xlfRegister, (LPXLOPER) &xResult, 2,
TempStr(" C:\\CPP\\Don_XLLs\\xllEvents\\Debug\\xllEvents.xll"),
TempStr(" xlCmdOnDoubleClick"));
if (nSuccess != xlretSuccess) //Excel() returned an error
{Excel(xlcMessage, 0, 2, TempBool(1), TempStr(" xlAutoOpen event: DblClick assignment failed"));}
//Attach xlCmdOnDoubleClick to double click event
nSuccess = Excel(xlcOnDoubleclick, (LPXLOPER) &xResult, 2, TempMissing(), TempStr(" xlCmdOnDoubleClick"));
if (nSuccess != xlretSuccess)
{Excel(xlcMessage, 0, 2, TempBool(1), TempStr(" xlAutoOpen event: DblClick assignment failed") ); }
else
{Excel(xlcMessage, 0, 2, TempBool(1), TempStr(" xlAutoOpen event: DblClick is on") );}
return 1;
}
--
Don H
Post by Steve Dalton
Hi Don
The answers to both questions are yes, although the ins and outs aren't
always that straightforward and there's some mixing of C API and COM which
is almost guaranteed to crash Excel. The official MS line is, perhaps
rightly, quite conservative (see KBA 301443 for example). The Excel 97 SDK
book has some limited guidance and if you look hard enough you can find a
few things on the internet and in other KBAs. (The SDK text is online on
the MS site). I might be breaking protocol to mention this, but I have a
book coming out in October which has a short section (really just an
introduction) on this subject.
Steve
Steve,
Thanks for the help. I'm glad I could confirm that, and I'll try to make
the events you've outlined work for me. I noticed all the events seem to be
exposed in OLE View. Can I make an XLL using automation that doesn't use
MFC? (Based on my reading I think the answer is yes) Also, can I combine use
of automation and the C API in the same XLL? (Again, I think this is yes).
Thanks again!
Don H
Post by Steve Dalton
Hi Don
Sadly, the C API doesn't provide access to all the events that VB does.
The
Post by Steve Dalton
only events that you can capture using the C API are
1. data coming in from an external DDE source
2. the user double-clicking on a cell in a worksheet
3. the user entering data into a cell in a worksheet
4. the user presses a certain key combination
5. the user or the system initiates a recalculation
6. the user selects a new worksheet window
7. the system clock reaching a specified time
The C API command functions are xlcOnData, xlcOnDoubleclick, xlcOnEntry,
xlcOnKey, xlcOnRecalc, xlcOnWindow, xlcOnTime respectively. You can
find
Post by Steve Dalton
out more about the syntax by checking the XLM macro language equivalents
of
Post by Steve Dalton
these functions.
Steve
Post by Don H
Hello All,
I'm an expert VBA developer for Excel, but I'm new to C++ and building
XLLs. I've learned to build an XLL that makes custom worksheet functions
available in Excel, but I'm having trouble capturing events. Can anyone
help
Post by Steve Dalton
me write the C++ equivalent of this VBA code in my XLL?
Post by Don H
Public WithEvents xlApp As Application
Option Explicit
Private Sub xlApp_NewWorkbook(ByVal Wb As Workbook)
MsgBox "NewWorkbook event"
End Sub
--
Don H
Jens Thiel
2004-07-18 11:24:24 UTC
Permalink
Thanks for the help. I'm glad I could confirm that, and I'll try to make
the events you've outlined work for me. I noticed all the events seem to be
exposed in OLE View. Can I make an XLL using automation that doesn't use
MFC? (Based on my reading I think the answer is yes) Also, can I combine use
of automation and the C API in the same XLL? (Again, I think this is yes).

Don,

a "hybrid" XLL add-in using both the C and the automation interfaces is
possible, but you have to keep an eye on threading issues if you do not want
to get GPFs.

Jens.
--
http://ManagedXLL.net/
Replace MSDN with my first name when replying to my email address!
Don H
2004-07-20 13:08:02 UTC
Permalink
Jens,

Thanks for the info. I'll keep that in mind as I go. Also, thanks for the tip on the CDROM. You were right. Good thing I got the book used:)
--
Don H
Post by Steve Dalton
Thanks for the help. I'm glad I could confirm that, and I'll try to make
the events you've outlined work for me. I noticed all the events seem to be
exposed in OLE View. Can I make an XLL using automation that doesn't use
MFC? (Based on my reading I think the answer is yes) Also, can I combine use
of automation and the C API in the same XLL? (Again, I think this is yes).
Don,
a "hybrid" XLL add-in using both the C and the automation interfaces is
possible, but you have to keep an eye on threading issues if you do not want
to get GPFs.
Jens.
--
http://ManagedXLL.net/
Replace MSDN with my first name when replying to my email address!
Loading...