[第二关]一键多用设计

单击按键是我们想要的字符;

双击按键是两个我想要的字符;

。。。

在不需要字符输入的界面;

一个字符可以设置一个热键;

两个相同的字符可不可设置成一个热键呢?

三个呢?

这就是我们的第二关,如何实现一键多用!有能力的朋友可以设计出更高级的函数,写不出来的朋友我想你们肯定也有很多想法吧!你可以文字描述!!

摩斯(timeout = 400) { ;
   tout := timeout/1000
   key := RegExReplace(A_ThisHotKey,"[\*\~\$\#\+\!\^]")
   Loop {
      t := A_TickCount
      KeyWait %key%
      Pattern .= A_TickCount-t > timeout
      KeyWait %key%,DT%tout%
      If (ErrorLevel)
         Return Pattern
   }
}
 
;使用示例:
!z::
   p := 摩斯()
   If (p = "0")
      MsgBox 单击
   Else If (p = "00")
      MsgBox 双击
   Else If (p = "01")
      MsgBox 长按
   Else
      MsgBox 按键模式 %p%
Return
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA捐赠
共{{data.count}}人
人已捐赠
其他教程

[坐标]屏幕-工作区坐标转换的两种方法演示

2017-2-23 15:40:22

其他教程

[图像]AHK获取图像尺寸(宽高)三种方法演示

2017-3-3 20:45:48

29 条回复 A文章作者 M管理员
  1. chn.fwt

    这个函数感觉很高级了啊, 使用的时候 只要加上 #if A_CaretX 判断一下就好了

    • hexuren

      哈哈 这就需要你的智慧了!我也认为是很高级了!我希望能有更完美的设计!

  2. 清墨
    F1::
    keywait, F1, T0.3
    if( 1==ErrorLevel )
    {
    	MsgBox 长按
    }
    else
    {
    	keywait, F1,D T0.15
    	if( 1==ErrorLevel )
    	{
    	MsgBox 按了1次F1
    	}
    	else
    	{
    	keywait, F1, T0.2 
    	if( 0==ErrorLevel )
    	MsgBox 按了2次F1
    	}
    }
    return
    
    • hexuren

      我测试一下!有空的

    • hexuren

      奖励100ab!

    • 戏言玩家

      这个我在实际使用需要更改系统键盘按键自动触发的间隔。要不总会触发单击。。。

  3. 枫丹白露

    官方例子

    ; 示例 #3: 检测热键的单次, 两次和三次按下. 这样
    ; 允许热键根据您按下次数的多少
    ; 执行不同的操作:
    #c::
    if winc_presses > 0 ; SetTimer 已经启动, 所以我们记录键击.
    {
        winc_presses += 1
        return
    }
    ; 否则, 这是新开始系列中的首次按下. 把次数设为 1 并启动
    ; 计时器:
    winc_presses = 1
    SetTimer, KeyWinC, -400 ; 在 400 毫秒内等待更多的键击.
    return
    
    KeyWinC:
    if winc_presses = 1 ; 此键按下了一次.
    {
        Run, m:\  ; 打开文件夹.
    }
    else if winc_presses = 2 ; 此键按下了两次.
    {
        Run, m:\multimedia  ; 打开不同的文件夹.
    }
    else if winc_presses > 2
    {
        MsgBox, Three or more clicks detected.
    }
    ; 不论触发了上面的哪个动作, 都对 count 进行重置
    ; 为下一个系列的按下做准备:
    winc_presses = 0
    return
    
  4. 枫丹白露
    RControl::
    if (A_ThisHotkey  A_PriorHotkey or A_TimeSincePriorHotkey>1000 or 总共用时>10000) 
    ;如果这次和上次按键不同 或者 两次按键间隔超过1000ms 或者 总共用时超过 10000ms
    
    {
    t:=A_TickCount
    总共用时:=0
    长按:=0
    短按:=0
    }
    
    KeyWait, RControl ;松开后开始算账
    
    if A_TimeSinceThisHotkey>500
    长按+=1
    else
    短按+=1
    
    总共用时:=A_TickCount-t
    
    ToolTip % " 长按: " 长按 " 短按: " 短按 " 本次/总共用时: " A_TimeSinceThisHotkey  "/" 总共用时
    return
    
    ~LControl::
    ToolTip ;清空
    return
    
  5. alei

    老哥,示例里面的摩斯码什么鬼哦。。。应该叫布尔值吧

    • hexuren

      我也不知道是什么鬼 哈哈

    • hexuren

      今天有幸用到这段代码,他用的aa的值有点像摩尔斯码,不知道摩尔斯码的可以自己百度一下!以前发电报都用这个!

  6. 惮殃
    #NoEnv
    #SingleInstance FORCE
    #Persistent
    CoordMode, tooltip, screen
    
    	;testFilepath = % A_ScriptDir "\" lineList.txt	;测试文件名称
    	testFilepath := % A_ScriptFullPath	;*****以本脚本内容为例,可更改
    	
    	global linenum := 20	;*****设定显示行数,决定焦点位置,可以更改
    	
    	
    	
    	global cliplist := FlLiToList(testFilepath)	;创建粘粘列表
    	global maxIlength := StrLen(cliplist.MaxIndex())	;列表极限数量字符长度
    	global FocusLine := 1		;初始关注焦点
    	
    	global showway := % (!Mod(linenum, 2)) ? (Floor(linenum / 2)) : Ceil(linenum / 2)	;focusline显示位置
    	
    	infofresh := 80		;信息刷新时间间隔
    	keyfocusgetsleep := 20	;按键切换功能休眠时间
    return
    
    MButton::
    	if (show1 := !show1) {
    		SetTimer, tooltip, % show1 ? infofresh : ("off")
    		show2 := 1
    	}
    	else
    		ToolTip
    return
    
    #if show1
    
    ;ctrl + 上键 焦点前移
    WheelUp::
    	FocusLine -= 1	;关注焦点上移,对应序号往前
    	if (FocusLine = cliplist.MaxIndex())
    		FocusLine := 1 ;至顶部
    
    	cliptex := % cliplist[FocusLine]
    	clip_change(cliptex)
    	sleep % keyfocusgetsleep
    return
    
    
    ;tooltip显示排版
    tooltip:
    	if (show2 != 1) {	;刚切换模式时
    		tooltex := maketoollist()
    		if (extext = tooltex) ;若上一次显示的内容与此次 相同,不显示ToolTip,解决闪屏
    			return
    	}
    	show2 = 2
    	if	cliplist.MaxIndex()	{ ;若列表不为空,显示排版
    		;若上一次显示的内容与此次 相同,不显示ToolTip
    		ToolTip, % tooltex, 0, 0
    		WinSet, TransColor, Color [N], WinTitle
    
    		extext := tooltex
    	}
    	else
    		ToolTip, [黏贴列表为空], 0, 0
    return
    
    maketoollist() {	;设定tooltip排版
    	rtTex := 0
    	;1.列表小于linenum数时,列表不增不减,关注焦点为focusline
    	if (cliplist.MaxIndex() <= linenum) { ;设定显示行数大于列表数量时,随focusline焦点
    		for i in cliplist
    		{
    			foc := i
    			if (i = 1) && (FocusLine = 1)
    				rtTex := % preCHO(foc) cliplist[foc]
    			else if (i != 1) && (FocusLine = 1)
    				rtTex := % rtTex "`n" preBLK(foc) cliplist[foc]
    			else if (i != 1) && (i = FocusLine)
    				rtTex := % rtTex "`n" preCHO(foc) cliplist[foc]
    		}
    	}
    	;2.showway以上或以下小于裁剪数量时,分别增量反方向的行数
    	else if (FocusLine  (!Mod(linenum, 2) ? (cliplist.MaxIndex() - showway) : (cliplist.MaxIndex() - showway))) {
    		loop, % cliplist.MaxIndex() - FocusLine + showway
    		{
    			foc := % focusline - showway + A_Index
    			if A_Index = 1
    				rtTex := % preBLK(foc) cliplist[foc]
    			else if ((foc) = FocusLine)
    				rtTex := % rtTex "`n" preCHO(foc) cliplist[foc]
    			else
    				rtTex := % rtTex "`n" preBLK(foc) cliplist[foc]
    			
    			if (foc) = cliplist.MaxIndex()
    				break
    		}
    		
    		downtopnum := % linenum - (cliplist.MaxIndex() - (focusline - showway))
    		Loop, % downtopnum
    		{
    			rtTex := % rtTex "`n" preBLK(A_Index) cliplist[A_Index]
    		}
    	}
    	;3.正常显示方式,
    	else {
    		foc := % FocusLine - showway + 1
    		loop % linenum
    		{
    			if a_INDEX = 1
    				rtTex := %  (FocusLine = 1) ? preCHO(foc) : preBLK(foc) cliplist[foc]
    			else 
    				rtTex := % rtTex "`n" ((foc != FocusLine) ? preBLK(foc) : preCHO(foc)) cliplist[foc]
    			foc += 1
    		}
    	}
    	return % rtTex
    }
    
    ;将字符串置入粘贴板
    clip_change(to_clipboard)
    {
    	Clipboard :=
    	Clipboard := % to_clipboard
    	ClipWait
    }
    
    preCHO(inchar) {	;前置显示选中
    	mid := % "> " 
    	gotforlen := maxIlength - StrLen(inchar)
    	Loop %gotforlen% 
    		Bfor := % Bfor "0"
    	return % Bfor inchar " |" mid 	
    }
    
    preBLK(inchar) {	;前置显示空白
    	mid := % "       "
    	gotforlen := maxIlength - StrLen(inchar)
    	Loop %gotforlen% 
    		Bfor := % Bfor "0"
    	return % Bfor inchar " |" mid 	
    }
    
    FlLiToList(filelongpath) {	;将true每行内容写入列表,返回列表
    	Array1 := []
    	loop, read, % filelongpath
    	{
    		if A_LoopReadLine
    			Array1.Insert(A_LoopReadLine)
    	}
    	if !Array1.MaxIndex()
    		return 0
    	else
    		return % Array1
    }
    
    • 惮殃

      用鼠标中键选择剪切板内容,linenum 变量初始为5….写完看上去可以用来做库函数示例的复制黏贴

    • 惮殃

      目测少了一大段。。。是不是论坛bug

    • hexuren

      请反馈的详细一些,如果有bug,我们团队会尽快修复!

    • hexuren

      经测试,没发现跟主题有关!请补充完善信息!谢谢

    • 惮殃

      额..果然0.0不好意思,没看清题目

  7. 惮殃

    再来~这次符合主题了

    f1::
        KCLable("F1", f1func_dict, ["消息1", "消息2", "消息3", "消息4", "消息5"])
        return
    
    消息1:
    消息2:
    消息3:
    消息4:
    消息5:
        MsgBox, % A_ThisLabel
        return
    
    /*
    功能描述:
        短击设定按键显示功能项目
        长按选择功能
        超时退出
    
    主函数:
    
    KCLable() __ Key Chose Lable
        参1:keyname_str          待激活的按键,为字符串
        参2:choscount_dict       设定用以统计列表功能选择次数的字典,酌情舍去
        参3:lablefunc_strlist    选择标签的列表,为字符串列表
        参4:waitsec_int      超时未切换或未选择退出,单位为妙,可为浮点数, 默认值2
        参5:chosgototm_int       长按选择功能时间,单位毫秒, 默认值300
        其他:无返回值
    
    
    子函数:
    1.LsToStr(lablefunc_list, focusline_int) :  不可复用,将列表转换为行格式的多行字符串返回,用于tooltip
    
    2.NMsecSubt(tmlsA, tmlsB):              可复用,以列表方式时间计算函数,计算系统时间差,用以判断按键按击时间
    
    3.sortDicToLs(thels, byref __diccount): 修改后可复用,将字典键的值以从大到小顺序排列为列表,输出该列表
    
    4.varInlist(var, ls):                       可复用,判断值是否在列表中
    */
    
    KCLable(keyname_str, ByRef choscount_dict,lablefunc_strlist, waitsec_int := 1, chosgototm_int := 200) {     ;主函数
        foucs_int := 1  ;每次按键初始焦点位置
        ;*** 功能选择次数统计点1 ***
        lablefunc_strlist := sortDicToLs(lablefunc_strlist, choscount_dict)
        ToolTip, % LsToStr(lablefunc_strlist, foucs_int)
        keywait, % keyname_str
        loop {
            KeyWait, % keyname_str, % "DT" waitsec_int
            if (ErrorLevel) {
                tooltip
                break
            }
            else {
                __noww := [A_Now, A_MSec]
                keywait, % keyname_str
                ;长按时选择功能后退出
                __gotsince := [A_Now, A_MSec]
                __gotPE := NMsecSubt(__gotsince, __noww)
                if (__gotPE >= chosgototm_int) {
                    gosub, % lablefunc_strlist[foucs_int]
                    ;*** 功能选择次数统计点2 ***
                    choscount_dict[lablefunc_strlist[foucs_int]] += 1
                    tooltip
                    ; 此处完成功能,计数标签功能选择次数并排序
                    break
                }
                ;短按切换焦点
                else {
                    foucs_int += 1
                    if (foucs_int > lablefunc_strlist.MaxIndex())
                        foucs_int := 1
                    ToolTip, % LsToStr(lablefunc_strlist, foucs_int)
                }
            }
        }
    }
    
    LsToStr(lablefunc_list, focusline_int) {    ;将列表设置为某种格式
        rt_str =
        for i in lablefunc_list
        {
            ;首行
            if (i == 1) {
                if (i == focusline_int)
                    rt_str := % "> " lablefunc_list[i]
                else
                    rt_str := % "      " lablefunc_list[i]
            }
            ;非首行
            else {
                if (i  == focusline_int)
                    rt_str := % rt_str "n> " lablefunc_list[i]
                else
                    rt_str := % rt_str "n      " lablefunc_list[i]
            }
        }
        return rt_str
    }
    
    NMsecSubt(tmlsA, tmlsB) {                   ;计算两时间点列表值的差,返回单位毫秒
        subSVar := tmlsA[1]
        subSVar -= tmlsB[1], s  ;两数相减的秒数
        if (subVar != 0) 
            return % (subSVar * 1000) + (tmlsA[2] - tmlsB[2])
        else
            return % (tmlsA[2] - tmlsB[2])
    }
    
    sortDicToLs(thels, byref __diccount) {      ;将字典键的值以从大到小顺序排列为列表,输出该列表
    
    for i in __diccount
        i := i
    if (!i) {   ;字典为空,创建字典
        __diccount := {}
        for i in thels
            __diccount.Insert(thels[i], 0)
        newls := thels
    }
    else {      ;字典不为空,根据字典值,升序排列
        maxit := 
        newls := []
        for thei in thels
        {
            ;寻找字典中的最大值
            maxit := 0 ;最大值初始
    
            for keyName in __diccount
            {
                iF !varInlist(keyName, newls)
                {
                    if (!maxit)
                        maxit := __diccount[keyName]
                    if (__diccount[keyName] > maxit)
                        maxit := __diccount[keyName]
                }
            }
            ;寻找字典中的最大值的首位键
            for theindex in thels
            {
                nowlsindex := thels[theindex] 
                if !varInlist(nowlsindex, newls) ;当前循环到的值不在新列表中
                {
                    TT := thels[theindex]
                    if (__diccount[TT] == maxit)
                    {
                        maxkey := thels[theindex]
                        break
                    }
                }
            }
            newls.Insert(maxkey)
        }
    }
    return newls
    
    }
    
    varInlist(var, ls) {
        for i in ls
        {
            if (ls[i] == var)
                return 1
        }
        return 0
    }
    
    • hexuren

      请注明使用的ahk版本!在1.x版本测试未通过!

    • hexuren

      已为你更新,效果非常不错!奖励1000积分!

  8. 惮殃

    。。。不造为毛格式变成那样,坛主将就着测试吧

    • hexuren

      使用我的格式就行了 或者直接使用markdown

  9. 李晓龙

    很了不起,看不懂啊,需要慢慢学习了

  10. HIALL

    都是高手

  11. ilaoyao

    #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
    #Persistent ;保持后台运行
    #SingleInstance FORCE ;单实例运行模式
    SetBatchLines -1
    return

    ;~ 按照Ctrl后,再按T(可多次)测试按键
    ~^T::
    {
    gnPressCount += 1
    if gnPressCount = 1
    SetTimer, tapstime, 600 ;在600毫秒内按下T键的次数

    return
    }

    tapstime:
    SetTimer, tapstime, Off
    {
    If gnPressCount = 1
    {
    msgbox, 单击代码
    }
    else if gnPressCount = 2
    {
    msgbox, 双击代码
    }
    else if gnPressCount = 3
    {
    msgbox, 三击代码
    }
    else if gnPressCount >3
    {
    msgbox, 你手速真快!
    }
    gnPressCount := 0
    Return
    }

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索