MFC SDL2 atascado cuando se cambia el tamaño de la ventana

Este artículo se reimprime, el enlace original: http://www.cnblogs.com/lihaiping/p/4324315.html

Hoy, utilicé la biblioteca SDL2.0 para la visualización de video en el proyecto, y hubo muchos problemas en ella, que se registran aquí y se usan como referencia futura.

 

Después de usar SDL_CreateWindowFrom y SDL_DestroyWindow varias veces con el mismo identificador de ventana, se encuentra que el programa se ejecuta normalmente, pero no se puede mostrar el video.

Pase Hwnd a SDL_CreateWindowFrom por primera vez para crear una ventana de visualización a SDL, y luego, cuando no esté en uso, llame a SDL_DestroyWindow para destruir la ventana de visualización que acaba de crear, libere los recursos relacionados con la visualización y luego use SDL_CreateWindowFrom nuevamente, el mismo identificador A es pasado a SDL_CreateWindowFrom, devuelve éxito y todas las operaciones posteriores se realizan normalmente, pero el video no siempre se muestra en la ventana.

Por esa razón, busqué durante mucho tiempo y luego especulé lentamente y sospeché algunos problemas del código fuente de SDL. El código fuente de SDL es el siguiente:

Copiar codigo

1 void 
 2 SDL_DestroyWindow (ventana SDL_Window *) 
 3 { 
 4 Pantalla SDL_VideoDisplay *; 
 5 
 6 CHECK_WINDOW_MAGIC (ventana,); 
 7 
 8 / * Restaurar el modo de video, etc. * / 
 9 SDL_HideWindow (ventana); / * 注意 这个 地方 哦 * / 
10 
11 / * Asegúrate de que esta ventana ya no tenga el foco * / 
12 if (SDL_GetKeyboardFocus () == ventana) { 
13 SDL_SetKeyboardFocus (NULL); 
14} 
15 if (SDL_GetMouseFocus () == ventana) { 
16 SDL_SetMouseFocus (NULL); 
17} 
18 
19 / * no hace que el contexto sea actual si esta es la ventana de contexto actual. * /  
20 if (ventana-> banderas & SDL_WINDOW_OPENGL) {
21 if (_this-> current_glwin == ventana) {
22 SDL_GL_MakeCurrent (ventana, NULL); 
23} 
24} 
25 
26 if (ventana-> superficie) { 
27 ventana-> superficie-> banderas & = ~ SDL_DONTFREE; 
28 SDL_FreeSurface (ventana-> superficie); 
29} 
30 if (_this-> DestroyWindowFramebuffer) { 
31 _this-> DestroyWindowFramebuffer (_this, window); 
32} 
33 if (_this-> DestroyWindow) { 
34 _this-> DestroyWindow (_this, ventana); 
35} 
36 if (ventana-> banderas & SDL_WINDOW_OPENGL) { 
37 SDL_GL_UnloadLibrary (); 
38}
41 si (pantalla-> 
39
40 pantalla = SDL_GetDisplayForWindow (ventana); 
42 display-> fullscreen_window = NULL; 
43} 
44 
45 / * Ahora invalida la magia * / 
46 ventana-> magia = NULL; 
47 
48 / * Memoria libre asociada a la ventana * / 
49 SDL_free (ventana-> título); 
50 SDL_FreeSurface (ventana-> icono); 
51 SDL_free (ventana-> gamma); 
52 while (ventana-> datos) { 
53 SDL_WindowUserData * datos = ventana-> datos; 
54 
55 ventana-> datos = datos-> siguiente; 
56 SDL_free (datos-> nombre); 
57 SDL_free (datos); 
58} 
59 
60 / * Desvincular la ventana de la lista * /
61 if (ventana-> siguiente) { 
62 ventana-> siguiente-> prev = ventana-> anterior; 
63} 
64 si (ventana-> anterior) {
65 ventana-> anterior-> siguiente = ventana-> siguiente; 
66} else { 
67 _this-> windows = window-> next; 
68} 
69 
70 SDL_free (ventana); 
71}

Copiar codigo

A partir del código anterior, comencé a preguntarme si SDL ocultó la ventana después de llamar a SDL_DestroyWindow, lo que causó el problema de que el video no se puede mostrar todo el tiempo cuando se muestra el video en él.

Así que agregué la siguiente declaración a mi código de prueba. Después de llamar a SDL_DestroyWindow, dije:

vDisplay.ShowWindow (SW_SHOWNORMAL); // Si desea mostrar la ventana, muéstrela,
donde vDisplay corresponde al objeto de control de ventana mostrado.

 Después de agregar esta línea de código al código del proyecto probado, el problema del proyecto está perfectamente resuelto.

================================================ ===========

Pregunta 2:

Cuando creo algunos recursos relacionados de la ventana de visualización en la función correspondiente del mensaje de la interfaz de usuario de MFC, se utiliza un hilo separado creado en segundo plano para actualizar y actualizar los datos de visualización, y luego liberar y destruir los recursos relacionados con la ventana de SDL en el mensaje de cierre de la interfaz de usuario respuesta.

El problema viene. Cuando uso la pantalla completa, el hilo de datos de actualización en segundo plano sigue informando errores:

Copiar codigo

1 if (o_pSdlHelper-> SDL_RenderClear (pDispContext-> pStruOut-> pRender) <0) 
 2 { 
 3 char outstr [200] = {0}; 
 4 const char * pbuf = o_pSdlHelper-> SDL_GetError (); 
 5 _snprintf (outstr, sizeof (outof), "% s \ n", pbuf); // 这里 出错 信息 为: Reset (): INVALIDCALL 
 6 OutputDebugStringA (outstr); 
 7 memset (out, 0, sizeof (out)); 
 8 
 9 return PCI_MC_UNKNOWN_ERR; 
10}

Copiar codigo

Esto me hace extraño. Cuando estaba en pantalla completa antes, no había ningún error. ¿Por qué hay un error ahora? ¡Y la pantalla de la ventana de visualización no se ha actualizado! !

Entonces pensé en la diferencia con el código anterior. La única diferencia es que llamo recursos como la creación y renderizado de ventanas, la creación de texturas, etc., que se colocan en el mismo hilo que la actualización de datos. De ninguna manera, no lo hago ' No sé. El motivo es volver al código original y transferir el código creado desde la respuesta del mensaje de la interfaz de usuario al mismo hilo que los datos de actualización en segundo plano. ¿El resultado extraño es que se puede ejecutar una operación de pantalla completa?

Maldita sea, ¿por qué es esto?

// Por esta razón, todavía necesitamos verificar la información relevante y el código fuente de SDL para saberlo. Resuelto temporalmente, pero no sé el motivo.

=========================================

Recientemente, siempre hay errores inexplicables al usar sdl. Más tarde, lo sé por el código fuente de sdl:

https://bugzilla.libsdl.org/show_bug.cgi?id=1995

 

 

/

Cuando sdl está mostrando video, cuando el tamaño de la ventana se ajusta constantemente, se producirá el bloqueo de sdl. El seguimiento posterior encontró que el bloqueo está en el mensaje windowsizechange de sdl, la función render-> updateview.

Sin embargo, este bloqueo parece fallar solo en algunas máquinas. La razón específica aún se desconoce, pero mi solución actual es comentar la función de procesamiento de respuesta de mensaje de sdl:

Copiar codigo

1 #ifdef GWLP_WNDPROC 
 2 datos- > wndproc = (WNDPROC) GetWindowLongPtr (hwnd, GWLP_WNDPROC); 
 3 si (datos-> wndproc == WIN_WindowProc) { 
 4 datos-> wndproc = NULL; 
 5} else {// modefy por lhp-20150720 
 6 // SetWindowLongPtr (hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc); 
 7} 
 8 #else 
 9 data-> wndproc = (WNDPROC) GetWindowLong (hwnd, GWL_WNDPROC); 
10 if (datos-> wndproc == WIN_WindowProc) { 
11 datos-> wndproc = NULL; 
12} else {// modefy por lhp-20150720- 注释 这个 sdl 消息 接管 函数
13 // SetWindowLong (hwnd, GWL_WNDPROC, (LONG_PTR) WIN_WindowProc); 
14} 
15 #endif

Copiar codigo

De: http://www.cnblogs.com/lihaiping/p/4324315.html 

Supongo que te gusta

Origin blog.csdn.net/gouguofei/article/details/81331271
Recomendado
Clasificación