Delphi vers asm

Signaler
Messages postés
223
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
15 février 2006
-
cricri_b34
Messages postés
223
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
15 février 2006
-
salut , J'ai un code en delphi que j'aimerais traduire en assembleur (masm32) :

var
KeyTable: array [0..255] of boolean

[....]

procedure CheckState;
var
I: integer;
begin
for I := 0 to 255 do
begin
if KeyTable[I]<>(GetAsyncKeyState(I)<>0) then
begin
if (I=1) then
begin
// souris gauche
if not KeyTable[1] then
begin
OnMouseDown()
end;
end
else
begin
// clavier
if not KeyTable[I] then
begin
OnKeyDown(I);
end;
end;
KeyTable[I] := GetAsyncKeyState(I)<>0;
end;
end;
end;

Cette procedure est executé a chaque millièmes de secondes et permet d'intercepter l'appui des touches du clavier et des boutons de la souris.
Donc j'aimerais m'en servir pour un programme en masm32. J'ai commecé a le traduire... voici le résultat :

.data
TableState db 255 dup(0)

[...]

CheckState Proc
mov ecx, 256
mov esi, offset TableState
Debut:
invoke GetAsyncKeyState, ecx
.if (eax!=0)
cmp BYTE ptr[esi+ecx], 1
je Suivant
invoke MessageBox, 0, 0, 0, 0
mov BYTE ptr[esi+ecx], 1
.else
cmp BYTE ptr[esi+ecx], 0
je Suivant
invoke MessageBox, 0, 0, 0, 0
mov BYTE ptr[esi+ecx], 0
.endif
Suivant:
loop Debut
Ret
CheckState EndP

Un MsgBox devrait apparaitre a chaque appui d'une touche mais, évidemment, ca marche pas...
Est-ce que quelqu'un pourrait m'aider?

16 réponses

Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
salut,

un truc dans le genre:

TableState db 256 dup(0) ; 0 a 255 = 256 valeures byte

CheckState PROC USES ESI
mov esi,256
@1:
dec esi ; for esi = 255 to 0
jb @3
invoke GetAsynKeyState,esi ; ecx certainement detruit lors de cet appel.
test ax,ax
setne cl ; GetAsynKeyState <> 0
cmp TableState[esi],cl ; <> TableState[I]
je @1
not TableState[esi] ; juste inversé la comparaison de I=0 et not TableState[I]
je @1
cmp esi,1
jne @2
invoke OnMouseDown
jmp @1
@2:
invoke OnKeyDown
jmp @1
@3:
ret
CheckState ENDP

@++
Messages postés
223
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
15 février 2006

ca ne marche pas... :

CheckState Proc USES ESI
mov esi, 256
@1:
dec esi
jb @3
invoke GetAsyncKeyState,esi
test ax,ax
setne cl
cmp TableState[esi],cl
je @1
not TableState[esi]
je @1
cmp esi,1
jne @2
;invoke OnMouseDown
jmp @1
@2:
invoke MessageBox, 0, 0, 0, 0
jmp @1
@3:
ret
CheckState EndP

cette proc me bombarde de MessageBox
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
re,

il te manque le "KeyTable[I] := GetAsyncKeyState(I)<>0" final

@++
Messages postés
223
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
15 février 2006

dsl, mais chui tout mêler dans ton code
jcomprend pas:
<<
test ax,ax
setne cl
cmp TableState[esi],cl
>>

et pour remplacer : KeyTable[I] := GetAsyncKeyState(I)<>0

est cque jpeux faire :

GetAsyncKeyState, esi
cmp eax, 0
je Relache
mov TableState[esi], 1
jmp FinEnregistrementEtat
Relache:
mov TableState[esi], 0
FinEnregistrementEtat :
...
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
CheckState PROC USES ESI
mov esi,256
@1:
dec esi ; for esi = 255 to 0
jb @3
invoke GetAsynKeyState,esi ; ecx certainement detruit lors de cet appel.
test ax,ax
setne cl ; GetAsynKeyState <> 0
cmp TableState[esi],cl ; <> TableState[I]
je @1
not TableState[esi] ; juste inversé la comparaison de I=0 et not TableState[I]
je @1
mov TableState[esi],cl ; voila le KeyTable[I] := GetAsyncKeyState(I)<>0 manquant
cmp esi,1
je @2 ; on inverse le test: sautera 1 fois au lieu de 255 ;-)
invoke OnKeyDown
jmp @1
@2:
invoke OnMouseDown
jmp @1
@3:
ret
CheckState ENDP

@++
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
je l'ai mal placé dans la boucle:
TableState db 257 dup(0) ; 0 a 255 = 256 valeures byte
CheckState PROC USES ESI
mov esi,256
@0:
mov TableState[esi],cl ; la premiere entrée ne compte pas d'ou TableState db 257
c'est juste pour eviter un "jmp @1" avant @0
@1:
dec esi ; for esi = 255 to 0
jb @3
invoke GetAsynKeyState,esi ; ecx certainement detruit lors de cet appel.
test ax,ax
setne cl ; GetAsynKeyState <> 0
cmp TableState[esi],cl ; <> TableState[I]
je @1
not TableState[esi] ; juste inversé la comparaison de I=0 et not TableState[I]
je @0
cmp esi,1
je @2 ; on inverse le test: sautera 1 fois au lieu de 255 ;-)
invoke OnKeyDown
jmp @0
@2:
invoke OnMouseDown
jmp @0
@3:
ret
CheckState ENDP

là je pense que ça devrait etre pas mal ...

@++
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
faudrait reflechir avant de poster mais bon ...




TableState db 256 dup(0) ; 0 a 255 = 256 valeures byte

CheckState PROC USES ESI
mov esi,256
@1:
dec esi ; for esi = 255 to 0
jb @3
invoke GetAsynKeyState,esi ; ecx certainement detruit lors de cet appel.
test ax,ax
setne cl ; GetAsynKeyState <> 0
cmp TableState[esi],cl ; <> TableState[I]
je @1
not TableState[esi] ; juste inversé la comparaison de I=1 et not TableState[I]
mov TableState[esi],cl ; il a mieux sa place là tout simplement
je @1
cmp esi,1
je @2 ; on inverse le test: sautera 1 fois au lieu de 255 ;-)
invoke OnKeyDown
jmp @1
@2:
invoke OnMouseDown
jmp @1
@3:
ret
CheckState ENDP

il me semble que c'est ça mais je peux me gourrer avec tout ces begin / end.
Messages postés
223
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
15 février 2006

non... ca marche toujours pas :

CheckState PROC USES ESI
mov esi,256
@1:
dec esi ; for esi = 255 to 0
jb @3
invoke GetAsyncKeyState,esi ; ecx certainement detruit lors de cet appel.
test ax,ax
setne cl ; GetAsynKeyState <> 0
cmp TableState[esi],cl ; <> TableState[I]
je @1
not TableState[esi] ; juste inversé la comparaison de I=1 et not TableState[I]
mov TableState[esi],cl ; il a mieux sa place là tout simplement
je @1
cmp esi,1
je @2 ; on inverse le test: sautera 1 fois au lieu de 255 ;-)
;invoke OnKeyDown
invoke MessageBox, 0, 0, 0, 0
jmp @1
@2:
;invoke OnMouseDown
jmp @1
@3:
ret
CheckState ENDP

si tu veux, j'ai le code aussi en vb :

(oups, je l'ai pas avec moi....)
Messages postés
223
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
15 février 2006

bon le voici :

Dim TableState(255) As Boolean

[...]

Private Sub Timer1_Timer()
Dim I As Integer
For I = 0 To 255
If (TableState(I) <> (GetAsyncKeyState(I) <> 0)) Then
If (GetAsyncKeyState(I) <> 0) Then
If (I <> 1) Then
MsgBox ("Une touche vient d'être appuyé!")
End If
TableState(I) = True
Else
TableState(I) = False
End If
End If
Next I
End Sub
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
16
OK mais tout ceci est obsolète hors de VB, en langage natif on met un hook système sur le clavier et oust le timer.

ciao...
http://dev.winsysdev.com
BruNews, MVP VC++
Messages postés
223
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
15 février 2006

il faut une dll pour utiliser un hook?
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
salut,

commme dit BruNews, le clavier est a la base géré par interruption, faire une lecture tout les x ms revient a supprimer cette interruption et donc a perdre un temps precieux.

par contre, les touches voulues sont celles de l'application ou celles du system ?

y'a pas de message WM_KEYDOWN / WM_KEYUP en VB ? Ca m'etonnerai vu que tout depends de l'api win32. Un hook WH_KEYBOARD ne gere que ces messages de toute façon.

un hook system requiert forcement une dll par contre, le clavier peut etre hooker uniquement pour l'application et le code peut etre dans l'exe.

cf SetWindowsHookEx,WH_KEYBOARD,KeyboardProc
@++
Messages postés
223
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
15 février 2006

ouais je c c quoi un hook, mais a ce que je sache, on est oubligé de le mettre dans une library (dll). c'est donc beaucoup plus simple d'utiliser un timer....
maitenant j'aimerais tout simplement qu'on réponde a ma question
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
un hook system requiert forcement une dll par contre, le clavier peut etre hooker uniquement pour l'application et le code peut etre dans l'exe.
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
concernant le code:
mov esi,256
@1:
dec esi ; for esi = 255 to 0
jb @3

l'operateur "dec" ne modifie pas le flag CARRY lors du passage 0->-1 mais le signe. esi devant etre limité a MAXINT=0x7FFFFFFF.

mov esi,256
@1:
dec esi ; for esi = 255 to 0
js @3

sera correct.

@++
Messages postés
223
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
15 février 2006

... marche pas :

CheckState PROC USES ESI
mov esi,256
@1:
dec esi ; for esi = 255 to 0
js @3
invoke GetAsyncKeyState,esi ; ecx certainement detruit lors de cet appel.
test ax,ax
setne cl ; GetAsynKeyState <> 0
cmp TableState[esi],cl ; <> TableState[I]
je @1
not TableState[esi] ; juste inversé la comparaison de I=1 et not TableState[I]
mov TableState[esi],cl ; il a mieux sa place là tout simplement
je @1
cmp esi,1
je @2 ; on inverse le test: sautera 1 fois au lieu de 255 ;-)
;invoke OnKeyDown
invoke MessageBox, 0, 0, 0, 0
jmp @1
@2:
;invoke OnMouseDown
jmp @1
@3:
ret
CheckState ENDP

ca me bombarde encore de msgbox