May 142022
 

Este proyecto lo había comenzado un par de años atrás luego lo abandoné, así que me decidí a retomarlo, si tendría que comenzarlo de cero hoy cambiaria muchas cosas ya que no son las más óptimas, pero esto no impide que el calendario funcione bien.

Ahora bien el control se trata de un calendario al cual podemos añadir eventos, esto puede servir para muchas cosas como ser mostrar vacaciones de personal, eventos de cobro, turnos, actividades de tiempo o mostrar de manera gráfica intervalos de fecha.

El control tiene soporte para hacer drag & drop de los eventos, tal como poder modificar con el mouse su rango de fecha, si presionamos la tecla Ctrl y hacemos drag & drop duplica este evento.

Luego la parte de entrada de datos queda a cargo del programador, en los ejemplos agregué unos formularios de muestra, lo que no hice fue crear una series de eventos, pero es posible si se tiene un poco de paciencia, cualquier duda sobre esto último puedo dar una guía de cómo hacerlo.

Dentro de los ejemplos en la carpeta «Advance» encontrarán un ejemplo enlazando el calendario a una base de datos de SQLite, deberán agregar a la referencia a la dll J3cnn.dll

Los eventos del calendario no se manejan por índice sino por keys esto porque internamente éstos son ordenados por fecha y de esta forma se pierde el índice (esto no gustó mucho cómo lo encaré de un principio).

El control no tiene ninguna dependencia, inclusive los iconos son pintados con líneas.

La rueda del scrollbar funciona correctamente cuanto está compilado, esto lo hice así ya que no utilicé Safe subclass, para evitarme dolores de cabeza al programar lo deje así, compilado funciona correctamente lo mismo para el evento MouseLeave. Si a alguien le es necesario que funcione en el ide puede quitar el «If App.LogMode Then».

Para ir cerrando sé que hay muchas cosas que quedaron pendientes, me gustaría que comenten si habría que implementar algo o corregir, también si ven algún error; así de esa manera me es más fácil. En los primeros días de subida seguramente lo esté actualizando frecuentemente a medida que me informen o encuentren detalles.

ucCalendar_Month.png
ucCalendar_Week.png
ucCalendar_Day.png
ucCalendar_Year.png

A continuación un detalle rápido de sus funciones y propiedades:

AddEvents: Función principal para agregar eventos al calendario, parámetros requerido; sujeto (titulo descriptivo), fecha y hora de inicio, fecha y hora de finalización y color del evento, el resto de los parámetros son opcionales, valor de retorno una key del evento.
CenterCalenarInNow: Mueve el scroll a la hora actual.
Clear: Elimina todo los eventos.
DateValue: Asigna o retorna la fecha actual del calendario.
DayHaveEvents: Retorna True/False si hay eventos en un día especifico.
DropDownColor: Cuando hay muchos eventos en un día y en el modo de vista Mes hay más de los que se pueden mostrar, se muestra una barra desplegable la cual podemos cambiar el color con esta propiedad.
EventsCount: Cantidad de eventos agregados.
EventsRoundCorner: Propiedad booleana para mostrar o no esquinas redondeadas en eventos y botones.
FirstDayOfWeek: Aquí podemos asignar que día queremos que se muestre como primer día de la semana, por defecto usa el del sistema.
GetAllEvents: Obtiene una colección de las keys de los eventos agregados.
GetEventData: Obtiene los datos de un evento, su primer parámetro es la key del evento la cual podemos obtenerla con GetAllEvents o por algún evento, el resto de los parámetros son valores de retorno.
GetEventsFromDay: Retorna una colección de keys de los eventos de un día en especifico,
GetSelectionRangeDate: Función para obtener el rango de fechas seleccionada.
HeaderColor: Color de la cabecera y parte de la temática.
HiddeEvent: Oculta el evento, útil para filtrar.
LinesColor: Color de las líneas.
Redraw: Habilita o deshabilita el repintando del calendario, esto sirve para acelerar la carga de eventos.
RemoveEvent: Elimina un evento.
Refresh: Refresca el repintado calendario.
SelectedEvent: Retorna el evento seleccionado.
SelectionColor: Color de la selección.
SetStrLanguage: Aqui podemos pasar la traducción de las palabras utilizadas.
ShowToolTipEvents: Si se quiere mostrar o no la ventana tooltip, esta se puede remplazar por otra personalizada y con informacion más detallada. Véase los eventos EventMouseEnter y EventMouseLeave.
Update: Es más completo que refresh, este vuelve a reordenar por fecha y alfabéticamente los evento, recalcula la posición y por último repinta todo.
UpdateEventData: Función para actualizar los datos de un evento. Debe pasarse la key del evento que queremos modificar.
UserCanChangeDate: Habilita o deshabilita para que el usuario pueda cambiar la pagina actual del calendario.
UserCanChangeEvents: Habilita o deshabilita si el usuario puede cambiar los eventos (mediante estiramiento o arrastre).
UserCanChangeViewMode: Oculta todos los botones en la parte superior de la parte derecha. De esta forma el usuario no puede cambiar el modo de vista o bien el programador toma el control de que vista quiere mostrar.
UserCanScrollMonth: En el modo de vista mes, se puede scrollear infinitamente si necesidad de cambiar de página, esto sólo si se habilita esta opcion.
ViewMode: Cambia por código en el modo de vista (Dia, Semana, Mes, Año)

Eventos:

DateBackColor: Al dispararse este evento podemos elegir según la fecha u hora el color de fondo de la celda, así como también su HatchStyle.
DateChange: Cuando el usuario cambia de página el calendario se dispara este evento.
DragNewEvent: Cuando el usuario tiene la presionada la tecla Control y hace drag & drop el evento se duplica, o sea un nuevo evento es agregado por el usuario, con este evento somos informados y así podremos guardar en la base de datos o como se lo esté manejando.
DropDownViewMore: Evento cuando se presiona el botón de ver más, este botón se encuentra en la vista «Meses», aparece cuando hay muchos eventos en un día y no entran en la celda, al presionar este cambiará a modo de vista = «Día», esto podemos cancelarlo y mostrar una ventana personalizada con los eventos del día, los eventos del día los podemos recuperar con GetEventsFromDay.
EventChangeDate: Este evento se dispara cuando el usuario hace drag & drop o cambia el tamaño del evento con el mouse. es útil para almacenar en la base de datos las nuevas fechas.
EventMouseEnter: Cuando el mouse entra sobre un evento.
EventMouseLeave: Cuando el mouse sale por encima del evento.
EventClick: Click en un evento.
PreDateChange: Antes de que el usuario pagine hacia otra fecha, aquí podemos cancelarlo.
PreEventChangeDate: Antes que el usuario cambie los datos de un evento con del drag & drop o el mouse, este evento es muy útil para impedir arrastrar eventos en ciertas fechas u horas en los que no queremos que se agregue un evento.


Actualización 16/05/2022:

  • En el ejemplo con SQLite se corrigió los tipos de campos de la base de datos
  • se almacenaron las variables booleanas como 1 y 0 para no tener conflictos en idiomas no español.
  • En los campos fechas se convirtió a formato Unix para que el ejemplo corra bien con cualquier configuración regional.

Actualización 13/05/2024:

  • Se añadió la propiedad StartCalendar para indicar el horario de comienzo del calendarito.
  • Se añadió la propiedad EndCalendar para indicar el horario de finalización del calendarito.
  • Se añadió la propiedad CalendarInterval para indicar las divisiones del calendario, por ejemplo cada 10, 15, 20 o 30 minutos, en este punto utilizar intervalos que la suma den 60 minutos

Un usuario @SearchingDataOnly de vbForum sugirió esta versión de RC6 para SQLite si alguien le interesa puede descargarlo aquí (primer post)

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
Dic 152015
 

Clásico juego de Ping Pong, sencillo, con la opción de jugar solo o con dos jugadores, en la hoja de Ayuda encontraran con que teclas deslizarse, también recuerden que pueden utilizar el zoom para ajustar a sus monitores, o también poner en pantalla completa.
Aclaro para todos estos juegos programados en vba y Excel se debe tener las Macros habilitadas.
PingPong.png

Mar 072013
 

Con la aparición de los nuevos móviles es más frecuente ver imágenes que contienen las coordenadas GPS de donde se tomaron las fotos, esto es aprovechado por algunas redes sociales para sugerir la ubicación de la captura. Si lo desean pueden fijarse desde alguna imágen tomada con el celular, si la tienen almacenada en su PC , dentro de las propiedades (en la pestaña detalles) van a ver las coordenadas, entre otros datos tales como: el tipo de cámara, fecha de captura y demás. Estos datos denominados EXIF o Metadatos, están incrustados en la imágen (como si fuera un archivo de recursos) y es común en los archivos jpg, pero esto no implica que los demás formatos no puedan contener esta información, pueden contener un tipo de archivo XMP  (con la misma estructura que un XML).

A continuación voy a poner un módulo que sirve para leer y grabar coordenadas GPS en imágenes y utiliza GDI Plus, este sólo es compatible con EXIF, no con XMP (el cual leerlo no seria el problema, sino guardarlo). El proyecto de descarga contiene un ejemplo con un mapa (google maps) en cual va interactuando con el código de VB, algo básico pero sirve para mostrar y cambiar las coordenadas.

Editado: 09/03/2013 – Se implemento un cuadro de búsqueda para facilitar, la localización en el mapa, el resultado sera el mas próximo, la función esta dentro del código de vb, pero podría hacerse dentro del webbrowser y listar todos los resultados referentes al criterio de búsqueda (para mas información buscar en la ayuda de las apis de gmaps.)

ImageGPS

Coordenadas GPS en fotos

Jul 292011
 

Módulo clase para agregar un botón en las partes no cliente del formulario (bordes), actualmente con la llegada de Windows Seven son varias las aplicaciones que utilizan este sistema. Bien, esta clase sólo intenta crear un efecto parecido, y digo intenta ya que es otro método el que utilizan, lo que hace es crear una ventana en la que aplica el API UpdateLayeredWindow, la cual transforma un mapa de bits en una máscara para la ventana, la cual tiene soporte Alpha. Las aplicaciones por ejemplo Firefox, donde hoy en día se puede ver un botón naranja sobre el área no cliente utilizan otro método (DwmExtendFrameIntoClientArea, DwmEnableBlurBehindWindow) que es el de repintar el marco de la ventana empleando la nueva Guid de Windows Seven, esta clase también se puede utilizar bajo Windows XP, para ser más exacto esta clase hace lo mismo que se vé en el Botón Inicio de Windows 7.

Detalles de sus propiedades y funciones:

  • CreateButton: Inicializa el botón, el primer parámetro debe ser el hwnd de la ventana padre, el segundo parámetro es opcional para el ToolTipText.
  • LoadImageFromFile: Lee una imagen desde archivo.
  • LoadImageFromRes: Lee una imagen desde el archivo de recurso de la aplicación.
  • LoadImageFromStream: Lee una imagen desde un array de bits.
  • Left: Devuelve o establece la ubicación izquierda del botón con respecto a su ventana padre.
  • Top: Devuelve o establece la ubicación superior del botón con respecto a su ventana padre.
  • Right: Devuelve o establece la ubicación derecha del botón con respecto a su ventana padre.
  • Bottom: Devuelve o establece la ubicación inferior del botón con respecto a su ventana padre.
  • MoveMode: Indica a la clase en qué sentido debe mover el botón cuando la ventana padre se mueva o cambie de tamaño.
  • Enabled: Devuelve o establece si el botón está o no habilitado
  • Alpha: Transparencia del botón rango de 0 a 255.
  • ToolTipText: Devuelve o establece el texto mostrado cuando el mouse se sitúa sobre el control.
  • ImageWidth: Devuelve  el ancho de la imagen cargada.
  • ImageHeight: Devuelve el alto de la imagen cargada.
  • hwnd: Devuelve el Handle del botón.
  • ButtonWidth: Devuelve el ancho del botón.
  • ButtonHeight: Devuelve el alto del botón.

Vale aclarar que el botón no tiene Caption ya que es una tira de imágenes (la imagen debe ser siempre una tira vertical) -ver el formato en el zip del ejemplo-, el orden utilizado de los estados es Normal, Hot, Presionado y Deshabilitado. El formato de la imagen es conveniente que sea .PNG para la transparencia.

Nota: La clase subclasifica las ventanas y no utilicé el método modo seguro (SafeMode) sólo para que no sea muy grande el módulo, así que ojo No presionar el Stop del IDE de VB6. Ante cualquier error seguramente se les cerrará todo el proyecto y en el peor de los casos se les reiniciara Windows. Es recomendable comentar la línea de inicialización del botón (CreateButton) hasta que se compile el proyecto.

Boton No Cliente

En el ejemplo hice una validación que si la versión de Windows es Vista o Seven que quite el icono y el Caption de la ventana utilizando el api SetWindowThemeAttribute, ahora si es Windows XP van a ver que no queda muy bien ya que debajo del botón se vé el icono y el caption, quizás estés pensando en poner un icono transparente y remover el Caption pero esto hará que no se vea en la barra de tareas.

Boton No Cliente

Abr 182009
 

Es un Proyecto WidGet que consta de un anotador o notas recordatorias. Cuenta con varias opciones, tales como: modificar el color de texto, color de fondo, tamaño, ubicación, sonido, fecha y hora de cuando se quiera mostrar.
Este proyecto está algo viejito, as que hay cosas que en la cWidget ya las hace automáticamente, pero bien no tena ganas de reformarlo, as que lo dejo como lo hice en un principio, además tiene como dependencia Microsoft Windows Common Controls.

Sample thumbnail