发表回复 
【已解决】怎样能令输入文本的情况下脚本内某些热键暂时失效?
2012-09-26, 16 : 47
 
我想大家如果没有先搞清Caret是什么,窗口是怎么实现Caret的,还有鼠标是怎么变化的,窗口是怎么实现鼠标变化的,那么就不会在一个无解的问题中徘徊很久,ahk​没有任何问题,他使用了非常普通的win32 api,如果无法满足各位要求,要么就怪微软没有为各位的需求量身定做,要么就想方设法使自己的程序更接近满足需求。

通过简单的api,我可以让非编辑区域也出现caret,也能拼命闪,这时怎么判断;此外可以任何时候鼠标都显示ibeam,这时又怎么判断。

所以说没有通用的标准,只有根据自己常用的软件来划分,我希望代码是这样的,具体来说
代码: (全选)
#if check()
yourhokteyhere::return
#if

check()
{
    ; check control class
    ; check caret
    ; check others
    return 0 or 1
}
没有其他意思,我只是想让这个论坛更专业
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-26, 16 : 57
 
我简单写了查看输入焦点信息的代码,
代码: (全选)
^/::
pid := DllCall("GetCurrentThreadId")
pid2 := DllCall("GetWindowThreadProcessId","uint",DllCall("GetForegroundWindow"))
DllCall("AttachThreadInput","uint",pid,"uint",pid2,"int",1)
VarSetCapacity(point,8,0)
DllCall("GetCaretPos","ptr",&point)
handle := DllCall("GetFocus")
WinGetClass,class,ahk_id %handle%
WinGetTitle,title,ahk_id %handle%
WinGetText,text,ahk_id %handle%
msgbox % "Class of Focused Control : " class "`nTitle : " Title "`nText : " text "`nCaret : " NumGet(point,0,"int") "," NumGet(point,4,"int")
DllCall("AttachThreadInput","uint",pid,"uint",pid2,"int",0)
return
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-27, 01 : 04
 
[i=s] 本帖最后由 roy2012 于 2012-9-27 01:10 编辑 [/i]

引用:我想大家如果没有先搞清Caret是什么,窗口是怎么实现Caret的,还有鼠标是怎么变化的,窗口是怎么实现鼠标变化的,那么就不会在一个无解的问题中徘徊很久,ahk​没有任何问题,他使用了非常普通的win32 api,如果无法满 ...
nepter 发表于 2012-9-26 16:47 [Image: back.gif]
并不是我们要在死胡同徘徊,而是有人提供了思路,我就尽量顺着那个方向尝试,走不通也没问题呀。
引用:amnesiac管理员
发表于 2012-9-10 09:10
一个简单的方法是判断是否存在文本插入点,即A_CaretX、A_CaretY

没有人说 期望AHK无所不能,我们之所以提问,就是有了想法,就拿出来探讨可能性而已。
也许是我进来的时候没看清楚这是专业人员的研讨专门站,没关系,我再去认真看一次论坛规定吧。

如果你认为一个人提出的想法很离谱 的话,你直接告诉他『你的要求超出了软件覆盖的范围』。
一个设想 能否成立,根本不是 以 懂不懂电脑语言和程序结构 来决定。
懂不懂电脑语言 只会影响得到结论的速度。

论坛没有分 专业 不专业,只有分 开放式 还是 俱乐部式。

任何一个讨论,无论有多低水平,对于后来搜索解决办法的人来说,都可能有莫大的帮助。

分享完上网态度,回到主题。
通过 获取输入焦点信息 来判断 的思路,有点类似 二次开发的味道,
很有针对性,也很复杂(对于我来说)。
就算有人愿意帮我量身写好 用于 特定软件 的脚本,我也无法读懂其中的语境,
无法从中理解到任何东西,以后遇到别的软件,结果还是要求人。
最致命的是,获取输入焦点信息 这个方式对网页无效。
上网便捷的重要性不需要我强调了。

我之所以从 text insertion point 开始着手,因为这是通俗的,
几乎所有软件 所有用电脑的人 都会应用到,假如能抓到它 把柄 作为 自动化 的 判断条件,
这将会产生爆炸性的便利,更重要的是,其他人随便修改就能收为己用,无论用什么软件。
OK,没有错,到目前,还没抓到。

帮助 里 清楚说明了A_Cursor 可以有Arrow, Cross, Help, IBeam……这些值
cursor 也可以 分别有 X Y 坐标值。
而,提及 A_CaretX 和 A_CaretY 的部分很含糊,说这两个变量 的值 可以是坐标值,
并无提及 Caret 是否 像 A_Cursor 那样 也有一些 以状态来表示的值。假设Visible or invisible这类,
这正是我所关心的。

稍微改变方向,回到之前的尝试,增加了A_Cursor = "SizeAll",减少了中文输入法候选栏对光标的影响。
看以下的脚本,它是经过实测,无论什么软件,全面有效。但不够高效。
(需要 在鼠标的设定中 取消 【打字时隐藏指针】选项。)
运用过程大致有两种情况,
1需要打字的时候,没问题,如常点击,键入,鼠标不会自己跑。
Cursor保持I型。自动Suspend On,特定热键暂时失效。good。
2遇到 PDF 和 网页内容 这类情况,
指针路过文字会变I型,自动Suspend On,特定热键失效,
路过空白 和其他元素变,Cursor 成 箭头,手形,等其他形式,特定热键恢复有效。
这就是需要改进的地方。

现在的想法是:
If (A_Cursor = "IBeam" ) or ( A_Cursor = "SizeAll" )条件下点击左键,
要求发出的指令是 Click 和触发 Suspend On。(这个Click打字前本来就要,无多余)

否则,A_Cursor = 其他值的时候 点击左键,
要求发出的指令是 Click 和 Suspend Off。
(这个Click比全自动多了半个动作,打完字要点击其他界面,算半个必要)

若能如此,就极度接近主题要求了,这个要怎样写?大家有什么建议。
代码: (全选)
#Persistent
SetTitleMatchMode, 2
#IfWinActive, Executive  ,
   SetTimer, timer_MonitorCursor, 100
   return
   timer_MonitorCursor:
      If ( (A_Cursor = "IBeam" ) or ( A_Cursor = "SizeAll" ) )
      {
         Suspend On
         ToolTip, S
      }
Else
{
Suspend Off
ToolTip ,
}
   return
#IfWinActive
a::b;纯举例
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-27, 01 : 37
 
[i=s] 本帖最后由 nepter 于 2012-9-27 01:38 编辑 [/i]

我又没强迫你更专业点,我只说。。。的话会更好,采不采纳随便,
我压根不觉得很离谱,你说至少在我的认识范围之内,但据我的认知,某些方法可能无法取得好效果。
我知道很多人都想学一点ahk语言就以为很多想法都能实现了,我想这太高估ahk了,也太低估windows了,
我也知道没什么人想在多学点windows编程的,这看起来很复杂的东西,
所以,就这样吧。

其实我很想你们能讨论出点新的东西来,一看到这贴子,所有可能的不可能的都在脑里过了一遍,我提了建设性的意见或者说能写出更好的ahk的想法或者我认为较专业的认识,相​不相信随便。

再补一句吧,settime suspend什么的,ahk太忙了
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-27, 09 : 12
 
[i=s] 本帖最后由 jony.tw 于 2012-9-27 12:46 编辑 [/i]

感恩netper版大:願意分享經驗,並伸手幫助我們這些新手們!實在感激不盡!
在理解思考過許多情況之後,必須承認您說的真的沒錯!

且M$不可能包辦所有的應用程式,而且為了安全性的理由,
網頁瀏覽器千方百計的避開程式機器人的操控,WinSpy探不到很正常

roy2012 您也很積極的在思考,但是....試過netper的取焦點程式,很明白!和WinSpy一樣探不到瀏覽器的文框,而昨天想的辦法也有嚴重副作用...像「智慧」型自動辦​別語系切換輸入法一樣...常令人抓狂的不到位的功能!你會關掉它...大部份時候程式是瞎子,而你看得見!


代码: (全选)
#Persistent
CoordMode ToolTip, Screen
CoordMode Caret, clinet
SetTimer, CaretPos, 600
return

CaretPos:
YY -= A_CaretY
XX -= A_CaretX

if  (not(YY=0  AND XX=0) )OR GetKeyState("LButton"){
XX := A_CaretX
sendinput,  {shift D}{asc 68}{shift U}
sleep 10
XX -= A_CaretX
sleep 10
if not(XX = 0){
    tooltip Editi%XX% , 800,0,1
    sendinput {Backspace}
}
else{
        tooltip None , 800,0,1
    }
tooltip % A_CaretX . "  " . A_CaretY, A_ScreenWidth-300, 0, 2

}
YY := A_CaretY
XX :=A_CaretX
sleep 30
return

先說,這程式是危險具副作用的,因為偷俞打的字...也會引起回應...有任何損傷..不負責
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-27, 13 : 33
 
我觉得settime是不合适的,settime的间隔短会增加系统负担,间隔长了的话,在间隔之间的状态是不确定的,会出现意想之外的结果,所以在热键的阶段判断是否运​行热键的方式是恰当的,
代码: (全选)
#if check()
yourhokteyhere::return
#if

check()
{
        ; check control class
        ; check caret
        ; check others
        return 0 or 1
}
这种方式只在触发热键时判断是否执行热键,对系统负担小,而且不会有遗漏,不会有意想之外的事发生。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-27, 14 : 02
 
判断a_caret,输入字符再退格是不合适的,输入的字符可能会导致窗口执行其他操作,
判断A_Cursor也是不太合适的,谁也无法保证触发热键时鼠标在正确的位置,
如果热键执行了不希望执行的命令,再返工不是更费时间。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-27, 17 : 54
 
引用:我觉得settime是不合适的,.....在热键的阶段判断是否运行热键的方式是恰当的nepter 发表于 2012-9-27 13:33 [Image: back.gif]

在測式失敗之後沈澱....檢查caret...一直檢查??太沒效率了!而且有恐怖的副作用
..雙撃..熱字串...都可能出錯...一直切模式也會使User操作處於極不穩定中的危險中
包括干擾檔案存取..


我也有相同的想法,檢查要改在快鍵按下的剎那去做... 只針對無法取得焦點物件時...
正常的送出字元...如果A_CaretX有小幅的前進(橫書的Editor狀態)或者
折行(A_CaretY有小幅下移,A_CaretX退了一大段)
則在Editor狀態...(但送出字元仍有副作用....雖然大多數非Edit窗不會有回應..)
不送出熱鍵...否則執行熱鍵...
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-28, 09 : 01
 
[i=s] 本帖最后由 jony.tw 于 2012-10-2 11:12 编辑 [/i]

代码: (全选)
;只管在Opera下的熱鍵,目前沒有考慮中文輸入狀態,因為在我平台上取得的程式碼並不能成功識別中文輸入法狀態


:*:ahky::autohotkey  
:*:kya::autohotkey  ;放這邊是有效的...不可放到#IF後面去..執行不到!
return

#IfWinActive ahk_class OperaWindowClass  ;如果你沒用Opera就改這行或剝掉它再試
{
$a::       ;因為熱鍵發送自己 前面要加$
oldCaretX := A_CaretX
sendinput , a
sleep 100
oldCaretX -= A_CaretX
if (oldCaretX = 0)  ;把情況略寫成IBeam沒有動作
{
        run www.google.com  ;啟動一個熱鍵功能
        return
}
return
}
如果改在AutoHotKey源碼裡...變成一個熱鍵定義選項..但對於原本就有單鍵熱踺定義的軟體...回應的可能是游標的改變OR其他動作

並不適合這麼做
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-28, 12 : 28
 
[i=s] 本帖最后由 roy2012 于 2012-9-28 21:14 编辑 [/i]

引用:;只管在Opera下的熱鍵,目前沒有考慮中文輸入狀態,因為在我平台上取得的程式碼並不能成功識別中文輸入法狀態

#IfWinActive ahk_class OperaWindowClass ;如果你沒用Opera就改這行或剝掉它再試
{
$a:: ; ...
jony.tw 发表于 2012-9-28 09:01 [Image: back.gif]
Hi,我有了小进展,初步确定有效,正在全面测试,有待完善,先贴出来。

点击 你想要 插入文本 的地方,脚本自动Suspend。
一旦指针移动到 没有 文本的地方,脚本自动恢复有效。
除非再次点击 有文本的地方,否则,脚本一直有效。
代码: (全选)
#Persistent

   SetTimer, timer_MonitorCursor, 300
   return

   timer_MonitorCursor:
      If  (A_Cursor = "IBeam" )
      {
         ~LButton::Suspend On
        
      }
Else
    If (A_Cursor = "Arrow" )
      {      
         Suspend Off
          
      }
   return
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-28, 15 : 59
 
[i=s] 本帖最后由 jony.tw 于 2012-10-2 11:13 编辑 [/i]

引用:Hi,我有了小进展,初步确定有效,正在全面测试,有待完善,先贴出来。

点击 你想要 插入文本 的地方,脚本自动Suspend。
一旦指针移动到 没有 文本的地方,脚本自动恢复有效。
除非再次点击 有文本的地方,否 ...
roy2012 发表于 2012-9-28 12:28 [Image: back.gif]

這不好玩!為了持續在編輯窗打字,(通常是用雙手唷)
你必須移開一手去按滑鼠左鍵
(啊!這不算是人工識別鍵嗎? 那單鍵切..在螢幕上有狀態Icon就好了呀)

而且只要一捲動或推遠了不小心讓鼠標變成小箭頭,
你就得再做一次!這沒比較方便說...

在你的平台A_Cursor="SizeAll"就一定是中文輸入狀態嗎?
那加個if ( A_Cursor="SizeAll")就OK了!
在我的平台(Win7上) 不可依賴..還不如去check輸入法窗的小Icon...

但是不同電腦上位置可能不同...user設成浮動又四處拖的話..根本找不到
甚至有人會隱藏它...還是必須要用DllCall去抓Windows的真正狀態

中文輸入狀態下出現的框在不同輸入法狀態不同也Spy不到..
caret與英文的獨立,也就是說中文打字中一摸到A熱鍵就觸發了...

如果能判斷中文輸入狀態,問題就算解決了(論壇上簡中有碼可查也許你的平台有效)
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-28, 16 : 21
 
31# roy2012 代码写错了,确定“初步确定有效”?
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-28, 17 : 43
 
另外因為我舉了Opera的例子!
其實Opera本身的自定快鍵就很多,包括中文常用的切換鍵都被用上了
雖然Spy探不到!但是用AHK改寫(覆蓋) 快鍵的話不能不考慮到,

像ctrl-e會Focus搜尋框...F9會切Focus到網頁...Edit狀態可以明白判斷
但User如果自己改定了快鍵呢!

太多可以客製化的可能..介面控制的覆寫就只能針對小眾有效了!
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-28, 19 : 49
 
引用:這不好玩!為了持續在編輯窗打字,(通常是用雙手唷)
你必須移開一手去按滑鼠左鍵
(啊!這不算是人工識別鍵嗎? 那單鍵切..在螢幕上有狀態Icon就好了呀)

而且只要一捲動或推遠了不小心讓鼠標變成小箭頭,
你 ...
jony.tw 发表于 2012-9-28 15:59 [Image: back.gif]

目前,在 箭头 形态 点击 也触发 Suspend On,只是 很快 自动 切换到Suspend Off
也就是说,现在的If (A_Cursor = "IBeam" ) 只是 控制 Suspend On能否 保持,
需要改进成为 If (A_Cursor = "IBeam" ) 控制 是否触发 Suspend On

关于 自动 切换到Suspend Off,现在希望改为:
Suspend On触发后, 除非 指针在箭头形态下 左键 点击 任何地方,
否则,就一直维持Suspend On。这样就不怕 指针移动了。
不过这句不懂怎样写才有效。

另外,在 桌面/资源管理器 内,新建文件 时候,
就算没有点击, 文件名 等待编辑的 文字段 已经高亮,并等待插入文本,
人的条件反射 将会 直接 键入 ,这样 容易 出事故。需要解决。

关于持续打字,我能持续打字的地方就只有 记事本 和网页。
打完字,随后动作必然是再次摸 鼠标 ,点击 提交 或其他界面,
所以,要指针 变回 箭头(自动Suspend Off)的动作 算是 95.2%自动了。
除了上述不足,暂时效果 令我满意,呵呵……
(我用的是谷歌输入法。)

有些通用型组合热键我已经映射到别处 一指禅,如下:
SetTitleMatchMode, 2

IfWinActive, Notepad
{
Ins::^s
Del::!F4
}
return

ScrollLock::^x
Break::^c
NumLock::^v
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-28, 19 : 51
 
引用: 31# roy2012 代码写错了,确定“初步确定有效”?
nepter 发表于 2012-9-28 16:21 [Image: back.gif]
我不知道上面那脚本 有没有错,我认识还很少。

不过是有效的,可能不够工整。。。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-28, 21 : 10
 
引用:這不好玩!為了持續在編輯窗打字,(通常是用雙手唷)
你必須移開一手去按滑鼠左鍵
(啊!這不算是人工識別鍵嗎? 那單鍵切..在螢幕上有狀態Icon就好了呀)

而且只要一捲動或推遠了不小心讓鼠標變成小箭頭,
你 ...
jony.tw 发表于 2012-9-28 15:59 [Image: back.gif]
SizeAll 这个值 表示 指针变成 十字型 ,我的平台上,当 指针 处于 输入法 候选栏 上面会变成 十字形。在最后贴的那个脚本里,其实是无需要的。修改过程忘记删除。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-29, 13 : 28
 
[i=s] 本帖最后由 jony.tw 于 2012-9-29 13:43 编辑 [/i]

#31
引用:Hi,我有了小进展,初步确定有效,正在全面测试,有待完善,先贴出来。
....
roy2012 发表于 2012-9-28 12:28 [Image: back.gif]

nepter指正的....

每300ms重定義一次熱鍵~LButton是錯的!
代码: (全选)
#Persistent

SetTimer, timer_MonitorCursor, 600

~LButton:: Suspend  If  (A_Cursor = "IBeam" ) Suspend On
#a:: run www.google.com

return


timer_MonitorCursor:
If (A_Cursor = "Arrow" ) Suspend Off
return
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-29, 13 : 39
 
[i=s] 本帖最后由 jony.tw 于 2012-9-29 16:38 编辑 [/i]

#35
引用:目前,在 箭头 形态....

关于 自动 切换到Suspend Off,现在希望改为:
Suspend On触发后, 除非 指针在箭头形态下 左键 点击 任何地方,
否则,就一直维持Suspend On。这样就不怕 指针移动了。
不过这句不懂怎样写才有效。roy2012 发表于 2012-9-28 19:49 [Image: back.gif]
代码: (全选)
#Persistent

~LButton:: Suspend  If  (A_Cursor = "IBeam" ) Suspend On else Suspend Off
#a:: run www.google.com

return

除了IBeam其他的游標點了就停

引用:另外,在 桌面/资源管理器 内,新建文件 时候,
就算没有点击, 文件名 等待编辑的 文字段 已经高亮,并等待插入文本,
人的条件反射 将会 直接 键入 ,这样 容易 出事故。需要解决。
roy2012 发表于 2012-9-28 19:49 [Image: back.gif]

代码: (全选)
#Persistent

$a::
ControlGetFocus theFocus, A ; 取得目前活動窗口 的焦點之控件标识符
if not (inStr(theFocus , "Edit") or  (theFocus = "Scintilla1") or (theFocus ="DirectUIHWND1") or  (OKK = 1)) {
run www.google.com ;快鍵內容
}else{
sendinput a
}
return

~LButton::
If  (A_Cursor = "IBeam" ) {
        OKK := 1
} else if(A_Cursor = "Arrow" ) {
   OKK := 0
}
return


試過用標籤與副程式去縮減程式碼但不知為何一直出錯..

只好把試OK的先貼出來...

相信你仍然沒去試那一段功能..其實抓caret仍然有幫助的
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-29, 17 : 53
 
[i=s] 本帖最后由 roy2012 于 2012-9-29 18:45 编辑 [/i]

感谢Jony.tw
和nepter热心指导 以及 展示样例。
Jony.tw最近展示的脚本,正在测试,暂时无懈可击。
强烈建议 喜欢傻瓜一指禅 的朋友试用,吧大半个键盘变成1键快捷。
我加入了一些个性化语句,形成以下脚本:
代码: (全选)
#Persistent;在脚本里请自行删除所有中文字

~LButton::
Suspend
If  (A_Cursor = "IBeam" )
{
Suspend On
ToolTip , Auto-Suspend for Text-Inserting,  A_CaretX +50,  A_CaretY -90
;在光标附近加入了这个提示,除了提醒,点击就可以解除Suspend,
;例如在 NotePad,整个范围内 指针都是I型,点击个提示就不用长距离移动指针
;正在学习怎样改变ToolTip颜色,令其更显眼。以便确定可以正常插入字符。
return
}
else
;if(A_Cursor = "Arrow" )有些图形软件会把指针变成unknown,我删减了这句,使其更兼容
{
Suspend Off
ToolTip
return
}
return

a:: run www.google.com

#IF check();这里开始,我还不懂其含义,需要继续学习,但帮助 和网上 资料 也很少有提及。
{
Suspend On
}
check()
{
ControlGetFocus theFocus, A
mOnEdit = inStr(theFocus , "Edit") or  (theFocus = "Scintilla1") or (theFocus ="DirectUIHWND1")
return mOnEdit
}
之前我有个误解,以外必须 settimer 才能监视 指针形态。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-30, 00 : 45
 
[i=s] 本帖最后由 roy2012 于 2012-9-30 01:32 编辑 [/i]

引用:
  1. ~LButton::
  2. If (A_Cursor = "IBeam" ) {
  3. OKK := 1
  4. } else if(A_Cursor = "Arrow" ) {
  5. OKK := 0
  6. }
  7. return
jony.tw 发表于 2012-9-29 13:39 [Image: back.gif]
这里的OKK代表 什么? 查不到。。。从上半截看,很有针对性,估计 比 通用型 的方式 稳妥,我这就去试试看。
另外,我有个新想法,
就是:如果“指针向任意方向移动超过50或100个像数” 就 怎样怎样。
写成一个条件,用来自动 切换 状态。
因为,打字的时候,鼠标不会动,
鼠标活动了, 有两种意图:
a 想选择另外的插入点,选中一定要点击;
b想转换到其他界面,暂不打字。热键自动待命。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
发表回复 


论坛跳转:


联系我们 | Autohotkey 中文站 | 回到顶部 | 回到正文区 | 精简(归档)模式 | RSS 聚合