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!
Posted on 2006-02-17 19:59:22 by JinYang