现有函数function GetSysFocus : integer;
Var
hFgWin,FgThreadID,hFocusWin : integer;
Begin
hFgWin := GetForegroundWindow;
FgThreadID := GetWindowThreadProcessID(hFgWin, nil);
If AttachThreadInput(GetCurrentThreadID, FgThreadID, true) Then
Begin
hFocusWin := GetFocus;
result := GetFocus;
AttachThreadInput(GetCurrentThreadID, FgThreadID, False);
End
else
result := GetFocus;
End;这是网上非常流行的一个版本,它存在一个问题,就是当系统焦点落在Console中的时候,这个函数根本不起作用。
经查,Console窗口的类名为ConsoleWindowClass兄弟们讨论一下,如何对付ForegroundWindow为ConsoleWindowClass的情况
Var
hFgWin,FgThreadID,hFocusWin : integer;
Begin
hFgWin := GetForegroundWindow;
FgThreadID := GetWindowThreadProcessID(hFgWin, nil);
If AttachThreadInput(GetCurrentThreadID, FgThreadID, true) Then
Begin
hFocusWin := GetFocus;
result := GetFocus;
AttachThreadInput(GetCurrentThreadID, FgThreadID, False);
End
else
result := GetFocus;
End;这是网上非常流行的一个版本,它存在一个问题,就是当系统焦点落在Console中的时候,这个函数根本不起作用。
经查,Console窗口的类名为ConsoleWindowClass兄弟们讨论一下,如何对付ForegroundWindow为ConsoleWindowClass的情况
我是要通过这个让我的Form获得焦点现在的问题是
当命令行窗口获得焦点的时候,我无法将焦点夺过来
SetForegroundWindow(hwnd);
ShowWindow(hwnd, SW_SHOW);
var
hOtherWin,OtherTHreadID,hFocusWin:integer;
WindowPlacement: PWindowPlacement;
begin Result := hwnd;
hOtherWin:=GetForeGroundWindow; if 'ConsoleWindowClass' = GetClassName(hOtherWin) then begin
//如果不是ConsoleWindowClass肯定是没有问题的
//在这里我试了很多方法,都没有成功,包括
//SetForeGroundWindow
//SetFocus
//SetWindowPos,可能是这个参数没设置好
Exit;
end;
OtherThreadID:=GetWindowThreadProcessID(hOtherWin,nil);
if AttachThreadInput(GetcurrentThreadID,OtherThreadID,True) then begin
hFocusWin := GetFocus;
Windows.SetFocus(hwnd);
if hFocusWin <> 0 then
AttachThreadInput(GetCurrentTHreadID,OtherTHreadID,False);
end
else begin
Result:=Windows.SetFocus(hwnd);
end;
end;
WM_ACTIVATEAPP
WM_SHOWWINDOW
WM_WINDOWPOSCHANGING
WM_WINDOWPOSCHANGED
WM_ACTIVATE
就这么多
而WM_WINDOWPOSCHANGING是由SetWindowPos引起的,因此我将目标锁定在这个api上
hOtherWin := GetForeGroundWindow;
SetSysFocus(frmTest.Handle);
if frmTest.ShowModal = mrOK then
Close;
SetForeGroundWindow(hOtherWin);
Windows.SetActiveWindow(Application.Handle);
Windows.SetFocus(Application.Handle);
Windows.SetFocus(hwnd);
Windows.SetActiveWindow(hwnd);
Windows 98/2000 doesn't want to foreground a window when
some other window has the keyboard focus.
ForceForegroundWindow is an enhanced SetForeGroundWindow/bringtofront
function to bring a window to the front.
}
{
Manchmal funktioniert die SetForeGroundWindow Funktion
nicht so, wie sie sollte; besonders unter Windows 98/2000,
wenn ein anderes Fenster den Fokus hat.
ForceForegroundWindow ist eine "verbesserte" Version von
der SetForeGroundWindow API-Funktion, um ein Fenster in
den Vordergrund zu bringen.
}
function ForceForegroundWindow(hwnd: THandle): Boolean;
const
SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;
SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;
var
ForegroundThreadID: DWORD;
ThisThreadID: DWORD;
timeout: DWORD;
begin
if IsIconic(hwnd) then ShowWindow(hwnd, SW_RESTORE); if GetForegroundWindow = hwnd then Result := True
else
begin
// Windows 98/2000 doesn't want to foreground a window when some other
// window has keyboard focus 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
// Code from Karl E. Peterson, www.mvps.org/vb/sample.htm
// Converted to Delphi by Ray Lischner
// Published in The Delphi Magazine 55, page 16 Result := False;
ForegroundThreadID := GetWindowThreadProcessID(GetForegroundWindow, nil);
ThisThreadID := GetWindowThreadPRocessId(hwnd, nil);
if AttachThreadInput(ThisThreadID, ForegroundThreadID, True) then
begin
BringWindowToTop(hwnd); // IE 5.5 related hack
SetForegroundWindow(hwnd);
AttachThreadInput(ThisThreadID, ForegroundThreadID, False);
Result := (GetForegroundWindow = hwnd);
end;
if not Result then
begin
// Code by Daniel P. Stasinski
SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0),
SPIF_SENDCHANGE);
BringWindowToTop(hwnd); // IE 5.5 related hack
SetForegroundWindow(hWnd);
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(timeout), SPIF_SENDCHANGE);
end;
end
else
begin
BringWindowToTop(hwnd); // IE 5.5 related hack
SetForegroundWindow(hwnd);
end; Result := (GetForegroundWindow = hwnd);
end;
end; { ForceForegroundWindow }
// 2. Way:
//**********************************************procedure ForceForegroundWindow(hwnd: THandle);
// (W) 2001 Daniel Rolf
// http://www.finecode.de
// [email protected]
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;// 3. Way:
//**********************************************
// by Thomas Stutz{
As far as you know the SetForegroundWindow function on Windows 98/2000 can
not force a window to the foreground while the user is working with another window.
Instead, SetForegroundWindow will activate the window and call the FlashWindowEx
function to notify the user. However in some kind of applications it is necessary
to make another window active and put the thread that created this window into the
foreground and of course, you can do it using one more undocumented function from
the USER32.DLL. void SwitchToThisWindow (HWND hWnd, // Handle to the window that should be activated
BOOL bRestore // Restore the window if it is minimized
);}procedure SwitchToThisWindow(h1: hWnd; x: bool); stdcall;
external user32 Name 'SwitchToThisWindow';
{x = false: Size unchanged, x = true: normal size}
procedure TForm1.Button2Click(Sender: TObject);
begin
SwitchToThisWindow(FindWindow('notepad', nil), True);
end;