In Lesson 2 we learned how to use the MoveWindow API call to relocate and resize a window or control. We can retrieve the coordinates of a window or control with GetWindowRect. This function requires a STRUCT. A STRUCT is similar to the PTR we discussed in Lesson 5 because it is a pointer to a location in memory. The similarity ends there, though.
Defining a STRUCT
A struct must be defined before it can be used. A STRUCT statement looks like this:
STRUCT StructName, firstMember as type, secondMember as type
The struct name is listed first, followed by a list of its parts, or members separated by commas. The struct may have many members, or just one member. Here is a simple struct with four members.
STRUCT RECT, left aslong, top aslong, right aslong, bottom aslong.
In an earlier lesson we said that a CALLDLL statement must be on a single line. A STRUCT statement must also be on a single line. It can be placed on multiple lines if the underscore line continuation character is used. Liberty BASIC then sees the struct statement as a single line. Here is the struct as it is typed on multiple lines:
STRUCT RECT,_
left aslong,_
top aslong,_
right aslong,_
bottom aslong.
Struct members can be the same types we used the CALLDLL statement. See Lesson 1 . Here is an example that has a PTR string member and a numeric long member.
STRUCT PERSON, name$ as PTR, age aslong
STRUCTs as Arguments
A struct is passed into a calldll statement as an argument with type "as struct". Here is a generic calldll statement that includes a struct.
STRUCT StructName, firstMember aslong secondMember asulong
CALLDLL FunctionName, handle asulong, StructName as struct, result asboolean
Assigning Values
Some API calls require the programmer to place values into struct members before the function is called. We assign values to the struct members with the equals sign. The struct members are accessed with the name of the struct, followed by a dot, then the member name, another dot, then the word STRUCT. Here is a simple example that creates a struct with a PTR member and a LONG member, then assigns values to both members.
STRUCT PERSON, name$ as PTR, age aslong
PERSON.name$.struct="John Smith"
PERSON.age.struct=45
Size of STRUCT
Some API functions that have struct arguments have an argument for the size of the struct. We can get the size of a struct with Liberty BASIC's native LEN() function with the name of the struct followed by a dot, then the word "struct" inside the parentheses, like this:
StructSize = LEN(PERSON.struct)
Note that a bug in Liberty BASIC requires the word "struct" to be in lowercase letters. If instead "STRUCT" is used with LEN() a "type mismatch" error is generated by Liberty BASIC.
Here is a code snippet to illustrate using LEN() to get the size of a struct:
STRUCT PERSON,name$ as PTR, age aslong
StructSize = len(PERSON.struct)
print "The size of the struct is ";StructSize
Retrieving Values
We retrieve values from structs in a similar way to the method used to assign values. To assign a value:
STRUCT PERSON,name$ as PTR, age aslong
PERSON.age.struct=45
To retrieve the value:
STRUCT PERSON,name$ as PTR, age aslong
PERSON.age.struct=45
ageValue = PERSON.age.struct
print "Age is "; ageValue
Getting a Window's Coordinates
We now know enough to make the GetWindowRect API call to retrieve a window's coordinates. The function requires a RECT struct, which looks like this:
STRUCT RECT,_
left aslong,_
top aslong,_
right aslong,_
bottom aslong.
The Microsoft documentation for this structure gives us this information:
Members
left
Specifies the x-coordinate of the upper-left corner of the rectangle.
top
Specifies the y-coordinate of the upper-left corner of the rectangle.
right
Specifies the x-coordinate of the lower-right corner of the rectangle.
bottom
Specifies the y-coordinate of the lower-right corner of the rectangle.
The API function looks like this:
calldll #user32, "GetWindowRect",_
hWindow asulong,_ 'window handle
RECT as struct,_ 'struct containing info
result asboolean'nonzero = success
Here is a small program that uses this function. It first sets up a RECT struct and obtains the handle of the window with Liberty BASIC's HWND() function. It then makes the GetWindowRect API call. After the function returns, the window's coordinates are contained in the struct. The program prints them in the mainwin for us to see.
open "Test Window"for window as #1
#1"trapclose [quit]"'get the window's handle
hWindow = HWND(#1)'declare a struct:
STRUCT RECT,_
left aslong,_
top aslong,_
right aslong,_
bottom aslong'retrieve window coordinates:
calldll #user32, "GetWindowRect",_
hWindow asulong,_ 'window handle
RECT as struct,_ 'struct containing info
result asboolean'nonzero = success'print coords in mainwin:
print "The left coordinate is ";RECT.left.struct
print "The top coordinate is ";RECT.top.struct
print "The right coordinate is ";RECT.right.struct
print "The bottom coordinate is ";RECT.bottom.struct
wait
[quit] close #1:end
Using Values Retrieved from Structs
The previous example printed the values in the struct. We can also assign their values to variables. If we use the struct again in another API call, the values will change. We can save the values in variables. To save the top coordinate of the window in the variable WindowTop, we do this:
WindowTop = RECT.top.struct
The values in structs can be used in any way that variables and literal values can be used. Since we know the window's coordinates, we can obtain its width and height by subtracting values. We subtract the left value from the right value to get the width. We subtract the top value from the bottom value to get the height.
'do math on retrieved values to get width and height:
width = RECT.right.struct- RECT.left.struct
height = RECT.bottom.struct- RECT.top.struct
Here it is, used in the sample program:
open "Test Window"for window as #1
#1"trapclose [quit]"'get the window's handle
hWindow = HWND(#1)'declare a struct:
STRUCT RECT,_
left aslong,_
top aslong,_
right aslong,_
bottom aslong'retrieve window coordinates:
calldll #user32, "GetWindowRect",_
hWindow asulong,_ 'window handle
RECT as struct,_ 'struct containing info
result asboolean'nonzero = success'do math on retrieved values to get width and height:
width = RECT.right.struct- RECT.left.struct
height = RECT.bottom.struct- RECT.top.struct
print "Width is ";width
print "Height is ";height
wait
[quit] close #1:end
More?
You can improve your STRUCT skills by trying these methods on other types of windows and controls. What happens if you try to obtain the coordinates of a button? A dialog window? Try it and see!
What's Next?
Lesson 7 will discuss the use of structs as pointers to numeric values.
Using Structs
Table of Contents
Defining a STRUCT
A struct must be defined before it can be used. A STRUCT statement looks like this:The struct name is listed first, followed by a list of its parts, or members separated by commas. The struct may have many members, or just one member. Here is a simple struct with four members.
In an earlier lesson we said that a CALLDLL statement must be on a single line. A STRUCT statement must also be on a single line. It can be placed on multiple lines if the underscore line continuation character is used. Liberty BASIC then sees the struct statement as a single line. Here is the struct as it is typed on multiple lines:
STRUCT RECT,_ left as long,_ top as long,_ right as long,_ bottom as long.Struct members can be the same types we used the CALLDLL statement. See Lesson 1 . Here is an example that has a PTR string member and a numeric long member.
STRUCTs as Arguments
A struct is passed into a calldll statement as an argument with type "as struct". Here is a generic calldll statement that includes a struct.Assigning Values
Some API calls require the programmer to place values into struct members before the function is called. We assign values to the struct members with the equals sign. The struct members are accessed with the name of the struct, followed by a dot, then the member name, another dot, then the word STRUCT. Here is a simple example that creates a struct with a PTR member and a LONG member, then assigns values to both members.Size of STRUCT
Some API functions that have struct arguments have an argument for the size of the struct. We can get the size of a struct with Liberty BASIC's native LEN() function with the name of the struct followed by a dot, then the word "struct" inside the parentheses, like this:Note that a bug in Liberty BASIC requires the word "struct" to be in lowercase letters. If instead "STRUCT" is used with LEN() a "type mismatch" error is generated by Liberty BASIC.
Here is a code snippet to illustrate using LEN() to get the size of a struct:
Retrieving Values
We retrieve values from structs in a similar way to the method used to assign values. To assign a value:To retrieve the value:
Getting a Window's Coordinates
We now know enough to make the GetWindowRect API call to retrieve a window's coordinates. The function requires a RECT struct, which looks like this:STRUCT RECT,_ left as long,_ top as long,_ right as long,_ bottom as long.The Microsoft documentation for this structure gives us this information:
Members
left
Specifies the x-coordinate of the upper-left corner of the rectangle.
top
Specifies the y-coordinate of the upper-left corner of the rectangle.
right
Specifies the x-coordinate of the lower-right corner of the rectangle.
bottom
Specifies the y-coordinate of the lower-right corner of the rectangle.
The API function looks like this:
Here is a small program that uses this function. It first sets up a RECT struct and obtains the handle of the window with Liberty BASIC's HWND() function. It then makes the GetWindowRect API call. After the function returns, the window's coordinates are contained in the struct. The program prints them in the mainwin for us to see.
Using Values Retrieved from Structs
The previous example printed the values in the struct. We can also assign their values to variables. If we use the struct again in another API call, the values will change. We can save the values in variables. To save the top coordinate of the window in the variable WindowTop, we do this:The values in structs can be used in any way that variables and literal values can be used. Since we know the window's coordinates, we can obtain its width and height by subtracting values. We subtract the left value from the right value to get the width. We subtract the top value from the bottom value to get the height.
Here it is, used in the sample program:
More?
You can improve your STRUCT skills by trying these methods on other types of windows and controls. What happens if you try to obtain the coordinates of a button? A dialog window? Try it and see!What's Next?
Lesson 7 will discuss the use of structs as pointers to numeric values.Written by Alyce Watson. For more on APIs, see:
APIs for Liberty BASIC