SetActiveWindow()只适用在前台同一线程消息队列不同窗口之间调度。
SetForegroundWindow()可激活一个窗口并将其强制为前台窗口。
** test.prg
#define WM_SETFOCUS
7
#define WM_KILLFOCUS
8
#define SW_SHOWNORMAL
1
#define SWP_NOSIZE
1
#define SWP_NOMOVE
2
#define HWND_TOPMOST
-1
#define HWND_NOTOPMOST
-2
#define MY_SETFOREGROUND
0x401
DECLARE LONG SendMessage IN User32 LONG, LONG, LONG, LONG
DECLARE LONG PostMessage IN User32 LONG, LONG, LONG, LONG
DECLARE LONG GetForegroundWindow IN user32
DECLARE LONG GetCurrentThreadId IN kernel32
DECLARE LONG GetWindowThreadProcessId IN user32 LONG, LONG
DECLARE LONG AttachThreadInput IN user32 LONG, LONG, LONG
DECLARE LONG ShowWindow IN user32 LONG, LONG
DECLARE LONG SetWindowPos IN user32 LONG, LONG, LONG, LONG, LONG, LONG, LONG
DECLARE LONG SetForegroundWindow IN user32 LONG
_SCREEN.Visible = .F.
of = CREATEOBJECT("myForm")
of.show
READ EVENTS
RETURN
DEFINE CLASS myForm As Form
Desktop = .T.
ShowWindow = 2
ADD OBJECT timer1 as timer WITH Interval=10000,Enabled=.F.
ADD OBJECT text1 as textbox WITH top=10,left=10
PROCEDURE Unload
CLEAR EVENTS
ENDPROC
PROCEDURE Init
BINDEVENT(this.hWnd, WM_SETFOCUS, this, "_SetFocus")
BINDEVENT(this.hWnd, WM_KILLFOCUS, this, "_KillFocus")
BINDEVENT(this.hWnd, MY_SETFOREGROUND, this, "_SetForeground")
ENDPROC
PROCEDURE Destroy
UNBINDEVENTS(this.hWnd)
ENDPROC
PROCEDURE timer1.timer
this.Enabled = .F.
PostMessage(thisform.hWnd, MY_SETFOREGROUND, 0, 0)
ENDPROC
FUNCTION _SetFocus(hWnd, nMsg, wParam, lParam)
this.Caption = "窗口获得焦点"
SendMessage(hWnd, nMsg, wParam, lParam)
ENDFUNC
FUNCTION _KillFocus(hWnd, nMsg, wParam, lParam)
this.Caption = "窗口失去焦点,10秒后自动获得焦点"
this.timer1.Enabled = .T.
SendMessage(hWnd, nMsg, wParam, lParam)
ENDFUNC
FUNCTION _SetForeground(hWnd, nMsg, wParam, lParam)
LOCAL hForeWnd, dwCurID, dwForeID
*INKEY(0.1)
&& 这时要加延时?
hForeWnd = GetForegroundWindow()
dwCurID
= GetCurrentThreadId()
dwForeID = GetWindowThreadProcessId(hForeWnd, 0)
AttachThreadInput(dwCurID, dwForeID, .T.)
&& 切换键盘输入焦点
ShowWindow(hWnd, SW_SHOWNORMAL)
&& 显示窗口(有时窗口被最小化/隐藏了)
SetWindowPos(hWnd, HWND_TOPMOST,0,0,0,0,SWP_NOSIZE+SWP_NOMOVE)
&& 更改窗口的Z序列使之最上
SetWindowPos(hWnd, HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE+SWP_NOMOVE) && 为了不影响后续窗口的Z序列,改完之后还原
SetForegroundWindow(hWnd)
AttachThreadInput(dwCurID, dwForeID, .F.)
ENDFUNC
ENDDEFINE