Pregunta

De acuerdo, así que en mi aplicación, hay un montón de Winapi y unos controles personalizados. Yay ...

Ahora, normalmente, que se acaba de volver a dibujar en silencio a sí mismos por las animaciones, el estado cambiante, etc .... y todo funciona bien.

Pero tengo un método de clase llamada ventana fija (). Esto se llama cada vez que el conjunto de las necesidades de la ventana para actualizarse. Se cambia el tamaño de los controles e invalida la ventana.

Cuando esto sucede, el fondo se dibuja, entonces el control de ficha, y luego todos los demás en la parte superior. Esto causa muy irritante parpadear, especialmente al cambiar el tamaño de la ventana (a causa de las constantes llamadas a fijo ()).

Lo que he intentado:

  • WS_EX_COMPOSITED. Esto sólo doble amortigua los controles individuales. Su una mejora, pero el parpadeo sigue siendo inevitable.
  • Apagar el dibujo de fondo. Casi no resuelve el problema, y ??en realidad empeora las cosas.

Así que: Necesito una técnica / método / lo que sea que me permita doblar-buffer de la ventana en su totalidad. Me di cuenta de que la gestión del mensaje WM_PAINT por mí podría ser una solución, pero no sabría por dónde empezar. Tengo la horrible sensación de que esto no es aún posible ...

Por favor, ayuda, este es un tema crítico. Voy a estar muy aliviado cuando este pequeño problema estúpida es fijo.

¿Fue útil?

Solución

Es en este momento que se dio cuenta de las profundidades de Microsoft de indiferencia por los desarrolladores nativos. Se podría, de hecho, comenzará a albergar delirios paranoides que Microsoft ha roto deliberadamente la pintura nativa con el fin de obligar a los desarrolladores nativos para desplazarse a WPF.

En primer lugar, considere WS_EX_COMPOSITED. WS_EX_COMPOSITED parece ser la mostaza: - se dice que impone un Botton a fin de pintura encima de los controles secundarios, y, básicamente, que los mensajes WM_PAINT consiguen manejados en un lote. Se dice que fue introducido en Windows 2000 (5,0) y, unas pocas líneas más abajo, que no funciona con la composición de escritorio habilitado. es decir, deja de funcionar a partir de Windows Vista (6.0), a menos que Aero Glass está apagado y que se va a hacer eso?

A continuación, hay dos posibles "hacks" para tratar de obtener sin parpadeos pintura a la obra:

  • En primer lugar, es necesario mimimize la cantidad de repintes. WS_EX_CLIPCHILDREN | WS_EX_CLIPSIBLINGS son necesarios para asegurar que cualquier área en particular de la ventana sólo se pinta una vez. BeginDeferWindowPos también es necesario cambiar el tamaño de lote de las operaciones para asegurar que los estados transitorios - donde uno se superpone a otra ventana -. no suceden (es decir, cuando la ventana A se ha cambiado el tamaño de la ventana, pero B no tiene)

Por supuesto, cuando usted está tratando de dibujar un cuadro de diálogo de piel, o el uso de marcos de grupo, o controles de ficha, o cualquier número de otras restricciones, WS_EX_CLIPSIBLINGS es simplemente no es apropiado.

  • WM_SETREDRAW es un mensaje de magia. No hay una API para acceder a esta funcionalidad: WM_SETREDRAW es manejado directamente por DefWindowProc para marcar esencialmente la ventana oculta para el resto. Después se envía WM_SETREDRAW, FALSE, llamadas a GetDC / GetDCEx / GetWindowDC etc utilizando el identificador de ventana padre (y todos sus hijos) devolverá un DC que no va a dibujar en la pantalla. Esto le da la oportunidad de hacer todo tipo de cosas a las ventanas hijas, cuando haya terminado de enviar un WM_SETREDRAW,TRUE, (y luego vuelva a pintar la ventana de forma manual). Todas las ventanas secundarias hará - por supuesto -. Pintura en su propio tiempo, y después de la ventana padre ha hecho su supresión de fondo, por lo que hay WM_SETREDRAW especie de panacea

Después de romper WS_EX_COMPOSITED, WPF de WinForms En .NET y re-escribió los controles desde el suelo hasta que no utilice los controles nativos, para que pudieran cocer en tampón pintar allí. Y alfa apoyo también.

Otros consejos

Hm. Antes la gente se apresura en y cerca de este tema como duplicado, será mejor que la mención de que el problema no es el doble búfer en sí, sino el parpadeo cuando el reposicionamiento de los controles, por lo que "manual" doble buffer es sólo una de varias soluciones.

Podría ser que, por ejemplo, BeginDeferWindowPos amigos y pueden solucionar el parpadeo.

Renuncia: Una vez conocí a casi todos los detalles de la API de Win16, pero ha sido algunos años desde que hice la programación a nivel de API

.

Saludos y HTH.,

- Alf

Sin código Apenas imaginar cuál es la situación real ... Pero se puede tratar de manejar WM_ERASEBKGND, devolver TRUE siempre que los recibió para saltar de borrado.

WM_ERASEBKGND manija para su ventana y en la puesta en práctica excluye las rectas de cada uno de los controles a su hijo, y luego rellenar el fondo restante de manera adecuada y contar el marco que ha pintado el fondo Urself devolviendo true. Hacer lo mismo para todos los demás controles secundarios que a su vez contienen otros controles como el control de pestaña en su caso.

aquí para un ejemplo que utiliza MFC.

En .NET hay ControlStyle.AllPaintingInWmPaint que deberían establecerse en cada ventana recipiente (por lo que la ventana principal y las pestañas). No pude encontrar un winapi equivalente. Pero lo que esto hace es mover la pintura del fondo de WM_ERASEBKGND a WM_PAINT. También resta el área del control de control de los padres para evitar el parpadeo, Podría ser que lo que necesita hacer esto manualmente.

Me sorprende WS_EX_COMPOSITED no ayuda. Eso debería funcionar, si se establece que en la ventana de nivel superior, y no llamar RedrawWindow en los controles sub.

También asegúrese de prueba con y sin DWM / Aero. Puede obtener diferentes resultados.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top