FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Frames, esperar a que cree sus controles
Hola :
Estoy trabajando con Frames , las cuales inserto en un TTabSheet. Aqui ningún problema. El tema que cuando creo el frame y lo muestro, y en el mismo evento intento acceder a sus me da un error de acceso violation. A partir de otro evento , es decir un boton para crearlos y otro para acceder a sus propiedades , si que puedo. Lo que sucede es que no se crea en el mismo momento, luego si puedo acceder. Asi que debo hacer un "Semaforo" para darle tiempo. Yo accedo asi. (Form.pagecontrol1.ActivePage.Controls[0] as TFRAME1).mMemo.lines.gettext ESto funciona pero si lo ejecuto en otro evento. Como debo hacer para no tener problemas ? |
#2
|
||||
|
||||
Hola paubar, se que recién estás iniciandote en los foros... no se si ya te aconsejaron la guia de estilo. Si no es así, creo que darles una leída no viene mal.
Con respecto a tu pregunta, ¿Serías tan amable de redactarla mejor? ¡No se te entiende lo que escribiste! Parece que estás con hambre por que te haz comido algunas palabras y signos de puntuación. Tranquilo, no te cobramos por la cantidad de palabras. Cuando más detalles nos dé y mejor formulada la pregunta... más fácil será responderte. Saludos, |
#3
|
||||
|
||||
Bueno, que [Delphius] tiene razón, está un poco confuso el planteo, pero igual creo que te he entendido.
Por lo que veo creas el frame desde código, no desde el diseñador, lo cual ya es algo raro, ¿no te sería más útil crearlo e insertarlo en tiempo de diseño? Si lo crearas en tiempo de diseño no tendrías este problema, pues el frame se crearía junto con el form y antes de mostrarse ambos. El problema es que si llamas al procedimiento Create del frame e inmediatamente tratas de acceder a sus propiedades o métodos resulta que no le das tiempo a Windows a crear un identificador para esa ventana, de ahí el error. Si esperas un tiempo prudente (milisegundos) a que finalicen las rutinas de creación del frame no tendrás problemas. Si no quieres o no puedes crearlo en tiempo de diseño e insistes en utilizar el tiempo de ejecución puedes usar una rutina del tipo try... except... end para comprobar si se han terminado las rutinas de creación, y mantener un bucle hasta que se cumpla esa condición. Sería algo así: de forma que si se produce una excepcion se vuelve a intentar hasta que se produzca un resultado válido. Espero que con esto soluciones tu problema. Saludos. |
#4
|
|||
|
|||
Exelente
Era esto lo que preguntaba.
Para serte sincero estaba pensando en algo similar,... agradezco el detalle del código. Por otra lado veo, e insisto hay otra manera de hacerlo ? Solo por curiosidad con esta idea ya me vale..pero si se puede aprender algo más--- Tratare de redactar mejor la proxima vez, gracias a todos. |
#5
|
||||
|
||||
Hola,
Habría que ver qué pasa por ahí... yo acabo de añadir un "Frame" con un botón en un formulario. A continuación he ocupado el evento "OnCreate" del formulario para acceder al "Frame" y deshabilitar el botón que este contiene. Y todo ha ido bien. Es decir, en el evento "OnCreate" del formulario ya se puede acceder al "Frame". ¿Estás creando el "Frame" en tiempo de ejecución? Pero, aunque así fuera, una vez creado el "Frame"... no debería haber problema para acceder al mismo. Ahora bien, si dices que hay algún problema... podrías acaso ser un poco más específico y aportar algo del código que estás usando en el constructor del "Frame" (si lo ocupas)... En todo caso la solución del compañero paldave no me parece muy acertada, puesto que además de hacer un uso del bloque "try...except" discutible, al menos, el usar un "goto" no creo que sea tampoco lo más natural... no sé... Para eso podría probarse con un bucle "while", o tal vez un "repeat"... pero yo creo que ni eso debe ser necesario. Si el objeto en cuestión (el "Frame") está creado... ¿qué problema hay para no poder acceder al mismo? Esto es lo que habría que mirar y tratar de solucionar, digo yo. |
#6
|
||||
|
||||
A ver si así les gusta más:
|
#7
|
||||
|
||||
Hola,
Pues, en mi ignorancia, me sigue pareciendo que se emplea un bloque "try...except" no como debería. De hecho el código anterior no me parece correcto, un bucle "repeat" que "intenta" obtener el texto de un Memo... pero si surge una excepción (cualquier excepción además) al cabo se volverá a intentar... indefinidamente... Ese código no parece que esté muy bien planteado, pero, no te culpo, puesto que al cabo tampoco sabemos a ciencia cierta qué puede estar ocurriendo. A ver si el compañero se decide a copiar por aquí un poco de código o a explicar de forma pormenorizada su caso. |
#8
|
|||
|
|||
No funciona la rutina anterior
Aplicar este bucle, no va, me sigue generando un acces violation y no lo puedo controlar con esto, se bloquea la aplicación.
Había pensado en algún evento del Frame para que cuando se mostrará sus componentes este aplicara una variable Boolean y de esta manera acceder a sus elementos, pero no tiene , se podriá leer algún "message" para determinar el pto en que esta todo creado?. Es decir un procedimiento de este tipo; procedure TForm1.UMCreateFrame(var msg: TUmCreateFrame); Var frame: TFrame; begin If msg.tabsheet.Tag <> 0 Then Begin frame := TFrameclass(msg.tabsheet.Tag).Create(self); frame.Parent := msg.tabsheet; frame.Align := alClient; End; end; Esto no me dice nada de sus componentes.... Por otro lado, yo creo los TTabsheet en runtime, y luego asigno el frame a él. Tab:=TTabSheet.Create(Self); Tab.PageControl:=suiPageControl1; Tab.Tag:=Integer(TFrame1); Tab.OnShow:=TabSheetShow; Tab.OnHide:=TabSheetHide; Tab.Caption:='Hola'; Tab.Show; Los Frame no son creado en runtime si no que los asigno al TTabsheet. Un salu2 |
#9
|
|||
|
|||
Mas codigo
Procedure TForm1.CreateFrame(forTabsheet: TSuiTabSheet);
begin If GetFrame( forTabsheet ) = nil Then PostMessage( handle, UM_CREATEFRAME, WPARAM(forTabsheet), 0 ); end; procedure TForm1.DestroyFrame(forTabsheet: TSuiTabsheet); begin getFrame( forTabsheet ).Free; end; function TForm1.GetFrame(forTabSheet: TSuiTabsheet): TFrame; begin If not Assigned( forTabsheet ) Then forTabsheet := Suipagecontrol1.activepage; Result := nil; If Assigned( forTabsheet ) and (forTabSheet.ControlCount > 0) and (forTabSheet.Controls[0] Is TFrame) Then result := TFrame(forTabSheet.Controls[0]); end; Type TFrameclass = class of TFrame1; procedure TForm1.UMCreateFrame(var msg: TUmCreateFrame); Var frame: TFrame; begin If msg.tabsheet.Tag <> 0 Then Begin frame := TFrameclass(msg.tabsheet.Tag).Create(self); frame.Parent := msg.tabsheet; frame.Align := alClient; End; end; Este es todo el codigo. Haber si podemos llegar a una solución. De todas maneras lo que pasa es que no se da tiempo a que windows cree los componentes. A lo mejor solo se trata de buscar el componentes con FindComponents y haber si es distinto de nil. Pero lo interesante es encontrar la mejor manera de hacerlo. |
#10
|
||||
|
||||
Saludos al foro
Viendo tu código rápidamente (dificil de leer sin las etiquetas [ DELPHI ][ /DELPHI ]), veo que utilizas PostMessage para enviar el mensaje de crear, ignoro que motivo tengas para usar este método, yo mandaría llamar directamente a UMCreateFrame sin más. Tu método tendría un defecto fundamental según mis escasos conocimientos teórico-técnicos , PostMessage inserta el mensaje al final de la cola, pudiendo existir cientos pendientes antes de ejecutar la creación, es decir al regresar de la llamada NO se ha creado el frame. Si usas SendMessage, manda el mensaje inmediatamente (que alguien me corrija si he cometido una barbaridad con semejante afirmación) y creo que sí se crea elcomponente al regresar de la llamada. De todas maneras, te recomiendo que cambies tu metodología y no dependas del sistema de mensajes para la creación de componentes, a menos que tengas una razón muy muy poderosa.
__________________
eLcHiCoTeMiDo - Rompecorazones profesional Yo no soy presumido; ¿Pero de qué sirve mi humilde opinión contra la de los espejos? Salva a un nylon, usa prendas de piel de foca |
#11
|
|||
|
|||
Solucion
Bueno he encontrado una solución, que es poner luego de la sentecia show.
lo siguiente: Sleep(1); Con eso es suficiente, pero ahora me encuentro en el dilema de quiero crear un control PageControl, con Tabsheet en tiempo de ejecucion, y a cada uno de ello asignarles el mismo Frame1,Los controles de mi Frame1 son unicos? Es decir una vez que cree Frame:=Frame1.Create(Self), no puedo hacer mas copias, esto funcionaba antes , porque en el evento hide se eliminaba mediante free, y no daba el error de que la Frame1 ya existía. Antes quedaban todos los tabsheet con su frame, pero cada vez que se mostraban se borra el texto del Mmemo que contiene, un rollo,es decir te lo ponia igual que al principio.A mi me interesa que ademas pueda hacer los cambios y perduren. Se puede hacer lo que quiero o no ? |
#12
|
||||
|
||||
Puedes insertar el archivo ".pas" o el proyecto completo zipeado? Sería de gran ayuda para ayudarte.
|
#13
|
|||
|
|||
Todo solucionado
Bueno:
1) Use Sleep(1) para dar tiempo a que se creen los controles, no me convence demasiado pero funciona, por otro lado se me habia ocurrido enviar un SendMessage y esperar a que me conteste, pero no se que mensaje enviar a un TFrame, creo que esa sería la opcion. 2) El segundo problema era solo un error de código, cambie la manera de crear un array de Frame1. Tab:=TSuiTabSheet.Create(Self); Tab.PageControl:=Form1.suiPageControl1; Tab.Tag:=Integer(TFrame1); Tab.Caption:=RemotoName; Form1.CreateFrame( Tab as TSuiTabsheet ); Tab.Show; Sleep(1); Aqui se crea el TabSheet Llamo directo al metodo CreateFrameProcedure TForm1.CreateFrame(forTabsheet: TSuiTabSheet); Var Frame: TFrame; begin Frame := TFrame1.Create(Self); with Frame do begin Parent := Self; Visible := True; frame.Parent := forTabsheet; frame.Align := alClient; Name := 'FFrames' + IntToStr(pIndex); inc(pIndex); end; pIndex es global Comentarios: El usar Sendmessage y posTmessage no obtuve cambio niguno, por lo menos perceptible.Los dos funcionaban igual aunque son distintos métodos. El error de código era porque desde el evento show se llamaba a createFrame y era que entonces al cambiar de pestaña se colocaba una frame nueva. Un saludo para todos y haber si podemos encontrar una solución mejor para el pto 1. Ciao |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Firebird 2.0 se hace esperar | Casimiro Notevi | Noticias | 2 | 18-08-2006 02:56:21 |
Cree el EXE en delphi 5 y lo corro en XP , marca error , alguna idea? | kamik | Varios | 10 | 22-12-2005 17:03:10 |
Esperar a que termine un proceso | felixgo | OOP | 4 | 02-06-2004 19:46:45 |
esperar a que se realicen los cambios | aram2r | Conexión con bases de datos | 2 | 23-02-2004 18:20:05 |
Esperar xx segundos | Antigol | Varios | 3 | 08-12-2003 02:44:11 |
|