'获得拥有输入焦点的窗口的句柄
Private Declare Function GetFocus Lib "user32" _
() As Long
'获得前台窗口的句柄。这里的“前台窗口”是指前台应用程序的活动窗口
Private Declare Function GetForegroundWindow Lib "user32" _
() As Long
'通常,系统内的每个线程都有自己的输入队列。本函数(既“连接线程输入函数”)允许线程和进程共享输入队列。连接了线程后,输入焦点、窗口激活、鼠标捕获、键盘状态以及输入队列状态都会进入共享状态
Private Declare Function AttachThreadInput Lib "user32" _
(ByVal idAttach As Long, _
ByVal idAttachTo As Long, _
ByVal fAttach As Long) As Long
'获取当前线程一个唯一的线程标识符
Private Declare Function GetCurrentThreadId Lib "kernel32" _
() As Long
'获取与指定窗口关联在一起的一个进程和线程标识符
Private Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, _
lpdwProcessId As Long) As Long
'暂停线索
Private Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)
'判断插入符的当前位置
Private Declare Function GetCaretPos Lib "user32" _
(lpPoint As POINTAPI) As Long
Private Type POINTAPI
x As Long
y As Long
End Type
'判断窗口内以客户区坐标表示的一个点的屏幕坐标
Private Declare Function ClientToScreen Lib "user32" _
(ByVal hwnd As Long, _
lpPoint As POINTAPI) As Long
Sub main()
Dim FoHandle As Long
Dim PHandle As Long
Dim ThisPoint As Long
Dim Point As POINTAPI
FoHandle = GetFocus
PHandle = GetForegroundWindow
AttachThreadInput GetCurrentThreadId, GetWindowThreadProcessId(PHandle, 0), 1
ThisPoint = GetCaretPos(Point)
ClientToScreen FoHandle, Point
Sleep 2
Debug.Print Point.x, Point.y, ThisPoint
If FoHandle = PHandle Then '这里是否有问题???
Form1.Visible = False
Form1.Visible = True
Form1.Left = Point.x
Form1.Top = Point.y
DoEvents
Else
Form1.Visible = False
End If
'获得拥有输入焦点的窗口的句柄
Private Declare Function GetFocus Lib "user32" _
() As Long
'获得前台窗口的句柄。这里的“前台窗口”是指前台应用程序的活动窗口
Private Declare Function GetForegroundWindow Lib "user32" _
() As Long
'通常,系统内的每个线程都有自己的输入队列。本函数(既“连接线程输入函数”)允许线程和进程共享输入队列。连接了线程后,输入焦点、窗口激活、鼠标捕获、键盘状态以及输入队列状态都会进入共享状态
Private Declare Function AttachThreadInput Lib "user32" _
(ByVal idAttach As Long, _
ByVal idAttachTo As Long, _
ByVal fAttach As Long) As Long
'获取当前线程一个唯一的线程标识符
Private Declare Function GetCurrentThreadId Lib "kernel32" _
() As Long
'获取与指定窗口关联在一起的一个进程和线程标识符
Private Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, _
lpdwProcessId As Long) As Long
'暂停线索
Private Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)
'判断插入符的当前位置
Private Declare Function GetCaretPos Lib "user32" _
(lpPoint As POINTAPI) As Long
Private Type POINTAPI
x As Long
y As Long
End Type
'判断窗口内以客户区坐标表示的一个点的屏幕坐标
Private Declare Function ClientToScreen Lib "user32" _
(ByVal hwnd As Long, _
lpPoint As POINTAPI) As Long
'这个函数能为窗口指定一个新位置和状态。它也可改变窗口在内部窗口列表中的位置。该函数与DeferWindowPos函数相似,只是它的作用是立即表现出来的(在vb里使用:针对vb窗体,如它们在win32下屏蔽或最小化,则需重设最顶部状态。如有必要,请用一个子类处理模块来重设最顶部状态
Private Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, _
ByVal hWndInsertAfter As Long, _
ByVal x As Long, _
ByVal y As Long, _
ByVal cx As Long, _
ByVal cy As Long, _
ByVal wFlags As Long) As Long
Public Const SWP_NOACTIVATE = &H10
Public Const SWP_NOSIZE = &H1
Public Const SWP_SHOWWINDOW = &H40
Public Const HWND_TOPMOST = -1
Sub Main()
Dim FoHandle As Long
Dim PHandle As Long
Dim ThisPoint As Long
Dim Point As POINTAPI
FoHandle = GetFocus
PHandle = GetForegroundWindow
AttachThreadInput GetCurrentThreadId, GetWindowThreadProcessId(PHandle, 0), 1
ThisPoint = GetCaretPos(Point)
ClientToScreen FoHandle, Point
If FoHandle <> Form1.hwnd Then '自己搞懂了,是实现了,好开心-:)
Debug.Print Form1.Left
SetWindowPos Form1.hwnd, HWND_TOPMOST, Point.x, Point.y, 0, 0, SWP_NOACTIVATE Or SWP_NOSIZE Or SWP_SHOWWINDOW
DoEvents
End If
End Sub
Private Sub Timer1_Timer()
Timer1.Interval = 100 '设置成每秒触发一次事件
Call Main
End Sub