现有函数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的情况

解决方案 »

  1.   

    也许是没说清楚
    我是要通过这个让我的Form获得焦点现在的问题是
    当命令行窗口获得焦点的时候,我无法将焦点夺过来
      

  2.   

    //加上,看看成不成
    SetForegroundWindow(hwnd);
    ShowWindow(hwnd, SW_SHOW);
      

  3.   

    function SetSysFocus(hwnd: Integer): Integer; 
    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;
      

  4.   

    to:zswang(伴水清清)(专家门诊清洁工)不可以
      

  5.   

    有个软件实现了这个功能,它收到的消息WM_WINDOWPOSCHANGING
    WM_ACTIVATEAPP 
    WM_SHOWWINDOW 
    WM_WINDOWPOSCHANGING 
    WM_WINDOWPOSCHANGED
    WM_ACTIVATE 
    就这么多
    而WM_WINDOWPOSCHANGING是由SetWindowPos引起的,因此我将目标锁定在这个api上
      

  6.   

    调试代码
        hOtherWin := GetForeGroundWindow;
        SetSysFocus(frmTest.Handle);
        if frmTest.ShowModal = mrOK then
          Close;
        SetForeGroundWindow(hOtherWin);
      

  7.   

    已用方法:
        Windows.SetActiveWindow(Application.Handle);
        Windows.SetFocus(Application.Handle);
        Windows.SetFocus(hwnd);
        Windows.SetActiveWindow(hwnd);
      

  8.   

    ...bring (force) a Window to the foreground?  {
      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;