TASM程序中如何检测鼠标右键的点击与释放操作
TASM程序右键切换颜色功能修复
问题描述
我编写了一个TASM简易绘图程序,需求是:
- 左键按住移动时绘制像素
- 实时显示鼠标光标坐标
- 右键点击切换绘图颜色
但当前程序存在问题:按住右键会连续跳过多个颜色,尝试添加右键点击/释放检测逻辑后,右键操作要么导致程序崩溃,要么仅绘制1个像素,要么无任何响应。
原代码
.model small .stack 256 .data .386 stat db ? col dw ? row dw ? color db 3 flag db 1 rezult db '000$' mult10 db 10 mesx db 'x =$' mesy db 'y =$' mes_er db 'мышь не установлена',13,10,'$' mes db 'пpогpамма завеpшена',13,10,'$' mask_m dw 16 dup(0ffffh) dw 07c0h,0c60h,1830h,3018h dw 6ccch,6ccch,600ch,600ch dw 644ch,3398h,1860h,0c60h dw 07c0h,0000h,0000h,0000h .code cursor_on proc near mov ax,01 int 33h ret cursor_on endp cursor_off proc near mov ax,2 int 33h ret cursor_off endp mouse_stat proc near mov ax,3 int 33h ret mouse_stat endp pixel proc near call cursor_off mov ah,0Ch mov al,color mov bh,0 int 10h call cursor_on ret pixel endp speed proc near mov ax,000fh mov cx,64 mov dx,64 int 33h mov ax,0013h mov dx,64 int 33h ret speed endp text_curc proc near mov ax,000AH mov bx,01 int 33h ret text_curc endp write proc near mov bx,3 cicle: idiv mult10 add ah,30h mov [si+bx-1],ah mov ah,0 dec bx jnz cicle mov ah,09 mov dx,offset rezult int 21h ret write endp go: mov ax,@data mov ds,ax mov ax,0 int 33h cmp ax,0 jne ner jmp er ner: mov ax,10h int 10h mov ax,9 xor bx,bx xor cx,cx push ds pop es lea dx,mask_m int 33h call speed call cursor_on call mouse_stat mov col,cx mov row,dx mov ah,02 mov bh,00 mov dx,0000h int 10h mov ah,9 lea dx,mesx int 21h mov ah,02 mov bh,00 mov dx,0009h int 10h mov ah,9 lea dx,mesy int 21h next: mov ah,02 mov bh,00 mov dx,0004h int 10h mov ax,col lea si,rezult call write mov ah,02 mov bh,0 mov dx,000Dh int 10h mov ax,row call write mov dx,row mov cx,col mov ah,1 int 16h jz nosym mov ah,0 int 16h cmp al,27 je ex mov ah,1 int 16h cmp al,32 je nextc nosym: mov flag,0 call mouse_stat mov stat,bl cmp col,cx je rov_lab mov col, cx mov flag ,1 rov_lab: cmp row,dx je pix mov row ,dx mov flag,1 pix: mov bl,stat and bl,2 cmp bl,2 ;je nextc is what was in the original program instead of 'je check' je check mov bl,stat and bl,1 cmp bl,1 jne next cmp flag,0 je next call pixel jmp next check: ; tried to write it myself but it doesn't work the way it needs to mov ax, 06h mov bx, 01h int 33h cmp ax, 02h je nextc ex: call cursor_off lea dx,mes jmp exit nextc: inc color jmp next er: lea dx,mes_er exit: mov ax,3 int 10h mov ah,9 int 21h mov ax,4c00h int 21h End go
问题分析
- 右键检测逻辑错误:原代码使用
int 33h ax=6读取鼠标事件缓冲区,但错误判断ax值(ax返回的是缓冲区中事件数量,不是按键类型),且未正确处理缓冲区残留事件,导致程序状态混乱。 - 连续触发切换:原逻辑在右键按住时会反复执行颜色切换,导致跳过多个颜色。
- 鼠标状态时序问题:调用鼠标事件读取后未更新当前鼠标状态,导致后续绘图逻辑异常。
修复方案
修改右键检测逻辑,改为检测右键按下后等待释放,确保每次点击只切换一次颜色,同时正确处理鼠标事件缓冲区:
; 替换原pix到check的代码段 pix: mov bl,stat and bl,2 cmp bl,2 je handle_right_click ; 左键绘图逻辑保留 mov bl,stat and bl,1 cmp bl,1 jne next cmp flag,0 je next call pixel jmp next handle_right_click: ; 循环等待右键释放 wait_right_release: call mouse_stat mov bl,stat and bl,2 jnz wait_right_release ; 切换颜色 inc color ; 清空鼠标事件缓冲区,避免残留事件干扰后续逻辑 mov ax,0Ch mov cx,0FFFFh int 33h jmp next
关键修改点
- 右键按下后进入循环,直到检测到右键释放才执行颜色切换,避免连续触发。
- 使用
int 33h ax=0Ch清空鼠标事件缓冲区,防止残留事件导致程序异常。 - 简化右键检测逻辑,直接通过
mouse_stat读取当前按键状态,替代错误的缓冲区读取方式。
内容的提问来源于stack exchange,提问作者Easyman121
相关产品推荐
相关产品推荐

