98/2000下切换前台窗口

  • 主题发起人 主题发起人 import
  • 开始时间 开始时间
I

import

Unregistered / Unconfirmed
GUEST, unregistred user!
Write by :lu0
98/2000下,有个公开的函数SetForegroundWindow,用于切换前台窗口.但是事实上,SetForegroundWindow并不能用于和其他进程的窗口协同工作,通常情况下SetForegroundWindow会调用FlashWindowEx来闪烁目标窗口,代表已经切换了窗口,但是这不是我们需要的.网络上有一些顶尖高手使用修改窗口切换的系统规则后,用SetForegroundWindow切换到其他进程的窗口,但是现在,我们有了UNDOCUMENTED的另外一个USER32函数:
SwitchToThisWindow(...);
来完成这项工作.
那么原型是怎么的呢? 下面就来揭晓了......
void WINAPI SwitchToThisWindow (
HWND hWnd, // Handle to the window that should be activated
BOOL bRestore // Restore the window if it is minimized
);
由于没有原型和库,我们在使用时通常用动态联接法.
typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
HMODULE hUser32 = GetModuleHandle("user32");
SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
{ Delphi Code:
procedure SwitchToThisWindow(hWnd:HWND;bRestore:Boolean);stdcall;external 'user32.dll';
}
这样,我们的任务就完成了.
*******************************
从Win98开始,微软更改了系统代码,一般的SetForegroundWindow只能将
状态栏中应用按钮闪烁,并没有将应用调到最前面。请使用下列函数:
function ForceForegroundWindow(hwnd: THandle): boolean;
const
SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;
SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;
var
timeout: DWORD;
begin
if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion
> 4)) or
((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and
((Win32MajorVersion > 4) or ((Win32MajorVersion = 4) and
(Win32MinorVersion > 0)))) then begin
SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout,
0);
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
TObject(0), SPIF_SENDCHANGE);
Result := SetForegroundWindow(hWnd);
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
TObject(timeout), SPIF_SENDCHANGE);
end
else
Result := SetForegroundWindow(hWnd);
end; { ForceForegroundWindow }
不过最后SystemParametersInfo恢复参数:
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,Pointer(timeout), SPIF_SENDCHANGE);
如果不去掉,在WIN2000下不灵
***********************
发现一个2000下面的方法,试一下
function AllowSetForegroundWindow( dwProcessId:DWORD): BOOL; stdcall;
implementation
function AllowSetForegroundWindow; external 'user32.dll' name 'AllowSetForegroundWindow';
****************
function ForceForegroundWindow(hWnd: THandle): BOOL;
var
hCurWnd: THandle;
begin
hCurWnd := GetForegroundWindow;
AttachThreadInput(GetWindowThreadProcessId(hCurWnd, nil), GetCurrentThreadId, True);
Result := SetForegroundWindow(hWnd);
AttachThreadInput(GetWindowThreadProcessId(hCurWnd, nil), GetCurrentThreadId, False);
end;
*********************
procedure ForceForegroundWindow(hwnd: THandle);
var
hlp: TForm;
begin
hlp := TForm.Create(nil);
try
hlp.BorderStyle := bsNone;
hlp.SetBounds(0, 0, 1, 1);
hlp.FormStyle := fsStayOnTop;
hlp.Show;
mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
SetForegroundWindow(hwnd);
finally
hlp.Free;
end;
end;
---------------------------------------
发现一个2000下面的方法,试一下
function AllowSetForegroundWindow( dwProcessId:DWORD): BOOL; stdcall;
function AllowSetForegroundWindow; external 'user32.dll' name 'AllowSetForegroundWindow';
 
后退
顶部