tag:blogger.com,1999:blog-3146149484209379412024-02-20T18:44:48.460-08:00Programación en españolUnknownnoreply@blogger.comBlogger12125tag:blogger.com,1999:blog-314614948420937941.post-67015801114122794632015-08-07T04:00:00.001-07:002015-08-07T04:00:22.552-07:00[FASM] Ensamblador en líneaHoy les traigo una manera muy simple de como utilizar ensamblador en sus programas, solo vamos a necesitar dos items, una libreria externa y ganas de programar.<br />
<br />
Empezamos descargando FASM.dll de este enlace: <a href="http://board.flatassembler.net/download.php?id=5133" target="_blank">¡Descargar!</a><br />
<br />
Esta libreria nos ofrece 3 procedimientos.<br />
<br />
<b><span style="color: purple;">Proc</span></b> fasm_Assemble(<b><span style="color: purple;">Referencia</span></b>:<b><span style="color: purple;">Cadena</span></b>,,,,:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b>, <span style="color: #666666;">"FASM.dll"</span><br />
<b><span style="color: purple;">Proc</span></b> fasm_GetVersion:<b><span style="color: purple;">Entero</span></b>, <span style="color: #666666;">"FASM.dll" </span><span style="color: #38761d;">' Sin parametros, Void...</span><br />
<b><span style="color: purple;">Proc</span></b> fasm_AssembleFile(<span style="color: purple;"><b>Referencia</b></span>:<b><span style="color: purple;">Cadena</span></b>,,,,:<span style="color: purple;"><b>Entero</b></span>):<b><span style="color: purple;">Entero</span></b>, <span style="color: #666666;">"FASM.dll"</span><br />
<span style="color: #666666;"><br /></span>
fasm_Assemble: Este procedimiento (o función) nos permite "compilar" nuestro código ensamblador con sintaxis FASM a Opcodes (o offsets) que pueden ser manipulados a nuestra voluntad.<br />
<br />
fasm_GetVersion: Este procedimiento retorna la versión de la libreria, se debe separar entre HiWord y LoWord.<br />
<br />
fasm_AssembleFile: Nos permite procesar un archivo de código fuente con formato ASM, muy util si quieren hacer procedimientos dinamicos.<br />
<br />
Por si no se puede apreciar, fasm_Assemble y fasm_AssembleFile tienen exactamente la misma cantidad de parametros y su uso es muy semejante.<br />
<br />
2 de 3 de estos procedimientos devuelven punteros a estructuras, estas son las siguientes:<br />
<br />
<span style="color: #38761d;">' Unión #1</span><br />
<b><span style="color: purple;">Unión</span></b> FASM_DATA1,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>output_length,_ <span style="color: #38761d;">' Cantidad de opcodes.</span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>error_code:<b><span style="color: purple;">Entero</span></b><span style="color: #38761d;"> ' Código del error.</span><br />
<br />
<span style="color: #38761d;">' Unión #2</span><br />
<b><span style="color: purple;">Unión</span></b> FASM_DATA2,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>output_data,_ <span style="color: #38761d;">' Puntero a los offsets.</span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>error_line:<b><span style="color: purple;">Entero</span></b> <span style="color: #38761d; font-family: '';">' Puntero a FASM_LINE_HEADER con la información del error.</span><br />
<br />
<b><span style="color: purple;">Unión</span></b> FASM_DATA3,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>file_offset,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>macro_calling_line:<b><span style="color: purple;">Entero</span></b><br />
<br />
<b><span style="color: purple;">Estruc</span></b> FASM_STATE,_ <span style="color: #38761d;">' Estructura que obtiene los offsets / Opcodes.</span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> condition:<b><span style="color: purple;">Entero</span></b>,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> a:FASM_DATA1,_ <span style="color: #38761d;">' Unión #1</span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> b:FASM_DATA2 <span style="color: #38761d;">' Unión #2</span><br />
<br />
<b><span style="color: purple;">Estruc</span></b> FASM_LINE_HEADER,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> file_path,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> line_number:<b><span style="color: purple;">Entero</span></b>,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> c:FASM_DATA3,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> macro_line:<b><span style="color: purple;">Entero</span></b><br />
<br />
fasm_Assemble acepta 5 parametros, los unicos que nos importan son los 3 primeros.<br />
<br />
Parametro #1: Código que se procesará.<br />
Parametro #2: Puntero al buffer que recibirá los datos de las estructuras.<br />
Paraemtro #3: Tamaño del buffer.<br />
Parametro #4: Debe ser 100.<br />
Parametro #5: Puntero a CallBack, debe ser cero.<br />
Retorno: 0 Si fue exitoso, otro valor si hubo un error.<br />
<br />
Un ejemplo de el uso de este procedimiento es el siguiente:<br />
<br />
<b><span style="color: purple;">Proc</span></b> ProcesarASM(<b><span style="color: purple;">Referencia</span></b> Código:<b><span style="color: purple;">Cadena</span></b>):<span style="color: purple;"><b>Byte</b></span>[]<br />
<b><span style="color: purple;">Var</span></b> Offsets[]:<b><span style="color: purple;">Byte</span></b> <span style="color: #38761d;">' Declaramos el buffer.</span><br />
<b><span style="color: purple;">Var</span></b> Info:<span style="font-family: '';">FASM_STATE<span style="color: #38761d;"> ' Estructura que contendra los datos recibidos del buffer.</span></span><br />
<span style="font-family: '';"><span style="color: #38761d;"> </span><b style="color: purple;">Var </b>Error:FASM_LINE_HEADER <span style="color: #38761d;">' Estructura que obtiene los errores encontrados.</span></span><br />
<b><span style="color: purple;">Var</span></b> Verificar:<span style="color: purple;"><b>Entero</b></span><span style="color: #38761d;"> ' Variable que utilizamos para obtener el código de error (si hubo).</span><br />
<b><span style="color: purple;">ReDim</span></b> Offsets,<span style="color: #0b5394;">10000</span><span style="color: #38761d;"> ' ReDimencionamos el buffer (tamaño recomendado).</span><br />
<span style="font-family: '';">Verificar = </span>fasm_Assemble(Código,Offsets[<span style="color: #0b5394;">0</span>]<span style="color: #351c75;">@</span>,<span style="color: #0b5394;">10000</span>,<span style="color: #0b5394;">100</span>,<span style="color: #0b5394;">0</span>)<br />
<b><span style="color: purple;">Si</span></b> Verificar = <span style="color: #0b5394;">0</span> <b><span style="color: purple;">Entonces </span></b><span style="color: #38761d;">' Si no hubo ningún problema.</span><br />
<span style="color: #38761d;"> </span><span style="color: purple; font-weight: bold;">AdmErr </span><span style="color: #38761d; font-weight: bold;">' </span><span style="color: #38761d;">Verificamos si se produce un error.</span><br />
CopyMemory(Info<span style="color: #351c75;">@</span>,Offsets[<span style="color: #0b5394;">0</span>]<span style="color: #351c75;">@</span>,Long(Info)) <span style="color: #38761d;">' Copiamos el contenido de "Offsets" en Info para _</span><br />
<span style="color: #38761d;"> ' rellenar la estructura.</span><br />
<span style="color: #38761d;"> </span>CopyMemory(Offsets[<span style="color: #0b5394;">0</span>]<span style="color: #351c75;">@</span>,Info.b.<span style="font-family: '';">output_data,Long(</span><span style="font-family: '';">Info.b.</span><span style="font-family: '';">output_data</span><span style="font-family: '';">)</span>) <span style="color: #38761d;">' Rellenamos el buffer _</span><br />
<span style="color: #38761d;"> ' con los datos que estan en la dirección de "<span style="font-family: '';">Info.b.</span><span style="font-family: '';">output_data" (offsets).</span></span><br />
<span style="font-family: '';"><span style="color: #38761d;"> </span><b style="color: purple;">Controlar </b><span style="color: #38761d;">' Si se produjo algún error.</span></span><br />
<span style="font-family: '';"><b style="color: purple;"> Salir </b><span style="color: #38761d;">' Salimos del procedimiento sin devolver nada.</span></span><br />
<span style="font-family: '';"><span style="color: purple;"><b> FinAdmErr</b></span></span><br />
<span style="font-family: '';"><b style="color: purple;"> ReDim </b><b><span style="color: purple;">Preservar</span></b><b style="color: purple;"> </b>Offsets,</span><span style="font-family: '';">Info.a.</span><span style="font-family: '';">output_length <span style="color: #38761d;">' Redimencionamos la matriz con la cantidad de offsets presentes.</span></span><br />
<span style="font-family: '';"><b style="color: purple;"> Resultado </b>= Offsets<span style="color: #38761d;"> ' Devolvemos los offsets.</span></span><br />
<b><span style="color: purple;">SiNo</span></b> <span style="color: #38761d;">' Si hubo un problema.</span><br />
<div style="font-family: '';">
CopyMemory(Info<span style="color: #351c75;">@</span>,Offsets[<span style="color: #0b5394;">0</span>]<span style="color: #351c75;">@</span>,Long(Info)) <span style="color: #38761d;">' Copiamos el contenido de "Offsets" en Info para _</span></div>
<div style="font-family: '';">
<span style="color: #38761d;"> ' rellenar la estructura.</span></div>
<div style="font-family: '';">
CopyMemory(Error<span style="color: #351c75;">@</span>,Info.b.error_line,Long(Error)) <span style="color: #38761d;">' Rellenamos la estructura Error con el contenido obtenido de la dirección "</span><span style="font-family: '';"><span style="color: #38761d;">Info.b.error_line".</span></span></div>
<span style="color: #38761d; font-family: '';"> </span><b><span style="color: purple;">Resultado</span></b><span style="color: #38761d;"> </span>=<span style="color: #38761d;"> </span>[<span style="color: #0b5394;">0</span>,ERROR.line_number,ERROR.c.file_offset]<br />
<b><span style="color: purple;">FinSi</span></b><br />
<b><span style="color: purple;">FinProc</span></b><br />
<b><span style="color: purple;"><br /></span></b>
Creo que el código de ejemplo esta muy claro.<br />
<br />
El procediento fasm_AssembleFile es muy parecido a fasm_Assemble, lo unico que cambia es que el primer parametro, en vez de ser código, es la dirección de un archivo ASM en nuestro sistema, en caso de no encontrarse "info.a.error_code" devuelve "FASM_SOURCE_NOT_FOUND" (-4).<br />
<br />
Saludos!<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-30297876012230497222015-07-14T22:45:00.002-07:002015-07-21T16:55:42.387-07:00Consejos para programar mejorNo se si yo sea el mas indicado para crear una entrada así, aunque si escribo código, pero hay cierto tabu en la programación si no programas en Java, Python, .NET o algún lenguaje relativamente popular, me ha pasado que me han preguntado:<br />
<br />
"¿En que lenguaje programás?"<br />
<br />
yo les dijo:<br />
<br />
"Yo programo en Autoit, Vb6 y Pauscal, a veces."<br />
<br />
Y ni saben que es, aunque ese no es el problema, nunca falta el cabeza que me dice:<br />
<br />
"Ah, entonces vos no programás."<br />
<br />
Cuando de hecho yo se hacer mas cosas con AutoIT que el (o ellos) en C Sharp, Python y PHP combinados.<br />
<br />
Pero bueno, la trama no es esa, el chiste aca es recibir consejos para programar mejor. Les informo que estos consejos se aplican a CUALQUIER LENGUAJE de programación existente.<br />
<br />
Comencemos.<br />
<br />
<span style="color: #3d85c6; font-size: x-large;">1 - Comentarios</span><br />
Para los que no creen que los comentarios son importantes, es porque nunca se encontraron con un proyecto real.<br />
<br />
Como sabemos, los comentarios son palabras que el compilador ignora y que nos sirven para poder entender mejor el código, nada mas util si se trabaja con código de terceros.<br />
<br />
Es recomendable comentar lo mas que se pueda el código con la definición mas humana posible, para mejores resultados, es bueno agregar etiquetas a los comentarios.<br />
<br />
<span style="background-color: white;"></span><br />
<ul style="font-family: inherit; line-height: 22px;"><span style="background-color: white;">
<li><span style="font-family: inherit;">FIXME: para marcar código problemático potencial que requiere una atención especial y/o revisión.</span></li>
<li><span style="font-family: inherit;">NOTE: peligros potenciales para documentar el funcionamiento interno del código y de indicar.</span></li>
<li><span style="font-family: inherit;">TODO: para indicar las mejoras planificadas.</span></li>
<li><span style="font-family: inherit;">XXX: para advertir a otros programadores de código problemático o equivoco.</span></li>
</span></ul>
<span style="background-color: white;">
</span>
<br />
<div style="font-family: inherit; line-height: 22px;">
<span style="background-color: white;">Aunque no me las se de memoria, estas etiquetas las e visto en código de Pauscal (obviamente codeadas por otra persona) y me ha sido de utilidad.</span></div>
<span style="background-color: white;">
</span>
<div style="font-family: inherit; line-height: 22px;">
<span style="background-color: white;"><br /></span></div>
<span style="background-color: white;">
<div style="font-family: inherit; line-height: 22px;">
<span style="color: #3d85c6; font-family: ''; font-size: x-large; line-height: normal;">2 - Funciones</span></div>
<div style="font-family: inherit; line-height: 22px;">
<span style="font-family: ''; line-height: normal;">Un error comun para muchos es llamar multiples veces una función que devuelve un mismo resultado, este error es bastante importante y es cometido mas que nada por los programadores novatos o con poca experiencia, relentiza la velocidad del programa (ya que invoca rutinas pre-programadas multiples veces) y es totalmente innecesario.</span></div>
<div style="font-family: inherit; line-height: 22px;">
<span style="font-family: ''; line-height: normal;"><br /></span></div>
<div style="font-family: inherit;">
Lo mejor que puedes hacer (con funciones que sabes que devolveran el mismo valor no importa cuantas veces la llames) es almacenar el valor de la función en una variable de su tipo y utilizar esta variable, tal vez no notes cambios visibles, pero tu procesador te lo agradecera.</div>
<div style="font-family: inherit;">
<br /></div>
<div style="font-family: inherit;">
Un código de ejemplo que muestra el mal habito de un programador, esta función convierte una cadena binaria en su valor octal.</div>
<div style="font-family: inherit;">
<br /></div>
<div>
<div>
<span style="color: blue;"><b>Function</b></span> BinToOct(BinNum <b><span style="color: blue;">As String</span></b>)<b><span style="color: blue;"> As String</span></b></div>
<div>
<b><span style="color: blue;">Dim</span></b> BinLen<b><span style="color: blue;"> As Integer</span></b>, i<b><span style="color: blue;"> As Integer</span></b></div>
<div>
<b><span style="color: blue;">Dim</span></b> OctNum<b><span style="color: blue;"> As Variant</span></b></div>
<div>
<b><span style="color: blue;">On Error GoTo</span></b> ErrorHandler</div>
<div>
BinLen = Len(BinNum)</div>
<div>
<b><span style="color: blue;">For</span></b> i = BinLen <b><span style="color: blue;">To</span></b> 1 <b><span style="color: blue;">Step</span></b> -1</div>
<div>
<span style="color: #38761d;">' Check the string for invalid characters</span></div>
<div>
<b><span style="color: blue;">If</span></b> Asc(Mid(BinNum, i, 1)) < 48 <span style="color: blue;"><b>Or</b></span> Asc(Mid(BinNum, i, 1)) > 49 <b><span style="color: blue;">Then </span><span style="color: #38761d;">' < ERROR</span></b></div>
<div>
OctNum = <span style="color: #666666;">""</span></div>
<div>
Err.Raise 1002, <span style="color: #666666;">"BinToOct"</span>,<span style="color: #666666;"> "Invalid Input"</span></div>
<div>
<span style="color: blue;"><b>End If</b></span></div>
<div>
<span style="color: #38761d;">' Calculate Octal value of BinNum</span></div>
<div>
<b><span style="color: blue;">If</span></b> Mid(BinNum, i, 1) <span style="color: blue;"><b>And</b></span> 1 <b><span style="color: blue;">Then</span></b></div>
<div>
OctNum = OctNum + 2 ^ Abs(i - BinLen)</div>
<div>
<b><span style="color: blue;">End If</span></b></div>
<div>
<b><span style="color: blue;">Next</span></b> i</div>
<div>
<span style="color: #38761d;">' Return OctNum as String</span></div>
<div>
BinToOct = Oct(OctNum)</div>
<div>
ErrorHandler:</div>
<div>
<b><span style="color: blue;">End Function</span></b></div>
</div>
<div>
<br /></div>
<div>
Como se puede apreciar, el programador de este código (no, no fui yo) utilizo dos veces la misma sentencia "<span style="font-family: '';">Asc(Mid(BinNum, i, 1))". ¿No conoce las variables? pff...</span></div>
<div>
<span style="font-family: '';"><br /></span></div>
<div>
<span style="color: #3d85c6; font-family: ''; font-size: x-large;">3 - Tabulaciones</span></div>
<div>
<span style="font-family: '';">Por fin llegamos a mi parte favorita, las tabulaciones, estas son tan importantes en mi código como el mismísimo código.</span></div>
<div>
<span style="font-family: '';"><br /></span></div>
<div>
<span style="font-family: '';">No son solo para que el código se vea mejor, nos hace diferenciar las instrucciones (por ejemplo) de dentro de un procedimiento a las de afuera de este, ocupan menos memoria ROM (¿a poco no es mejor usar tabulaciones que 6 espacios normales? por favor... son 5 bytes ahorrados...) y son mas estéticamente correctas.</span></div>
<div>
<span style="font-family: '';"><br /></span></div>
<div>
En el ejemplo anterior les mostre un código de Visual Basic 6.0 sin tabular.</div>
<div>
<br /></div>
<div>
<div style="font-family: '';">
<span style="color: blue;"><b>Function</b></span> BinToOct(BinNum <b><span style="color: blue;">As String</span></b>)<b><span style="color: blue;"> As String</span></b></div>
<div>
<span style="font-family: '';"><span style="white-space: pre;"> </span><span style="color: blue; font-weight: bold;">Dim</span></span> BinLen<b style="font-family: '';"><span style="color: blue;"> As Integer</span></b>, i<b style="font-family: '';"><span style="color: blue;"> As Integer</span></b></div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><b style="font-family: '';"><span style="color: blue;">Dim</span></b> OctNum<b style="font-family: '';"><span style="color: blue;"> As Variant</span></b></div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><b style="font-family: '';"><span style="color: blue;">On Error GoTo</span></b> ErrorHandler</div>
<div>
<span style="font-family: ''; white-space: pre;"> </span>BinLen = Len(BinNum)</div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><b style="font-family: '';"><span style="color: blue;">For</span></b> i = BinLen <b style="font-family: '';"><span style="color: blue;">To</span></b> 1 <b style="font-family: '';"><span style="color: blue;">Step</span></b> -1</div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"><span style="color: #38761d;">'</span></span><span style="color: #38761d; font-family: '';">Check the string for invalid characters</span></div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span><b style="font-family: '';"><span style="color: blue;">If</span></b> Asc(Mid(BinNum, i, 1)) < 48 <span style="color: blue; font-family: '';"><b>Or</b></span> Asc(Mid(BinNum, i, 1)) > 49 <b style="font-family: '';"><span style="color: blue;">Then </span><span style="color: #38761d;">' < ERROR</span></b></div>
<div>
<span class="Apple-tab-span" style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span>OctNum = <span style="color: #666666; font-family: '';">""</span></div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span>Err.Raise 1002, <span style="color: #666666; font-family: '';">"BinToOct"</span>,<span style="color: #666666; font-family: '';"> "Invalid Input"</span></div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span><b style="color: blue; font-family: '';">End If</b></div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"><span style="color: #38761d;">'</span></span><span style="color: #38761d; font-family: '';">Calculate Octal value of BinNum</span></div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span><b style="font-family: '';"><span style="color: blue;">If</span></b> Mid(BinNum, i, 1) <span style="color: blue; font-family: '';"><b>And</b></span> 1 <b style="font-family: '';"><span style="color: blue;">Then</span></b></div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span>OctNum = OctNum + 2 ^ Abs(i - BinLen)</div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><span style="font-family: ''; white-space: pre;"> </span><b style="font-family: '';"><span style="color: blue;">End If</span></b></div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><b style="font-family: '';"><span style="color: blue;">Next</span></b> i</div>
<div>
<span style="font-family: ''; white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"><span style="color: #38761d;">'</span></span><span style="color: #38761d; font-family: '';">Return OctNum as String</span></div>
<div>
<span style="font-family: ''; white-space: pre;"> </span>BinToOct = Oct(OctNum)</div>
<div>
<span style="font-family: ''; white-space: pre;"> </span>ErrorHandler:</div>
<div style="font-family: '';">
<b><span style="color: blue;">End Function</span></b></div>
</div>
<div style="font-family: '';">
<b><span style="color: blue;"><br /></span></b></div>
<div style="font-family: '';">
¿No les parece mas bonito?</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<span style="color: #3d85c6; font-family: ''; font-size: x-large;">4 - Parametros</span></div>
<div style="font-family: '';">
Los parámetros son general mente pasados por valor (se crea una copia en la función o procedimiento con el mismo valor), esto puede ser conveniente aveces, pero si no vas a modificar el parámetro en ningún aspecto, no olvides pasarlos por referencia para evitarle al compilador tener que crear la copia a la variable parámetro.<br />
<br />
<span style="color: #3d85c6; font-family: ''; font-size: x-large;">5 - POO</span><br />
<span style="font-family: '';">La programación orientada a objetos es muy util, pero muchas personas se vuelven "adictas" a este paradigma, imaginense a alguien que haga una función unica pero dentro de una clase, ¿que chiste tiene?. </span><span style="font-family: '';">Siempre que sea posible evita utilizar POO, ya que añade código innecesario y por lo tanto, reduce el rendimiento de tus aplicaciones, la programación orientada a objetos es utilizada para encerrar procedimientos en una tematica en particular, como una clase llamada "SO" que administre el sistema operativo, pero si programás en C# o Java, lamentablemente este tip no te sirve.</span><br />
<span style="font-family: '';"><br /></span>
<b>¡Saludos!</b></div>
</span>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-20830187740685051172015-07-07T02:08:00.001-07:002015-07-07T02:08:56.460-07:00Tipo de dato VarianteEn algunos lenguajes de programación el tipo de dato Variante no existe, no es como si todos supieran programar en Python ¿verdad?, pero en lenguajes como Visual Basic este tipo de dato es tan comun como la estructura "if", entonces, ¿que hay detras de este tipo de dato?.<br />
<br />
Yo recuerdo que pensaba que este tipo de dato era una simple unión (para los que no saben que es una unión, vease: <a href="https://es.wikipedia.org/wiki/Uni%C3%B3n_de_datos" target="_blank">Unión</a>) de todos los datos existentes, pero es algo un poquitito mas complicado, veamos.<br />
<br />
En el mundo real, este tipo de dato puede ser declarado como una estructura con tres miembros de tipo entero (int - integer).<br />
<br />
<ol>
<li>Tipo - El tipo de dato que contendra la variante .</li>
<li>Reservado - Este miembro debe ser cero.</li>
<li>Ptr - Este miembro debe contener la dirección del dato.</li>
</ol>
<div>
El primer miembro puede contener uno de los siguientes valores.</div>
<br />
<table class="wikitable" style="background-color: #f9f9f9; border-collapse: collapse; border: 1px solid rgb(170, 170, 170); color: black; font-family: sans-serif; font-size: 14px; line-height: 22px; margin: 1em 0px;"><tbody>
<tr><th style="background-color: #f2f2f2; border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em; text-align: center;">Tipo de variable</th><th style="background-color: #f2f2f2; border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em; text-align: center;">Bytes de datos</th><th style="background-color: #f2f2f2; border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em; text-align: center;">Tipo C/C++</th><th style="background-color: #f2f2f2; border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em; text-align: center;">Nombre de tipo</th></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">0</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;"></td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;"></td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Limpio<sup style="line-height: 1em;">1</sup></td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">1</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;"></td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;"></td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Nulo<sup style="line-height: 1em;">2</sup></td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">10</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">2A000A80</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">HRESULT (long int)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Error</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">10</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">80020004</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">HRESULT (long int)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;"><i>Missing</i><sup style="line-height: 1em;">3</sup></td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">17</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">2A</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">BYTE (unsigned char)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Byte</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">11</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">FFFF</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">VARIANT_BOOL (short int)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Booleano</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">2</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">2A00</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">short int</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Entero</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">3</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">2A000000</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">long int</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Largo</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">4</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">00002842</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">float</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Real</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">5</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">0000000000004540</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">double</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Doble</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">6</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">A068060000000000</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">CY Estructura</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Decimal</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">7</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">00000000C0D5E140</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">DATE (double)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Dato</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">8</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">xxxxxxxx</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">BSTR (<a class="new" href="https://es.wikipedia.org/w/index.php?title=Wide_character&action=edit&redlink=1" style="background-image: none; background-position: initial initial; background-repeat: initial initial; color: #a55858; text-decoration: none;" title="Wide character (aún no redactado)">wchar_t</a> pointer)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Cadena</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">9</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">00000000</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Puntero <a href="https://es.wikipedia.org/wiki/IUnknown" style="background-image: none; background-position: initial initial; background-repeat: initial initial; color: #0b0080; text-decoration: none;" title="IUnknown">IUnknown</a></td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Nada<sup style="line-height: 1em;">4</sup></td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">9</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">xxxxxxxx</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Puntero IUnknown</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;"><i>Referencia a objeto</i><sup style="line-height: 1em;">5</sup></td></tr>
</tbody></table>
<div>
</div>
<br />
<div>
Muy simple, probemor escribir el código.</div>
<div>
<br /></div>
<div>
<b><span style="color: purple;">Estruc</span></b> Variante,_</div>
<div>
Tipo:<b><span style="color: purple;">Entero</span></b>,_</div>
<div>
Reservado:<b><span style="color: purple;">Entero</span></b>,_</div>
<div>
Ptr:<b><span style="color: purple;">Entero</span></b></div>
<div>
<br /></div>
<div>
Supongamos lo siguiene, en Visual Basic por <b>X </b>motivo necesitamos utilizar un procedimiento de una DLL externa que NOSOTROS programamos, y por <b>X </b>motivo el primer parametro debe ser si o si variante, ¿como choclo hago?.</div>
<div>
<br /></div>
<div>
Pues muy facil, veamos el código de Visual Basic.</div>
<div>
<br /></div>
<div>
<b><span style="color: #3d85c6;">Private declare function</span></b> Mensaje <b><span style="color: #3d85c6;">lib</span></b> <span style="color: #666666;">"MiDLL.dll"</span> (Parametro1 <span style="color: #3d85c6;"><b>as</b></span> <span style="color: #3d85c6;"><b>Variant</b></span>)</div>
<div>
<br /></div>
<div>
<b><span style="color: #3d85c6;">Sub</span></b> Form_Load()</div>
<div>
Mensaje <span style="color: #666666;">"Hola Mundo!"</span> <span style="color: #38761d;">' Llamamos al procedimiento de nuestra DLL.</span></div>
<div>
<b><span style="color: #3d85c6;">End Sub</span></b></div>
<div>
<b><span style="color: #3d85c6;"><br /></span></b></div>
<div>
Entonces el código de la DLL seria el siguiente.</div>
<div>
<br /></div>
<div>
<b><span style="color: purple;">Importar</span></b> <span style="color: #666666;">"Cadena.prp"</span></div>
<div>
<span style="color: #38761d;">' API</span></div>
<div>
<b><span style="color: purple;">Proc</span></b> MessageBox(hWnd:<b><span style="color: purple;">Entero</span></b>,<span style="color: purple; font-weight: bold;">Referencia </span>Texto,Título:<b><span style="color: purple;">Cadena</span></b>,Bandera:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b>,<span style="color: #666666;">"User32" "MessageBoxA"</span></div>
<div>
<br /></div>
<br />
<div style="font-family: '';">
<b><span style="color: purple;">Estruc</span></b> Variante,_</div>
<div>
<div style="font-family: '';">
Tipo:<b><span style="color: purple;">Entero</span></b>,_</div>
<div style="font-family: '';">
Reservado:<b><span style="color: purple;">Entero</span></b>,_</div>
<div style="font-family: '';">
Ptr:<b><span style="color: purple;">Entero</span></b></div>
</div>
<div style="font-family: '';">
<b style="color: purple;"><br /></b></div>
<div style="font-family: '';">
<b style="color: purple;">Proc </b>Mensaje(Parametro1:Variante) <b><span style="color: purple;">Exportar</span></b></div>
<div style="font-family: '';">
<b><span style="color: purple;">Seleccionar</span></b> Parametro1.Tipo<span style="color: #38761d;"> ' Seleccionamos el tipo devuelto por la llamada de VB.</span></div>
<div style="font-family: '';">
<span style="color: purple;"><b>Caso</b></span> <span style="color: #990000;">8</span> <span style="color: #38761d;">' Si el tipo del dato variante es una cadena (vease la tabla anterior).</span></div>
<div style="font-family: '';">
MessageBox(<span style="color: #990000;">0</span>,CadDePtr(Parametro1.Ptr),<span style="color: #666666;">"Título!"</span>,<span style="color: #990000;">48</span>) <span style="color: #38761d;">' Mostrar el contenido obtenido de Ptr miembro.</span></div>
<div style="font-family: '';">
<b><span style="color: purple;"> Caso Otro</span></b></div>
<div style="font-family: '';">
<b><span style="color: purple;"> Salir</span></b></div>
<div style="font-family: '';">
<span style="color: purple;"><b>FinSeleccionar</b></span></div>
<div style="font-family: '';">
<b><span style="color: purple;">FinProc</span></b></div>
<div style="font-family: '';">
<b><span style="color: purple;"><br /></span></b></div>
<div style="font-family: '';">
Saludos!</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-12260349656549411942015-07-07T01:25:00.002-07:002015-07-08T18:47:59.331-07:00Crear Interfaces COM y usarlas<div>
Todos sabemos lo que es COM (o también conocido como OLE/ActiveX), pero si no lo sabes puedes pasarte por: <a href="https://es.wikipedia.org/wiki/Component_Object_Model" target="_blank">COM</a>.</div>
<div>
<br /></div>
Hoy les voy a enseñar a como crear Interfaces COM, pero no con simples marcos ("Interfase Nombre, Metodo1,Metodo2[,Metodo3 ...]") como es hoy en día en la mayoría de los lenguajes de programación, que en realidad ocultan el verdadero diseño de la tecnología COM de Microsoft.<br />
<span style="font-family: '';">Hoy les voy a crear verdaderas y nativas interfaces para utilizarlas en sus objetos COM.</span><br />
<br />
Este manual esta pensado para aquellos programadores que le gustan los lenguajes basados en prototipos.<br />
¿Clonación de objetos mediante instancias? ¿Quien necesita eso?<br />
<br />
<div>
Bien, para este manual voy a utilizar el lenguaje de programación <a href="http://www.pauscal.com.ar/" target="_blank">Pauscal</a> debido a su simplicidad, su increíble potencia y su alta semejanza al pseudo-código, aunque no lo conozcan, seguro se les va a hacer muy simple entender lo que se trata de realizar, de todas formas voy a tratar de comentar y comentar el código lo mas posible, también les informo que yo uso exclusivamente Windows.</div>
<div>
<br /></div>
<div>
Antes que nada, el manual da por entendido que usted (o ustedes) tiene conocimientos sobre estructuras, tipos de datos, prototipos, clases (POO), punteros y obviamente interfaces (si... con marcos...), si no es así... te recomiendo que empieces a aprender a programar.<br />
<br />
También les informo que si ustedes tienen bastos conocimientos sobre los temas recién mencionados, pueden saltar hacia el final del manual, donde habrá un resumen sobre lo que son interfaces COM.<br />
<br />
También les dejo una lista de los tipos de datos del lenguaje, por si tienen dudas sobre su alcance.<br />
<table class="wikitable" style="background-color: #f9f9f9; border-collapse: collapse; border: 1px solid rgb(170, 170, 170); color: black; font-family: sans-serif; font-size: 14px; line-height: 22px; margin: 1em 0px;"><tbody>
<tr><th style="background-color: #f2f2f2; border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em; text-align: center;">Nombre</th><th style="background-color: #f2f2f2; border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em; text-align: center;">Memoria requerida</th><th style="background-color: #f2f2f2; border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em; text-align: center;">Rango</th><th style="background-color: #f2f2f2; border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em; text-align: center;">Descripción</th></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Booleano</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">1 byte (8 Bits)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Verdad - Falso</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">1 - 0</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Byte</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">1 byte (8 Bits)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">0 - 255</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Byte sin signo.</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">ByteSig</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">1 byte (8 Bits)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">(-128) - 127</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Byte con signo.</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Word</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">2 byte (16 Bits)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">0 - 65.535</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Word sin signo.</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">WordSig</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">2 byte (16 Bits)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">(-32768) - 32767</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Word con signo.</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Entero</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">4 byte (32 Bits)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">0 - 4.294.967.295</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Entero sin signo.</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">EnteroSig</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">4 byte (32 Bits)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">(-2.147.483.648) - 2.147.483.647</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Entero con signo.</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Real</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">8 byte (64 Bits)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">(-1,79769313486232^308) - (-4.94065645841247^-324)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Número con coma flotante de doble precisión</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Decimal</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">8 byte (64 Bits)</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">(-922.337.203.685.477,5800) - 922.337.203.685.477,5800</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Número con coma fija de 4 decimales.</td></tr>
<tr><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Cadena</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Variable</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">0 ~ 2.000 millones de caracteres</td><td style="border: 1px solid rgb(170, 170, 170); padding: 0.2em 0.4em;">Cadena caracteres alfanumérica.</td></tr>
</tbody></table>
<br />
Para aprender a crear una interfase, tenemos que conocer una estructura.<br />
Una estructura esta conformada por un identificador, y el identificador de sus miembros. Por ejemplo:<br />
<br />
<b><span style="color: purple;">Estruc</span></b> Estructura, _<br />
Miembro1:<span style="color: purple;"><b>Entero</b></span><br />
Miembro2:<span style="color: purple;"><b>Cadena</b></span><br />
<span style="color: purple;"><b><br /></b></span>
Estas son general mente declaradas en una variable de tipo (digo "de tipo" cuando el tipo de dato es diferente a los nativos, también puede ser llamado "tipo de dato compuesto" obviamente "compuesto" por diferentes tipos de datos ¿se entiende?). Por ejemplo:<br />
<br />
<div style="font-family: '';">
<b><span style="color: purple;">Estruc</span></b> Estructura, _</div>
<div style="font-family: '';">
Miembro1:<span style="color: purple;"><b>Entero</b></span></div>
<div style="font-family: '';">
Miembro2:<span style="color: purple;"><b>Cadena</b></span></div>
<div style="font-family: '';">
<span style="color: purple;"><b><br /></b></span></div>
<b><span style="color: purple;">Var</span></b> Variable:Estructura<br />
<b><br /></b>
Y se puede acceder a sus miembros (general mente) escribiéndolos antes de un punto. Por ejemplo:<br />
<br />
Variable.Miembro <span style="color: #38761d;">' Hola, soy un comentario.</span><br />
<span style="color: #6fa8dc;"><br /></span>
Para los que conozcan POO (Programación Orientada a Objetos) se les hará conocido, algo que comienza con "P" y termina con "ropiedad", a estas propiedades se les puede escribir y leer valores, lo mismo pasa con un miembro de una estructura.<br />
<br />
¿Pero esto como nos ayuda a crear interfaces? Una interfase es en realidad una estructura. Ya me imagino lo que ustedes deben estar pensando.<br />
<br />
<span style="color: #444444;">"Pero yo vi que en C++ una interfase se declara como una clase con métodos virtuales."</span><br />
<span style="color: #444444;">"Vos no sabes nada, seguro sos un nerd envidioso! ¿Cuantos programas tenes?"</span><br />
<br />
En C++, es posible declarar una clase con métodos virtuales que es utilizado para crear objetos COM, pero esta clase es en realidad un marco, una mascara del código real, esa clase es en realidad una estructura con prototipos (en caso de C++, puntero a prototipos) y variables (de milagro no puntero a variables...).<br />
<br />
Bueno, ya que aclaramos que es una estructura y su semejanza a las clases, aclaremos lo que es un prototipo.<br />
Un prototipo vendría a ser la "cara" de un procedimiento que aún no existe. Un ejemplo de prototipo puede ser:<br />
<br />
<b><span style="color: purple;">Prototipo</span></b> Ejemplo(Argumento1:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Byte</span></b><br />
<br />
¿Les recuerda algo? Sí, se parece a un procedimiento sin terminar. Un prototipo no tiene código y solo puede ser utilizado si le asignamos una dirección en memoria que contenga código compatible.<br />
<br />
¿Sabias que los miembros de una estructura pueden ser de tipo prototipo? Sí, significa que "en teoría" (es una realidad, pero teoría para ustedes) un miembro de una estructura podría ejecutar código funcional sin problema alguno.<br />
<br />
Un ejemplo de estructura con miembros de prototipo es el siguiente.<br />
<br />
<b style="font-family: '';"><span style="color: purple;">Prototipo</span></b><span style="font-family: '';"> Ejemplo(Argumento1:</span><b style="font-family: '';"><span style="color: purple;">Cadena</span></b><span style="font-family: '';">):<span style="color: purple;"><b>Entero</b></span></span><br />
<b style="font-family: '';"><span style="color: purple;"><br /></span></b>
<b><span style="color: purple;">Estruc</span></b> Estructura,_<br />
MetodoSimulado:Ejemplo,_<br />
SimpleMiembro:<b><span style="color: purple;">Entero</span></b><br />
<br />
<b style="font-family: '';"><span style="color: purple;">Var</span></b><span style="font-family: '';"> Variable:</span><span style="font-family: '';">Estructura</span><br />
<span style="font-family: '';"><br /></span>
<span style="font-family: '';"><span style="color: #38761d;">' Variable.MetodoSimulado("Hola Mundo!") ' Produce error.</span></span><br />
<span style="font-family: '';"><br /></span>
Si quisieramos utilizar el método de esta estructura, obtendríamos el típico error de Pauscal (Error al acceder en memoria) esto es debido a que nuestro miembro de prototipo apunta hacia 0, hacia nada.<br />
<br />
Para hacer que el método funcione (un miembro de tipo prototipo se dominaría "método" en una clase normal), debemos hacer que apunte hacia algo, en este caso, cambiare los argumentos del prototipo y haré que apunte hacia la API (IPA en español) MessageBox.<br />
<br />
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;">Prototipo</span></b><span style="font-family: '';"> Ejemplo(hWnd,lpText,lpCaption,uType:<span style="color: purple;"><b>Entero</b></span></span><span style="font-family: '';">):<span style="color: purple;"><b>Entero</b></span></span></div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;"><br /></span></b></div>
<div style="font-family: '';">
<b><span style="color: purple;">Estruc</span></b> Estructura,_</div>
<div style="font-family: '';">
MetodoSimulado:Ejemplo,_</div>
<div style="font-family: '';">
SimpleMiembro:<b><span style="color: purple;">Entero</span></b></div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;">Var</span></b><span style="font-family: '';"> Variable:</span><span style="font-family: '';">Estructura</span></div>
<div style="font-family: '';">
<span style="font-family: '';"><br /></span></div>
<div style="font-family: '';">
<span style="font-family: '';">Variable.MetodoSimulado<b><span style="color: #0b5394;">@</span></b> = MessageBox<b><span style="color: #0b5394;">@</span></b></span></div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
Si desconocen esos arrobas, significa que estamos estableciendo la dirección de "MetodoSimulado" la dirección de "MessageBox".</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
Ahora si podemos utilizar el metodo y sera totalmente funcional.</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;">Prototipo</span></b><span style="font-family: '';"> Ejemplo(hWnd,lpText,lpCaption,uType:<span style="color: purple;"><b>Entero</b></span></span><span style="font-family: '';">):<span style="color: purple;"><b>Entero</b></span></span></div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;"><br /></span></b></div>
<div style="font-family: '';">
<b><span style="color: purple;">Estruc</span></b> Estructura,_</div>
<div style="font-family: '';">
MetodoSimulado:Ejemplo,_</div>
<div style="font-family: '';">
SimpleMiembro:<b><span style="color: purple;">Entero</span></b></div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;">Var</span></b><span style="font-family: '';"> Variable:</span><span style="font-family: '';">Estructura</span></div>
<div style="font-family: '';">
<span style="font-family: '';"><span style="color: #38761d;">' Utilizamos "CadPtr" para obtener un puntero a la cadena.</span></span></div>
<div style="font-family: '';">
<span style="font-family: '';">Variable.MetodoSimulado(<span style="color: #990000;">0</span>,CadPtr(<span style="color: #666666;">"Hola!"</span>),CadPtr(<span style="color: #666666;">"Soy un título!"</span>),<span style="color: #990000;">48</span>)</span></div>
<div style="font-family: '';">
<span style="font-family: '';"><br /></span></div>
<div>
<div style="font-family: '';">
<span style="font-family: '';">Este es solo un ejemplo de como podemos utilizar un prototipo en una estructura y ejecutar código 100% funcional, pero cada método y propiedad de un objeto real (creado de una interfase COM) necesita acceder a sus miembros. Para ello, a cada prototipo hay que agregarle un parámetro adicional que se utiliza para obtener el puntero al objeto, este parámetro general mente es el primero.</span></div>
<div style="font-family: '';">
<span style="font-family: '';"><br /></span></div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;">Prototipo</span></b><span style="font-family: '';"> Ejemplo(PtrAEstructura,Parametro1,Parametro2:<span style="color: purple;"><b>Entero</b></span></span><span style="font-family: '';">):<span style="color: purple;"><b>Entero</b></span></span></div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;"><br /></span></b></div>
<div style="font-family: '';">
<b><span style="color: purple;">Estruc</span></b> Estructura,_</div>
<div style="font-family: '';">
MetodoSimulado:Ejemplo,_</div>
<div style="font-family: '';">
SimpleMiembro:<b><span style="color: purple;">Entero</span></b></div>
<div style="font-family: '';">
<br /></div>
<div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;">Var</span></b><span style="font-family: '';"> Variable:</span><span style="font-family: '';">Estructura</span></div>
<div style="font-family: '';">
<span style="font-family: '';"><br /></span></div>
<div style="font-family: '';">
Vamos a escribir un procedimiento que pueda obtener datos de los miembros de la estructura a través de un puntero a la estructura.</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<b><span style="color: purple;">Proc</span></b> ObtMiembro(PtrEstruc,Param1,Param2:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b></div>
<div style="font-family: '';">
<b><span style="color: purple;">Var</span></b> <b><span style="color: #0b5394;">@</span></b>RefAEstruct:Estructura<span style="color: #38761d;"> ' Creamos un puntero de referencia a la estructura.</span></div>
<div style="font-family: '';">
RefAEstruct<b><span style="color: #0b5394;">@</span></b> = PtrEstruc <span style="color: #38761d;">' Establecemos la dirección a la estructura obtenida del primer parámetro.</span></div>
<div style="font-family: '';">
<b><span style="color: purple;">Devolver</span></b> RefAEstruct.SimpleMiembro<span style="color: #38761d;"> ' Devolvemos el miembro "SimpleMiembro" de la estructura.</span></div>
<div style="font-family: '';">
<b><span style="color: purple;">FinProc</span></b></div>
<div style="font-family: '';">
<b><span style="color: purple;"><br /></span></b></div>
<div style="font-family: '';">
Ya tenemos el prototipo, entonces ¿Como lo usamos? obvio... al igual que con el ejemplo en el que aparece el MessageBox.</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<b><span style="color: purple;">Proc</span></b> ObtMiembro(PtrEstruc,Param1,Param2:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b></div>
<div style="font-family: '';">
<b><span style="color: purple;">Var</span></b> <b><span style="color: #0b5394;">@</span></b>RefAEstruct:Estructura<span style="color: #38761d;"> ' Creamos un puntero de referencia a la estructura.</span></div>
<div style="font-family: '';">
RefAEstruct<b><span style="color: #0b5394;">@</span></b> = PtrEstruc <span style="color: #38761d;">' Establecemos la dirección a la estructura obtenida del primer parámetro.</span></div>
<div style="font-family: '';">
<b><span style="color: purple;">Devolver</span></b> RefAEstruct.SimpleMiembro<span style="color: #38761d;"> ' Devolvemos el miembro "SimpleMiembro".</span></div>
<div style="font-family: '';">
<b><span style="color: purple;">FinProc</span></b></div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;">Prototipo</span></b><span style="font-family: '';"> Ejemplo(PtrAEstructura,Parametro1,Parametro2:<span style="color: purple;"><b>Entero</b></span></span><span style="font-family: '';">):<span style="color: purple;"><b>Entero</b></span></span></div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;"><br /></span></b></div>
<div style="font-family: '';">
<b><span style="color: purple;">Estruc</span></b> Estructura,_</div>
<div style="font-family: '';">
MetodoSimulado:Ejemplo,_</div>
<div style="font-family: '';">
SimpleMiembro:<b><span style="color: purple;">Entero</span></b></div>
<div style="font-family: '';">
<br /></div>
<div>
<div style="font-family: '';">
<b style="font-family: '';"><span style="color: purple;">Var</span></b><span style="font-family: '';"> Variable:</span><span style="font-family: '';">Estructura</span></div>
<div style="font-family: '';">
<span style="font-family: '';"><br /></span></div>
<div style="font-family: '';">
Variable.MetodoSimulado<span style="color: #0b5394;"><b>@</b></span> = ObtMiembro<b><span style="color: #0b5394;">@</span></b><span style="color: #38761d;"> ' Le establecemos <span style="font-family: '';">al prototipo</span><span style="font-family: '';"> la dirección del procedimiento.</span></span></div>
<div style="font-family: '';">
<span style="font-family: '';"><br /></span></div>
<div style="font-family: '';">
Variable.SimpleMiembro = <span style="color: #990000;">55</span></div>
<div style="font-family: '';">
<span style="color: #38761d;">' EntCad = Entero a Cadena, Estructura@ = Puntero de la estructura.</span></div>
<div style="font-family: '';">
Mensaje(EntCad(Variable.MetodoSimulado(Estructura<b><span style="color: #0b5394;">@</span></b>,<span style="color: #990000;">0</span>,<span style="color: #990000;">0</span>) )) <span style="color: #38761d;">' Los dos parámetros finales no son utilizados.</span></div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
En el ejemplo, el método "MetodoSimulado" devuelve 55 debido a que obtiene el valor de el miembro "SimpleMiembro" de la estructura establecida en el primer parámetro.</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
Este es el cuerpo de una interfase, es una estructura con prototipos que aceptan principal mente como primer parámetro un puntero a su mismo objeto.</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
Pero aún sigue sin ser una interfase funcional, mas adelante veremos porque.</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<span style="color: #444444; font-size: x-large;">GUID</span></div>
<div style="font-family: '';">
Un GUID (Identificador único global) es un termino utilizado por Microsoft para un número que su programación para crear una identidad única para una entidad; como un documento de Word. GUID son ampliamente utilizados en productos de Microsoft para identificar interfaces, conjuntos de replicas, registros y otros objetos. Diferentes tipos de objetos tienen diferentes tipos de GUID.</div>
<div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<span style="font-family: '';">Aparte de ser un termino, u</span>n GUID es una estructura que es rellenada con valores aleatorios y que identifican a un objeto.</div>
<div style="font-family: '';">
<br /></div>
<b><span style="color: purple;">Estruc</span></b> GUID,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> Data1:<b><span style="color: purple;">Entero</span></b>,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> Data2,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> Data3:<b><span style="color: purple;">Word</span></b>,_<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> Data4[<span style="color: #990000;">8</span>]:<span style="color: purple;"><b>Byte</b></span><br />
<br />
Para los que no conozcan los diferentes terminos de C++ sobre GUID, le mostrare una pequeña lista.<br />
<br />
<ul>
<li>REFIID - Referencia a estructura GUID.</li>
<li>IID - Estructura GUID.</li>
<li>CLSID - Estructura GUID.</li>
</ul>
</div>
<div style="font-family: '';">
Referencia: <a href="http://translate.google.com/translate?langpair=auto%7Ces&u=http://searchwindowsserver.techtarget.com/definition/GUID-global-unique-identifier" target="_blank">What is GUID</a></div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<span style="color: #444444; font-family: ''; font-size: x-large;">IUnknown</span></div>
<div style="font-family: '';">
IUnknown es la interface basica de todo objeto, cada objeto creado debe tener como mínimo esta interfase (sus métodos).</div>
<div style="font-family: '';">
Esta interfase consiste en tres métodos.</div>
<div style="font-family: '';">
</div>
<ul>
<li><b style="font-family: '';">QueryInterface</b></li>
<li><b style="font-family: '';">AddRef</b></li>
<li><b style="font-family: '';">Release</b></li>
</ul>
<div>
<span style="font-family: '';">Al igual que cualquier otra interface, se crea a partir de una estructura con prototipos y cada prototipo </span><br />
<span style="font-family: '';">requiere como primer parámetro el puntero a su objeto.</span></div>
<div>
<br />
Para mas información: <a href="https://es.wikipedia.org/wiki/IUnknown" target="_blank">IUnknown</a>.</div>
<div>
<br /></div>
<br />
<div style="font-family: '';">
<span style="color: #444444; font-size: x-large;">CoCreateInstance</span></div>
<div style="font-family: '';">
Para crear un objeto funcional, debemos obtener la dirección en memoria de tal objeto, y para esto utilizamos la API CoCreateInstance.</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
CoCreateInstance tiene la siguiente sintaxis (en C++).</div>
<pre style="font-family: Consolas, Courier, monospace !important; font-size: 14px; line-height: 20px; overflow: auto; padding: 5px; word-wrap: normal;">HRESULT CoCreateInstance(
_In_ REFCLSID rclsid,
_In_ LPUNKNOWN pUnkOuter,
_In_ DWORD dwClsContext,
_In_ REFIID riid,
_Out_ LPVOID *ppv
);</pre>
<div style="font-family: '';">
Aca podemos ver las innecesaria re-definiciones de los tipos de datos elementales del lenguaje.</div>
<div style="font-family: '';">
En Pauscal, esto es:</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
<b><span style="color: purple;">Proc</span></b> CoCreateInstance(<b><span style="color: purple;">Referencia</span></b> rclsid:GUID,_</div>
<div style="font-family: '';">
pUnkOuter:<b><span style="color: purple;">Entero</span></b>,_</div>
<div style="font-family: '';">
dwClsContext:<b><span style="color: purple;">Entero</span></b>,_</div>
<div style="font-family: '';">
<b><span style="color: purple;"> Referencia</span></b> riid:GUID,_</div>
<div style="font-family: '';">
ppv:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b>, <span style="color: #666666;">"Ole32.dll"</span></div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
Como se puede apreciar, REFCLSID y REFIID son referencias a la misma estructura (GUID), pero con diferente nombre (aunque el nombre es irrelevante, lo que cuenta son sus miembros).</div>
<div style="font-family: '';">
<br /></div>
<div style="font-family: '';">
A continuación, una descripción de los parámetros:</div>
<ol>
<li>rclsid - El CLSID (GUID) asociado con los datos y el código que se utilizarán para crear el objeto.</li>
<li>pUnkOuter - Indica que el objeto esta siendo creado como parte de un agregado.</li>
<li>dwClsConext - Contexto en el que el código se gestiona</li>
<li>riid - Una referencia al identificador de la interfaz que se utiliza para comunicarse con el objeto.</li>
<li>ppv - Dirección de la variable que recibe el puntero de la interfase solicitada en riid.</li>
</ol>
<div>
El parametro 1 y 5 son los que realmente nos importa.<br />
<br />
rclsid es el identificador de el objeto, no voy a entrar en como obtenerlo ya que este manual no enseña a utilizar llanamente la tecnología COM, solo voy a enseñar a crear Interfaces COM.<br />
<br />
El parámetro 5 es un puntero hacia una variable que contendrá el puntero. El puntero obtenido es un puntero hacia un puntero VTable (no un puntero hacia un puntero nulo como se dice en C++, eso no existe).<br />
<br />
¿Recuerdan cuando les dije que ustedes no habían aprendido a crear una interfase funcional?<br />
Me refería a esto.<br />
<br />
Ustedes aprendieron a crear VTables (Estructuras miembros de tipo prototipo). Una ejemplo-referencia de interfase es la siguiente.<br />
<br />
<b><span style="color: purple;">Prototipo</span></b> SoyUnPrototipo(PtrEstructura:<b><span style="color: purple;">Entero</span></b>,<b><span style="color: purple;">Opcional</span></b> Param1,Param2:<b><span style="color: purple;">Entero</span></b>):<span style="color: purple;"><b>Entero</b></span><br />
<br />
<b><span style="color: purple;">Estruc</span></b> Estructura,_<br />
Metodo1:SoyUnPrototipo<br />
<br />
<b><span style="color: purple;">Estruc</span></b> Interface,<b><span style="color: blue;">@</span></b>VTable:Estructura<br />
<br />
Una interfase real es una estructura que tiene como miembro un puntero a una VTable. Ahora les voy a mostrar un ejemplo real de interfase 100% real.<br />
<br />
<b><span style="color: purple;">Prototipo</span></b> pQueryInterface(<span style="font-family: '';">PtrEstruc</span>:<b><span style="color: purple;">Entero</span></b>,riid:GUID,ptrReturn:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b><br />
<b><span style="color: purple;">Prototipo</span></b> pAddRef(<span style="font-family: '';">PtrEstruc</span>:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b><br />
<b><span style="color: purple;">Prototipo</span></b> pRelease(<span style="font-family: '';">PtrEstruc</span>:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b><br />
<b><span style="color: purple;">Prototipo</span></b> pHrInit(PtrEstruc:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b><br />
<b><span style="color: purple;">Prototipo</span></b> pAddTab(<span style="font-family: '';">PtrEstruc</span>,<span style="font-family: '';">hWnd</span>:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b><br />
<b><span style="color: purple;">Prototipo</span></b> pDeleteTab(<span style="font-family: '';">PtrEstruc</span>,<span style="font-family: '';">hWnd</span>:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b><br />
<b><span style="color: purple;">Prototipo</span></b> pActivateTab(<span style="font-family: '';">PtrEstruc</span>,<span style="font-family: '';">hWnd</span>:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b><br />
<b><span style="color: purple;">Prototipo</span></b> pSetActivateAlt(<span style="font-family: '';">PtrEstruc</span>,hWnd:<b><span style="color: purple;">Entero</span></b>):<b><span style="color: purple;">Entero</span></b><br />
<br />
<b><span style="color: purple;">Estruc</span></b> pITaskbarList,_<br />
QueryInterface:pQueryInterface,_<br />
<span style="font-family: '';"> </span>AddRef:pAddRef,_<br />
<span style="font-family: '';"> </span>Release:pRelease,_<br />
<span style="font-family: '';"> </span>HrInit:pHrInit,_<br />
<span style="font-family: '';"> </span>AddTab:pAddTab,_<br />
<span style="font-family: '';"> </span>DeleteTab:pDeleteTab,_<br />
<span style="font-family: '';"> </span>ActivateTab:pActivateTab,_<br />
<span style="font-family: '';"> </span>SetActivateAlt:pSetActivateAlt<br />
<br />
<b><span style="color: purple;">Estruc</span></b> ITaskbarList,<b><span style="color: blue;">@</span></b>Ptr:pITaskbarList<br />
<br />
Como interfase, debe contener como mínimo la interface IUnknown incorporada en sus primeros tres miembros, de otra forma, no seria valida y no la podriamos usar.<br />
<br />
La CLSID de ITaskbarList es "{56FDF344-FD6D-11D0-958A-006097C9A090}", pueden convertir esta cadena a su correspondiente GUID estructura con la IPA <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms680589(v=vs.85).aspx" target="_blank">CLSIDFromString</a>.<br />
<br />
Ahora vamos a utilizar esta Interface (POR FIN!). Intenten seguir el siguiente código, despues se los explicare con detalle, les explico las funciones que voy a importar de la libreria "COM.prp".<br />
<br />
<ul>
<li>CadGUID - Convierte una cadena GUID valida en un GUID estructura.</li>
</ul>
<br />
<b><span style="color: purple;">Importar</span></b> <span style="color: #666666;">"COM.prp"</span><br />
<br />
<span style="color: #38761d;">' Constantes</span><br />
<b><span style="color: purple;">Const </span></b>CLSCTX_INPROC_SERVER = <span style="color: #990000;">&1</span><br />
<b><span style="color: purple;">Const</span></b> CLSCTX_INPROC_HANDLER = <span style="color: #990000;">&2</span><br />
<b><span style="color: purple;">Const</span></b> CLSCTX_LOCAL_SERVER = <span style="color: #990000;">&4</span><br />
<b><span style="color: purple;">Const</span></b> CLSCTX_REMOTE_SERVER =<span style="color: #990000;"> &10</span><br />
<b><span style="color: purple;">Const</span></b> CLSCTX_ALL = CLSCTX_INPROC_SERVER <b><span style="color: purple;">Or</span></b> CLSCTX_INPROC_HANDLER <b><span style="color: purple;">Or</span></b> CLSCTX_LOCAL_SERVER <b><span style="color: purple;">Or</span></b> CLSCTX_REMOTE_SERVER<br />
<div>
<br /></div>
<b><span style="color: purple;">Var</span></b> PtrObtener:<b><span style="color: purple;">Entero</span></b>,<b><span style="color: blue;">@</span></b>TaskbarList:ITaskbarList<br />
CoInitialize <span style="color: #38761d;">' Inicializamos COM.</span><br />
CoCreateInstance(_<br />
CadGUID(<span style="font-family: '';"><span style="color: #666666;">"{56FDF344-FD6D-11D0-958A-006097C9A090}"</span></span>),_ <span style="color: #38761d;">' GUID del objeto a obtener.</span><br />
0,_ <span style="color: #38761d;">' Este parametro es innecesario, se establece en nulo.</span><br />
CLSCTX_ALL,_ <span style="color: #38761d;">' Solamente pongan CLSCTX_ALL...</span><br />
CadGUID(<span style="color: #666666;">"{00000000-0000-0000-C000-000000000046}"</span>),_ <span style="color: #38761d;">' Este parametro es innecesario, pueden poner el IID de la interface IUnknown, pero generalmente cada objeto tiene su IID.</span><br />
PtrObtener<b><span style="color: blue;">@</span></b>) <span style="color: #38761d;">' Puntero a la variable de tipo entero.</span><br />
<br />
<b><span style="color: purple;">Si</span></b> PtrObtener <> <span style="color: #990000;">0</span> <b><span style="color: purple;">Entonces</span></b> TaskbarList<b><span style="color: blue;">@</span></b> = PtrObtener<br />
CoUninitialize <span style="color: #38761d;">' Finalizamos COM.</span><br />
<span style="color: #38761d;"><br /></span>
Primero, declaramos las constantes necesarias, creamos 2 variables. una de tipo entero (PtrObtener) que obtendra el puntero del objeto, y un puntero a la interface creada que podremos utilizar una vez le asignemos la dirección devuelta a PtrObtener por CoCreateInstance.<br />
<br />
Llamamos a la IPA, su primer parametro es una estructura GUID, utilizamos CadGUID para convertir la cadena a una estructura GUID, el segundo parametro es innecesario, lo establecemos nulo, el tercer parametro indica el contexto del objeto, es preferible establecer CLSCTX_ALL, el cuarto parametro es el IID del objeto, podemos establecer el IID de la interfase IUnknown, el quinto parametro es el puntero a la variable que obtendra la dirección del objeto (este objeto contiene aparte un puntero a la VTable), establecimos la dirección de PtrObtener.<br />
<br />
Una vez llamada la función (y suponiendo que no haya ocurrido ningún error) la IPA retornara 0, PtrObtener contendra el puntero al objeto y se lo asignamos a TaskbarList.<br />
<br />
Una vez hecho esto, el objeto esta creado y puede ser utilizado, pero recuerden establecer la dirección del objeto en el primer parametro de los metodos.<br />
<br />
Aunque ya lo explique muchas veces, seguro no recuerdan que en cada metodo hay que establecer el puntero al objeto; asique les voy a mostrar como usar un objeto.<br />
<br />
Taskbarlist.Ptr.HrInit(TaskbarList<b><span style="color: blue;">@</span></b>)<br />
Taskbarlist.Ptr.DeleteTab(TaskbarList<b><span style="color: blue;">@</span></b>,Formulario.hWnd) <span style="color: #38761d;">' Borra el icono de un formulario en la barra de tareas.</span><br />
<br />
No fue tan dificil ¿Verdad?</div>
</div>
</div>
</div>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-33058604346821956592015-06-28T20:39:00.000-07:002015-06-28T20:39:02.843-07:00StackOverflow para hispanosUna sección muy visitada por programadores/desarrolladores es StackOverflow, y es inevitable... esta lleno de preguntas que nos hacemos muy amenudo y respuestas tan buenas que te podrian sacar varias dudas de una sola lectura. El unico problema es que... esta en ingles.<br />
<br />
El gran problema de los programadores hispanos es que no sabemos hablar o leer en ingles, aunque esto no nos detiene, si nos molesta bastante (o al menos a mí), lo peor es que los que si aprendieron a hacer algo, no comparten sus conocimientos con la comunidad hispana.<br />
Pero bueno, dejando de lado a los traicioneros, una comunidad ha abierto sus puertas para todos los desarrolladores/programadores que quieran compartir sus conocimientos con otras personas menos experimentadas. Y se llama: <a href="http://entredesarrolladores.com/" target="_blank">Entre Desarrolladores</a> <span style="font-family: '';">(yo le hubiera puesto StackUnderflow)</span>.<br />
<br />
Si tienes alguna duda o sabes la respuesta de alguna cuestión, no dudes en entrar y aportar.<br />
<br />
Saludos!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-23850198537005137412015-06-28T20:14:00.002-07:002015-06-28T20:18:59.618-07:00Como usar ScintillaScintilla es un control de edición de texto avanzado, por lo que no es simple utilizarlo; tiene sus dificultades y defectos, pero es muy potente y util para programadores.<br />
<div>
<br /></div>
<div>
Con este control se han creado programas como SciTE, Eclipse, Notepad++ y muchisimos otros.</div>
<div>
<br /></div>
<div>
En esta entrada les voy a enseñar a como utilizar Scintilla, aunque sea de lo mas basico.</div>
<div>
Primero tenemos que descargar Scintilla (SciLexer.dll), desde aca: <a href="http://www.scintilla.org/" target="_blank">Scintilla Oficial</a></div>
<div>
<br /></div>
<div style="text-align: left;">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://img.prntscr.com/img?url=http://i.imgur.com/jPsJiec.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://img.prntscr.com/img?url=http://i.imgur.com/jPsJiec.png" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Esta DLL debe estar junto a nuestro proyecto.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Para utilizar el control hay que comenzar registrandolo, pero ¿como lo hago? pues muy facil. usando la API "LoadLibrary".</div>
<div style="text-align: left;">
<br />
<span style="background-color: #444444;">LoadLibrary(<span style="color: #eeeeee;">"SciLexer.dll"</span>)</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Y se registra automaticamente, si... por si solo.</div>
<div style="text-align: left;">
Ahora, vamos a crear el control Scintilla en el formulario, el ejemplo siguiente sera en el lenguaje de programación <a href="http://www.pauscal.com.ar/" target="_blank">Pauscal</a>.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="background-color: #444444;"><b><span style="color: magenta;">Var</span></b> X,Y,Width,Height,hWndPadre,Modulo,PtrControl:<span style="color: magenta;"><b>Entero</b></span></span></div>
<div style="text-align: left;">
<span style="background-color: #444444;">X = <span style="color: #3d85c6;">0</span> <span style="color: #6aa84f;">' Posición X</span></span></div>
<div style="text-align: left;">
<span style="background-color: #444444;">Y = <span style="color: #3d85c6;">0</span> <span style="color: #6aa84f;">' Posición Y</span></span></div>
<div style="text-align: left;">
<span style="background-color: #444444;">Width = <span style="color: #3d85c6;">400</span> <span style="color: #6aa84f;">' Ancho</span></span></div>
<div style="text-align: left;">
<span style="background-color: #444444;">Height = <span style="color: #3d85c6;">400</span> <span style="color: #6aa84f;">' Alto</span></span></div>
<div style="text-align: left;">
<span style="background-color: #444444;">hWndPadre = Padre.hWnd <span style="color: #6aa84f;">' Puntero a la ventana padre</span></span></div>
<div style="text-align: left;">
<span style="background-color: #444444;">Modulo = GetModuleHandle(<span style="color: #eeeeee;">""</span>) <span style="color: #6aa84f;">' Modulo del programa</span></span></div>
<div style="text-align: left;">
<span style="background-color: #444444;"><span style="font-family: '';">PtrControl = </span>CreateWindowEx(WS_EX_CLIENTEDGE,<span style="color: #eeeeee;">"Scintilla"</span>,<span style="color: #eeeeee;">"Texto de ejemplo >:("</span>,WS_CHILD+WS_VISIBLE,X,Y,Width,Height,hWndPadre,<span style="color: #3d85c6;">0</span>,Modulo,<span style="color: #3d85c6;">0</span>)</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Y listo, ya tienen su control Scintilla en su formulario.</div>
<div style="text-align: left;">
Ahora, quiero hacer que el control Scintilla haga algo, ¿Como hago? facil, utilizamos la siempre util y entretenida API "SendMessage", la lista completa de mensajes esta en la pagina oficia de este control, y se llama <a href="http://www.scintilla.org/ScintillaDoc.html" target="_blank">Scintilla Doc</a>.<br />
Un ejemplo simple envio de mensajes el siguiente.<br />
<br />
<span style="background-color: #444444;">SendMessage(PtrControl,SCI_CALLTIPSHOW,<span style="color: #3d85c6;">0</span>,CadPtr(<span style="color: #eeeeee;">"Hola Mundo!"</span>))</span><br />
<br />
Veran como se agrega una pequeña notificación con el mensaje "Hola Mundo!" en la linea número cero.<br />
Pueden la lista de mensajes completa de mi repositorio en <a href="https://github.com/DarkBlueZV/Pauscal-Libs/blob/master/ConstScintilla.bdp" target="_blank">GitHub</a>.<br />
<br />
Si se quedaron con "hambre" en esta entrada, por favor no duden en comentar.<br />
<br />
Saludos!</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-66605153377851876472014-12-20T21:33:00.001-08:002014-12-20T21:34:15.917-08:00Buguear MessageBoxABueno, hoy les traigo un interesante truco con la API MessageBox que encontré mientras testeaba un código.<br />
<br />
Se puede modificar la visualización del texto establecido en la API modificando su bandera con un valor mayor o menor (Max: 5 Min: 5) a 2737476.<br />
<br />
Por ejemplo.<br />
<br />
<code>MessageBoxA(0,"Título","Texto",2737476)</code>
<br />
<code><br /></code>
Supongamos que tenemos un mensaje tipico, un "Hola Mundo" por ejemplo.<br />
<br />
<code>Mensaje("Hola Mundo",,48)</code><br />
<code><br /></code>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/zH6FlMP.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/zH6FlMP.png" /></a></div>
Con el valor 2737476 se ve asi<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/0uY33Nr.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/0uY33Nr.png" height="160" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Lo interesante de este bug (y que me acabo de enterar) no es el cambio de visualización, Si No que no puede ser capturado por el capturador de imágenes FastStone Capture en modo Capture Window / Object, lo que sugiere una vulnerabilidad en captura de ventana.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Esto puede ser irrelevante para muchos, pero tal bug bien utilizado puede ser una buena herramienta para hackear de alguna u otra manera el ordenador de alguien.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Probado en Windows 7 Ultimate - Sp 1 - 32 Bits.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Un saludo!</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-45844181175327580762014-11-06T18:25:00.003-08:002014-12-20T21:34:35.495-08:00Manual de PauscalBueno, como bien dice el titulo, hice un manual para aprender a programar en Pauscal desde 0, si quieres leer este manual que es gratis solamente has clic en el siguiente enlace.<br />
<div>
<br /></div>
<div>
<a href="http://pauscalwiki-armon.rhcloud.com/index.php/Manual_de_Pauscal" target="_blank">Manual de Pauscal</a></div>
<div>
<br /></div>
<div>
Si tienes alguna pregunta, por favor no dudes en comentar o simplemente entrar al foro oficial del lenguaje en español.</div>
<div>
<br /></div>
<div>
<a href="http://www.pauscal.com.ar/foro" target="_blank">Pauscal</a></div>
<div>
<br /></div>
<div>
¡Saludos!</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-20897220642483469252014-10-24T16:19:00.001-07:002014-12-20T21:34:56.327-08:00Simular VarPtr con AutoitComo sabemos, AutoitScript es un lenguaje cuyas variables son de tipo Variante, no tienen un tipo de dato especifico, son representadas por el interprete, así que seria algo difícil obtener de alguna manera un puntero constante.<br />
<br />
Yo no se como funcione el interprete de Autoit, pero puedo imaginar que:<br />
<br />
1_ Son analizadas por primera vez como tipo de dato Cadena (Texto plano).<br />
2_ Si son de tipo numerico (Entero por ejemplo), Son almacenadas en una variable de tipo entero.<br />
3_ Vuelve al paso 1<br />
4_ Si sus valores cambian de tipo numerico a cadena, son almacenadas en otra variable de tipo cadena.<br />
<br />
esto puede ser complicado y hasta creo que me estoy llendo del tema principal, Asi que ire directo a la simulación de VarPtr.<br />
<br />
Con lo explicado anteriormente puedo decir, que no es muy posible obtener un puntero de una variable variante de Autoit, por lo que hay que utilizar estructuras.<br />
<br />
Se pueden declarar variables de tipos de datos nativos utilizando estructuras en Autoit (DllStructCreate).<br />
<br />
Observen el siguiente codigo.<br />
<br />
<code>$Estructura = DllStructCreate("int")</code><br />
<code><br /></code>
Acabamos de declarar una variable, esta dentro de una estructura pero puede ser utilizada de manera indiferente a cualquier otra variable.<br />
<br />
Modificaremos el código un poco ...<br />
<br />
<code>$Estructura = DllStructCreate("int;char[128]")</code><br />
<code><br /></code>
Ahora tenemos 2 variables de distintos tipos de datos nativos, Entero y Cadena. Podemos obtener el puntero individual de cada variable creada utilizando "DllStructGetPtr".<br />
<br />
<code>$Estructura = DllStructCreate("int;char[128]")<br />
$Ptr = DllStructGetPtr($Estructura,1)<br />
MsgBox(0,0,$Ptr)</code><br />
<code><br /></code>
¡Atención! El puntero obtenido es únicamente valido para Autoit (Formato binario: 0x000FFD3), pero puede ser convertido utilizando la función "Int".<br />
<br />
<code>$Estructura = DllStructCreate("int;char[128]")</code><br />
<code>$Ptr = DllStructGetPtr($Estructura,1)</code><br />
<code>MsgBox(0,0,Int($Ptr))</code>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-11424345939946863712014-10-24T15:53:00.002-07:002014-12-20T21:35:20.474-08:00Llamar librerias Pauscal desde AutoitBienvenidos, hoy le mostrare como crear librerías DLL en Pauscal y llamarlas desde el lenguaje de programación AutoitScript.<br />
<br />
Bien, Antes de comenzar les informo que tienen que saber lo básico de llamadas a dll en ambos lenguajes, "Proc" en Pauscal y "DllCall" en Autoit.<br />
<br />
Comenzamos abriendo el IDE de Pauscal y creando una nueva biblioteca.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/VB827Rd.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/VB827Rd.png" height="330" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Como ejemplo, exportaremos un simple procedimiento que muestre un mensaje en pantalla, Ingresamos el siguiente código.<br />
<br />
<code>Importar "Utiles.prp" ' Importamos la librería que contiene el procedimiento "Mensaje"<br />
<br />
Proc Msg(Contenido:Entero) Exportar ' Creamos un procedimiento, lo nombramos "Msg" y establecemos su primer parámetro como un Entero, finalmente Exportamos el procedimiento.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Mensaje(CadenaDePtrCad(Contenido)) ' Utilizamos el procedimiento "CadenaDePtrCad" para obtener la cadena desde el puntero que ingresa gracias a "DllCall" de Autoit.<br />
FinProc ' Fin procedimiento</code><br />
<code><br /></code>
Una vez escrito el código, lo compilamos cliqueando en el botón que esta a la izquierda del botón verde mas llamativo.<br />
<br />
Yo lo pondré en el escritorio y lo llamare "Dll".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/vyqXBBO.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/vyqXBBO.png" /></a></div>
<br />
Ahora creamos un Script de Autoit.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/Ws5y7EX.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/Ws5y7EX.png" /></a></div>
<br />
Lo abrimos con nuestro editor de texto de preferencia y le pegamos el siguiente código.<br />
<br />
<code>Dim $Var1</code><br />
<code>$Mensaje = "Mensaje"</code><br />
<code>$Var1 = DllCall("Dll.dll","none","Msg","str",$Mensaje)</code><br />
<code><br /></code>
<span style="font-family: monospace;">Seguramente los que ya hayan probado la función "DllCall" en Autoit se preguntaran:</span><br />
<span style="font-family: monospace;"><br /></span>
<span style="font-family: monospace;">"¿Por Que le establecemos el parámetro 1 de tipo "Str" si es para Cadenas</span><span style="font-family: monospace;">?"</span><br />
<span style="font-family: monospace;">"Ademas </span><span style="font-family: monospace;">en Pauscal le establecimos el parámetro 1 de tipo Entero que es numérico"</span><br />
<span style="font-family: monospace;"><br /></span>
<span style="font-family: monospace;">Lo que hace el tipo de dato "Str" en Autoit es enviar un puntero a la cadena, se puede apreciar esta realidad en la documentación del lenguaje.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/sMyuQpe.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/sMyuQpe.png" height="53" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span style="font-family: monospace;">Si no mal recuerdo, LPCSTR significa "Puntero constante a Cadena" y LPSTR es "Puntero a Cadena", Por lo que nos indica que claramente envía un Puntero a la cadena que esta contenida en memoria y que sera obtenida por la librería gracias al procedimiento "CadenaDePtrCad" (Cadena de puntero a cadena).</span><br />
<br />
Ejecutan el código y pueden visualizar claramente el mensaje.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/q6QXM5E.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/q6QXM5E.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
¡Saludos!</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-50454834595649347392014-10-24T03:16:00.005-07:002014-12-20T21:35:38.775-08:00Dll Export ViewerDll Export Viewer es un programa que nos permite obtener datos sobre las librerías DLL que exportan funciones.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/Pqa24gy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/Pqa24gy.png" height="252" width="400" /></a></div>
<div style="text-align: center;">
<br /></div>
<br />
Actualmente disponible en 23 idiomas, Nos ofrece el nombre de las funciones, su dirección y dirección relativa entre otros datos.<br />
<br />
Ademas de lo anterior mencionado, nos ofrece exportar una lista de las funciones en HTML, buscarlas en Google o guardarlas en un archivo de texto plano.<br />
<br />
Si quieres descargar este programa, puedes hacerlo desde la pagina web oficial.<br />
<br />
<a href="http://www.nirsoft.net/utils/dll_export_viewer.html" target="_blank">www.nirsoft.net</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-314614948420937941.post-21341101989375091652014-10-24T00:57:00.002-07:002014-10-24T03:32:25.015-07:00Programación en españolEs un placer para mi anunciar la apertura de este nuevo blog, Si te gusta la programación pero estas harto del ingles, este es tu sitio!<br />
<br />
Les informo que en este blog solo utilizare 3 lenguajes de programación:<br />
<br />
Autoit<br />
Pauscal<br />
Visual Basic 6.0<br />
<br />
Si necesitan algo sobre C++ o Java les recomiendo que busquen otro blog.<br />
<br />
¡Saludos!Unknownnoreply@blogger.com0