Jul 262009
 

Siguiendo con el tema de los íconos, este es un Control de Usuario al estilo ImageCombo, utiliza el ComboBoxEx32 del sistema y la ventaja que tenemos es no tener que incluir el Common Control 6.0 OCX ya que éste lo crea vía Api de Windows, me di cuenta tarde pero este control ya había sido diseñado en Visual Basic así que para muchos no va a ser ninguna novedad, incluí como ejemplo una forma de crear una lista desplegable al estilo explorador de Windows (imágen 2).

ComboBoxEx

 

Jul 232009
 

Esta es una función que sirve para pintar una imágen de forma ampliada pero manteniendo su contorno original, para que se entienda, cuando utilizamos PaintPicture o StretchBlt en una imágen, ésta se estira proporcionalmente y en un caso como éste (imágen) el borde del botón se deformaría, en esta función debe pasarse un parámetro en el cual debe indicarse un ancho/alto en común para los bordes.

RenderStrecht

Option Explicit

' -------------------------------------------------
' Autor: Leandro Ascierto
' Web:   www.leandroascierto.com.ar
' -------------------------------------------------

Private Declare Function StretchBlt Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Private Declare Function SetStretchBltMode Lib "gdi32.dll" (ByVal hdc As Long, ByVal nStretchMode As Long) As Long
Private Declare Function BitBlt Lib "gdi32.dll" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
Private Declare Function GdiTransparentBlt Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal crTransparent As Long) As Boolean
Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal hObject As Long) As Long
  
Private Function RenderStretchFromDC(ByVal DestDC As Long, _
                                ByVal DestX As Long, _
                                ByVal DestY As Long, _
                                ByVal DestW As Long, _
                                ByVal DestH As Long, _
                                ByVal SrcDC As Long, _
                                ByVal x As Long, _
                                ByVal y As Long, _
                                ByVal Width As Long, _
                                ByVal Height As Long, _
                                ByVal Size As Long, _
                                Optional MaskColor As Long = -1)
 
Dim Sx2 As Long
 
Sx2 = Size * 2
 
If MaskColor <> -1 Then
    Dim mDC         As Long
    Dim mX          As Long
    Dim mY          As Long
    Dim DC          As Long
    Dim hBmp        As Long
    Dim hOldBmp     As Long
 
    mDC = DestDC
    DC = GetDC(0)
    DestDC = CreateCompatibleDC(0)
    hBmp = CreateCompatibleBitmap(DC, DestW, DestH)
    hOldBmp = SelectObject(DestDC, hBmp) ' save the original BMP for later reselection
    mX = DestX: mY = DestY
    DestX = 0: DestY = 0
End If
 
SetStretchBltMode DestDC, vbPaletteModeNone
 
BitBlt DestDC, DestX, DestY, Size, Size, SrcDC, x, y, vbSrcCopy  'TOP_LEFT
StretchBlt DestDC, DestX + Size, DestY, DestW - Sx2, Size, SrcDC, x + Size, y, Width - Sx2, Size, vbSrcCopy 'TOP_CENTER
BitBlt DestDC, DestX + DestW - Size, DestY, Size, Size, SrcDC, x + Width - Size, y, vbSrcCopy 'TOP_RIGHT
StretchBlt DestDC, DestX, DestY + Size, Size, DestH - Sx2, SrcDC, x, y + Size, Size, Height - Sx2, vbSrcCopy 'MID_LEFT
StretchBlt DestDC, DestX + Size, DestY + Size, DestW - Sx2, DestH - Sx2, SrcDC, x + Size, y + Size, Width - Sx2, Height - Sx2, vbSrcCopy 'MID_CENTER
StretchBlt DestDC, DestX + DestW - Size, DestY + Size, Size, DestH - Sx2, SrcDC, x + Width - Size, y + Size, Size, Height - Sx2, vbSrcCopy 'MID_RIGHT
BitBlt DestDC, DestX, DestY + DestH - Size, Size, Size, SrcDC, x, y + Height - Size, vbSrcCopy 'BOTTOM_LEFT
StretchBlt DestDC, DestX + Size, DestY + DestH - Size, DestW - Sx2, Size, SrcDC, x + Size, y + Height - Size, Width - Sx2, Size, vbSrcCopy   'BOTTOM_CENTER
BitBlt DestDC, DestX + DestW - Size, DestY + DestH - Size, Size, Size, SrcDC, x + Width - Size, y + Height - Size, vbSrcCopy 'BOTTOM_RIGHT

If MaskColor <> -1 Then
    GdiTransparentBlt mDC, mX, mY, DestW, DestH, DestDC, 0, 0, DestW, DestH, MaskColor
    SelectObject DestDC, hOldBmp
    DeleteObject hBmp
    DeleteDC DC
    DeleteDC DestDC
End If
 
End Function 
 
Private Function RenderStretchFromPicture(ByVal DestDC As Long, _
                                ByVal DestX As Long, _
                                ByVal DestY As Long, _
                                ByVal DestW As Long, _
                                ByVal DestH As Long, _
                                ByVal SrcPicture As StdPicture, _
                                ByVal x As Long, _
                                ByVal y As Long, _
                                ByVal Width As Long, _
                                ByVal Height As Long, _
                                ByVal Size As Long, _
                                Optional MaskColor As Long = -1)
 
    Dim DC          As Long
    Dim hOldBmp     As Long
 
    DC = CreateCompatibleDC(0)
    hOldBmp = SelectObject(DC, SrcPicture.Handle)
 
    RenderStretchFromDC DestDC, DestX, DestY, DestW, DestH, DC, x, y, Width, Height, Size, MaskColor 

    hOldBmp = SelectObject(DC, hOldBmp)
    DeleteDC DC

End Function

Jul 192009
 

Este es un Control de Usuario realizado por Vlad Vissoultchev allá por el año 2002. Este UCR originalmente tiene dos estilos diferentes, el de Windows XP y el utilizado hoy en día por Visual Basic.net, yo me tomé el atrevimiento de agregarle dos estilos nuevos, el de Windows Vista, el Estilo Menú Ribbon y también que los estilos se apliquen a la barra de menú. El UCR no tiene muchas propiedades disponibles pero cuenta con la opción de agregarle iconos al menú de una forma muy sencilla, quizás lo más incómodo sea la cantidad de módulos que utiliza (cuatro módulos clase, un módulo .bas, un archivo.tlb, una página de propiedades, más el control de usuario). El que quiere puede convertirlo en un OCX.

HookMenu

 Publicado por a las 16:39  Tagged with:
Jul 142009
 

Este es un Control de Usuario de un ListBox con algunas cualidades extras, tales como poder insertar íconos, personalizar la selección o personalizar el borde, también permite optar entre un método de deslizamiento automático a través de dos botones en su parte superior e inferior o el clásico ScrollBar. El ícono puede alinearse tanto a la izquierda del texto como en la parte superior, diría que es especial para crear un menú lateral, acepta íconos de 32 bits, aclaro sólo íconos, no bitmaps. Además tiene casi todas las opciones y eventos que los demás controles poseen,  me gustaría que si alguien encuentra algún error o desea agregarle alguna otra propiedad utilice el sistema de comentarios.

ListBoxEx
ListBoxEx2

 

Jul 102009
 

Este es un módulo para trabajar con los Socket de Windows, vendría a ser un reemplazo del WinSock.ocx, en este me he basado en el módulo de KPD-Team y lo reformé a mi gusto. Su uso creo, es muy sencillo y práctico, especialmente a la hora de trabajar con múltiples conexiones, si lo utilizan tal vez puedan encontrarse con algunas diferencias con respecto a la forma convencional de trabajo de como se utiliza con el WinSock.ocx.
A continuación voy a dejar dos ejemplos de uso, en el cual expliqué detalladamente, para su fácil entendimiento:
El primero trata de una conexión Cliente-Servidor de tipo Chat donde el Servidor puede escuchar en distintos puertos a la vez y aceptar varias conexiones al mismo tiempo, para la parte Cliente también puede realizar más de una conexión y en diferentes puertos a la vez.
El segundo se trata de una conexión Cliente-Servidor para Transferir Archivos.
Una cosa para resaltar, si es que lo van a usar, es que deben agregar manualmente las subrutinas comentadas en el final del módulo al formulario o módulo clase que llame a la función InitWinSock Me  del módulo WinSock32.
No lo he probado a full, pero creo que está funcionando perfectamente, cualquier inquietud, sugerencia o error pueden utilizar el sistema de comentarios.

Option Explicit

' --------------------------------------------------------------------
' Autor:     Leandro Ascierto
' WEB:       www.leandroascierto.com.ar
' Fecha:     09/07/2009
' Adaptado a mi gusto :)
' Basado en el módulo de KPD-Team  http://www.allapi.net/
'----------------------------------------------------------------------

Private Declare Function accept Lib "wsock32.dll" (ByVal s As Long, addr As SOCKADDR, addrlen As Long) As Long
Private Declare Function bind Lib "wsock32.dll" (ByVal s As Long, addr As SOCKADDR, ByVal namelen As Long) As Long
Private Declare Function closesocket Lib "wsock32.dll" (ByVal s As Long) As Long
Private Declare Function Connect Lib "wsock32.dll" Alias "connect" (ByVal s As Long, addr As SOCKADDR, ByVal namelen As Long) As Long
Private Declare Function htonl Lib "wsock32.dll" (ByVal hostlong As Long) As Long
Private Declare Function htons Lib "wsock32.dll" (ByVal hostshort As Long) As Integer
Private Declare Function inet_ntoa Lib "wsock32.dll" (ByVal inn As Long) As Long
Private Declare Function Listen Lib "wsock32.dll" Alias "listen" (ByVal s As Long, ByVal backlog As Long) As Long
Private Declare Function recv Lib "wsock32.dll" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal Flags As Long) As Long
Private Declare Function Send Lib "wsock32.dll" Alias "send" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal Flags As Long) As Long
Private Declare Function Socket Lib "wsock32.dll" Alias "socket" (ByVal af As Long, ByVal s_type As Long, ByVal protocol As Long) As Long
Private Declare Function gethostbyname Lib "wsock32.dll" (ByVal host_name As String) As Long
Private Declare Function gethostname Lib "wsock32.dll" (ByVal host_name As String, ByVal namelen As Long) As Long
Private Declare Function WSAStartup Lib "wsock32.dll" (ByVal wVR As Long, lpWSAD As WSADataType) As Long
Private Declare Function WSACleanup Lib "wsock32.dll" () As Long
Private Declare Function WSAIsBlocking Lib "wsock32.dll" () As Long
Private Declare Function WSACancelBlockingCall Lib "wsock32.dll" () As Long
Private Declare Function inet_addr Lib "wsock32.dll" (ByVal cp As String) As Long
Private Declare Function WSAAsyncSelect Lib "wsock32.dll" (ByVal s As Long, ByVal hWnd As Long, ByVal wMsg As Long, ByVal lEvent As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
Private Declare Function DestroyWindow Lib "user32.dll" (ByVal hWnd As Long) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Any) As Long
Private Declare Function GetTickCount Lib "kernel32.dll" () As Long
Private Declare Sub CopyMemoryIP Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)
Private Declare Sub MemCopy Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal cb As Long)
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)

Private Type WSADataType
    wVersion As Integer
    wHighVersion As Integer
    szDescription As String * 257
    szSystemStatus As String * 129
    iMaxSockets As Integer
    iMaxUdpDg As Integer
    lpVendorInfo As Long
End Type

Private Type HostEnt
    hName As Long
    hAliases As Long
    hAddrType As Integer
    hLen As Integer
    hAddrList As Long
End Type

Private Type SOCKADDR
    sin_family As Integer
    sin_port As Integer
    sin_addr As Long
    sin_zero As String * 8
End Type

Private Const WINSOCK_MESSAGE As Long = 1025
Private Const INADDR_NONE As Long = &HFFFF
Private Const INADDR_ANY As Long = &H0
Private Const IPPROTO_TCP As Long = 6
Private Const INVALID_SOCKET As Long = -1
Private Const SOCKET_ERROR As Long = -1
Private Const SOCK_STREAM As Long = 1
Private Const AF_INET As Long = 2
Private Const PF_INET As Long = 2
Private Const FD_READ As Long = &H1&
Private Const FD_WRITE As Long = &H2&
Private Const FD_OOB As Long = &H4&
Private Const FD_ACCEPT As Long = &H8&
Private Const FD_CONNECT As Long = &H10&
Private Const FD_CLOSE As Long = &H20&
Private Const GWL_WNDPROC As Long = (-4)

Private PrevProc As Long
Private bIsInit As Boolean
Private hWin As Long
Private m_ObjectHost As Object
Private TimeOut As Long

Public PortOpen  As Collection       ' Colección de los puertos abiertos, tiene como key el ID/Sesión de los puertos Abiertos.
Public PortSesion As Collection      ' Colección de los ID/Sesión de los puertos Abiertos.

Public Sockets As Collection         ' Colección de el ID/Sesión de las Conexiones establecidas.
Public IPAddresses As Collection     ' Colección de las IP de las Conexiones establecidas, tiene como key el ID/Sesión.
Public PortConection As Collection   ' Colección de los Puertos de las Conexiones establecidas, tiene como key el ID/Sesión.

Public CurrentSocketHandle As Long   ' ID de la última sesión activa.

' Esta función inicializa los Socket, debe hallarse al comienzo, y ObjectHost es el formulario o módulo clase que recibirá los Eventos/Mensajes
' En ese formulario o módulo clase deberán ir las líneas comentadas que se encuentran al final de este módulo.

Public Function InitWinSock(ObjectHost As Object) As Boolean
    Dim StartupData As WSADataType
    Set Sockets = New Collection
    Set IPAddresses = New Collection
    Set PortOpen = New Collection
    Set PortSesion = New Collection
    Set PortConection = New Collection

    Set m_ObjectHost = ObjectHost

    If Not bIsInit Then
        If Not WSAStartup(&H101, StartupData) Then
            bIsInit = True
            hWin = CreateWindowEx(0&, "STATIC", "SOCKET_WINDOW", 0&, 0&, 0&, 0&, 0&, 0&, 0&, App.hInstance, ByVal 0&)
            PrevProc = SetWindowLong(hWin, GWL_WNDPROC, AddressOf WindowProc)
        Else
            bIsInit = False
        End If
    End If

    InitWinSock = bIsInit

End Function

' Esta función es importante llamarla cuando se descarga el formulario, nunca cerrar el Visual Basic desde el Stop
' Sino no se ejecutara esta rutina, el IDE de Visual Basic se cerrará automáticamente dando lugar a no guardar los cambios.

Public Sub TerminateWinSock()

    Dim Ret As Long
    Dim Cnt As Long

    For Cnt = 1 To Sockets.Count
        WsClose Sockets.Item(1)
    Next

    For Cnt = 1 To PortSesion.Count
        closesocket PortSesion.Item(1)
        PortSesion.Remove (1)
        PortOpen.Remove (1)
    Next

    If WSAIsBlocking Then WSACancelBlockingCall

    Call WSACleanup

    bIsInit = False
    SetWindowLong hWin, GWL_WNDPROC, PrevProc
    DestroyWindow hWin

    Set Sockets = Nothing
    Set IPAddresses = Nothing
    Set PortConection = Nothing
    Set PortSesion = Nothing
    Set PortOpen = Nothing

End Sub

' Función para conectar, Host es la ip o el dsn a que se quiera conectar, y port el puerto.
' Si conecta la función retorna el ID de la sesión del Socket, de lo contrario 0.

Public Function WsConnect(ByVal Host As String, ByVal Port As Long) As Long

    Dim s As Long
    Dim Sockin As SOCKADDR

    Sockin.sin_family = AF_INET
    Sockin.sin_port = htons(Port)

    If Sockin.sin_port = INVALID_SOCKET Then Exit Function

    Sockin.sin_addr = GetHostByNameAlias(Host$)

    If Sockin.sin_addr = INADDR_NONE Then Exit Function

    s = Socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
    If s < 0 Then Exit Function

    If Connect(s, Sockin, 16) <> 0 Then
        If s Then closesocket s
        Exit Function
    End If

    If WSAAsyncSelect(s, hWin, ByVal WINSOCK_MESSAGE, ByVal FD_READ Or FD_WRITE Or FD_CONNECT Or FD_CLOSE) Then
        closesocket s
    Else
        IPAddresses.Add GetAscIp(Sockin.sin_addr), CStr(s)
        Sockets.Add s, CStr(s)
        PortConection.Add Port, CStr(s)
        CurrentSocketHandle = s
        WsConnect = s
    End If

End Function

' Función para poner a la escucha en determinado puerto.
' Si no ocurre ningún error y el puerto está disponible, la función retorna el ID de la sesión del Socket, de lo contrario 0.

Public Function WsListenInPort(ByVal Port As Long) As Long

    Dim s As Long
    Dim Sockin As SOCKADDR

    Sockin.sin_family = AF_INET
    Sockin.sin_port = htons(Port)

    If Sockin.sin_port = INVALID_SOCKET Then Exit Function

    Sockin.sin_addr = htonl(INADDR_ANY)

    If Sockin.sin_addr = INADDR_NONE Then Exit Function

    s = Socket(PF_INET, SOCK_STREAM, 0)
    If s < 0 Then Exit Function     If bind(s, Sockin, 16) Then         closesocket s         Exit Function     End If     If WSAAsyncSelect(s, hWin, ByVal WINSOCK_MESSAGE, ByVal FD_READ Or FD_WRITE Or FD_CLOSE Or FD_ACCEPT) Then         closesocket s         Exit Function     End If     If Listen(s, 1) Then         closesocket s     Else         WsListenInPort = s         PortOpen.Add Port, CStr(s)         PortSesion.Add s, CStr(s)     End If End Function ' Esta función Cierra un puerto previamente abierto, si se afirma ForceCloseConection, cerrará todas las conexiones establecidas en ese puerto ' de lo contrario, las conexiones que ya estaban establecidas permanecen y pueden seguir enviando mensajes, pero no se podrá hacer una nueva conexión a ese puerto ' si todo sale bien la funcion retorna True. Public Function WsClosePort(ByVal Port As Long, Optional ForceCloseConection As Boolean) As Boolean     On Error GoTo ErrOut     Dim s As Long     Dim Cnt As Long     For Cnt = 1 To PortOpen.Count         If PortOpen(Cnt) = Port Then             s = PortSesion(Cnt)             Exit For         End If     Next     If s = 0 Then Exit Function     closesocket s     PortSesion.Remove CStr(s)     PortOpen.Remove CStr(s)     If ForceCloseConection Then         For Cnt = Sockets.Count To 1 Step -1             If PortConection(Cnt) = Port Then                 WsClose Sockets(Cnt)             End If         Next     End If     WsClosePort = True     Exit Function ErrOut:     WsClosePort = False End Function ' Esta función envía datos al servidor, el primer parámetro es el ID de la sesión, la cual la podemos obtener de Sockets(index) ' o con CurrentSocketHandle que es el último ID de sesión activa. ' El segundo parámetro la data a enviar. ' Si el mensaje se envió con éxito la función devuelve True Public Function SendData(Socket As Long, Data As Variant) As Boolean     Dim Ret As Long     Dim TheMsg() As Byte, sTemp$     TheMsg = ""     Select Case VarType(Data)         Case 8209   'byte array             sTemp = Data             TheMsg = sTemp         Case 8      'String             sTemp = StrConv(Data, vbFromUnicode)         Case Else             sTemp = CStr(Data)             sTemp = StrConv(Data, vbFromUnicode)     End Select     TheMsg = sTemp     If UBound(TheMsg) > -1 Then
        Ret = Send(Socket, TheMsg(0), (UBound(TheMsg) - LBound(TheMsg) + 1), 0)

        If Ret = SOCKET_ERROR Then
            TimeOut = GetTickCount + 5000
            Do While Ret = SOCKET_ERROR
                Ret = Send(Socket, TheMsg(0), (UBound(TheMsg) - LBound(TheMsg) + 1), 0)
                DoEvents
                Sleep 10
                If TimeOut < GetTickCount Then Exit Do
            Loop
        End If
        SendData = Ret <> SOCKET_ERROR
    End If

End Function

' Esta función cierra la conexión indicada mediante el ID de sesión que se pase como parámetro
' el ID lo obtenemos de Sockets(index) o con CurrentSocketHandle que es el último ID de sesión activa.
' si todo sale bien la función retorna True.

Public Function WsClose(ByVal s As Long) As Boolean
On Local Error Resume Next
    WsClose = closesocket(s)
    IPAddresses.Remove CStr(s)
    Sockets.Remove CStr(s)
    PortConection.Remove CStr(s)
End Function

' Función que retorna la IP Local.
Public Function GetLocalIp() As String

    Dim sHostName As String * 256
    Dim lpHost As Long
    Dim Host As HostEnt
    Dim dwIPAddr As Long
    Dim tmpIPAddr() As Byte
    Dim i As Integer
    Dim sIPAddr As String

    lpHost = gethostbyname(sHostName)

    CopyMemoryIP Host, lpHost, Len(Host)
    CopyMemoryIP dwIPAddr, Host.hAddrList, 4
    ReDim tmpIPAddr(1 To Host.hLen)
    CopyMemoryIP tmpIPAddr(1), dwIPAddr, Host.hLen
    For i = 1 To Host.hLen
        sIPAddr = sIPAddr & tmpIPAddr(i) & "."
    Next
    GetLocalIp = Mid$(sIPAddr, 1, Len(sIPAddr) - 1)

End Function

' Función que retorna el Nombre de Host Local.

Public Function LocalHostName() As String
    Dim sHostName As String * 256
    If gethostname(sHostName, 256) <> INVALID_SOCKET Then
        LocalHostName = Trim$(sHostName)
    End If
End Function

' Función Privada del módulo.
Private Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

On Local Error Resume Next

    If uMsg = WINSOCK_MESSAGE Then

        Dim mIP As String
        Dim mPuerto As String

        CurrentSocketHandle = wParam

        Select Case lParam

            Case FD_ACCEPT
                Dim s As Long, tempAddr As SOCKADDR
                s = accept(wParam, tempAddr, Len(tempAddr))

                mIP = GetAscIp(tempAddr.sin_addr)
                mPuerto = PortOpen(CStr(wParam))

                IPAddresses.Add mIP, CStr(s)
                Sockets.Add s, CStr(s)
                PortConection.Add mPuerto, CStr(s)

                Call m_ObjectHost.Socket_Conect(s, mIP, mPuerto)

            Case FD_CONNECT
                'Debug.Print "FD_CONNECT"

            Case FD_WRITE
                'Debug.Print "FD_WRITE"

            Case FD_READ
                Dim sTemp As String, lRet As Long, szBuf As String

                Do
                    szBuf = String(1024, 0)
                    lRet = recv(wParam, ByVal szBuf, Len(szBuf), 0)
                    If lRet > 0 Then sTemp = sTemp + Left$(szBuf, lRet)
                Loop Until lRet  0 Then
                    mIP = IPAddresses(CStr(wParam))
                    mPuerto = PortConection(CStr(wParam))
                    Call m_ObjectHost.Socket_DataArrival(wParam, mIP, mPuerto, sTemp)
                End If

            Case Else 'FD_CLOSE
                mPuerto = PortConection(CStr(wParam))
                mIP = IPAddresses(CStr(wParam))
                WsClose wParam
                Call m_ObjectHost.Socket_Close(wParam, mIP, mPuerto)

        End Select

    Else
        WindowProc = CallWindowProc(PrevProc, hWnd, uMsg, wParam, lParam)
    End If

End Function

' Función Privada del módulo.
Private Function GetHostByNameAlias(ByVal HostName As String) As Long

    On Error Resume Next
    Err.Clear

    Dim heDestHost As HostEnt
    Dim addrList As Long
    Dim retIP As Long
    Dim phe As Long

    retIP = inet_addr(HostName)

    If retIP = INADDR_NONE Then
        phe = gethostbyname(HostName)
        If phe <> 0 Then
            MemCopy heDestHost, ByVal phe, 16
            MemCopy addrList, ByVal heDestHost.hAddrList, 4
            MemCopy retIP, ByVal addrList, heDestHost.hLen
        Else
            retIP = INADDR_NONE
        End If
    End If

    GetHostByNameAlias = retIP

    If Err Then GetHostByNameAlias = INADDR_NONE
End Function

'Funcion Privada del módulo
Private Function GetAscIp(ByVal inn As Long) As String
    On Error Resume Next
    Dim lpStr&
    Dim nStr&
    Dim retString$

    retString = String(32, 0)

    lpStr = inet_ntoa(inn)
    If lpStr = 0 Then
        GetAscIp = "255.255.255.255"
        Exit Function
    End If
    nStr = lstrlen(lpStr)
    If nStr > 32 Then nStr = 32
    MemCopy ByVal retString, ByVal lpStr, nStr
    retString = Left(retString, nStr)
    GetAscIp = retString
    If Err Then GetAscIp = "255.255.255.255"
End Function

'*=====================ATENCION=====ATENCION======ATENCION=======================*
'*===============================================================================*
'*===============================================================================*
'ESTAS LINEAS DEBEN IR EN EL FORMULARIO O MODULO CLASE DONDE RECIBIRAN LOS EVENTOS
'*===============================================================================*
'*===============================================================================*
'_________________________________________________________________________________________________

'Public Sub Socket_Conect(ID As Long, IP As String, Puerto As String)
'End Sub
'_________________________________________________________________________________________________

'Public Sub Socket_DataArrival(ID As Long, IP As String, Puerto As String, Data As String)
'End Sub
'_________________________________________________________________________________________________

'Public Sub Socket_Close(ID As Long, IP As String, Puerto As String)
'End Sub
'_________________________________________________________________________________________________

Ejemplo: Cliente – Servidor (Chat)
Webcam

Ejemplo: Cliente – Servidor (Transferencia de archivos)
Webcam

 Publicado por a las 22:05  Tagged with:
Jun 232009
 

Este es un módulo clase para utilizar el traductor de google, el cual trabaja con la API AJAX de idiomas para traducción y detección, para mas información sobre esta api puedes consultar aquí.
Cuenta con cuarenta y un lenguajes, y una función para auto-detectar el idioma, el módulo es más lento que las traducciones de la página de google ya que por lo que pude interpretar en la guía de ayuda, sólo trabaja con métodos GET y ésta sólo se limita a un máximo de 2000 caracteres por consulta, entonces si el texto a traducir es mayor a esta cantidad el módulo enviará más de una petición para traducir todo el texto, quizás algunos se preguntarán por qué no obtener el texto directamente de la web de google, y la respuesta es que la web con el tiempo puede cambiar su contenido HTML, dando como resultado un módulo obsoleto.
Otra cosa a tener en cuenta es la traducción a idiomas que utilicen una codificación de caracteres especiales como el «chino» que no se mostrará correctamente en un TextBox.
Su uso es muy sencillo y lo pueden ver en el siguiente ejemplo.

Google Traductor

 Publicado por a las 21:50  Tagged with:
Jun 092009
 

Esta es la segunda versión de este proyecto, en esta versión se corrigen muchas fallas, y se optimiza mucho mas todo el código y su ejecución. lo nuevo es la implementación de dscwpmsg.dll para hacer un hook a la barra de tareas, ahora también se puede obtener una vista previa de las ventanas agrupadas en un mismo botón. Las vistas previas toman la región original de la ventana y la ajustan al tamaño de las mismas. Se dejó el ToolTip original de la barra de tareas, el uso de la api PrintWindow para obtener las capturas. En caso de que el Explorer se cierre por algún error la aplicación se reinicia siguiendo su ejecución normal.
Cuando ejecuten el proyecto no lo detengan desde el Stop de Visual Basic, ya que tiene cuatro AddressOf en ejecución, para detenerlo háganlo desde el menú que se despliega con el icono que se encuentra junto a la hora de barra de tareas.
Las vistas previas las ira generando a medida que vayamos pasando el mouse por encima de cada botón de la barra, si al ejecutar por primera vez el proyecto y la ventana está minimizada, esta será capturada sólo cuando haya tomado el foco.

Task Preview

Jun 022009
 

Este es un control de usuario, el cual sirve para mostrar una gráfica compuesta por tres estados. Este tipo de control puede servir para mostrar la gráfica del volumen de audio donde el color rojo nos indica que comienza a saturarse, también puede utilizarse para mostrar el espacio disponible de un disco rígido o pen drive, es cuestión de utilizar la imaginación para qué les podría servir, las zonas rojas y amarillas son totalmente configurables, y maneja una medida de 0 a 100 (Propiedad Value).

Sample thumbnail

May 272009
 

Este es un Proyecto WidGet que nos permitirá utilizar cuatro escritorios a la vez, es una utilidad para aquellos que les gusta tener muchas ventanas abiertas al mismo tiempo, bien con esta aplicación podrán organizarse mejor ya que se podrá ocultar y mostrar las ventanas que deseen para cada escritorio.
Este proyecto utiliza una DLL no ActiveX la cual está embebida dentro de un archivo de recurso, es la encargada de provocar un hook para detectar cuando se hace Click en los menús de las ventanas externas, gran parte de este proyecto se lo debo a Cobein, autor de muchos módulos clases que utiliza este proyecto.

Nota: Si ejecutan el proyecto desde el IDE de Visual Basic no detengan la aplicación desde el Stop, den Click al icono que aparece junto a la hora de la barra de tareas y seleccionen la opción «Cerrar».

Sample thumbnail

May 102009
 

Esta es una Api que sirve para dibujar texto con una sombra difuminada al estilo Windows Vista, en el siguiente ejemplo he creado una pequeña función a modo de simplificarla un poco, pero esto depende del uso que se le quiera dar.
Lo malo de esta Api es que requiere que esté inicializada comctl32.dll, es decir, que tendremos que llamar a InitCommonControls y tener el archivo .manifest para que funcione, por lo tanto desde el IDE si no se tiene aplicado los temas de Windows en el VB6.EXE no se mostrará el dibujo del texto y además nos dará un error al llamar a esta Api, el cual lo podremos controlar con On Error, pero bien al compilarlo y teniendo el .manifest funcionará perfectamente.

Draw Shadow Text


Option Explicit

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Declare Function OffsetRect Lib "user32" (lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function DrawText Lib "user32.dll" Alias "DrawTextA" (ByVal hdc As Long, ByVal lpStr As String, ByVal nCount As Long, ByRef lpRect As RECT, ByVal wFormat As Long) As Long
Private Declare Function DrawShadowText Lib "comctl32.dll" (ByVal hdc As Long, ByVal lpStr As Long, ByVal nCount As Long, lpRect As RECT, ByVal dwFlags As Long, ByVal crText As Long, ByVal crShadow As Long, ByVal ixOffset As Long, ByVal iyOffset As Long) As Long
Private Declare Function TranslateColor Lib "olepro32.dll" Alias "OleTranslateColor" (ByVal clr As OLE_COLOR, ByVal palet As Long, col As Long) As Long
Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
Private Const DT_CALCRECT As Long = &H400

Public Function DrawTextShadow (DestDC As Long, Text As String, ByVal x As Long, ByVal y As Long, TextColor As OLE_COLOR, ShadowColor As OLE_COLOR, Optional OffsetX As Long = 1, Optional OffsetY As Long = 1) As Boolean

    On Error Resume Next     	'Si no incluye el archivo .manifest el api DrawShadowText provoca un error

    Dim Color1 As Long
    Dim Color2 As Long
    Dim Rec As RECT

    TranslateColor TextColor, 0, Color1
    TranslateColor ShadowColor, 0, Color2

    DrawText DestDC, Text, Len(Text), Rec, DT_CALCRECT
    OffsetRect Rec, x, y

    If Color1 = 0 Then Color1 = 1
    ' El quinto parámetro es la alineación, en este caso 0 = izquierda, 1 centrado, 2 derecha
    DrawTextShadow = DrawShadowText(DestDC, StrPtr(Text), Len(Text), Rec, 0, Color1, Color2, OffsetX, OffsetY)
    ' Esta función podría ser modificada en caso de el api DrawShadowText diera error, podría ser suplementada con DrawText

End Function

Private Sub Form_Initialize()
    InitCommonControls
End Sub

Private Sub Form_Load()

    Me.AutoRedraw = True
    Me.Font.Size = 8

    If DrawTextShadow(Me.hdc, "Hola Mundo", 10, 10, vbBlack, vbRed) = False Then
        MsgBox "Para probar este ejemplo debe compilar este proyecto y agregar un archivo Proyecto1.exe.manifest", vbInformation
    End If

    Me.Font.Size = 12
    DrawTextShadow Me.hdc, "Hola Mundo", 10, 30, vbBlue, vbRed
    Me.Font.Size = 32
    Me.Font.Name = "Times New Roman"
    DrawTextShadow Me.hdc, "Hola Mundo", 10, 50, vbGreen, vbMagenta
    DrawTextShadow Me.hdc, "Hola Mundo", 10, 90, Me.BackColor, vbBlue
    Me.FontBold = True
    DrawTextShadow Me.hdc, "Hola" & vbCrLf & "Mundo", 10, 130, vbWhite, vbBlack, 3, 3
End Sub

Private Sub Timer1_Timer()
    Picture1.Cls
    DrawTextShadow Picture1.hdc, Now, 5, 0, &H333333, &H80000005
End Sub

 Publicado por a las 23:51
May 082009
 

Ejemplo:

A continuación se encuentra un ejemplo sencillo que les enseñará cómo aplicar dichos Skins a un formulario, además se mostrarán las propiedades y funciones con las que cuenta.
Nota: Es aconsejable implementarlo cuando estemos por compilar y no cuando estemos construyendo algún proyecto ya que de haber algún error este podría provocar el cierre de Visual Basic y no nos permitirá guardar los cambios de nuestro proyecto.

Option Explicit

' Declaramos cSkin como la clase ClsSkinner.
 Dim cSkin As ClsSkinner

Private Sub Form_Load()

' Creamos e inicializamos a cSkin
 Set cSkin = New ClsSkinner

' Esto es si queremos que el área del cliente se pinte con el tema del skin.
 ' Ojo!! esto hará que los controles Labels, Image, Shapes y Line que estén directamente sobre el formuario no se muestren.
 ' En el caso que no querramos que esto pase lo dejamos = False.
 cSkin.PaintClientArea = True

' Indicamos el path donde debe leer el archivo.Skin
 cSkin.LoadSkinFromFile App.Path & "\Comander.Skin"

' Si quisiéramos leer el Skin desde un archivo de recursos llamamos a la función. LoadSkinFromResource
 ' Donde 101 es el index y "SKIN" es la sección.
 cSkin.LoadSkinFromResource 101, "SKIN"

' Aplicamos el Skin a nuestro Formulario.
 cSkin.HookForm Me.hwnd

End Sub

Private Sub Form_Unload(Cancel As Integer)

' Detenemos la Sublcasificación.
 cSkin.UnHookForm Me.hwnd

' Descargamos la clase de la memoria
 Set cSkin = Nothing

End Sub

 Publicado por a las 15:57  Tagged with: