|
Post by Walt Decker on Dec 15, 2020 16:30:01 GMT -5
How does one pass a struct as an argument
I have tried
GLOBAL Hndls STRUCT Hndls, A AS ULONG
B AS ULONG Call A
SUB A PRINT #1.txt, Hndls.A.STRUCT
and I get error undefined struct
STRUCT Hndls, _ WinMain AS ULONG, _ TxtWin AS ULONG
CALL A Hndls
and I get error not a variable
STRUCT Hndls, _ WinMain AS ULONG, _ TxtWin AS ULONG
CALL A Hndls AS STRUCT
and I get error not a variable
|
|
|
Post by Chris Iverson on Dec 15, 2020 16:36:08 GMT -5
If you mean directly into a function/sub in LB, you can't.
Structs are global special entities, like arrays, and can't be passed as parameters in LB SUBs or FUNCTIONs.
'Struct in global scope struct a, b as long a.b.struct = 12
'Call sub Call mysub print c.d.struct end
Sub mysub print a.b.struct
'New struct in sub struct c, d as long c.d.struct = 40 End Sub
There is a quirk in LB that kind of lets you do it, and passes it in as a string, but it's undocumented and undefined, and not really reliable.
Example:
'Struct in global scope struct a, b as long
a.b.struct = 12
call mysub a.struct
Sub mysub param$ b$ = param$ print len(b$)
print for x = 1 to len(b$) print asc(mid$(b$, x, 1)) next x End Sub
In fact, code that uses this "quirk" won't run at all in the debugger, and in fact, even this example will fail if you don't immediately copy the param$ variable to another string local to the function.
'Struct in global scope struct a, b as long
a.b.struct = 12
call mysub a.struct
Sub mysub param$ print len(param$)
print for x = 1 to len(param$) print asc(mid$(param$, x, 1)) next x End Sub
Really, the fact that this works at all in LB I think is down to a bug, which is actually disappointing. I would absolutely love to be able to convert a struct to a string and back as easily as assigning it like that. It would make management of multiple structs so much easier.
EDIT: Thinking about it more, the way it goes into a subroutine is a bug, but the "STRUCTNAME.struct" construction is not, as that's how you get the length of the struct for API calls that need it. So you can kind of turn a struct into a string using STRUCTNAME.struct(b$ = a.struct), but you can't go the other way(a.struct = b$ fails)
|
|
|
Post by Walt Decker on Dec 15, 2020 17:21:31 GMT -5
I must be doing something terrifically wrong because:
NOMAINWIN
STRUCT Hndls, _ WinMain AS ULONG, _ TxtWin AS ULONG
MF.BYPOSITION = HEXDEC("&H00000400") MF.GRAYED = 00000001 MF.DISABLED = 00000002
MenuHndl = 0 MnuPosn = 0 A = 0 B = 0 MnuAction = 0
WinLeftX = 300 WinLeftY = 100 WindowWidth = 300 WindowHeight = 200
TEXTEDITOR #Win.Txt, 0, 0, 300, 200 OPEN "Edit Test" FOR WINDOW AS #Win
Hndls.WinMain.Struct = HWND(#Win) Hndls.TxtWin.Struct = HWND(#Win.Txt)
OPEN "User32" FOR DLL AS #USER CALLDLL #USER, "GetMenu", Hndls.WinMain.Struct AS ULONG, MenuHndl AS ULONG CALLDLL #USER, "DeleteMenu", MenuHndl AS ULONG, 0 AS ULONG, _ MF.BYPOSITION AS ULONG, A AS LONG CALLDLL #USER, "DrawMenuBar", Hndls.WinMain.Struct AS ULONG, B AS ULONG
PRINT #Win.Txt, Hndls.WinMain.Struct PRINT #Win.Txt, Hndls.TxtWin.Struct
CALL DoLoop
CALL Aloop, Hndls.WinMain.Struct, Hndls.TxtWin.Struct
WAIT
CLOSE #Win CLOSE #USER END
'----------------------------------------------------------------------------- '-----------------------------------------------------------------------------
SUB DoLoop
PRINT #Win.Txt, Hndls.WinMain.Struct PRINT #Win.Txt, Hndls.TxtWin.Struct
END SUB
'----------------------------------------------------------------------------- '-----------------------------------------------------------------------------
SUB Aloop Mw, Tw PRINT #Win.Txt, Mw PRINT #Win.Txt, Tw END SUB
Sub DoLoop prints 0, 0 and Aloop prints the correct values.
One should be able to pass a struct to a sub/function. It can be done for API calls.
|
|
|
Post by Chris Iverson on Dec 15, 2020 17:42:51 GMT -5
You're invoking struct parameters incorrectly each time.
Names are case sensitive.
Hndls.WinMain.struct invokes the WinMain parameter of the Hndls struct.
Hndls.WinMain.Struct does NOT. It creates/access a separate variable named "Hndls.WinMain.Struct".
Find/replace, replace all ".Struct" with ".struct".
Also,
API calls are the entire reason structs exist in the first place. If there wasn't access to the API with CallDLL, they wouldn't exist at all.
They're not a first-class object/type in LB. They're glue meant to make it easier to piece data together for external code.
|
|