Blog de Fernando Machado Piriz

Artículos sobre arquitectura corporativa y temas relacionados

Archivo para agosto 2010

Open Space de Metodologías Ágiles en Montevideo

with 2 comments

El sábado 11 de setiembre, de 9:30 a 16:00 horas, en las oficinas de Microsoft Uruguay, Cebollatí 1474 piso 5, tendrá lugar el primer open space de metodologías ágiles organizado por Ágil Uruguay.

Written by fernandomachadopiriz

31/08/2010 at 11:29

Publicado en Anuncios

Reunión mensual de CUMUY: Natural User Interfaces y Service Factory 2010

leave a comment »

logoEl próximo 31 de agosto a las 18:30 horas en Microsoft Uruguay, Cebollatí 1474 piso 5, tendrá lugar la reunión mensual del CUMUY. Tendremos dos excelentes charlas:

  • Alex Bounjour nos hablará sobre las Natural User Interfaces (NUI), la próxima revolución de la interacción humano-computadora. Cada vez mas nuestros gadget están orientados a la NUI mediante interfaces multitouch como monitores y Tablet PC. Esta sesión se centra en cómo se puede crear una NUI multi-touch de estos dispositivos. Se manejarán las diferencias entre las manipulaciones y los gestos, cuándo utilizar cada uno, y la forma de aplicar conceptos de diseño específicos NUI con la API Touch de Silverlight y Windows Presentation Foundation (WPF) 4.
  • Pablo Peralta nos motrará  las últimas novedades de Service Factory 2010, incluyendo la integración con Visual Studio 2010, las mejoras que tiene esta nueva versión, y cómo con ellas podemos aumentar la productividad de los equipos de desarrollo.

Pueden registrarse haciendo clic aquí.

¡Los esperamos!

Written by fernandomachadopiriz

26/08/2010 at 22:08

Publicado en Anuncios

Nuevo número de la revista CompartiMOSS

leave a comment »

Hace un par de días salió un nuevo número de la revista CompartiMOSS, que vienen publicando regularmente desde hace ya un tiempo dos capos de la comunidad SharePoint de hispanoamérica como Fabián Imaz y Gustavo Vélez.

CompartiMOSS es una publicación de referencia para el mundo de SharePoint, pero incluye artículos sobre desarrollo de software en general.

En este número, además de las secciones fijas, aparecen:

  • Editorial
  • Mayor productividad en Microsoft Office 2010 (Alejandro Garrido)
  • Manejadores de Eventos en SharePoint 2010 (Juan Pablo Pussacq Laborde)
  • Automatización de pruebas de interfaz de usuario con Visual Studio 2010 (Fernando Machado)
  • Motor de búsqueda de SharePoint 2007 y aplicaciones personalizadas para el acceso de la información (Fabián Imaz)
  • Herramientas para SharePoint de Recuperación, Búsqueda, Restauración y Migración (Rafael Jiménez)

Written by fernandomachadopiriz

23/08/2010 at 13:31

Publicado en Anuncios

Etiquetado con

Primera beta de Microsoft Visual Studio LightSwitch

with 8 comments

Un nuevo miembro de la familia de herramientas para desarrolladores fue anunciado a comienzos de este mes y la primera versión beta estará disponible para descarga a partir del 23 de agosto: Microsoft Visual Studio LightSwitch.

¿Qué es y para qué sirve?

LightSwitch permite crear fácil y rápidamente aplicaciones de negocio completas desde cero, incluyendo no sólo los formularios de la interfaz de usuario, sino también la base de datos; también permite crear aplicaciones a partir de bases de datos existentes.

En este artículo voy a dar un rápido paseo sobre LightSwitch usando la versión beta que estará disponible en breve. Lo que voy a crear es una aplicación muy simple para registrar los libros que presto a mis amigos.

Una nueva aplicación con LightSwitch comienza con la creación de un nuevo proyecto en Visual Studio. Un proyecto LightSwitch va a contener la definición de los datos y de los formularios de la aplicación. A partir de esas definiciones LightSwitch genera la base de datos en SQL Server y el código fuente de la aplicación en C# o Visual Basic.

En este artículo voy a usar la plantilla de proyecto de C#. Aquí pueden ver el familiar cuadro de diálogo para la creación de un nuevo proyecto en Visual Studio con las dos plantillas provistas por LightSwitch.

image

Una vez creado el proyecto podemos conectarnos a una fuente de datos existente o crear una nueva definición de los datos de la aplicación. En este artículo voy a mostrarles cómo crear la definición de los datos desde cero.

image

La primera definición es la de los libros. De cada libro me interesa el autor y el título. Creo una entidad Book, con campos Author y Title, ambos de tipo String y ambos requeridos. Estas entidades estarán almacenadas en una tabla Books.

image

Luego creo la definición de los préstamos. De cada préstamo me interesa saber a quién se lo presté, cuándo lo presté y cuándo me lo devolvieron. Creo entonces una segunda entidad Loan, con campos ToFriend, DateLoaned y DateReturned; el primero es de tipo String y los otros dos de tipo Date; los dos primeros son requeridos, no así el último. Estas entidades estarán almacenadas en una tabla Loans.

image

Ahora defino una nueva relación entre libros y préstamos.

image

Vean a continuación cómo queda la definición de la entidad Loan y su relación con Book.

image

Ahora debo definir los formularios para editar estas entidades. Varias plantillas de formularios están disponibles -para editar los registros de a uno, en una grilla, etc.-. Voy a usar la plantilla para un formulario simple de altas.

image

La definición del formulario puede ser modificada. Lo que he cambiado es solamente el nombre a mostrar y la descripción.

image

Una vez terminada la definición, puedo probar la aplicación. Esta versión de LightSwitch permite generar los siguientes tres tipos de aplicaciones:

image

Al hacer el build LightSwitch:

  • Crea la base de datos
  • Genera el código fuente
  • Compila el código de la aplicación

Una aplicación LightSwitch típicamente es una aplicación en tres capas, que usa ciertas tecnologías específicas para cada una de ellas:

  • La capa de presentación, responsable de la edición y presentación de los datos, es una aplicación Silverlight 4.0
  • La capa de lógica de negocio, responsable de las consultas, actualizaciones, validaciones y procesamiento de datos, y expone un conjunto de WCF RIA Domain Services corriendo en ASP.NET 4.0 sobre IIS o un Windows Azure web role.
  • La capa de datos, responsable de almacenar los datos, usa SQL Server o SQL Azure.

En este artículo –en inglés- pueden encontrar más información sobre la arquitectura de una aplicación LightSwitch.

Al ejecutar la aplicación LightSwitch

  • Levanta un web server local
  • Despliega la aplicación en ese web server
  • Abre la aplicación

Esto es lo que vemos:

image

Completamos los campos para agregar el primer libro:

image

La aplicación asigna automáticamente un identificador al primer libro:

image

La aplicación incluye out of the box algunas validaciones elementales, como las de los campos que están marcados como requeridos.

image

image

image

El segundo formulario es el de alta de préstamos. También es un formulario simple de altas. Podemos ver como LightSwitch asignó un control Date Picker a los campos DateLoaned y DateReturned, que son de tipo Date. También asignó un control de tipo Modal Window Picker para editar la asociación entre Loan y Book.

image

Al ejecutar la aplicación podemos ver cómo luce el control asignado automáticamente a los campos de tipo Date.

image

El control Modal Window Picker permite buscar y seleccionar un libro para asociar con este préstamo. El control incluye funciones de búsqueda y paginado de los resultados.

image

Aunque esta forma de editar los préstamos no está mal, preferiría poder ver la lista de libros y desde allí fácilmente acceder a los préstamos de cada libro y eventualmente agregar nuevos préstamos también desde allí. La plantilla para este tipo de mantenimiento es List and Details Screen. Vean cómo LightSwitch me permite indicar si quiero incluir los detalles de los libros y de los préstamos en el mismo formulario.

image

Una vez creado el formulario puedo editar su definición. Al igual que en los casos anteriores, sólo cambio ligeramente el nombre a mostrar sugerido y agrego una descripción.

image

Podemos ver cómo luce este nuevo formulario al ejecutar la aplicación. La lista de libros aparece a la izquierda. Desde allí puedo agregar, modificar y eliminar libros. Para el libro seleccionado en la lista de la izquierda, puedo ver los préstamos en la parte derecha. También aquí puedo agregar, modificar y eliminar préstamos.

image

Vean que para agregar y modificar libros y préstamos LightSwitch generó automáticamente un formulario con los mismos controles que definí antes en los respectivos formularios para dar de alta estas entidades.

image

image

Estos formularios también tienen el comportamiento para las validaciones definidas en las entidades.

image

El editar más de una entidad en una lista, las modificaciones son impactadas en la base de datos al guardar la lista y no cada entidad.

image

¿Cuánto me llevó hacer todo esto? No mucho, vean el siguiente video:

Pueden descargar el video desde aquí.

Todo esto está muy bien, pero ¿qué aplicaciones puedo hacer con LightSwitch? Probablemente haya que esperar un tiempo para ver realmente quiénes pueden aprovechar esta nueva tecnología. Aplicaciones simples como la del ejemplo pueden ser creadas muy rápidamente, pero todos sabemos que las aplicaciones del mundo real nunca son tan fáciles como las de las demos, ¿verdad? Para los desarrolladores ocasionales o no profesionales -para quienes en su momento fueron pensadas cosas como Microsoft Access o Visual FoxPro- LightSwitch puede ser su nueva herramienta. Los desarrolladores profesionales probablemente no puedan construir con LightSwitch el 100% de las complejas aplicaciones de negocios que crean hoy en día. Pero aún ellos pueden al menos usar LightSwitch como herramienta para la creación de prototipos rápidamente.

En ciertos lugares de la definición de la aplicación puedo escribir código C# para agregar aquellas funcionalidades no contempladas inicialmente por LightSwitch -para las reglas de negocio por ejemplo-. Pero entonces tengo que conocer el modelo de objetos generado por LightSwitch, para poder consumir desde mi código escrito a mano los tipos generados automáticamente.

Algunas de las plantillas parecen extensibles –hoy algunas listas de plantillas tienen un solo elemento, pero probablemente se deba a que se trata de una versión beta-. Además, parece que LightSwitch podrá generar aplicaciones también para Windows Azure. Desde que todo el código y la base de datos son generados a partir de las definiciones, la misma aplicación podría ser migrada desde el escritorio a la nube con sólo cambiar una opción en las propiedades del proyecto.

Con un modelo de objetos fácil de consumir en los puntos de extensión y un ecosistema fuerte aumentando las capacidades de LightSwitch, es probable que podamos usarlo para desarrollar aplicaciones no tan triviales como las del ejemplo. Es muy pronto todavía, el tiempo lo dirá.

Written by fernandomachadopiriz

19/08/2010 at 19:56

Denme un handle y moveré el mundo

with one comment

imageEl título de este artículo parafrasea una expresión atribuida a Arquimedes, quién dijo refiriéndose a las palancas “denme un punto de apoyo y moveré el mundo”.

Para los que desarrollamos aplicaciones para Windows desde hace algunos años, los handles eran la puerta de entrada a prácticamente cualquier recurso a través de la API de Win32. ¿Quieres cerrar o minimizar una ventana? Necesitas el handle de esa ventana. ¿Quieres escribir texto en una ventana? Necesitas un handle a la fuente, un handle al contexto del dispositivo, y un handle a la ventana. Y así con todo. Los handles eran como números mágicos que las funciones de la API de Win32 usaban para hacer su trabajo, aunque en realidad eran las direcciones de memoria donde estaban las estructuras de datos usadas por esas funciones.

Afortunadamente, en los tiempos que corren del .NET Framework, casi nadie se preocupa por tener que usar, y menos de saber qué es, un handle. El .NET Framework oculta la complejidad de manejar los recursos de Windows que tenía la API de Win32, y con ello, oculta también los handles.

Sin embargo, muy de vez en cuando, aparecen algunos problemas para los que no hay más remedio que conseguir un handle. He aquí un ejemplo.

Una de las características de Giving a Presentation es poder ocultar los íconos del escritorio durante una presentación, volviéndolos a mostrar nuevamente cuando la presentación termina. Mientras estaba programando esa característica, busqué infructuosamente en la web una forma de hacer esto. Hasta donde pude averiguar, no hay una función pública en la API de Windows para hacer esto; y la mayoría de los hacks que se encuentran en la web –este por ejemplo- usan handles y funciones de la API de Win32, pero no funcionan correctamente: inhabilitan el escritorio por completo, no sólo sus íconos; como consecuencia, no responde el menú desplegable al que se accede haciendo clic con el botón secundario del mouse, por ejemplo.

Hablando del menú desplegable del escritorio, lo que necesitaba era la funcionalidad del comando Show desktop icons.

image

Aquí fue donde los viejos conocimientos de handles y compañía fueron útiles nuevamente. Yo sabía que este comando del menú terminaba tarde o temprano siendo transformado en un mensaje WM_COMMAND al escritorio. Lo que necesitaba para emular este comando era saber los argumentos del mensaje WM_COMMAND y –como no podía ser de otra manera- el handle del escritorio. Cuando averiguara eso, podía enviar el mismo mensaje WM_COMMAND. El escritorio no podría saber si el mensaje lo estaba enviando el menú o si lo estaba enviando mi programa, por lo que debería procesarlo de la misma forma.

Para ambas cosas usé una vieja herramienta que todavía sigue estando incluida en Visual Studio: Spy++. Esta herramienta permite ubicar una ventana y, entre otras cosas, ver los mensajes que recibe. La imagen siguiente muestra el nodo en la lista de ventanas de Spy++ que corresponde al escritorio. Noten que el escritorio es una ventana de la clase SHELLDLL_DefView; luego veremos para qué sirve saber esto.

clip_image003

La siguiente imagen muestra los mensajes recibidos por esa ventana al ejecutar el comando Show desktop icons. Noten que el ID del comando enviado es el número 29698; también veremos luego para qué sirve esto:

clip_image004

La función para mostrar u ocultar los iconos del escritorio quedó finalmente así:

 

/// <summary>
/// Toggles desktop icons visibility by sending a low level command to desktop window in the same way as the popup menu "Show desktop
/// icons" does. Use <code>AreDesktopIconsVisible</code> to get current desktop icons visibility status.
/// </summary>
private static void ToggleDesktopIconsVisibility()
{
    IntPtr defaultViewHandle = FindShellWindow();
    UIntPtr resultArgument;
    IntPtr returnValue = NativeMethods.SendMessageTimeout(
        defaultViewHandle, 
        NativeMethods.WM_COMMAND, 
        new IntPtr(29698), 
        IntPtr.Zero,
        NativeMethods.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
        1000, 
        out resultArgument);
}

 

La clase NativeMethods contiene todas las funciones y constantes importadas de la API de Win32; el código no está aquí por simplicidad, pero pueden descargarlo de CodePlex. La función SendMessageTimeout es usada para enviar el mensaje WM_COMMAND con ID 29698a la ventana cuyo handle se obtuvo con la función FindShellWindow.

Por su lado, la función FindShellWindow, se encarga de buscar y retornar el handle al escritorio, más precisamente, el handle de la ventana que contiene los íconos del escritorio, cuya clase es SHELLDLL_DefView. Encontrar esta ventana no es fácil. Vaya uno a saber porqué, en ciertos sistemas la ventana está en una parte de la jerarquía de ventanas y en otros sistemas en otro –siendo estos sistemas en ambos casos Windows 7 RTM de 32 bits con las últimas actualizaciones instaladas-. Debido a esto la funcionalidad de ocultar los íconos del escritorio de Giving a Presentation en algunos casos funcionaba y en otros no. Debo agradecer a mi colega MVP Elías Mereb por haberme ayudado a probar varias versiones hasta que dar con la solución.

 

/// <summary>
/// Called by EnumWindows. Sets <code>shellWindowHandle</code> if a window with class "SHELLDLL_DefView" is found during enumeration.
/// </summary>
/// <param name="handle">The handle of the window being enumerated.</param>
/// <param name="param">The argument passed to <code>EnumWindowsProc</code>; not used in this application.</param>
/// <returns>Allways returns 1.</returns>
private static int EnumWindowsProc(IntPtr handle, int param)
{
    try
    {
        IntPtr foundHandle = NativeMethods.FindWindowEx(handle, IntPtr.Zero, "SHELLDLL_DefView", null);
        if (!foundHandle.Equals(IntPtr.Zero))
        {
            shellWindowHandle = foundHandle;
            return 0;
        }
    }
    catch
    {
        // Intentionally left blank
    }

    return 1;
}

/// <summary>
/// Finds the window containing desktop icons.
/// </summary>
/// <returns>The handle of the window.</returns>
private static IntPtr FindShellWindow()
{
    IntPtr progmanHandle;
    IntPtr defaultViewHandle = IntPtr.Zero;
    IntPtr workerWHandle;
    int errorCode = NativeMethods.ERROR_SUCCESS;

    // Try the easy way first. "SHELLDLL_DefView" is a child window of "Progman".
    progmanHandle = NativeMethods.FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Progman", null);

    if (!progmanHandle.Equals(IntPtr.Zero))
    {
        defaultViewHandle = NativeMethods.FindWindowEx(progmanHandle, IntPtr.Zero, "SHELLDLL_DefView", null);
        errorCode = Marshal.GetLastWin32Error();
    }

    if (!defaultViewHandle.Equals(IntPtr.Zero))
    {
        return defaultViewHandle;
    }
    else if (errorCode != NativeMethods.ERROR_SUCCESS)
    {
        Marshal.ThrowExceptionForHR(errorCode);
    }

    // Try the not so easy way then. In some systems "SHELLDLL_DefView" is a child of "WorkerW".
    errorCode = NativeMethods.ERROR_SUCCESS;
    workerWHandle = NativeMethods.FindWindowEx(IntPtr.Zero, IntPtr.Zero, "WorkerW", null);
    Debug.WriteLine("FindShellWindow.workerWHandle: {0}", workerWHandle);

    if (!workerWHandle.Equals(IntPtr.Zero))
    {
        defaultViewHandle = NativeMethods.FindWindowEx(workerWHandle, IntPtr.Zero, "SHELLDLL_DefView", null);
        errorCode = Marshal.GetLastWin32Error();
    }

    if (!defaultViewHandle.Equals(IntPtr.Zero))
    {
        return defaultViewHandle;
    }
    else if (errorCode != NativeMethods.ERROR_SUCCESS)
    {
        Marshal.ThrowExceptionForHR(errorCode);
    }

    shellWindowHandle = IntPtr.Zero;

    // Try the hard way. In some systems "SHELLDLL_DefView" is a child or a child of "Progman".
    if (NativeMethods.EnumWindows(EnumWindowsProc, progmanHandle) == 0)
    {
        errorCode = Marshal.GetLastWin32Error();
        if (errorCode != NativeMethods.ERROR_SUCCESS)
        {
            Marshal.ThrowExceptionForHR(errorCode);
        }
    }

    // Try the even more harder way. Just in case "SHELLDLL_DefView" is in another desktop.
    if (shellWindowHandle.Equals(IntPtr.Zero))
    {
        if (NativeMethods.EnumDesktopWindows(IntPtr.Zero, EnumWindowsProc, progmanHandle))
        {
            errorCode = Marshal.GetLastWin32Error();
            if (errorCode != NativeMethods.ERROR_SUCCESS)
            {
                Marshal.ThrowExceptionForHR(errorCode);
            }
        }
    }

    return shellWindowHandle;
}

En ciertas situaciones, aún en los tiempos del .NET Framework, todavía sigue siendo útil conseguir un handle: denme un handle y moveré el mundo. O al menos, ocultaré los íconos del escritorio, API de Win32 mediante. Hasta la próxima.

Written by fernandomachadopiriz

08/08/2010 at 23:52

Publicado en C# 4.0

Etiquetado con

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.