En Windows XP y superior, dado un identificador de ventana (HWND), ¿cómo puedo saber si la posición y el tamaño de la ventana dejan la ventana irremediablemente fuera de la pantalla? Por ejemplo, si la barra de título está disponible para el cursor, entonces la ventana puede arrastrarse hacia atrás en la pantalla. Necesito descubrir si la ventana es de hecho visible o al menos disponible para el usuario. Creo que también necesito saber cómo detectar y responder a los cambios de resolución y cómo lidiar con múltiples monitores. Esto parece bastante importante. Estoy usando C++ y el SDK normal, así que limite sus respuestas a esa plataforma en lugar de invocar C# o similar.¿Cómo puedo determinar si una ventana está fuera de la pantalla?
Respuesta
Windows hace que sea relativamente simple determinar el tamaño del área de trabajo de un usuario en el monitor principal (es decir, el área de la pantalla no oscurecida por la barra de tareas). Llame al SystemParametersInfo
function y especifique SPI_GETWORKAREA
para el primer parámetro (uiAction
). El parámetro pvParam
debe apuntar a un RECT
structure que recibirá las coordenadas del área de trabajo en coordenadas de pantalla virtual.
Una vez que tenga las coordenadas que describen el área de trabajo, es una simple cuestión de compararlas con la posición actual de la ventana de su aplicación para determinar si se encuentra dentro de esos límites.
El deseo de admitir monitores múltiples hace las cosas un poco más complicadas. La documentación para SystemParametersInfo
sugiere que necesita llamar al GetMonitorInfo
function en su lugar para obtener el área de trabajo de un monitor que no sea el primario. Llena una estructura llamada MONITORINFOEX
que contiene el miembro rcWork
que define el área de trabajo de ese monitor, nuevamente expresada en coordenadas de pantalla virtual como una estructura RECT
.
Para hacerlo bien, deberá enumerar todos los monitores que un usuario ha conectado al sistema y recuperar el área de trabajo de cada uno que use GetMonitorInfo
.
Hay algunas muestras de este que se encuentran en torno a Internet:
- MSDN tiene un código de ejemplo para Positioning Objects on a Multiple Display Setup.
- Si está utilizando MFC, esto es lo que parece ser an excellent example de compatibilidad con monitores múltiples.
- Incluso si no está utilizando MFC, ese artículo hace referencia al the following link que parece ser una verdadera joya en cuanto a explicar cómo funcionan los múltiples soportes de monitor en Windows, incluso si es un poco vieja escuela. Nos guste o no, muy poco de esto ha cambiado en versiones posteriores de Windows.
Finalmente, usted mencionó querer detectar cambios de resolución. Esto es mucho más simple de lo que probablemente imaginaste. Como sabe, si ha realizado alguna programación de Windows, la forma principal en que el sistema operativo se comunica con su aplicación es enviando mensajes a su WindowProc
function.
En este caso, querrá ver el WM_DISPLAYCHANGE
message, que se envía a todas las ventanas cuando la resolución de la pantalla ha cambiado. El wParam
contiene la nueva profundidad de imagen en bits por píxel; la palabra de orden inferior lParam
especifica la resolución horizontal y la palabra de orden superior lParam
especifica la resolución vertical de la pantalla.
La comprobación de la visibilidad es realmente fácil.
RECT rtDesktop, rtView;
GetWindowRect(GetDesktopWindow(), &rtDesktop);
GetWindowRect(m_hWnd, &rtView);
HRGN rgn = CreateRectRgn(rtDesktop.left, rtDesktop.top, rtDesktop.right, rtDesktop.bottom);
BOOL viewIsVisible = RectInRegion(rgn, &rtView);
DeleteObject(rgn);
No tiene que usar RectInRegion, lo usé para acortar el código.
La visualización, la supervisión del cambio de resolución también es fácil si maneja el mensaje WM_SETTINGCHANGE.
http://msdn.microsoft.com/en-us/library/ms725497(v=vs.85).aspx
ACTUALIZACIÓN
Como se señaló @Cody gris, creo WM_DISPLAYCHANGE es más apropiado que WM_SETTINGCHANGE. Pero la biblioteca MFC 9.0 utiliza WM_SETTINGCHANGE.
- 1. ¿Cómo determinar si una aplicación de Windows está fuera de pantalla?
- 2. Determinando si un formulario está completamente fuera de pantalla
- 3. ¿Cómo determinar si la ventana actual es la ventana activa?
- 4. ¿Cómo puedo determinar si una casilla de verificación está marcada?
- 5. ¿Cómo puedo determinar si una matriz está vacía en PHP?
- 6. La ventana aparece fuera de la pantalla en ubuntu
- 7. ¿Cómo puedo determinar si un pthread está vivo?
- 8. ¿Cómo puedo saber si la pantalla está activada en Android?
- 9. ¿Cómo determinar si un dispositivo Android tiene una pantalla táctil?
- 10. Cómo determinar en qué pantalla está la barra de tareas
- 11. ¿Cómo puedo determinar si una URL redirige?
- 12. cómo puedo configurar los divs para "visibilidad: oculto" si están fuera de la ventana gráfica
- 13. Determinar si una ventana abierta de WPF está visible en cualquier monitor
- 14. ¿Cómo puedo determinar si mi texto TextBlock está siendo recortado?
- 15. ¿Cómo puedo determinar si un archivo está bloqueado con VBS?
- 16. ¿Cómo puedo determinar si un archivo está vacío?
- 17. ¿Cómo puedo determinar si una columna está en la clave principal de su tabla? (SQL Server)
- 18. Determinar si una cadena está "vacía"
- 19. ¿Determinar si la tienda está abierta?
- 20. Cómo determinar si una anotación está dentro de MKPolygonView (iOS)
- 21. Cómo determinar si una fecha está antes de otra
- 22. ¿Cómo determinar si XML está bien formado?
- 23. Determinar si la transacción SQLite3 está activo
- 24. ¿Cómo puedo saber si un UIView está visible y en la pantalla?
- 25. Cómo determinar si NSString está vacío
- 26. ¿Hay alguna forma de determinar si la aplicación de Android se está ejecutando a pantalla completa?
- 27. Determinar si la barra de acciones está dividida
- 28. ¿Cómo determinar si una lista está ordenada en Java?
- 29. ¿Cómo determinar si una columna no está firmada?
- 30. Cómo determinar si una aplicación web se está ejecutando actualmente
Gracias, eso es un excelente comienzo. No puedo creer que no haya encontrado antes SystemParametersInfo. Todavía estoy atascado con el problema de si la barra de título es visible o no, y qué sucede si la resolución cambia. – hatcat
@hatcat: No hay razón para castigarte; la API de Windows es grande y nadie sabe todo. No estoy seguro de cómo todavía podría estar atascado en la visibilidad de la barra de título. Verifique si la región de su ventana que contiene la barra de título se encuentra dentro del área de trabajo de la pantalla que obtuvo usando cualquiera de las funciones descritas anteriormente. Y me olvidé de detectar cambios de resolución; Actualizaré mi respuesta. –
¡Gracias! He estado programando Windows desde 1992, lo creas o no. Creo que lo más difícil es saber qué funcionalidad ha sido reemplazada y cuándo, y si debes o no quedarte con lo que sabes. La parte de la barra de título tenía más que ver con recuperar esa región para poder probarla. Voy a comprobar los diez píxeles superiores y los diez píxeles laterales, eso debería ser suficiente. – hatcat