The following code is a handy keyboard and mouse interface for PBCC.
Please copy the following lines and paste it into a file 'kmiget.inc':
-----------------------------------
And the following lines mey be used to test the features of kmiget:
------------------------
Enjoy!
regards, Albert
------------------
[This message has been edited by Albert Richheimer (edited October 09, 2002).]
Please copy the following lines and paste it into a file 'kmiget.inc':
Code:
'=========================================================================== ' ' NAME ' ' KMIGET - Keyboard & Mouse Interface: Get User Input ' ' SYNOPSIS ' ' #include "kmiget.inc" ' ' wRetCode=kmiget(kmi_mode) ' ' data passed: kmi_mode %KMI_NOWT = No Wait ' %KMI_WAIT = Wait for Input ' ' data returned: wRetCode %KMI_NULL = No Input (No Wait mode only) ' %KMI_DATA = Keyboard Data ' %KMI_FUNC = Keyboard Function ' %KMI_MMOV = Mouse Move ' %KMI_MEVT = Mouse Button Event ' %KMI_KBRK = Ctrl-Break Signal ' ' DESCRIPTION ' ' Actual data is returned in the global kmi structure: ' ' Shift States: (Keyboard & Mouse Action) ' kmi.wShft Shift Word: 1 = Right Alt ' 2 = Left Alt ' 4 = Right Ctrl ' 8 = Left Ctrl ' 16 = Shift ' 32 = NumLock ' 64 = Scroll Lock ' 128 = Caps Lock ' 256 = Enhanced Key ' kmi.bShft Shift Byte: 1 = Shift, 2 = Ctrl 3 = Alt ' ' Data/Function Keys ' kmi.bData Data Byte ' kmi.bFunc Function Byte ' ' Mouse Position/Action ' kmi.wMouX Horizontal Pouse Position ' kmi.wMouY Vertical Mouse Position ' kmi.wMouE Mouse event: %KMI_MMOVE = Mouse Movement ' %KMI_MLDCK = Mouse Left Doubleclick ' %KMI_MLBPR = Mouse Left Button Press ' %KMI_MLBRE = Mouse Left Button Release ' %KMI_MRDCK = Mouse Right Doubleclick ' %KMI_MRBPR = Mouse Right Button Press ' %KMI_MRBRE = Mouse Right Button Release ' ' ' DIAGNOSTICS ' ' Alt-numeric-pad keys are returned as data bytes. Note, however, ' that kmiget behaves different depending on running Windows platform 1 ' (Win95, Win98, WinME) or running platform 2 (WinNT, W2k, XP): ' ' platform 1: 3 key strokes needed to compose a character. E.g. to ' compose the character 'A' you need to type (Alt-hold) ' '0', '6', '5' (Alt-release) ' ' platform 2: only as many key strokes as needed. E.g. to compose ' the character 'A' you to need to type (Alt-hold) ' '6', '5' (Alt-release) ' ' All composed characters are subject to modulo-256. If you type ' '8', '8', '8' kmiget will return "x" (decimal 120). ' ' '=========================================================================== DECLARE FUNCTION SetConsoleCtrlHandler LIB "KERNEL32.DLL" ALIAS _ "SetConsoleCtrlHandler" _ (BYVAL HandlerRoutine AS LONG, _ BYVAL nAdd AS LONG) AS LONG DECLARE FUNCTION GetAsyncKeyState LIB "USER32.DLL" ALIAS _ "GetAsyncKeyState" (BYVAL vKey AS LONG) AS INTEGER %VK_MENU = &H12 %VK_LMENU = &HA4 %VK_RMENU = &HA5 '--------------------------------------------------------------------------- ' ' Function Key Codes ' ------------------ %KMI_BKSP = 8 %KMI_TAB = 9 %KMI_ESC = 27 %KMI_F1 = 59 %KMI_F2 = 60 %KMI_F3 = 61 %KMI_F4 = 62 %KMI_F5 = 63 %KMI_F6 = 64 %KMI_F7 = 65 %KMI_F8 = 66 %KMI_F9 = 67 %KMI_F10 = 68 %KMI_F11 = 133 %KMI_F12 = 134 %KMI_HOME = 71 %KMI_UP = 72 %KMI_PGUP = 73 %KMI_LEFT = 75 %KMI_RGHT = 77 %KMI_END = 79 %KMI_DOWN = 80 %KMI_PGDN = 81 %KMI_INS = 82 %KMI_DEL = 83 ' ' Shift-Function ' -------------- ' %KMI_sBKSP = 120 %KMI_sTAB = 15 %KMI_sESC = 121 %KMI_sF1 = 84 %KMI_sF2 = 85 %KMI_sF3 = 86 %KMI_sF4 = 87 %KMI_sF5 = 88 %KMI_sF6 = 89 %KMI_sF7 = 90 %KMI_sF8 = 91 %KMI_sF9 = 92 %KMI_sF10 = 93 %KMI_sF11 = 135 %KMI_sF12 = 136 %KMI_sHOME = 55 %KMI_sUP = 56 %KMI_sPGUP = 57 %KMI_sLEFT = 52 %KMI_sRGHT = 54 %KMI_sEND = 49 %KMI_sDOWN = 50 %KMI_sPGDN = 51 %KMI_sINS = 48 %KMI_sDEL = 46 ' ' Ctrl-Function ' ------------- ' %KMI_cBKSP = 127 %KMI_cTAB = 148 %KMI_cESC = 170 %KMI_cF1 = 94 %KMI_cF2 = 95 %KMI_cF3 = 96 %KMI_cF4 = 97 %KMI_cF5 = 98 %KMI_cF6 = 99 %KMI_cF7 = 100 %KMI_cF8 = 101 %KMI_cF9 = 102 %KMI_cF10 = 103 %KMI_cF11 = 137 %KMI_cF12 = 138 %KMI_cHOME = 119 %KMI_cUP = 141 %KMI_cPGUP = 132 %KMI_cLEFT = 115 %KMI_cRGHT = 116 %KMI_cEND = 117 %KMI_cDOWN = 145 %KMI_cPGDN = 118 %KMI_cINS = 146 %KMI_cDEL = 147 ' ' Alt-Function ' ------------ ' %KMI_aBKSP = 14 %KMI_aA = 30 %KMI_aB = 48 %KMI_aC = 46 %KMI_aD = 32 %KMI_aE = 18 %KMI_aF = 33 %KMI_aG = 34 %KMI_aH = 35 %KMI_aI = 23 %KMI_aJ = 36 %KMI_aK = 37 %KMI_aL = 38 %KMI_aM = 50 %KMI_aN = 49 %KMI_aO = 24 %KMI_aP = 25 %KMI_aQ = 16 %KMI_aR = 19 %KMI_aS = 31 %KMI_aT = 20 %KMI_aU = 22 %KMI_aV = 47 %KMI_aW = 17 %KMI_aX = 45 %KMI_aY = 21 %KMI_aZ = 44 %KMI_aTAB = 165 %KMI_aESC = 1 %KMI_aF1 = 104 %KMI_aF2 = 105 %KMI_aF3 = 106 %KMI_aF4 = 107 %KMI_aF5 = 108 %KMI_aF6 = 109 %KMI_aF7 = 110 %KMI_aF8 = 111 %KMI_aF9 = 112 %KMI_aF10 = 113 %KMI_aF11 = 139 %KMI_aF12 = 140 %KMI_aHOME = 151 %KMI_aUP = 152 %KMI_aPGUP = 153 %KMI_aLEFT = 155 %KMI_aRGHT = 157 %KMI_aEND = 159 %KMI_aDOWN = 160 %KMI_aPGDN = 161 %KMI_aINS = 162 %KMI_aDEL = 163 '--------------------------------------------------------------------------- ' Mode Codes ' ---------- %KMI_NOWT = 0 %KMI_WAIT = 1 '--------------------------------------------------------------------------- ' Result Codes ' ------------ %KMI_NULL = 0 %KMI_DATA = 1 %KMI_FUNC = 2 %KMI_MMOV = 129 %KMI_MEVT = 130 %KMI_KBRK = 255 '--------------------------------------------------------------------------- ' Mouse Event Codes ' ----------------- %KMI_MMOVE = 1 ' Mouse Movement %KMI_MLDCK = 2 ' Mouse Left Doubleclick %KMI_MLBPR = 4 ' Mouse Left Button Press %KMI_MLBRE = 8 ' Mouse Left Button Release %KMI_MRDCK = 16 ' Mouse Right Doubleclick %KMI_MRBPR = 32 ' Mouse Right Button Press %KMI_MRBRE = 64 ' Mouse Right Button Release '--------------------------------------------------------------------------- ' ' Global kmi vars ' --------------- ' type kmiglob wShft as word bShft as byte bData as byte bFunc as byte wBkhd as word wFtim as word wMouX as word wMouY as word wMouE as word end type global kmi as kmiglob '--------------------------------------------------------------------------- ' ' Aux. kmi-Subs ' ------------- ' FUNCTION kmimevent(p3 as string) as byte dim p6 as byte dim p7 as byte dim p8 as byte p6=asc(p3,3) p7=asc(p3,4) if (p6 and 1) then p8=p8 or %KMI_MMOVE if (p6 and 2) and (p7 and 1) then p8=p8 or %KMI_MLDCK if (p6 and 4) and (p7 and 1) then p8=p8 or %KMI_MLBPR if (p6 and 8) and (p7 and 1) then p8=p8 or %KMI_MLBRE if (p6 and 2) and (p7 and 2) then p8=p8 or %KMI_MRDCK if (p6 and 4) and (p7 and 2) then p8=p8 or %KMI_MRBPR if (p6 and 8) and (p7 and 2) then p8=p8 or %KMI_MRBRE function=p8 end function function kmi_breakhandler() as long kmi.wBkhd=1 kmi_breakhandler=1 end function sub GetShiftState kmi.wShft = inshift kmi.bShft = 0 if (kmi.wShft and 16) then kmi.bShft = 1 if (kmi.wShft and 12) then kmi.bShft = 2 if (kmi.wShft and 3) then kmi.bShft = 3 end sub function ModFunc(byval bInput as byte, byval bShiftState as byte) as byte local bResult as byte modf0010: ! push eax ! push ebx ! push edx ! push esi ! xor edx,edx ! mov al,bInput ! mov dl,bShiftState ! xor esi,esi modf0110: ! cmp dword ptr modftab[esi],0 ! je modf0130 ! cmp byte ptr modftab[esi],al ! je modf0120 ! add esi,5 ! jmp modf0110 modf0120: ! add esi,edx ! inc esi ! mov al,modftab[esi] modf0130: ! mov bResult,al ! pop esi ! pop edx ! pop ebx ! pop eax function=bResult exit function modftab: ! db 008, %KMI_BKSP, %KMI_sBKSP, %KMI_cBKSP, %KMI_aBKSP ! db 009, %KMI_TAB, %KMI_sTAB, %KMI_cTAB, %KMI_aTAB ! db 015, %KMI_TAB, %KMI_sTAB, %KMI_cTAB, %KMI_aTAB ! db 027, %KMI_ESC, %KMI_sESC, %KMI_cESC, %KMI_aESC ! db 059, %KMI_F1, %KMI_sF1, %KMI_cF1, %KMI_aF1 ! db 060, %KMI_F2, %KMI_sF2, %KMI_cF2, %KMI_aF2 ! db 061, %KMI_F3, %KMI_sF3, %KMI_cF3, %KMI_aF3 ! db 062, %KMI_F4, %KMI_sF4, %KMI_cF4, %KMI_aF4 ! db 063, %KMI_F5, %KMI_sF5, %KMI_cF5, %KMI_aF5 ! db 064, %KMI_F6, %KMI_sF6, %KMI_cF6, %KMI_aF6 ! db 065, %KMI_F7, %KMI_sF7, %KMI_cF7, %KMI_aF7 ! db 066, %KMI_F8, %KMI_sF8, %KMI_cF8, %KMI_aF8 ! db 067, %KMI_F9, %KMI_sF9, %KMI_cF9, %KMI_aF9 ! db 068, %KMI_F10, %KMI_sF10, %KMI_cF10, %KMI_aF10 ! db 087, %KMI_F11, %KMI_sF11, %KMI_cF11, %KMI_aF11 ! db 088, %KMI_F12, %KMI_sF12, %KMI_cF12, %KMI_aF12 ! db 071, %KMI_HOME, %KMI_sHOME, %KMI_cHOME, %KMI_aHOME ! db 072, %KMI_UP, %KMI_sUP, %KMI_cUP, %KMI_aUP ! db 073, %KMI_PGUP, %KMI_sPGUP, %KMI_cPGUP, %KMI_aPGUP ! db 075, %KMI_LEFT, %KMI_sLEFT, %KMI_cLEFT, %KMI_aLEFT ! db 077, %KMI_RGHT, %KMI_sRGHT, %KMI_cRGHT, %KMI_aRGHT ! db 079, %KMI_END, %KMI_sEND, %KMI_cEND, %KMI_aEND ! db 080, %KMI_DOWN, %KMI_sDOWN, %KMI_cDOWN, %KMI_aDOWN ! db 081, %KMI_PGDN, %KMI_sPGDN, %KMI_cPGDN, %KMI_aPGDN ! db 082, %KMI_INS, %KMI_sINS, %KMI_cINS, %KMI_aINS ! db 083, %KMI_DEL, %KMI_sDEL, %KMI_cDEL, %KMI_aDEL ! db 127, %KMI_BKSP, %KMI_sBKSP, %KMI_cBKSP, %KMI_aBKSP ! db 240, %KMI_ESC, %KMI_sESC, %KMI_cESC, %KMI_aESC ! db 000, %KMI_NULL, %KMI_NULL, %KMI_NULL, %KMI_NULL end function '--------------------------------------------------------------------------- ' ' KMIGET - Keyboard/Mouse Interface ' --------------------------------- ' ' retcode=kmiget(kmi_mode) ' passed : kmi_mode %KMI_NOWT no wait for input ' %KMI_WAIT wait for input ' ' returns : function value ' %KMI_NULL = none ' %KMI_DATA = Data Byte (in kmi_bData) ' %KMI_FUNC = Function Key (in kmi_bFunc) ' %KMI_MMOV = Mouse Movement ' %KMI_MEVT = Mouse Event ' %KMI_KBRK = Keyboard Break (kmi_bFunc=255) ' function kmiget(kmi_mode as word) as word local sInput as string local ilInpL as long local bNumVal as byte static ilSwMen as integer static bNumPad as byte static sNumPad as string static iRAsync as integer static iLAsync as integer if kmi.wFtim=0 then SetConsoleCtrlHandler codeptr(kmi_breakhandler),1 mouse on mouse 3, double, move, down, up kmi.wFtim=1 kmi.wBkhd=0 end if while (-1) while (-1) iRAsync=getAsyncKeyState(%VK_MENU) if iRAsync<0 then iRAsync=-1 if iRAsync>-1 then iRAsync=1 if iRAsync<>iLAsync then if (iRAsync=1) and (iLAsync=-1) then if len(sNumPad) then ilSwMen=1 end if iLAsync=iRAsync end if if kmi.wBkhd then exit loop if instat then exit loop if kmi_mode=%KMI_NOWT then exit loop if ilSwMen then exit loop sleep 1 wend sInput=inkey$ ilInpL=len(sInput) select case ilInpL ' Data Length Dispatcher case 0 ' Break detect / No Wait if kmi.wBkhd then kmiget=%KMI_KBRK kmi.bFunc=%KMI_KBRK kmi.bData = 0 kmi.wBkhd = 0 bNumPad = 0 sNumPad = "" exit loop end if if ilSwMen then kmi.bData=val(sNumPad) mod 256 kmi.bFunc=0 kmiget=%KMI_DATA GetShiftState bNumPad = 0 sNumPad = "" ilSwMen = 0 exit loop end if if kmi_mode=%KMI_NOWT then kmiget=%KMI_NULL exit loop end if case 1 ' Data Byte GetShiftState kmi.bData=asc(sInput) select case kmi.bData case 8, 9, 27, 127, 240 kmi.bFunc=ModFunc(kmi.bData,kmi.bShft) kmiget=%KMI_FUNC case else kmiget=%KMI_DATA end select bNumPad = 0 sNumPad = "" exit loop case 2 ' Function Key GetShiftState kmi.bFunc=ModFunc(asc(sInput,2),kmi.bShft) bNumVal=instr(chr$(162,159,160,161,155,76,157,151,152,153), _ chr$(kmi.bFunc)) if bNumVal>0 and (kmi.wShft and 256)=0 then incr bNumPad sNumPad=sNumPad+format$(bNumVal-1,"0") if bNumPad=3 then kmi.bData=val(sNumPad) mod 256 kmi.bFunc=0 kmiget=%KMI_DATA bNumPad = 0 sNumPad = "" exit loop end if exit select end if kmiget=%KMI_FUNC bNumPad = 0 sNumPad = "" exit loop case 4 ' Mouse Movement/Event GetShiftState select case asc(sInput,3) ' Mouse Move/Event Dispatcher case 1 ' movement if mousex=kmi.wMouX and mousey=kmi.wMouY then exit select kmi.wMouX=mousex kmi.wMouY=mousey if asc(sInput,4)=1 then kmi.wMouE=%KMI_MMOVE kmiget=%KMI_MMOV exit loop case 2 ' double click kmiget=%KMI_MEVT kmi.wMouX=mousex kmi.wMouY=mousey if asc(sInput,4)=1 then kmi.wMouE=%KMI_MLDCK if asc(sInput,4)=2 then kmi.wMouE=%KMI_MRDCK kmiget=%KMI_MEVT exit loop case 4 ' button press kmiget=%KMI_MEVT kmi.wMouX=mousex kmi.wMouY=mousey if asc(sInput,4)=1 then kmi.wMouE=%KMI_MLBPR if asc(sInput,4)=2 then kmi.wMouE=%KMI_MRBPR kmiget=%KMI_MEVT exit loop case 8 ' button release kmiget=%KMI_MEVT kmi.wMouX=mousex kmi.wMouY=mousey if asc(sInput,4)=1 then kmi.wMouE=%KMI_MLBRE if asc(sInput,4)=2 then kmi.wMouE=%KMI_MRBRE kmiget=%KMI_MEVT exit loop end select if kmi_mode=%KMI_WAIT then exit select exit loop end select wend end function
And the following lines mey be used to test the features of kmiget:
Code:
#dim all #compile exe #include "kmiget.inc" function disevent(p5 as word) as string if p5=%KMI_MMOVE then disevent="Mouse move" if p5=%KMI_MLDCK then disevent="Mouse Left Doubleclick" if p5=%KMI_MLBPR then disevent="Mouse Left Button Press" if p5=%KMI_MLBRE then disevent="Mouse Left Button Release" if p5=%KMI_MRDCK then disevent="Mouse Right Doubleclick" if p5=%KMI_MRBPR then disevent="Mouse Right Button Press" if p5=%KMI_MRBRE then disevent="Mouse Right Button Release" end function function disshift() as string local p5 as string p5 = "" if (kmi.wShft and 1) then p5=p5+" Right Alt " if (kmi.wShft and 2) then p5=p5+" Left Alt " if (kmi.wShft and 4) then p5=p5+" Right Ctrl " if (kmi.wShft and 8) then p5=p5+" Left Ctrl " if (kmi.wShft and 16) then p5=p5+" Shift " if (kmi.wShft and 32) then p5=p5+" NumLock " if (kmi.wShft and 64) then p5=p5+" Scroll Lock " if (kmi.wShft and 128) then p5=p5+" Caps Lock " if (kmi.wShft and 256) then p5=p5+" Enhanced Key " disshift=p5 end function function pbmain() as long dim rc as long stdout "Type <ESC> to exit"+$CR+$LF while (-1) rc=kmiget(%KMI_NOWT) select case rc case %KMI_DATA stdout "normal key: "+str$(kmi.bData)+" "+chr$(kmi.bData)+disshift case %KMI_FUNC stdout "function key: "+str$(kmi.bFunc)+disshift if kmi.bFunc=27 then exit loop case %KMI_MMOV stdout "mouse move: "+str$(kmi.wMouX)+str$(kmi.wMouY)+disshift case %KMI_MEVT stdout "mouse event: "+str$(kmi.wMouX)+str$(kmi.wMouY)+" "+disevent(kmi.wMouE)+disshift case %KMI_KBRK stdout "Keyb Break: "+str$(kmi.bFunc) case %KMI_NULL sleep 1 end select wend end function
Enjoy!
regards, Albert
------------------
[This message has been edited by Albert Richheimer (edited October 09, 2002).]