¿Es significativo el orden en que las manijas son devueltas por EnumWindows?
winapi enumeration (5)
A partir de un par de pruebas preliminares, parece que EnumWindows
siempre devuelve las ventanas en orden inverso de instanciación, es decir, la ventana instanciada más reciente primero. ¿Es eso una observación válida? Si es así, ¿es cierto en todas las versiones de Windows? ¿Y es esto una suposición confiable, es decir, ese comportamiento está documentado en alguna parte?
Contexto: estoy lidiando con una situación en la que estoy activando una aplicación de terceros para abrir varias ventanas no modales y necesito enviar algunos mensajes de ventana a esas ventanas una vez que están abiertas, sin embargo, no tengo un camino seguro de identificarlos como ni sus clases de ventana ni sus subtítulos serán diferentes y tampoco sé sus coordenadas esperadas. Sin embargo, si pudiera confiar en el comportamiento anterior de EnumWindows
podría simplemente usar el primer identificador devuelto por EnumWindows
cuya clase y título coinciden con mis expectativas. Eso todavía deja algunos agujeros de bucle hipotéticos, pero creo que será lo suficientemente bueno. Sin embargo, sugerencias alternativas son bienvenidas.
Los devuelve en orden Z. Primero, la ventana más WS_EX_TOPMOST
con el conjunto WS_EX_TOPMOST
, hasta la ventana inferior con WS_EX_TOPMOST set
, luego la ventana superior sin WS_EX_TOPMOST
, aunque en la ventana inferior sin WS_EX_TOPMOST
. Tenga en cuenta que la visibilidad no es un factor determinante, por lo que una ventana invisible que sea más alta en el orden Z que una ventana visible seguirá apareciendo antes.
EDITAR :
Es muy poco probable que pueda usar esto como desee, solo tomando la primera devolución de EnumWindows
. No solo es probable que su nueva ventana sea la primera devolución, sino que también tendría una condición de carrera en la que se podrían abrir otras ventanas mientras tanto. Sin embargo, podría mantener una lista de todas las ventanas conocidas para la aplicación, y cuando necesite encontrar una ventana recién abierta, llame a EnumWindows
y compare los identificadores de ventana con los de su lista. Cuando encuentre uno que tenga la clase y el título correctos (incluso podría verificar que pertenece al proceso correcto con GetWindowThreadProcessID
) que no está en su lista, entonces ha encontrado la nueva ventana.
Sin embargo, para sus propósitos, es posible que se sienta mejor si instala un gancho CBT y observa la notificación HCBT_CREATEWND. Consulte la ayuda de MSDN en SetWindowsHookEx()
y la devolución de llamada CBTProc
para obtener más información.
Nivel de certeza sobre el orden de enumeración :
Una serie de comentarios y otras respuestas a esta pregunta han mencionado la falta de documentación precisa en MSDN sobre el orden en que EnumWindows
devuelve los identificadores de ventanas. Y, de hecho, las páginas de EnumWindows
y la EnumWindowsProc
llamada EnumWindowsProc
son bastante silenciosas sobre el tema. Ofrezco como evidencia lo siguiente:
Un artículo de C & P de Q & A en la revista MSDN especifica específicamente:
EnumWindows enumera las ventanas en orden Z descendente
La página en
EnumChildWindows
alude al orden en la sección de comentarios:Una ventana secundaria que se mueva o reposicione en el orden Z durante el proceso de enumeración se enumerará correctamente.
Esto implica que la orden depende del orden Z. Y dado que, en la descripción del parámetro hWndParent , dice esto:
Si este parámetro es NULL, esta función es equivalente a EnumWindows.
uno puede suponer que la misma lógica y orden se aplica a
EnumWindows
.- Este es el comportamiento observable de esta función, lo que hace que sea un cambio radical alterarlo. En general, Microsoft ha sido muy bueno sobre no hacer cambios bruscos en el comportamiento observable. Eso no es una garantía, pero es una apuesta bastante segura. Es más probable que descubra que en la próxima versión la función que está utilizando ha quedado en desuso y reemplazada por otra versión "Ex" más que para descubrir que su comportamiento observable ha cambiado.
Por supuesto, todo esto es muy académico en este punto, ya que EnumWindows
probablemente no sea la mejor solución para el problema del OP EnumThreadWindows
menos, EnumThreadWindows
probablemente sería un mejor EnumThreadWindows
pero pensé que valía la pena mencionarlo para otras personas que podrían venir a través de esta publicación.
Si controla ambos procesos, puede enviar desde el primero un SendMessage con "HWND_BROADCAST" como primer parámetro.
Luego, el otro programa cuando recibe el mensaje, puede enviar un mensaje de texto a las ventanas de su hijo.
Si la documentación no dice nada sobre el orden de la enumeración, le recomiendo encarecidamente que se mantenga alejado de cualquier suposición. Un par de publicaciones en el blog de Raymond Chen (blogs.msdn.com/oldnewthing) te revelarán cuántas aplicaciones hay que confían en todas estas cosas / observaciones indocumentadas, y algo va terriblemente mal cuando sale una nueva versión de Windows (a menos que Los desarrolladores de MS presentan otro complemento para otra aplicación que se comporta mal).
En cuanto a su propósito, hay varias funciones, como GetWindowThreadProcessID, GetParent, EnumThreadWindows y EnumWindows que podrían ayudarlo a lograr la tarea.
La orden no está especificada en la API ( enlace de MSDN ), por lo que no se garantiza que sea algo en particular; si existiera una garantía, se especificaría explícitamente en la API. ¿Qué sucede, por ejemplo, si se crea una ventana a mitad de la enumeración? ¿Se incluye en la enumeración? Esto le permite al administrador de ventanas la libertad de cambiar su implementación en caso de que sea más eficiente hacerlo.
Sin embargo, hay un valor único que se puede usar para diferenciar entre ventanas: el identificador de ventana en sí. En su método EnumWindowProc
, guarde el identificador de ventana para cada ventana coincidente; de todos modos lo necesita para enviar mensajes a la ventana.
Las respuestas anteriores necesitan un refinamiento considerable. Enum-order = orden Z solo si GetSystemMetrics (SM_IMMENABLED) = 0, es decir, las características de Input Method Manager / Input Method Editor están deshabilitadas. Porque todas las clases de Windows "IME" (el título "IME predeterminado") y "MSI de MSCTFIME" se enumeran después de la ventana "Progman" ("Administrador de programas"), es decir, no en orden Z.