problemas con el grabador de acciones titaniun's recorder

Esta sección es para preguntas sobre programación/scripting usando AutoHotkey.

Moderator: Flipeador

tittet11
Posts: 8
Joined: 27 Apr 2021, 03:36

problemas con el grabador de acciones titaniun's recorder

01 May 2021, 17:46

hola a quien corresponda. estaba usando el script de Titan's Recorder. este script que dejaré mas adelante sirve para gravar las acciones del teclado y el mouse; (anteriormente ya lo había publicado en otro post).
el objetivo de esta publicación es buscar una solución a los errores que estoy descubriendo , por ejemplo, las flechas de arriba abajo o izquierda o derecha, no las detecta en ningún cuadro de diálogo, ni si quiera en el diálogo ejecutar ni en el explorador de archivos.

cabe destacar que todo lo ejecuté con privilegios administrativos en un archivo .EXE.
además, las teclas que uno asigna para iniciar la grabación así como detener e iniciar la reproducción, en muchas ocasiones no las detecta. en mi caso, puse que fueran las teclas start=#F1,stop=#F2 y play=#F3.

también, suele pasar en todas las ocasiones, que si gravas realizando una acción con la tecla ctrl, shift o la tecla alt, sucede que al terminar de ejecutar la grabación, estas teclas se quedan pulsadas, y la única manera de destrabarlas es presionando cada tecla de forma individual.
por ejemplo. utilicé la tecla ctrl mas shift mas escape para abrir el administrador de tareas y cuando detuve la grabación la tecla shift y ctrl se quedaron presionadas.

la pregunta es, existe alguna solución para esto, alguien puede ayudarme por favor, muchas gracias
antes de finalizar aquí dejaré el script

Code: Select all

; Authors: Titan, BoBo¨, Metaxal, Anonymous
; GNU General Public License 3.0 or higher <http www.gnu.org /licenses/gpl-3.0.txt>  Broken Link for safety

/*
   original topic:
   http://www.autohotkey.com/forum/viewtopic.php?t=23671

   Version history:
       - 0.19d
        - Add Spanish text
        - Add Language Selector (By Boiler)
		- Add Replay Button (By Boiler)
		- Clear Button clean temp.ahk
		- Other small changes
    - 0.18x (X)
        - set language to english and included anchor.ahk
    - 0.17m (Metaxal)
        - bugfix: moverel now moves the mouse relatively to the initial mouse coordinates
        - added "WAIT!" message 
        - (bug) added var gui_windowrel, to move in Coordmode Relative, NOT YET FUNCTIONAL!
            added gui control
            (Russian and German traductions for this are approximate)
    - 0.16m (Metaxal)
        - added: Russian text by Anton Bukov
   - 0.15m (Metaxal)
      - added: ExitApp key in generated scripts (the same key as the one used to stop recording, which makes sense!)
      - added NumpadEnter as bug key
      - added Replay button, script saved by default in temp.ahk
   - 0.14m (Metaxal)
      - fixed: buggy keys (Delete, Home, PgUp, ...) not logged
      - fixed: recording mouse moves was not functional?
      - not tested: relative mouse moves
   - 0.13m (Metaxal)
      - fixed: mouse clicks not recorded relative to screen...
      - Using VK codes instead of explicit symbols
         -> no problem whatever the foreign keyboard?
         -> can handle mysterious keys !
         -> handles mouse up and down + joysticks (?)
   - 0.12m (Metaxal)
      - french translation
      - removed consolidate, added add_log
      -> no need for #Include grep.ahk anymore. Multiple "Sends" are still merged, but "aaaa" is no more compressed
      -> also corrects the "Sl{e 2}p" error
      - added WinWait, IfWinActive and WinWaitActive
      - F11 and F12 for start/stop prefered to avoid some bugs with combined hotkeys
      - fixed: WinActivate not detected (wParam=32772)
      - fixed: "Send, " without parameter was added at end of script
      - fixed: mouse cordinates not relative or absolute
      - fixed(?): pressing Shift or Control at beginning of script would go to some other hotkey label
      (sometimes stop, sometimes start, or even exit when *~Esc is active)
      resolved by placing the call to hotkeys() before initializing the start and stop hotkeys
      Not sure this is completely fixed
      - fixed: wrong Sleep times
      - fixed: Sleep not initialized at each new recording
      - NOT fixed: keys are sometimes missed, and sometimes added??
      
   - 0.11a
      Original version by Titan, german translations by BoBo¨
*/

/*
   TODO:
   - Add a tooltip in the generated script to show when the script is playng or is ended.
*/

#SingleInstance ignore
#NoEnv
#NoTrayIcon

#Include %A_ScriptDir% ; Metaxal: Ensures a consistent #Include directory
; #Include Anchor.ahk ; Included at end of script by Anonymous
; #Include grep.ahk ; Metaxal: not needed anymore

SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

SetBatchLines, -1
CoordMode, ToolTip, Screen
CoordMode, Mouse, Screen

lang_table =
( Join`n `
Esp,Eng,Deu,Fra,Rus
Grabador de Titan,Recorder by Titan,Titans Makro Recorder,Enregistreur de macro par Titan,Генератор макросов Titan-а
Opciones de grabación,Recording options,Aufnahmeoptionen,Options d'enregistrement,Опции записи             
In&tervalos de tiempo ,&Time intervals       ,&Zeitintervalle       ,&Intervalles de temps ,Временные интервалы  
Acciones de &window   ,&Window actions       ,&Fensteraktionen      ,&Gestion des fenetres ,Действия над окнами  
&Usar comandos de control          ,&Use control commands              ,&Control-Befehle                   ,&Commandes de controle             ,Действия над элементами управления 
Acciones del teclado ,&Keyboard actions     ,&Tastaturaktionen     ,C&lavier              ,Нажатия клавиш       
C&licks del mouse ,Mouse c&licks     ,&Mausklicks       ,Clics &souris     ,Клики мышкой     
&Movimientos ,&Movements  ,&Bewegungen ,&Mouvements ,Движения    
Rel ,Rel ,Rel ,Rel ,РВ  
Rel a Ventana       ,Window Rel          ,Fenster Rel         ,Rel Fenetre         ,по отношению к окну 
Controles,Hotkeys,Hotkeys,Hotkeys,Горячие клавиши
&Empezar: ,      S&tart:,      St&art:,    &Debut:,    Старт:
 De&tener:,      St&op:,      St&op:,         &Fin:,     Стоп:
Repetir:,Replay:,Abspiel:,Rejouer:,Выполнить:
Guardar Como...,Save As...,Speichern unter...,Enregistrer sous...,Сохранить как...
Bo&rrar,&Clear,Z&urucksetzen,&Effacer,Очистить
Macro,Macro,Makro,Macro,Макрос
Guardar Como...,&Save As...,&Speichern unter...,&Enregistrer sous...,Сохранить как...
Script de AutoHotkey,AutoHotkey Scripts,AutoHotkey Scripts,AutoHotkey ScriptsбAutoHotkey скрипты
Grabando macro...`nPresiona $1 para detener.,Recording macro...`nPress $1 to stop.,Makroaufzeichnung...`nBeenden mit $1,Enregistrement en cours...`nAppuyez sur $1 pour arreter,Запись макроса... `nДля остановки нажмите $1
"Cargando script, por favor espere...","Loading script, please wait...","Lade Skript, bitte warten...","Chargement du script, veuillez patienter..."б"Скрипт загружается..."
Guardar script,Save script,Skript speichern,Enregistrer le script,Сохранить скрипт
¿Le gustaría guardar el script actual antes de se cerrar?,Would you like to save the current script before closing?,Vor Beenden speichern?,Enregistrer avant de quitter ?,Сохранить изменения?
¡ESPERE!,WAIT!, WARTEN!, ATTENDEZ !, ждать!
&Empezar,S&tart,St&art,&Debut,Старт
De&tener,St&op,St&op,&Fin,Стоп
Repetir,Replay,Abspiel,Rejouer,Выполнить
     Idioma ,Language ,  Sprache ,     Idiome ,      Язык 
)

currLang := "Esp"
lang := {}
langIndex := []

loop, Parse, lang_table, `n
{
	i := A_Index
	loop, Parse, A_LoopField, CSV
	{
		if (i = 1)
		{
			lang[A_LoopField] := {}
			langIndex[A_Index] := A_LoopField
		}
		else if (i = 2)
			lang[langIndex[A_Index]].Lang01 := A_LoopField
		else if (i = 3)
			lang[langIndex[A_Index]].Lang02 := A_LoopField
		else if (i = 4)
			lang[langIndex[A_Index]].Lang03 := A_LoopField
		else if (i = 5)
			lang[langIndex[A_Index]].Lang04 := A_LoopField
		else if (i = 6)
			lang[langIndex[A_Index]].Lang05 := A_LoopField
		else if (i = 7)
			lang[langIndex[A_Index]].Lang06 := A_LoopField
		else if (i = 8)
			lang[langIndex[A_Index]].Lang07 := A_LoopField
		else if (i = 9)
			lang[langIndex[A_Index]].Lang08 := A_LoopField
		else if (i = 10)
			lang[langIndex[A_Index]].Lang09 := A_LoopField
		else if (i = 11)
			lang[langIndex[A_Index]].Lang10 := A_LoopField
		else if (i = 12)
			lang[langIndex[A_Index]].Lang11 := A_LoopField
		else if (i = 13)
			lang[langIndex[A_Index]].Lang12 := A_LoopField
		else if (i = 14)
			lang[langIndex[A_Index]].Lang13 := A_LoopField
		else if (i = 15)
			lang[langIndex[A_Index]].Lang14 := A_LoopField
		else if (i = 16)
			lang[langIndex[A_Index]].Lang15 := A_LoopField
		else if (i = 17)
			lang[langIndex[A_Index]].Lang16 := A_LoopField
		else if (i = 18)
			lang[langIndex[A_Index]].Lang17 := A_LoopField
		else if (i = 19)
			lang[langIndex[A_Index]].Lang18 := A_LoopField
		else if (i = 20)
			lang[langIndex[A_Index]].Lang19 := A_LoopField
		else if (i = 21)
			lang[langIndex[A_Index]].Lang20 := A_LoopField
		else if (i = 22)
			lang[langIndex[A_Index]].Lang21 := A_LoopField
		else if (i = 23)
			lang[langIndex[A_Index]].Lang22 := A_LoopField
		else if (i = 24)
			lang[langIndex[A_Index]].Lang23 := A_LoopField
		else if (i = 25)
			lang[langIndex[A_Index]].Lang24 := A_LoopField
		else if (i = 26)
			lang[langIndex[A_Index]].Lang25 := A_LoopField
		else if (i = 27)
			lang[langIndex[A_Index]].Lang26 := A_LoopField
		else if (i = 28)
			lang[langIndex[A_Index]].Lang27 := A_LoopField
		else if (i = 29)
			lang[langIndex[A_Index]].Lang28 := A_LoopField			
	}
}
;listvars

title = Recorder
vers = 0.19d
config = %A_AppData%\%title%.ini
config_list = clicks,keyboard,window,ctrl,sleep,movements=0,movint=10,moveinte=10,moverel=0,start=F11,stop=F12,play=F9,windowrel=0
Loop, Parse, config_list, `,
{
   StringSplit, v, A_LoopField, =
   IniRead, gui_%v1%, %config%, Options, %v1%, % InStr(A_LoopField, "=") ? v2 : 1
}

Gui, +Resize +MinSize +LastFound
; fixed width font is too big
Gui, Add, Edit, vscr Hwndhscr w350 h200 gType
Gui, Font
Gui, Add, Text,vlbl6 ym x+115, % lang[currLang].Lang28
Gui, Add, GroupBox, vsec1 Section y+5 xp-105 w200 r7.5, % lang[currLang].Lang02
Gui, Add, CheckBox, vgui_sleep xp+15 yp+25 Checked%gui_sleep%, % lang[currLang].Lang03
Gui, Add, CheckBox, vgui_window Checked%gui_window%, % lang[currLang].Lang04
Gui, Add, CheckBox, vgui_ctrl Checked%gui_ctrl% Disabled, % lang[currLang].Lang05
Gui, Add, CheckBox, vgui_keyboard Checked%gui_keyboard%, % lang[currLang].Lang06
Gui, Add, CheckBox, vgui_clicks Checked%gui_clicks%, % lang[currLang].Lang07
Gui, Add, CheckBox, vgui_movements Checked%gui_movements% gMov, % lang[currLang].Lang08
Gui, Add, Edit, vgui_moveinte xp+85 yp-2 w50 Limit4
Gui, Add, UpDown, vgui_movint Range1-5000, %gui_movint%
Gui, Add, CheckBox, vgui_moverel xp-60 yp+25 Checked%gui_moverel%, % lang[currLang].Lang09 ;xp+60 yp+2 
Gui, Add, CheckBox, vgui_windowrel xp+40 yp Checked%gui_windowrel%, % lang[currLang].Lang10 ;xp-60 yp+20 
Gui, Add, GroupBox, vsec2 xs w200 r5, % lang[currLang].Lang11
Gui, Add, Text, vlbl1 xp+5 yp+25, % lang[currLang].Lang12
Gui, Add, Hotkey, vgui_start xp+50 yp-2 Limit1 gHotkey, %gui_start%
Gui, Add, Text, vlbl2 xp-50 yp+27, % lang[currLang].Lang13
Gui, Add, Hotkey, vgui_stop xp+50 yp-2 Limit1 gHotkey, %gui_stop%
Gui, Add, Text, vlbl4 xp-50 yp+29, % lang[currLang].Lang14
Gui, Add, Hotkey, vgui_play xp+50 yp-2 Limit1 gHotkey, %gui_play%
Gui, Add, Button, vsave Section xm yp+10 w100 h23 Disabled gSave, % lang[currLang].Lang18
Gui, Add, Button, vclear ys w100 h23 Disabled gClear, % lang[currLang].Lang16
Gui, Add, Button, vlbl3 xm+286 ys-30 w65 h23 Default gStart, % lang[currLang].Lang25
Gui, Add, Button, vlbl5 xm+286 ys w65 h23 Default gPlayTemp, % lang[currLang].Lang27
for each, language in langIndex
	langList .= language . "|"
Gui, Add, DropDownList, x525 y2 w45 gSelect vSelection, % RegExReplace(StrReplace(RTrim(langList, "|"), currLang, currLang . "|"), "\|$", "||")
Gui, Show,, % lang[currLang].Lang01 " ( v%vers% )"

Select:
	Gui, Submit, NoHide
	GuiControl,, sec1, % lang[Selection].Lang02
	GuiControl,, gui_sleep, % lang[Selection].Lang03
	GuiControl,, gui_window, % lang[Selection].Lang04
	GuiControl,, gui_ctrl, % lang[Selection].Lang05
	GuiControl,, gui_keyboard, % lang[Selection].Lang06
	GuiControl,, gui_clicks, % lang[Selection].Lang07
	GuiControl,, gui_movements, % lang[Selection].Lang08
	GuiControl,, gui_moverel, % lang[Selection].Lang09
	GuiControl,, gui_windowrel, % lang[Selection].Lang10
	GuiControl,, sec2, % lang[Selection].Lang11
	GuiControl,, lbl1, % lang[Selection].Lang12
	GuiControl,, lbl2, % lang[Selection].Lang13
	GuiControl,, lbl4, % lang[Selection].Lang14
	GuiControl,, save, % lang[Selection].Lang18
	GuiControl,, clear, % lang[Selection].Lang16
	GuiControl,, lbl3, % lang[Selection].Lang25
	GuiControl,, lbl5, % lang[Selection].Lang27
	GuiControl,, lbl6, % lang[Selection].Lang28
	Gui, Show,, % lang[Selection].Lang01 " ( v" vers " )"
	
return

SendMessage, 208, 0, RegisterCallback("EditWordBreakProc"), , ahk_id %hscr%
GoSub, Mov
FileCreateDir , Macros
; adapted from Skan's script at http://www.autohotkey.com/forum/viewtopic.php?p=123323#123323:
DllCall("RegisterShellHookWindow", "UInt", WinExist())
OnMessage(DllCall("RegisterWindowMessage", "Str", "SHELLHOOK"), "ShellMessage")

Hotkey:
GuiControlGet, v, , gui_start
If v !=
   Hotkey, %v%, Start
GuiControlGet, v, , gui_stop
If v !=
   Hotkey, %v%, Stop
GuiControlGet, v, , gui_play
If v !=
   Hotkey, %v%, PlayTemp
Return

;;; END OF AUTO-EXECUTE SECTION ;;; 

GuiSize:

Anchor("scr", "wh")
v = sec1,gui_movint,gui_clicks,gui_keyboard,gui_window,gui_ctrl,gui_sleep,gui_movements,gui_movint,gui_moverel,sec2,lbl1,gui_start,lbl2,gui_stop,gui_play,lbl4,gui_moveinte,gui_windowrel
Loop, Parse, v, `,
   Anchor(A_LoopField, "x", true)
Anchor("save", "y")
Anchor("clear", "y")
Anchor("lbl3", "xy")
Anchor("lbl5", "xy")
Anchor("lbl6", "x")
Anchor("Selection", "x")
Return

Mov:
GuiControlGet, v, , gui_movements
GuiControl, Enable%v%, gui_moveinte
GuiControl, Enable%v%, gui_moverel
Return

Clear:
;GuiControl, , scr
ControlSend, , ^{Home}^+{End}{Del}, ahk_id %hscr% ; this allows undo
FileDelete temp.ahk
FileAppend , , temp.ahk
Type:
GuiControlGet, scr, , scr
v := StrLen(scr) > 0
GuiControl, Enable%v%, save
GuiControl, Enable%v%, clear
unsaved := true
Return

Save:
GuiControlGet, scr, , scr
Gui, +OwnDialogs
FormatTime, d, , yyyy MM dd
FormatTime, t, , h:mm.tt
StringReplace, t, t, :, .
FileSelectFile, file, S19, % A_ScriptDir "\Macros\" lang[Selection].Lang17 " " d " " t ".ahk", % lang[Selection].Lang15, % lang[Selection].Lang19 " (*.ahk; *.txt)"
If file =
   Return
FileDelete, %file%
FileAppend, %scr%, %file%
unsaved := false
VarSetCapacity(scr, 0)
Return

Start:
FileAppend, , %A_ScriptDir%\temp.ahk
ToolTip, % lang[Selection].Lang24, 5, 5
hotkeys(true) ; Metaxal: needs to be BEFORE setting gui_start and gui_stop??
Gosub, Hotkey
GuiControlGet, v, FocusV
If v in gui_start,gui_stop
   Return
GuiControlGet, v, , gui_stop
StringReplace, s, lang18, $1, %v%
StringReplace, s, s, ``n, `n
Gui, Submit
GuiControlGet, gui_movint, , gui_moveinte
log_mpx := 0
log_mpy := 0
log_s = 1
log_xt := A_TickCount ; Initialize sleep counter
last_cmd=
log_text=
log_text .= "#NoEnv`n" ; SendMode Input`n" ; buggy with mousemove! (not synchronous)
add_log("CoordMode", "Mouse, " . (gui_windowrel ? "Relative" : "Screen"))
if gui_windowrel ; Not yet functional!
   CoordMode, Mouse, Relative
else
   CoordMode, Mouse, Screen
add_log("SetMouseDelay",  "2")   

If (gui_movements and gui_movint > 0 and gui_movint <= 5000) {
   ;MsgBox timer=%gui_movint%
   SetTimer, MouseMov, %gui_movint%
   }

ToolTip, %s%, 5, 5

;Loop {
;   Input, v, L1 V ; now useless
;   logkey(v)
;   If !log_s
;      Break
;}

Return

Stop:
log_s = 0
ToolTip, % lang[Selection].Lang21, 5, 5
;Input
SetTimer, MouseMov, Off
hotkeys(false)
Gui, Show
ToolTip
GuiControlGet, v, , log_text
If v
   v .= "`n"
log_text .= "`nExitApp`n" . gui_stop . "::ExitApp`n" ; the exit key is the one used to stop the script!
FileDelete temp.ahk
FileAppend %log_text%, temp.ahk
GuiControl, , scr, %v%%log_text%
VarSetCapacity(log_text, 0)
ControlSend, , ^{End}, ahk_id %hscr%
Goto, Type
Return

LogKey:
If log_s {
   StringTrimLeft, v, A_ThisHotkey, 2 ; -2 to remove "~*"
   logkey(v)
}
Return

MouseMov:
   MouseGetPos, x, y
   If (x != log_mpx or y != log_mpy) {
      If gui_moverel
         add_log("MouseMove ", (log_mpx ? x - log_mpx : 0) . ", " . (log_mpy ? y - log_mpy : 0) . ",, R")
      Else 
         add_log("MouseMove", x . ", " . y)
   }
         
   log_mpx := x
   log_mpy := y

Return

PlayTemp:
   Run %A_AhkPath% temp.ahk
Return

;~*Esc:: ; for debugging
GuiClose:
GuiControlGet, scr, , scr
If (scr != "" and unsaved)
{
   Gui, +OwnDialogs
   MsgBox, 20, % lang[Selection].Lang22, % lang[Selection].Lang23
   IfMsgBox, Yes
      Gosub, Save
}
Gui, Submit
Loop, Parse, config_list, `,
{
   StringSplit, v, A_LoopField, =
   IniWrite, % gui_%v1%, %config%, Options, %v1%
}
FileDelete temp.ahk
ExitApp

; Metaxal
add_log(cmd, params) {
   global last_cmd, log_text, log_xt, gui_sleep, log_xt

   If gui_sleep and (cmd != "Sleep") {
      v := Round((A_TickCount - log_xt) / 1)
      If (log_text and v > 700)
         add_log("Sleep", v) ; 
      log_xt := A_TickCount
   }

   If (SubStr(cmd, 1, 4) = "Send") and (cmd = last_cmd)
      log_text .= params
   Else
      log_text .= "`n" . cmd . ", " . params
   
   last_cmd = %cmd%
}

logkey(v) {
   local _w, _ct
   
   k := SubStr(v, 1, 4)
   if v not contains up
      v = %v% down
   v = {%v%}
   
   ; VK codes can also detect mouse down and up !!
   if k in VK01,VK02,VK04 ; mouse clicks
   {
      If gui_clicks {
         GoSub MouseMov
         add_log("Send", v) ; Synchronous click
      }
   }
   Else If gui_keyboard {
      add_log("SendInput", v)
   }
}

ShellMessage(wParam, lParam) {
   local t, c
   ;If wParam = 4 ; HSHELL_WINDOWACTIVATED
   If (wParam = 32772) or (wParam = 4) ; HSHELL_RUDEAPPACTIVATED or HSHELL_WINDOWACTIVATED
   {
      WinGetTitle, t, ahk_id %lParam%
      WinGetClass, c, ahk_id %lParam%
      If (log_s and gui_window and t and c) {
         d := t . " ahk_class " . c
         ;add_log("WinWait", d)
         add_log("IfWinNotActive", d . ", , WinActivate, " . d)
         add_log("WinWaitActive", d)
      }
   }
}

hotkeys(on = true) {

   ; VK codes seem to be much more reliable concerning different keyboard configurations.
   ; also handles properly the down and up of several keys, even mouse ones.
   ; also handles joysticks ?!
   
   ; This should allow for *any* foreign keyboard (?)
   ; although it is not very readable, so the script cannot really be modified manually
   nums=0123456789ABCDEF
   StringSplit numarray, nums

   Loop %numarray0%
   {
      n1 := numarray%A_Index%
      Loop %numarray0%
      {
         n2 := numarray%A_Index%
         n := n1 . n2
         if n=00
            continue
         k := "*~VK" . n
         Hotkey, %k%, LogKey, % "B" . (on ? "On" : "Off") ;%
         Hotkey, %k% up, LogKey, % "B" . (on ? "On" : "Off") ;%
      }
   }
   
   bugkeys=Delete,Home,PgUp,PgDn,Insert,End,NumpadEnter
   Loop, Parse, bugkeys, `,
   {
      k =  ~*%A_LoopField%
      Hotkey, %k%, LogKey, % "B" . (on ? "On" : "Off") ;%
      Hotkey, %k% up, LogKey, % "B" . (on ? "On" : "Off") ;%
   }
   
}

; taken from http://www.autohotkey.com/forum/topic20337.html
EditWordBreakProc(lpch, ichCurrent, cch, code) {
   static exp = "\W" ; treat any non alphanumeric character as a delimiter with this regex
   Loop, % cch * 2 ; build the string: ;%
      str .= Chr(*(lpch - 1 + A_Index))
   If code = 0 ; WB_LEFT
   {
      ; reverse and return last match:
      StringMid, str, str, 1, --ichCurrent
      Loop, Parse, str
         rev := A_LoopField . rev
      Return, ichCurrent - RegExMatch(rev, exp, "[^" . exp . "]+$") + 1
   }
   Else If code = 1 ; WB_RIGHT
      Return, ichCurrent >= cch ? cch : RegExMatch(str, exp, "", ichCurrent + 1) - 1
   Else If code = 2 ; WB_ISDELIMITER
      Return, RegExMatch(SubStr(str, ichCurrent, 1), exp)
}

/*
	Revised version for 64-bit/unicode - author unknown // posted by uname
	http://www.autohotkey.com/board/topic/91997-gui-anchor-for-current-version-of-ahk/?p=580170


	Function: Anchor
		Defines how controls should be automatically positioned relative to the new dimensions of a window when resized.

	Parameters:
		cl - a control HWND, associated variable name or ClassNN to operate on
		a - (optional) one or more of the anchors: 'x', 'y', 'w' (width) and 'h' (height),
			optionally followed by a relative factor, e.g. "x h0.5"
		r - (optional) true to redraw controls, recommended for GroupBox and Button types

	Examples:
		> "xy" ; bounds a control to the bottom-left edge of the window
		> "w0.5" ; any change in the width of the window will resize the width of the control on a 2:1 ratio
		> "h" ; similar to above but directrly proportional to height

	Remarks:
		To assume the current window size for the new bounds of a control (i.e. resetting) simply omit the second and third parameters.
		However if the control had been created with DllCall() and has its own parent window,
			the container AutoHotkey created GUI must be made default with the +LastFound option prior to the call.
		For a complete example see anchor-example.ahk.

	License:
		- Version 4.60a <http www.autohotkey.net /~polyethene/#anchor>  Broken Link for safety
		- Dedicated to the public domain (CC0 1.0) <http creativecommons.org /publicdomain/zero/1.0/>  Broken Link for safety
*/
Anchor(i, a := "", r := false) {
	static c, cs := 12, cx := 255, cl := 0, g, gs := 8, gl := 0, gpi, gw, gh, z := 0, k := 0xffff, ptr
	if z = 0
		VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), ptr := A_PtrSize ? "Ptr" : "UInt", z := true
	if !WinExist("ahk_id" . i) {
		GuiControlGet t, Hwnd, %i%
		if ErrorLevel = 0
			i := t
		else ControlGet i, Hwnd,, %i%
	}
	VarSetCapacity(gi, 68, 0), DllCall("GetWindowInfo", "UInt", gp := DllCall("GetParent", "UInt", i), ptr, &gi)
		, giw := NumGet(gi, 28, "Int") - NumGet(gi, 20, "Int"), gih := NumGet(gi, 32, "Int") - NumGet(gi, 24, "Int")
	if (gp != gpi) {
		gpi := gp
		loop %gl%
			if NumGet(g, cb := gs * (A_Index - 1), "UInt") == gp {
				gw := NumGet(g, cb + 4, "Short"), gh := NumGet(g, cb + 6, "Short"), gf := 1
				break
			}
		if !gf
			NumPut(gp, g, gl, "UInt"), NumPut(gw := giw, g, gl + 4, "Short"), NumPut(gh := gih, g, gl + 6, "Short"), gl += gs
	}
	ControlGetPos dx, dy, dw, dh,, ahk_id %i%
	loop %cl%
		if NumGet(c, cb := cs * (A_Index - 1), "UInt") == i {
			if (a = "") {
				cf := 1
				break
			}
			giw -= gw, gih -= gh, as := 1, dx := NumGet(c, cb + 4, "Short"), dy := NumGet(c, cb + 6, "Short")
				, cw := dw, dw := NumGet(c, cb + 8, "Short"), ch := dh, dh := NumGet(c, cb + 10, "Short")
			loop Parse, a, xywh
				if A_Index > 1
					av := SubStr(a, as, 1), as += 1 + StrLen(A_LoopField)
						, d%av% += (InStr("yh", av) ? gih : giw) * (A_LoopField + 0 ? A_LoopField : 1)
			DllCall("SetWindowPos", "UInt", i, "UInt", 0, "Int", dx, "Int", dy
				, "Int", InStr(a, "w") ? dw : cw, "Int", InStr(a, "h") ? dh : ch, "Int", 4)
			if r != 0
				DllCall("RedrawWindow", "UInt", i, "UInt", 0, "UInt", 0, "UInt", 0x0101) ; RDW_UPDATENOW | RDW_INVALIDATE
			return
		}
	if cf != 1
		cb := cl, cl += cs
	bx := NumGet(gi, 48, "UInt"), by := NumGet(gi, 16, "Int") - NumGet(gi, 8, "Int") - gih - NumGet(gi, 52, "UInt")
	if cf = 1
		dw -= giw - gw, dh -= gih - gh
	NumPut(i, c, cb, "UInt"), NumPut(dx - bx, c, cb + 4, "Short"), NumPut(dy - by, c, cb + 6, "Short")
		, NumPut(dw, c, cb + 8, "Short"), NumPut(dh, c, cb + 10, "Short")
	return true
} 

Return to “Pedir Ayuda”

Who is online

Users browsing this forum: No registered users and 42 guests