Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

An update for AutoScriptWriter


  • Please log in to reply
45 replies to this topic
Thalon
  • Members
  • 641 posts
  • Last active: Jan 02 2017 12:17 PM
  • Joined: 12 Jul 2005
At the moment my little code recognizes Mousclicks in windows and works under normal conditions. Also clicks onto desktop works already.
There are no double-clicks or right-clicks at the moment.
At the moment I am playing around with finding the correct commands for Control-Handling (if I have time).

I can send you my few lines not before monday, because it lies on my desktop at work. ^^

Thalon

AHKnow*
  • Guests
  • Last active:
  • Joined: --
Do you want to post the code in a new post? This way everyone gets to work on the AHK script method. Everyone can make comments, suggestions, improvements, test it, etc....

Thalon
  • Members
  • 641 posts
  • Last active: Jan 02 2017 12:17 PM
  • Joined: 12 Jul 2005
After some days of not having time I created a first version which works (should work ;) ) for mousehandling of buttons (and only for them at the moment).
The checkbox-implementation for 3-states is only until I have the time to search the correct message.

It is a code where I am playing around to find the best solution and there are still some points to improve (e.g. How to find Sleeptimes, Doubleclicking, Rightclicks...).

Do you think the identification of controls in groups (like Buttons) can be done correct by name in all cases? And is the subclassing via control-styles a good way to find the best possible command?

I am looking forward to your comments!
GoSub, InitStyle

Gui, Add, Tab, , Test
Gui, Tab, 1
Gui, Add, Text, , TestText
Gui, Add, Edit, , MyEdit
Gui, Add, UpDown, , 
Gui, Add, Picture, , D:\projects\KBmpTest.pgp\Logical\visu\Bitmaps\Images43.jpg
Gui, Add, Button, , KlickMe
Gui, Add, Checkbox, , Check/Uncheck me
Gui, Add, Checkbox, Check3, Check/Uncheck me
Gui, Add, Radio, , 1
Gui, Add, Radio, , 2
Gui, Add, Radio, , 3
Gui, Add, DropDownList, , Text|Text2|Text3
Gui, Add, Combobox, , Text|Text2|Text3
Gui, Add, Listbox, , Text|Text2|Text3
;Listview
Gui, Add, Hotkey, 
;DateTime
;MonthCal
Gui, Add, Slider, 
Gui, Add, Progress
Gui, Add, Groupbox
Gui, Show, , Test-Gui

Suspend		;Start suspended
return

*$LButton::
MouseGetPos, XPos, YPos, WinID, Controlname
WinGetClass, WinClass, ahk_id %WinID%
WinGetTitle, WinTitle, ahk_id %WinID%
History = %History%Sleep`, %A_TimeSincePriorHotkey%`n

if (WinClass = "Progman" or WinClass = "WorkerW")		;Desktop
{
	CoordMode, Mouse, Screen
	MouseGetPos, XPos, YPos
	History = %History%MouseMove`, %XPos%`,%YPos%`, 5`n
	
	History = %History%Loop`,`n`{`nMouseGetPos`, `, `, WinID`nWinGetClass`, WinClass`, ahk_id `%WinID`%`n
	;Falls Desktop nicht an dieser Stelle: alle Fenster minimieren
	History = %History%if (WinClass != "Progman" and WinClass != "WorkerW")`nSend`, #m`nelse break`n`}`n
	CoordMode, Mouse, Relative
}
else	;"normal" Window
{
	if WinID != %OldWinID%
	{
		;Code for activating the correct window
		History = %History%IfWinNotActive`, %WinTitle%`, `, WinActivate`, %WinTitle%`n
		History = %History%%A_Tab%WinWaitActive`, %WinTitle%`n
		History = %History%WinID := WinExist("A")`n
		OldWinID = %WinID%
	}

	;Getting style for clearer information
	ControlGet, ControlStyle, Style, , %Controlname%, ahk_id %WinID%
	

	if InStr(Controlname, "Button")	;Normaler Button, Checkbox, Radio, 
	{
		ControlStyle := (ControlStyle & 0xF)		;Es ist nur B0000 bis B1111 interessant
		if (ControlStyle = BS_PUSHBUTTON OR ControlStyle = BS_DEFPUSHBUTTON)
		{
			LButtonDownTime = %A_TickCount%
			History = %History%ControlClick`, %Controlname%`, ahk_id `%WinID`%`, `, Left`, 1`, D`n
		}
		else if (ControlStyle = BS_3STATE OR ControlStyle = BS_AUTO3STATE)
		{
			SendMessage, BM_GETSTATE, 0, 0, %Controlname%, ahk_id %WinID%
	  	state := ErrorLevel
	  	;Obey: The previous state has to be used for check...
	  	If (state & 0x3 = BST_UNCHECKED)	;State = CHECKED
				History = %History%Control`, Check`, `, %Controlname%`, ahk_id `%WinID`%`n
			Else If (state & 0x3 = BST_CHECKED)		;State = INDETERMINATE
				History = %History%SendMessage`, %BM_SETCHECK%`, %BST_INDETERMINATE%`, 0`, %Controlname%, ahk_id `%WinID`%`n
			Else If (state & 0x3 = BST_INDETERMINATE)		;State = UNCHECKED
				History = %History%Control`, UnCheck`, `, %Controlname%`, ahk_id `%WinID`%`n
		}
		else if (ControlStyle = BS_CHECKBOX OR ControlStyle = BS_AUTOCHECKBOX)
		{
			ControlGet, Checked?, Checked, , %Controlname%, ahk_id %WinID%
			if Checked? = 1	;Beachte: Mausklick erfolgt erst nach Statuserfassung!
				History = %History%Control`, UnCheck`, `, %Controlname%`, ahk_id `%WinID`%`n
			else
				History = %History%Control`, Check`, `, %Controlname%`, ahk_id `%WinID`%`n
		}
		else if (ControlStyle = BS_RADIOBUTTON OR ControlStyle = BS_AUTORADIOBUTTON)
			History = %History%ControlClick`, %Controlname%`, ahk_id `%WinID`%`, `, Left`, 1`n
		else	;Unhandled Button-Type
		{
			LButtonDownTime = %A_TickCount%
			History = %History%MouseClick`, Left`, %XPos%`, %YPos%`, `, `, D`n
		}
	}
	else if InStr(Controlname, "Edit")		;Edit, Combobox (here only Edit-part)
	{
		History = %History%ControlFocus`, %Controlname%`, ahk_id `%WinID`%`n
	}
/*
	else if InStr(Controlname, "ComboBox")	;DropDown, Combobox (hier nur Button zum droppen)
	{
		
	}
	else if InStr(Controlname, "Listbox")	;Listbox
	{
		
	}
	else if InStr(Controlname, "Hotkey")	;Hotkey-Control
	{
		History = %History%ControlFocus`, %Controlname%`, ahk_id `%WinID`%`n
	}
	else if InStr(Controlname, "Trackbar")	;Slider
	{
		
	}
	*/
	else	;Klick somewhere in the window or unknown control
	{
		MouseGetPos, XPos, YPos
		LButtonDownTime = %A_TickCount%
		History = %History%MouseClick`, Left`, %XPos%`, %YPos%`, `, `, D`n
	}
}

MouseClick, Left, , , , , D
return 


;########################

*$LButton Up::
if LButtonDownTime !=
{
	LButtonDownDuration := A_TickCount - LButtonDownTime
	History = %History%Sleep`, %LButtonDownDuration%`nMouseClick`, Left`, `, `, `, `, U`n
	LButtonDownTime =
}
MouseClick, Left, , , , , U
return

;########################


;AltGr+H opens a Dialog with the written code
<^>!h::
Suspend, Permit
Suspend, On
Gui, 2:Add, Edit, r10, %History%
Gui, 2:Add, Button, g2Perform, Perform		;Saves the script and launches it
Gui, 2:Show, , Script
return

2Perform:
Gui, 2:Destroy
FileDelete, WrotenScript.ahk			;Delete previous Script
FileAppend, %History%, WrotenScript.ahk		;Save Script
History =				;Clear Script 
OldWinID =			;Prepare for new script
RunWait, WrotenScript.ahk					;Run Script
return

;If the Perform-Dialog is closed clear recording
2GuiClose:
History =			;Clear Script 
OldWinID = 			;Prepare for new script
Gui, 2:Destroy
return

;########################

;Toggles activation-state
Pause::Suspend

;########################
;Reload Hotkey
^!r::
Suspend, Permit
Reload



;Set constants
InitStyle:
;Borderstyles
BS_PUSHBUTTON = 0x0
BS_DEFPUSHBUTTON = 0x1
BS_CHECKBOX = 0x2
BS_AUTOCHECKBOX = 0x3
BS_RADIOBUTTON = 0x4 
BS_3STATE = 0x5
BS_AUTO3STATE = 0x6
BS_GROUPBOX = 0x7
BS_AUTORADIOBUTTON = 0x9
;BS_PUSHLIKE = 0x1000

;Constants for retreive/set 3rd state of a checkbox
BM_GETSTATE = 0xF2
BST_UNCHECKED = 0x0
BST_CHECKED = 0x1
BST_INDETERMINATE = 0x2
BM_SETCHECK = 0xF1
return
Thalon

Note: Another way would be real subclassing of window-messages, but I would have to generate a dll for this. I thought to try it as "clean" Ahk-Solution

AHKnow*
  • Guests
  • Last active:
  • Joined: --
What is this "D:\projects\KBmpTest.pgp\Logical\visu\Bitmaps\Images43.jpg" in your GUI code?

Thalon
  • Members
  • 641 posts
  • Last active: Jan 02 2017 12:17 PM
  • Joined: 12 Jul 2005
It's only a smilie I have added to my Testgui. It doesn't have any special usage at the moment...

Thalon

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Although I haven't tried it yet, it looks good from looking at the script. I plan to try it after I get the next release out; then I can give you some feedback.

AHKnow
  • Members
  • 121 posts
  • Last active: May 17 2009 09:11 PM
  • Joined: 03 Jul 2004
Some suggestions:

1. I think that it might be a good idea to separate the test GUI code from the AutoScriptWriter code. The 2 combined creates issues. I think you can have a testgui.ahk and a newautoscriptwriter.ahk (new asw).

2. Perhaps there should be focus on a new autoscriptwriter.ahk GUI. It would appear that the old AutoScriptWriter GUI should be the main reference point.

3. Each part of the code, should perhaps have even more comments about its intent. This way, everyone is clear on what each part does.

4. This part of the code, ;
AltGr+H opens a Dialog with the written code
<^>!h::
, should perhaps be some different combo. How about Ctrl+Alt+O (O for Open). Also, this would obviously be nice to connect to a button on the new AutoScriptWriter GUI.

5. The new AutoScriptWriter's GUI should obviously have a "Save As" feature.


Below is a proposed sample of the separation between the test GUI and the New AutoScriptWriter code:

Test GUI

GoSub, InitStyle

Gui, Add, Tab, , Test
Gui, Tab, 1
Gui, Add, Text, , TestText
Gui, Add, Edit, , MyEdit
Gui, Add, UpDown, ,
Gui, Add, Picture, , D:\projects\KBmpTest.pgp\Logical\visu\Bitmaps\Images43.jpg
Gui, Add, Button, , KlickMe
Gui, Add, Checkbox, , Check/Uncheck me
Gui, Add, Checkbox, Check3, Check/Uncheck me
Gui, Add, Radio, , 1
Gui, Add, Radio, , 2
Gui, Add, Radio, , 3
Gui, Add, DropDownList, , Text|Text2|Text3
Gui, Add, Combobox, , Text|Text2|Text3
Gui, Add, Listbox, , Text|Text2|Text3
;Listview
Gui, Add, Hotkey,
;DateTime
;MonthCal
Gui, Add, Slider,
Gui, Add, Progress
Gui, Add, Groupbox
Gui, Show, , Test-Gui

Suspend      ;Start suspended
return


;Set constants
InitStyle:
;Borderstyles
BS_PUSHBUTTON = 0x0
BS_DEFPUSHBUTTON = 0x1
BS_CHECKBOX = 0x2
BS_AUTOCHECKBOX = 0x3
BS_RADIOBUTTON = 0x4
BS_3STATE = 0x5
BS_AUTO3STATE = 0x6
BS_GROUPBOX = 0x7
BS_AUTORADIOBUTTON = 0x9
;BS_PUSHLIKE = 0x1000

;Constants for retreive/set 3rd state of a checkbox
BM_GETSTATE = 0xF2
BST_UNCHECKED = 0x0
BST_CHECKED = 0x1
BST_INDETERMINATE = 0x2
BM_SETCHECK = 0xF1
return


New AutoScriptWriter (AutoHotkey) code (by Thalon):

*$LButton::
MouseGetPos, XPos, YPos, WinID, Controlname
WinGetClass, WinClass, ahk_id %WinID%
WinGetTitle, WinTitle, ahk_id %WinID%
History = %History%Sleep`, %A_TimeSincePriorHotkey%`n

if (WinClass = "Progman" or WinClass = "WorkerW")      ;Desktop
{
   CoordMode, Mouse, Screen
   MouseGetPos, XPos, YPos
   History = %History%MouseMove`, %XPos%`,%YPos%`, 5`n
   
   History = %History%Loop`,`n`{`nMouseGetPos`, `, `, WinID`nWinGetClass`, WinClass`, ahk_id `%WinID`%`n
   ;Falls Desktop nicht an dieser Stelle: alle Fenster minimieren
   History = %History%if (WinClass != "Progman" and WinClass != "WorkerW")`nSend`, #m`nelse break`n`}`n
   CoordMode, Mouse, Relative
}
else   ;"normal" Window
{
   if WinID != %OldWinID%
   {
      ;Code for activating the correct window
      History = %History%IfWinNotActive`, %WinTitle%`, `, WinActivate`, %WinTitle%`n
      History = %History%%A_Tab%WinWaitActive`, %WinTitle%`n
      History = %History%WinID := WinExist("A")`n
      OldWinID = %WinID%
   }

   ;Getting style for clearer information
   ControlGet, ControlStyle, Style, , %Controlname%, ahk_id %WinID%
   

   if InStr(Controlname, "Button")   ;Normaler Button, Checkbox, Radio,
   {
      ControlStyle := (ControlStyle & 0xF)      ;Es ist nur B0000 bis B1111 interessant
      if (ControlStyle = BS_PUSHBUTTON OR ControlStyle = BS_DEFPUSHBUTTON)
      {
         LButtonDownTime = %A_TickCount%
         History = %History%ControlClick`, %Controlname%`, ahk_id `%WinID`%`, `, Left`, 1`, D`n
      }
      else if (ControlStyle = BS_3STATE OR ControlStyle = BS_AUTO3STATE)
      {
         SendMessage, BM_GETSTATE, 0, 0, %Controlname%, ahk_id %WinID%
        state := ErrorLevel
        ;Obey: The previous state has to be used for check...
        If (state & 0x3 = BST_UNCHECKED)   ;State = CHECKED
            History = %History%Control`, Check`, `, %Controlname%`, ahk_id `%WinID`%`n
         Else If (state & 0x3 = BST_CHECKED)      ;State = INDETERMINATE
            History = %History%SendMessage`, %BM_SETCHECK%`, %BST_INDETERMINATE%`, 0`, %Controlname%, ahk_id `%WinID`%`n
         Else If (state & 0x3 = BST_INDETERMINATE)      ;State = UNCHECKED
            History = %History%Control`, UnCheck`, `, %Controlname%`, ahk_id `%WinID`%`n
      }
      else if (ControlStyle = BS_CHECKBOX OR ControlStyle = BS_AUTOCHECKBOX)
      {
         ControlGet, Checked?, Checked, , %Controlname%, ahk_id %WinID%
         if Checked? = 1   ;Beachte: Mausklick erfolgt erst nach Statuserfassung!
            History = %History%Control`, UnCheck`, `, %Controlname%`, ahk_id `%WinID`%`n
         else
            History = %History%Control`, Check`, `, %Controlname%`, ahk_id `%WinID`%`n
      }
      else if (ControlStyle = BS_RADIOBUTTON OR ControlStyle = BS_AUTORADIOBUTTON)
         History = %History%ControlClick`, %Controlname%`, ahk_id `%WinID`%`, `, Left`, 1`n
      else   ;Unhandled Button-Type
      {
         LButtonDownTime = %A_TickCount%
         History = %History%MouseClick`, Left`, %XPos%`, %YPos%`, `, `, D`n
      }
   }
   else if InStr(Controlname, "Edit")      ;Edit, Combobox (here only Edit-part)
   {
      History = %History%ControlFocus`, %Controlname%`, ahk_id `%WinID`%`n
   }
/*
   else if InStr(Controlname, "ComboBox")   ;DropDown, Combobox (hier nur Button zum droppen)
   {
      
   }
   else if InStr(Controlname, "Listbox")   ;Listbox
   {
      
   }
   else if InStr(Controlname, "Hotkey")   ;Hotkey-Control
   {
      History = %History%ControlFocus`, %Controlname%`, ahk_id `%WinID`%`n
   }
   else if InStr(Controlname, "Trackbar")   ;Slider
   {
      
   }
   */
   else   ;Klick somewhere in the window or unknown control
   {
      MouseGetPos, XPos, YPos
      LButtonDownTime = %A_TickCount%
      History = %History%MouseClick`, Left`, %XPos%`, %YPos%`, `, `, D`n
   }
}

MouseClick, Left, , , , , D
return


;########################

*$LButton Up::
if LButtonDownTime !=
{
   LButtonDownDuration := A_TickCount - LButtonDownTime
   History = %History%Sleep`, %LButtonDownDuration%`nMouseClick`, Left`, `, `, `, `, U`n
   LButtonDownTime =
}
MouseClick, Left, , , , , U
return

;########################


;Ctrl+Alt+O ( O for Open... :-) )Opens a Dialog with the written code
^!o::
Suspend, Permit
Suspend, On
Gui, 2:Add, Edit, r10, %History%
Gui, 2:Add, Button, g2Perform, Perform      ;Saves the script and launches it
Gui, 2:Show, , Script
return

2Perform:
Gui, 2:Destroy
FileDelete, WrotenScript.ahk         ;Delete previous Script
FileAppend, %History%, WrotenScript.ahk      ;Save Script
History =            ;Clear Script
OldWinID =         ;Prepare for new script
RunWait, WrotenScript.ahk               ;Run Script
return

;If the Perform-Dialog is closed clear recording
2GuiClose:
History =         ;Clear Script
OldWinID =          ;Prepare for new script
Gui, 2:Destroy
return

;########################

;Toggles activation-state
Pause::Suspend

;########################
;Reload Hotkey
^!r::
Suspend, Permit
Reload





Thanks Thalon :)

Lemming
  • Members
  • 184 posts
  • Last active: Feb 03 2014 11:03 AM
  • Joined: 20 Dec 2005

...
The Window Spy program is 99% the work of Larry Keys, which is why the AutoIt name is retained in the Start Menu. However, the name "Spy" might be changed since a few have expressed concern over its shady connotations.


I second that. "Spy" was a cool word once upon a time, but with the advent of spyware, that is no longer the case.

Just the other day, I had to run Au3_spy on a users's PC to get some Control info, and she asked whether I was "installing some kind of spyware".

With a name like AU3 SPY, I can't really blame her. Of course, I could've easily renamed the EXE, but I'd have to remember to do that every new version.

You can all it anything you like, as long as there are no spies involved. :wink:

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
Ahh, I was wondering what were these "shaddy connotations", after USSR collapsed... :-)
Indeed, there are these dreaded spywares.
Except they probably rarely name themselves "spy"...

What name to adopt? InfoRevealer? DataDigger? WindowExplorer? (sound too familiar...) ControlInquisitor? (shaddy too? ;-))
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Toralf has been working on a replacement for Window Spy. He named it AHK Window Info. For those who have time, please go give it a try and give him some feedback.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Thalon,

I finally tried your script above (sorry it took me 6 months; I'd forgotten about it). I like the concept and interface. As AHKnow said, having a better macro recorder -- especially a control-centric one like yours -- would be an enormous benefit to the community (even if manipulation of controls becomes difficult or impossible in Windows Vista).

In addition to your script, there's a lot of good info throughout this topic. I guess the problem is that not enough people know about it yet -- or maybe they lack the time and interest to contribute or give feedback.

Maybe what is needed is to create a Help Wanted topic somewhere so that great projects like this one can be given more attention.

Thanks.

Thalon
  • Members
  • 641 posts
  • Last active: Jan 02 2017 12:17 PM
  • Joined: 12 Jul 2005
I have written a bit more than above, but other projects took my time and I didn't came far now.
If interest exists I'll try me as Gravedigger and write some more code. The last point I stopped was recording keys :oops:

I hope I can get this between 2 of my running projects...
Thalon

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
There's no pressure. I know how hard it is to divide your time between competing projects. Perhaps it's best that you wait until after one or both of them is done.

Thalon
  • Members
  • 641 posts
  • Last active: Jan 02 2017 12:17 PM
  • Joined: 12 Jul 2005
After some time without doing anything at this project I did pick up it yesterday evening and spent 3 hours (while watching TV).

I have to do some code-review today and include some details - and of course test this version until I do not find any bugs any more.
As I don't have any very important projects at the moment I'll finish most of it.

The rest should only be feeding it with informations for increased usage of AHKs possibilities. I'll finish a first version with keyboard-, window-, button- and Editcontrol-Handling.
Then I post it here for testing purposes.
Rest should only be to add more controls if it works in general...

After a lookover of the present state I expect 2 more days...

Thalon

Thalon
  • Members
  • 641 posts
  • Last active: Jan 02 2017 12:17 PM
  • Joined: 12 Jul 2005
So... 2 days are over and there is much more work to do :(
But I post my actual code here.
There will be some rework in keyboard-handling, but mouse should be finished.

I've experienced one problem, where I don't know how to solve it (or if I should report it as bug):
If I have a window activated and then directly click onto a icon on desktop I get coordinates with a value higher than 32.000 !
If I click on desktop itself it doesn't happen...

For testing please click modifiers (inclusive mouse) minimum 50ms :D
I'll present a new version after weekend..

Thalon