1,486
社区成员
发帖
与我相关
我的任务
分享
Public Const GWL_WNDPROC As Long = (-4)
Public Const WM_ACTIVATE As Long = &H6
Public Const WA_ACTIVE As Long = 1
Public Const WA_CLICKACTIVE As Long = 2
Public Const WA_INACTIVE As Long = 0
Public preWndProc As Long
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As Long
Public MainHwnd As Long
Public Sub HookWindow(hwnd As Long)
preWndProc = GetWindowLong(hwnd, GWL_WNDPROC)
'记录原本的Window Procedure的位址preWinProc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
'设定Combo1的window Procedure到wndproc
SetWindowLong hwnd, GWL_WNDPROC, AddressOf WndProc
MainHwnd = hwnd
End Sub
Sub UnHookWindow()
SetWindowLong MainHwnd, GWL_WNDPROC, preWndProc
End Sub
Public Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Dim fActive As Long
If Msg = WM_ACTIVATE Then
'取得wParam的LowWord
fActive = CInt(wParam And &HFFFF)
'If fActive = WA_INACTIVE Then
If (wParam = WA_ACTIVE Or wParam = WA_CLICKACTIVE) Then
Debug.Print lParam & "(" & Hex(lParam) & ")" & " 获得焦点" & ",hwnd=" & hwnd&; ",wParam=" & wParam
Else
Debug.Print lParam & "(" & Hex(lParam) & ")" & "失去-焦点" & ",hwnd=" & hwnd & ",wParam=" & wParam
End If
If lParam = 0 And wParam = 0 Then
Debug.Print "程序被切换到其他EXE"
UnHookWindow
SetForegroundWindow MainHwnd
BringWindowToTop MainHwnd
'Form1.Show
'HookWindow MainHwnd
WndProc = -1
Exit Function
End If
End If
'将之送往原来的Window Procedure
WndProc = CallWindowProc(preWndProc, hwnd, Msg, wParam, lParam)
End Function
1,类似Alt+Tab键切换窗口(因为是模拟按键,貌似会遗留下按键状态的异常,不过可以解决)
void SetForegroundWindowInternal(HWND hWnd)
{
if(!::IsWindow(hWnd)) return;
BYTE keyState[256] = {0};
//to unlock SetForegroundWindow we need to imitate Alt pressing
if(::GetKeyboardState((LPBYTE)&keyState))
{
if(!(keyState[VK_MENU] & 0x80))
{
::keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
}
}
::SetForegroundWindow(hWnd);
if(::GetKeyboardState((LPBYTE)&keyState))
{
if(!(keyState[VK_MENU] & 0x80))
{
::keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}
}
}
2
void SetForegroundWindowInternal(HWND hWnd)
{
if(!::IsWindow(hWnd)) return;
//relation time of SetForegroundWindow lock
DWORD lockTimeOut = 0;
HWND hCurrWnd = ::GetForegroundWindow();
DWORD dwThisTID = ::GetCurrentThreadId(),
dwCurrTID = ::GetWindowThreadProcessId(hCurrWnd,0);
//we need to bypass some limitations from Microsoft :)
if(dwThisTID != dwCurrTID)
{
::AttachThreadInput(dwThisTID, dwCurrTID, TRUE);
::SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT,0,&lockTimeOut,0);
::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,0,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
::AllowSetForegroundWindow(ASFW_ANY);
}
::SetForegroundWindow(hWnd);
if(dwThisTID != dwCurrTID)
{
::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,(PVOID)lockTimeOut,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
::AttachThreadInput(dwThisTID, dwCurrTID, FALSE);
}
}