Pregunta

Quiero hacer un control de VCL personalizado que envuelve una superficie de representación SDL través de la función SDL_CreateWindowFrom. SDL_CreateWindowFrom lleva un mango HWND existente y pone un contexto de procesamiento de alto rendimiento (tiene varios backends disponibles, incluyendo DirectX y OpenGL) en la misma.

El archivo de ayuda dice "No se refiera a la propiedad de la manija durante la creación o streaming componente." Pero no dice por qué. Se dice que la primera vez que intente acceder a la propiedad de la manija, se llamará HandleNeeded para asegurar que existe un identificador válido.

Así que tengo dos preguntas. 1: ¿Cuál es la razón por la que no debería hacer referencia a la propiedad Handle durante la creación del componente? 2. Si el punto de control de la totalidad es envolver una superficie de representación que requiere un HWND que ser inicializado, cuando es seguro para realizar la inicialización que (idealmente) debería estar teniendo lugar durante la creación / de streaming?

¿Fue útil?

Solución

En su núcleo, es una cosa de rendimiento. Hay potencialmente otros "malos" efectos secundarios que pueden suceder así ya que durante el proceso de transmisión. Las cosas están en "mediados de la construcción" y todo lo que normalmente se espera que sea probable que no lo son.

Cuando hace referencia a la propiedad "Handle", esto va a iniciar el proceso de creación del mango. Esto se debe a la manija de lectura en realidad llama GetHandle. Hacer esto demasiado pronto en el proceso de transmisión, y usted puede terminar con, a lo sumo, un rendimiento más lento en streaming, en el peor, una parte configurada "mango".

Si necesita hacer referencia al manejar adecuadamente desde el interior de un regulador de la propiedad, usted debe comprobar si el mango ha sido creado por el control de HandleAllocated, y sólo entonces qué hacer referencia a ella. Si usted necesita para hacer algunos cambios a la bandera el mango como llamar SetWindowLong () o algo así, entonces debería "caché" ese estado en la instancia del componente y luego anular CreateWnd y aplicar estos ajustes en ese punto. Otra opción es aplazar todos los accesos mango durante la transmisión (si csLoading en ComponentState a continuación) hasta que se llama el método virtual cargado.

Por último, es necesario tener en cuenta los casos en que puede necesitar para poner recreado su mango. Esto puede suceder si la forma envolvente o el mango del componente principal pasa por un proceso de recreación. Hasta versiones más recientes de Windows, el único modo de cambiar algunas banderas de la ventana era destruir el mango y recrear con nuevas banderas en la llamada CreateWindowEx (). Hay muchos componentes que todavía hacen esto. Cómo saber si usted está en una situación recrear mediante la comprobación (csRecreating en ControlState).

Así que para responder directamente a su pregunta, el mejor lugar es para anular CreateWnd y hacer su trabajo allí. CreateWnd sólo se llama cuando el mango se crea. Un componente diseñado correctamente debe recibir sólo una llamada a CreateWnd justo antes de que se va a mostrar.

Otros consejos

Para responder a su segunda pregunta: Suponiendo que su control es un TCustomControl probablemente debería anular CreateWindowHandle () . Esto tiene la ventaja de que toda la inicialización se repite correctamente cada vez que se crea un nuevo identificador de ventana para el control. Esto permite cambiar algunos indicadores de estilo de ventana que no se pueda establecer o restablecer sin volver a crear la ventana. Lo hace también permite conservar los recursos al liberar el mango cuando no es necesario, y volver a crearlo más adelante.

Vea también esta pregunta cuál es-la-diferencia-entre-createwnd-e -createwindowhandle y aún más las respuestas detalladas sobre qué hacer y cuando ...

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