Older Version Newer Version

RodBird RodBird Nov 25, 2015

=Stefan's Advanced Polygon API Demos= 
//[[user:StPendl]]//
[[toc|flat]]
----
=Array of Structures= 
Currently there are two ways to handle an array of structures.

1) using direct memory access. This is the regular way, but involves using API functions.

[[code format="lb"]]
    'draw_polygon.bas
    'Author: Stefan Pendl
    'Date: 30.01.06
    '
    ' draw polygon thru user defined points
    ' minimum number of points is 3
    '
    ' left mouse button to set ponts
    ' right mouse button to daw poly

    nomainwin

    polyDrawn = 0
    ptSize = 4
    ptColor$ = "red"
    polySize = 1
    polyColor$ = "black"
    fillColor$ = "green"
    polyFillColor$ = "blue"

    gbWidth = 300
    gbHeight = 300

    if gbWidth > DisplayWidth - 30 then gbWidth = DisplayWidth - 30
    if gbHeight > DisplayHeight - 90 then gbHeight = DisplayHeight - 90

    WindowWidth = gbWidth + 30
    WindowHeight = gbHeight + 90

    UpperLeftX = int((DisplayWidth-WindowWidth)/2)
    UpperLeftY = int((DisplayHeight-WindowHeight)/2)

    graphicbox #1.gb, 10, 10, gbWidth, gbHeight
    button #1.draw, "Draw Poly", [drawPoly], ul, 10, gbHeight + 20, 60, 20
    stylebits #1.ptnum, _SS_RIGHT, 0, 0, 0
    statictext #1.ptnum, "0", 80, gbHeight + 20, 15, 15
    statictext #1.pt, "Points selected", 100, gbHeight + 20, 100, 15

    statictext #1.ptx, "X:", 200, gbHeight + 20, 10, 15
    stylebits #1.ptxpos, _SS_RIGHT, 0, 0, 0
    statictext #1.ptxpos, "000", 215, gbHeight + 20, 20, 15

    statictext #1.pty, "Y:", 200, gbHeight + 40, 10, 15
    stylebits #1.ptypos, _SS_RIGHT, 0, 0, 0
    statictext #1.ptypos, "000", 215, gbHeight + 40, 20, 15
    open "Polygon" for window_nf as #1
    #1 "trapclose [quit]"
    #1.draw "!disable"
    #1.gb "down;fill ";fillColor$;";flush"
    #1.gb "size "; ptSize
    #1.gb "color "; ptColor$
    #1.gb "backcolor "; polyFillColor$
    #1.gb "when mouseMove [updatePos]"
    #1.gb "when leftButtonUp [drawPoint]"
    #1.gb "when rightButtonUp [drawPoly]"
    h=hwnd(#1.gb) 'window handle

    'get device context for window:
    calldll #user32, "GetDC",_
        h   as ulong,_
        hdc as ulong

    cursor crosshair
    wait

[updatePos]
    #1.ptxpos MouseX
    #1.ptypos MouseY
    wait

[drawPoint]
    if polyDrawn = 1 then
        #1.gb "cls;fill "; fillColor$; ";flush blank"
        polyDrawn = 0
        Points$ = ""
        ptNum = 0
    end if

    Points$ = Points$; MouseX; " "; MouseY; " "

    #1.gb "set "; MouseX; " "; MouseY

    ptNum = ptNum + 1
    #1.ptnum ptNum

    if ptNum = 3 then #1.draw "!enable"
    wait

[drawPoly]
    if ptNum < 3 then wait

    #1.draw "!disable"
    #1.gb "size "; polySize
    #1.gb "color "; polyColor$

    STRUCT PolyPoints,_
        x as long,_
        y as long

    PolyPointsLen = len(PolyPoints.struct)

    cbBuf = PolyPointsLen * ptNum

    uFlags = _LMEM_MOVEABLE or _LMEM_ZEROINIT

    CallDll #kernel32, "LocalAlloc", _
        uFlags  as ulong, _
        cbBuf   as ulong, _
        hMem    as ulong

    CallDll #kernel32, "LocalLock", _
        hMem            as ulong, _
        PolyPointsArray as ulong

    BufferPointer = PolyPointsArray

    'The STRUCT must be filled before it can be used in an api call:
    for count = 1 to ptNum * 2 step 2
        PolyPoints.x.struct = val(word$(Points$, count))
        PolyPoints.y.struct = val(word$(Points$, count + 1))

        calldll #kernel32, "RtlMoveMemory", _
            BufferPointer as ulong, _
            PolyPoints    as struct,_
            PolyPointsLen as ulong, _
            result        as void

        BufferPointer = BufferPointer + PolyPointsLen
    next

    calldll #gdi32, "Polygon",_
        hdc             as ulong,_    'device context of window or control
        PolyPointsArray as ulong,_    'memory address of array of points
        ptNum           as ulong,_     'number of x,y pairs in array
        result          as long

    #1.gb "getbmp pix 0 0 ";gbWidth; " "; gbHeight
    #1.gb "delsegment Polygon;drawbmp pix 0 0;flush Polygon"
    #1.gb "size "; ptSize
    #1.gb "color "; ptColor$
    polyDrawn = 1

    ' free PolyPointsArray memory
    calldll #kernel32, "LocalFree", _
        hMem   as ulong, _
        result as ulong
    wait

[quit]
    calldll #user32, "ReleaseDC",_
        h   as ulong,_
        hdc as ulong,_
        ret as long

    close #1
    end

[[code]]

=String Hack= 
This one is based on an easter egg of LB, where a structure is basically handled like a string, since you use the LEN() function to get the size of the structure in LB.

[[code format="lb"]]
    'draw_poly.bas
    'Author: Stefan Pendl
    'Date: 08.07.08
    '
    ' draw polygon thru user defined points
    ' minimum number of points is 3
    '
    ' left mouse button to set ponts
    ' right mouse button to daw poly

    nomainwin

    polyDrawn = 0
    ptSize = 4
    ptColor$ = "red"
    polySize = 1
    polyColor$ = "black"
    fillColor$ = "green"
    polyFillColor$ = "blue"

    gbWidth = 300
    gbHeight = 300

    if gbWidth > DisplayWidth - 30 then gbWidth = DisplayWidth - 30
    if gbHeight > DisplayHeight - 90 then gbHeight = DisplayHeight - 90

    WindowWidth = gbWidth + 30
    WindowHeight = gbHeight + 90

    UpperLeftX = int((DisplayWidth-WindowWidth)/2)
    UpperLeftY = int((DisplayHeight-WindowHeight)/2)

    graphicbox #1.gb, 10, 10, gbWidth, gbHeight
    button #1.draw, "Draw Poly", [drawPoly], ul, 10, gbHeight + 20, 60, 20
    stylebits #1.ptnum, _SS_RIGHT, 0, 0, 0
    statictext #1.ptnum, "0", 80, gbHeight + 20, 15, 15
    statictext #1.pt, "Points selected", 100, gbHeight + 20, 100, 15

    statictext #1.ptx, "X:", 200, gbHeight + 20, 10, 15
    stylebits #1.ptxpos, _SS_RIGHT, 0, 0, 0
    statictext #1.ptxpos, "000", 215, gbHeight + 20, 20, 15

    statictext #1.pty, "Y:", 200, gbHeight + 40, 10, 15
    stylebits #1.ptypos, _SS_RIGHT, 0, 0, 0
    statictext #1.ptypos, "000", 215, gbHeight + 40, 20, 15
    open "Polygon" for window_nf as #1
    #1 "trapclose [quit]"
    #1.draw "!disable"
    #1.gb "down;fill ";fillColor$;";flush"
    #1.gb "size "; ptSize
    #1.gb "color "; ptColor$
    #1.gb "backcolor "; polyFillColor$
    #1.gb "when mouseMove [updatePos]"
    #1.gb "when leftButtonUp [drawPoint]"
    #1.gb "when rightButtonUp [drawPoly]"
    h=hwnd(#1.gb) 'window handle

    'get device context for window:
    calldll #user32, "GetDC",_
        h   as ulong,_
        hdc as ulong

    cursor crosshair
    wait

[updatePos]
    #1.ptxpos MouseX
    #1.ptypos MouseY
    wait

[drawPoint]
    if polyDrawn = 1 then
        #1.gb "cls;fill "; fillColor$; ";flush blank"
        polyDrawn = 0
        Points$ = ""
        ptNum = 0
    end if

    Points$ = Points$; MouseX; " "; MouseY; " "

    #1.gb "set "; MouseX; " "; MouseY

    ptNum = ptNum + 1
    #1.ptnum ptNum

    if ptNum = 3 then #1.draw "!enable"
    wait

[drawPoly]
    if ptNum < 3 then wait

    #1.draw "!disable"
    #1.gb "size "; polySize
    #1.gb "color "; polyColor$

    STRUCT PolyPoints,_
        x as long,_
        y as long

    PolyPointsArray$ = ""

    'The STRUCT must be filled before it can be used in an api call:
    for count = 1 to ptNum * 2 step 2
        PolyPoints.x.struct = val(word$(Points$, count))
        PolyPoints.y.struct = val(word$(Points$, count + 1))

        PolyPointsArray$ = PolyPointsArray$; PolyPoints.struct
    next

    calldll #gdi32, "Polygon",_
        hdc              as ulong,_    'device context of window or control
        PolyPointsArray$ as ptr,_    'memory address of array of points
        ptNum            as ulong,_     'number of x,y pairs in array
        result           as long

    #1.gb "getbmp pix 0 0 ";gbWidth; " "; gbHeight
    #1.gb "delsegment Polygon;drawbmp pix 0 0;flush Polygon"
    #1.gb "size "; ptSize
    #1.gb "color "; ptColor$
    polyDrawn = 1

    wait

[quit]
    calldll #user32, "ReleaseDC",_
        h   as ulong,_
        hdc as ulong,_
        ret as long

    close #1
    end
[[code]]

----
[[toc|flat]]