; 按F1判断当前光标是否选取了文字
#NoEnv
SetBatchLines -1
#SingleInstance Force

; AHK脚本以管理员权限自启
if !A_IsAdmin && !RegExMatch(_:=DllCall("GetCommandLine", "Str"), " /restart(?!\S)")
  RunWait % "*RunAs " RegExReplace(_, "^\"".*?\""\K|^\S*\K", " /restart")

Menu, TRAY, NoStandard
Menu, TRAY, DeleteAll
Menu, Tray, UseErrorLevel
Menu, TRAY,Add, WindowSpy,WindowSpy
Menu, TRAY,Add,
Menu, TRAY,Add, 重启程序,OnReload
Menu, TRAY,Add,
Menu, TRAY,Add, 退出程序,OnExits

;================================重复进程检查与处理================================================
If A_IsCompiled {
  thisPID := DllCall("GetCurrentProcessId")
  if objCount(Processlist:=GetProcessNameList(A_ScriptName))>1
  {
    loop,% objCount(Processlist)
    {
      if (thisPID<>Processlist[A_Index,2]){
        process,Close,% Processlist[A_Index,2]
      }
    }
  }
} Else {
  DetectHiddenWindows, On
  thisPID := DllCall("GetCurrentProcessId")
  WinGet, List, List, %A_ScriptFullPath% ahk_class AutoHotkey
  Loop % List
  { 
    WinGet, PID, PID, % "ahk_id" List%A_Index%
    If (PID != thisPID){
      Process, Close, %PID%
    }
  }
  DetectHiddenWindows, Off
}

;;================================程序图标如果隐藏托盘则提醒=================================
TrayIconInfo:=TrayIcon_GetInfo(A_IsCompiled?A_ScriptName:RegExReplace(A_AhkPath,".+\\"))
if objcount(TrayIconInfo){
  for key,value In TrayIconInfo
  {
    if (InStr(TrayIconInfo[key,"Tray"],"NotifyIconOverflowWindow")&&TrayIconInfo[key,"pid"]=DllCall("GetCurrentProcessId")){
      if !A_IconHidden
        Traytip,Warning Notify,请把程序图标从托盘区移至`n任务栏以方便更好的操作!,,1
      Else
        MsgBox, 262144, Warning Notify,请把程序图标从托盘区移至`n任务栏以方便更好的操作!,10
    }
  }
}
TrayRefresh(),EmptyMem()

;;================================监控消息回调ShellIMEMessage监控窗口变化================================
Gui +LastFound
DllCall( "RegisterShellHookWindow", UInt,WinExist() )
OnMessage( DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" ), "ShellIMEMessage")
ShellIMEMessage( wParam,lParam ) {
  /*    wParam参数:
    ;1 顶级窗体被创建 	;2 顶级窗体即将被关闭 	;54 退出全屏	;32772 窗口切换
    ;3 SHELL 的主窗体将被激活 	;4 顶级窗体被激活 	;&H8000& 掩码 	;53 全屏
    ;5 顶级窗体被最大化或最小化 	;6 Windows 任务栏被刷新,也可以理解成标题变更
    ;7 任务列表的内容被选中 	;8 中英文切换或输入法切换 	;13 wParam=被替换的顶级窗口的hWnd 
    ;9 显示系统菜单 	;10 顶级窗体被强制关闭 	;14 wParam=替换顶级窗口的窗口hWnd
    ;12 没有被程序处理的APPCOMMAND。见WM_APPCOMMAND
  */
  if (A_Is64bitOS&&A_PtrSize<8){
    SetRegView, 64
  }
  RegRead, InstallDir, HKEY_LOCAL_MACHINE\SOFTWARE\AutoHotkey,InstallDir
  if FileExist(InstallDir "\WindowSpy.ahk"){
    Menu, TRAY,Enable, WindowSpy
  }else{
    Menu, TRAY,Disable, WindowSpy
  }
  ;消除重复运行程序时弹出”Could not close the previous instance of this script. Keep waiting“窗口
  if WinExist(A_ScriptName){
    ControlGetText, WinStaticText , Static1,A
    if WinStaticText {
      if InStr(WinStaticText,"keep Waiting"){
        WinSet,AlwaysOnTop,On,A
        WinActivate ,A
        ControlFocus,Button1
        ControlSend , Button1, {Enter}, A
        if ErrorLevel {
          Send,{Enter}
        }
        OnReload()
      }
    }
  }
}

F1::
  StartNormal := EndNormal := 0
  GetSelectionNormal(GetControl(WinActive("A")), StartNormal, EndNormal)
  ;MsgBox % StartNormal "-" EndNormal
  if (EndNormal&&Abs(StartNormal-EndNormal)>0) {
    MsgBox,你选中了字段!
  } Else if (StartNormal=EndNormal) {
    MsgBox,你没有选中了字段!
  } Else {
    MsgBox,获取不成功,判断失败!
  }
Return
;;==================================================================================================================

GetControl(id) {
  Global MCtlClass
  ControlGetFocus, ctrlClass, ahk_id %id%
  MCtlClass:=ctrlClass?ctrlClass:MCtlClass
  ControlGet, ctrlHwnd, Hwnd,, %MCtlClass%,ahk_id %id%

  return ctrlHwnd
}

GetSelectionNormal(ctrl, ByRef start, ByRef end) {
  if !Ctrl {
    start :=0,end :=0
    Return
  }
  SendMessage, EM_GETSEL:=0x00B0, &start, &end,, ahk_id %ctrl%
  start := NumGet(start, 0, "UInt")
  end := NumGet(end, 0, "UInt")
}

WindowSpy(){
  RegRead, InstallDir, HKEY_LOCAL_MACHINE\SOFTWARE\AutoHotkey,InstallDir
  if FileExist(InstallDir "\WindowSpy.ahk"){
    if A_IsCompiled {
      Run *RunAs "%InstallDir%\AutoHotkey.exe" "%InstallDir%\WindowSpy.ahk" /restart
    }Else
      Run *RunAs "%A_AhkPath%" /restart "%InstallDir%\WindowSpy.ahk"
  }
}

OnReload(){
  Reload
}


OnExits(){
  ExitApp
}

;;;根据进程文件名获取托盘图标信息列表,以判断托盘图标是否正常显示
TrayIcon_GetInfo(sExeName := "")
{
  d := A_DetectHiddenWindows
  DetectHiddenWindows, On
 
  oTrayInfo := []
  For key,sTray in ["Shell_TrayWnd", "NotifyIconOverflowWindow"]
  {
    idxTB := TrayIcon_GetTrayBar(sTray)
    WinGet, pidTaskbar, PID, ahk_class %sTray%
    
    hProc := DllCall("OpenProcess",	UInt,0x38, Int,0, UInt,pidTaskbar)
    pRB   := DllCall("VirtualAllocEx", Ptr,hProc, Ptr,0, UPtr,20, UInt,0x1000, UInt,0x04)
 
    szBtn := VarSetCapacity(btn, (A_Is64bitOS ? 32 : 20), 0)
    szNfo := VarSetCapacity(nfo, (A_Is64bitOS ? 32 : 24), 0)
    szTip := VarSetCapacity(tip, 128 * 2, 0)
 
    ; TB_BUTTONCOUNT = 0x0418
    SendMessage, 0x0418, 0, 0, ToolbarWindow32%idxTB%, ahk_class %sTray%
    Loop, %ErrorLevel%
    {
       ; TB_GETBUTTON 0x0417
      SendMessage, 0x0417, A_Index-1, pRB, ToolbarWindow32%idxTB%, ahk_class %sTray%
 
      DllCall("ReadProcessMemory", Ptr,hProc, Ptr,pRB, Ptr,&btn, UPtr,szBtn, UPtr,0)
 
      iBitmap := NumGet(btn, 0, "Int")
      idCmd   := NumGet(btn, 4, "Int")
      fsState := NumGet(btn, 8, "UChar")
      fsStyle := NumGet(btn, 9, "UChar")
      dwData  := NumGet(btn, (A_Is64bitOS ? 16 : 12), "UPtr")
      iString := NumGet(btn, (A_Is64bitOS ? 24 : 16), "Ptr")
 
      DllCall("ReadProcessMemory", Ptr,hProc, Ptr,dwData, Ptr,&nfo, UPtr,szNfo, UPtr,0)
 
      hWnd  := NumGet(nfo, 0, "Ptr")
      uId   := NumGet(nfo, (A_Is64bitOS ?  8 :  4), "UInt")
      msgId := NumGet(nfo, (A_Is64bitOS ? 12 :  8), "UPtr")
      hIcon := NumGet(nfo, (A_Is64bitOS ? 24 : 20), "Ptr")
 
      WinGet, nPid, PID, ahk_id %hWnd%
      WinGet, sProcess, ProcessName, ahk_id %hWnd%
      WinGetClass, sClass, ahk_id %hWnd%
 
      If ( !sExeName || sExeName == sProcess || sExeName == nPid )
      {
        DllCall("ReadProcessMemory", Ptr,hProc, Ptr,iString, Ptr,&tip, UPtr,szTip, UPtr,0)
        oTrayInfo.Push({ "idx"	 : A_Index-1
                 , "idcmd"   : idCmd
                 , "pid"	 : nPid
                 , "uid"	 : uId
                 , "msgid"   : msgId
                 , "hicon"   : hIcon
                 , "hwnd"	: hWnd
                 , "class"   : sClass
                 , "process" : sProcess
                 , "tooltip" : StrGet(&tip, "UTF-16")
                 , "tray"	: sTray })
      }
    }
    DllCall("VirtualFreeEx", Ptr,hProc, Ptr,pRB, UPtr,0, UInt,0x8000)
    DllCall("CloseHandle",   Ptr,hProc)
  }
  DetectHiddenWindows, %d%
  Return oTrayInfo
}

TrayIcon_GetTrayBar(sTray:="Shell_TrayWnd")
{
  d := A_DetectHiddenWindows
  DetectHiddenWindows, On
  WinGet, ControlList, ControlList, ahk_class %sTray%
  RegExMatch(ControlList, "(?<=ToolbarWindow32)\d+(?!.*ToolbarWindow32)", nTB)
  Loop, %nTB%
  {
    ControlGet, hWnd, hWnd,, ToolbarWindow32%A_Index%, ahk_class %sTray%
    hParent := DllCall( "GetParent", Ptr, hWnd )
    WinGetClass, sClass, ahk_id %hParent%
    If !(sClass == "SysPager" || sClass == "NotifyIconOverflowWindow" )
      Continue
    idxTB := A_Index
    Break
  }
  DetectHiddenWindows, %d%
  Return idxTB
}
;;根据进程文件名获取进程信息列表
GetProcessNameList(ProcessName:=""){
  list:="",tarr:=[]
  s := 10240  ; 缓存和数组的大小(4 KB)

  Process, Exist  ; 设置 ErrorLevel 为这个正在运行脚本的 PID.
  ; 使用 PROCESS_QUERY_INFORMATION(0x0400) 获取此脚本的句柄:
  h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ErrorLevel, "Ptr")
  ; 打开此进程的可调整的访问令牌(TOKEN_ADJUST_PRIVILEGES = 32):
  DllCall("Advapi32.dll\OpenProcessToken", "Ptr", h, "UInt", 32, "PtrP", t)
  VarSetCapacity(ti, 16, 0)  ; 特权结构
  NumPut(1, ti, 0, "UInt")  ; 特权数组中的一个条目...
  ; 获取调试特权的本地唯一标识符:
  DllCall("Advapi32.dll\LookupPrivilegeValue", "Ptr", 0, "Str", "SeDebugPrivilege", "Int64P", luid)
  NumPut(luid, ti, 4, "Int64")
  NumPut(2, ti, 12, "UInt")  ; 启用这个特权: SE_PRIVILEGE_ENABLED = 2
  ; 使用新的访问令牌更新此进程的特权:
  r := DllCall("Advapi32.dll\AdjustTokenPrivileges", "Ptr", t, "Int", false, "Ptr", &ti, "UInt", 0, "Ptr", 0, "Ptr", 0)
  DllCall("CloseHandle", "Ptr", t)  ; 关闭此访问令牌句柄以节约内存.
  DllCall("CloseHandle", "Ptr", h)  ; 关闭此进程句柄以节约内存.

  hModule := DllCall("LoadLibrary", "Str", "Psapi.dll")  ; 通过预加载来提升性能.
  s := VarSetCapacity(a, s)  ; 接收进程列表标识符的数组:

  DllCall("Psapi.dll\EnumProcesses", "Ptr", &a, "UInt", s, "UIntP", r)
  Loop, % r // 4  ; 把数组解析为 DWORD(32 位) 的标识符:
  {
    id := NumGet(a, A_Index * 4, "UInt")
    ; 打开进程: PROCESS_VM_READ(0x0010) | PROCESS_QUERY_INFORMATION(0x0400)
    h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400, "Int", false, "UInt", id, "Ptr")
    if !h
      continue
    VarSetCapacity(n, s, 0)  ; 接收模块基础名称的缓存:
    e := DllCall("Psapi.dll\GetModuleBaseName", "Ptr", h, "Ptr", 0, "Str", n, "UInt", A_IsUnicode ? s//2 : s)
    if !e    ;  用于 64 位进程在 32 位模式时的回退方法:
      if e := DllCall("Psapi.dll\GetProcessImageFileName", "Ptr", h, "Str", n, "UInt", A_IsUnicode ? s//2 : s)
        SplitPath n, n
    DllCall("CloseHandle", "Ptr", h)  ; 关闭进程句柄以节约内存
    if (n && e){  ; 如果映像不是空的, 则添加到列表:
      If (ProcessName&&ProcessName=n)
        tarr.push([n,id])
      else
        list.=n "/" id "|"
    }
  }
  DllCall("FreeLibrary", "Ptr", hModule)  ; 卸载库来释放内存.

  return !ProcessName?list:tarr
}

EmptyMem(PID=""){
  pid:=!PID ? DllCall("GetCurrentProcessId") : pid
  h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid)
  DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
  DllCall("CloseHandle", "Int", h)
}

TrayRefresh() {
/*		Remove any dead icon from the tray menu
 *		Should work both for W7 & W10
 */
  WM_MOUSEMOVE := 0x200
  detectHiddenWin := A_DetectHiddenWindows
  DetectHiddenWindows, On
  allTitles := ["ahk_class Shell_TrayWnd"
      , "ahk_class NotifyIconOverflowWindow"]
  allControls := ["ToolbarWindow321"
        ,"ToolbarWindow322"
        ,"ToolbarWindow323"
        ,"ToolbarWindow324"]
  allIconSizes := [24,32]

  for id, title in allTitles {
    for id, controlName in allControls
    {
      for id, iconSize in allIconSizes
      {
        ControlGetPos, xTray,yTray,wdTray,htTray,% controlName,% title
        y := htTray - 10
        While (y > 0)
        {
          x := wdTray - iconSize/2
          While (x > 0)
          {
            point := (y << 16) + x
            PostMessage,% WM_MOUSEMOVE, 0,% point,% controlName,% title
            x -= iconSize/2
          }
          y -= iconSize/2
        }
      }
    }
  }
  DetectHiddenWindows, %detectHiddenWin%
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。