2009-03-27 5 views
5

Estoy trabajando en una aplicación que resulta ser la herramienta de arranque para un instalador en el que también estoy trabajando. La aplicación hace algunas llamadas MSI para obtener la información que necesito para armar el asistente que es la ventana principal de mi aplicación, lo que hace que se abra una ventana de progreso mientras se recopila la información y luego se va una vez que se ha hecho. Luego, el asistente se configura y se inicia. Mi problema es que el asistente (derivado de CPropertySheet) no quiere pasar al frente y ser la aplicación activa sin que yo agregue algunas llamadas para hacerlo.¿Cómo obligo a mi aplicación a pasar al frente y concentrarse?

he resuelto el problema de llevarlo a la parte delantera con el siguiente código en mi método OnInitDialog():

SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // force window to top 
SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // lose the topmost status that the previous line gave us 

Mi problema es que todavía no he encontrado la manera de hacer que la ventana autoactivarse (es decir, hacerse a sí mismo el que tiene el foco). SetFocus() no funcionará en este contexto. Necesito algo que fuerce la ventana a la parte superior del orden Z y lo active, preferiblemente en el menor número de llamadas posible.

Supongo que la ventana de progreso abierta al principio por las llamadas MSI está causando que la ventana principal se estropee, pero no tengo manera de evitar que aparezca esa ventana. Además, no tendría sentido ocultarlo, ya que le permite al usuario saber qué está sucediendo antes de que llegue la ventana principal.

Respuesta

0

¿No funciona ShowWindow (youwindow, SW_SHOWNORMAL)? -don

+0

No lo he probado, pero supongo que no es más efectivo que BringWindowToTop(). (Vea mi comentario sobre la respuesta de Mitch Wheat.) – RobH

0

Encontrará que BringWindowToTop o SetForegroundWindow tienen requisitos que se deben cumplir antes de que la ventana se forzará realmente al frente sobre todas las demás ventanas (aplicaciones). Si no se cumplen, Windows solo mostrará el ícono de la aplicación en la barra de tareas. El artículo This presenta una forma de evitarlo, pero como señala 1800 INFORMATION, no se recomienda. Supongo que solo tendrás que aceptarlo.

+0

No haga esto. Raymond Chen explica por qué esto a menudo hace que su aplicación cuelgue: http://blogs.msdn.com/oldnewthing/archive/2008/08/01/8795860.aspx –

+0

Gracias. He editado mi respuesta. –

7

No se puede robar el enfoque. Período.

ver este viejo artículo del New cosa:

https://blogs.msdn.microsoft.com/oldnewthing/20090220-00/?p=19083

+1

Gracias, estaba buscando este artículo como la respuesta a esta pregunta.Por favor, todos los que lean esto, internalícenlo y solucionen el virus que intenta robar la activación en primer plano. ¡Pero mi aplicación es especial! Tu aplicación es hostil para el usuario. No lo hagas! –

+1

Acepto, y aunque con toda probabilidad esto se aplica al autor, él (u otra persona) puede tener una buena razón para necesitar esta funcionalidad (sistema cerrado, computadora privada o doméstica solamente). Haga una recomendación sobre el uso pero no oculte la información. –

+1

Espero que Microsoft, algún día, finalmente arregle todo el robo de foco de una vez por todas. Los programadores que roban temas deben enviarse a Siberia. Desnudo. – snemarch

7

Andrew no es completamente correcto. Windows hace todo lo posible para evitar que te robes el foco, pero es posible usando el siguiente método.

  1. Colóquelo en el hilo de la ventana que actualmente tiene el foco.
  2. Traiga su ventana al foco.
  3. Separar del hilo.

Y el código para ese sería algo como esto:

DWORD dwCurrentThread = GetCurrentThreadId(); 
DWORD dwFGThread  = GetWindowThreadProcessId(GetForegroundWindow(), NULL); 


AttachThreadInput(dwCurrentThread, dwFGThread, TRUE); 

// Possible actions you may wan to bring the window into focus. 
SetForegroundWindow(hwnd); 
SetCapture(hwnd); 
SetFocus(hwnd); 
SetActiveWindow(hwnd); 
EnableWindow(hwnd, TRUE); 

AttachThreadInput(dwCurrentThread, dwFGThread, FALSE); 

Usted puede o no necesita tener que ejecutar su programa con privilegios administrativos para que esto funcione, pero he utilizado este código personalmente y ha hecho el trabajo.

+0

Esto no funciona en Windows 10 1703 (Actualización de creadores) –

Cuestiones relacionadas