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

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

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

一般应该是这样判断, 当按钮被按下的同时, 开启一个定时器(例如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

登录后方可回帖

登 录
信息栏
 私人小站

本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...