| 
			
				|  | Cheat Engine The Official Site of Cheat Engine
 
 
 |  
 
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| AylinCE Grandmaster Cheater Supreme
 
  Reputation: 37 
 Joined: 16 Feb 2017
 Posts: 1527
 
 
 | 
			
				|  Posted: Mon Oct 14, 2024 9:06 pm    Post subject: Get the position of the text cursor (Caret)! |   |  
				| 
 |  
				| I tried this in many ways but the result always remained with the "LuaJIT" or "ffi" module. 
 Below is a sample code, it needs to print the position of the blinking cursor (caret) in the Windows window but I did not get the correct result.
 
 User32.dll Caret:
 
  	  | Code: |  	  | <DllImport("user32.dll", ExactSpelling:=True)> _ Public Shared Function GetCaretPos(<Out> ByRef pt As Point) As BOOL
 End Function
 | 
 
 User32.dll POINT:
 
  	  | Code: |  	  | <Serializable, StructLayout(LayoutKind.Sequential), TypeConverter(GetType(PointConverter)), ComVisible(True)> _ Public Structure Point
 Public Shared ReadOnly Empty As Point
 Private x As Integer
 Private y As Integer
 Public Sub New(ByVal x As Integer, ByVal y As Integer)
 Me.x = x
 Me.y = y
 End Sub
 
 Public Sub New(ByVal sz As Size)
 Me.x = sz.Width
 Me.y = sz.Height
 End Sub
 
 Public Sub New(ByVal dw As Integer)
 Me.x = CShort(Point.LOWORD(dw))
 Me.y = CShort(Point.HIWORD(dw))
 End Sub
 
 <Browsable(False)> _
 Public ReadOnly Property IsEmpty As Boolean
 Get
 Return ((Me.x = 0) AndAlso (Me.y = 0))
 End Get
 End Property
 
 Public Property X As Integer
 Get
 Return Me.x
 End Get
 Set(ByVal value As Integer)
 Me.x = value
 End Set
 End Property
 
 Public Property Y As Integer
 Get
 Return Me.y
 End Get
 Set(ByVal value As Integer)
 Me.y = value
 End Set
 End Property
 
 Public Shared Widening Operator CType(ByVal p As Point) As PointF
 Return New PointF(CSng(p.X), CSng(p.Y))
 End Operator
 
 Public Shared Narrowing Operator CType(ByVal p As Point) As Size
 Return New Size(p.X, p.Y)
 End Operator
 
 Public Shared Operator +(ByVal pt As Point, ByVal sz As Size) As Point
 Return Point.Add(pt, sz)
 End Operator
 
 Public Shared Operator -(ByVal pt As Point, ByVal sz As Size) As Point
 Return Point.Subtract(pt, sz)
 End Operator
 
 Public Shared Operator =(ByVal left As Point, ByVal right As Point) As Boolean
 Return ((left.X = right.X) AndAlso (left.Y = right.Y))
 End Operator
 
 Public Shared Operator <>(ByVal left As Point, ByVal right As Point) As Boolean
 Return Not (left = right)
 End Operator
 
 Public Shared Function Add(ByVal pt As Point, ByVal sz As Size) As Point
 Return New Point((pt.X + sz.Width), (pt.Y + sz.Height))
 End Function
 
 Public Shared Function Subtract(ByVal pt As Point, ByVal sz As Size) As Point
 Return New Point((pt.X - sz.Width), (pt.Y - sz.Height))
 End Function
 
 Public Shared Function Ceiling(ByVal value As PointF) As Point
 Return New Point(CInt(Math.Ceiling(CDbl(value.X))), CInt(Math.Ceiling(CDbl(value.Y))))
 End Function
 
 Public Shared Function Truncate(ByVal value As PointF) As Point
 Return New Point(CInt(value.X), CInt(value.Y))
 End Function
 
 Public Shared Function Round(ByVal value As PointF) As Point
 Return New Point(CInt(Math.Round(CDbl(value.X))), CInt(Math.Round(CDbl(value.Y))))
 End Function
 
 Public Overrides Function Equals(ByVal obj As Object) As Boolean
 If Not TypeOf obj Is Point Then
 Return False
 End If
 Dim point As Point = DirectCast(obj, Point)
 Return ((point.X = Me.X) AndAlso (point.Y = Me.Y))
 End Function
 
 Public Overrides Function GetHashCode() As Integer
 Return (Me.x Xor Me.y)
 End Function
 
 Public Sub Offset(ByVal dx As Integer, ByVal dy As Integer)
 Me.X = (Me.X + dx)
 Me.Y = (Me.Y + dy)
 End Sub
 
 Public Sub Offset(ByVal p As Point)
 Me.Offset(p.X, p.Y)
 End Sub
 
 Public Overrides Function ToString() As String
 Dim textArray1 As String() = New String() { "{X=", Me.X.ToString(CultureInfo.CurrentCulture), ",Y=", Me.Y.ToString(CultureInfo.CurrentCulture), "}" }
 Return String.Concat(textArray1)
 End Function
 
 Private Shared Function HIWORD(ByVal n As Integer) As Integer
 Return ((n >> &H10) And &HFFFF)
 End Function
 
 Private Shared Function LOWORD(ByVal n As Integer) As Integer
 Return (n And &HFFFF)
 End Function
 
 Shared Sub New()
 End Sub
 End Structure
 | 
 
 
  	  | Code: |  	  | function GetCaretPos() local point = { x = 0, y = 0 }
 local result = executeCodeLocalEx("user32.GetCaretPos", point) -- nil
 -- executeCodeLocalEx("user32.GetCaretPos", "") -- 1
 if result then
 return point.x, point.y
 else
 return nil, nil
 end
 end
 
 local function printCaretPosition()
 local x, y = GetCaretPos()
 if x and y then
 print(string.format("caret position: (%d, %d)", x, y))
 else
 print("Unable to get caret position")
 end
 end
 
 printCaretPosition()
 | 
 
 
 As a result of my research, I learned that the "ffi" module can do this.
 
 However, although I left the "ffi.dll" library in the "C:\Program Files\Cheat Engine 7.5\clibs64" folder, I got errors like "local ffi = require("ffi")" path not found.
 
 My question is:
 If there are multiple notebooks in a Windows window (Desktop), I want to print the blinking text cursor (Caret) in which one or its position.
 
 Note: Please, do not suggest me to click somewhere all the time and get "getMousePos" or "getCursorPos".
 
 I want to see the cursor's position (Position) at runtime (Write).
 
 ChatGPT keeps telling me that the most effective method is the "ffi" module.
 
 
  	  | Code: |  	  | -- Define the necessary Windows API functions local ffi = require("ffi")
 
 ffi.cdef[[
 typedef struct {
 int x;
 int y;
 } POINT;
 
 bool GetCaretPos(POINT* lpPoint);
 ]]
 
 local user32 = ffi.load("user32.dll")
 
 -- Function to get caret position
 local function GetCaretPos()
 local point = ffi.new("POINT")
 if user32.GetCaretPos(point) then
 return point.x, point.y
 else
 return nil, nil
 end
 end
 
 -- Function to print caret position
 local function printCaretPosition()
 local x, y = GetCaretPos()
 if x and y then
 print(string.format("caret position: (%d, %d)", x, y))
 else
 print("Unable to get caret position")
 end
 end
 
 -- Example usage: call printCaretPosition to print the caret position
 printCaretPosition()
 
 | 
 
 But if you have a workable solution, feel free to contribute to this project.
 Thanks in advance.
 _________________
 
 |  |  
		| Back to top |  |  
		|  |  
		| xxhehe Expert Cheater
 
 ![]() Reputation: 0 
 Joined: 11 Mar 2015
 Posts: 154
 
 
 | 
			
				|  Posted: Fri Nov 15, 2024 5:40 am    Post subject: Re: Get the position of the text cursor (Caret)! |   |  
				| 
 |  
				|  	  | AylinCE wrote: |  	  | I tried this in many ways but the result always remained with the "LuaJIT" or "ffi" module. 
 Below is a sample code, it needs to print the position of the blinking cursor (caret) in the Windows window but I did not get the correct result.
 
 User32.dll Caret:
 
  	  | Code: |  	  | <DllImport("user32.dll", ExactSpelling:=True)> _ Public Shared Function GetCaretPos(<Out> ByRef pt As Point) As BOOL
 End Function
 | 
 
 User32.dll POINT:
 
  	  | Code: |  	  | <Serializable, StructLayout(LayoutKind.Sequential), TypeConverter(GetType(PointConverter)), ComVisible(True)> _ Public Structure Point
 Public Shared ReadOnly Empty As Point
 Private x As Integer
 Private y As Integer
 Public Sub New(ByVal x As Integer, ByVal y As Integer)
 Me.x = x
 Me.y = y
 End Sub
 
 Public Sub New(ByVal sz As Size)
 Me.x = sz.Width
 Me.y = sz.Height
 End Sub
 
 Public Sub New(ByVal dw As Integer)
 Me.x = CShort(Point.LOWORD(dw))
 Me.y = CShort(Point.HIWORD(dw))
 End Sub
 
 <Browsable(False)> _
 Public ReadOnly Property IsEmpty As Boolean
 Get
 Return ((Me.x = 0) AndAlso (Me.y = 0))
 End Get
 End Property
 
 Public Property X As Integer
 Get
 Return Me.x
 End Get
 Set(ByVal value As Integer)
 Me.x = value
 End Set
 End Property
 
 Public Property Y As Integer
 Get
 Return Me.y
 End Get
 Set(ByVal value As Integer)
 Me.y = value
 End Set
 End Property
 
 Public Shared Widening Operator CType(ByVal p As Point) As PointF
 Return New PointF(CSng(p.X), CSng(p.Y))
 End Operator
 
 Public Shared Narrowing Operator CType(ByVal p As Point) As Size
 Return New Size(p.X, p.Y)
 End Operator
 
 Public Shared Operator +(ByVal pt As Point, ByVal sz As Size) As Point
 Return Point.Add(pt, sz)
 End Operator
 
 Public Shared Operator -(ByVal pt As Point, ByVal sz As Size) As Point
 Return Point.Subtract(pt, sz)
 End Operator
 
 Public Shared Operator =(ByVal left As Point, ByVal right As Point) As Boolean
 Return ((left.X = right.X) AndAlso (left.Y = right.Y))
 End Operator
 
 Public Shared Operator <>(ByVal left As Point, ByVal right As Point) As Boolean
 Return Not (left = right)
 End Operator
 
 Public Shared Function Add(ByVal pt As Point, ByVal sz As Size) As Point
 Return New Point((pt.X + sz.Width), (pt.Y + sz.Height))
 End Function
 
 Public Shared Function Subtract(ByVal pt As Point, ByVal sz As Size) As Point
 Return New Point((pt.X - sz.Width), (pt.Y - sz.Height))
 End Function
 
 Public Shared Function Ceiling(ByVal value As PointF) As Point
 Return New Point(CInt(Math.Ceiling(CDbl(value.X))), CInt(Math.Ceiling(CDbl(value.Y))))
 End Function
 
 Public Shared Function Truncate(ByVal value As PointF) As Point
 Return New Point(CInt(value.X), CInt(value.Y))
 End Function
 
 Public Shared Function Round(ByVal value As PointF) As Point
 Return New Point(CInt(Math.Round(CDbl(value.X))), CInt(Math.Round(CDbl(value.Y))))
 End Function
 
 Public Overrides Function Equals(ByVal obj As Object) As Boolean
 If Not TypeOf obj Is Point Then
 Return False
 End If
 Dim point As Point = DirectCast(obj, Point)
 Return ((point.X = Me.X) AndAlso (point.Y = Me.Y))
 End Function
 
 Public Overrides Function GetHashCode() As Integer
 Return (Me.x Xor Me.y)
 End Function
 
 Public Sub Offset(ByVal dx As Integer, ByVal dy As Integer)
 Me.X = (Me.X + dx)
 Me.Y = (Me.Y + dy)
 End Sub
 
 Public Sub Offset(ByVal p As Point)
 Me.Offset(p.X, p.Y)
 End Sub
 
 Public Overrides Function ToString() As String
 Dim textArray1 As String() = New String() { "{X=", Me.X.ToString(CultureInfo.CurrentCulture), ",Y=", Me.Y.ToString(CultureInfo.CurrentCulture), "}" }
 Return String.Concat(textArray1)
 End Function
 
 Private Shared Function HIWORD(ByVal n As Integer) As Integer
 Return ((n >> &H10) And &HFFFF)
 End Function
 
 Private Shared Function LOWORD(ByVal n As Integer) As Integer
 Return (n And &HFFFF)
 End Function
 
 Shared Sub New()
 End Sub
 End Structure
 | 
 
 
  	  | Code: |  	  | function GetCaretPos() local point = { x = 0, y = 0 }
 local result = executeCodeLocalEx("user32.GetCaretPos", point) -- nil
 -- executeCodeLocalEx("user32.GetCaretPos", "") -- 1
 if result then
 return point.x, point.y
 else
 return nil, nil
 end
 end
 
 local function printCaretPosition()
 local x, y = GetCaretPos()
 if x and y then
 print(string.format("caret position: (%d, %d)", x, y))
 else
 print("Unable to get caret position")
 end
 end
 
 printCaretPosition()
 | 
 
 
 As a result of my research, I learned that the "ffi" module can do this.
 
 However, although I left the "ffi.dll" library in the "C:\Program Files\Cheat Engine 7.5\clibs64" folder, I got errors like "local ffi = require("ffi")" path not found.
 
 My question is:
 If there are multiple notebooks in a Windows window (Desktop), I want to print the blinking text cursor (Caret) in which one or its position.
 
 Note: Please, do not suggest me to click somewhere all the time and get "getMousePos" or "getCursorPos".
 
 I want to see the cursor's position (Position) at runtime (Write).
 
 ChatGPT keeps telling me that the most effective method is the "ffi" module.
 
 
  	  | Code: |  	  | -- Define the necessary Windows API functions local ffi = require("ffi")
 
 ffi.cdef[[
 typedef struct {
 int x;
 int y;
 } POINT;
 
 bool GetCaretPos(POINT* lpPoint);
 ]]
 
 local user32 = ffi.load("user32.dll")
 
 -- Function to get caret position
 local function GetCaretPos()
 local point = ffi.new("POINT")
 if user32.GetCaretPos(point) then
 return point.x, point.y
 else
 return nil, nil
 end
 end
 
 -- Function to print caret position
 local function printCaretPosition()
 local x, y = GetCaretPos()
 if x and y then
 print(string.format("caret position: (%d, %d)", x, y))
 else
 print("Unable to get caret position")
 end
 end
 
 -- Example usage: call printCaretPosition to print the caret position
 printCaretPosition()
 
 | 
 
 But if you have a workable solution, feel free to contribute to this project.
 Thanks in advance.
 | 
 
 Write an executable in C/C++/luajit  to get the position of the text caret, and then use CE's executeCode/executeCodeEx to execute it.
 |  |  
		| Back to top |  |  
		|  |  
		| AylinCE Grandmaster Cheater Supreme
 
  Reputation: 37 
 Joined: 16 Feb 2017
 Posts: 1527
 
 
 | 
			
				|  Posted: Fri Nov 15, 2024 6:26 am    Post subject: Re: Get the position of the text cursor (Caret)! |   |  
				| 
 |  
				|  	  | xxhehe wrote: |  	  | 
 Write an executable in C/C++/luajit  to get the position of the text caret, and then use CE's executeCode/executeCodeEx to execute it.
 | 
 
 Join the project only if you have a solution.
 The advice you give requires other external coding and leads to more complex coding (probably in coding languages we do not know) instead of solving the problem in the current situation.
 
 So which one do you recommend me to specialize in?
 C? C++ ? luajit ?
   
 Note: Windows' "GetCursorPos()" (Mouse) function works and produces correct results.
 However, "GetCaretPos()" always returns "0" or does not work.
 This is a bit strange!
 _________________
 
 |  |  
		| Back to top |  |  
		|  |  
		| xxhehe Expert Cheater
 
 ![]() Reputation: 0 
 Joined: 11 Mar 2015
 Posts: 154
 
 
 | 
			
				|  Posted: Fri Nov 15, 2024 7:39 am    Post subject: Re: Get the position of the text cursor (Caret)! |   |  
				| 
 |  
				|  	  | AylinCE wrote: |  	  |  	  | xxhehe wrote: |  	  | 
 Write an executable in C/C++/luajit  to get the position of the text caret, and then use CE's executeCode/executeCodeEx to execute it.
 | 
 
 Join the project only if you have a solution.
 The advice you give requires other external coding and leads to more complex coding (probably in coding languages we do not know) instead of solving the problem in the current situation.
 
 So which one do you recommend me to specialize in?
 C? C++ ? luajit ?
   
 Note: Windows' "GetCursorPos()" (Mouse) function works and produces correct results.
 However, "GetCaretPos()" always returns "0" or does not work.
 This is a bit strange!
 | 
 I don't care about your project..As a true LUA novice, I may indeed have underestimated the difficulty of implementation.
 |  |  
		| Back to top |  |  
		|  |  
		| AylinCE Grandmaster Cheater Supreme
 
  Reputation: 37 
 Joined: 16 Feb 2017
 Posts: 1527
 
 
 | 
			
				|  Posted: Fri Nov 15, 2024 8:32 am    Post subject: |   |  
				| 
 |  
				| By "project" I only meant this question topic. 
 The codes I gave at the beginning of the topic have already been used and tested, but no results were obtained.
 
 Please only participate in this topic with code examples that have yielded positive results.
 
 Otherwise, I do not intend to drag the topic into a discussion area.
 
 Thanks for your feedback anyway.
 _________________
 
 |  |  
		| Back to top |  |  
		|  |  
		| panraven Grandmaster Cheater
 
 ![]() Reputation: 62 
 Joined: 01 Oct 2008
 Posts: 958
 
 
 |  |  
		| Back to top |  |  
		|  |  
		| AylinCE Grandmaster Cheater Supreme
 
  Reputation: 37 
 Joined: 16 Feb 2017
 Posts: 1527
 
 
 | 
			
				|  Posted: Fri Nov 15, 2024 10:22 am    Post subject: |   |  
				| 
 |  
				|  	  | panraven wrote: |  	  | The <Out> parameter need to provide a memory address for the function to write to (as return results) 
 eg.
 
  	  | Code: |  	  | local function GetCaretPos()
 local ms = createMemoryStream()
 ms.writeQword(0x12345678) -- just allocate 2x 4 bytes
 --    print(ms.Size)
 local ok = executeCodeLocalEx("user32.GetCaretPos", ms.Memory)
 ms.Position = 0 -- reset read from start
 local x = ms.readDword()-- read in sequence
 local y = ms.readDword()-- don't x,y = ms.readDword(), ms.readDword()
 ms.Destroy()
 --    print(ok, x, y)
 return x,y
 end
 
 print(GetCaretPos())
 
 | 
 
 I don't know what the numbers means (in pixel? chars?),  tho.
 | 
 
 Perfect working example and thanks.
 
 You are a secret weapon! You only focus on the right targets.
 
 Thanks.
 
 The code you created does the following:
 
 It does not print the caret's location on the desktop.
 It only prints the current location of the caret in the material (Notepad, Lua Script etc.) that is being written.
 In other words, it takes focus from the material (Notepad.Width, Notepad.Height) and tells its location in it.
 
 When there are 3 notebooks on the desktop, it does not tell which one "Caret" is in, but actually, this is the solution I wanted.
 
 This code will save me the trouble of calculating "Left, Top, Height, Width" to get the cursor's focus.
 
 Note: With the "Y" parameter (by clicking on the previous and next lines) we can calculate the height of the current font.
 
 Similarly, the "x" parameter can calculate the "Width" covered by each letter.
 
 
 I don't know why you joined so late, but thanks again for your effective solution. (+1 to be returned after the time limit).
 
 ***
 _________________
 
 |  |  
		| Back to top |  |  
		|  |  
		| xxhehe Expert Cheater
 
 ![]() Reputation: 0 
 Joined: 11 Mar 2015
 Posts: 154
 
 
 | 
			
				|  Posted: Fri Nov 15, 2024 8:50 pm    Post subject: |   |  
				| 
 |  
				|  	  | panraven wrote: |  	  | The <Out> parameter need to provide a memory address for the function to write to (as return results) 
 eg.
 
  	  | Code: |  	  | local function GetCaretPos()
 local ms = createMemoryStream()
 ms.writeQword(0x12345678) -- just allocate 2x 4 bytes
 --    print(ms.Size)
 local ok = executeCodeLocalEx("user32.GetCaretPos", ms.Memory)
 ms.Position = 0 -- reset read from start
 local x = ms.readDword()-- read in sequence
 local y = ms.readDword()-- don't x,y = ms.readDword(), ms.readDword()
 ms.Destroy()
 --    print(ok, x, y)
 return x,y
 end
 
 print(GetCaretPos())
 
 | 
 
 I don't know what the numbers means (in pixel? chars?),  tho.
 | 
 
 
 Great code. Use executeCodeLocalEx to call external programs, such as exe/dll, to implement GetCaretPos.
 |  |  
		| Back to top |  |  
		|  |  
		|  |  
  
	| 
 
 | You cannot post new topics in this forum You cannot reply to topics in this forum
 You cannot edit your posts in this forum
 You cannot delete your posts in this forum
 You cannot vote in polls in this forum
 You cannot attach files in this forum
 You can download files in this forum
 
 |  |