Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Sobre llamar procedimientos desde otros Form. (https://www.clubdelphi.com/foros/showthread.php?t=65496)

Robin1 19-12-2009 18:37:05

Sobre llamar procedimientos desde otros Form.
 
Hola a todos, y un gran saludo.

Estuve buscando por el foro, sobre un modo, específico, para llamar un procedimiento declarado en un Form, desde otro form, y la verdad, no he podido encontrar específicamente un post, que me ayude a resolver el pequeño problema que me ocupa.

Haber si puedo explicarlo de forma clara.

En el Form1, tengo declarado un procedimiento, que, en tiempo de ejecución, crea un nuevo Tab en el formulario.

En el Form2, necesito poner un botón, que llame a ese procedimiento de crear un Tab en tiempo de ejecución, YA declarado en el form1, como si ese procedimiento, ubiese sido llamado de forma nativa desde su propio Form.

De este modo, para lograrlo, he intendo con esto, tomando elgunos elementos que he visto en los diferentes Post, que he estado visitando en búsqueda de ayuda:

En el Form1, tengo mi procedimiento para crear este nuevo Tab, en tiempo de ejecución:

Código:

procedure TForm1.NewTab1Click(Sender: TObject);
begin
NewTab := TTabSheet.Create(Self);  //Se crea la nueva pestaña
  NewTab.Caption := '  Tab  ' + IntToStr(PageControl1.PageCount + 1);
end;

Entonces, cada vez que en ese mismo Form1 clickeo esta opcion, se creará en tiempo de ejecución el nuevo Tab.

Hasta ahí, no habría problema. Todo funciona perfectamente, puesto que el procedimiento está escrito y declarado en el Form1 y todo de momento, sucede en este mismo Form.

Ahora bien, en el Form2, quiero poner un botón, que haga lo mismo, pero aplicabdole esta acción, al mismo Form1, es decir, que si ejecuto este procedimiento en el Form2, el Form1 cree un nuevo Tab.

Que he tratado de hacer entonces en el Form2:

Código:

procedure TForm2.BtnNewTabForm1Click(Sender: TObject);
begin
begin
  Form1:= TForm1.Create(application);
    Form1.ShowModal;
    Form1.NewTab1Click(sender);
      Form2.Close;

El programa que hace entonces:

Crea una nueva del Form1 (adicional a la que ya hay), y efectivamente crea en tiempo de ejecución un nuevo tab, y el Form 2 se cierra.

Al cerrar este nuevo Form1, se crea una Excepción, que hace referencia a lo siguiente:

EInvalidOperation with message Cannot Focus a disable or invisible Window'.

Comentarios finales:

1) No quisiera que en tiempo de ejecucion, se cree una nueva instancia del Form1. Finalmente este ya está anteriormente abierto. No deseo crear otro.

2)¿Es posible sobre el Form1 que ya está abierto en tiempo de ejecución, se ejecute este procedimiento?

3) Qué genera dicha excepcion al intentar cerrar esta nueva instancia del form1 creado?

Ojalá pudiesen ayudarme. Es de momento, lo ultimo que me faltaría, para poder entregar este proyecto.

Mil gracias, y un gran saludo.

Julián.

voldemmor 19-12-2009 19:13:45

form.....
 
A ver si te sirve algo como esto.

La declaracion de tu procedure hasla en
Código Delphi [-]
public.

En la form2 coloca una referencia a tu form1

en el procedimiento del boton en tu form2 has la referencia al objeto form1 que ya existe
Código Delphi [-]
uses
tform1;
 
procedure boton
begin
  form1.creartab();
end;

espero te ayude en algo

Robin1 19-12-2009 19:36:03

Hola, Voldemmor, mil gracias por tu amable respuesta.

Verás, implementando el método que muy amablemente me expones, sucede esto: "No hay parametros suficientes", según el compilador Delphi 7.

Esta función, sobre crear un nuevo Tab, tiene algunas variables en el form1 que hay que declarar, para que los objetos que se crean con él, en tiempo de ejecución, lo hagan del modo correcto.

De este modo, no sé, si es necesario hacer referencia también a todo esto, o definitivamente, por ahí, no está la solución.

Tu que opinas?

Mil gracias por tu respuesta, y un gran saludo.

Julián

rrf 19-12-2009 23:12:12

Hola.
Creo que el error salta porque, en el ejemplo de código de voldemmor, no se pone ningún parámetro dentro del paréntesis al llamar al procedimiento. Y posiblemente, en el procedimiento al que tu llamas, sí que tiene 1 ó más parámetros.

Así, en lugar de escribir:

Código Delphi [-]
procedure boton
begin
  form1.creartab();
end;

deberías escribir la lista de parámetros que le pasas al procedimiento dentro del paréntesis. Si fueran 3 valores del tipo Integer (por ejemplo: 1, 3 y 8), podría quedar así:

Código Delphi [-]
procedure boton
begin
  form1.creartab( 1, 3, 8 );
end;

Espero te sirva.
Ramón.

Robin1 20-12-2009 19:56:26

Hola, rrf, mil gracias por tu respuesta.

Verás, estuve intentándolo del modo que me propones, pasando los parametros a la función, pero definitivamente, al momento de la compilación, se crea una excepción.

Quisiera en tiempo de ejecución, crear un nuevo tab, en un page control, en el Form1, desde el Form2.

He estado tratando incluso, escribiendo todo el procedimiento, en el propio Form2, tal cual, lo hago en el Form1, pero tampoco funciona.

Mil gracias por la amable ayuda. Haber de que modo se puede implementar.

Un gran abrazo, y un gran saludo.

rrf 21-12-2009 00:32:22

Hola Robin1.
A ver si esta idea te sirve.
Si vas a crear el componente en el Form1, haz un procedimiento en el form1 que haga lo que quieres (por ejemplo, lo llamas "crea_Tab") y que sea llamado desde el mismo Form1; por ejemplo, al hacer click en un botón.
Comprueba que funciona.
Cuando ya veas que está bien y que funciona, haz la llamada a ese procedimiento desde el form2. (para ello, en el 'uses' del form2 debes incluir el Form1 y la llamada desde el form2 al procedimiento sería algo así 'form1.crea_Tab' ).
un saludo.
Ramón.

voldemmor 21-12-2009 23:26:34

Disculpas
 
Ante todo disculpas por no responder antes, estube algo ocupadito.:D.

Bueno la idea de rrt es la misma que se la plantee con anterioridad.
Que te parece si vas probando linea por linea tu codig.
Por ejemplo primero crea un procedure en la parte public de tu form1, llamalo desde tu form2.

Primero solo vas ha crear un mensaje de tu applicacion
Código:

showmmessage('funciona');
;
Si todo va bien trata con iniciar escribiendo parte por parte el codigo que usas a ver donde te da el error.

Con todo por favor postea el codigo que usas a ver si te podemos ayudar un poco mas.

Nuevamente diosculpas por no responder antes

voldemmor 21-12-2009 23:27:27

Disculpas
 
Ante todo disculpas por no responder antes, estube algo ocupadito.:D.

Bueno la idea de rrf es la misma que se la plantee con anterioridad.
Que te parece si vas probando linea por linea tu codig.
Por ejemplo primero crea un procedure en la parte public de tu form1, llamalo desde tu form2.

Primero solo vas ha crear un mensaje de tu applicacion
Código:

showmmessage('funciona');
;
Si todo va bien trata con iniciar escribiendo parte por parte el codigo que usas a ver donde te da el error.

Con todo por favor postea el codigo que usas a ver si te podemos ayudar un poco mas.

Nuevamente diosculpas por no responder antes

Robin1 22-12-2009 00:19:58

Hola, y mil gracias, tanto Voldemmor, como rrf, por responder.

En verdad que esta vez si que estoy perdido con esto.

Explicaré inicialmente, qué es lo que pretendo, y como va la cosa.

La aplicación en cuestión, es un navegador de Internet personalizado, que se basa en el motor de renderizado Gecko de Mozilla Firefox.

Entonces, el Form1, es en donde se encuentra toda la interfaz (lastima no poder mostrar fotos) de usuario, es decir, el navegador, la barra de navegación, los tabs, todos los controles, etc.

El Form2, es un Form estilo "About".

Qué sucede entonces:

En el form1 hay por ejemplo, un menú en la parte superior contextual, que tiene esta opción: "New Tab".

De este modo, al dar click sobre este comando, se desencadena el siguiente evento:

Código:

procedure TForm1.NewTab1Click(Sender: TObject);
var
 NewTab: TTabSheet;
    NewBrowser: TGeckoBrowser;
    PageControl1: TPageControl; //Solo en el procedimiento Reset, de momento es utilizada esta variable.

begin
 //Todo procedimiento que incluya nuevos elementos, y carga de Internet, debe primero pasar por una verificación del PingBrowser.
  PingBrowser.Navigate('Pagina de Google');
   
NewTab := TTabSheet.Create(Self);  //Se crea la nueva pestaña
    NewTab.Caption := '  Tab  ' + IntToStr(PageControl1.PageCount + 1); //Consecutivo de Nombres para cada pestaña
      NewTab.PageControl := PageControl1; //El contenedor de la pestaña sera un PageControl

        NewBrowser := TGeckoBrowser.Create(Self);
          NewBrowser.Parent := NewTab;
          NewBrowser.Align:= alClient;

            PageControl1.ActivePage := NewTab; //Se activa la pestaña. Esta parte es la clave, para que Gecko se cargue en la pestaña a la que debe ir. Sin esto, nunca funcionará nada.

            if Pos('Connected', ConnectionStatus.Text) > 0 then
                  NewBrowser.LoadURI('La pagina a la que Gecko debe dirigirse')
            else
              begin

                TOleControl(ErrorBrowser).Visible := True;
                TOleControl(ErrorBrowser).Align:= alClient;
                  ErrorBrowser.Navigate('file:///' + ExtractFilePath(ParamStr(0)) + 'res\html\war\ConnectionFail.html');
              end;
end;

Entonces, de este modo, se va creando cada pestaña, en el Form1.

Qué sucede entonces con el Form2?

Bien, en el Form2 tengo un Label que dice: "Preguntas Frecuentes", de este modo, si el usuario Clickea este Label, el navegador debe redirigir abriendo un nuevo Tab en el form1, hacia la página Web, en donde está la sección de preguntas frecuentes.

Básicamente esa es la cuestión, ya viéndolo un poco mas aterrizado en la práctica.

Que observo:

Cualquier procedimiento que esté tanto en el form1 o en el Form2, si lo paso a la sección "Public" de inmediato el compilador genera una excepción (Uso Delphi 7), y el programa no se deja compilar.

De este modo, veo muy complicado poder hacer este llamado desde el Form2, a ese procedimiento que está en el Form1.

¿Como le podría hacer?

Digamos, ¿es posible entonces, por ejemplo, no generar ese llamado, sino más bien, desde el Form2 crear un procedimiento idéntico para el Form1?

Nuevamente, mil gracias, en verdad, por esta magnifica ayuda que he recibido. Ahí poco a poco, con esta valiosa ayuda, vamos viendo las opciones, para solucionar este tema, haber si puedo ya lanzar el programa :-), jajajajaja!!!

Un gran abrazo, señores.

Julián Franco

Robin1 22-12-2009 05:03:32

Solucionadooooooooo!!!!!!!!!! :-)
 
Bueno, aquí sentado probando varias formas, y, evidentemente, siguiendo al pie de la letra las muy pertinentes indicaciones, que, Voldemmor, y rrf, me han sugerido, he encontrado la solución al problema, que resultó ser una pequeña omisión, de algo muy simple.

No hubo necesidad de declarar este procedimiento, desde el Form1 en la parte de declaraciones públicas (ya que este simple hecho, me estaba generando una Excepción en tiempo de ejecución... -->Eso aún no lo comprendo, y sería tema de discusion para otro Post)

Entonces, teniendo en cuenta esto, era necesario optar por otra vía.

Que hice? Dejé todo tal cual, como estaba al principio, es decir, todas las declaraciones en el lugar en que por defecto están, y los procedimientos en la parte de abajo, en el Form1.

En el Form2, generé el evento de dar Click, sobre el Label de preguntas frecuentes.

Notaba que todo estaba (aparentemente) bien declarado, es decir, no había errores de sintaxis, por lo cual, pensaba qen que algo me faltaba, ya que el programa corría perfectamente, pero al abrirse el Form2, y dar Click sobre el Label, se generaba una excepción, que cerraba el programa.

Comencé a pensar, y aquí llego la solución:

Si el llamado se hace desde el Form2, para que abra en el Form1 una nueva pestaña, y ubique un componente Browser, y navegue hacia determinada página, ¿Quien tiene en ese mismo momento el Foco?

Lo tiene el Form2.

Entonces, qué debería hacer primero?

Aquí está codigo que hace el llamado desde el Form2, sin problema:

Código:

procedure TForm2.LblFrequentlyAskedQuestionsClick(Sender: TObject);
begin
  Form1.SetFocus;
  Form1.ReleaseNotes1Click(Sender);
    Form2.Close;
end;

Form1.SetFocus, era la clave de todo.

Agradezco mucho, la gran ayuda prestada, y la colaboración que recibí. Este proyecto que desarrollo, hace parte de algo muy importante para mí, ya que no soy programador, soy comunicador Social y todo lo he ido aprendiendo sólo en mi casa, leyendo y practicando mucho, y contando con la ayuda de gente como la que hay en este buen lugar.

Mil gracias de nuevo, y un gran saludo a todos.

Julian Franco

rosalara 26-04-2011 06:32:56

Hola buen dia a todos, me pregunto si alguien peude asesorarme en cuanto a los procedimientos llamados desde un form diferente a donde se crearon, ya hice lo que aqui proponen pero me sigue dando el error en el nuevo form que dice asi Undeclared identifier: 'Grafica' que es el procedimiento que necesito ojala alguien me pueda auxiliar

rrf 26-04-2011 16:23:33

Hola rosalara.

Mira, creo que el continuar este tema es un error, porque lo que tratas no tiene una clara relación con el tema desarrollado hasta ahora. Además, el tema anterior se agotó en el 2009 y estamos en el 2011.

Te sugeriría que abrieras un nuevo tema para tu consulta, que expliques el problema lo mejor posible y que, si puede ser, añadas el código que has escrito y que te produce un error.

Asi será más fácil que recibas ayuda.

Saludos.


La franja horaria es GMT +2. Ahora son las 07:12:35.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi