Hi,everybody!
i am trying to develop an Excel add-in using masm32
now,my xll could be loaded by Excel and perform some simple task like:
invoke XLCallVer
invoke Excel4,xlcAlert,0,1,addr xl_str ;xl_str is an address of a xltypeStr XLOPER
Here is the XLOPER structure i made according to frmwrk32(the excel sdk):
;/*
;** XLREF structure
;**
;** Describes a single rectangular reference
;*/
xlref struct
rwFirst word ?
rwLast word ?
colFirst byte ?
colLast byte ?
xlref ends
;/*
;** XLMREF structure
;**
;** Describes multiple rectangular references.
;** This is a variable size structure, default
;** size is 1 reference.
;*/
xlmref struct
count word ?
reftbl xlref <>
xlmref ends
;/*
;** XLOPER structure
;**
;** Excel's fundamental data type: can hold data
;** of any type. Use "R" as the argument type in the
;** REGISTER function.
;**/
sref_ struct
count word ?; /* always = 1 */
ref xlref <>;
sref_ ends; /* xltypeSRef */
mref_ struct
lpmref dword ?;
idSheet dword ?;
mref_ ends ;/* xltypeSRef */
array_ struct
lparray dword ?;
rows word ?;
columns word ?;
array_ ends; /* xltypeMulti */
valflow_ union
level word ?; /* xlflowRestart */
tbctrl word ?; /* xlflowPause */
idSheet dword ?; /* xlflowGoto */
valflow_ ends
flow_ struct
valflow valflow_ <>
rw word ?; /* xlflowGoto */
col byte ?; /* xlflowGoto */
xlflow byte ?;
flow_ ends; /* xltypeFlow */
h_ union
lpbData dword ?; /* data passed to XL */
hdata dword ?; /* data returned from XL */
h_ ends
bigdata_ struct
h h_ <>
cbData dword ?;
bigdata_ ends; /* xltypeBigData */
val_ union
num DOUBLE ?; /* xltypeNum */
str_ dword ?; /* xltypeStr */
bool word ?; /* xltypeBool */
err word ?; /* xltypeErr */
w word ?; /* xltypeInt */
sref sref_ <>
mref mref_ <>
array array_ <>
flow flow_ <>
bigdata bigdata_ <>
val_ ends
xloper struct
val val_ <>
xltype word ?
xloper ends
and the sdk xloper structure(C++ version):
/*
** XLREF structure
**
** Describes a single rectangular reference
*/
typedef struct xlref
{
WORD rwFirst;
WORD rwLast;
BYTE colFirst;
BYTE colLast;
} XLREF, FAR *LPXLREF;
/*
** XLMREF structure
**
** Describes multiple rectangular references.
** This is a variable size structure, default
** size is 1 reference.
*/
typedef struct xlmref
{
WORD count;
XLREF reftbl[1]; /* actually reftbl */
} XLMREF, FAR *LPXLMREF;
/*
** XLOPER structure
**
** Excel's fundamental data type: can hold data
** of any type. Use "R" as the argument type in the
** REGISTER function.
**/
typedef struct xloper
{
union
{
double num; /* xltypeNum */
LPSTR str; /* xltypeStr */
WORD bool; /* xltypeBool */
WORD err; /* xltypeErr */
short int w; /* xltypeInt */
struct
{
WORD count; /* always = 1 */
XLREF ref;
} sref; /* xltypeSRef */
struct
{
XLMREF far *lpmref;
DWORD idSheet;
} mref; /* xltypeRef */
struct
{
struct xloper far *lparray;
WORD rows;
WORD columns;
} array; /* xltypeMulti */
struct
{
union
{
short int level; /* xlflowRestart */
short int tbctrl; /* xlflowPause */
DWORD idSheet; /* xlflowGoto */
} valflow;
WORD rw; /* xlflowGoto */
BYTE col; /* xlflowGoto */
BYTE xlflow;
} flow; /* xltypeFlow */
struct
{
union
{
BYTE far *lpbData; /* data passed to XL */
HANDLE hdata; /* data returned from XL */
} h;
long cbData;
} bigdata; /* xltypeBigData */
} val;
WORD xltype;
} XLOPER, FAR *LPXLOPER;
when i was trying to use xltypeMulti XLOPER to create dialog by calling xlfDialogBox Excel function,it returned xlretInvXloper(the xloper i provided is invalid),i don't know why!
here is the code:
.data
;the null string
align 4
str_null db ' ',0
;number string
align 4
str_1 db ' 1',0
align 4
str_2 db ' 2',0
align 4
str_5 db ' 5',0
align 4
str_11 db ' 11',0
align 4
str_19 db ' 19',0
align 4
str_88 db ' 88',0
align 4
str_174 db ' 174',0
align 4
str_210 db ' 210',0
align 4
str_225 db ' 225',0
align 4
str_330 db ' 330',0
align 4
str_494 db ' 494',0
align 4
str_Name db ' Name',0
align 4
str_dl db ' Login',0
align 4
str_dlsjk db ' Database Login',0
align 4
str_qx db ' Cancel',0
;the array 7*3 rows
align 4
xa_login dword offset str_null
dword offset str_null
dword offset str_null
dword offset str_494
dword offset str_210
dword offset str_dlsjk
dword offset str_null
dword offset str_1
dword offset str_330
dword offset str_174
dword offset str_88
dword offset str_null
dword offset str_dl
dword offset str_null
dword offset str_2
dword offset str_225
dword offset str_174
dword offset str_88
dword offset str_null
dword offset str_qx
dword offset str_null
.code
;the function Fillxloper put the string array into xloper array
;px is the address of xloper array,pa is the string array
FillXloper proc uses ebx esi edi px,pa,rows
mov esi,pa
mov edi,px
assume edi:ptr xloper
.while rows>0
.if dword ptr ==offset str_null ;empty string
mov .xltype,xltypeNil
.else
mov .xltype,xltypeStr
mov eax,dword ptr
mov .val.str_,eax
.endif
add esi,4
add edi,sizeof xloper
dec rows
.endw
assume edi:nothing
ret
FillXloper endp
;here is the code to create a dialog
Login proc
local pxLoginArray:ptr,hxLoginArray:ptr
local pxLogin:ptr,hxLogin:ptr
local pxLoginRet:ptr,hxLoginRet:ptr
;allocate memory for the xloper array
invoke GlobalAlloc,GMEM_MOVEABLE,(sizeof xloper)*7*3
mov hxLoginArray,eax
invoke GlobalLock,eax
mov pxLoginArray,eax
;the xltypeMulti xloper to be passed to Excel4 function
invoke GlobalAlloc,GMEM_MOVEABLE,sizeof xloper
mov hxLogin,eax
invoke GlobalLock,eax
mov pxLogin,eax
;the return xloper to be passed to Excel4 function
invoke GlobalAlloc,GMEM_MOVEABLE,sizeof xloper
mov hxLoginRet,eax
invoke GlobalLock,eax
mov pxLoginRet,eax
;make the xloper array
invoke FillXloper,pxLoginArray,addr xa_login,7*3
;set the xltypeMulti xloper
mov eax,pxLogin
assume eax:ptr xloper
mov .xltype,xltypeMulti
push pxLoginArray
pop .val.array.lparray
mov .val.array.rows,3
mov .val.array.columns,7
assume eax:nothing
invoke Excel4,xlfDialogBox,pxLoginRet,1,pxLogin
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!this function returns xlretInvXloper!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
invoke GlobalUnlock,hxLogin
invoke GlobalFree,hxLogin
invoke GlobalUnlock,hxLoginRet
invoke GlobalFree,hxLoginRet
invoke GlobalUnlock,hxLogin
invoke GlobalFree,hxLogin
ret
Login endp
could anyone tell me where the problem is?
thanks!
i am trying to develop an Excel add-in using masm32
now,my xll could be loaded by Excel and perform some simple task like:
invoke XLCallVer
invoke Excel4,xlcAlert,0,1,addr xl_str ;xl_str is an address of a xltypeStr XLOPER
Here is the XLOPER structure i made according to frmwrk32(the excel sdk):
;/*
;** XLREF structure
;**
;** Describes a single rectangular reference
;*/
xlref struct
rwFirst word ?
rwLast word ?
colFirst byte ?
colLast byte ?
xlref ends
;/*
;** XLMREF structure
;**
;** Describes multiple rectangular references.
;** This is a variable size structure, default
;** size is 1 reference.
;*/
xlmref struct
count word ?
reftbl xlref <>
xlmref ends
;/*
;** XLOPER structure
;**
;** Excel's fundamental data type: can hold data
;** of any type. Use "R" as the argument type in the
;** REGISTER function.
;**/
sref_ struct
count word ?; /* always = 1 */
ref xlref <>;
sref_ ends; /* xltypeSRef */
mref_ struct
lpmref dword ?;
idSheet dword ?;
mref_ ends ;/* xltypeSRef */
array_ struct
lparray dword ?;
rows word ?;
columns word ?;
array_ ends; /* xltypeMulti */
valflow_ union
level word ?; /* xlflowRestart */
tbctrl word ?; /* xlflowPause */
idSheet dword ?; /* xlflowGoto */
valflow_ ends
flow_ struct
valflow valflow_ <>
rw word ?; /* xlflowGoto */
col byte ?; /* xlflowGoto */
xlflow byte ?;
flow_ ends; /* xltypeFlow */
h_ union
lpbData dword ?; /* data passed to XL */
hdata dword ?; /* data returned from XL */
h_ ends
bigdata_ struct
h h_ <>
cbData dword ?;
bigdata_ ends; /* xltypeBigData */
val_ union
num DOUBLE ?; /* xltypeNum */
str_ dword ?; /* xltypeStr */
bool word ?; /* xltypeBool */
err word ?; /* xltypeErr */
w word ?; /* xltypeInt */
sref sref_ <>
mref mref_ <>
array array_ <>
flow flow_ <>
bigdata bigdata_ <>
val_ ends
xloper struct
val val_ <>
xltype word ?
xloper ends
and the sdk xloper structure(C++ version):
/*
** XLREF structure
**
** Describes a single rectangular reference
*/
typedef struct xlref
{
WORD rwFirst;
WORD rwLast;
BYTE colFirst;
BYTE colLast;
} XLREF, FAR *LPXLREF;
/*
** XLMREF structure
**
** Describes multiple rectangular references.
** This is a variable size structure, default
** size is 1 reference.
*/
typedef struct xlmref
{
WORD count;
XLREF reftbl[1]; /* actually reftbl */
} XLMREF, FAR *LPXLMREF;
/*
** XLOPER structure
**
** Excel's fundamental data type: can hold data
** of any type. Use "R" as the argument type in the
** REGISTER function.
**/
typedef struct xloper
{
union
{
double num; /* xltypeNum */
LPSTR str; /* xltypeStr */
WORD bool; /* xltypeBool */
WORD err; /* xltypeErr */
short int w; /* xltypeInt */
struct
{
WORD count; /* always = 1 */
XLREF ref;
} sref; /* xltypeSRef */
struct
{
XLMREF far *lpmref;
DWORD idSheet;
} mref; /* xltypeRef */
struct
{
struct xloper far *lparray;
WORD rows;
WORD columns;
} array; /* xltypeMulti */
struct
{
union
{
short int level; /* xlflowRestart */
short int tbctrl; /* xlflowPause */
DWORD idSheet; /* xlflowGoto */
} valflow;
WORD rw; /* xlflowGoto */
BYTE col; /* xlflowGoto */
BYTE xlflow;
} flow; /* xltypeFlow */
struct
{
union
{
BYTE far *lpbData; /* data passed to XL */
HANDLE hdata; /* data returned from XL */
} h;
long cbData;
} bigdata; /* xltypeBigData */
} val;
WORD xltype;
} XLOPER, FAR *LPXLOPER;
when i was trying to use xltypeMulti XLOPER to create dialog by calling xlfDialogBox Excel function,it returned xlretInvXloper(the xloper i provided is invalid),i don't know why!
here is the code:
.data
;the null string
align 4
str_null db ' ',0
;number string
align 4
str_1 db ' 1',0
align 4
str_2 db ' 2',0
align 4
str_5 db ' 5',0
align 4
str_11 db ' 11',0
align 4
str_19 db ' 19',0
align 4
str_88 db ' 88',0
align 4
str_174 db ' 174',0
align 4
str_210 db ' 210',0
align 4
str_225 db ' 225',0
align 4
str_330 db ' 330',0
align 4
str_494 db ' 494',0
align 4
str_Name db ' Name',0
align 4
str_dl db ' Login',0
align 4
str_dlsjk db ' Database Login',0
align 4
str_qx db ' Cancel',0
;the array 7*3 rows
align 4
xa_login dword offset str_null
dword offset str_null
dword offset str_null
dword offset str_494
dword offset str_210
dword offset str_dlsjk
dword offset str_null
dword offset str_1
dword offset str_330
dword offset str_174
dword offset str_88
dword offset str_null
dword offset str_dl
dword offset str_null
dword offset str_2
dword offset str_225
dword offset str_174
dword offset str_88
dword offset str_null
dword offset str_qx
dword offset str_null
.code
;the function Fillxloper put the string array into xloper array
;px is the address of xloper array,pa is the string array
FillXloper proc uses ebx esi edi px,pa,rows
mov esi,pa
mov edi,px
assume edi:ptr xloper
.while rows>0
.if dword ptr ==offset str_null ;empty string
mov .xltype,xltypeNil
.else
mov .xltype,xltypeStr
mov eax,dword ptr
mov .val.str_,eax
.endif
add esi,4
add edi,sizeof xloper
dec rows
.endw
assume edi:nothing
ret
FillXloper endp
;here is the code to create a dialog
Login proc
local pxLoginArray:ptr,hxLoginArray:ptr
local pxLogin:ptr,hxLogin:ptr
local pxLoginRet:ptr,hxLoginRet:ptr
;allocate memory for the xloper array
invoke GlobalAlloc,GMEM_MOVEABLE,(sizeof xloper)*7*3
mov hxLoginArray,eax
invoke GlobalLock,eax
mov pxLoginArray,eax
;the xltypeMulti xloper to be passed to Excel4 function
invoke GlobalAlloc,GMEM_MOVEABLE,sizeof xloper
mov hxLogin,eax
invoke GlobalLock,eax
mov pxLogin,eax
;the return xloper to be passed to Excel4 function
invoke GlobalAlloc,GMEM_MOVEABLE,sizeof xloper
mov hxLoginRet,eax
invoke GlobalLock,eax
mov pxLoginRet,eax
;make the xloper array
invoke FillXloper,pxLoginArray,addr xa_login,7*3
;set the xltypeMulti xloper
mov eax,pxLogin
assume eax:ptr xloper
mov .xltype,xltypeMulti
push pxLoginArray
pop .val.array.lparray
mov .val.array.rows,3
mov .val.array.columns,7
assume eax:nothing
invoke Excel4,xlfDialogBox,pxLoginRet,1,pxLogin
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!this function returns xlretInvXloper!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
invoke GlobalUnlock,hxLogin
invoke GlobalFree,hxLogin
invoke GlobalUnlock,hxLoginRet
invoke GlobalFree,hxLoginRet
invoke GlobalUnlock,hxLogin
invoke GlobalFree,hxLogin
ret
Login endp
could anyone tell me where the problem is?
thanks!