• Página 1 de 3
  • 1
  • 2
  • 3
  • »
Moderador del foro: ZorG  
Algunos momentos interesantes (y útiles)
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 1 | 5:14 PM
Barras de desplazamiento con valor siempre visible

Este es un simple módulo de clase que puede ser útil cuando necesitamos utilizar barras de desplazamiento en nuestros programas, y poder visualizar el valor actual de la barra (propiedad Value) en todo momento, y que además dicho valor se posicione y muestre junto al botón del ScrollBar.

El ejemplo está basado en este otro, pero en este caso , como se dijo, se utiliza un simple módulo de clase por dos motivos, uno para poder utilizarlo con varias barras de scroll. Ya que el ejemplo anterior, si se desea utilizar muchas, se debería agregar demasiado código en el formulario. Otro motivo, es para que al utilizarlo desde el módulo, poder añadir propiedades extra y algunos eventos para cada necesidad. Por defecto solo contiene propiedades básicas, y no difiere mucho del ejemplo anterior. Pero ya teniendo la base (es decir el módulo implementado), es mucho mas fácil poder añadir nuestra propias opciones. Por ejemplo se podría modificar para desplegar un ToolTip multilínea , en ves de el texto que visualiza el value del Scroll, por decir un caso. Aunque esto último no e intentado realizarlo, y por eso no se y tampoco tengo idea si se debería cambiar mucho el código.

Otro error importante que se corrigió, con respecto al anterior ejemplo, es que si la barra la debíamos utilizar dentro de un contenedor (Frame o PictureBox), no se podía ( a no ser modificando el código). Ahora el módulo, se encarga de obtener el objeto contenedor, y nosotros despreocuparnos si la barra está contenida dentro del form, o de un frame , o de un PicBox.

De todas formas, como se dijo, es un simple ejemplo, se puede optimizar mucho, añadir funcionalidades, corregir algunas otras que seguramente tiene, pero un poco mas funcional y fácil de utilizar que el anterior seguramente lo es, ya que solo se necesita: Añadir una ScrollBar y crear una instancia para asociarla a la barra.

Vista previa del código fuente de ejemplo.



Importante.
Para utilizar el módulo de clase, y poder utilizar las barras, se debe crear una instancia del módulo, por cada barra que se utilice. Por ejemplo, si voy a utilizar dos barras, se debería declarar en el formulario lo siguiente

Quote
' \\ -- Variables de clase para cada una de las barras
' --------------------------------------------------------------------------------
Private WithEvents mCHScrollTip1 As ClsHScrollValue
Private WithEvents mCHScrollTip2 As ClsHScrollValue

Luego, en la carga del formulario que utilice las barras, se debería (luego de instanciar las variables de módulo), ejecutar el método Init con los siguientes parámetros

Call .Init (Barra horizontal, Valor Mínimo, Valor Máximo, Valor actual)

Importante. PAra ubicar las barras en el form (es decir posicionarlas y redimensionarlas), no utilizar el método Move de cada barra, si no el método MoveHS del módulo.

Ejemplo
• Iniciar y crear un nuevo proyecto en visual basic.
• Añadir al formulario 3 barras de Scroll Horizontal (Dejarles el nombre por defecto: HScroll1, HScroll2, HScroll3)
• Añadir un módulo de clase (Cambiarle el nombre por defecto Class1 a ClsHScrollValue)
• Agregar un botón

Código fuente a pegar en el formulario

Quote
Option Explicit

' --------------------------------------------------------------------------------
' \\ -- Declaraciones
' --------------------------------------------------------------------------------
Private Declare Sub InitCommonControls Lib "comctl32" ()

' \\ -- Variables de clase para cada una de las barras
' --------------------------------------------------------------------------------
Private WithEvents mCHScrollTip1 As ClsHScrollValue
Private WithEvents mCHScrollTip2 As ClsHScrollValue
Private WithEvents mCHScrollTip3 As ClsHScrollValue

' ---------------------------------------------------------------------------------
' \\ -- Botón para restaurar valor por defecto
' ---------------------------------------------------------------------------------
Private Sub Command1_Click()
' -- Scroll 1
With mCHScrollTip1
.Value = .DefaultValue
End With
' -- Scroll 2
With mCHScrollTip2
.Value = .DefaultValue
End With
' -- Scroll 3
With mCHScrollTip3
.Value = .DefaultValue
End With
End Sub

' ---------------------------------------------------------------------------------
' \\ -- Inicio
' ---------------------------------------------------------------------------------
Private Sub Form_Initialize()
Call InitCommonControls
End Sub

Private Sub Form_Load()

' -- Crear instancia del módulo de clase para las tres barras
Set mCHScrollTip1 = New ClsHScrollValue
Set mCHScrollTip2 = New ClsHScrollValue
Set mCHScrollTip3 = New ClsHScrollValue

' -- Iniciar el módulo, pasándole la barra de desplazamiento, el formulario actual
' y si el valor se debe ocultar al perder el foco, y si se visualiza el borde del label

' -- Barra 1 ( Este oculta el texto al perder el foco)
With mCHScrollTip1
' -- Iniciar
.DefaultValue = 100
Call .Init(HScroll1, Me, -200, 200, 100, 10, 10, False, False, vbRed)
' -- Posicionar y ubicar en la ventana
Call .MoveHS(500, 200, 2000, 255)
End With
' -- Barra 2
With mCHScrollTip2
.DefaultValue = 0
Call .Init(HScroll2, Me, 0, 255, 100, 10, 10, False, False, RGB(135, 169, 250))
Call .MoveHS(500, mCHScrollTip1.Top + mCHScrollTip1.Height + 100, 2000, 255)
End With
' -- Barra 3
With mCHScrollTip3
.DefaultValue = 25000
Call .Init(HScroll3, Me, 0, 32000, 10000, 250, 250, False, False, RGB(126, 126, 126))
Call .MoveHS(500, mCHScrollTip2.Top + mCHScrollTip2.Height + 100, 2000, 255)
End With
Command1.Caption = "Restaurar valores por defecto"

End Sub
' ----------------------------------------------------------------------------------
' \\ -- Terminar instancia para eliminar los controles creados en forma dinámica
' ----------------------------------------------------------------------------------
Private Sub Form_Unload(Cancel As Integer)
Set mCHScrollTip1 = Nothing
Set mCHScrollTip2 = Nothing
Set mCHScrollTip3 = Nothing
End Sub
' ----------------------------------------------------------------------------------
' \\ -- Evento que recupera el valor al desplazar la barra ( para la barra 1)
' ----------------------------------------------------------------------------------
Private Sub mCHScrollTip1_ChangeValue(ByVal iValue As Integer)
Me.Caption = iValue
End Sub
' ----------------------------------------------------------------------------------
' \\ -- Evento que recupera el valor al desplazar la barra ( para la barra 2)
' ----------------------------------------------------------------------------------
Private Sub mCHScrollTip2_ChangeValue(ByVal iValue As Integer)
Me.Caption = iValue
End Sub
' ----------------------------------------------------------------------------------
' \\ -- Evento que recupera el valor al desplazar la barra ( para la barra 3)
' ----------------------------------------------------------------------------------
Private Sub mCHScrollTip3_ChangeValue(ByVal iValue As Integer)
Me.Caption = iValue
End Sub


Código fuente a pegar dentro del módulo de clase llamado ClsHScrollValue

Quote
Option Explicit

' -----------------------------------------------------------------------------------------------------------
' -- Descripción: Simple módulo para mostrar un tip/Text al mover una barra de desplazamiento horizontal de vb utilizando un label
' -- Autor original del ejemplo ( función pvShowValue -- Desconocido -- Creo que el ejemplo es del sitio web www.a1vbcode.com )
' -- Adaptado para usarlo en un módulo de clase para poder implementarlo con varios scroll: ( Luciano Lodola -- http://www.recursosvisualbasic.com.ar/ )
' -- Derechos : Este ejemplo no contiene limitaciones de uso:
' Se puede utilizar, modificar y distribuir sin ningún tipo de restricción.
' En caso de publicar en un sitio o utilizarlo en un programa, se agradece mensionar y mantener el nombre de los autores del mismo


' -----------------------------------------------------------------------------------------------------------

' -- Importante: Solo implementado para utilizarlo con Scrolls horizontales,
' ( Falta el código para adaptarlo con Barras verticales, y algunas propiedades y eventos básicos )
' --------------------------------------------------------------------------------

' --------------------------------------------------------------------------------
' \\ -- Declaraciones
' --------------------------------------------------------------------------------

Private Type TOpciones
lBorderStyle As Integer
HideLostFocus As Boolean
End Type

' -- Variables
Private x As Double
Private y As Double
Private WithEvents mHSBar As hScrollBar ' -- Declaración de controles
Private WithEvents mVS As VScrollBar
Private WithEvents mPicContainer As PictureBox
Private WithEvents mText As Label
Private WithEvents mOwnerForm As Form
Private mNameContainer As String ' -- Nombres para poder descargarlos
Private mNameLabel As String
Private OptionLabel As TOpciones ' -- Opciones del texto del label
Private bInitActivateFlag As Boolean
Private mDefaultValue As Integer ' -- Valor por defecto de las barras

' -- Eventos
Event ChangeValue(ByVal iValue As Integer)

' --------------------------------------------------------------------------------
' \\ -- Fin del módulo
' --------------------------------------------------------------------------------
Private Sub Class_Terminate()
'On Error Resume Next
With mOwnerForm
If Not mOwnerForm Is Nothing Then
Set mHSBar.Container = mOwnerForm
Call .Controls.Remove(mNameLabel)
Call .Controls.Remove(mNameContainer)
End If
End With
'On Error GoTo 0
End Sub
' --------------------------------------------------------------------------------
' \\ -- Inicio del módulo
' --------------------------------------------------------------------------------
Sub Init( _
hScrollBar As hScrollBar, _
OwnerForm As Form, _
MinValue As Integer, _
MaxValue As Integer, _
iValue As Integer, _
Optional iLargeChange As Integer = 1, _
Optional iSmallChange As Integer = 1, _
Optional HideLostFocus As Boolean = False, _
Optional ShowBorderStyle As Boolean = False, _
Optional lForeColorText As Long)


On Error GoTo Error_Handler

' -- Variables
Dim mParent As Object

' --- Referenciar controles para poder usarlos internemente
' dentro del módulo y también acceder a los eventos
' ( Están declarados con WithEvents )
Set mHSBar = hScrollBar
Set mOwnerForm = OwnerForm
' -- Referncia al control contenedor de las barras ( puede ser el form, un picture o un frame), _
No está implementado para mas de un contenedor, por ejemplo un Frame dentro de un picture, y las barras dentro del frame
Set mParent = mHSBar.Container
' -- Opciones del texto
With OptionLabel
.HideLostFocus = HideLostFocus
.lBorderStyle = Abs(ShowBorderStyle)
End With
Dim xNumber As Variant
Randomize (Timer)
xNumber = CInt(Rnd * 32000)
' -- Crear nombres únicos de controles ( Por si se utilizan varias instancias del módulo)
mNameLabel = "Label" & CStr(Val(xNumber))
mNameContainer = "PicContainer" & CStr(Val(xNumber))

' -- Crear controles en forma dinámica ( contenedor y label para el texto)
With mOwnerForm
Set mPicContainer = .Controls.Add("vb.PictureBox", mNameContainer)
Set mText = .Controls.Add("vb.Label", mNameLabel)
End With

' -- Setear el Scrollbar
With mHSBar
.Min = MinValue
.Max = MaxValue
.Value = iValue
.SmallChange = iSmallChange
.LargeChange = iLargeChange
Set .Container = mPicContainer
End With
' -- Setear el contenedor
With mPicContainer
.BorderStyle = 0
.Width = mHSBar.Width
.BackColor = mParent.BackColor
.Visible = True
Set .Container = mParent
End With
' -- Setear el Label
With mText
.FontName = "Verdana"
.BorderStyle = OptionLabel.lBorderStyle
.BackStyle = 0
.ForeColor = lForeColorText
.AutoSize = True
Set .Container = mPicContainer
If (OptionLabel.HideLostFocus = False) Then
.Visible = True
End If
End With

If Not mParent Is Nothing Then Set mParent = Nothing

Exit Sub
' -- Errores
Error_Handler:
MsgBox Err.Number, vbCritical, "Error en INIT"
End Sub
' -------------------------------------------------------------------------------------
' \\ -- Evento de cambio de valor de la barra de desplazamiento
' -------------------------------------------------------------------------------------
Private Sub mHSBar_Change()
Call pvShowValue
End Sub
' -------------------------------------------------------------------------------------
' \\ -- Evento cuando obtiene el foco la barra de desplazamiento
' -------------------------------------------------------------------------------------
Private Sub mHSBar_GotFocus()
With mText
.Visible = True
End With
Call mHSBar_Change
End Sub
' -------------------------------------------------------------------------------------
' \\ -- Interceptar el evento KeyDown de la barra, _
' para cambiar el valor con las teclas izquierda y derecha
' La magnitud del cambio la define el valor SmallChange pasado en la función Init de este módulo
' -------------------------------------------------------------------------------------
Private Sub mHSBar_KeyDown(KeyCode As Integer, Shift As Integer)
With mHSBar
' -- Tecla izquierda ( Disminuir valor )
Select Case KeyCode
Case vbKeyLeft
If (.Value - .SmallChange) < .Min Then
.Value = .Min
Else
.Value = .Value - .SmallChange
End If
' -- Tecla derecha ( Aumentar el valor )
Case vbKeyRight
If (.Value + .SmallChange) > .Max Then
.Value = .Max
Else
.Value = .Value + .SmallChange
End If
End Select
End With
End Sub
' -------------------------------------------------------------------------------------
' \\ -- Interceptar el evento LostFocus para ocultar el Value en caso de haber pasado
' el Valor True en el parámetro HideLostFocus de la función Init
' -------------------------------------------------------------------------------------
Private Sub mHSBar_LostFocus()
On Error GoTo Error_Handler
mText.Visible = Not (OptionLabel.HideLostFocus)
' -- Errores
Exit Sub
Error_Handler:
End Sub
' -------------------------------------------------------------------------------------
' \\ -- Actualizar label/texto en el Evento de Scroll de la barra de desplazamiento
' -------------------------------------------------------------------------------------
Private Sub mHSBar_Scroll()
Call pvShowValue
End Sub
' -------------------------------------------------------------------------------------
' \\ -- Procedimiento privado para mostrar el valor al cambiar el scroll
' -------------------------------------------------------------------------------------
Private Sub pvShowValue()
Dim k As Double
If (Not mHSBar Is Nothing) Or (Not mText Is Nothing) Then
With mText
.Caption = Trim(Str(mHSBar.Value))
k = Len(.Caption)
.Move (y + x * (mHSBar.Value - mHSBar.Min) - (k * 50) - 10), (mHSBar.Top - .Height)
' -- Lanzar evento ( es el mismo que se puede acceder desde el
' form con la propiedad Scroll/Change de la barra. Está implementado nada mas,
' por si se desea hacer alguna validación, o enviar algún parámetro extra)
RaiseEvent ChangeValue(CInt(.Caption))
End With
End If
End Sub
' -------------------------------------------------------------------------------------
' \\ -- La única forma que se me ocurrió de poder corregir el
' error de posicionar el valor al iniciar el módulo
' ya que si no no lo acutualizaba.
' -------------------------------------------------------------------------------------
Private Sub mOwnerForm_Activate()
' -- Se ejecuta una solo vez ( Actualiza la posición del
' label con respecto al botón de la barra)
If Not bInitActivateFlag Then
bInitActivateFlag = True
Call pvShowValue
End If
End Sub
' -------------------------------------------------------------------------------------
' \\ -- Redimensionar contenedor del texto
' -------------------------------------------------------------------------------------
Private Sub mPicContainer_Resize()
' -- Posicionar y redimensionar el label y la barra
With mText
.Move 0, 0, 540, 225
mHSBar.Move 0, (.Top + .Height)
End With
' -- Posicionar y redimensionar el contenedor
With mPicContainer
.Width = mHSBar.Width
.Height = mText.Height + mHSBar.Height
x = ((.Width - 600) / (mHSBar.Max - mHSBar.Min))
y = 300
End With
End Sub
' -------------------------------------------------------------------------------------
' \\ -- Método para posicionar las barras ( la posición
' izquierda, el top, el ancho y alto)
' -------------------------------------------------------------------------------------
Sub MoveHS(x As Single, y As Single, x1 As Single, Optional y1 As Single = 255)
With mPicContainer
.Left = x
.Top = y
End With
With mHSBar
.Width = x1
.Height = y1
End With
Call mPicContainer_Resize
End Sub
' ------------------------------------------------------------------------------------
' \\ -- Propiedades para definir la ubicación y dimensiones de la barra
' ------------------------------------------------------------------------------------
Property Get Width() As Single
Width = mPicContainer.Width
End Property
Property Get Height() As Single
Height = mPicContainer.Height
End Property
Property Get Top() As Single
Top = mPicContainer.Top
End Property
Property Get Left() As Single
Left = mPicContainer.Left
End Property
' -------------------------------------------------------------------------------------
' \\ -- Propiedad para recuperar el valor actual, Mínimo y máximo
' -------------------------------------------------------------------------------------
Property Get Value() As Integer
Value = CInt(mText.Caption)
End Property
Property Let Value(iValue As Integer)
mHSBar.Value = iValue
Call mHSBar_Change
End Property
' -------------------------------------------------------------------------------------
' \\ -- Propiedad para guardar un valor por defecto y luego poder restaurar
' Importante: No se comprueba que de error con los Min,Max, Value, al asignar la propiedad
' -------------------------------------------------------------------------------------
Property Get DefaultValue() As Integer
DefaultValue = mDefaultValue
End Property
Property Let DefaultValue(ByVal iValue As Integer)
mDefaultValue = iValue
If Not mHSBar Is Nothing Then
mHSBar.Value = mDefaultValue
Call pvShowValue
End If
End Property


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 2 | 5:49 PM
Mostrar el valor de la propiedad Value de un Scrollbar mientras movemos la barra

Ejemplo hecho con un picturebox y un Label para poder mostrar el valor tipo leyenda al mover el Scrollbar, es decir en el evento Change y el evento Scroll de la barra

Colocar en el formulario
• un control picturebox
• un Scrollbar Horizontal
• y un control Label

Código fuente en el Formulario

Quote
Option Explicit

Private Declare Sub InitCommonControls Lib "comctl32" ()
Private Type TOpciones
lBorderStyle As Integer
HideLostFocus As Boolean
End Type

'posición x y posición y del Label1
Dim X As Double, Y As Double
' para almacenar opciones
Private OptionLabel As TOpciones

Private Sub Form_Initialize()
Call InitCommonControls
End Sub

Private Sub HScroll1_Change()
Call MostrarLeyenda
End Sub

Private Sub HScroll1_GotFocus()
HScroll1_Change
End Sub

Private Sub HScroll1_LostFocus()
If OptionLabel.HideLostFocus Then
Label1.Visible = False
End If
End Sub

Private Sub HScroll1_Scroll()
Call MostrarLeyenda
End Sub

' muestra el valor al ejecutar el _
evento Scroll y el evento Change de la barra
''''''''''''''''''''''''''''''''''''''''''''''''''
Sub MostrarLeyenda()
Dim k As Double
With Label1
.Caption = Trim(Str(HScroll1.Value))
k = Len(Label1.Caption)
.Move (Y + X * (HScroll1.Value - HScroll1.Min) - _
(k * 50) - 10), (HScroll1.Top - Label1.Height)
.Visible = True
.AutoSize = True
End With
End Sub


Private Sub Form_Load()

' oculta la leyenda cundo la barra pierde el foco
OptionLabel.HideLostFocus = False
' estilo del label
OptionLabel.lBorderStyle = 0

'Propiedades del Scrollbar
With HScroll1
.Min = 0
.Max = 255
' coloca el HScrollbar dentro del picturebox
Set .Container = Picture1
End With
' propiedades del Picture1
With Picture1
.BorderStyle = 0
.Width = HScroll1.Width
.BackColor = &H8000000F
End With
' propiedades del Label1
With Label1
.Visible = False
.FontName = "Verdana"
.BackColor = &H80000013
.BorderStyle = OptionLabel.lBorderStyle
.BackStyle = 0
.ForeColor = vbBlack
.AutoSize = True
' coloca el Label dentro del picturebox
Set .Container = Picture1
End With

End Sub

' redimensiona los control al cambiar el tamaño del picture1
Private Sub Picture1_Resize()
Label1.Move 0, 0, 540, 225
HScroll1.Move 0, (Label1.Top + Label1.Height)
Picture1.Width = HScroll1.Width
Picture1.Height = Label1.Height + HScroll1.Height

X = ((Picture1.Width - 600) / (HScroll1.Max - HScroll1.Min))
Y = 300
End Sub


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 3 | 6:17 PM
Animar barra de progreso usando SendMessage

Código fuente de ejemplo que muestra como modificar el estilo de un control Progressbar utilizando la función del Api SetWindowLong con el estilo PBS_MARQUEE, y luego enviando el mensaje PBM_SETMARQUEE mediante la función SendMessage para que la barra de progreso muestre una animación en forma de marquesina, útil para poder mostrar un progreso de carga guando no se sabe el valor inicial y final.



Nota. Este ejemplo funciona perfectamente con los temas clásicos de windows XP : Verde oliva, el plateado y el Azul. Pero con otros temas o aplicaciones que modifican los estilos del sistema, no funciona, y la animación no se visualiza, por lo menos usando esta forma.

No funciona



He buscado bastante para poder hacerlo funcionar, y no he encontrado la forma de poder arreglar el problema, y buscando en internet, hay varias páginas en inglés que también comentan este problema.

Realmente es una lástima que no se pueda utilizar el ejemplo por este motivo, aunque se me ocurre una posible solución, que no sería la mejor, pero por lo menos es funcional, y es desactivar el tema de XP. Pero no desactivar el tema a toda la aplicación (ventana del formularios y el resto de controles), si no solo al Progressbar. Haciendo esto, la barra no tomaría el estilo, pero por lo menos se mostraría el efecto, y mantendría el tema a los demás controles.

Es decir se visualizaría de la siguiente forma:

El tema de vista que no funcionaba se vería

También funciona con el estilo clásico de windows

Otra posible solución que no he probado, es al iniciar el programa, que se compruebe si el tema actual del sistema son los default de XP. si es así, utilizarlo sin hacer la llamada a SetWindowTheme ya que funcionaria correctamente, si no, desactivar el tema al control Progressbar. (Nota, Creo que para averiguar los temas se usa la función OpenThemeData y algunas otras, pero no lo aseguro, pero hay muchas información en Internet sobre las funciones de la librería uxtheme.dll)

Ejemplo:

• Colocar una barra de progreso (la versión 5)
• Compilar el programa
• Colocar el archivo Manifest junto al exe

Código fuente

Quote
Option Explicit

' ----------------------------------------------------------------------------------
' -- Autor : Leandro Ascierto
' -- Descripción : Usar una barra de progreso animada mediante el Api de windows

' Nota : Deberás compilar el proyecto para poder probar el efecto, y tener el archivo Manifest junto al ejecutable
' ----------------------------------------------------------------------------------

Private Const GWL_EXSTYLE = (-20) ' -- mensaje que requiere GetWindowLong

Private Const WM_USER As Long = &H400
Private Const PBS_MARQUEE As Long = 8 ' -- Estilo del progressbar ( Marquesina )
Private Const PBM_SETMARQUEE = (WM_USER + 10) ' -- Mensaje - Para SendMessage

Const GWL_STYLE = (-16)

' -- Apis para tomar la apariencia de windows
Private Declare Function SetErrorMode Lib "kernel32" (ByVal wMode As Long) As Long
Private Declare Sub InitCommonControls Lib "Comctl32" ()

' -- Modificar el estilo del progressbar
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex 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

' ' Para manipular el Progressbar
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

' Para desactivar el tema de windows (Solo para el control Progress, no para todo la ventana y resto de controles)
Private Declare Function SetWindowTheme Lib "uxtheme.dll" (ByVal hwnd As Long, ByVal pszSubAppName As Long, ByVal pszSubIdList As Long) As Long


Private Sub Form_Initialize()
Call SetErrorMode(2)
Call InitCommonControls
End Sub

Private Sub Form_Load()

Dim Ret As Long
Ret = SetStyleMarquee(ProgressBar1, 50)
If Ret = False Then
MsgBox "No se pudo aplicar el estilo"
End If
End Sub


' -- Velocity : Velocidad de animación del progreso
Public Function SetStyleMarquee(ProgressBar As ProgressBar, Velocity As Long) As Boolean
With ProgressBar
Call SetWindowTheme(.hwnd, StrPtr(" "), StrPtr(" "))
SetWindowLong .hwnd, GWL_STYLE, GetWindowLong(.hwnd, GWL_STYLE) Or PBS_MARQUEE
SetStyleMarquee = SendMessageLong(.hwnd, WM_USER + 10, 1, Velocity)
End With
End Function

Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 4 | 12:20 PM
Cambiar el estilo de un control o una ventana de Windows

Ejemplo que cambia el estilo de un formulario o ventana de Windows en tiempo de ejecución


Para el mismo se utilizan las Api SetWindowLong y SetWindowPos. y lo que hace es modificar el estilo a ToolWindow o barra de herramientas. Por ejemplo: si tenemos el BorderStyle del Form de esta forma:

se cambia a este estilo:



Para el ejemplo se necesita un control CheckBox

Código fuente en el Formulario

Quote
Option Explicit


'Declaraciones del Api
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 SetWindowPos Lib "user32" (ByVal hwnd As Long, _
ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal cx As Long, ByVal cy As Long, _
ByVal wFlags As Long) As Long

'constantes
Private Const GWL_EXSTYLE = (-20)
Private Const SWP_FRAMECHANGED = &H20
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOZORDER = &H4
Private Const SWP_NOSIZE = &H1
Private Const WS_EX_TOOLWINDOW = &H80


Private Sub Check1_Click()

If Check1 Then
' establece el estilo de ventana tipo ToolWindow
SetWindowLong hwnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW
Else
' reestablece el estilo anterior
SetWindowLong hwnd, GWL_EXSTYLE, 0
End If
SetWindowPos hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED Or SWP_NOMOVE Or _
SWP_NOZORDER Or SWP_NOSIZE

End Sub

Private Sub Form_Load()
Me.Caption = " Cambiar estilo de una ventana "
Check1.Caption = " Cambiar estilo "
End Sub


________________________________________

Nota: Esta es una lista de constantes relacionadas, para pasar en el tercer parámetro de SetWindowLong y poder establecer otros estilos, como por ejemplo la Transparencia de una ventana o control, diferentes estilos de borde, establecer el caption de la ventana alineada a la derecha y algunas otras constantes.

Quote
Const WS_EX_DLGMODALFRAME = &H1
Const WS_EX_NOPARENTNOTIFY = &H4
Const WS_EX_TOPMOST = &H8
Const WS_EX_ACCEPTFILES = &H10
Const WS_EX_TRANSPARENT = &H20
Const WS_EX_MDICHILD = &H40
Const WS_EX_TOOLWINDOW = &H80
Const WS_EX_WINDOWEDGE = &H100
Const WS_EX_CLIENTEDGE = &H200
Const WS_EX_CONTEXTHELP = &H400
Const WS_EX_RIGHT = &H1000
Const WS_EX_LEFT = &H0
Const WS_EX_RTLREADING = &H2000
Const WS_EX_LTRREADING = &H0
Const WS_EX_LEFTSCROLLBAR = &H4000
Const WS_EX_RIGHTSCROLLBAR = &H0
Const WS_EX_CONTROLPARENT = &H10000
Const WS_EX_STATICEDGE = &H20000
Const WS_EX_APPWINDOW = &H40000
Const WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE + WS_EX_CLIENTEDGE
Const WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE + WS_EX_TOOLWINDOW + WS_EX_TOPMOST


Nota: los estilos se pueden aplicar también a controles que posean HWND, especificando en el primer parámetro de SetWindowLong el handle del control. Por ejemplo para alinear el Scrollbar de un Combo o control Listbox a la derecha ...por decir uno.

Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 5 | 1:02 PM
Validar direcciones url con expresiones regulares
________________________________________

I. Validar direcciones
Esta es una serie de ejemplos para poder validar direcciones url con el componente de visual basic que permite el uso de expresiones regulares.

Nota: Si se quiere utilizar en vbs, o desde vb sin incluir la referencia, se puede instanciar con Create Object de la siguiente forma:

Quote
Private Function Validate_url(sPattern As String, sData As String)

On Local Error GoTo Error_Handler

' -- Crear nuevo objeto RegExp con CreateObject
Dim objRegExp As Object
Set objRegExp = CreateObject("VBScript.RegExp")
With objRegExp
.Pattern = sPattern
.IgnoreCase = True
.Global = True
End With
Validate_url = objRegExp.Test(sData)

Exit Function

' -- Errores
Error_Handler:
End Function

Código fuente en un form con un botón (Añadir la referencia a Microsoft Visual basic Script Regular Expressions 5)

Quote
Option Explicit

' -------------------------------------------------------------------------
' -- Descripción : Ejemplo para validar una dirección url en una cadena ( Solo el dominio )
' -- Autor : Luciano Lodola -- http://www.recursosvisualbasic.com.ar/
' -- Referencias : Incluir el componente Microsoft Visual basic Script Regular Expressions 5,
' -- : o instanciarlo con CreateObject
' -- Derechos : Este código fuente no contiene restricciones de uso. Se puede utilizar, publicar y redistribuir sin ninguna restricción
' -- : En caso de publicación en un sitio o utilización en un programa se agradece mantener y hacer mensión a los autores del código.
'***************************************************************************

' --------------------------------------------------------------------------------
' \\ -- Botón para validar la dirección
' --------------------------------------------------------------------------------
Private Sub Command1_Click()

' -- Retorna verdadero -- Comienza con http// y termina con el dominio .org, com o net
MsgBox Validate_url("^http:\/\/(.*\.(net$|com$|org$))", "http://www.direccion.org")

' -- Retorna Falso -- No incluye el protocolo http:// en la dirección
MsgBox Validate_url("^http:\/\/(.*\.(com$|net$|org$))", "www.direccion.org")

' -- Retorna verdadero -- Comienza con http:// y el dominio debe ser solo .info
MsgBox Validate_url("^http:\/\/(.*\.(info$))", "http://direccion.info")

' -- Retorna verdadero -- Comienza con http://, con www, o con ambos + el dominio que debe ser solo .com
MsgBox Validate_url("^(www|http:\/\/)(.*\.(com$))", "http://www.direccion.com")

' -- Retorna Falso -- El dominio es correcto, pero comienza con un texto delante de http o www
MsgBox Validate_url("^(www|http:\/\/)(.*\.(com$))", "La dirección web es: http://google.com ")

' -- Retorna Falso -- 3 errores - 1 - Comienza con un texto delante de http o www, 2 - termina con un texto al final del dominio, 3 - el dominio es diferente a .net
MsgBox Validate_url("^(www|http:\/\/)(.*\.(net$))", "La dirección url es: http://google.com >>>")


' -- Otros ejemplos para validar direcciones url, no solo el dominio con el http, si no _
para otros protocolos además del http: https, ftp. _
Fuente : http://www.microsoft.com/spanish....ex.mspx

Dim sPattern As String
Dim sUrl As String

' -- Dirección válida - Retorna verdadero
sPattern = "^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)( [a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$"
sUrl = "https://login.yahoo.com"
MsgBox Validate_url(sPattern, sUrl)

' -- Dirección válida - Retorna verdadero
sPattern = "^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)( [a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$"
sUrl = "ftp://ftp.servidor.com"
MsgBox Validate_url(sPattern, sUrl)

End Sub
' --------------------------------------------------------------------------------
' \\ -- Inicio
' --------------------------------------------------------------------------------
Private Sub Form_Load()
Command1.Caption = "Verificar direcciones"
End Sub
' --------------------------------------------------------------------------------
' \\ -- Función para validar las direcciones - retorna Verdadero o falso
' --------------------------------------------------------------------------------
Private Function Validate_url(sPattern As String, sData As String)

On Local Error GoTo Error_Handler

' -- Crear nuevo objeto RegExp para utilizar el método Test
Dim objRegExp As New RegExp
' -- Setear el objeto y establecer el patrón
With objRegExp
' -- Establecer el patrón de búsqueda
.Pattern = sPattern
.IgnoreCase = True
.Global = True
End With
' -- Ejecutar el método Test y retornar un valor Boolean a la función
Validate_url = objRegExp.Test(sData)

Exit Function
' -- Errores
Error_Handler:
MsgBox " Número de error: " & Err.Number & vbNewLine & " Descripción del Error: " & Err.Description, vbCritical
End Function


________________________________________

II. Validar y comprobar si se pueden acceder desde Internet
Este código es similar al anterior, pero luego de validar, en caso de que la dirección es correcta, comprueba si se encuentra disponible, utilizando la función del Api InternetCheckConnection.

Agregar un botón y la referencia a RegExp

Quote
Option Explicit

' -------------------------------------------------------------------------
' -- Descripción : Ejemplo para validar una dirección url en una cadena ( Solo el dominio ) y comprobar la conexión
' -- Autor : Luciano Lodola -- http://www.recursosvisualbasic.com.ar/
' -- Referencias : Incluir el componente Microsoft Visual basic Script Regular Expressions 5,
' -- : o instanciarlo con CreateObject
' -- Derechos : Este código fuente no contiene restricciones de uso. Se puede utilizar, publicar y redistribuir sin ninguna restricción
' -- : En caso de publicación en un sitio o utilización en un programa se agradece mantener y hacer mensión a los autores del código.
' -- Créditos : Uso de InternetCheckConnection -- Fuente http://www.allapi.net/
' -- : Ejemplos de expresiones reg. -- Fuente http://www.microsoft.com/spanish....ex.mspx
'***************************************************************************


' \\ -- Declaraciones
' ---------------------------------------------------------------------------
Private Const FLAG_ICC_FORCE_CONNECTION = &H1

' \\ -- Función api InternetCheckConnection -- Fuente http://www.allapi.net/
Private Declare Function InternetCheckConnection Lib "wininet.dll" Alias "InternetCheckConnectionA" (ByVal lpszUrl As String, ByVal dwFlags As Long, ByVal dwReserved As Long) As Long

' --------------------------------------------------------------------------------
' \\ -- Botón para validar la dirección y comprobar el estado de conexión
' --------------------------------------------------------------------------------
Private Sub Command1_Click()

Dim sPattern As String
Dim sUrl As String

sPattern = "^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)( [a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$"
sUrl = InputBox("Escribir dirección url", "Ingresar una url", "http://www.google.com")
If Len(sUrl) Then
' -- Comprobar la dirección si está bien escrita
If Validate_url(sPattern, sUrl) Then
' -- Comprobar si se puede acceder
If CheckConnection(sUrl) Then
MsgBox "Se pudo acceder correctamente a la dirección: " & sUrl, vbInformation
Else
MsgBox "No se pudo acceder a la url: " & sUrl, vbCritical
End If
Else
MsgBox "La dirección url no es válida ", vbCritical
End If
End If

End Sub
' --------------------------------------------------------------------------------
' \\ -- Devuelve true si la conexión a la url se pudo realizar
' --------------------------------------------------------------------------------
Private Function CheckConnection(sUrl As String) As Boolean
CheckConnection = InternetCheckConnection(sUrl, FLAG_ICC_FORCE_CONNECTION, 0&)
End Function

' --------------------------------------------------------------------------------
' \\ -- Inicio
' --------------------------------------------------------------------------------
Private Sub Form_Load()
Command1.Caption = "Ingresar URL"
End Sub

' --------------------------------------------------------------------------------
' \\ -- Función para validar las direcciones - retorna Verdadero o falso
' --------------------------------------------------------------------------------
Private Function Validate_url(sPattern As String, sData As String)

On Local Error GoTo Error_Handler

' -- Crear nuevo objeto RegExp para utilizar el método Test
Dim objRegExp As New RegExp
' -- Setear el objeto y establecer el patrón
With objRegExp
' -- Establecer el patrón de búsqueda
.Pattern = sPattern
.IgnoreCase = True
.Global = True
End With
' -- Ejecutar el método Test y retornar un valor Boolean a la función
Validate_url = objRegExp.Test(sData)

Exit Function
' -- Errores
Error_Handler:
MsgBox " Número de error: " & Err.Number & vbNewLine & " Descripción del Error: " & Err.Description, vbCritical
End Function

Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 6 | 4:51 PM
Utilización de anclas

Las anclas se usan para ir a una parte concreta de una página. Esto es muy útil en grandes documentos donde moverse entre las partes del mismo puede ser dificultoso.

Un ancla se crea de la siguiente forma:

Quote
<a name = "nombre_ancla"></a>

Este código lo debemos insertar en la parte a donde queramos que se vaya cuando se pinche en un link que llame a un ancla, los links que llamen a un ancla deben de ser así:

Quote
<!--Para ir a un ancla en la misma página:-->
<a href = "#nombre_ancla">Ir al ancla "nombre_ancla"</a>
<!--Para ir a un ancla en otra página:-->
<a href = "http://tuweb.com/tupagina.htm##nombre_ancla">Ir al ancla "nombre_ancla"</a>

Ejemplo:

Quote
<h1><a name="indice"></a>Índice:</h1>
<a href="#capitulo1">Capitulo1</a><br>
<a href="#capitulo2">Capitulo2</a><br>
<a href="#capitulo3">Capitulo3</a><br>
<br><br>

<h2><a name="capitulo1"></a>Capitulo1</h2>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<a href="#indice">Volver al Índice</a>

<h2><a name="capitulo2"></a>Capitulo2</h2>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<a href="#indice">Volver al Índice</a>

<h2><a name="capitulo3"></a>Capitulo3</h2>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<a href="#indice">Volver al Índice</a>


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 7 | 5:16 PM
Controlar cuando el usuario activa el menú contextual

Este articulo va destinado a recomendar como se "debe" hacer tanto como NO.

Por Internet hay un código, que incluso se "vende" como código para evitar que te "roben" el código que es un claro ejemplo de lo que no debes poner si quieres que tu página sea tomada en serio. el código es este:

Quote
<SCRIPT language=JavaScript1.1>
<!-- Begin
function non(clic) {
var msg="message";
if (navigator.appName == 'Netscape' && clic.which==3) {
alert(msg);
return false;}
else
if (navigator.appName == 'Microsoft Internet Explorer' && event.button==2) {
alert(msg);
return false;
}
return true;
}
document.onmousedown = non;
// End -->
</SCRIPT>

Esto lo que hace es mandar un mensaje cuando el usuario da al botón derecho del ratón. Lo que realmente hace de él que sea un código funesto es que para evitar que "salte" esta función tiene que dar una orden de mayor importancia que el menú o sea un alert; eh aquí el problema ya que un alert es un mensaje muy molesto; por lo que cada vez que salte hay una gran posibilidad de que el usuario abandone tu página.

Los alert deben de ser usados como eso; MENSAJES DE ALERTA.

Este código lo que hace es eso evitar que salte el menú contextual; pero sin molestos alert y además de una forma mucho mas sencilla. El problema es que solo funciona en Internet Explorer 5.0 o superior; aun así aunque lo pongáis en vuestra página; no os debería de dar error en Netscape, aunque no lo ejecutaría. De todas formas recomendaros que NUNCA pongáis el código de arriba y que sepáis que todo lo que le llega al usuario; este podrá ver el código, lo único que podrías hacer es complicar un "poquito" la vida.

En el BODY:

Quote
<body oncontextmenu="return false;">

Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 8 | 5:21 PM
Comprobar la dirección de correo

Este código comprueba que la dirección de correo pasada sea valida (por ejemplo: vadim@ucoz.com )
A este código se le pasa una variable (texto) que es la dirección de correo pasada a comprobar.
Lo primero que hace es pasar todos los caracteres validos de dirección de mail a la variable cadena.
Luego se asegura de que haya solo una arroba (si hay mas de una o ninguna la variable arroba pasará -1).
A continuación coge el último punto de la cadena dada.
En el bucle 'for' se asegura de que la cadena no tiene ningún carácter no válido.
Por fin el 'if' comprueba:
1. Que tenga la arroba
2. Que tenga punto y este esté después de la arroba
3. Que después del punto haya al menos dos caracteres
4. Que la variable mailres (que antes hizo comprobaciones) sea true
5. Que no haya dos puntos seguidos

Esta función devolverá true si la dirección es verdadera o false si es falsa
________________________________________

En el HEAD:

Quote
<script language="javascript">
//Su explorador no soporta java o lo tiene deshabilitado; esta pagina necesita javascript para funcionar correctamente<!--
//Copyright © McAnam.com

function mail(texto){

var mailres = true;
var cadena = "abcdefghijklmnñopqrstuvwxyzABCDEFGHIJKLMNÑOPQRSTUVWXYZ1234567890@._-";

var arroba = texto.indexOf("@",0);
if ((texto.lastIndexOf("@")) != arroba) arroba = -1;

var punto = texto.lastIndexOf(".");

for (var contador = 0 ; contador < texto.length ; contador++){
if (cadena.indexOf(texto.substr(contador, 1),0) == -1){
mailres = false;
break;
}
}

if ((arroba > 1) && (arroba + 1 < punto) && (punto + 2 < (texto.length)) && (mailres == true) && (texto.indexOf("..",0) == -1))
mailres = true;
else
mailres = false;

return mailres;
}

//-->
</script>

En el BODY:

Quote
<p>
<input type="text" name="texto" id="texto">
<input type="button" onclick="alert(mail(texto.value))" value="Comprueba si es una dirección de correo">
</p>

Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 9 | 1:32 PM
7 formas sencillas de testear compatibilidad en navegadores

Ideal para diseñadores, desarrolladores y cualquier otra persona que alguna vez haya luchado con la necesidad de probar sus sitios en los distintos navegadores.

Aquí les ofrecemos siete herramientas simples para realizar un testeo de compatibilidad en los distintos navegadores y lo mejor es que todas las aplicaciones pueden utilizarse de forma gratuita.

1. Xenocode Browser Sandbox
El Xenocode Browser Sandbox es un navegador de prueba para máquinas con Windows. Con un sólo clic puedes probar tu web en varias versiones de IE, Firefox, Google Chrome e incluso Safari, sin necesidad de instalar absolutamente nada.

Lo mejor: Podrás probar los navegadores en directo, nada de simples capturas de pantalla. Plus: servicio completamente gratuito.

Lo malo: Sin embargo, no es la solución perfecta, por ahora no hay soporte para Macintosh; lo que implica un problema significativo.

Visitar Xenocode Browser Sandbox »

2. CrossBrowserTesting.com
Sesiones de testeo que te llevarán sólo cinco minutos para usuarios registrados, y mucho más que esto para aquellos que pagan. CrossBrowserTesting es tan fácil de usar como simplemente ingresar y seleccionar una máquina disponible con los navegadores que desees para comenzar tu prueba.

Puedes utilizar un java applet basado en la web para conectarte a su sistema de prueba de máquinas remotas, o utilizar un cliente local VNC si tienes uno instalado. El sistema permite testeo completo de la interactividad de un sitio y, como Xenocode, no se trata sólo de screenshots.

Visitar CrossBrowserTesting.com »

3. IETester
Este es un programa gratuito para Windows que se encuentra todavía en sus primeras etapas de desarrollo. Dicho esto, es un recurso que te permitirá probar completamente tus sitios en todas las versiones relevantes de Internet Explorer.

El programa incluso permite comparar dos versiones diferentes lado a lado.

Visitar IETester »

4. BrowsrCamp
La versión gratuita de este servicio ofrece capturas de pantalla casi instantáneas de cómo funcionaría la web en la última versión de Safari. Aunque le falta un poco en lo que respecta a las versiones de los navegadores lo compensa gracias a su increíble velocidad.

Por un par de dólares extra, ofrecen la posibilidad de apoderarse por completo de una máquina y realizar un testeo mucho más profundo.

Visita BrowsrCamp »

5. Litmus
Es una de las herramientas de testeo de compatibilidad de navegadores más populares hoy en día. Lamentablemente su versión gratuita es bastante limitada, permitiéndonos probar los sitios sólo en IE7 y Firefox 2.

La versión paga es significativamente mejor, dándonos la posibilidad de extender las pruebas a docenas de navegadores e incluso en clientes de email. Desafortunadamente, con una suscripción de usuario comenzando a $49 dólares por mes esto no es nada barato. Sin embargo, para aquellos que necesitan un testeo robusto puede que valga la pena.

Visita Litmus »

6. NetRenderer

NetRenderer es una opción más humilde para probar la compatibilidad de IE. Este servicio crea screenshots de tu sitio en varios navegadores. Actualmente soporta todas las versiones desde IE5 a IE8, y crea las capturas de pantalla rápidamente sin necesidad de esperar.

También nos provee de una barra de navegador que nos permite rápidamente probar cualquier sitio en el que nos encontremos sin necesidad de entrar a la web de su servicio.

Visita NetRenderer »

7. BrowserShots
BrowserShots se ha convertido en uno de los métodos de análisis más comunes hoy en día y con buenas razones. Permiten el testeo en casi cualquier navegador, incluyendo algunas combinaciones muy extrañas.

Su versión gratuita sólo tiene una limitación: debes esperar a que los usuarios pagos tengan acceso primero.

Debido a su popularidad, puede resultar muy lento recibir las capturas de pantalla de la prueba en algunas ocasiones. Como se basan en las computadores de los miembros para proveer las screenshots, mientras más popular sea la combinación de navegadores que selecciones más rápido recibirás tus capturas. A menos que todos los demás estén probando la misma combinación.

Visita BrowserShots »

Bonus 8. Adobe MeerMeer

Se trata de una aplicación que pronto lanzará Adobe. Adelantaron algunas de sus características en su Adobe MAX y desde ese momento, todo el que se escuchó sobre ella son grandes promesas.

MeerMeer ofrecerá un significante número de beneficios comparados con las herramientas que actualmente existen para este tipo de pruebas. El más popular es seguramente “onion skin”, o la capacidad de interponer el resultado de una prueba sobre otra de un navegador diferente como si fuera una mesa de calco. Mantente alerta: este recurso será importante.

¿Y tu cómo pruebas la compatibilidad web?


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 10 | 4:24 PM
Desarrollando lo invisible

A menudo, la parte invisible del diseño es olvidada, jugando ésta un papel muy importante en el aspecto final de cualquier producto. En este artículo se tienen en cuenta aspectos a menudo olvidados como la alineación y el espaciado.

Trabajamos en las interacciones y prestaciones posibles según nuestro tiempo y recursos. Discutimos casos complejos y clarificamos cómo deben trabajar las interacciones específicas para cada caso. Discutimos la estrategia del producto, la estructura de la información, el mercado meta, la tecnología de interfaz de usuario, etc. Frecuentemente nos encontramos con el mismo problema: la necesidad de considerar lo que no está ahí.

La forma a la que llegamos a esa conclusión es siempre la misma. Trabajo con el equipo de producción para equilibrar las metas del usuario, los requisitos del negocio y las consideraciones técnicas para crear un diseño del producto. El diseño queda revisado, iterado y finalmente documentado.
Fundamentalmente trabajo con empresas web; frecuentemente tengo que crear la documentación de mi diseño en muy poco tiempo. Esto significa que no hay mucho tiempo para crear detalladas especificaciones del diseño, ni tampoco hay oportunidad de proveer plantillas en HTML y CSS para todas las partes de una aplicación, así que trabajo con maquetaciones y diagramas de flujo (en forma de historias o diagramas de flujo) con el equipo de desarrollo. Lo que obtengo en la mayoría de los casos es la mitad del diseño.

Cuando digo "la mitad del diseño" me refiero a que todas las prestaciones, contenido y funciones están ahí, funcionando de forma acorde a como fueron diseñadas. Así que, ¿qué es lo que falta? ¿acaso no es ese el diseño completo del producto? Falta lo que es invisible: la alineación y el espaciado.

A menudo los elementos del interfaz de usuario no están alineados. Lo que está centrado en el diseño no aparece de esa forma en su implementación. Lo que estaba alineado vertical u horizontalmente en el diseño aparece desigual.

"Los cambios en el espaciado y la alineación pueden impactar de forma negativa en la legibilidad y oscurecer las relaciones visuales que aclaran la forma de usar una interfaz."

El espaciado o los espacios en blanco a menudo empeoran el diseño. En algunos lugares el espaciado se va; en otros hay demasiado. El espaciado es establecido con diferentes valores, conduciendo a columnas de filas de anchura variable. Los cambios en el espaciado y en la alineación pueden impactar negativamente sobre la legibilidad y oscurecer las relaciones visuales que aclaran la forma de usar una interfaz.

Las figuras 1 y 2 muestran algunos problemas con la alineación y el espaciado en la implementación de diseños. El diseño original aparece a la izquierda; la implementación en la derecha.

Figura 1 - ¿Ves las diferencias entre estos ejemplos?

Figura 2. Otro ejemplo que muestra diferencias en el espaciado y la alineación:

¿Por qué es este el caso? No es que los desarrolladores deliberadamente modificaran el diseño, ni que consideren que la alineación y el espaciado no sean importantes. Es que esos elementos en la interfaz de usuario a menudo son invisibles a ellos.

Los equipos de desarrollo son los responsables de incluir prestaciones interactivas y de contenido en un producto. El espacio en blanco no es ni prestación ni contenido. Por tanto no es un requisito. Para un diseñador, sin embargo, el espacio en blanco es a menudo tan importante como el contenido.

Como diseñador, empleo mucho tiempo ajustando el espacio en blanco para permitir la exploración eficaz del contenido. También empleo mucho tiempo ajustando la alineación y el espaciado para establecer la correcta priorización entre elementos de la interfaz. Utilizo ambos elementos de diseño para guiar a los usuarios a través de las interacciones en la página. Los uso para comunicar qué es más importante, qué está relacionado y qué necesita atención. Para los diseñadores, estos son requisitos clave para la comunicación efectiva. Y, si, hay mucha evidencia que muestra que lo que es invisible marca la diferencia.

"Una comprensión compartida de qué está siendo construido (ya sea visible o invisible) va en camino de hacer los productos que nuestros usuarios pueden comprender."

Ahora antes de que pienses que soy un diseñador que se queja del equipo de ingenieros por no construir exactamente lo que he diseñado, déjame decir que sé que la dificultad del equipo de ingeniería al enlazar el diseño del producto y el producto acabado es incalculable.

Como diseñadores debemos conocer las posibilidades de HTML y CSS y cómo hacer buenos diseños en todos los aspectos. Los equipos de desarrollo deberían reconocer que el espacio entre y alrededor de los elementos de la interfaz de usuario y la alineación de los mismos puede ser tan importante como los elementos en sí.

Me encantaría ver a más desarrolladores emplear la destreza y el arte que usan para la construcción de lo visible en la construcción de lo invisible: espaciado y alineación. Una vez que aprendan a mirar estos elementos en la especificación o maquetación de un diseño, tendrán un mejor sentido del diseño. Una comprensión compartida de qué está siendo construido (ya sea visible o invisible) va en camino de hacer que nuestros productos puedan ser comprendidos por el usuario.


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 11 | 5:02 PM
Diez Paradojas del Diseño Gráfico

01. No hay cosa tal como malos clientes: solamente malos diseñadores. Amamos culpar a nuestros clientes por trabajos pobres.
Cuando los proyectos van mal, son siempre los clientes – nunca nosotros – los culpables. Seguro, hay malos clientes, pero los diseñadores que usualmente los tratan mal, los han convertido en malos clientes. Como diseñadores, terminamos con los clientes que merecemos.

02. La mejor manera de aprender cómo convertirse en mejor diseñador gráfico es convirtiéndose en un cliente.
En las pocas ocasiones que he pagado por un diseño gráfico, he aprendido más sobre ser diseñador que por todo lo demás que haya hecho. Sólo comisionando a diseñadores gráficos es como descubrimos que la mayor parte de nosotros no somos muy buenos en la congruencia entre lo que hacemos y cómo trabajamos. Para muchos clientes, los diseñadores parecen funcionar bajo el principio expresado por el arquitecto héroe de “”The Fountainhead” de Ayn Rand: “No es mi intención construir para tener clientes. Mi intención es tener clientes para construir.” Como parte de su entrenamiento, todos los diseñadores deberían ser obligados a gastar una suma de su propio dinero en diseño gráfico.

03. Si deseamos educar a nuestros clientes sobre diseño, debemos primero educarnos sobre nuestros clientes.
Cuando oigo a los diseñadores decir que “debemos educar a nuestros clientes”, quisiera desmayarme. En vez de educar a nuestros clientes, debemos educarnos en los métodos de nuestros clientes. Entonces – y solamente entonces – los clientes nos tomarán seriamente.

04. Si deseamos hacer dinero como diseñador gráfico, debemos concentrarnos en el trabajo – no en el dinero.
Siempre que he aceptado proyectos de diseño “sólo por el dinero,” el desastre ha sobrevenido invariablemente. Cuando ponemos el dinero primero y el trabajo en segundo lugar, terminamos siempre con un mal trabajo y un balance incluso peor. No quiero decir que los diseñadores no deben ser pagados correctamente por su trabajo, o que los diseñadores no deben ser financieramente listos (los clientes generalmente lo son). Pero el motivo primario del diseñador tiene que ser la calidad del diseño y no del tamaño del honorario. Cuando el foco está en el dinero, el trabajo es generalmente pobre.

05. Para los diseñadores, las habilidades verbales son tan importantes como las habilidades visuales.
Puesto que el diseño gráfico debe explicarse por sí mismo, los diseñadores podrían ser perdonados por pensar que la necesidad de proporcionar un análisis verbal razonado de su trabajo es poco importante. ¿El trabajo debería tener éxito por sus propios méritos sin requerir la defensa de un diseñador? Cierto. A menos que nunca hubiera un cliente que no deseara una explicación para cada aspecto de cada pieza de trabajo creativo que contrató. Si no podemos hablar de nuestro trabajo de una manera clara, racional y objetiva – libre de toda jerga – entonces no podemos sorprendernos cuando nos encontremos con el rechazo.

06. Las ideas fallan generalmente no porque sean malas ideas, sino porque se presentan erróneamente.
La capacidad de presentar una idea es tan importante como la idea en sí misma. Lo único y más importante que necesitamos recordar cuando presentamos un trabajo a los clientes es que están aterrorizados con la posibilidad de lo que vamos a mostrarles. Para los clientes, comisionar diseño es como entrar a una sala de exhibición de muebles, comprar un sofá y que el vendedor les diga, “seguro, puedo venderle un sofá, pero no puedo mostrárselo.” ¿Quién gastaría dinero en algo que no puede ver? Sí, esto es justo lo que pedimos que nuestros clientes hagan cuando nos contratan.

07. “Soy un profesional: Sé qué es lo mejor.”
Los únicos diseñadores que utilizan esta discusión son diseñadores no profesionales. Los diseñadores dicen a menudo, “nadie dice a un doctor qué hacer, así que ¿por qué es ACEPTABLE el decirme qué hacer?” Pero el mito del omnipotente profesional ha sido descartado. Ya no aceptamos que los doctores, los abogados y los fontaneros tengan un monopolio del conocimiento. Hable a cualquier doctor y le dirá que la gente entra a sus consultorios armada con información descargada de Internet. Hace mucho tiempo hemos aprendido a preguntar y desafiar el juicio de los expertos. ¿Por qué deben los diseñadores estar exentos? Cualquier persona que utiliza el argumento “soy un profesional, por lo tanto debe aceptar lo que digo” ha perdido la discusión.

08. “Todos los buenos trabajos son para otros diseñadores.”
Falso: de hecho, casi todos los trabajos comienzan siendo ni buenos, ni malos. Nos engañamos si pensamos que sólo otros consiguen buenos trabajos y nosotros el escombro. La verdad es que casi todos los trabajos comienzan igual, y nuestra respuesta como diseñadores determina el éxito o fracaso de cada uno. No hay proyectos buenos o malos en diseño, solamente buenas o malas respuestas. A menudo me he entrevistado con diseñadores que me dijeron que les gustaría cambiar de trabajo porque solamente “les asignan proyectos horribles”. Sin embargo, cuando me enseñaron en lo que habían estado trabajando, generalmente parecían grandes trabajos.

09. La mejor manera de administrar un estudio es ser dominante y poderoso.
De hecho, la verdad es lo contrario. Los diseñadores que administran estudios o lideran equipos a menudo piensan que tienen que guiar desde el frente. Piensan que tienen que dominar. Piensan que tienen que tomar el crédito para todo. De hecho, la verdad es lo contrario. Los buenos líderes de los equipos de diseño conducen desde atrás. Se ponen ellos mismos en último lugar y permiten que los otros brillen. Cuando se permite a los diseñadores brillar, brillan con más esplendor.

10. Si no creemos en nada, no debemos preguntarnos porqué nadie cree en nosotros.
En un mundo sin principios, la gente respeta a los que tienen principios. El personificar a un tapete es una manera pobre de ser un diseñador gráfico eficaz. De hecho, el mantenerse firme sobre lo que creemos – ética, moralidad, estándares profesionales e incluso las preferencias estéticas – es la única manera de producir un trabajo significativo. Por supuesto no ganaremos siempre, pero ganaremos con más frecuencia que el diseñador que no cree en nada. Hay maneras incontables para demostrar integridad profesional – el único error que podemos cometer es no demostrar ninguna.

Nota: Al igual que el amplificador en “Spinal Tap”, que va hasta 11, mi lista de 10 paradojas contiene realmente 11 puntos. Aquí está la undécima paradoja del diseño gráfico.

11. Cuando un cliente dice las palabras – “usted tiene completa libertad creativa” nunca significa completa libertad creativa.
A cualquier cosa que usted le muestre, ellos le encontrarán un problema. Siempre ocurre.


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 12 | 12:16 PM
Comprobar el número de renglón correspondiente al texto de una capa
Manejar renglones con javascript
Veremos cómo mostrar sólo los 5 primeros renglones del texto escrito en una capa.

Separar un texto en renglones puede ser algo problemático, ya que, como sabemos, los caracteres de las tipografías que no son monoespaciadas presentan anchos variables y, entonces, una separación basada en cálculos matemáticos y conteo de caracteres puede no tener los resultados esperados.
Afortunadamente, existe un camino alternativo para averiguar en qué renglón se encuentra ubicado cualquier carácter, utilizando su posición vertical respecto del documento.

Veamos cómo aplicar esa técnica para mostrar sólo los primeros cinco renglones de un texto:

Quote
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>test</title>
<script>
Array.prototype.inArray=function(el){
for(var i=0,l=this.length;i<l;i++)
if(this[i]==el)
return true;
return false;
}
onload=function(){
var txt='<span>'+document.getElementById('ej').innerHTML.split('').join('</span><span>')+'</span>';
document.getElementById('ej').innerHTML=txt;
var t='';
var cuenta=[];
for(var i=0, l=document.getElementById('ej').getElementsByTagName('span'),ll=l.length;i<ll;i++){
if(!cuenta.inArray(l[i].offsetTop))
cuenta.push(l[i].offsetTop);
if(cuenta.length<6)
t+=l[i].innerHTML;
else
break;
}
document.getElementById('ej').innerHTML=t;
}
</script>
</head>

<body>
<div id="ej" style="width:300px;">Lorm ipsum dolor sit amet, consecteuer adipi scing elit. Nulla ante arcu, scelerisque ut, imperdiet nec, aliquet et, magna. Cras mauris odio, volutpat quis, aliquam in, lacinia at, arcu. Nulla vitae magna vitae erat aliquam ultricies. Vestibulum euismod nisl eget augue. Donec magna. Sed porttitor, libero ac egestas pharetra, velit augue scelerisque nunc, convallis rhoncus elit est et enim. Proin pulvinar condimentum wisi. Nullam quis nulla. Etiam elementum, nunc a t lacinia condimentum, nunc neque nonummy wisi, sit amet volutpat est purus id massa. Nunc purus wisi, fringilla id, accumsan ac, lobortis nec, arcu. Integer sagittis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut suscipit fermentum ligula. Suspendisse posuere. Donec varius, ipsum sit amet ultricies iaculis, magna nisl hendrerit libero, ac ultrices orci lacus eget neque.

Maecenas tellus enim, convallis euismod, interdum sed, pharetra et, libero. Nam suscipit nisl nec ligula. Nullam vitae risus quis neque rutrum sollicitudin. Fusce sed nulla. Integer posuere sapien et turpis. Donec dui ipsum, vulputate vitae, nonummy at, fringilla non, justo. Aliquam quis urna non nunc pulvinar aliquam. Cras libero. Quisque nec wisi vitae tellus tincidunt congue. Fusce vulputate dolor in pede. Maecenas sollicitudin molestie sem. Aenean sagittis, metus ut blandit pharetra, lorem justo gravida felis, in adipiscing eros at magna. Nunc porta odio non felis. Quisque posuere faucibus ipsum. Phasellus nibh augue, tempus vitae, euismod ut, gravida a, leo. Donec felis. </div>
</body>
</html>

La técnica, aunque simple, es bastante poderosa y funciona bien en todos los navegadores modernos. Sólo le encuentro un inconveniente: si bien la cantidad de renglones siempre es la esperada, la cantidad de caracteres por renglón no es igual en todos los navegadores. Un inconveniente menor, pero que conviene tener en cuenta.


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 13 | 6:01 PM
Insertar videos de YouTube con XHTML válido

Insertar un video de YouTube en tu sitio web o blog es muy sencillo. Basta con copiar y pegar el HTML que se nos proporciona. Pues bien, si simplemente hacemos esto la página resultante no va a ser XHTML válido.

Para que los videos de Youtube aprueben la validación de la W3C (estándar web de la correcta codificación y uso de HTML y XHTML) debemos realizar unas pequeñas modificaciones al código original que nos proporciona Youtube.

Si bien el posicionamiento de una web o blog en los buscadores no se ve directamente influenciado al tener una correcta validación de plantilla acorde con los lineamientos de la W3C, sí le da a éstas una mejor y correcta estructura que le facilita el trabajo a los robots de Google.

El problema
Si son de aquellos a quienes nos gusta mantener un código válido y además gusta de insertar videos de en tu blog, seguramente se habrán dado cuenta del horroroso código que algunos proveedores entregan para insertar los videos.

Por ejemplo, veamos el código que entrega YouTube:

Quote
<object width="425" height="350">
<param name="movie" value="http://www.youtube.com/v/PsRkU7FV4aw"></param>
<param name="wmode" value="transparent"></param>
<embed src="http://www.youtube.com/v/PsRkU7FV4aw"
type="application/x-shockwave-flash" wmode="transparent"
width="425" height="350">
</embed>
</object>

El problema es que el elemento <embed /> no es válido, o más bien, no existe en las especificaciones del W3, sino que es un invento de Netscape (de aquellos tiempos en que su navegador aún era importante). Por otra parte, object sí es válido, pero si insertáramos el código precedente sin ninguna otra modificación que remover el elemento embed, los usuarios de Firefox no verían nada.

La solución
La solución: utilizar object pero especificando un atributo fundamental, type="application/x-shockwave-flash". El código válido quedaría de esta forma:

Quote
<object width="425" height="350" type="application/x-shockwave-flash"
data="http://www.youtube.com/v/PsRkU7FV4aw">
<param name="movie" value="http://www.youtube.com/v/PsRkU7FV4aw" />
<param name="wmode" value="transparent" />
</object>

Facilitando las cosas
Como (casi) siempre, existe una manera más fácil de hacer las cosas, y en este caso como en muchos otros pasa por un plugin para WordPress: con Embedded video with Link podrás insertar videos de YouTube, Google Video y un par de sitios alemanes de alojamiento de videos que no creo que sean muy populares entre ustedes, lectores de este blog.

Una vez instalado, puedes insertar videos de la siguiente forma:

Quote
[youtube id-del-video texto-para-el-enlace]
[google id-del-video texto-para-el-enlace]

La “id-del-video” es una cadena de caracteres que forma parte de la dirección de cada video:

Quote
http://www.youtube.com/watch?v=PDxMQaMqsig
http://video.google.com/videoplay?docid=2331852903610109378

El “texto-para-el-enlace” es… adivinen qué cry . Puede contener espacios. biggrin


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 14 | 6:44 PM
Uso de mailto: para enviar mensajes desde un enlace

Desde un enlace podemos enviar mensajes por correo electrónico realmente complicados y largos. Sólo hace falta saber un par de cosillas.

Introducción
El facilitar a los visitantes de tu página que te manden un mensaje es tan sencillo como poner un enlace. Eso sí, el enlace debe contener la dirección de correo y estar precedida por mailto: en lugar del archiconocido http://.

Quote
<A HREF="mailto:direccion@correo.com">Escribeme</A>

Pulsa sobre el enlace y... ¡voila! Ventanita de "escribir mensaje" al canto. Evidentemente no he puesto mi dirección, que si no me machacáis a base de mensajes, seguro.

Compliquemos las cosas
Como comprenderéis, para deciros semejante tontería no me iba a poner a escribir un artículo. Lo que os quería contar es que se pueden rellenar algunos campos del mensaje siguiendo la codificación estándar de las URL. Son los siguientes:

subject: El asunto del mensaje.
cc: Enviar una copia del mensaje a la dirección indicada.
body: El texto del mensaje.

La manera de escribir todo esto dentro del enlace es muy sencilla. Después de poner la dirección de envío como hicimos arriba, ponemos un signo de interrogación seguido de una serie de parejas de la forma campo=valor separados por símbolos de ampersand (&). Usease:

Quote
<A HREF="mailto:direccion@correo.com?cc=otradir@correo.es&subject=Burro">
Escribeme</A>

Ala, a pulsar.

Varias líneas en el cuerpo del mensaje
Un problema común a la hora de incluir el texto del mensaje en un enlace es que, a primera vista, no hay quien ponga espacios ni varias líneas en el mismo. Esto se soluciona utilizando la codificación reservada a caracteres de control y extendidos. Para poner un espacio escribiremos %20 y para cambiar de línea %0D%0A:

Quote
<A HREF="..subject=Burro&body=Hola,%20zoquete.%0D%0ABurro%20es%20con%20B.">
Escribeme</A>


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 15 | 6:49 PM
Guía sobre los comentarios condicionales


Para detectar qué navegador estamos usando, se utilizan los comentarios condicionales. Estos comentarios fueron creados por Microsoft y solo pueden usarse para el navegador creado por Microsoft, Internet Explorer. Se colocan entre las etiquetas <head> y </head> de nuestro documento HTML.

Hay varias maneras de definir los comentarios, pero la base es esta:

Quote
<!--[if CONDICION]>
Código HTML
<![endif]–>

En la condición se puede utilizar estas versiones de Internet Explorer por el momento, que soportan los comentarios condicionales: IE 5, 5.5, 6, 7:

Quote
IE
Cualquier versión de Internet Explorer
lt IE X
Versiones inferiores a X
lte IE X
Versiones inferiores o iguales a X
IE X
Solo para la version X
gte IE X
Versiones superiores o iguales a X
gt IE X
Versiones superiores a X

Ahora un ejemplo:

Quote
<!-- (…) -->
<head>
<title>Título</title>
<link href="all_browsers.css" rel="stylesheet" type="text/css">
<!--[if IE]>
<link href="ie_any_version.css" rel="stylesheet" type="text/css">
<![endif]-->
<!--[if lt IE 7]>
<link href="ie_6_and_below.css" rel="stylesheet" type="text/css">
<![endif]-->
<!--[if !lt IE 7]>
<![IGNORE[--><![IGNORE[]]>
<link href="recent_versions.css" rel="stylesheet" type="text/css">
<!--<![endif]-->
<!--[if !IE]>-->
<link href="not_ie.css" rel="stylesheet" type="text/css">
<!--<![endif]-->
</head>
<!-- (…) -->

También podemos usar un truco, que es el de incluir un guión bajo para definir las propiedades de los estilos. Ningún navegador excepto Internet Explorer leerá lo que esté con un guión bajo o asterisco, excepto Internet Explorer:

Quote
body {
background: #FFFFFF
/* Firefox y los demás */
*background: #000000
/* IE7 e inferiores */
_background: #CCCCCC;
/* Sólo IE6 */
}

Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
  • Página 1 de 3
  • 1
  • 2
  • 3
  • »
Búscar: