|
En este capitulo vamos a dar una breve introducción, de 2 temas que seguramente será de muy poco uso en VB, pero que algunas veces es necesario conocerlos para el manejo de algunas funciones API’S, por ejemplo, las funciones que vamos a ver a nivel de Cadenas o String, no ve ser necesario usarlas en VB, ya que dicho lenguaje presenta funciones que hacen el trabajo. Pero uno nunca sabe cuando uno puede usar estas funciones, inclusive para aquellos osados que programen en C entonces si necesitaran el conocer estas funciones. CADENAS O STRING En esta sección veremos algunas funciones API’S utilizadas para la manipulación de caracteres, para este proyecto es necesario: 3 Label o etiquetas, 1 listBox y 1 caja de texto o TextBox. Luego peguen este código: Ver Codigo
CharLower Api: Declare Function CharLower Lib "user32" Alias "CharLowerA" (ByVal lpsz As String) As String Función encargada de poner en minúscula una cadena de texto, dicha cadena se le pasa como único parámetro, y la función retorna la nueva cadena con todos los caracteres en minúscula. CharLowerBuff Api: Declare Function CharLowerBuff Lib "user32" Alias "CharLowerBuffA" (ByVal lpsz As String, ByVal cchLength As Long) As Long Hace exactamente lo mismo que la función descrita arriba, con la diferencia que como segundo parámetro le pasamos la cantidad de caracteres que queramos poner en minúscula, es decir, con esta función podemos convertir en minúscula una porción de la cadena de caracteres. CharUpper Api: Declare Function CharUpper Lib "user32" Alias "CharUpperA" (ByVal lpsz As String) As String Igual que la función CharLower con la diferencia que convierte los caracteres que están en minúscula en mayúsculas. CharUpperBuff Api: Declare Function CharUpperBuff Lib "user32" Alias "CharUpperBuffA" (ByVal lpsz As String, ByVal cchLength As Long) As Long Igual que la función CharUpperBuff con la diferencia que convierte los caracteres que están en minúscula en mayúsculas. IsCharAlpha Api: Declare Function IsCharAlpha Lib "user32" Alias "IsCharAlphaA" (ByVal cChar As Byte) As Long Determina si un carácter es “Alpha”, es decir, es cualquier letra del abecedario, ya sea en mayúscula o en minúscula, dicho carácter, se le pasa como primer parámetro en forma de “byte” lo cual significa que se le pasa el código ASCII. Si el carácter es del tipo “Alpha” entonces retornara un valor distinto de 0. En caso contrario retorna 0. IsCharAlphaNumeric Api: Declare Function IsCharAlphaNumeric Lib "user32" Alias "IsCharAlphaNumericA" (ByVal cChar As Byte) As Long Determina si un carácter es del tipo “Alpha” numérico, es decir, todos los caracteres del abecedario incluyendo los números. Las condiciones del primer parámetro son iguales a IsCharAlpha. IsCharLower Api: Declare Function IsCharLower Lib "user32" Alias "IsCharLowerA" (ByVal cChar As Byte) As Long Determina si un carácter esta en minúscula, si el carácter esta en minúscula la función retorna un valor distinto de 0. IsCharUpper Api: Declare Function IsCharUpper Lib "user32" Alias "IsCharUpperA" (ByVal cChar As Byte) As Long Determina si un carácter esta en mayúscula, si el carácter esta en mayúscula la función retorna un valor distinto de 0. lstrcat Api: Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long Función que concatena 2 cadenas, es decir, pega “lpString2” en “lpString1”, ejm: Cadena1 = “Hola” Cadena2 = “ Mundo”. Cadena1 después de lstrcat = “Hola Mundo” lstrcmp Private Declare Function lstrcmp Lib "kernel32" Alias "lstrcmpA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long Compara dos cadenas de caracteres, dicha comparación “es sensitiva a mayúsculas y minúsculas”, es decir, para esta función: s1 = "String 1" s2 = "string 1" Estas cadenas, no son iguales, ya que “s1” tiene “S” y “s2” tiene “s”. lstrcmpi Api: Declare Function lstrcmpi Lib "kernel32" Alias "lstrcmpiA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long Hace lo mismo que la anterior con la diferencia que “no es sensitiva”, es decir, para esta función: s1 = "String 1" s2 = "string 1" Son iguales. lstrcpy Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long Copia la cadena que hay en “lpString2” en “lpString1”. lstrcpyn Private Declare Function lstrcpyn Lib "kernel32" Alias "lstrcpynA" (ByVal lpString1 As String, ByVal lpString2 As String, ByVal iMaxLength As Long) As Long Copia una cantidad de bytes específicos que hay en “lpString2” en “lpString1”. Dicha cantidad de bytes es pasada en el tercer parámetro de la función. lstrlen Api: Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Long Determina la longitud de la cadena de texto, pero dicha longitud dependerá del formato del texto, el valor que retorna será la cantidad en bytes, si la cadena es del tipo (ANSI) o retornara la cantidad de caracteres si el del tipo (UNICODE). MEMORIA En esta sección vamos a tratar las funciones básicas para tratar con la memoria del sistema, todos sabemos que con la introducción de Windows 95, se añadió lo que se llama memoria virtual, dicha memoria esta localizada en el disco duro, y el sistema la usa cuando la memoria ram se encuentra llena, en el proyecto que veremos a continuación trabajamos con la memoria RAM, pero las explicaciones de las funciones que veremos son análogas para el manejo de la memoria virtual. Para este proyecto es necesario: 2 botones, y 2 etiquetas o label. Luego pegan este código: Ver Codigo
Cuando arranquen y aprieten los botones, verán que las etiquetas se llenan con información, ustedes podrían preguntarse, ¿Para que hacer todo esto, si con solo asignar variable1=variable2, estamos listo?. Ciertamente, esto es un proceso un poco engorroso, pero algunas veces, para manipular algunas API’S es necesario tener en cuenta estas funciones primordialmente CopyMemory. GlobalAlloc Api: Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long Función encargada de reservar un espacio en memoria, el primer parámetro puede tener una combinación OR de las siguientes constantes: Private Const GMEM_FIXED = &H0 ‘ Reserva un espacio ya fijo, en la memoria. Private Const GMEM_MOVEABLE = &H2 ‘ Reserva un especio el cual no esta fijo, es decir, Windows, tiene la libertad de moverlo. Private Const GMEM_DDESHARE = &H2000 Private Const GMEM_SHARE = &H2000 ‘ Estas dos constantes, sirven para reservar un especio de memoria compartido. Private Const GMEM_DISCARDABLE = &H100 Private Const GMEM_NOT_BANKED = &H1000 ‘ Private Const GMEM_LOWER = GMEM_NOT_BANKED Private Const GMEM_NOTIFY = &H4000 Private Const GMEM_NOCOMPACT = &H10 Private Const GMEM_NODISCARD = &H20 ‘ Todas estas constante son ignorada por el sistema, solo se usa para mantener compatibilidad con aplicaciones de 16 Bits. Private Const GMEM_ZEROINIT = &H40 ‘ Inicializa el contenido de la memoria con 0. Como segundo parámetro “dwBytes”, le pasamos la cantidad de bytes que queremos reservar para dicha memoria. En caso de no poseer suficiente espacio en la pila de memoria, la función retornara NULL, de lo contrario retorna el “handle” o identificador de la memoria, en caso de haber usado GMEM_FIXED la función retorna directamente el puntero de la memoria, es decir, la ubicación en donde almacenaremos nuestra información. GlobalReAlloc Api: Declare Function GlobalReAlloc Lib "kernel32" (ByVal hMem As Long, ByVal dwBytes As Long, ByVal wFlags As Long) As Long Función que sirve para cambiar los atributos o tamaño a un “handle” de memoria ya creado. Como primer parámetro le pasamos el “handle” de la memoria, como segundo parámetro le pasamos el nuevo tamaño en bytes, y como tercer parámetro les pasamos los “flag” los cuales son los mismos que las constantes de la función GloballAlloc. GlobalLock Api: Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long Función que bloquea el espacio de memoria asignado con GlobalAlloc, ¿Qué quiere decir bloquear?. Cuando creamos un espacio en memoria, sin usar la constante GMEM_FIXED, el sistema operativo esta en la autoridad de poder mover dicha información, esto puede ocasionar fallas en el programa. Imaginemos que tenemos una variable “a”, que esta en la posición 1 de la memoria , y le asignamos el valor de 5, si creamos la variable “a” con GlobalAlloc sin haber usado GlobalLock, cuando vayamos a consultar la variable “a” puede que Windows nos retorne un error, y esto se debe a que Windows pudo haber cambiado la posición en donde estaba la información de “a”, con GloballLock, nosotros lo que hacemos es fijar o bloquear ese espacio para que Windows no lo mueva y así poder trabajar dicho espacio sin problemas. El único parámetro a usar es el “handle” de la memoria que nos retorna GlobalAlloc. GlobalUnlock Api: Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long Lo que hace es desbloquear un “handle” de memoria. GlobalFree Api: Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long Con esto liberamos el espacio de memoria que fue utilizado, dejando que otro programa pueda usar dicho espacio. Todo espacio que creamos con GlobalAlloc tiene que ser liberado, sino aunque cerremos el programa que manipulaba la memoria la información sigue estando contenida en la memoria RAM de la computadora. CopyMemory Api: Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Función encargada de copiar la información de un espacio de memoria a otro. Los dos primeros parámetro hablan por si solo, y el tercer parámetro es la longitud en bytes de la cantidad de información que queremos copiar. FillMemory Private Declare Sub FillMemory Lib "kernel32.dll" Alias "RtlFillMemory" (Destination As Any, ByVal Length As Long, ByVal Fill As Byte) Llena el espacio en memoria, con la información que se le pasa en el tercer parámetro “fill”, es decir: Fillmemory(espacio,4,65) Aquí lo que estoy haciendo es que en la dirección de memoria contenido en la variable “espacio”, almacena 4 bytes, donde cada byte tendrá la letra “A”, si lo vemos como carácter o 65 si lo vemos como número. ¿Lo ven?. Llena el contenido de la memoria con la información pasada en “fill”. Vayamos a los ejemplos, primero veamos el “command1”: Dim espacio As Long Dim espaciofijo As Long ‘ Declaro las dos variable que almacenaran la dirección de memoria reservada. Dim num As Long, num2 As Long num = 100 espacio = GlobalAlloc(GMEM_ZEROINIT, 4) ‘ Reservo 4 bytes de memoria, y los inicializo en 0 espaciofijo = GlobalLock(espacio) ‘ Fijo el espacio para que Windows no cambie la información. CopyMemory ByVal espaciofijo, num, 4 ‘ Copio el valor de “num”, en la dirección de memoria de “espaciofijo”. CopyMemory num2, ByVal espaciofijo, 4 ‘ Copio lo que hay en la dirección “espaciofijo” en la variable “num2” Label2 = num2 ‘ Muestro el contenido “num2” que es igual al de “num1” GlobalUnlock espaciofijo ‘ Desbloqueé el espacio que esta bloqueado, para liberarlo. GlobalFree espacio ‘ Libero el espacio. Dense cuenta de algo, la variable “espaciofijo” contiene la dirección de memoria donde almacenaremos información, es decir: CopyMemory ByVal espaciofijo, num, 4
Es incorrecto pensar que “espaciofijo” ahora tiene el valor de “num”, NO!, la dirección que apunta “espaciofijo” contiene el valor de “num”, que es algo muy distinto. “espaciofijo” es una variable ubicado en X lugar de la memoria, cuyo numero de tipo “long” que contiene específicamente una dirección en la memoria. Espero que vean la diferencia. Para los conocedores de C seguro no habrá problema. Vayamos al “command2”: Dim espacio As Long s1 = "Hola mundo!" espacio = GlobalAlloc(GMEM_FIXED Or GMEM_ZEROINIT, Len(s1)) ‘ Reservamos un espacio ya fijo en la memoria, esto es gracias a la constante GMEM_FIXED es decir, no es necesario el uso de la función GlobalLock. CopyMemory ByVal espacio, ByVal s1, Len(s1) ‘ Copiamos la cadena de caracteres “s1”, en la dirección de memoria que tiene almacenada la variable “espacio”. s2 = String$(lstrlen(espacio), 0) ‘ Inicializamos el espacio de memoria donde almacenáremos el contenido de la dirección de memoria almacenada en la variable “espacio”. CopyMemory ByVal s2, ByVal espacio, lstrlen(s1) ‘ Copiamos el contenido de la dirección que esta en “espacio” en la variable “s2”. Label1 = s2 GlobalFree espacio ‘Liberamos dicho espacio. Como pueden ver no es muy cómodo trabajar de esta manera, y mas cuando todo se pudo haber solucionado con s1 = s2, y listo!, pero resulta que algunas veces las funciones API’S de Windows nos regresan punteros de memoria que para visualizar su contenido tenemos que hacer lo antes expuesto arriba, no tanto el procedimiento como tal, sino el uso de CopyMemory. Funciones “Virtual”. VirtualAlloc Api: Declare Function VirtualAlloc Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long VirtualLock Api: Declare Function VirtualLock Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long) As Long VirtualUnlock Api: Declare Function VirtualUnlock Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long) As Long VirtualFree Api: Declare Function VirtualFree Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long Estas funciones trabajan exactamente igual a sus homologas de arriba. Con la diferencia que trabajan sobre la memoria virtual.
|