Private Type POINTAPI
x As Long
y As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function GetCaretPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function GetFocus Lib "user32" () As Long
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function AttachThreadInput Lib "user32.dll" (ByVal idAttach As Long, ByVal idAttachTo As Long, ByVal fAttach As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function GetClientRect Lib "user32.dll" (ByVal hwnd As Long, lpRect As RECT) As Long
'Private Declare Function GetCurrentThreadId Lib "kernel32.dll" () As Long
'Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
'Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
'Private Const EM_GETRECT As Long = &HB2
Private Sub Timer1_Timer()
Dim K As POINTAPI, hwnd As Long, retVal As Long, dX As Long, dY As Long
Dim idAttach As Long, R As RECT
hwnd = GetForegroundWindow()
idAttach = GetWindowThreadProcessId(hwnd, 0)
If idAttach = App.ThreadID Then
hwnd = GetFocus()
GetCaretPos K
Else
If AttachThreadInput(App.ThreadID, idAttach, 1) <> 0 Then
hwnd = GetFocus()
GetCaretPos K
AttachThreadInput App.ThreadID, idAttach, 0
Else
If Err.LastDllError <> 1400 Then MsgBox Err.LastDllError ' 1400是INVALID_HANDLE,切换的时候会发生,正常
End If
End If
GetWindowRect hwnd, R
dX = R.Right - R.Left
dY = R.Bottom - R.Top
K.x = R.Left + K.x
K.y = R.Top + K.y
GetClientRect hwnd, R
dX = (dX - R.Right) \ 2
dY = (dY - R.Bottom) \ 2
K.x = R.Left + K.x + dX
K.y = R.Top + K.y + dY
Label1 = "Caret Position - X: " & CStr(K.x) & " Y: " & CStr(K.y)
End Sub