xe2 versiones programacion language full embarcadero ejemplos descargar delphi delphi-xe2

versiones - embarcadero delphi full



¿Cómo llevar mi aplicación al frente? (8)

Sé todas las razones por las cuales es una mala idea. No me gusta si una aplicación roba el foco de entrada, pero esto es para uso puramente personal y quiero que suceda; no molestará a nada.

(Para los curiosos: estoy ejecutando pruebas unitarias en NetBeans, que generan un archivo de registro. Cuando mi aplicación en segundo plano ve la marca de tiempo del archivo de registro cambiar, quiero que analice el archivo de registro y llegue al frente para mostrar los resultados).

Esta pregunta no ayudó, ni buscó en Google. Parece que BringToFront() no funcionó durante mucho tiempo y no puedo encontrar ninguna alternativa que lo haga.

¿Algunas ideas?


Aquí hay algo simple que parece funcionar, probado con múltiples cajas que consisten en XP, Server2003, Vista, Server2008, W7. La aplicación de prueba se ejecutó con una cuenta estándar (o de administrador), robó el foco de entrada desde el bloc de notas mientras escribía en primer plano.

var Input: TInput; begin ZeroMemory(@Input, SizeOf(Input)); SendInput(1, Input, SizeOf(Input)); // don''t send anyting actually to another app.. SetForegroundWindow(Handle);

Puede ajustarlo más para una aplicación minimizada o, si es necesario.


Estoy haciendo algo similar en una de mis aplicaciones y esta función funciona para mí en xp / vista / w7:

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 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;

Otra solución es no robar el foco y simplemente poner la ventana TOPMOST en el búfer z:

procedure ForceForegroundNoActivate(hWnd : THandle); begin if IsIconic(Application.Handle) then ShowWindow(Application.Handle, SW_SHOWNOACTIVATE); SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOMOVE); SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOMOVE); end;


No puedes hacer esto de manera confiable. Windows XP tenía una solución que lo permitía, pero las versiones desde entonces lo prohíben en su mayor parte (ver nota a continuación). Esto se establece expresamente en la sección de comentarios de la documentación de MSDN en SetForegroundWindow :

El sistema restringe qué procesos pueden establecer la ventana de primer plano. Un proceso puede establecer la ventana de primer plano solo si una de las siguientes condiciones es verdadera:

  • El proceso es el proceso en primer plano.
  • El proceso fue iniciado por el proceso en primer plano.
  • El proceso recibió el último evento de entrada.
  • No hay un proceso en primer plano.
  • El proceso en primer plano se está depurando.
  • El primer plano no está bloqueado (ver LockSetForegroundWindow).
  • El tiempo de espera de bloqueo de primer plano ha caducado (consulte SPI_GETFOREGROUNDLOCKTIMEOUT en SystemParametersInfo).
  • No hay menús activos.

Una aplicación no puede forzar una ventana al primer plano mientras el usuario está trabajando con otra ventana. En cambio, Windows muestra el botón de la barra de tareas de la ventana para notificar al usuario.

Tenga en cuenta el último párrafo de la documentación citada, especialmente la primera oración.

El problema con

esto es para uso puramente personal y quiero que suceda; no molestará a nada.

es que cualquier aplicación podría intentar hacer lo mismo. ¿De qué manera el "uso puramente personal" dice que es usted personalmente y no solo una aplicación? :-)

Nota: He intentado todo lo que puedo pensar para mostrar la documentación del IDE en primer plano cuando hago clic en el botón de la herramienta de ayuda, pero todo lo que puedo obtener es el botón de la barra de tareas (y yo, como el usuario lo quiero hacer) .


Podría escribir un archivo ejecutable para solucionar esa limitación. Tomemos, por ejemplo, una aplicación simple (no visual) (básicamente una aplicación de consola pero sin {$ APPTYPE CONSOLE}) con el único propósito de mostrar su ventana deseada al frente.

Su aplicación de monitoreo de fondo llama a la aplicación auxiliar a través de una llamada de línea de comando (por ejemplo, ShellExecute) cada vez que se necesita una acción bring-front. Dado que esta aplicación se está convirtiendo en el proceso en primer plano, es capaz de traer otras ventanas al frente (SetForeGroundWindow). Puede usar FindWindow para obtener un control sobre su ventana de destino o pasar los parámetros apropiados al iniciar su aplicación de ayuda.


Form.bringtfront; ?

Deberia trabajar. Si lo pones en un temporizador, permanecerá al frente.


function WinActivate(const AWinTitle: string): boolean; var _WindowHandle: HWND; begin Result := false; _WindowHandle := FindWindow(nil, PWideChar(AWinTitle)); if _WindowHandle <> 0 then begin if IsIconic(_WindowHandle) then Result := ShowWindow(_WindowHandle, SW_RESTORE) else Result := SetForegroundWindow(_WindowHandle); end; end; if WinActivate(self.Caption) then ShowMessage(''This works for me in Windows 10'');


Asumiendo que no hay otras aplicaciones StayOnTop ejecutándose, puede establecer temporalmente sus formularios FormStyle para que sean fsStayOnTop y luego lo hagan y Application Restore y BringToFront y luego cambie el estilo de formulario a lo que sea.

tmpFormStyle := Application.MainForm.FormStyle; Application.MainForm.FormStyle := fsStayOnTop; Application.Restore; // optional Application.BringToFront; Application.MainForm.FormStyle := tmpFormStyle;

De nuevo, esto solo funciona si no hay otras aplicaciones stayontop.


Esto debería funcionar incluso en el sistema operativo Windows 7 + 8. El único requisito es que una aplicación en sí misma pueda llamar a funciones. Es más complicado usar una aplicación externa para configurar el frente de la ventana de otro proceso.

Application.Restore; // unminimize window, makes no harm always call it SetWindowPos(self.Handle, HWND_NOTOPMOST,0,0,0,0, SWP_NOMOVE or SWP_NOSIZE); SetWindowPos(self.Handle, HWND_TOPMOST,0,0,0,0, SWP_NOMOVE or SWP_NOSIZE); SetWindowPos(self.Handle, HWND_NOTOPMOST,0,0,0,0, SWP_SHOWWINDOW or SWP_NOMOVE or SWP_NOSIZE);

Editar Ok Encontré un problema con esto. La aplicación se lleva al frente pero el enfoque se guarda en una aplicación original. Usa esta respuesta para solucionar el problema, es un método bastante complejo, pero copiar pega el truco. Antes de llamar a ForceForegroundWindow (wnd) es posible que deba llamar a Application.Restore para realizar una minimización de una ventana. https://.com/a/5885318/185565