NET: Como convertir el CLR una app en “AnyCPU” en “32bits”

Os propongo un escenario:

  • Aplicación desarrollada en .NET, hace mucho tiempo, y a decir verdad, con la mitad de los conocimientos que tenemos ahora.
  • Por desgracia, se compiló como “AnyCPU” (lo que se ha demostrado como un error a lo largo del tiempo).
  • Ahora lo lanzas, y te encuentras con un: “Error en microsoft.jet.oledb.4.0”. Tras leer, te das cuenta que esto se arregla recompilando en “x86”
  • … Solo tengo el ejecutable, y unas horas para presentar el programa (música de terror de fondo…)

Bueno, pues hay un trucoquillo para marcar un ejecutable de .NET, compilado en AnyCPU, como un ejecutable x86, ya que realmente, solo hay que cambiar un campo en la cabecera (más o menos). ¿Cómo?, ahora te lo explico:

  • Doy por sentado que tienes el SDK de desarrollo del NET o el Visual Studio en cualquier de sus sabores (con el componente “Developer Tools -> Windows Development Tools -> .NET Development Tools” instalado)
  • Te metes en: “Program Files\Microsoft SDKs\Windows\v6.1\Bin” (ojo el v6.1 es para NET 3.5, para NET 4.x cambiará obviamente) y allí tienes que encontrar un fichero “corflags.exe”.
  • Ejecutas:
    corflags /32bit+ <RutaATuEjecutableANYCPU>

    Y tachán. Ejecutable en 32bits :).

Referencias:

  • http://stackoverflow.com/questions/1507268/force-x86-clr-on-any-cpu-net-assembly
  • http://stackoverflow.com/questions/242304/where-should-i-download-corflags-exe-from
Please follow and like us:

Aprendiendo a programar en Android

Cuando empiezas a programar en algo (ya sea un lenguaje, dispositivo, paradigma o lo que sea) siempre se agradece un buen manual para empezar, y conocer al menos los principios básicos para empezar.

Muchos usamos los libros como fuente de referencia, pero Internet siempre nos sorprende con gente que nos ofrece “sabiduría” de manera desinteresada, en forma de manuales.

En este caso, aquí os dejo un buen manual para empezar y evolucionar en la programación en Android, desde montar el entorno para desarrollar, hasta manejo de XML, a crear tus controles… Muy bueno, no os lo perdáis.

Desarrollo en Android

Please follow and like us:

Cuando Double.MaxValue, no es Double.MaxValue

Creo que es uno de los primeros post que voy a escribir por absoluta desesperación. Y el título lo dice todo.

Estamos desarrollando una aplicación en mi empresa, donde usamos un librería “open source” construida de manera intachable. Bien estructurada, con sus clases, con sus interfaces, y todo en NET 2.0.

Ahora viene lo bueno, dentro de la librería, hay un:

public const double Missing = Double.MaxValue;

Esta línea, parece encarnar el mal, y tiene el número #630 dentro del sistema de bugtracking del proyecto (a partir de ahora el número del mal). En ciertos equipos (si, en ciertos, sin diferenciación mayor que ser otro equipo), provoca que el programa se salga (mejor dicho: explote), sin generar ninguna excepción (lo que implica un error por debajo incluso del NET) y sin dejar ningún registro de error. En cambio, si ponemos:

Si hacemos una asignación quitando el alias:

public const double Missing = 1.7976931348623157E+308;

Tenemos otro crash silencioso al ejecutar el programa. Incluso rebajando el exponente, tenemos el mismo fallo. Pero esperen, que viene lo mejor:

public const double Missing = 999999999999999999;

Entonces, todo el felicidad, los pájaros cantan y las nubes se levantan… No falla.

¿¿¿Porqué???. De verdad que no lo entiendo, y los oscuros mundos del NET me tienen frito.

Pues no termino de entender el porque. Puedo conjeturar que viene por la representación que le da .NET, no es representable por algún nivel más bajo de la máquina, o algún redondeo que implique un overflow. Pero la verdad que no he encontrado nada por la red, y menos aun por los foros de la librería. Pueden ser muchos factores, y me estaré dejando muchos sin tener en cuenta, pero desde luego ahora mismo estoy falto de ideas.

Please follow and like us:

¿Como seleccionar varios elementos de un “select” multi-seleccionable sin usar la tecla Control (en Javascript)?

"Select" con el atributo "multiple" activo

"Select" con el atributo "multiple" activo

Cuando programas con HTML, usar Javascript dentro de tu código puede ser tu solución o tu perdición. Pero en muchos casos, suele ayudarte en tareas que van más allá de lo que nos ofrece el HTML. Y más aun cuando tratas de hacer algo dinámico, con algo de 2.0, pues es obligatorio.

Imaginaros que tenéis una etiqueta “select“, con el atributo “multiple” activo, lo que os permite seleccionar varios elementos de esta selección a la vez como muestra la imagen de la derecha. Pero esto no es tan sencillo, ya que para seleccionar varios de estos elementos (o “options“) tenemos que pulsar la teclar “Ctrl” a la vez que pinchamos encima.

¿Ctrl + ratón?, estamos locos… “, esto es lo que pensó uno de los usuarios que probó una aplicación que estábamos desarrollando, por lo que nos tocó hacerlo más intuitivo, es decir, sólo usar el click del ratón para que el usuario no se haga un lío.

Para realizar esto, tienes que añadir a tu “select” un nuevo atributo “onChange“, que se disparará cuando haya un cambio dentro del control generado:

<select multiple="multiple" id="lbZonas" onChange="select_OnChange();">

Al ocurrir un cambio, lanzaremos la función “select_OnChange“. Entonces, solo tenemos que añadir este código y tendremos lo que buscamos:

// Array donde almacenaremos los elementos seleccionados
var aSelected = new Array();
// Puntero al control seleccionado
var multiList_Select;
// Busco el control que quiero monitorizar
// y lo dejo guardado en nuestro puntero
if (document.getElementById)
{
    // Pon el ID que tenga tu etiqueta "select"
    multiList_Select = document.getElementById("lbZonas");
}
else
{
    for (var iList=0; iList<document.forms.length; iList++)
    {
      var oForm = document.forms[iList];
      if (oForm.multiList)
       {
           multiList_Select = oForm.multiList;
       }
    }
}

// Inicializo el array con los valores que
// estan seleccionados en el control
function select_Init()
{
    for (var iList=0; iList<multiList_Select.options.length; iList++)
    {
        aSelected[iList] = multiList_Select.options[iList].selected;
    }
}

// Esta funcion se ejecuta cada vez que hay un cambio
// y selecciona todos los elementos anteriormente seleccionados
// y el nuevo en el que se ha hecho click. En el caso que ya estubiera
// seleccionado, sencillamente lo pone a falso en el array
function select_OnChange()
{
    var theIndex = multiList_Select.selectedIndex;
    aSelected[theIndex] = !aSelected[theIndex];

    for (var iList=0; iList<multiList_Select.options.length; iList++)
    {
        multiList_Select.options[iList].selected = aSelected[iList];
    }
}
// Esto se lanza solo una vez, y inicializa el array
select_Init();

Solo existe un problema, que se nota algo en Firefox y es un pequeño parpadeo cada vez que se selecciona un elemento, y realmente no se como solucionarlo, pero el problema es bastante pequeño y aceptable. Aunque si conocéis alguna solución soy todo oídos :).

select
Please follow and like us:

Excel y .NET, malos amigos (III): ¿Como poner una imagen en un rango de celdas?

Otra nueva guerra con Excel, desde C#. Ahora el problema era introducir una imagen en un rango de celdas. Un verdadero problema, ya que la imagen tenia que ajustarse a ellas aunque se deformara. Además tenía que funcionar en Office 2003 y 2007. ¿Más madera?, no importa soy informático :P.

Pues bien, primer intento, me pongo manos a la obra y a tirar líneas:

// Rango donde se intertará la imagen
Microsoft.Office.Interop.Excel.Range r1;
r1 = (Microsoft.Office.Interop.Excel.Range) objSheet.get_Range("F5", "AB37");
r1.Select(); //Es necesario seleccinar un rango para poder insertar

// Objeto de todas las imagenes del excel
Microsoft.Office.Interop.Excel.Pictures oPictures =
(Microsoft.Office.Interop.Excel.Pictures)objSheet.Pictures(System.Reflection.Missing.Value);

//La ruta de la imagen donde esta la imagen a insertar,
//OJO es necesario indicar bien la ruta, de lo contrario marcará el siguiente error
//"Error en el método Insert de la clase Pictures" y pues eso despista ya que solo es
//la ruta y no la implementacion del método
string pathTEMP_BMP = System.IO.Path.GetTempFileName();
this._datos.im.Save(pathTEMP_BMP, System.Drawing.Imaging.ImageFormat.Bmp);

// Crear un objeto Picture de Office
Microsoft.Office.Interop.Excel.Picture p =
oPictures.Insert(pathTEMP_BMP, System.Reflection.Missing.Value);
// Redimensionar
p.Width = (double) r1.Width;
p.Height = (double) r1.Height;

Bueno, pues un medio “Fail”. Funciona bien en 2003, pero cuando se abre con Excel 2007, la imagen no se ajusta al rango “r1” de celdas. Miro a la pantalla con resignación torera y exclamo mi mítico: “Me cago en tó”.

Vale, no desesperemos, tras bucear un poco por internet, veo este articulo que me da otra buena idea. No usar el objeto “Pictures” de Excel, si no usar el “Shapes”. Vamos a intentarlo:

// Eliminamos apartir de la línea 17 en adelante y incluimos esto
objSheet.Shapes.AddPicture(pathTEMP_BMP, 
               Microsoft.Office.Core.MsoTriState.msoFalse, 
               Microsoft.Office.Core.MsoTriState.msoCTrue,
               float.Parse(r1.Left.ToString()), float.Parse(r1.Top.ToString()), 
               float.Parse(r1.Width.ToString()), float.Parse(r1.Height.ToString())); 

Perfecto, ahora si funciona bien en 2003, y 2007. Pero lo que cuesta hacer la cosas bien :).

Please follow and like us:

Ocultar elementos “Button” con Javascript

Os adjunto una funcionilla que muestra sólo un botón cuando se seleccionan elementos de un “ListBox“. Cuando solo hay un elemento seleccionado se muestra el botón “btnUNO” y cuando se seleccionan varios “btnVarios“. Esto está hecho con la intención de mostrar diferentes botones con diferentes funcionalidades para cada una de las posibilidades. Al estar hecho con javascript, no hace falta recargar, por lo que se puede hacer casi invisible al usuario.

function ItemsSeleccionados()
	{
            // lb es el listbox que vamos a controlar
	    var lb = document.getElementById("lbZonas");
	    var optLength = lb.options.length;
	    var nselec = 0;

	    if (lb != null)
	    {
	        for(var i=0;i<optLength;i++){
                if(lb.options[i].selected)
                    nselec++;
            }

            // Si solo dejo btnUNO, sino btnVarios
            var btnUNO = document.getElementById("btnSelZona");
            var btnVarios = document.getElementById("btnSelZona2");
            if (nselec > 1)
            {
                btnUNO.style.visibility  = 'hidden'; // No se ve
                btnUNO.style.display = 'none'; // No ocupa espacio
                btnVarios.style.visibility  = 'visible'; // Se ve
                btnVarios.style.display = ''; // Se muestra por defecto
            }
            else
            {
                btnUNO.style.visibility  = 'visible';
                btnUNO.style.display = '';
                btnVarios.style.visibility  = 'hidden';
                btnVarios.style.display = 'none';
            }
	    }
	}

Cómo habréis notado, no hace falta cambiar “visibility” (oculta el control, pero ocupa espacio) en el estilo si se toca el “display” (se elimina de los controles y no ocupa espacio), pero lo he dejado para ver las diferentes cosas que se pueden hacer.

Please follow and like us:

Como poner un label transparente sobre un picturebox en .NET

Programando, y programando me he encontrado con muchas cosas curiosas, entre ellas esta.

Imagina que quieres poner un texto encima de una imagen, lo normal sería, poner un picturebox, y luego poner encima un label pero si pones un label sobre un picturebox o cualquier otra imagen o control, pasan cosas como esta:

Fallo marcado en rojo

Fallo marcado en rojo

Como veis en la captura de arriba (programa que me he hecho en 5 minutos), esto es un problema como la copa de un pino, ya que se ve gris. Bueno no realmente, se ve del color del Form en el cual están alojados el picturebox y el label. Y este el problema, el “parent” del label es el Form, por lo que al hacer la transparencia, que la esta haciendo, la hace con su padre y no con la imagen que tiene encima, de ahí el color gris.

¿Como lograr entonces la transparencia?, pues hay dos métodos, uno sencillo que es cambiar el “parent” del label y poner el picturebox, por lo que la transparencia la tratará de hacer con el picturebox, y otra, escribir el texto en el evento “Paint” del control picturebox que es más complejo pero infinitamente mas potente.

Os adjunto el código para que nos entendamos, con comentarios:

private void Form1_Load(object sender, EventArgs e)
        {
            // Metodo 1º
            // ---------
            // Sencillo y barato... al menos es el que uso para cosas rápidas

            // Inicialización chorra
            this.label1.Text = "Esta no funciona...";
            this.label2.Text = "Esta si funciona...";

            // No funciona
            // ¿PERO QUE COÑO?
            this.label1.BackColor = Color.Transparent;

            // Funciona
            // Me cago en tó... ¿pero porqué?
            this.label2.Parent = this.pictureBox1;
            this.label2.BackColor = Color.Transparent;

        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            // Metodo 2º
            // ---------
            // Bastante mas complicado pero con muchas mas posibilidades
            Font fuente = new Font("Verdana", 8);
            SolidBrush brocha = new SolidBrush(Color.Black);

            e.Graphics.DrawString("Este si funciona, pero es mas complejo", fuente, brocha, 30, 110);

        }

Si queréis echar un ojo al programa os lo adjunto también: transparenciasLabel.

Please follow and like us:

Excel y .NET, malos amigos (II): Proteger un Excel y su contenido

Por desgracia, mis problemas con el maldito Excel no han acabado. Pero ni mucho menos.

Nuevo problema, nueva comedura de cabeza. Necesito proteger el contenido de un Excel, mediante programación (en C#) para que un usuario no pueda ni modificar sus valores ni el formato de las celdas.

Existen varias protecciones que se pueden aplicar: a Celda, a Hoja (Worksheet en MSDN) y a Libro (Workbook en MSDN).

La protección del libro, nos permite proteger la estructura general del libro, el orden de las hojas, añadir mas, o eliminar. El protección de la hoja, es la parte mas interesante, nos permite un montón de cosas, desde prohibir modificar contenido, hasta ordenar las filas/columnas.

Un código de ejemplo es este, que restringe por completo las acciones del usuario:

// Protejo una hoja en particular:
objSheet = (Microsoft.Office.Interop.Excel.Worksheet)objWorkbook.Sheets["Hoja 1"];
objSheet.Activate();
objSheet.Protect("clave", true, true, true, false, false, false, false, false, false, false, false, false, false, false, false);
// Protejo el libro completo:
m_Excel.Application.ActiveWorkbook.Protect("clave 2", true, false);

Si queréis, saber mas, solo visitar las urls que os he dejamos mas arriba para dar los permisos que queráis, y no los mas restrictivos.

Please follow and like us:

.NET: Como hacer una única función de “Close” para multiples paneles

Os pongo en situación: una aplicación escrita en Visual C# 2005 con múltiples paneles a modo de ventanas flotantes en el form principal. Por necesidades del cliente, ahora se necesita que todos estos paneles tengan un botón de “salida”, o “close”.

Imaginaros, tengo 10 paneles, ¿tengo que hacer 10 funciones?. No hombre… es muy sencillo:

  • Poner los botones en cada panel. Haz doble click sobre uno, y escribe el código siguiente:
    private void btnCerrar_Click(object sender, EventArgs e)
    {
    System.Windows.Forms.Button btn = (Button)sender;
    btn.Parent.Visible = false;
    }
  • Ahora te vas a cada boton y le asignas esta función en cada evento click. Ya está.

Como veras, se puede usar para cerrar panels (en este caso hacerlos invisibles), mover cosas, cerrar un form, y todo lo que se te ocurra que sea muy repetivivo. Espero que os sirva de ayuda.

Please follow and like us:

Una prueba visual, encuentre la diferencia entre estos dos textos

Renfe confía a Indra la gestión de sus sistemas corporativos por 11,5 millones de euros

Y

11,5 millones de euros no bastan para hacer una web decente, la vergüenza nacional de Renfe.es

Pero no importa, INDRA, seguirá siendo una de las grandes (al menos su web es bonita)… Las consultoras es lo que tiene, y la fama de esta “empresa” (habría mucho que decir al respecto) ya la precede.

Por cierto, ¡qué gran viñeta de Mauro!.

Please follow and like us: