LB Booster
« Gesture Input »

Welcome Guest. Please Login or Register.
Apr 1st, 2018, 04:57am



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
We apologize Conforums does not have any export functions to migrate data.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

Thank you Conforums members.
Speed up Liberty BASIC programs by up to ten times!
Compile Liberty BASIC programs to compact, standalone executables!
Overcome many of Liberty BASIC's bugs and limitations!
LB Booster Resources
LB Booster documentation
LB Booster Home Page
LB Booster technical Wiki
Just BASIC forum
BBC BASIC Home Page
Liberty BASIC forum (the original)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Gesture Input  (Read 481 times)
Rod
Full Member
ImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 110
xx Gesture Input
« Thread started on: Apr 17th, 2016, 6:48pm »

Blitting not working, tried bringwindowtotop but no success.

Code:

    'nomainwin
    global WM.GESTURE, imgX, imgY, imgScale, imgWidth, imgHeight, scrWidth, scrHeight, hWnd,sDC,mDC,hPic
    global panning, zooming, panX,panY,startX,startY,startZ,deltaZ
    WM.GESTURE = 281

    'a struct for the xy points
    Struct pt, x As long, y As long

    'a struct for the gestureinfo data
    Struct gi, cbSize       As ulong, _
               dwFlags      As ulong, _
               dwID         As ulong, _
               hwndTarget   As ulong, _
               x            As short, _
               y            As short, _
               dwInstanceID As ulong, _
               dwSequenceID As ulong, _
               ullArgHi     As ulong, _
               ullArgLow    As ulong, _
               cbExtraArgs  As ulong, _
               a            As ulong,_
               b as ulong

    'the size of the structure is
    gi.cbSize.struct = Len(gi.struct)


    'get the image file to display
    filedialog "Choose an image","*.jpg;*.png;*.tiff;*.ico;*.bmp;*.gif",file$
    if file$="" then
        call quit "No File"
    else
        hPic=LoadImgFromFile(file$)
        if hPic<>0 then
            loadbmp "pic",hPic
        else
            notice "Could not load the image file!"
        end if
    end if


    'get the image size
    'Struct necessary for returning image file information
    Struct ImageInfo, _
        imgType as Long, _
        imgWidth as Long, _
        imgHeight as Long, _
        imgWidthBytes as Long, _
        imgPlanes as Word, _
        imgBitsPixel as Word, _
        imgBits as Long
    lStruct = Len(ImageInfo.struct)
    CallDLL #gdi32, "GetObjectA", _
        hPic as uLong, _
        lStruct as Long, _
        ImageInfo as struct, _
        result as Long
    imgWidth = ImageInfo.imgWidth.struct
    imgHeight = ImageInfo.imgHeight.struct
    imgScale=1
    scrWidth=600
    scrHeight=400
    imgX=(scrWidth-imgWidth)/2
    imgY=(scrHeight-imgHeight)/2


    Open "WMLiberty" For DLL As #wmlib
    WindowWidth = 800
    WindowHeight = 600
    graphicbox #w.gb,100,100,scrWidth,scrHeight
    Open "Gesture demo" For graphics_nf_nsb As #w
    hWnd = hwnd(#w.gb)


    calldll #user32, "BringWindowToTop", hWnd as ulong, r as long
    #w "trapclose quit"
    #w.gb "down; fill black"

    ' sDC is our screen, (DC handle to the graphicsbox)
    sDC=GetDC(hWnd)


    ' mDC is a copy of the screen in memory
    mDC=CreateCompatibleDC(sDC)

    'select the pic into the DC
    oldBmp=SelectObject(mDC,hPic)

    'draw it from memory to screen
    call StretchBlt,sDC,int(imgX*imgScale),int(imgY*imgScale),int(imgWidth*imgScale),int(imgHeight*imgScale),mDC,0,0,imgWidth,imgHeight


    ' set up callback to receive touch messages
    callback lpwmgesture, wmgesture(ulong, ulong, ulong, ulong), long
    calldll #wmlib, "SetWMHandler",_
        hWnd        As ulong, _
        WM.GESTURE  As ulong, _
        lpwmgesture As ulong, _
        1           As long, _
        ret         As long


    ' now scan for messages
    [wait] ' Must use a Scan loop.
    Scan
    CallDLL #kernel32, "Sleep",_
        50  As Long,_
        ret As Void
    GoTo [wait]



Sub quit h$
    Close #w
    Close #wmlib
    End
End Sub

Function wmgesture(hw, msg, wparam, lparam)
    'print hw,msg,wparam,lparam
    CallDLL #user32, "GetGestureInfo",_
        lparam   As ulong, _
        gi       As struct,_
        ret      As long
    pt.x.struct = gi.x.struct
    pt.y.struct = gi.y.struct
    CallDLL #user32, "ScreenToClient",_
        hw   As ulong, _
        pt   As struct, _
        ret  As long

    select case wparam
        case 1  'GID_BEGIN
            'print "Gesture begins"
        case 2  'GID_ENDS
            'print "Gesture ends"
            if panning then
                imgX=imgX+panX
                imgY=imgY+panY
                panX=0
                panY=0
                panning=0
            end if
            if zooming then
                imgScale=imgScale+deltaZ
                deltaZ=0
                zooming=0
                imgX=imgX+panX
                imgY=imgY+panY
                panX=0
                panY=0
            end if
        case 3  'GID_ZOOM
            'print "Zooming"
            if zooming then
                deltaZ=gi.ullArgLow.struct/100-startZ
                panX=0-deltaZ*10
                panY=0-deltaZ*10
                if imgWidth*(imgScale+deltaZ)<scrWidth then imgScale=scrWidth/imgWidth : deltaZ=0 :imgX=0
                if imgHeight*(imgScale+deltaZ)<scrHeight then imgScale=scrHeight/imgHeight : deltaZ=0 : imgY=0
            else
                zooming=1
                startZ=gi.ullArgLow.struct/100
            end if

        case 4  'GID_PAN
            if panning then
                panX=pt.x.struct-startX
                panY=pt.y.struct-startY
                if imgX+panX >0 then imgX=0 : panX=0
                if imgX+panX <scrWidth-imgWidth then imgX=scrWidth-imgWidth : panX=0
                if imgY+panY >0 then imgY=0 : panY=0
                if imgY+panY <scrHeight-imgHeight then imgY=scrHeight-imgHeight : panY=0
            else
                panning=1
                startX=pt.x.struct
                startY=pt.y.struct
            end if

        case 5  'GID_ROTATE
            print "Rotating"
        case 6  'GID_TWOFINGURETAP
            'print "Two fingure tap"
            imgScale=scrWidth/imgWidth
            panning=0
            panX=0
            panY=0
            zooming=0
            deltaZ=0
            imgX=0
            imgY=0
        case 7  'GID_PRESSANDTAP
            'print "Press and tap"
    end select
    x=int((imgX+panX)*(imgScale+deltaZ))
    y=int((imgY+panY)*(imgScale+deltaZ))
    w=int(imgWidth*(imgScale+deltaZ))
    h=int(imgHeight*(imgScale+deltaZ))
    call StretchBlt,sDC,x,y,w,h,mDC,0,0,imgWidth,imgHeight
    'forward start and end messages to window
    if wparam=1 or wparam=2 then
        CallDll #user32, "DefWindowProcA",_
            hw       As ulong,_
            msg      As ulong,_
            wparam   As ulong,_
            lparam   As ulong,_
            ret      As long
    else
        CallDLL #user32, "CloseGestureInfoHandle",_
            lparam   As ulong, _
            ret      As long
    end if

End Function


'=============================Load image functions=================================
function wchar$(string$)
    for i = 1 to len(string$)
        wchar$=wchar$+mid$(string$,i,1)+chr$(0)
    next i
    wchar$=wchar$+chr$(0)+chr$(0)
end function

function LoadImgFromFile(file$)
    open "gdiplus.dll" for dll as #gdip
    struct dword,a as ulong
    gdistart$=chr$(1)
    for i = 1 to 15
        gdistart$=gdistart$+chr$(0)
    next i
    calldll #gdip,"GdiplusStartup",_
        dword as struct,_
        gdistart$ as ptr,_
        status as ulong
    token=dword.a.struct
    if status<>0 then
        LoadImgFromFile=0
    else
        wFileLoc$=wchar$(file$)
        calldll #gdip,"GdipCreateBitmapFromFile",_
            wFileLoc$ as ptr,_
            dword as struct,_
            status as ulong
        hPic=dword.a.struct
        if status<>0 then
            LoadImgFromFile=0
        else
            calldll #gdip,"GdipCreateHBITMAPFromBitmap",_
                hPic as ulong,_
                dword as struct,_
                0 as ulong,_
                status as ulong
            hBmp=dword.a.struct
            if status<>0 then
                LoadImgFromFile=0
            else
                LoadImgFromFile=hBmp
            end if
            calldll #gdip,"GdipDisposeImage",_
                hPic as ulong,_
                ret as ulong
        end if
        calldll #gdip,"GdiplusShutdown",_
            token as ulong,_
            ret as ulong
    end if
    close #gdip
end function

'=============================Window and DC functions=================================
Function GetDC(hWnd)
    CallDLL #user32, "GetDC",_
        hWnd As ulong,_  'window or control handle
        GetDC As ulong   'returns device context
    End Function

Sub ReleaseDC hWnd, hDC
    CallDLL#user32,"ReleaseDC",_
        hWnd As ulong,_  'window or control handle
        hDC As ulong,_   'handle of DC to delete
        result As Long
    End Sub

Function CreateCompatibleDC(hDC)
    CallDLL #gdi32,"CreateCompatibleDC",_
        hDC As ulong,_               'window DC
        CreateCompatibleDC As ulong  'memory DC
    End Function

Sub DeleteDC hDC
    CallDLL #gdi32, "DeleteDC",_
    hDC As ulong,_   'memory DC to delete
    r As Boolean
    End Sub

Sub StretchBlt hDCdest,x,y,w,h,hDCsrc,x2,y2,w2,h2
    CallDLL #gdi32, "SetStretchBltMode",_
        hDCdest As ulong,_       'device context
        _COLORONCOLOR As Long,_ 'color reduction mode
        RESULT As Long
    CallDLL #gdi32, "StretchBlt",_
        hDCdest As ulong,_   'destination
        x As Long,_         'destination x pos
        y As Long,_         'destination y pos
        w As Long,_         'destination width desired
        h As Long,_         'destination height desired
        hDCsrc As ulong,_    'source
        x2 As Long,_        'x location to start from source
        y2 As Long,_        'y location to start from source
        w2 As Long,_        'width desired from source
        h2 As Long,_        'height desired from source
        _SRCCOPY As long,_ 'dwRasterOperation
        RESULT As Boolean
    End Sub


Function SelectObject(hDC,hObject)
    CallDLL #gdi32,"SelectObject",_
        hDC As ulong,_        'memory device context
        hObject As long,_    'handle of object
        SelectObject As long 'returns previously selected object
    End Function
 
« Last Edit: Apr 17th, 2016, 6:49pm by Rod » User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Gesture Input
« Reply #1 on: Apr 17th, 2016, 9:07pm »

on Apr 17th, 2016, 6:48pm, Rod wrote:
Blitting not working, tried bringwindowtotop but no success.

Add a call to InvalidateRect immediately after both your StretchBlts. This notifies Windows that you've updated the bitmap and need it to be re-blitted to the screen:

Code:
    calldll #user32, "InvalidateRect", hWnd as ulong, 0 as long, _
        0 as long, ret as void 

Also, shortening the Sleep will improve the responsiveness tremendously:

Code:
    [wait] ' Must use a Scan loop.
    Scan
    CallDLL #kernel32, "Sleep",_
        1  As Long,_
        ret As Void
    GoTo [wait] 

Richard.
User IP Logged

Rod
Full Member
ImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 110
xx Re: Gesture Input
« Reply #2 on: Apr 18th, 2016, 08:09am »

Thanks, strangely the invalidateRect call needs to act on sDC in Liberty but needs hWnd in LBB.

Code:
'nomainwin
    global WM.GESTURE, imgX, imgY, imgScale, imgWidth, imgHeight, scrWidth, scrHeight, hWnd,sDC,mDC,hPic
    global panning, zooming, panX,panY,startX,startY,startZ,deltaZ
    WM.GESTURE = 281

    'a struct for the xy points
    Struct pt, x As long, y As long

    'a struct for the gestureinfo data
    Struct gi, cbSize       As ulong, _
               dwFlags      As ulong, _
               dwID         As ulong, _
               hwndTarget   As ulong, _
               x            As short, _
               y            As short, _
               dwInstanceID As ulong, _
               dwSequenceID As ulong, _
               ullArgHi     As ulong, _
               ullArgLow    As ulong, _
               cbExtraArgs  As ulong, _
               a            As ulong,_
               b as ulong

    'the size of the structure is
    gi.cbSize.struct = Len(gi.struct)


    'get the image file to display
    filedialog "Choose an image","*.jpg;*.png;*.tiff;*.ico;*.bmp;*.gif",file$
    if file$="" then
        call quit "No File"
    else
        hPic=LoadImgFromFile(file$)
        if hPic<>0 then
            loadbmp "pic",hPic
        else
            notice "Could not load the image file!"
        end if
    end if


    'get the image size
    'Struct necessary for returning image file information
    Struct ImageInfo, _
        imgType as Long, _
        imgWidth as Long, _
        imgHeight as Long, _
        imgWidthBytes as Long, _
        imgPlanes as Word, _
        imgBitsPixel as Word, _
        imgBits as Long
    lStruct = Len(ImageInfo.struct)
    CallDLL #gdi32, "GetObjectA", _
        hPic as uLong, _
        lStruct as Long, _
        ImageInfo as struct, _
        result as Long
    imgWidth = ImageInfo.imgWidth.struct
    imgHeight = ImageInfo.imgHeight.struct
    imgScale=1
    scrWidth=600
    scrHeight=400
    imgX=(scrWidth-imgWidth)/2
    imgY=(scrHeight-imgHeight)/2


    Open "WMLiberty" For DLL As #wmlib
    WindowWidth = 800
    WindowHeight = 600
    graphicbox #w.gb,100,100,scrWidth,scrHeight
    Open "Gesture demo" For graphics_nf_nsb As #w
    hWnd = hwnd(#w.gb)


    calldll #user32, "BringWindowToTop", hWnd as ulong, r as long
    #w "trapclose quit"
    #w.gb "down; fill black"

    ' sDC is our screen, (DC handle to the graphicsbox)
    sDC=GetDC(hWnd)


    ' mDC is a copy of the screen in memory
    mDC=CreateCompatibleDC(sDC)

    'select the pic into the DC
    oldBmp=SelectObject(mDC,hPic)

    'draw it from memory to screen
    call StretchBlt,sDC,int(imgX*imgScale),int(imgY*imgScale),int(imgWidth*imgScale),int(imgHeight*imgScale),mDC,0,0,imgWidth,imgHeight
    calldll #user32, "InvalidateRect",_
        hWnd as ulong,_
        0 as long,_
        0 as long,_
        ret as void

    ' set up callback to receive touch messages
    callback lpwmgesture, wmgesture(ulong, ulong, ulong, ulong), long
    calldll #wmlib, "SetWMHandler",_
        hWnd        As ulong, _
        WM.GESTURE  As ulong, _
        lpwmgesture As ulong, _
        1           As long, _
        ret         As long


    ' now scan for messages
    [wait] ' Must use a Scan loop.
    Scan
    CallDLL #kernel32, "Sleep",_
        1  As Long,_
        ret As Void
    GoTo [wait]



Sub quit h$
    Close #w
    Close #wmlib
    End
End Sub

Function wmgesture(hw, msg, wparam, lparam)
    'print hw,msg,wparam,lparam
    CallDLL #user32, "GetGestureInfo",_
        lparam   As ulong, _
        gi       As struct,_
        ret      As long
    pt.x.struct = gi.x.struct
    pt.y.struct = gi.y.struct
    CallDLL #user32, "ScreenToClient",_
        hw   As ulong, _
        pt   As struct, _
        ret  As long

    select case wparam
        case 1  'GID_BEGIN
            'print "Gesture begins"
        case 2  'GID_ENDS
            'print "Gesture ends"
            if panning then
                imgX=imgX+panX
                imgY=imgY+panY
                panX=0
                panY=0
                panning=0
            end if
            if zooming then
                imgScale=imgScale+deltaZ
                deltaZ=0
                zooming=0
                imgX=imgX+panX
                imgY=imgY+panY
                panX=0
                panY=0
            end if
        case 3  'GID_ZOOM
            'print "Zooming"
            if zooming then
                deltaZ=gi.ullArgLow.struct/100-startZ
                panX=0-deltaZ*10
                panY=0-deltaZ*10
                if imgWidth*(imgScale+deltaZ)<scrWidth then imgScale=scrWidth/imgWidth : deltaZ=0 :imgX=0
                if imgHeight*(imgScale+deltaZ)<scrHeight then imgScale=scrHeight/imgHeight : deltaZ=0 : imgY=0
            else
                zooming=1
                startZ=gi.ullArgLow.struct/100
            end if

        case 4  'GID_PAN
            if panning then
                panX=pt.x.struct-startX
                panY=pt.y.struct-startY
                if imgX+panX >0 then imgX=0 : panX=0
                if imgX+panX <scrWidth-imgWidth then imgX=scrWidth-imgWidth : panX=0
                if imgY+panY >0 then imgY=0 : panY=0
                if imgY+panY <scrHeight-imgHeight then imgY=scrHeight-imgHeight : panY=0
            else
                panning=1
                startX=pt.x.struct
                startY=pt.y.struct
            end if

        case 5  'GID_ROTATE
            print "Rotating"
        case 6  'GID_TWOFINGURETAP
            'print "Two fingure tap"
            imgScale=scrWidth/imgWidth
            panning=0
            panX=0
            panY=0
            zooming=0
            deltaZ=0
            imgX=0
            imgY=0
        case 7  'GID_PRESSANDTAP
            'print "Press and tap"
    end select
    x=int((imgX+panX)*(imgScale+deltaZ))
    y=int((imgY+panY)*(imgScale+deltaZ))
    w=int(imgWidth*(imgScale+deltaZ))
    h=int(imgHeight*(imgScale+deltaZ))
    call StretchBlt,sDC,x,y,w,h,mDC,0,0,imgWidth,imgHeight
    calldll #user32, "InvalidateRect",_
        hWnd as ulong,_
        0 as long,_
        0 as long,_
        ret as void

    'forward start and end messages to window
    if wparam=1 or wparam=2 then
        CallDll #user32, "DefWindowProcA",_
            hw       As ulong,_
            msg      As ulong,_
            wparam   As ulong,_
            lparam   As ulong,_
            ret      As long
    else
        CallDLL #user32, "CloseGestureInfoHandle",_
            lparam   As ulong, _
            ret      As long
    end if

End Function


'=============================Load image functions=================================
function wchar$(string$)
    for i = 1 to len(string$)
        wchar$=wchar$+mid$(string$,i,1)+chr$(0)
    next i
    wchar$=wchar$+chr$(0)+chr$(0)
end function

function LoadImgFromFile(file$)
    open "gdiplus.dll" for dll as #gdip
    struct dword,a as ulong
    gdistart$=chr$(1)
    for i = 1 to 15
        gdistart$=gdistart$+chr$(0)
    next i
    calldll #gdip,"GdiplusStartup",_
        dword as struct,_
        gdistart$ as ptr,_
        status as ulong
    token=dword.a.struct
    if status<>0 then
        LoadImgFromFile=0
    else
        wFileLoc$=wchar$(file$)
        calldll #gdip,"GdipCreateBitmapFromFile",_
            wFileLoc$ as ptr,_
            dword as struct,_
            status as ulong
        hPic=dword.a.struct
        if status<>0 then
            LoadImgFromFile=0
        else
            calldll #gdip,"GdipCreateHBITMAPFromBitmap",_
                hPic as ulong,_
                dword as struct,_
                0 as ulong,_
                status as ulong
            hBmp=dword.a.struct
            if status<>0 then
                LoadImgFromFile=0
            else
                LoadImgFromFile=hBmp
            end if
            calldll #gdip,"GdipDisposeImage",_
                hPic as ulong,_
                ret as ulong
        end if
        calldll #gdip,"GdiplusShutdown",_
            token as ulong,_
            ret as ulong
    end if
    close #gdip
end function

'=============================Window and DC functions=================================
Function GetDC(hWnd)
    CallDLL #user32, "GetDC",_
        hWnd As ulong,_  'window or control handle
        GetDC As ulong   'returns device context
    End Function

Sub ReleaseDC hWnd, hDC
    CallDLL#user32,"ReleaseDC",_
        hWnd As ulong,_  'window or control handle
        hDC As ulong,_   'handle of DC to delete
        result As Long
    End Sub

Function CreateCompatibleDC(hDC)
    CallDLL #gdi32,"CreateCompatibleDC",_
        hDC As ulong,_               'window DC
        CreateCompatibleDC As ulong  'memory DC
    End Function

Sub DeleteDC hDC
    CallDLL #gdi32, "DeleteDC",_
    hDC As ulong,_   'memory DC to delete
    r As Boolean
    End Sub

Sub StretchBlt hDCdest,x,y,w,h,hDCsrc,x2,y2,w2,h2
    CallDLL #gdi32, "SetStretchBltMode",_
        hDCdest As ulong,_       'device context
        _COLORONCOLOR As Long,_ 'color reduction mode
        RESULT As Long
    CallDLL #gdi32, "StretchBlt",_
        hDCdest As ulong,_   'destination
        x As Long,_         'destination x pos
        y As Long,_         'destination y pos
        w As Long,_         'destination width desired
        h As Long,_         'destination height desired
        hDCsrc As ulong,_    'source
        x2 As Long,_        'x location to start from source
        y2 As Long,_        'y location to start from source
        w2 As Long,_        'width desired from source
        h2 As Long,_        'height desired from source
        _SRCCOPY As long,_ 'dwRasterOperation
        RESULT As Boolean
    End Sub


Function SelectObject(hDC,hObject)
    CallDLL #gdi32,"SelectObject",_
        hDC As ulong,_        'memory device context
        hObject As long,_    'handle of object
        SelectObject As long 'returns previously selected object
    End Function
 
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Gesture Input
« Reply #3 on: Apr 18th, 2016, 10:34am »

on Apr 18th, 2016, 08:09am, Rod wrote:
Thanks, strangely the invalidateRect call needs to act on sDC in Liberty but needs hWnd in LBB.

LB 4 draws directly to the screen, hence graphics not 'sticking'. LBB is double-buffered and draws to an offscreen bitmap. That makes graphics 'stick' automatically, but necessarily it implies an additional step of blitting from the offscreen bitmap to the screen.

With native graphics statements this happens automatically, but if you draw things using API calls you must tell Windows to do that additional blitting step, hence the need for InvalidateRect.

I wouldn't have expected the presence of that to upset LB 4, but if it does you can make it conditional using the code listed in the LBB help docs:

Code:
    if instr(Platform$, "LBB") then
      calldll #user32, "InvalidateRect", hWnd as ulong, 0 as long, _
          0 as long, ret as void
    end if 

Richard.
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls