Author |
Topic: Gesture Input (Read 480 times) |
|
Rod
Full Member
member is offline
Gender:
Posts: 110
|
|
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 » |
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
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.
|
|
Logged
|
|
|
|
Rod
Full Member
member is offline
Gender:
Posts: 110
|
|
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
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
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.
|
|
Logged
|
|
|
|
|