Jul 072021
 

UserControl multi función el cual cumple con las funcionalidades de los controles ListBox, ComboBox, Lista Desplegable, Menú y Autocomplete de un TextBox. La novedad es que adiciona varios extras y cambios estéticos, como ser bordes redondeados, sombras, ítems personalizados, soporte para imágenes Png y estándares, a las imágenes se le puede aplicar esquinas redondeadas y cambios de colores para el caso de imágenes vectoriales (PNG), grupos de ítems, barras separadora, filtro y subtexto.

Para el caso del estilo ListBox los cambios de propiedades y adición de ítem no refrescan automáticamente, es necesario llamar a Update; esto es con la intención ganar la velocidad (aunque me quedó la duda si fue lo correcto haberlo hecho así)

Quizás hay muchas cosas que me gustaría aclarar pero por el momento sólo voy a dejar unos cuantos ejemplos donde podrán aprender a emplearlo fácilmente.

ucListPlus1.png ucListPlus2.png ucListPlus3.png ucListPlus4.png ucListPlus5.png

Actualizado: 05/08/2021 (corrección en algunas fallas de la sombra en ventanas padres)

Jun 212021
 

Como su nombre en inglés lo indica clase para sombras, un módulo que nos servirá para implementar sombras a nuestro formulario y controles, esta clase fue realizada con fines para otro control que compartiré más adelante, pero decidí publicarlos por separado para que sea más fácil de entender el uso de cada uno. Como verán en la imagen, además de la sombra da una forma redondeada a los controles y formularios, esto coincide justamente con la nueva interfaz de Windows 11, pero en realidad la idea es copiar a los diseños que vemos en HTML y CSS con Bootstrap, si bien a primera vista parece lo que se hizo con el LabelPlus, esto es algo diferente y mucho más rápido para este propósito.

Técnicamente su funcionamiento se divide en dos: para ventanas hijas y ventanas padres. En el caso de las ventanas hijas crea otra ventana que copia el color de fondo de la ventana contenedora, dibuja la sombra, borde y la misma se sitúa debajo del control que queremos aplicar dicho estilo. Si tuviéramos un fondo degradado o con una imagen el efecto quedaría mal ya que esta ventana no es transparente, sólo simula serlo (si bien es posible hacerla transparente, es más costoso en memoria, por lo cual decidí dejarlo así). En el caso de las ventas padres también se crea una ventana con el estilo WS_EX_LAYERED y contiene un DIB con la imagen de la sombra, bordes y se sitúa por detrás de la ventana en cuestión. En este último caso la ventana tiene transparencia.

La función principal que inicia todo es «ShowBorders», su primer parámetro es el hwnd de la ventana a aplicar los bordes y sombras, el segundo parámetro boolean es si esta ventana es hija (control) o Padre(Formulario) .

Traté de subclasificar lo menos posible, sólo WM_PAINT en ventanas hijas y WM_MOVE en ventanas padres por lo que si se ocultara el control queda en mano del programador llamar a la función «HideBorders» para ocultar la sombra, lo mismo cuando se cambie el tamaño del control u otras, es necesario llamar a «Refresh». Mirando los ejemplos se podrá entender mejor su funcionamiento, por el momento funcionará así, más adelante de ser necesario haré algunos cambios.

ClsShadow1.png ClsShadow2.png

Actualizado: 05/08/2021 (corrección en algunas fallas de la sombra en ventanas padres)

Mar 182021
 

En este caso se trata por un lado de un Módulo clase y por otro un Usercontrol para crear una interfaz de usuario moderna llamada Neumorphism o Neomorfismo, la cual comenzó a ponerse de moda a partir del 2020, si bien está pensada para aplicaciones móviles o webs no veo motivo para no implementarlo en nuestro querido vb6, al menos en aplicaciones pequeñas para no sobrecargar mucho la memoria y ralentizar nuestra app. El motor de todo esta basado en GDI+.

Con el módulo clase hay un ejemplo donde podemos jugar con las propiedades de la clase y otro formularios con algunos ejemplos graficados.
Además este permite dibujar un Path de GDI+ con el cual se utilizó un módulo extra, donde se puede crear distintas formas (Shapes) y se les puede aplicar el estilo, aprovecho para agradecer a Eduardo por tomar parte de las rutinas de su ShapeEx.



Con el Usercontrol hay tres ejemplos aplicados. No voy a detallar todas las propiedades, es cuestión de meter mano y jugar un poco, son las mismas del módulo. Con los ejemplos esta acompañando el usercontrol «LabelPlus» que es para agregar texto e iconos a las formas, (no quise volver a programar todo esto por eso utilicé dos usercontrols).

Ya más adelante voy a subir un reproductor de música en el que estoy trabajando donde puede verse todo esto aplicado.

Por último quiero aclarar que todo esto funciona más rápido cuando está compilado..

Neumorphism1.png Neumorphism2.png Neumorphism3.png Neumorphism4.png Neumorphism5.png
Mar 012021
 

Hola en esta ocasión un poco más de lo mismo ya en el blog hay 3 artículos más referidos a menús, pero bien, esta clase se trata de armar un menú popup con apis de una forma más sencilla y con varias propiedades que vb6 no contiene, algunas de ellas son: ItemBitmap, ItemRadioCheck, ItemDefault, ItemHilite, ítems en columna (Break).

Como plus hay un módulo que sirve para leer imágenes, con un tamaño específico, esto esta pensado más que nada para soporte del DPI.

Dentro del módulo está la función llamada LoadPictureEx con la que podemos pasarle como primer parámetro:

  • Un Array de bits de la imagen
  • El path de la imagen
  • Una Url web de la imagen
  • Una url con la imagen codificada en ella «data:image/png;base64,iVBORw…»
  • Un objeto Stream (devuelto por algunas librerías de windows)
  • Un hBitmap
  • un hIcon

El segundo y tercer parámetro es el alto y ancho de la imagen. El tercero boolean si queremos que se ajuste a ese ancho o que sea proporcional. El cuarto parámetro el formato de salida vbPicTypeBitmap o vbPicTypeIcon. El quinto parámetro es un color, para esas imágenes tipo vectoriales de un solo color, con esta función podemos pintarlas a ese color (aclaro no tiene soporte para SVG). El sexto parámetro BackColor, sería por si es un png y lo queremos mostrar en un control imagen, elegimos su color de fondo.

la función retorna un iPicture o StdPicture con un Bitmap o Icono con una imagen de 32Bits de profundidad, la cual sirve para pasar a los common controls. y el menú por supuesto. también se pude utilizar con el icono del formulario con SendMenssage, el SysTray etc etc etc.

ClsApiMenu.png
Dic 192020
 

Este proyecto me lo compartió el colega J. Elihu quien fue que lo trabajo, así que les dejo como descripción su propio Readme.txt para que entiendan mejor. Se los recomiendo!

CONTENIDO:

  1. ¿Que es vbSqlite?
  2. Caracteristicas
  3. ¿Como usar?
  4. Licencia

  1. ¿Qué es vbSqlite3?

SQlite3 + VB6: vbSqlite3 es un envoltorio (ligero,entendible) que permite
integrar el motor de base de datos de SQlite con las aplicaciones de VB6
Todo estos sin generar dependencias (ODBC, ADO y DLL’s activex) y usando
las versiones actuales del MDB de SQlite3.

REQUERIMIENTOS

- Sqlite3.dll   -> MDB de Sqlite.
- cLib      -> Conectar Sqlite3.dll + VB6.
- cSqlite   -> Conexión a la base de datos.
- cSqliteCursor -> Manejador de consultas a la base de datos.

CREDITOS

- Cobein   (mSqlite.bas)
- Cocus    (cSQLiteConnection.cls)
- Cocus    (cSQLiteRecordset.cls)

  1. Caracteristicas

vbSqlite3 implementa todas las funciones requeridas para una conexión con
el motor de base de datos de SQlite, adicionalmente implementa rutinas,
propiedades y funciones que facilitan su uso y claro entendimiento.
El envoltorio permite:

- Ejecutar commandos SQL de SQlite.
- Adjuntar varias bases de datos a una conexión de SQlite.
- Copia de seguridad de la 'db' (backup).
- Eliminar los espacios en blanco de la 'db' (vacuum)
- Configurar el modo WAL de la 'db'
- Cambiar la codificación de la 'db'
- Activar/Desactivar la restrición de claves foraneas.
- Cambiar el modo de sincronización de la 'db'.
- Obtener el código y mensaje de error.
- Insertar/Actualizar datos mediante un objeto de consulta
  (cSqliteCursor) - (Sqlite_bind_*).
- Reestablecer los objetos de consulta (reset).
- Obtener los campos BLOB de una consulta.
- Adjuntar datos a una declaracion preparada (Sqlite_bind_*).
- Obtener la ID del ultmio registro insertado.
- Obtener la cantidad de registros afectados por una consulta.
- Ejecutar transacciones desde una coleccion de sentencias SQL.
- Obtener y establecer la version de usuario(UserVersion).
- Crear multiples instancias de conexión (cSqlite).
- Cargar la libreria de SQlite desde una ruta personalizada.

Las actualizaciones posteriores del envoltorio pueden incluir nuevas
características y funciones.


  1. ¿Como usar?

Se incluye la demo en el proyecto como guia de incio rápido para el uso del
envoltorio.

1 - Incluya Sqlite3.dll en la carpeta de su proyecto, o en la carpeta
    System32, o cargue la dll desde una ruta personalizada.
2 - Cree una nueva instancia de cSqlite y establezca la conexión.
3 - Llame a cSqlite.Execute para ejecutar sentencias SQL.
4 - Llame a cSqlite.Query para instanciar un nuevo objeto de consulta.
5 - Para interactuar con el objeto de consulta, segun el caso, llame a: 
    cSqliteCursor.Step
    cSqliteCursor.Value
    cSqliteCursor.BLOB
    cSqliteCursor.Bind
    cSqliteCursor.Reset
6 - Para finalizar la conexión, destruya primero la instancia del
    objeto de consulta (cSqliteCursor) y luego la instancia de la
    conexión(cSqlite).

Para Añadir/Actualizar/Remover datos mediante un objecto de declaracion
preparada debe usar la rutina: ‘cSqliteCursor.Bind’. Para mayor información
consultar la documentacion oficial: https://www.sqlite.org/docs.html


  1. Licencia

  - El envoltorio 'vbSqlite3' es gratuito.
- El envoltorio es de propiedad del autor.
- Se puede editar/cambiar/redistribuir el codigo manteniendo los
  creditos del autor.
- Se permite redistribuir el codigo fuente siempre que no se cobra
  ninguna tarifa.

J. Elihu
E-mail: elihulgst.10@gmail.com

vbsqlite3_1.jfif
vbsqlite3_2.jfif
vbsqlite3_3.jfif
Sep 102018
 

Se trata de un modulo clase que se encarga de simular una barra de titulo, lo que en realidad hace es eliminar la original y dibujar una personalizada en el área cliente (osea dentro del mismo formulario) la clase empezó un poco jugando luego fui modificando muchas cosas ,en un principio para dibujar los botones utilizaba los temas de windows (nada fácil ya que para pintar tal como se ven en la imagen había que hacer unas cuantas piruetas) luego decidí que era mas fácil utilizar métodos gráficos con GDI+ y hacerlos yo mismo, inclusive es mucho mas rápido así.

Seguramente quien vea la chorrera de código dirán para que tango lío, si sacando el borde del formulario ya esta, pero bien a mi gusto entre muchas otras cosas es preservar la sombra del formulario y otras cuestiones como que el usuario pueda cambiar el tamaño, simular a las aplicaciones que hay en el store de microsoft y etc etc.

bien las opciones del modulo es cambiar el color de la barra elegir si se quiere entre iconos y etiqueta blanca u oscura, y bien como ven en la imagen se puede agregar controles o dibujar sobre la barra, dentro del zip hay un ejemplo donde se muestra como hacerlo, las opciones son muchas es cuestión de que sepan aprovecharlas. si bien es compatible en windows XP y superiores, esta pensado para windows 10.

Actualizado 16/10/2018: ahora soporte para el escalado de DPI

CustomTitleBar.png
CustomTitleBar.png

 Posted by at 0:26
Dic 172016
 

Este código hace tiempo que había quedado pendiente en un hilo del foro por el amigo 79137913 el cual sirve para recuperar contraseñas guardadas en Windows 8 y posteriores, haciendo un breve resúmen en versiones anteriores Internet explorer (IE7) éste almacenaba sus contraseñas en el registro de windows, las cuales utilizando algunas apis de desencriptación se podían obtener todos los datos. Con la llegada de Windows 8 el sistema cambió y comenzaron a guardarlas en Windows Vault, si nos metemos desde el Administrador de credenciales podemos ver todas las contraseñas guardas con sus respectivos Usuarios y Url.

Me dió mucho trabajo poder traducir el código de C, ya que son todas apis indocumentadas y el manejo desde VB y los punteros a las estructuras es un tanto engorroso, pero tras prueba y error pude  lograr recuperar las contraseñas.

Tanto I.Explorer como Microsoft Edge guardan las contraseñas en el mismo lugar con el mismo seudónimo (Intenet Explorer) (ya sabemos que ambos son la misma cosa).

El código se puede resumir si se quiere, pero traté de mantener todas las estructuras y enumeraciones para que sea más entendible su funcionamiento o poder usar otras funcionalidades de las credenciales.

(Aclaro esto sólo sirve en Windows 8 y posteriores, si bien las credenciales estaban disponibles en Windows 7, mi  internet explorer no almacenaba sus contraseñas en vault, y si estoy equivocado es fácil corregir, sólo hay que verificar la versión de windows y cambiar la estructura según el S.O.).


Option Explicit
Private Declare Function VaultOpenVault Lib "vaultcli.dll" (ByRef VaultGuid As GUID, ByVal dwFlags As Long, ByRef VaultHandle As Long) As Long
Private Declare Function VaultCloseVault Lib "vaultcli.dll" (ByRef VaultHandle As Long) As Long
Private Declare Function VaultEnumerateItems Lib "vaultcli.dll" (ByVal VaultHandle As Long, ByVal dwFlags As Long, ByRef ItemsCount As Long, ByRef Items As Long) As Long
Private Declare Function VaultGetItem Lib "vaultcli.dll" (ByVal VaultHandle As Long, pSchemaId As GUID, ByVal pResource As Long, ByVal pIdentity As Long, ByVal pPackageSid As Long, ByVal hwndOwner As Long, ByVal dwFlags As Long, ppItem As Long) As Long
Private Declare Function VaultFree Lib "vaultcli.dll" (ByVal ppItem As Long) As Long

Private Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As GUID) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long


Private Enum VAULT_SCHEMA_ELEMENT_ID
 ElementId_Illegal = 0
 ElementId_Resource = 1
 ElementId_Identity = 2
 ElementId_Authenticator = 3
 ElementId_Tag = 4
 ElementId_PackageSid = 5
 ElementId_AppStart = &H64
 ElementId_AppEnd = &H2710
End Enum
 
Private Enum VAULT_ELEMENT_TYPE
 ElementType_Boolean = 0
 ElementType_Short = 1
 ElementType_UnsignedShort = 2
 ElementType_Integer = 3
 ElementType_UnsignedInteger = 4
 ElementType_Double = 5
 ElementType_Guid = 6
 ElementType_String = 7
 ElementType_ByteArray = 8
 ElementType_TimeStamp = 9
 ElementType_ProtectedArray = 10
 ElementType_Attribute = 11
 ElementType_Sid = 12
 ElementType_Last = 13
 ElementType_Undefined = -1
End Enum

Private Type FILETIME
 dwLowDateTime As Long
 dwHighDateTime As Long
End Type

Private Type VAULT_VARIANT
 veType As VAULT_ELEMENT_TYPE
 Unknown As Long
 lpString As Long
End Type
 
Private Type VAULT_ITEM_ELEMENT
 SchemaElementId As VAULT_SCHEMA_ELEMENT_ID
 Unknown As Long
 ItemValue As VAULT_VARIANT
End Type
 
Private Type GUID
 Data1 As Long
 Data2 As Integer
 Data3 As Integer
 Data4(0 To 7) As Byte
End Type
 
Private Type VAULT_ITEM_W8
 SchemaId As GUID
 pszCredentialFriendlyName As Long
 pResourceElement As Long ' VAULT_ITEM_ELEMENT
 pIdentityElement As Long ' VAULT_ITEM_ELEMENT
 pAuthenticatorElement As Long ' VAULT_ITEM_ELEMENT
 pPackageSid As Long ' VAULT_ITEM_ELEMENT
 LastModified As FILETIME
 dwFlags As Long
 dwPropertiesCount As Long
 pPropertyElements As Long ' VAULT_ITEM_ELEMENT
End Type

Private Type VAULT_ITEM_W7
 SchemaId As GUID
 pszCredentialFriendlyName As Long
 pResourceElement As Long ' VAULT_ITEM_ELEMENT
 pIdentityElement As Long ' VAULT_ITEM_ELEMENT
 pAuthenticatorElement As Long ' VAULT_ITEM_ELEMENT
 LastModified As FILETIME
 dwFlags As Long
 dwPropertiesCount As Long
 pPropertyElements As Long ' VAULT_ITEM_ELEMENT
End Type

Const WEB_CREDENTIALS As String = "{4BF4C442-9B8A-41A0-B380-DD4A704DDB28}"
Const VAULT_ENUMERATE_ALL_ITEMS = 512
 
Public Function GetVaultCredentials() As String
 Dim tGUID As GUID
 Dim hVault As Long
 Dim ItemsCount As Long, i As Long
 Dim Items As Long
 Dim VI_W8() As VAULT_ITEM_W8
 Dim dwError As Long
 Dim ppCredentials As Long 'VAULT_ITEM_W8
 Dim tVIE As VAULT_ITEM_ELEMENT
 Dim sResult As String
 Dim tItemVault As VAULT_ITEM_W8
 
 CLSIDFromString StrPtr(WEB_CREDENTIALS), tGUID
 
 If VaultOpenVault(tGUID, 0, hVault) <> 0 Then Exit Function
 
 Call VaultEnumerateItems(hVault, 0, ItemsCount, Items)
 ReDim VI_W8(ItemsCount - 1)
 CopyMemory VI_W8(0), ByVal Items, Len(VI_W8(0)) * ItemsCount
 
 For i = 0 To ItemsCount - 1
 If VI_W8(i).dwPropertiesCount <> 0 Then
 
 dwError = VaultGetItem(hVault, VI_W8(i).SchemaId, VI_W8(i).pResourceElement, VI_W8(i).pIdentityElement, 0&, 0&, 0&, ppCredentials)

 If dwError = 0 Then
 sResult = sResult & "Account: " & PtrToString(VI_W8(i).pszCredentialFriendlyName)
 
 CopyMemory tVIE, ByVal VI_W8(i).pResourceElement, Len(tVIE)
 
 sResult = sResult & " URL: " & PtrToString(tVIE.ItemValue.lpString)
 
 CopyMemory tVIE, ByVal VI_W8(i).pIdentityElement, Len(tVIE)
 
 sResult = sResult & " User: " & PtrToString(tVIE.ItemValue.lpString)

 CopyMemory tItemVault, ByVal ppCredentials, Len(tItemVault)
 CopyMemory tVIE, ByVal tItemVault.pAuthenticatorElement, Len(tVIE)
 
 sResult = sResult & " Pass: " & PtrToString(tVIE.ItemValue.lpString) & vbCrLf
 
 VaultFree (ppCredentials)
 ppCredentials = 0
 End If
 End If
 Next

 VaultCloseVault (hVault)
 
 GetVaultCredentials = sResult
End Function
 
Private Function PtrToString(lpwString As Long) As String
 Dim Buffer() As Byte
 Dim nLen As Long
 If lpwString Then
 nLen = lstrlenW(lpwString) * 2
 If nLen Then
 ReDim Buffer(0 To (nLen - 1)) As Byte
 CopyMemory Buffer(0), ByVal lpwString, nLen
 PtrToString = Buffer
 End If
 End If
End Function

Private Sub Form_Load()
 Text1.Text = GetVaultCredentials
End Sub