Un clasico caso de herencias entre padres e hijos

Aunque como siempre empezaremos diciendo que este ejemplo responde a las inquietudes de algunas consultas recibidas sobre MDI y de nuevo intentando darle un aire desenfadado, os dejo esta idea para clarificar… o liaros mas en el concepto de heredar.


Espero vuestros comentarios… eso si, que sean amables y con cariño.
Pep Lluis,


‘ Un clasico caso de Herencias…

Public Class ElPadre   
» 
   
» Construir el entorno en tiempo de carga
    »   
Private Sub ElPadre_Load() Handles MyBase.Load
       
‘ Me declaro contenedor de toda mi descendencia
        Me.IsMdiContainer = True
        Me.Text = «Soy el Progenitor, Padre de algunos y Abuelo de otros»
        ‘ Mi primer Hijo tendra un boton para crear mas hijos
        Dim CrearFormHijo As New Button
        CrearFormHijo.Text = «Tener un hijo»
        CrearFormHijo.Dock = DockStyle.Top
        Me.Controls.Add(CrearFormHijo)
        ‘ Invocar la funcion de Crear, al hacer click
        AddHandler CrearFormHijo.Click, AddressOf Crear   
End Sub
    »
    » Crear y Definir el Aspecto de los Hijos del Padre y sus Nietos
    »
    Private Sub Crear()
       
        ‘Definir la primera linea de descendencia
        Dim FormHijo As New MiForm(Me)
        FormHijo.Text = «Yo Soy el Hijo – Descendencia directa»
        ‘Presentar al nieto en sociedad
        FormHijo.Show()
       
        ‘Definir la segunda linea tomando la primera
        ‘como referencia y añadiendo nuevas particularidades
        Dim FormNieto As New MiForm(Me)
        FormNieto.Text = «Yo Soy el Nieto»
       
        ‘Los nietos tienen dos botones… peazo xoyo!
        Dim BotonDelNieto As New Button
        BotonDelNieto.Name = «BotonDelNieto»
        BotonDelNieto.Text = «Abuelo! Que hora es?»
        BotonDelNieto.Dock = DockStyle.Bottom
        FormNieto.Controls.Add(BotonDelNieto)
       
        ‘Llamar al Abuelo al pulsar el boton de todos los descendientes
        AddHandler BotonDelNieto.Click, AddressOf FormHijo.llamarAPapa
       
        ‘Llamar al verdadero padre, sobre el boton particular de los nietos
        AddHandler FormNieto.Controls.Item(0).Click, AddressOf FormNieto.YoSoyElVerdaderoPadre
        ‘Presentar al nieto en sociedad
        FormNieto.Show()
    End Sub
   
    ‘ solo mis hijos y nietos saben la hora
   
    Public Function MensajeDePapa() As String
        Return «Son las « + System.DateTime.Now
    End Function End Class

»
» Origen «genetico» de todos mis form’s
»
Public Class MiForm
    ‘ A su vez heredo todas las particularidades de WinForms
    Inherits Form    ‘ La referencia a mi antepasado
    Private MiPadre As Object
   
    ‘ Nacimiento!
   
    Sub New(ByVal padre As Object)
        ‘ Referenciar y no olvidar mis origenes
        MiPadre = padre
        MdiParent = MiPadre
       
        ‘ Mi descendencia heredara un boton mas que yo.
        
        Dim BotonDelHijo As New Button
        BotonDelHijo.Name = «BotonDelHijo»
        BotonDelHijo.Text = «Papa!… que hora es?»
        BotonDelHijo.Dock = DockStyle.Top
        Controls.Add(BotonDelHijo)
        ‘ Llamar a mi papa por click en boton del hijo
        AddHandler BotonDelHijo.Click, AddressOf llamarAPapa
    End Sub
   
    ‘ LLamar a papa
   
    Sub llamarAPapa()
        MessageBox.Show(MiPadre.mensajeDePapa, «Ummm…»)
    End Sub
   
    ‘ Llamar a mis antecesores… eres tu abuelo?
   
    Sub YoSoyElVerdaderoPadre()
        MessageBox.Show(» Yo soy tu verdadero padre!!», «Aunque te respondio Mi padre»)
    End Sub 

End Class


 

Conversaciones entre lenguages y compiladores – Vasado en una historia Real!

Con vuestro permiso y para no perder costumbre os invito a leer este relato corto en tono de humor… que lo disfrutéis!

Hace algunos días, en una de esas reuniones de profesionales, en las que aprovechando el buen recaudo de una cena, se discuten y se tratan todo tipo de temas sin orden ni concierto; recuerdo como entre medio de disertaciones sobre metodologías, lenguajes y sintaxis, me encontré  “para variar” evocando aquellos tiempos en que el pan era pan, el vino, vino y los lenguajes eran lenguajes de ¡alto nivel!.  

A lo ancho de la alargada mesa  se mantenían diversos “hilos” activos con diversas conversaciones “a saber cual la mejor”. Mientras sin saber porque,  y acaloradamente  empecé a recordar aquellos tiempos en los que los compiladores eras verdaderas joyas de la ingeniería.  Aquellos tiempos en los que sin existir la programación orientada a objeto éramos capaces de depurar los ensamblados de los Intel 8086 de las lanzaderas espaciales “online” y en tiempo real, para terminar llevando a un puñado de astronautas a la luna… de pronto me grite para mis adentros  :

“Pep!!! Eres un viejo incorregible, siempre terminas hablando de cómo era, pareces un petrificado historiador de informática”
A caldo de la conversación y después de mi pausa se fueron apagando el resto de conversaciones. Sin darme cuenta concentre todas las miradas mientras argumentaba que a pesar de entender la incorporación de ciertas metodologías tales como el procedimiento de realizar un “Invoke” para poder manejar datos entre hilos, tenía cierta sensación de que la medida que avanzábamos en las técnicas perdíamos ciertas purezas del lenguaje. Para poner un ejemplo, desde cierto punto de vista aunque no global, podría entender que fuera el propio compilador que decidiera como cruzar esos datos que se generan entre hilos de ejecución diferentes, de forma que no me obligara a invocar un procedimiento a no ser que yo lo explicitara.

Me gustaría poder enseñaros una foto del las caras que reflejaban los que estaban atentos a mi conversación, en ese momento no se si ponían cara de bobo por absortos o porque realmente estaban pensando que Pep  estaba  más loco que una cabra. Una vez mas para mis adentros pensé ..

“quien me mandara a mi meterme en semejantes pasteles! … luego me quejo de mi fama! J”.

En honor a todos los presentes y en pro de mi integridad y dedicado a mis contertulios más próximos Vicenc Masanas y Marc Rubiño, os dejo el apunte que en una línea resume lo estaba intentando explicar y que ¡en una línea! Explica que mis pensamientos no eran tan salidos de contexto ni estaban en absoluto equivocados.

CheckForIllegalCrossThreadCalls = false;

Para los que no estuvisteis en la cena… con este pragma instruimos al compilador si queremos controlar o no, las llamadas entre hilos a pesar de que sean “ilegales”, por lo tanto mi código podrá intercambiar datos entre hilos por contrabando sin necesidad de invoKar a nadie.Eso si en C++… ahora os dejo a vosotros que averigüéis si mi critica a los compiladores de C# o Visual Basic , eran infundadas y disponen de algo parecido.Cuidaros mucho y buen FinDe,
Pep Lluis,

 

Acceder al Espacio System.IO.Ports en C++

Algunos de vosotros en el foro estáis solicitando si es posible utilizar el System.IO.Ports con C++, esperando que esto sea un punto de entrada en un ejemplo súper simple!! De solo enviar y recibir una trama.

System IO Port & C++

Podéis descargaros el archivo adjunto, no esta probado en C++ express, pero supongo que no tendréis ningún problema en ejecutarlo.

Por cierto si reubicáis el proyecto (lo colocáis en un path diferente al original), cuando intentéis recompilarlo os generara un error : C1093 – detallando que no puede encontrar «stdafx.h». El concepto es que el proyecto genera y apunta determinadas referencias en tiempo de compilación, entonces la solución es  hacer un “build>Clean Solution” desde “Generar>Proyecto>Limpiar”. Luego simplemente “F5” J

Espero vuestras valoraciones.
Pep Lluis,

** El proyecto esta realizado con la vesion 9 de Visual Studio. (2008)
A peticion vuestra os dejo el codigo, para utilizarlo con Visual Studio 2005. Solo teneis que crear nuevo proyecto ‘winforms’ arrastrando y soltando un ‘ListBox’ un ‘Boton’ y un SerialPort.

namespace SystemIOPorts_EN_C {

 

      using namespace System;

      using namespace System::ComponentModel;

      using namespace System::Collections;

      using namespace System::Windows::Forms;

      using namespace System::Data;

      using namespace System::Drawing;

 

      /// <summary>

      /// Resumen de Form1

      /// Ejemplo de utilizacion del System.IO.Ports desde C++

      /// (C) Pep Lluis 2008

      ///

      ///

      /// Para realizar las pruebas es necesario insertar un

      /// conector de 9 pins en el puerto serie utilizado

      /// cortocircuitando (puenteando) los pines 2/3

      ///

      /// </summary>

      public ref class Form1 : public System::Windows::Forms::Form

      {

      public:

 

            Form1(void)

            {

                  InitializeComponent();

                  //

                  // Abrir el puerto de comunicaciones

                  // inhibir la verificacion de error de llamadas entre hilos

                  //

                  this->serialPort1->Open();

                  CheckForIllegalCrossThreadCalls = false;

            }

 

      protected:

            /// <summary>

            /// Limpiar los recursos que se estén utilizando.

            /// </summary>

            ~Form1()

            {

                  if (components)

                  {

                        delete components;

                  }

            }

      private: System::IO::Ports::SerialPort^  serialPort1;

      private: System::Windows::Forms::ListBox^  listBox1;

      private: System::Windows::Forms::Button^  button1;

      protected:

      private: System::ComponentModel::IContainer^  components;

 

      private:

            /// <summary>

            /// Variable del diseñador requerida.

            /// </summary>

 

 

#pragma region Windows Form Designer generated code

            /// <summary>

            /// Método necesario para admitir el Diseñador. No se puede modificar

            /// el contenido del método con el editor de código.

            /// </summary>

            void InitializeComponent(void)

            {

                  this->components = (gcnew System::ComponentModel::Container());

                  this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components));

                  this->listBox1 = (gcnew System::Windows::Forms::ListBox());

                  this->button1 = (gcnew System::Windows::Forms::Button());

                  this->SuspendLayout();

                  //

                  // serialPort1

                  //

                  this->serialPort1->BaudRate = 115200;

                  this->serialPort1->DataReceived += gcnew System::IO::Ports::SerialDataReceivedEventHandler(this, &Form1::serialPort1_DataReceived);

                  //

                  // listBox1

                  //

                  this->listBox1->FormattingEnabled = true;

                  this->listBox1->Location = System::Drawing::Point(13, 13);

                  this->listBox1->Name = L«listBox1»;

                  this->listBox1->Size = System::Drawing::Size(259, 95);

                  this->listBox1->TabIndex = 0;

                  //

                  // button1

                  //

                  this->button1->Location = System::Drawing::Point(197, 114);

                  this->button1->Name = L«button1»;

                  this->button1->Size = System::Drawing::Size(75, 23);

                  this->button1->TabIndex = 1;

                  this->button1->Text = L«Enviar»;

                  this->button1->UseVisualStyleBackColor = true;

                  this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);

                  //

                  // Form1

                  //

                  this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);

                  this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;

                  this->ClientSize = System::Drawing::Size(284, 147);

                  this->Controls->Add(this->button1);

                  this->Controls->Add(this->listBox1);

                  this->Name = L«Form1»;

                  this->Text = L«C++ & System.IO.Ports»;

                  this->ResumeLayout(false);

 

            }

#pragma endregion

 

            /// Enviar trama usando System.IO.Ports

      private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {

                         this->serialPort1->Write(L«Hola Gente»);

                   }

 

          /// Leer los caracteres recibidos y añadirlos al ListBox

      private: System::Void serialPort1_DataReceived(System::Object^  sender, System::IO::Ports::SerialDataReceivedEventArgs^  e) {

                         this->listBox1->Items->Add(serialPort1->ReadExisting());

                   }

 

      };

     

}

 

Delegados?

A menudo preguntamos sobre que son y para que sirven los delegados… valga esta entradrilla :-))

‘Según definición…
‘ Un delegado es un tipo que referencia un método compartido
‘ de un método tipo o una instancia de un objeto
‘ Cualquier procedimiento puede ser utilizado para crear una clase delegada
‘ de la instancia y posteriormente ser invocada a través del delegado
‘ … ea una especie de punteros…

 


‘Aunque el siguiente ejemplo no ilustre todos los usos 
espero sirva de punto de partida para los que empiezan.


‘No olvideis que el delegado puede contener y devolver parámetros…


‘pero eso es trabajo del artista.
 


 Delegate Function MiDelegado()

 Public Class Form1
    Private Encendido As Boolean = False

    Private Sub Form1_Load() Handles MyBase.Load
        ‘construir botón
        Dim MiBoton As New Button
        MiBoton.Text = «Asignar Delegado»
        MiBoton.AutoSize = True
        MiBoton.Dock = DockStyle.Bottom
        ‘al hacer click ejecutar sub
        AddHandler MiBoton.Click, AddressOf EncenderApagar
        ‘añadir botón al form
        Me.Controls.Add(MiBoton)
    End Sub

 
   Private Sub EncenderApagar()
        ‘Crear mi referencia al tipo delegado
        Dim MiRefencia As MiDelegado
        ‘Encender si está apagado / apagar si encendido
        If Not Encendido Then
            ‘asignar referencia a la función de encender
            MiRefencia = AddressOf Encender
        Else
            ‘asignar referencia a la función de apagar
            MiRefencia = AddressOf Apagar
        End If
        ‘Invocar la función en mi delegado
        MessageBox.Show(MiRefencia.Invoke)
    End Sub
   
    ‘Devolver el estado de encendido
    Private Function Encender() As String
        Encendido = True
        Return «Encendido»
    End Function
   
    ‘Devolver el estado de apagado
    Private Function Apagar() As String
        Encendido = False
        Return «Apagado»
    End Function
 End Class

Saludos,
Pep Lluis,