Autoit get current caret position Or current text box position - autoit

So i am working on a project and i got stuck on this part.
I am trying to locate the position of ether the typing caret(The blinking line while typing) or the current text box that is being typed in.
The main part that is hard is i am looking to do this for every input on my computer (Firefox search, Notepad, Renaming files, writing this post...)
I am beginning to doubt that auto-it can do this, i am open to using another language that can do this. (I have not checked any other language but Auto-it yet)
I have tested "WinGetCaretPos()" and a few other random scripts, but they had the same problem, they don't return the correct position.
~Thanks

Not all controls are standard window controls that can be accessed with AutoIt functions. Many programs (especially browsers) have nonstandard controls so "every input" on the computer might be hard to get.
Here is an example of how to get the control information of any active window that is giving focus to a control AND has standard windows controls.
HotKeySet("{ESC}", "Terminate")
While 1
Sleep(500)
GetControlFocus()
WEnd
Func GetControlFocus()
Local $hWinHandle = WinGetHandle("[Active]")
Local $sControl = ControlGetFocus($hWinHandle)
Local $sText = "The active window handle is: " & $hWinHandle & #CRLF
If $sControl <> "" Then
$sText &= "The control with focus in the active window is: " & $sControl & #CRLF
Local $aPos = ControlGetPos($hWinHandle, "", $sControl)
$sText &= "Mouse position: X: " & $aPos[0] & " Y: " & $aPos[1] & #CRLF & "Size: " & $aPos[2] & ", " & $aPos[3]
Else
$sText &= "The active window is not giving focus to a control that AutoIt recognizes."
EndIf
ToolTip($sText, 0, 0)
EndFunc ;==>GetControlFocus
Func Terminate()
Exit
EndFunc ;==>Terminate
You can get the control position of other programs using IUIAutomation and this UDF. But it would not be as simple as using a few standard AutoIt functions.

Related

Rule runs manually but returns the error code "an unexpected error has occurred" when incoming mail arrives

Microsoft 365 V2205, build 15225.20204
The following VBA macro used to work, and it still works when run manually. A couple of years ago, I am guessing that a change from Microsoft occurred, and it now returns the error code "an unexpected error has occurred" when Outlook automatically runs it. Can someone show me a fix for the rule/VBA that will allow the rule/VBA to:
On an incoming email
Mark it as high importance
Update the subject
Set a category “Bill”
Set a reminder
Here is the:
Rules description
Apply this rule after the message arrives
With ‘Your credit card statement is ready’ or ‘Your statement is ready for credit card ending’
And on this computer only
Mark it as high importance
And run Damian.PendingPaid1
Here is the VBA:
Sub PendingPaid1(Item As Outlook.MailItem)
Item.Categories = "Bill"
Item.Subject = Item.Subject & " " & Chr(150) & " Pending " & Chr(150) & " PAID " & Chr(150) & " 220"
Item.ReminderSet = True
Item.FlagDueBy = Date + 1 & Space(1) & "8:45 AM" ' Remind 1 day from now.
Item.ReminderTime = Date + 1 & Space(1) & "8:45 AM" ' Remind 1 day from now.
Item.Save
End Sub

SciTE Script - How to get inside a Tree Control to set checkboxes

I'm using AutoIt and SciTE to create an installation script. The problem I am running into is that there is a tree menu for selection of features. I can select the whole treeview (SysTreeView32), but am not sure how to get inside it to check the boxes without doing a mouse move and click (not a great option).
The Treeview looks like this:
The Control Info from AutoIT is like this:
I'm sure it is possible, just can't figure out how to do it. This is my first attempt a such a script. Creating a response file does not work for this exe for some reason. So - this appears to be my only way out to create a somewhat silent install (not silent anymore, but at least automated).
* EDIT - Current State of Things *
I did figure out how to do some of this, but I still can't figure out if the items is selected before accessing it. So - since it toggles, I could be turning off a feature I want!
$hWnd = WinWaitActive($WindowTitle, 'Select Features')
$tvCtl = ControlGetHandle($WindowTitle, '', 'SysTreeView321')
$firstItem = _GUICtrlTreeView_FindItem($tvCtl, 'eBooks')
_GUICtrlTreeView_SelectItem($tvCtl, $firstItem, $TVGN_FIRSTVISIBLE)
_GUICtrlTreeView_ClickItem($tvCtl, $firstItem, "left", True, 1)
Send('{SPACE}')
I wouldn't think I would have to send the space since I sent the ClickItem, but seems so.
I could also do this:
ControlTreeView($hWnd, '', $tvCtl, 'Select', '#0')
ControlSend($hWnd, '', $tvCtl, ' ')
That will toggle the first one. So - i can count them all up and do it that way.
But when I check for "IsEnabled" or "IsChecked", it always says NO. So - I can't check the ones I need only. I have to hope their status is what I expect.
Here is how I am checking "IsChecked" and "IsEnabled":
If ControlCommand($hWnd, '', $logTool, 'IsEnabled') then
ConsoleWrite('Log Tool - IsEnabled' & #CRLF)
Else
ConsoleWrite('Log Tool - NOTEnabled' & #CRLF)
EndIf
and
If ControlCommand($hWnd, '', $logTool, 'IsChecked') then
ConsoleWrite('Log Tool - IsChecked' & #CRLF)
Else
ConsoleWrite('Log Tool - NOTChecked' & #CRLF)
EndIf
It always comes back NOTEnabled and NOTChecked. I made sure that I ran the same procedure above: FindItem, SelectItem, ClickItem. And, the correct item is highlighted/selected when this procedure is run - I can see that. So - it just isn't returning a proper value.
Opt('WinTitleMatchMode', 2)
$hWnd = WinGetHandle("InstallShield Wizard") ; Notice the correct title
$hTree = ControlGetHandle($hWnd, '', "[CLASS:SysTreeView32;INSTANCE:1]")
; == Now you can interact with the treeview with functions from "GuiTreeView.au3"
EDIT:
Try this
; Select the item so:
_GUICtrlTreeView_SelectItem($hTree, $hItem, $TVGN_CARET)
; Get checked state:
_GUICtrlTreeView_GetChecked($hTree, $hItem)
For more deatails read the AutoIt help.

AutoIT execute application hotkey

I see there are a lot of guides about setting hotkeys with autoit. What I want to do though is execute an applications hotkey.
So for instance, I have this to load firefox
Run(#ProgramFilesDir & "\Mozilla Firefox\firefox.exe", "", #SW_MINIMIZE)
Opt("WinTitleMatchMode", 2)
WinWait("Mozilla Firefox")
WinSetState("Mozilla Firefox", "", #SW_MINIMIZE)
Now in firefox's menu, I can see that the combination of Ctrl + D will bookmark a page. Is there any way to perform this action once firefox has been loaded, via autoit?
Thanks
Just use the Send command. Also have a look at SendKeepActive.
With the FireFox window active, just use the Send command.
Send("^d")
There are a few ways to go about doing this. I will list a few different methods below.
Method One - Send Keys
; Below is simply the code you listed in the example to open Firefox and wait for it to load.
Run(#ProgramFilesDir & "\Mozilla Firefox\firefox.exe", "", #SW_MINIMIZE)
Opt("WinTitleMatchMode", 2)
WinWait("Mozilla Firefox")
WinSetState("Mozilla Firefox", "", #SW_MINIMIZE)
; Once FireFox is loaded, and you are at the page you want to bookmark, send Ctrl+D to the page to bookmark it. Since you started the browser Minimized, you will need to activate the page first.
; Activate the window
WinActivate("Mozilla Firefox")
; Send "Ctrl + D"
Send("^d")
Method Two - AutoIt HotKeys
; Create a HotKey controller
HotKeySet("^d", "bookmarkPage")
; Your code is below again.
Run(#ProgramFilesDir & "\Mozilla Firefox\firefox.exe", "", #SW_MINIMIZE)
Opt("WinTitleMatchMode", 2)
WinWait("Mozilla Firefox")
WinSetState("Mozilla Firefox", "", #SW_MINIMIZE)
; The function that is called when "Ctrl + D" is pressed.
Func bookmarkPage ()
; Activate the window
WinActivate("Mozilla Firefox")
; Send they keys
Send("^d")
EndFunc
Method Three - MouseMove (Not recommended)
; Your code below
Run(#ProgramFilesDir & "\Mozilla Firefox\firefox.exe", "", #SW_MINIMIZE)
Opt("WinTitleMatchMode", 2)
WinWait("Mozilla Firefox")
WinSetState("Mozilla Firefox", "", #SW_MINIMIZE)
; Use the mouse move function to move the cursor to the 'Bookmark' icon.
MouseMove(xxxx,xxxx)
Sleep(100)
MouseClick("left")
I HIGHLY recommend not using the last option. I hope one of these worked for you!

how to automate uninstall of a program via autoit?

I am trying to uninstall a program from add or remove programs via an AutoIt script.
*I dont want to uninstall via removing the registry keys.
* I dont want to uninstall via running an uninstaller.
I can open "add remove programs" by a appwiz.cpl command
However I am failing to recognize the correct program name from the list and invoke an uninstall.
All I want to do is recognize my program from the list, for example "Helloworld" and invoke an uninstall.
You can just loop through all your corresponding Registry Values of which your uninstall list in your "Add or remove programs" is made of... And then directly extract the command that you want to execute. I display it in a Message Box in this example, but you could directly compare the DisplayName to "Helloworld" and then execute the UninstallString with Run(...). This is the exact same as your "Add or remove programs" would invoke. It doesn't mean simply removing registry keys. And it doesn't mean just running "any" uninstaller but the proper one, needed to exactly uninstall this very program like clicking the "Uninstall" button in appwiz.cpl will invoke. So to perform what you asked for as a result, this solution works just fine. It does not acutally handle the appwiz.cpl and cycle through the list of programs...
$uninstall_path1 = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall"
searchUninstallStrings($uninstall_path1)
$uninstall_path2 = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
searchUninstallStrings($uninstall_path2)
Func searchUninstallStrings($uninstall_path)
$i = 0
While True
$i += 1
Local $entry = RegEnumKey($uninstall_path, $i)
If #error <> 0 Then ExitLoop
$regPath = $uninstall_path & "\" & $entry
$DisplayName = RegRead($regPath, "DisplayName")
If $DisplayName <> "" Then
$message = $DisplayName & #CR
$UninstallString = RegRead($regPath, "UninstallString")
If $UninstallString <> "" Then
$message &= "Uninstall: '" & $UninstallString & "'"
MsgBox(4096, "SubKey #" & $i & ": " & $entry, $message)
EndIf
EndIf
WEnd
EndFunc
Good Luck!
I was able to successfully automate program uninstalls with the following command to open up the Programs and Features control panel menu followed by a series of keystrokes:
Run("C:\Windows\System32\control.exe appwiz.cpl")
WinWait("Programs and Features")
WinActivate("Programs and Features")
Send("ProgramNameHere")
Send("{Enter}")

Accessing VB6 Collection Item from VBScript embedded in HTML

i'm learning by practice. I was given an OCX file which according to who gave it to me was created using VB6 and I have the task of creating a user interface for it to test all the functionality that is described in a poorly written documentation file. On top of that I am not well-versed in VBScript but I've managed to dodge a few bullets while learning.
I have a method which returns a Collection and when I try to access it from VBScript I am only able to query the Count but when I try to do job.Item(i) or job(i) I get an error stating it doesn't have that property or method.
Can someone point me in the right direction to be able to traverse the contents of this collection?
I had to do it from JavaScript but since some things weren't that easy I decided that perhaps VBScript would help me bridge the gaps where JavaScript didn't cut it. I can access all properties from the ActiveXObject from JavaScript, but the methods which return other VB objects are a little more obscure to me. I've tried aJob.Item(iCount), aJob.Items(iCount) and aJob(iCount).
My code is:
For iCount = 1 To aJobs.Count
MsgBox("Num " & iCount)
MsgBox(aJobs.Item(iCount))
Next
Thanks.
People often create specialized and/or strongly typed collection classes in VB6. They don't always do it correctly though, and they sometimes create "partial" collection implementations that have no Item() method (or fail to mark it as the default member of the class). They might even have a similar method or property but name it something entirely different.
It is rarer to return a raw Collection object, but it can be done and if it is you shouldn't have the problems you have indicated from VBScript.
I just created a DLL project named "HallLib" with three classes: Hallway, DoorKnobs, and DoorKnob. The DoorKnobs class is a collection of DoorKnob objects. The Hallway class has a DoorKnobs object that it initializes with a random set of DoorKnob objects with randomly set properties. Hallway.DoorKnobs() returns the DoorKnobs collection object as its result.
It works fine in this script:
Option Explicit
Dim Hallway, DoorKnobs, DoorKnob
Set Hallway = CreateObject("HallLib.Hallway")
Set DoorKnobs = Hallway.DoorKnobs()
MsgBox "DoorKnobs.Count = " & CStr(DoorKnobs.Count)
For Each DoorKnob In DoorKnobs
MsgBox "DoorKnob.Material = " & CStr(DoorKnob.Material) & vbNewLine _
& "DoorKnob.Color = " & CStr(DoorKnob.Color)
Next
Update:
This script produces identical results:
Option Explicit
Dim Hallway, DoorKnobs, KnobIndex
Set Hallway = CreateObject("HallLib.Hallway")
Set DoorKnobs = Hallway.DoorKnobs()
MsgBox "DoorKnobs.Count = " & CStr(DoorKnobs.Count)
For KnobIndex = 1 To DoorKnobs.Count
With DoorKnobs.Item(KnobIndex)
MsgBox "DoorKnob.Material = " & CStr(.Material) & vbNewLine _
& "DoorKnob.Color = " & CStr(.Color)
End With
Next
As does:
Option Explicit
Dim Hallway, DoorKnobs, KnobIndex
Set Hallway = CreateObject("HallLib.Hallway")
Set DoorKnobs = Hallway.DoorKnobs()
MsgBox "DoorKnobs.Count = " & CStr(DoorKnobs.Count)
For KnobIndex = 1 To DoorKnobs.Count
With DoorKnobs(KnobIndex)
MsgBox "DoorKnob.Material = " & CStr(.Material) & vbNewLine _
& "DoorKnob.Color = " & CStr(.Color)
End With
Next
So I suspect you'll need to use some type library browser like OLEView to look at your OCX to see what classes and members it actually exposes.

Resources