如何让Button按钮实现[单击]和[长按]功能
By
admin
at 2018-03-10 • 0人收藏 • 2172人看过
很多时候为了用户操作方便,需要在窗口功能中实现 长按功能 ,并且也不能失去这个按钮的单击功能, 那么
一般应该是这样判断, 当按钮被按下的同时, 开启一个定时器(例如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
登录后方可回帖
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();