jueves, 31 de enero de 2013

[Matlab] -> Compilar programa

Para compilar un programa y crear ejecutable en Matlab sigue los siguientes pasos:


  1. Instala en el ordenador cliente el MCR de Matlab. (puedes bajarlo aquí).
  2. Ejecuta el comando>>mbuild -setup

    y selecciona el compilador: LCC-win32 ...
  3. ejecuta el comando:
    >>deploytool

    Se abrirá el asistente en el cual debes seleccionar el archivo de código .m principal y después los anexos (si es que tu programa principal llama a otros ficheros .m creados por ti, o a alguna figura).
    Después pulsa compilar y se creará en la carpeta del proyecto el archivo .exe que debes distribuir.

[Matlab] -> Simular doevents Visual Basic

Cuando compilas los programas realizados en Matlab y se está ejecutando un bucle puede ser que el GUI te quede como "colgado". Para resolver esto (en Visual Basic usamos la función Application.DoEvents) puedes intercalar la función drawnow para que se vuelva a repintar el GUI.

miércoles, 16 de enero de 2013

[Matlab] -> GUI Capturar valor de textbox

Para capturar el valor de un textbox creado en Editor de GUI de Matlab usar el siguiente comando:

numero = str2double(get(handles.txtNumero,'String'));

donde:
- txtNumero:  es el valor de la propiedad 'Tag' que se le asignó al textbox en el Inspector de Propiedades.

Con esto almacenamos en la variable 'numero' el número introducido en el textbox 'txtNumero'

martes, 22 de marzo de 2011

[Microsoft Visual .NET] -> Manejar registro de windows

Con estas sencillas 2 funciones declaradas en un módulo podrás manejar las claves del registro de windows que uses para tu aplicación.

Por defecto las claves trabajan en el nivel de Usuario, en subcarpeta con el nombre de tu aplicación.

Para grabar una clave en el registro usa el procedimiento:
Public Sub grabarClave(ByVal nombre as String, ByVal valor as String)
 Try 
   My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\" & appTitle,nombre,valor)
 catch ex as Exception
  msgbox ex.message
 End Try
End Sub


La variable appTitle se declara al principio del módulo como:
Public appTitle as String = My.Application.Info.ProductName

y para leer clave del registro la siguiente función:
Public Function leerClave(ByVal nombre as String) as String
 Dim valor as String="NULL"
 Try
  valor=My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Software\" & appTitle,nombre,"NULL")
 if valor Is Nothing The valor="NULL"
 Return valor
 catch ex as Exception
  msgbox ex.message
  Return "NULL"
 End Try
End Function
 
 

jueves, 17 de marzo de 2011

[MySQL] --> Compactar y optimizar Base de datos

Igual que el post anterior crearemos un fichero bat, según el mismo procedimiento comentado.

Escribiremos lo siguiente:

@echo off
mysqlcheck -u miuser -p mipassword mibd -c
mysqlcheck -u miuser -p mipassword mibd-o
pause

Donde sustituimos miuser por el nombre de usuario, mipassword por la contraseña y mibd por el nombre de la base de datos.
De esta forma compactamos la base de datos y regeneramos los índices.

miércoles, 16 de marzo de 2011

[MySQL] --> Realizar copia de seguridad

A continuación explicaré como realizar un programa MSDOS para realizar copia de seguridad de nuestra base de datos MySQL utilizando el programa mysqldump que viene con la instalación de MySQL.

Para ello crearemos un nuevo fichero de texto con el  bloc de notas y escribiremos las siguientes líneas de texto:

@echo off
mysqldump --user=miusuario --password=mipassword --opt mibd > cseg.sql
echo Copia realizada correctamente
pause

En la cual sustituiremos miusuario por el nombre de usuario con el que hayamos creado la bd y mipassword por nuestra contraseña. mibd es el nombre de nuestra base de datos.

Ahora le daremos a Archivo->Guardar como  y de  nombre por ejemplo Realizar copia.bat (es importante que la extensión sea bat) verificando que en el combo Tipo de archivo esté seleccionado: Todos los archivos.

Este bat lo guardamos en la carpeta bin de la instalación de MySQL (generalmente: C:\Archivos de Programa\MySql\bin").

Al ejecutarlo se generará en el mismo directorio bin un fichero de extensión sql con la copia de seguridad de nuestra base de datos que posteriormente podremos importar.

martes, 15 de marzo de 2011

[Visual Net] --> Capturar video webcam para PictureBox

Alguna vez hemos necesitado capturar una imagen, para por ejemplo asignarla a un cliente en un programa de facturación, o bien para un programa TPV para asignarla a un determinado artículo y después posteriormente cargarla en un listView.

Para esto creamos un nuevo módulo que llamaremos por ejemplo: modWebCam

En la primera línea del módulo importamos la siguiente librería: Imports System.Runtime.InteropServices

Dentro del módulo declaramos las siguients constantes:
    Const WM_CAP_START = &H400S
    Const WS_CHILD = &H40000000
    Const WS_VISIBLE = &H10000000

    Const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10
    Const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11
    Const WM_CAP_EDIT_COPY = WM_CAP_START + 30
    Const WM_CAP_SEQUENCE = WM_CAP_START + 62
    Const WM_CAP_FILE_SAVEAS = WM_CAP_START + 23

    Const WM_CAP_SET_SCALE = WM_CAP_START + 53
    Const WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52
    Const WM_CAP_SET_PREVIEW = WM_CAP_START + 50

    Const SWP_NOMOVE = &H2S
    Const SWP_NOSIZE = 1
    Const SWP_NOZORDER = &H4S
    Const HWND_BOTTOM = 1


Declaramos una serie de funciones de la API de Windows:


Declaramos función que nos da la versión y la descripción del driver
 Declare Function capGetDriverDescriptionA Lib "avicap32.dll" _
       (ByVal wDriverIndex As Short, _
        ByVal lpszName As String, ByVal cbName As Integer, ByVal lpszVer As String, _
        ByVal cbVer As Integer) As Boolean

Declaramos función que crea captura de ventana
Declare Function capCreateCaptureWindowA Lib "avicap32.dll" _
       (ByVal lpszWindowName As String, ByVal dwStyle As Integer, _
        ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, _
        ByVal nHeight As Short, ByVal hWnd As Integer, _
        ByVal nID As Integer) As Integer

Declaramos función que envía mensaje a ventana
Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
       (ByVal hwnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, _
       ByVal lParam As Object) As Integer

Función que ajusta la posición de la ventana en relación al buffer de la pantalla
Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" _
       (ByVal hwnd As Integer, _
        ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal y As Integer, _
        ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer) As Integer

Función para destruir la ventana especificada
Declare Function DestroyWindow Lib "user32" (ByVal hndw As Integer) As Boolean

Creamos nuestra funciones personalizadas
Función que captura la imagen y nos devuelve un objeto Image que podemos asociar a un Picture Box por ejemplo

Public Function CapturaImagen() As Image

        Dim data As IDataObject
        Dim bmap As Image

        Try
            '---copiamos la imagen
            SendMessage(hWnd, WM_CAP_EDIT_COPY, 0, 0)

            '---capturamos la imagen del portapapeles
            data = Clipboard.GetDataObject()
            If data.GetDataPresent(GetType(System.Drawing.Bitmap)) Then
                bmap = _
                   CType(data.GetData(GetType(System.Drawing.Bitmap)),  _
                   Image)
                StopPreviewWindow()
                Return bmap
            Else
                Throw New Exception("Error intentando capturar imagen")
            End If
        Catch ex As Exception
            err("modWebCam/CapturaImagen", ex.Message)
        End Try
    End Function

Función para desconectar la entrada de Video:
 Private Sub StopPreviewWindow()
        SendMessage(hWnd, WM_CAP_DRIVER_DISCONNECT, VideoSource, 0)
        DestroyWindow(hWnd)
    End Sub

Previsualización de la entrada de video:
Private Sub PreviewVideo(ByVal pbCtrl As PictureBox)
        hWnd = capCreateCaptureWindowA(VideoSource, WS_VISIBLE Or WS_CHILD, 0, 0, 0, _
            0, pbCtrl.Handle.ToInt32, 0)

        If SendMessage(hWnd, WM_CAP_DRIVER_CONNECT, VideoSource, 0) Then
            '---set the preview scale---
            SendMessage(hWnd, WM_CAP_SET_SCALE, True, 0)
            '---set the preview rate (ms)---
            SendMessage(hWnd, WM_CAP_SET_PREVIEWRATE, 30, 0)
            '---start previewing the image---
            SendMessage(hWnd, WM_CAP_SET_PREVIEW, True, 0)
            '---resize window to fit in PictureBox control---
            SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, _
               pbCtrl.Width, pbCtrl.Height, _
               SWP_NOMOVE Or SWP_NOZORDER)
        Else
            '--error connecting to video source---
            DestroyWindow(hWnd)
        End If
    End Sub

Ejemplo de uso donde llamamos a la función PreviewVideo para previsualizar la imagen de la cam en un picturebox (pcbFoto) que se encuentra en formulario (frmWebCam)

Public Sub IniciaCam()
        Try

            VideoSource = 0
            StopPreviewWindow()
            PreviewVideo(frmWebCam.pcbFoto)
            frmWebCam.ShowDialog()
        Catch ex As Exception
            err("modGeneral/IniciaCam", ex.Message)
        End Try
    End Sub

miércoles, 2 de marzo de 2011

[Visual Net] --> Ejecutar transacciones en base de datos

Cuando enviamos órdenes a una base de datos mediante el objeto Connection estas se ejecutan secuencialmente. Algunas veces cuando el usuario realiza alguna acción necesitamos grabar cambios en varias tablas, y nos debemos asegurar de que si se produce algún error los cambios se deshagan en todas las tablas. Para esto se usan las transacciones.

Durante una transacción se ejecutan varias órdenes a una base de datos (inserciones, modificaciones o eliminaciones) y cuando se realiza la ejecución de la transacción (Commit) se intentan ejecutar todas, si alguna da algún fallo no se ejecuta ninguna y se vuelve al estado inicial (Rollback).

En el siguiente código vemos un ejemplo de actualización de 2 tablas mediante una conexión ODBC:


Using bd as New System.Data.Odbc.OdbcConnection(cnn)
   Dim cmd as New Odbc.OdcCommand
   Dim transaction as Odbc.OdbcTransaction
   Try
    bd.Open
    transaction=bd.BeginTransaction   ' aquí comienza la transacción
    cmd.Connection=bd       ' asigno la conexión al comando
    cmd.Transaction=transaction           ' asigno la transacción al comando
    sql = "INSERT INTO tblUsers(nombre,apellidos) VALUES ('Pepe','Gonzalez')
    cmd.CommandText=sql          ' asigno la sentencia sql
    cmd.ExecuteNonQuery()
    ' ejecuto 2ª sentencia
    sql="INSERT INTO tblPassword(nombre,passw) VALUES ('Pepe','1234')
    cmd.CommandText=sql
    cmd.ExecuteNonQuery()

    ' ejecuto la transacción
    transaction.Commit()
  catch ex as Exception
   Try
      transaction.Rollback
   End Try
  End Try
End Using

lunes, 13 de diciembre de 2010

[Visual Basic / Visual .NET] --> Controlar ventana de otra aplicación

Algunas veces necesitamos controlar ventana de otra aplicación que tenemos abierta, como por ejemplo realizar clic con el ratón o pulsar una combinación de teclas para realizar alguna acción.

Para realizar este, mediante código, desde nuestra aplicación usaremos lo siguiente:

  1. Función Win32 para encontrar la aplicación y asociarle un puntero.
  2. Función Win32 para activarla y establecer el foco para enviarle la combinación de teclas.
  3. Envío de la combinación de teclas.
1.- Encontrar la aplicación
Para realizar esto usamos la función disponible en la librería "USER32.dll" que se muestra el código a continuación:
Declare Auto Function Lib "USER32.DLL" ( _
  ByVal lpClassName As String, _
  ByVal lpWindowName as String) As IntPtr

Como observamos esta función busca la ventana en función del nombre (texto que aparece en el barra de tareas de windows) y nos devuelve un puntero (dirección de memoria) a dicha ventana.

2.- Activar la ventana
Para enviar la pulsación de teclas y que estas surgan efecto es necesario establecer el foco en esta ventana, para ello usaremos la siguiente función:
Declare Auto Function SetForegroundWindow Lib "USER32.DLL" ( _
  ByVal hWnd as IntPtr) as Boolean

A esta función es necesario pasarle como parámetro el puntero de la ventana obtenido con la función anterior.

3.- Envío de las pulsaciones
Para el envío de las pulsaciones usaremos la función "SendKeys". Como ejemplo abriremos la calculadora y le enviaremos una combinación de teclas para realizar la operación: 120*5

Dim wndCalculadora as IntPtr = FindWindow(Nothing,"Calculadora")
If wndCalculadora=IntPtr.Zero Then
   Throw New Exception("Debes abrir la calculadora")
End If
SetForegroundWindow(wndCalculadora)
SendKeys.SendWait("120")
SendKeys.SendWait("*")
SendKeys.SendWait("5")
SendKeys.SendWait("=")

miércoles, 21 de abril de 2010

[Base datos MySQL] -> Problema con consultas consecutivas: ERROR [HY000] [MySQL][ODBC 3.51 Driver]Can't connect to MySQL server on 'localhost' (10048)

Este error suele ocurrir cuando se realizan gran cantidad de consultas consecutivas a la base de datos en un intervalo corto de tiempo.

La presentación de este error puede variar según el software utilizado, este ejemplo corresponde al generador generado tras conectarse a BBDD MySQL a través de ODBC con Microsoft Visual Studio .NET.

Otros síntomas:
  • La aplicación ha podido conectarse anteriormente a la base de datos sin problemas.
  • Tras esperar un cierto tiempo (por ejemplo 1 minuto o 2) la aplicación puede volver a conectarse a la BBDD.
  • El error parece manifestarse tras condiciones de gran exigencia, cuando el número de conexiones abiertas y cerradas en un corto espacio de tiempo son altas.
 Causa
El error no es causado por MySQL o el controlador ODBC de MySQL, sino por el comportamiento de Windows. Por motivos de rendimiento, Windows mantiene una conexión en un puerto TCP después de que este sea cerrado (por defecto) 4 minutos. La ventaja de esto es que si la conexión tiene que volver a abrirse se puede realizar a un costo menor. El problema es que bajo una carga pesada, cuando un gran número de conexiones se abren y se cierran, el sistema puede alcanzar el número máximo de conexiones permitidas (a pesar que en la aplicación las conexiones se hayan cerrado).

Solución

1. Para reducir la demora antes de que Windows lance una conexión TCP abierta, edite la siguiente entrada en el Registro de Windows:
 HKEY_Local_Machine\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay

Este valor no existe por defecto y tendrá que ser creado. Debe ser de tipo DWORD. El rango válido es de 0x1E - 0x12C (30 segundos a 300 segundos), el valor predeterminado es de 0xF0 (240 segundos). 

La disminución de este valor debe ayudar, pero no puede resolver definitivamente el problema para un sistema ocupado (porque si el sistema está ocupado los límites también se verán afectados). 
 
2. Considere si es posible modificar la aplicación para que la conexión se re-utilice en lugar de cerrar y abrirla sucesivamente.

En teoría la agrupación de conexiones también podría resolver este problema. http://support.microsoft.com/default.aspx?scid=kb; EN-US; q169470