MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey-v1.0 / ScriptGetCaret

Method ScriptGetCaret

Source/script.cpp:10683–10744  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

10681
10682
10683VarSizeType Script::ScriptGetCaret(VarTypeType aVarType, char *aBuf)
10684{
10685 if (!aBuf)
10686 return MAX_NUMBER_LENGTH;
10687
10688 // These static variables are used to keep the X and Y coordinates in sync with each other, as a snapshot
10689 // of where the caret was at one precise instant in time. This is because the X and Y vars are resolved
10690 // separately by the script, and due to split second timing, they might otherwise not be accurate with
10691 // respect to each other. This method also helps performance since it avoids unnecessary calls to
10692 // ATTACH_THREAD_INPUT.
10693 static HWND sForeWinPrev = NULL;
10694 static DWORD sTimestamp = GetTickCount();
10695 static POINT sPoint;
10696 static BOOL sResult;
10697
10698 // I believe only the foreground window can have a caret position due to relationship with focused control.
10699 HWND target_window = GetForegroundWindow(); // Variable must be named target_window for ATTACH_THREAD_INPUT.
10700 if (!target_window) // No window is in the foreground, report blank coordinate.
10701 {
10702 *aBuf = '\0';
10703 return 0;
10704 }
10705
10706 DWORD now_tick = GetTickCount();
10707
10708 if (target_window != sForeWinPrev || now_tick - sTimestamp > 5) // Different window or too much time has passed.
10709 {
10710 // Otherwise:
10711 ATTACH_THREAD_INPUT // au3: Doesn't work without attaching.
10712 sResult = GetCaretPos(&sPoint);
10713 HWND focused_control = GetFocus(); // Also relies on threads being attached.
10714 DETACH_THREAD_INPUT
10715 if (!sResult)
10716 {
10717 *aBuf = '\0';
10718 return 0;
10719 }
10720 ClientToScreen(focused_control ? focused_control : target_window, &sPoint);
10721 if (!(g.CoordMode & COORD_MODE_CARET)) // Using the default, which is coordinates relative to window.
10722 {
10723 // Convert screen coordinates to window coordinates:
10724 RECT rect;
10725 GetWindowRect(target_window, &rect);
10726 sPoint.x -= rect.left;
10727 sPoint.y -= rect.top;
10728 }
10729 // Now that all failure conditions have been checked, update static variables for the next caller:
10730 sForeWinPrev = target_window;
10731 sTimestamp = now_tick;
10732 }
10733 else // Same window and recent enough, but did prior call fail? If so, provide a blank result like the prior.
10734 {
10735 if (!sResult)
10736 {
10737 *aBuf = '\0';
10738 return 0;
10739 }
10740 }

Callers 1

GetMethod · 0.80

Calls

no outgoing calls

Tested by

no test coverage detected