translating a small C# code to AHK Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
TheBeginner
Posts: 91
Joined: 19 Oct 2018, 12:05

translating a small C# code to AHK

Post by TheBeginner » 13 Sep 2022, 15:55

Anybody know how to translate this C# code into AHK, the code can retrieve the caret position from more modern applications, not just WPF/Win32/WinForms, rather Google Chrome or VS Code, Slack, etc.

C# code
Source with a bit more information > https://docs.microsoft.com/en-us/answers/questions/818647/how-to-get-caret-position-in-any-application-from.html

Code: Select all

 var guid = typeof(IAccessible).GUID;
 object accessibleObject = null;
 var retVal = WinApiProvider.AccessibleObjectFromWindow(hwnd, WinApiProvider.OBJID_CARET, ref guid, ref accessibleObject);
 var accessible = accessibleObject as IAccessible;
 accessible.accLocation(out int left, out int top, out int width, out int height, WinApiProvider.CHILDID_SELF);
.

teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: translating a small C# code to AHK  Topic is solved

Post by teadrinker » 13 Sep 2022, 18:53

Code: Select all

$F1::
   if !GetCaretPos(x, y)
      MsgBox, Cant recognize caret position
   else {
      CoordMode, Mouse
      MouseMove, x, y
   }
   Return

GetCaretPos(ByRef x, ByRef y) {
   static OBJID_CARET := 0xFFFFFFF8
   CoordMode, Caret
   if (A_CaretX != "" && A_CaretY != "")
      x := A_CaretX, y := A_CaretY
   else {
      AccObject := AccObjectFromWindow(WinExist("A"), OBJID_CARET)
      Pos := AccLocation(AccObject)
      x := Pos.x, y := Pos.y
   }
   Return x && y
}

AccObjectFromWindow(hWnd, idObject = 0) {
   static IID_IDispatch   := "{00020400-0000-0000-C000-000000000046}"
        , IID_IAccessible := "{618736E0-3C3D-11CF-810C-00AA00389B71}"
        , OBJID_NATIVEOM  := 0xFFFFFFF0, VT_DISPATCH := 9, F_OWNVALUE := 1
        , h := DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
        
   VarSetCapacity(IID, 16), idObject &= 0xFFFFFFFF, AccObject := 0
   DllCall("ole32\CLSIDFromString", "Str", idObject = OBJID_NATIVEOM ? IID_IDispatch : IID_IAccessible, "Ptr", &IID)
   if DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject, "Ptr", &IID, "PtrP", pAcc) = 0
      AccObject := ComObject(VT_DISPATCH, pAcc, F_OWNVALUE)
   Return AccObject
}

AccLocation(Acc, ChildId := 0, ByRef Position := "") {
   static type := (VT_BYREF := 0x4000) | (VT_I4 := 3)
   try Acc.accLocation( ComObject(type, &x := 0), ComObject(type, &y := 0)
                      , ComObject(type, &w := 0), ComObject(type, &h := 0), ChildId )
   catch
      Return
   _x := NumGet(x, "int"), _y := NumGet(y, "int"), _w = NumGet(w, "int"), _h := NumGet(h, "int")
   Position := "x" . _x . " y" . _y . " w" . _w . " h" . _h
   Return {x: _x, y: _y, w: _w, h: _h}
}

TheBeginner
Posts: 91
Joined: 19 Oct 2018, 12:05

Re: translating a small C# code to AHK

Post by TheBeginner » 14 Sep 2022, 01:22

WOW!! Works perfectly with every application I've tested

Finally a way to track the caret, there is probably even away to know if you are in a active text With the AccessibleObject approach
but it's beyond my skill

This will return the caret position even if the element or window is no longer in focus,
I think It could be huge to know where the caret it, the name of the object, and whether that object is in focus (aka ready to be typed in)

That way you can avoid sending keystrokes when there is no text field and focus

Simply Awesome

TheBeginner
Posts: 91
Joined: 19 Oct 2018, 12:05

Re: translating a small C# code to AHK

Post by TheBeginner » 23 Sep 2022, 00:44

what do I need to know, if I want to expand this functionality to know if the caret is inside a focused field (a field that is ready to be typed in)
I'm not sure it's within my skill but I could give it a try

Post Reply

Return to “Ask for Help (v1)”