点击鼠标一次重复多次 TASM
Clicking mouse once repeats it many times TASM
我正在处理一个使用鼠标的程序集项目(TASM 和 DOSBox)。
当用户点击屏幕上的某个区域时,会打印出某条消息。
我的问题是,只要按下鼠标按钮(每次单击 3 或 4 次),计算机就会继续打印消息。
我尝试保存最后按下的按钮,并在同一按钮被连续按下两次时阻止打印消息,如下面的代码所示,但它似乎不起作用。我也知道有一种方法可以获取按钮 release 信息,但我似乎也无法让它工作。
有人知道我可以做些什么来解决这个问题或用不同的方法吗?谢谢
IDEAL
MODEL small
STACK 0f500h
mouse_last_button dw 1 ;holds the value of last mouse button clicked
mouse_button dw 0 ;holds the value of mouse button clicked
counter dw ?
x_clicked dw ?
y_clicked dw ?
half_button dw 9
arr_length dw 76
clear_x dw 229
clear_y dw 137
CODESEG
;================PROCEDURES================
proc setGraphic
;sets graphic mode
mov ax, 13h
int 10h
ret
endp setGraphic
;-----------------
proc initMouse
;initializes mouse
mov ax, 0
int 33h ;resets mouse
mov ax, 1
int 33h ;shows pointer
ret
endp initMouse
;-----------------
proc initImage
;imports keyboard bitmap
mov [BmpLeft],0
mov [BmpTop],99
mov [BmpColSize], 320
mov [BmpRowSize] ,101
mov dx,offset SmallPicName
call OpenShowBmp
ret
endp initImage
;-----------------
proc getMouseClick
mov ax, [mouse_button] ;stores the value of the last state of the mouse
mov [mouse_last_button], ax
mov ax,3
int 33h ;gets mouse information
shr cx, 1 ;halves the x position value since the interrupt returns double
mov [mouse_button],bx ;saves the click's button, x and y position
mov [x_clicked],cx
mov [y_clicked],dx
ret
endp getMouseClick
;-----------------
proc checkMouseButton
ret
endp checkMouseButton
;-----------------
proc checkXR
;check if click is not more than 9 pixels right to the center (of the button)
mov bx, offset x_arr
add bx,[counter]
mov ax,[bx]
add ax,[half_button]
ret
endp checkXR
;-----------------
proc checkXL
;check if click is not more than 9 pixels left to the center
mov ax,[bx]
sub ax,[half_button]
ret
endp checkXL
;-----------------
proc checkYT
;check if click is not more than 9 pixels above the center
mov bx, offset y_arr
add bx,[counter]
mov ax,[bx]
sub ax,[half_button]
ret
endp checkYT
;-----------------
proc checkYB
;check if click is not more than 9 pixels below the center
mov ax,[bx]
add ax,[half_button]
ret
endp checkYB
;-----------------
proc printLetter
;prints the character at button that was clicked
mov bx, offset letter_arr
mov ax,[counter]
shr ax,1 ;halves counter since letter_arr is byte sized and counter is word sized
add bx,ax
mov dx, [bx]
mov ah, 2
int 21h
ret
endp printLetter
;-----------------
;================PROCEDURES================
start:
mov ax,@data
mov ds,ax
call setGraphic ;sets graphic mode
call initMouse ;initializes mouse
call initImage ;displays keyboard's image
mov cx, [arr_length] ;iterates over all of the buttons in the keyboard until one matches a click's location
mov [counter],cx
mouseLoop:
call getMouseClick
mov ax, [mouse_button] ;waits for the user to click left mouse button
cmp ax, 1
jne doLoop
cmp ax,[mouse_last_button] ;if button pressed before is the same as the current one, wait for another press
je mouseLoop
call checkXR ;checks X right
cmp [x_clicked],ax
ja searchAgain
call checkXL ;checks X left
cmp [x_clicked],ax
jb searchAgain
call checkYT ;checks Y top
cmp [y_clicked],ax
jb searchAgain
call checkYB ;checks Y bottom
cmp [y_clicked],ax
jb writeLetter
searchAgain:
;precedes to the next button in the array
mov cx,[counter]
dec [counter]
cmp cx,0
jnz mouseLoop
jmp doLoop
writeLetter:
call printLetter ;prints the letter found
call initImage ;restarts the keyboard image
mov ax, 1
int 33h ;shows pointer
doLoop:
;starts iterating over arrays again
mov cx,[arr_length]
mov [counter],cx
jmp mouseLoop
exit:
mov ax, 4c00h
int 21h
END start
还有一点要提:当我设置
cmp ax,[mouse_last_button]
jne mouseLoop
到je
(实际上应该如此),什么也没有发生。
我找到了解决办法。
我删除了:
cmp ax,[mouse_last_button]
je mouseLoop
并添加:
waitForRelease:
call getMouseClick
mov ax,[mouse_button]
cmp ax,0
jne waitForRelease
在 writeLetter
之后进入等待用户释放鼠标按钮的循环,然后继续。
我正在处理一个使用鼠标的程序集项目(TASM 和 DOSBox)。 当用户点击屏幕上的某个区域时,会打印出某条消息。
我的问题是,只要按下鼠标按钮(每次单击 3 或 4 次),计算机就会继续打印消息。
我尝试保存最后按下的按钮,并在同一按钮被连续按下两次时阻止打印消息,如下面的代码所示,但它似乎不起作用。我也知道有一种方法可以获取按钮 release 信息,但我似乎也无法让它工作。
有人知道我可以做些什么来解决这个问题或用不同的方法吗?谢谢
IDEAL
MODEL small
STACK 0f500h
mouse_last_button dw 1 ;holds the value of last mouse button clicked
mouse_button dw 0 ;holds the value of mouse button clicked
counter dw ?
x_clicked dw ?
y_clicked dw ?
half_button dw 9
arr_length dw 76
clear_x dw 229
clear_y dw 137
CODESEG
;================PROCEDURES================
proc setGraphic
;sets graphic mode
mov ax, 13h
int 10h
ret
endp setGraphic
;-----------------
proc initMouse
;initializes mouse
mov ax, 0
int 33h ;resets mouse
mov ax, 1
int 33h ;shows pointer
ret
endp initMouse
;-----------------
proc initImage
;imports keyboard bitmap
mov [BmpLeft],0
mov [BmpTop],99
mov [BmpColSize], 320
mov [BmpRowSize] ,101
mov dx,offset SmallPicName
call OpenShowBmp
ret
endp initImage
;-----------------
proc getMouseClick
mov ax, [mouse_button] ;stores the value of the last state of the mouse
mov [mouse_last_button], ax
mov ax,3
int 33h ;gets mouse information
shr cx, 1 ;halves the x position value since the interrupt returns double
mov [mouse_button],bx ;saves the click's button, x and y position
mov [x_clicked],cx
mov [y_clicked],dx
ret
endp getMouseClick
;-----------------
proc checkMouseButton
ret
endp checkMouseButton
;-----------------
proc checkXR
;check if click is not more than 9 pixels right to the center (of the button)
mov bx, offset x_arr
add bx,[counter]
mov ax,[bx]
add ax,[half_button]
ret
endp checkXR
;-----------------
proc checkXL
;check if click is not more than 9 pixels left to the center
mov ax,[bx]
sub ax,[half_button]
ret
endp checkXL
;-----------------
proc checkYT
;check if click is not more than 9 pixels above the center
mov bx, offset y_arr
add bx,[counter]
mov ax,[bx]
sub ax,[half_button]
ret
endp checkYT
;-----------------
proc checkYB
;check if click is not more than 9 pixels below the center
mov ax,[bx]
add ax,[half_button]
ret
endp checkYB
;-----------------
proc printLetter
;prints the character at button that was clicked
mov bx, offset letter_arr
mov ax,[counter]
shr ax,1 ;halves counter since letter_arr is byte sized and counter is word sized
add bx,ax
mov dx, [bx]
mov ah, 2
int 21h
ret
endp printLetter
;-----------------
;================PROCEDURES================
start:
mov ax,@data
mov ds,ax
call setGraphic ;sets graphic mode
call initMouse ;initializes mouse
call initImage ;displays keyboard's image
mov cx, [arr_length] ;iterates over all of the buttons in the keyboard until one matches a click's location
mov [counter],cx
mouseLoop:
call getMouseClick
mov ax, [mouse_button] ;waits for the user to click left mouse button
cmp ax, 1
jne doLoop
cmp ax,[mouse_last_button] ;if button pressed before is the same as the current one, wait for another press
je mouseLoop
call checkXR ;checks X right
cmp [x_clicked],ax
ja searchAgain
call checkXL ;checks X left
cmp [x_clicked],ax
jb searchAgain
call checkYT ;checks Y top
cmp [y_clicked],ax
jb searchAgain
call checkYB ;checks Y bottom
cmp [y_clicked],ax
jb writeLetter
searchAgain:
;precedes to the next button in the array
mov cx,[counter]
dec [counter]
cmp cx,0
jnz mouseLoop
jmp doLoop
writeLetter:
call printLetter ;prints the letter found
call initImage ;restarts the keyboard image
mov ax, 1
int 33h ;shows pointer
doLoop:
;starts iterating over arrays again
mov cx,[arr_length]
mov [counter],cx
jmp mouseLoop
exit:
mov ax, 4c00h
int 21h
END start
还有一点要提:当我设置
cmp ax,[mouse_last_button]
jne mouseLoop
到je
(实际上应该如此),什么也没有发生。
我找到了解决办法。 我删除了:
cmp ax,[mouse_last_button]
je mouseLoop
并添加:
waitForRelease:
call getMouseClick
mov ax,[mouse_button]
cmp ax,0
jne waitForRelease
在 writeLetter
之后进入等待用户释放鼠标按钮的循环,然后继续。