如何让Button按钮实现[单击]和[长按]功能

By admin at 2018-03-10 • 0人收藏 • 416人看过

很多时候为了用户操作方便,需要在窗口功能中实现 长按功能 ,并且也不能失去这个按钮的单击功能, 那么

一般应该是这样判断, 当按钮被按下的同时, 开启一个定时器(例如300毫秒), 然后判断在这段时间内是否松开了鼠标, 如果没有松开就判断它为长按, 否则为普通的单击事件


由此考虑: 有两种办法

1,开启一个1毫秒定时器 , 在定时器里获取鼠标左键状态 , 如果发现在不到300毫秒的间隔之内松开了鼠标,那么判定为单击, 超过300毫秒仍然处于按下状态则判断为长按!

2,利用多线程操作, 按下的同时开启一个线程, 线程里判断鼠标的状态,并且和按下当时的时间进行比较, 如果大于300毫秒仍然没有检测到鼠标松开状态就判定为长按, 否则为单击


那么两者有什么优略呢?

它们之间最大不同是: 定时器是在界面线程中操作, 而下面的是在另外一个线程中操作...


我个人猜测,第二种优于第一种方法, 至少不会影响到界面线程的其他方面....


第二种实现代码如下:

import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=356;bottom=240)
winform.add(
button={cls="button";text="单击 / 长按";left=92;top=91;right=261;bottom=156;z=1}
)
/*}}*/

import console
console.open()
winform.button.wndproc = function(hwnd,message,wParam,lParam){
    if(message == 0x202/*_WM_LBUTTONUP*/){
        thread.set("左键按下",false )
        console.log("终止操作")
 
    }elseif(message == 0x201/*_WM_LBUTTONDOWN*/){
         
        thread.invoke(
            function(  ){
                import console; 
                var Pretk = time.tick();
                var Nexttk;
                var 长按标志 = false;
                thread.set("左键按下",true )       
                while( thread.get("左键按下") ){
                    Nexttk = time.tick() - Pretk;
                    if(Nexttk > 300){
                        console.log("连续操作")
                        长按标志 = true;
                        break;
                    }
                }
                if(长按标志 == false){
                    console.log("单击操作")
                }
                 
            }   
        )
         //防止点击过快,调用双击操作
    }elseif(message == 0x203/*_WM_LBUTTONDBLCLK*/){
    	console.log("单击操作")
    }
    //无返回值则继续调用默认回调函数
}

winform.show() 
win.loopMessage();



为了便于理解,伪代码如下:

import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=356;bottom=240)
winform.add(
button={cls="button";text="单击 / 长按";left=92;top=91;right=261;bottom=156;z=1}
)
/*}}*/

import console;
console.open()
函数A = function(){
        console.log("正在执行函数A( 单步前进100mm )")
}

函数B = function(){
        console.log("正在执行函数B( 连续前进 )")
}

函数C = function(){
        console.log("正在执行函数C ( 停止前进 )")
}


winform.button.wndproc = function(hwnd,message,wParam,lParam){
    //弹起
    if(message == 0x202/*_WM_LBUTTONUP*/){
        
                thread.set("左键按下",false )
        函数C();
                        
    }elseif(message == 0x201/*_WM_LBUTTONDOWN*/){//按下
                thread.invoke(
            function( 函数A,函数B ){
                import console; 
                var Pretk = time.tick();
                var Nexttk;
                var 长按标志 = false;
                thread.set("左键按下",true )       
                while( thread.get("左键按下") ){
                    Nexttk = time.tick() - Pretk;
                    if(Nexttk > 300){
                        函数B();
                        长按标志 = true;
                        break;
                    } 
                }
                if(长按标志 == false){
                    函数A();
                }
                 
            },函数A,函数B)
    }elseif(message == 0x203/*_WM_LBUTTONDBLCLK*/){
    	函数A();
    }
    
    //无返回值则继续调用默认回调函数
}

winform.show() 
win.loopMessage();


1 个回复 | 最后更新于 2018-12-27
2018-12-27   #1
import fonts.fontAwesome;
import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=672;bottom=362)
winform.add(
plus={cls="plus";text='\uF0C8 预览按钮效果';left=178;top=135;right=393;bottom=204;bgcolor=-8355840;font=LOGFONT(h=-16;name='FontAwesome';charset=0);z=1}
)
/*}}*/

winform.plus.skin({
	background={
		active=0xFFCF8E2D;
		default=0xFF008080;
		hover=0xFF00C2C2

	};
})

import console
console.open()

var thrd;				//执行的显示线程
var mouseClickFlag = false;	//鼠标单击标识
var mousePushFlag = false;	//鼠标长按标识

var ddd = function(){
	import console
	var i = 1;
	do{
		console.log(i)
		i++;
		sleep(10)
	}while(1)
}



winform.plus.onMouseDown = function(wParam,lParam){
	//鼠标按下,令 单击标识 和 长按标识 都为0 , 因为此时不知道是否是单击或者长按
    mouseClickFlag = false;
    mousePushFlag = false;
    //延时200ms , 一次鼠标单击所用时间大概在200ms左右
    win.delay(200);
    //如果,在200ms时间内,没有触发鼠标抬起事件(即mouseClickFlag标识不是1),则认为这次是长按 
    if(!mouseClickFlag){
        //捕获全局鼠标信息,防止鼠标飘出plus控件范围
        winform.plus.capture = true;
        //置鼠标长按标识
        mousePushFlag = true;
        //开启显示线程
		thrd = thread.create(ddd,null);
	}
}

winform.plus.onMouseUp = function(wParam,lParam){
   //只要鼠标抬起, 立即关闭全局鼠标捕获
   winform.plus.capture = false;
   //置鼠标单击标识
   mouseClickFlag = true;
   //如果之前是长按
   if(mousePushFlag){
     //暂停定时显示
   	 thread.suspend(thrd)
   	 //销毁定时显示线程
  	 thread.terminate(thrd,0)
   }else {
  	 console.log("单击了一下")
   }	
}


winform.show() 
win.loopMessage();

image.png

登录后方可回帖

登 录
信息栏
本站永久域名:HtmLayout.Cn
纯私人站,当笔记本用的,学到哪写到哪,目前正在学aardio+halcon机器视觉.
本 站 主 站:Stm32cube中文网
Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
aardio在线手册Aardio在线手册
黑猫Aar教程网:简码编程
C大Aardio论坛:Aar爱好者论坛
AARDIO语言QQ群:70517368
赞助商:才仁机械
下载站:非凡软件站
Loading...