A tortas con el MFC y los cursores e iconos

Bueno, hoy he estado haciendo pruebas sobre como crear un control estático donde maneje a mi antojo lo que dibuje en el con MFC para windows, y entre otras cosas se me ha ocurrido meterle un icono como dibujo y que cuando el ratón pase por una zona del control se cambie el cursor (el puntero).

Para el primero he tenido varios problemas puesto que no esta muy depurada la API de windows para manejar cursores y dejarlos en 16×16 pixeles, haciendo cosas raras, menos mal que dentro del oceano de Internet uno puede ir recopilando informaciones cuando no se encuentra todo en un documento para saber como hacerlo. Tan sencillo como esto:

Primero cargo el icono con la función LoadImage, donde le paso como parámetros la instancia de la aplicación donde se encuentra el icono (la misma aplicación donde se ejecuta), el identificador del recurso del icono pasado a cadena con la macro MAKEINTRESOURCE, el tipo de imagen que es (un icono), la anchura y la altura del mismo y finalmente que lo coja con los colores por defecto.

Segundo dibujo el icono en el dispositivo de contexto que nos ofrece windows para dibujar en el control CStatic, no uso la función DrawIcon del objeto de dispositivo contexto por que no consigue adaptar bién el icono a 16×16 pixeles, por lo que uso la función win32 DrawIconEx que si me lo permite, pasandole como parámetros el manejeador del dispositivo de contexto, la posición x e y donde quiero dibujar el icono, el icono, su achura y altura, ningúna brocha (no es necesario) y le digo que es una imagen con transparencias (DI_NORMAL indica todo eso).

Tercero lo destruyo porque en esto de la programación en C es bueno la «limpieza».

Para el segundo caso, siendo aún más sencillo me he partido más los cuernos, simplemente porque el evento que se debe usar para cambiar el cursor no tiene mucha lógica con lo que uno quiere hacer. Mi idea es que cuando moviese el ratón por una zona del CStatic, se cambiase el cursor, sin embargo usando el evento OnMouseMove no funciona para nada la función SetCursor. He de decir que cuando digo CStatic, en realidad es una clase que he derivado de esa para poder interceptar los eventos. Por lo visto para que funcione lo que queremos hacer debemos usar el vento OnSetCursor, que funciona a semejanza del OnMouseMove, pero que no te da las coordenadas dentro del control donde se encuentre el puntero del ratón, sino que se activa cuando se pasa el ratón por el control. Esto no funcionaría si no tuviesemos activado la opción «notify» de los estilos del control. Aquí dejo mi solución de como lo he conseguido al final:

Primero declaro una variable POINT, luego pregunto con GetCursorPos que me diga la posición relativa a pantalla donde se encuentra el ratón, y a continuación lo transformo a coordenadas del control gracias a la función ScreenToClient. Con todo esto logramos saber en que posición de nuestro control esta el cursor ya que el OnSetCursor no nos la da como parámetro como lo hicera el OnMouseMove.

Segundo comparo si el cursor esta dentro de un rango en el eje de la altura y si es así ya uso la función SetCursor (de la api de win32 no del objeto), pasandole como parámetro el cursor que me devuelve la función LoadCursor, a la cual se le pasan como parámetros la instancia donde se encuentra el cursor (la nuestra en este caso) y el identificador del cursor pasado a cadena con la macro explicada antes. Después salimos de la función delvolviendo un valor TRUE indicando que no hay que hacer nada más.

Tercero, si llega hasta aquí significa que no ha pasado por el if y que llama al manejador por defecto devolviendo el valor que a su vez este devuelve, esta linea la incorpora automáticamente el Editor de Visual C++ cuando añadimos el evento OnSetFocus.

Como veis la programación de Windows es apasionante, pero muchas veces me encuentro con cosas que no funcionan como deben o se manejan de forma ilógica, pero bueno, menos mal que ya hay mucho escrito sobre eso. Por cierto, sigo pendiente de aprender programar linux, estoy por el capítulo de programación avanzada de ficheros y en siguiente ya son los demonios, y aún así me queda mucho libro por leer 🙂

Navegación anónima

Después de las vacaciones de verano ya va siendo hora que postee de nuevo en el blog, aunque me da a mi que nadie o casi nadie lo lee, pero bueno, aquí estamos.

Muchas veces hemos navegado por Internet con nuestro navegador favorito y sabemos que vamos dejando nuestro rastro allá por donde vamos, o bién queremos opinar en algún foro como una persona distinta, o bién queremos votar más de una vez en alguna votación, mandar un correo electrónico y que no se sepa el origen, etc etc etc.

Pues bién, la solución a todos estos problemas son los proxys abiertos, los cuales son proxys mal configurados por administradores o usuarios particulares que los tienen para compartir una conexión a Internet y por tanto cualquiera puede usar ese mismo proxy desde fuera de la red donde se encuentra.

Configurando la conexión en nuestro navegador web para que pase a través de un proxy abierto, se elimina la ip que poseemos y se sustituye por la ip del proxy (en algunos casos se pasa como cabecera de la petición a la página con lo que no se elimina del todo), pudiendo asi interactuar con la web que hayamos visitado sin que sepa realmente quienes somos (normalmente no se sabe quienes somos, y menos si tenemos ip dinámica, pero con esto se dobla el anonimato en la navegación).

Se puede acceder a ftp, http, https desde un proxy (siempre que este configurado para permitirlo) y conectarnos a otros puertos si usamos la tecnología SOCKS v4 o v5 (igualmente debe estar configurado para permitirlo), con lo que prácticamente se

puede hacer de todo en internet a través de un proxy. Es más, si estas en tu empresa y te capan todos los puertos menos el puerto 80 para salir a Internet, con un proxy podrás acceder al resto de puertos sin mayor peoblema.

Hay muchas listas de proxys abiertos por Internet, yo suelo usar Open Proxies, pero hay muchas listas más o menos públicas para llevar a cabo tu intimidad y anonimato.

Programación TCP/IP

Creo que a estas alturas todo el mundo sabe que es internet, y lo que aporta a la comunidad, lo que no creo que sepa tanta gente es que como la información se transmite y como hace para llegar a su destino sin errores, diferenciando tantos servicios como existen en internet y demás. Dentro de este último grupo seguro que también hay gente que además de saber lo que son los protocolos TCP e IP, les gustaría saber qué pasos seguir para programar un cliente o un servidor de red para Internet o para intranets basadas en TCP/IP. Pues bién, hay una guia estupenda llamada Beej’s Guide to Network Programming que te explica todo lo que tienes que saber para empezar a programar sockets, que no son otra cosa que los descriptores de «fichero» para la red. Tiene traducción al castellano y además, aunque esta orientado a sistemas linux/unix, también te explica como hacerlo en windows. Yo ya hice mis pinitos hace tiempo con esta guia, y entre otras cosas hice este juego para windows del conecta 4 para dos jugadores (tiene sus bugs escondidos, asi que no le trateis mal 🙂

Futuro proyecto

No se si os habeis dado cuenta ya que me gusta experiementar con tecnologías sms y email. Pues bién, mi futuro proyecto es crear un gateway email/sms/email, el cual alguien puede enviar un mensaje desde cualquier móvil al celular del gateway con el formato <dirección de email> <mensaje>, por lo que enviará ese mensaje a la dirección de correo que se solicita. Para el proceso contrario, se debe meter el número de teléfono en el asunto y el texto en el cuerpo del mensaje, con lo que se enviará ese texto al número de teléfono que se indica.

De momento lo estoy desarollando, sin embargo tengo una utilidad instalada en mi servidor linux particular (http://www.sistemasorp.com) llamada smstools que es capaz guardar los mensajes entrantes de un movil conectado por el puerto serie en una carpeta denominada incoming, como de enviar los mensajes que se encuentren en una carpeta denomiada outgoing al mismo.

La idea es que tenga un demonio corriendo bajo linux que sea quien lea la cuenta de correo habilitada a tal efecto (sms@sistemasorp.com) enviando el sms si el email es correcto, y que a su vez comprueba la carpeta incoming para enviar el email si el sms es correcto.

De momento tengo que aprender un poco más de programación en linux para hacer demonios y demás cosillas, espero que pronto este finalizado este proyecto para que podais disfrutarlo.

Edición 31/7/2004:

Buscando cosas por internet me he encontrado los mailtuils, que es básicamente una serie de utilidades y librerias para lidiar con el correo. A mi me viene de perlas, porque así puedo recoger los mensajes, interpretar las cabeceras MIME del mensaje, enviar emails, etc. desde el código de la aplicación, y sin tener que hacer llamadas al sistema a «mail» y similares como tenía pensado. Ahora solo me queda ponerme con la programación de demonios en linux para tener a punto el gateway.

Envio de sms con cualquier remitente

Y ya puestos después de publicar el anterior artículo, os comentaré como enviar mensajes SMS con un remitente cualquiera. Esta posibilidad es aún más creible que los correos electrónicos, puesto que cuando un usuario de móvil recibe un mensaje de texto en su móvil, creerá que el remitente del mismo es quien le ha enviado tal mensaje, ya que la

gran mayoría no sabrá que los sms se pueden falsificar.

Esto no es como lo del e-mail, es costoso: Si os haceis una cuenta en www.truesenses.com y comprais una cantidad de mensajes, su interfaz te permite poner además del destinatario y el mensaje, el remitente del mismo. Por lo que puedes poner como origen cadenas de texto o ún número de móvil (cuando el destinatario reciba el mensaje si tiene ese número en la agenda le aparecerá con el nombre con el que lo hubiera guardado).

Así de sencillo, 300 mensajes cuestan unos 30 euros, sin embargo al ser un operador suizo y al hacer roaming, cuando se envía un mensaje a España se cuenta como si hubieras enviado 2.

Sin embargo, y por tiempo limitado, aquí os dejo un formulario donde podreis probar este tipo de característica. Que os divirtais.

Remitente (una cadena o número internacional de móvil de 12 caracteres como máximo)
Destinatario (un número internacional de móvil de 12 caracteres como máximo)
Mensaje (130 caractéres máximo)

Edición 06/08/2004:

Después de haber tenido el servicio levantado durante 1 mes y 15 días aprox. lo cierro con la satisfacción de que ha sido una gran experiencia para todos los que lo han usado con cerca de 160 mensajes enviados desde este formulario. Quién sabe, a lo mejor me animo y lo vuelvo a activar desde www.sistemasorp.com (no lo probeis ya que tiene el movil sin batería)

Envio de mails con cualquier remitente

No se si lo sabíais, pero es relativamente fácil falsificar un remitente de una dirección de correo electrónico. Para ello solo teneis que saber lo básico del protocolo SMTP de internet, o lo que es lo mismo, el protocolo que recibe los emails para luego enviarlos, ya sea a destinatarios del mismo dominio (correo local), o bién a destinatarios de otros dominios (distribución, aunque en este último caso si no eres del mismo dominio que el servidor SMTP es bastante improbable que puedas poner un remitente y un destinatario diferentes que el dominio del propio servidor).

El caso es que queremos enviar un mensaje a un conocido con un remitente distinto al nuestro. Aunque configurasemos nuestro cliente de correo con una cuenta ficticia, probablemente nuestro servidor de correo SMTP no nos dejase enviarlo por lo que he explicado en el anterior párrafo. Sin embargo con unos pocos conocimientos podemos ser nosotros mismos quienes depositemos en mensaje trucado en el buzón del destinatario.

El proceso a seguir es el siguiente:

1 – Averiguar el servidor de correo del destinatario, para ello en la linea de comandos ponemos:

(en windows nt, 2000, xp o Linux) nslookup -q=MX dominio

Donde «dominio» es el del propio del destinatario, por ejemplo pepito@yahoo.es el dominio es «yahoo.es», con lo que al final queda nslookup -q=MX yahoo.es. Entónces cogemos la direccion que aparece a la derecha de mail exchanger; en el caso de yahoo me han salido varios, yo cojo el primero, es decir, mx2.mail.yahoo.com

2 – Poner luego en la misma linea de comandos lo siguiente:

(en windows o Linux) telnet servidor 25

Donde «servidor» es la dirección a la que haciamos referencia en el punto 1, con lo que al final queda telnet mx2.mail.yahoo.com 25. Si ponemos 25 es porque ese es el puerto por donde habitualmente escucha el servidor SMTP de correo del dominio al que queremos conectarnos.

3 – Una vez conectados veremos un mensaje de bienvenida con un código numérico y un texto, nosotros solo nos centraremos en los códigos numéricos. Si todo funciona correctamente debemos haber recibido un 220.

Lo primero que haremos es poner HELO dominio y pulsaremos enter, donde «dominio» se supone que es el dominio del remitente del mensaje, si nosotros queremos enviar el mensaje como billgates@microsoft.com sería HELO microsoft.com

Si todo va bien, recibiremos un código 250. Ahora pondremos la dirección de correo del remitente de la siguiente forma MAIL FROM: <remitente> y pulsaremos enter, donde «remitente» en nuestro ejemplo sería billgates@microsoft.com y quedaría así MAIL FROM: <billgates@microsoft.com>

Si todo fué bién, volveremos a recibir un código 250. Ahora pondremos la dirección de correo del destinatario de la siguiente forma RCPT TO: <destinatario> y pulsaremos enter, donde «destinatario» en nuestro ejemplo sería pepito@yahoo.es y quedaría así RCPT TO: <pepito@yahoo.es>. En el caso de que haya varios destinatarios en el mismo dominio repetir el mismo proceso con todos ellos.

Si hemos recibido otro código 250 es que esto va como la seda. Ahora ponemos DATA y pulsamos enter, si recibimos un código 354 es que ya podemos poner el correo en sí.

Primero vienen las cabeceras, luego una linea en blanco, luego el texto y luego una linea con un punto, asi que si queremos poner el nombre del remitente, el del destinatario, el título como «Hola colega» y el mensaje «¿Que tál estas?», debemos escribir las siguientes lineas a continuación:

From:»Bill Gates» <billgates@microsoft.com>

To:»Pepito Perez» <pepito@yahoo.es>

Subject:Hola colega

Content-type:text/plain;charset=»iso-8859-1″

¿Que tal estás?

.

La linea Content-type:text/plain;charset=»iso-8859-1″ de la cabecera sirve para indicar que el texto contiene caracteres occidentales como acentos y demás. Si recibimos un código 250 significa que el mensaje ha sido enviado satisfactoriamente y que el usuario lo recibirá en cuanto recoja el correo. Ahora si tecleais QUIT saldreis de la sesión.

Os animo a que lo probeis con vuestras cuentas de correo para que comprobeis que funciona y coger experiencia para luego probarlo con otras cuentas ;). Una cosa

importante es que vuestra dirección IP se queda reflejada en la cabecera del mensaje,

asi que o bién os buscais un proxy con socks o un wingate para ocultarla, o bien dejais que vuestra ip permanezca en la cabecera si veis que el destinatario no sabrá encontrarla u os da igual que este en la cabecera.

¿Formato de un fichero?

Supongo que todos los que nos dedicamos a programar siempre nos hemos preguntado cual sería el formato de un fichero, como poder leerlo, interpretar sus cabeceras, escribir uno por nuestra cuenta y que pueda ser leido por otras herramientas ajenas a la nuestra, etc. El problema es que siempre que queramos conseguir la descripción de cualquier formato de fichero que tengamos que usar nos tocará buscarlo por Internet , y muchas veces uno se desespera porque hay muchas refrencias a un tipo de fichero pero ninguna que nos interese. Sin embargo, esto se soluciona en gran medida gracias a wotsit’s format: una web donde podrás buscar casi cualquier tipo de fichero y leer sus especificaciones. Esta organizado por función, tiene busquedas y en general es bastante sencillo de usar, ¿que quieres saber cual es el formato del fichero .DOC, .XLS. PDF, .JPG, .CAD, etc? pues aqui lo encontrarás, por lo que es el sitio ideal siempre que quieras buscar un formato de fichero.

Las patentes

Recientemente se ha aprobado en la Unión Europea las patentes de software al más puro estilo Yankee. Esto, lejos de ser beneficioso, provoca que las grandes corporaciones se hagan aún más fuertes en el mercado del software. Hay gente que dice que si tu has desarrollado un algoritmo de software, debes patentarlo para respetar tu autoría y poder explotarlo económicamente. Sin embargo esto no es tan bonito como parece, puesto que el principal perjudicado sería el software libre que ahora estaba empezando a pegar fuerte tanto en empresas como en los hogares. Hace muy poco tiempo Microsoft patentó en los E.E.U.U un sistema de ejecución de programas basado en tiempos a través de un hardware específico, encubriendo así el famoso click y doble click del ratón. Esto podría repercutir en cualquier sistema Mac, Linux/Unix, OS/400, VMS, etc. porque Microsoft podría cobrarles sumas millonarias a aquellos que lo implementen, pudiendo provocar la ruina a muchos de ellos de tal forma que al final M$ consiguiese quedarse como único proveedor de software y posteriormente subiendo los precios como se le antojase sin tener competencia ninguna. Alguno puede que diga que ya se inventará otro sistema para hacer lo mismo, pero el problema es que no es lo único que se puede patentar y un sistema lo conforman muchas cosas.

El mundo de XSL

Como primer artículo comentaré que labor estoy desarrollando ahora mismo en mi trabajo. Para poneros en antecedentes os diré que estoy desarrollando (e investigando) en un proyecto para la Comunidad de Madrid. No os comentaré mucho de que trata porque no creo que sin haber salido a la luz les guste a los responsables del mismo que se le de publicidad. Sin embargo si os puedo comentar algo de lo que estoy haciendo:

Dentro del proyecto hay un apartado donde se generan unas cedulas informativas. El objetivo es poder generar cedulas en formato PDF, sin embargo no es moco de pavo, porque dependiendo del municipio habrá distintos tipos de información y se tendrá que representar de forma igualmente distinta. El caso es que como es un proceso que posiblemente tenga que atender cientos de peticiones no es un simple «imprime en la impresora pdf» como podría ser en word o similares.

Hay una cosa clara, y es que la información que se baraja tiende a ser la misma, pero no así la presentación (¿os suena esto a la programación a tres capas?). El caso es que existe una herramienta denominada FOP la cual te permite pasarle un fichero XML, un fichero XSL (XSL + FO) y te genera un pdf en un santiamen. El proceso es el siguiente, el XML solo tiene los datos estructuradamente, el XSL contiene el pseudocodigo que manejará los datos XML. Luego cuando se ejecuta el fop, se interpreta el XSL que le dice donde poner los datos del fichero XML y a continuación genera un PDF interpretando las directrices del FO. El resultado es bastante bueno, aunque la generación del XSL la hago de momento a mano y suele ser un poco laborioso, sin embargo es gratificante ver sus resultados.

Un ejemplo muy cortito sería este:

——————————————————————————–

Fichero XML

——————————————————————————–

<?xml version=»1.0″ encoding=»ISO-8859-1″?>

<RAIZ>

<NOMBRE>Oscar Rodríguez</NOMBRE>

</RAIZ>

——————————————————————————–

Fichero XSL

——————————————————————————–

<?xml version=»1.0″ encoding=»iso-8859-1″?>

<xsl:stylesheet xmlns:xsl=»http://www.w3.org/1999/XSL/Transform» version=»1.0″ xmlns:fo=»http://www.w3.org/1999/XSL/Format»>

<xsl:template match=»/»>

<fo:root>

<fo:layout-master-set>

<fo:simple-page-master master-name=»pagina» page-width=»210mm» page-height=»297mm»>

<fo:region-body margin=»1cm»/>

</fo:simple-page-master>

</fo:layout-master-set>

<fo:page-sequence master-reference=»pagina»>

<fo:flow flow-name=»xsl-region-body»>

<xsl:apply-templates select=»//NOMBRE»/>

</fo:flow>

</fo:page-sequence>

</fo:root>

</xsl:template>

<xsl:template match=»NOMBRE»>

<fo:block font-family=»Times» font-size=»8pt» color=»blue»>Hola, soy <xsl:value-of select=».»/></fo:block>

</xsl:template>

</xsl:stylesheet>

——————————————————————————–

Si os fijais, como comentaba antes el XML es una chorrada, sin embargo el XSL es más laborioso porque al fin y al cabo hay que tratar tanto la información del XML (aquellas etiquetas que empiecen por xsl) como indicar como se va a presentar (las etiquetas que empiecen por fo). En este ejemplo se esta diciendo que se genere una página DIN A4 con margen por todos los lados de 1 centimetro; que procese la etiqueta NOMBRE (o lo que sería como llamar a la función NOMBRE) para que saque al final la frase «Hola, soy Oscar Rodríguez» con un tipo de letra Times New Romans de 8 puntos y de color azul.

EL FOP al ejecutarlo de la siguiente forma:

fop -xsl oscar.xsl -xml oscar.xml -pdf oscar.pdf

muestra lo siguiente:

[INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser

[INFO] FOP 0.20.5

[INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser

[INFO] building formatting object tree

[INFO] setting up fonts

[INFO] [1]

[INFO] Parsing of document complete, stopping renderer

Y el resultado final queda así

Luego se puede complicar más poniendo cabeceras, números de página, imágenes, etc. Yo aún sigo investigando para ver todas las posibilidades del XSL (y su hermano menor el FO).

Hay que darle vidilla a esto

Mi iniciativa de crear un blog se quedó poco menos que en el aire después de que haya pasado casi un año desde la primera (y única) publicación en blogger, pero hasta aquí hemos llegado. Mi idea era la de desarrollar yo mismo un sistema de weblogging, pero visto los cambios que ha hecho blogger me quedaré con el sistema actual (la excusa extra-oficial es la pereza que me da hacerlo de nuevo).

Este fenómeno de los weblogs es creciente, tanto que para un tio como yo que le apasiona tanto la informática no puede pasarme desapercibido. Es cierto que esto exige una constancia en cuanto a la publicación, tanta que muchos han desistido o los dejan medio abandonados. Este abandono para mi es quedar mal con los lectores, por lo que sin pillarme las manos, seré un escritor + o – asiduo si a alguien le interesa mi bitácora.

¿De que va a tratar? De programación, de informática y demás. Estos tres puntos intentaré diferenciarlos bién, porque yo soy desarrollador, pero también me gustaría escribir sobre cosas relacionadas con el mundo de la informática, y por supuesto, como no es un sistema cerrado también escribiré sobre otros temas que no tengan que ver con los anteriores.

Mi objetivo es compartir mis experiencias, mis opiniones, mis logros, mis decepciones, etc. por lo que todos los artículos tendrán tinte personal (para eso es un weblog ¿no?), y quien sabe si algún día compartiré con más gente.

Si has llegado hasta aquí y no te has aburrido, te doy las gracias y te animo a que leas el resto de publicaciones en este blog.