Repintado de datos en tiempo real durante un bucle modal en un diálogo de Windows -- ++ campo con gui campo con winapi camp codereview Relacionados El problema

Repainting real-time data during a modal loop in a Windows dialog


2
vote

problema

Español

El siguiente código iniciará un temporizador para continuar dibujando datos en tiempo real (que se ha realizado pre-tamponado, para intercambiarse en la GUI tan rápido como pueda) a la ventana durante el reposicionamiento o dentro de un bucle de menú.

  // State of the application static bool running = false; static uint32_t modalmode = 0, modalcount = 0; static const UINT_PTR TIMER_ID = 1337; static const UINT TIMER_INTERVAL = 33;  // Window message handling LRESULT CALLBACK WindowCallback(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) {     uint32_t curmodalmode = 0;     switch(msg) {         case WM_CLOSE: {             if(running) {                 running = false;                 ::DestroyWindow(wnd);             }         }   break;          case WM_PAINT: {             PAINTSTRUCT paint;             HDC dc = ::BeginPaint(wnd, &paint);             // Buffer swapping / drawing happens here             ::EndPaint(wnd, &paint);         }   return ::DefWindowProcW(wnd, msg, wparam, lparam);              // The following block handles modal modes             // like resizing, moving or opening a system menu         case WM_ENTERMENULOOP:             if(!curmodalmode)                 curmodalmode = 1;         case WM_ENTERSIZEMOVE: {             if(!curmodalmode)                 curmodalmode = 2;             // Reset the counter and start the timer if entering modal mode             if(!modalmode) {                 modalcount = 0;                 if(0 == ::SetTimer(wnd, TIMER_ID, TIMER_INTERVAL, nullptr))                     assert(false);             }             modalmode |= curmodalmode;         }   break;         case WM_TIMER: {             ++modalcount;             // Repaint             ::SendMessageW(wnd, WM_PAINT, 0, 0);         }   break;         case WM_EXITMENULOOP:             if(!curmodalmode)                 curmodalmode = 1;         case WM_EXITSIZEMOVE: {             if(!curmodalmode)                 curmodalmode = 2;             modalmode &= ~curmodalmode;             // Kill timer if leaving modal mode             if(!modalmode)                 if(!::KillTimer(wnd, TIMER_ID))                     assert(false);         }   break;             // End of the modal mode handling          default: {         }   return ::DefWindowProcW(wnd, msg, wparam, lparam);     }      return S_OK; }   

Específicamente quiero saber si es una buena idea Send1 en lugar de Post El mensaje para volver a dibujar la ventana, o si hay son mejores, más enfoques idiomáticos en la API de Windows para dibujar en tiempo real durante una bomba de mensajes modales.

  1. Puedo vivir con una velocidad de fotograma fija y inferior (aquí alrededor de 33ms por cuadro) durante un bucle modal, ya que el usuario probablemente esté ocupado con colocar la ventana o leer el menú. Puedo imaginar cambiar la tasa de fotogramas de acuerdo con el costo de manejar las interacciones de la GUI, pero esa no es mi preocupación en este momento.
  2. Publicar el mensaje en el lado de simulación (pre-buffering) introduciría una sincronización adicional (o alternativamente inundará el búfer de mensajes) que quiero evitar: las actualizaciones de actualización predecibles son uno de los primeros objetivos del lado de la simulación, la visual El tiempo de actualización es secundario.
Original en ingles

The following code will start a timer to continue drawing real-time data (that has been pre-buffered, to be swapped in the gui as fast as it can) to the window during repositioning or inside a menu loop.

// State of the application static bool running = false; static uint32_t modalmode = 0, modalcount = 0; static const UINT_PTR TIMER_ID = 1337; static const UINT TIMER_INTERVAL = 33;  // Window message handling LRESULT CALLBACK WindowCallback(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) {     uint32_t curmodalmode = 0;     switch(msg) {         case WM_CLOSE: {             if(running) {                 running = false;                 ::DestroyWindow(wnd);             }         }   break;          case WM_PAINT: {             PAINTSTRUCT paint;             HDC dc = ::BeginPaint(wnd, &paint);             // Buffer swapping / drawing happens here             ::EndPaint(wnd, &paint);         }   return ::DefWindowProcW(wnd, msg, wparam, lparam);              // The following block handles modal modes             // like resizing, moving or opening a system menu         case WM_ENTERMENULOOP:             if(!curmodalmode)                 curmodalmode = 1;         case WM_ENTERSIZEMOVE: {             if(!curmodalmode)                 curmodalmode = 2;             // Reset the counter and start the timer if entering modal mode             if(!modalmode) {                 modalcount = 0;                 if(0 == ::SetTimer(wnd, TIMER_ID, TIMER_INTERVAL, nullptr))                     assert(false);             }             modalmode |= curmodalmode;         }   break;         case WM_TIMER: {             ++modalcount;             // Repaint             ::SendMessageW(wnd, WM_PAINT, 0, 0);         }   break;         case WM_EXITMENULOOP:             if(!curmodalmode)                 curmodalmode = 1;         case WM_EXITSIZEMOVE: {             if(!curmodalmode)                 curmodalmode = 2;             modalmode &= ~curmodalmode;             // Kill timer if leaving modal mode             if(!modalmode)                 if(!::KillTimer(wnd, TIMER_ID))                     assert(false);         }   break;             // End of the modal mode handling          default: {         }   return ::DefWindowProcW(wnd, msg, wparam, lparam);     }      return S_OK; } 

I specifically want to know if it's a good idea to Send instead of Post the WM_PAINT message to redraw the window, or if there are better, more idiomatic approaches in the Windows API to drawing in real-time during a modal message pump.

  1. I can live with a fixed, lower frame rate (here around 33ms per frame) during a modal loop, since the user is probably occupied with positioning the window or reading through the menu. I can imagine changing the frame rate dynamically according to the cost of handling the GUI interactions, but that's not my concern right now.
  2. Posting the message on the simulation side (pre-buffering) would introduce additional synchronisation (or alternatively flood the message buffer) that I want to avoid: predictable update-times is one of the first goals on the simulation side, the visual update time is secondary.
        
   
   

Lista de respuestas


Relacionados problema

3  std :: string / std :: wtring plantilla wrapper para Win32 API  ( Stdstring stdwstring template wrapper for win32 api ) 
No he completado esto, pero quiero hacer mi propia biblioteca de plantillas para envolver la API de Win32 para que sea compatible con STD :: STRING / STD :: W...

2  Creación de una identificación única para una aplicación en tiempo de ejecución  ( Creating a unique id for an application on runtime ) 
Esto parece funcionar en alguna versión de Windows y actúa raro en otros. Esto es inestable y redundante. ¿Cómo puedo mejorar esto de una manera que tiene e...

4  Lifesaver: Oculta y manipula Windows  ( Lifesaver hides and manipulates windows ) 
[Esta aplicación está ahora en github !! ] Este es un pequeño programa que escribí para ocultar / mostrar diferentes ventanas en mi PC con Windows. Esto...

2  Gestión de la memoria para obtener una lista de letras de unidad en Windows  ( Memory management for fetching a list of drive letters on windows ) 
Estoy usando el winapi GetLogicalDriveStrings() Función que requiere un LPWSTR y me pregunto si hay una forma más segura de hacer esto para asegurarse d...

2  sistema de archivos crea una carpeta  ( Filesystem create a folder ) 
Tengo una mezcla de dos idiomas C y C ++ El código encuentra la carpeta Mis documentos y crea carpetas adicionales cuando comienza el programa, no encontré ...

4  Juego de serpiente básica en c  ( Basic snake game in c ) 
Quería aprender C y Win32, así que pensé que la mejor manera de empezar sería crear un juego simple para familiarizarse con el idioma, así que hice la serpien...

7  Pruebas si el nodo de TreeView está marcado  ( Testing if treeviews node is checked ) 
He respondido recientemente a una Pregunta en el desbordamiento de la pila ¿Dónde que OP quería determinar programáticamente si el nodo remaining_distance0...

4  Recreated la funcionalidad de consulta de la consola de la consola de Microsoft en C ++ (reg.exe)  ( Recreated microsofts console registry tools query functionality in c reg ex ) 
Decidí intentar recrear la funcionalidad de consulta reg.exe de Microsoft. "Reg.exe" es la herramienta de registro de consola de Microsoft. Utilicé la docum...

4  Clase de envoltura de creación de ventanas  ( Window creation wrapper class ) 
Esta pregunta ahora tiene un seguimiento aquí No creo que haya ninguna técnica nueva en mi código, pero en mi opinión está bien, todo en todos (con un poc...

6  Código Winapi para consultas DNS  ( Winapi code for dns queries ) 
Este es solo un código de prueba que estoy haciendo para aprender C ++ 11. Recopila y corre constantemente. Pero, ¿es algo malo que eventualmente (o bajo circ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos