A structure is nothing more than a series of bytes. The trick is to know how much bytes...
For this you need to look at what the structures must contain:
(U)INT means an (unsigned) integer, this is 2 bytes long (also known as a WORD).
(actually these types in the WINDOWPLACEMENT structure are defined as UINTs, which are unsigned integers; there's a difference between INT - signed integers, and UINT - unsigned integers)
a POINT and a RECT are structures on their own, they are as long as the individual types used in the structure:
However a POINT structure is:
POINT {
LONG x;
LONG y;
}
Thus they are LONGs, not INTs. Since a LONG is 4 bytes (also known as a double word or DWORD) that makes this substructure 8 bytes in total. A RECT structure is defined as:
RECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
}
thus that makes the RECT structure 16 bytes long.
If we add all this up we come to 3 INTs, 2 POINTs, 1 REC or 3 INTs, 8 LONGs or 38 bytes...
So we need to allocate 38 bytes with the Interop.Allocate function to create this particular datablock (aka structure).
code:
Var WINDOWPLACEMENT = Interop.Allocate(38);
Once we have that we either can use the pointer to this allocated memory as a place for the API to store the complete structure, or either we can start to fill the structure on our own with the needed stuff:
code:
WINDOWPLACEMENT.WriteWORD(0, WINDOWPLACEMENT.Size); // UINT length
WINDOWPLACEMENT.WriteWORD(2, flags); // UINT flags
WINDOWPLACEMENT.WriteWORD(4, showCmd); // UINT showCmd
WINDOWPLACEMENT.WriteDWORD(6, minx); // LONG ptMinPosition_x
WINDOWPLACEMENT.WriteDWORD(10, miny); // LONG ptMinPosition_y
WINDOWPLACEMENT.WriteDWORD(14, maxx); // LONG ptMaxPosition_x
WINDOWPLACEMENT.WriteDWORD(18, maxy); // LONG ptMaxPosition_y
WINDOWPLACEMENT.WriteDWORD(22, left); // LONG rcNormalPosition_left
WINDOWPLACEMENT.WriteDWORD(26, top); // LONG rcNormalPosition_top
WINDOWPLACEMENT.WriteDWORD(30, right); // LONG rcNormalPosition_right
WINDOWPLACEMENT.WriteDWORD(34, bottom); // LONG rcNormalPosition_bottom
Notice the byte positions at which we write the values of the variables (datablocks start at byte position 0, just as arrays, character positions, etc, not 1. Don't mess this up or your structure will be wrong and unexpected stuff might happen.
Reading the structure works in the same way (after it has been filled by the API of course):
code:
var flags = WINDOWPLACEMENT.ReadWORD(2); // UINT flags
To use the structure in an API call:
code:
Interop.Call('user32.dll', 'GetWindowPlacement', hWnd, WINDOWPLACEMENT.DataPtr);
-------------
Note that the above code can be made shorter:
code:
with (WINDOWPLACEMENT) {
WriteWORD(0, Size); // UINT length
WriteWORD(2, flags); // UINT flags
WriteWORD(4, showCmd); // UINT showCmd
etc...
}
use the 'with' statement...
and:
code:
Interop.Call('user32.dll', 'GetWindowPlacement', hWnd, WINDOWPLACEMENT);
DataPtr is the default method when you pass a datablock to the Call method.