When VB Becomes OOP / Cuando VB se convirtió en POO

YES!!  Vb2

Sixteen years ago, after unending “Basic” programs, running lines of sequential sentences by number interpreted by a sad Basic runtime compiler, VB born announcing great news, one of more expected features claimed for Basic developers are the Objectoriented programming and now included in this first release.  (… I know.. Not full, light, but OOP 😉 ) , the other one, is changing the classical algorism when write programs, introducing advanced programming paradigms.

With this launch in 1992, VB for first time in several years becomes a first class language… this represent an incredible step for VB programmers and have your first implementation build for DOS space, using ASCII Chars to recreate real windows environment. ¡¡what’s folly!!

The short live of this product and the jumping Windows age, be responsible to not produce enough waves to arrival at wide developers community.  Only few enterprises can develop real applications with this fantastic environment, but I’m sure that the spirit and essence of this language comes inside the heart of all versions.

UMM… good times.  J
Pep Lluis,

 

Hace dieciséis años y después de interminables programas en Basic que ejecutaban líneas secuenciales de sentencias ordenadas por números interpretadas por aburridos compiladores, VB Nace anunciando una gran noticia en torno a la aplicación de nuevos paradigmas de programación avanzada. En esta Ocasión añadiendo la esperada y tan aclamada Programación orientada a objetos, aunque carecía de algunos aspectos primordiales de una POO real, podemos afirmar que era una buena implementación filosóficamente hablando. Con este avance VB se convierte en un lenguaje de primera línea… este gran paso para los programadores de Basic en 1992, vio su primera implementación en DOS y utilizando caracteres ASCII para simular un entorno real de ventanas. ¡Menuda locura! La corta vida de este producto y el despegue de la era de Windows fueron responsables e impidieron que llegara a conocimiento del grueso de la comunidad de desarrolladores. Solo unas pocas empresas pudieron desarrollar aplicaciones reales en este fantástico entorno, aunque estoy seguro de que el espíritu y la esencia del lenguaje continúan presentes en el corazón de todas sus versiones.

UM… qué tiempos aquellos.. J
Pep Lluis,

VB9 – Implicitly Typed Local Variables

Una de las preguntas mas frecuentes en repetidas conversaciones, es : que hay de nuevo en el recien liberado VB9?
Pues bien a modo de cortos y para hacer mas asequible la utilizacion de algunas de las ‘nuevas’ aqui va la primera de una pequeña serie.


OfCourse… espero vuestro comentarios.

 ‘Explicito.. lo de siempre
Dim MiNombre As String = “PepLluis”
Dim MiEdad As Integer = 29
Dim MisPersonas As Persona = New Persona With {.Nombre = “Maria”}
 ‘Implicito, Inferencia en la definicion
Dim TuNombre = “Mauricio”
Dim TuEdad = 39
Dim TusPersonas = New Persona With {.Nombre = “Carmen”, .Edad = 20}

‘Nuestra clase Persona
Class Persona
     Public Nombre = “”
     Public Apellido = “”
     Public Edad = 0
End Class

PD. Si asi lo considerais, podemos comentar el codigo, añadiendo mas explicaciones… quizas sea mas clarificador, espero vuestras valoraciones.

Saber de los Hijos de un MDI

Una pregunta frecuente sobre los “Multiple Document Interfaces’ es como saber los forms que estan cargados en un momento determinado. Aqui os dejo un breve y como siempre ‘Simple’ ejemplo, para tener acceso a la lista de documentos cargados en un MDI.


Por supuesto faltara recorrer la lista de items en el ‘menuItem’ para procesar las decisiones en funcion a los forms cargados, pero supongo que esa es la parte facil… supongo bien?…


Cualquier sugerencia o comentario sera bien recibido,
Saludos,
Pep Lluis,

Public Class Form1   
  ‘   
  ‘Al cargar el form
   
  ‘
   
  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

       ‘El form1 se convierte en un MDIContainer
        Me.IsMdiContainer = True
        ‘Crear un nuevo boton para añadir
        Dim MiBoton As New Button
        MiBoton.Text = “Añadir”
        MiBoton.Dock = DockStyle.Bottom
        ‘Apuntar a la funcion de añadir al hacer click al boton
        AddHandler MiBoton.Click, AddressOf NuevoFormHijo
        ‘Añadir un boton al final del MDI
        Me.Controls.Add(MiBoton)
        ‘Crear un nuevo Menu
        Dim MiMenu As MainMenu = New MainMenu
        Me.Menu = MiMenu
        ‘Anadir item de forms cargados al menu
        Dim misForms As MenuItem = MiMenu.MenuItems.Add(“&Forms Cargados”)
        ‘este item debera visualizar la MdiList
        misForms.MdiList = True
    End Sub
   
    ‘Añadir un nuevo form al contenedor MDI
   
    Private Sub NuevoFormHijo(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim UnHijoMas As New Form
        UnHijoMas.Text = “He Nacido a las : “ + System.DateTime.Now
        UnHijoMas.MdiParent = Me
        UnHijoMas.Show()
    End Sub

End Class


 

Visual Studio, LoaderLock con proyectos que Utilizan DirectX o WinSocks.

LoaderLock managed debugging assistant (MDA) detects attempts to execute managed code on a thread that holds the Microsoft Windows operating system loader lock. Any such execution is illegal because it can lead to deadlocks and to use of DLLs before they have been initialized by the operating system’s loader.”


O sea que los MDA’s detectan que estamos intentando ejecutar codigo administrado en un hilo que el cargador del sistema operativo tiene bloqueado, cualquier ejecucion es ilegal pues prodria perder los vinculos con los ‘deadlocks’ y usar las DLL’s antes de que estas hubieran sido inicializadas por el cargador del sistema operativo.


Acostumbra a ser un ‘toston’ en fases de desarrollo, pues solo afecta a los Debuggers, para poder sortear esta dificultat simplemente tienes que deshabilitar la opcion ‘loaderlock’ de Visual Studio.



  1. Pulsa ‘Ctrl+Alt+E’ (te aparecera la ventana de excepciones)

  2. Bajo ‘Managed Debugging Assistants’ busca ‘loaderlock’ 

  3. Click para dejarlo sin seleccion.

¡Listo! Cuando te pongas a trabajar… solo tendras que aceptar la advertencia de bloqueo… pero nada mas.


Saludos,
Pep Lluis,

No se controló COMException! – Interoperar objectos COM de VS6 a VS2005

No cabe la menor duda, que uno de nuestros trabajos mas desagradables es entender y resolver problemas de interaccion entre aplicaciones diseñadas y desarrolladas con diferentes tecnologias.


No hace mucho me toco ¡perder toda una mañana! Intentando interactuar con un ‘Component Object Model’  desarrollado en VB6.  Referenciar e instanciar el objeto esta claro que fue muy sencillo… sin embargo las sonrisas se iniciaron al intercambiar informacion entre ambos :


Los tipos no coinciden. (Excepción de HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))


Originalmente utilizaba typos ‘variant’ en .NET ‘object’, estaba tan convencido de que todo estaba bien que incluso no quise buscar ninguna solucion en la ‘base de conocimiento’ ni en la ayuda… dale que te pego, hasta darme cuenta!!


Por defecto cualquier al crear un nuevo proyecto en el ‘AssemblyInfo’ nos crea una entrada que por defecto!… POR DIOS!!  â€¦ es ‘False’. Se trata de saber que esa entrada, exactamente esa entrada debe estar en ‘True’ para disponer de la funcionalidad que requiere mi proyecto.


Mi disgusto viene despues de andar cuatro horas detrás de todo esto para entender que ademas de continuar siendo un novato despues de 30 años, mi torpeza tampoco mejora!

Espero que algun que otro sufridor con este problema, localice informacion en menos tiempo que yo.

<Assembly: ComVisible(False)> ‘POR DEFECTO (CON ERROR)
<Assembly: ComVisible(True)>  â€˜La SOLUCION!


o Bien Seleccionando la opcion ‘Crear ensamblado visible a traves de COM’ en la ‘Informacion del Ensamblado’


Como siempre las cosas mas evidentes son las que nos quitan el sueño y nos hacen perder la mayor parte de nuestro preciado tiempo.


Saludotes!
Pep Lluis,

Visual Studio 2005 – La ubicacion del Proyecto no es de confianza… ofCourse en Vista!

También en Vista y a pesar de disponer de un buen numero de herramientas para la gestión de código, en algunas situaciones nos interesa poder acceder a los proyectos de Visual Studio almacenados en algún que otro recurso de red. “También en Vista” necesitamos del ‘caspol’… pero donde esta el de FW 3.0!Pues la respuesta es ¡No esta!, para estos menesteres, continuaremos utilizando el – .NET Framework 2.0 Configuration.

… Inicio>Panel de Control>Herramientas Administrativas>

A continuación abriremos la ‘Management Console’ del Framework 2.0 Configuration.

Mi Pc>Directiva de seguridad en tiempo de ejecución>Equipo>All_Code>LocalIntranet_Zone>

En el agregaremos un grupo de código secundario y lo configuraremos para que el recurso ‘url’ este mapeado a su dirección, ejemplo : “file://Servidor/Recurso/*. ” para posteriormente otorgarle conjunto de permisos ‘FullTrust’.Espero que os sea de utilidad y como siempre no dudeis en consultar sobre cualquier duda al respecto.
Pep Lluis,

Por cierto, si el recurso pertenece a un Dominio… son buenas practicas que dicho equipo este unido a ese dominio.

Cargar/Descargar Archivos Desde y Hacia una Columna ‘image’ SQL

 


Friend Class Ejemplo


    Private _ms As MemoryStream  ‘Carga/descarga de archivos SQL


    Private _Fs As FileStream    ’Manejo archivos en memoria


    Private _By() As Byte = Nothing  ‘Array de intercambio


 


   


    ‘Guardar el Documento


    Private Sub Doc_Almacenar(ByVal Origen As String, ByVal Nombre As String)


        Try


            ‘crear un nuevo fstrm con el archivo apuntado en la ruta


            ‘contenida en el origen


            _Fs = New FileStream(Origen, FileMode.Open, FileAccess.Read)


            ‘redimensionarlo y adaptarlo a su longitud


            ReDim _By(_Fs.Length)


            ‘convertir el fstrm en un array de bytes


            _Fs.Read(_By, 0, _Fs.Length)


            ‘Archivos es el tableadapter


            ‘almacenar array en una imagen binaria Sql


            Archivos.Insert(Nombre, _By)


            _Fs.Close()               ‘cerrar el fstrm


            _Fs.Dispose()             ‘Liberarlo


        Catch ex As Exception


            ‘En caso de excepcion…


            Me.lblExcepciones.Text = “DocAlmacenar: “ + ex.Message


        End Try


    End Sub


   


    ‘Cargar documento desde la col imagen de SQL


    Private Sub Doc_Recuperar(ByVal Nombre As String)


        Try


            ‘Recuperar imagen de SQL a un array intermedio


            If Nombre.Length > 0 Then


                ‘el table adapter devuelve una imagen


                ‘resultante de la consulta ‘Recuperar(Col Nombre)’


                Dim Buffer() As Byte = Archivos.Recuperar(Nombre).Rows(0).Item(“Imagen”)


                ‘Crear un nuevo archivo


                _Fs = New FileStream(“Documento.tmp”, FileMode.Create, FileAccess.Write)


                ‘escribirlo a partir del array intermedio


                _Fs.Write(Buffer, 0, Buffer.Length)


                _Fs.Close()       ‘Cerrar el fstrm


                _Fs.Dispose()     ‘Liberarlo


            End If


        Catch ex As Exception


            ‘En caso de excepcion, reportar


            Me.lblExcepciones.Text = “DocRecuperar: “ + ex.Message


            Try


                My.Computer.FileSystem.DeleteFile(“Documento.tmp”)


            Catch ex2 As Exception


                Me.lblExcepciones.Text = “Eliminar: “ + ex.Message


            End Try


        End Try


    End Sub


End Class


 

DataGridView… Quiero saltar de de Columna!!! no de fila

Muchos de nosotros aprovechamos el control DataGridView como visualizador, sin embargo además puede ser una excelente ayuda para añadir nuevas filas a nuestras estructuras de datos.

En un proceso donde la información se estructura mediante columnas y líneas, el objetivo es introducir nuevas filas con la mayor facilidad posible, es entonces cuando nos percatamos de que por defecto el DataGridView actúa de una forma un tanto inconveniente para nuestro cometido. Cada vez que pulsamos ‘enter’ ya sea en modo ‘edición’  el efecto es que nos crea una nueva fila desplazándose acto seguido a la primera celda de la misma (como en Excel), entonces nos obliga a utilizar los cursores para reubicar el ‘foco’ a la celda donde va a continuar nuestra próxima entrada. Realmente es un inconveniente, pues nos hace perder muchísimo tiempo empleándolo en pulsaciones simplemente inútiles.

Dicho esto, para poder introducir datos de izquierda a derecha tal y como estamos acostumbrados en la mayoría de situaciones en la que manejamos información, podemos recurrir a varios recursos, os proponemos ver como anulando las funciones ‘ProcessDialogKey’  ‘OnKeyDown’ y rescribiendo el código para que la pulsación de una tecla ‘enter’ sea substituida por un ‘tab’  utilizando un ‘sendkeys’, pudiendo conseguir una mejora increíble en la funcionalidad. También en una segunda propuesta os introducimos a como manejar el direccionamiento de selección de las ‘celdas’ de un DataGridView capturando las pulsaciones en el ‘PreProcessMessage’, ambas heredando la funcionalidad DataGridView y añadiendo a esta personalidad propia.

Esperamos que os sea de utilidad… solo tenéis que ¡cortar y pegar!

Pep Lluis y Rafael.

'' (c) Pep Lluis & Rafa Vargas

'' Ambos ejemplos vienen derivados de una inquietud compartida en

'' el ultimo Code Camp del Escorial en el 2006 entre Rafa Vargas y

'' Pep Lluis… no cabe duda del lema 'Comparte y Aprenderas'.

''

Public Class form1

    Private WithEvents _MiDGView1 As New DgvPlus     'Mi DGV, que traduce el 'Enter' en 'Tab'

    Private WithEvents _MiDGView2 As New MiDGView    'Mi DGV, que controla la posicion de la celda actual

    '

    ' al lanzar nuestro form (en el momento de carga)

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        '

        'Construir el primer DGV

        _MiDGView1.Dock = DockStyle.Left                                          'Acoplarlo a la izquierda

        _MiDGView1.ColumnCount = 4                                                'con cuatro columnas

        _MiDGView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill     'Ajustarlo al tamaño

        _MiDGView1.Columns(0).HeaderText = "Caso A"                               'Etiquetar columna

        Me.Controls.Add(_MiDGView1)                                               'Añadirlo al form

        '

        'Construir el segundo DGV

        _MiDGView2.Dock = DockStyle.Right

        _MiDGView2.ColumnCount = 4

        _MiDGView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill

        _MiDGView2.Columns(0).HeaderText = "Caso B"

        Me.Controls.Add(_MiDGView2)

        '

        'La ventana (aspecto)

        Me.Width = Me._MiDGView1.Width + Me._MiDGView2.Width + 25           'Ajustar el ancho del form

        Me.Text = "Pep/Rafa DataGridView"                                    'Ponerle titulo

    End Sub

End Class

'

' Nuestra personalizacion para MiDGView —————————————————————

'

Public Class MiDGView

    Inherits DataGridView       'Heredar del DataGridView

    '

    'Prepocesar mensajes

    Public Overrides Function PreProcessMessage(ByRef msg As System.Windows.Forms.Message) As Boolean

        If msg.Msg = 257 And msg.WParam.ToInt32 = 13 Then                    'Si es 'KeyDown' y 'Enter'

            Dim MiCol As Integer = 0

            Dim MiFil As Integer = Me.CurrentCell.RowIndex – 1

            If Me.CurrentCell.ColumnIndex < Me.ColumnCount – 1 Then          'Si noSalimos del limite

                MiCol = Me.CurrentCell.ColumnIndex + 1                       'Siguiente columna

            End If

            If MiFil > -1 Then Me.CurrentCell = Me(MiCol, MiFil) 'Posicionar columna

        End If

        Return MyBase.PreProcessMessage(msg)

    End Function

End Class

'

' Nuestra personalizacion para DGVPlus —————————————————————

'

Public Class DgvPlus

    Inherits DataGridView   'Heredar del DataGridView

    '

    'en el 'processDialogKey'… cuando estamos en edicion

    Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean

        If keyData = Keys.Enter Then                'Si es 'enter'

            SendKeys.Send(Chr(Keys.Tab))            'Enviar un 'Tab'

            Return True                             'Marcar como procesado

        Else                                        'en caso contrario

            Return MyBase.ProcessDialogKey(keyData) 'devolver KeyData

        End If

    End Function

    '

    ' en 'OnKeyDown'… cuando no estamos en edicion

    Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)

        If e.KeyData = Keys.Enter Then              'Si es 'enter'

            SendKeys.Send(Chr(Keys.Tab))            'Enviar un 'Tab'

        Else

            MyBase.OnKeyDown(e)                     'Devolver el KeyEventArgs

        End If

    End Sub

End Class