RSS

Archivo de la categoría: Desarrollo

WebCasts Windows Mobile 6.5

MSDEV ha publicado 8 Webcast de alto interés sobre desarrollo de aplicaciones en Windows Mobile 6.5. Os los recomiendo ya que tienen muy buena calidad (en todos los sentidos) y os ayudarán tanto a empezar a desarrollar sobre WM6.5 como a descubrir pequeños trucos que hasta ahora no conocíais.

  1. Getting Started with Application Development for Windows Mobile 6.5
  2. Using SQL Server Compact Edition with Windows Mobile 6.5
  3. Accessing Local Files with Windows Mobile 6.5
  4. Building a GPS-aware Application with Windows Mobile 6.5
  5. Building a Windows Mobile Application with Bing
  6. Basic Messaging with Windows Mobile 6.5
  7. Windows Mobile 6.5 Security Fundamentals
  8. Introducing the Gesture APIs in Windows Mobile 6.5
Anuncios
 
Deja un comentario

Publicado por en 28 enero, 2010 en Artículo, Desarrollo

 

Asociar extensiones de archivo a nuestra aplicación

En Windows Mobile al igual que en Windows podemos asociar una extensión de archivo para que se ejecute una aplicación determinada. Podemos asociar los archivos con una extensión (por ejemplo .rxr) para que sean abiertos con una aplicación desarrollada por nosotros.

En Windows Mobile esto lo podemos hacer modificando el registro.

AsociarArchivos

Las claves a generar se encuentran dentro de HKEY_CLASSES_ROOT.

Lo primero será crear una clave con el nombre de nuestra extensión (por ejemplo .rxr) en el valor por defecto especificamos la asociación (por ejemplo rxrfile).

Después crearemos una nueva clave en HKEY_CLASSES_ROOT con el nombre de la asociación (rxtfile), dentro de esta creemos la estructura HKEY_CLASSES_ROOT\rxrfile\Opend\Command y modificaremos el valor por defecto de Command por la ruta al ejecutable (en nuestro ejemplo nuestra propia aplicación) y lo haremos de modo que pueda recoger un parámetro (esto lo hacemos agregando %1), este parámetro se inicializara con la ruta del archivo que se esté ejecutando.

Si deseamos asociar el icono de nuestra aplicación a la extensión asociada podemos agregar la clave HKEY_CLASSES_ROOT\rxrfile\DefaultIcon y establecer el valor con la ruta del ejecutable y agregar ,0 al final.

Aquí os dejo un ejemplo de como podemos hacer todo esto.

/// <summary>
/// Asociar una extensi¢n de archivo a una aplicación
/// </summary>
/// <param name="extension">Extensión a asociar</param>
/// <param name="aplicacion">Aplicación a ejecutar</param>
private void AsociarArchivo(string extension, string aplicacion)
{
  //Creamos la key en HKEY_CLASSES_ROOT
  RegistryKey key1declaracion = Registry.ClassesRoot.CreateSubKey("." + extension);

  key1declaracion.SetValue("Default", extension + "file");

  //Creamos las siguientes claves en
//HKEY_CLASSES_ROOT\xxxfile\Shell\Open\Command
RegistryKey key2asociacion = Registry.ClassesRoot.CreateSubKey(@"\" + extension + "file" + @"\Shell\Open\Command");

// Establecemos el valor por defecto a la ruta al ejecutable a asociar,
// %1 ser  el parametro con el que se iniciar  la aplicación y
// equivaldr  al path del archivo.
key2asociacion.SetValue("Default",@"""" + aplicacion + @""" ""%1""");

//Asociamos el icono de nuestro ejecutable a la extensi¢n asociada
RegistryKey key3Icono = Registry.ClassesRoot.CreateSubKey(@"\" + extension + "file" + @"\DefaultIcon");
key3Icono.SetValue("Default", @"""" + aplicacion + @"""" + "0");
}

 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

AsociarArchivos2

 
Deja un comentario

Publicado por en 24 abril, 2009 en Desarrollo, Trucos

 

Sincronización de bases de datos con ADO.net Sync Services en VS 2008

Joaquin Raya nos envía un artículo muy interesante, una guía para utilizar Microsoft ADO.net Sync Services.

En este documento se muestra el procedimiento a seguir para sincronizar tablas con Microsoft ADO.net Sync Services. Para acelerar este proceso abusaremos de todos los diseñadores, wizards y sistemas automatizados de los que nos provee Microsoft. El código de la aplicación de pruebas es totalmente trivial, se deja como tarea para el usuario introducir escenarios más complejos.

Sync

Para una visión general del Sync Framework, proveedores de sincronización, arquitectura y etc, consultar MSDN en:

http://msdn.microsoft.com/en-us/sync/default.aspx

Para ver la guía podéis hacerlo aquí:

[PDF] >Sincronización con Sync Services [972 KB (996.178 bytes)]

Para descargar el ejemplo aquí.

 
Deja un comentario

Publicado por en 7 abril, 2009 en Artículo, Desarrollo

 

Ojito con el idioma de SQL Server en las replicas por mezcla

[Dynamics Mobile discontinuado Ver más aquí]

Hoy trasteando con algo que no tenia nada que ver con Dynamics Mobile me he "topado" con un problema que existe en el script de instalación de Dynamics Mobile Server, más concretamente en el script de SQL "3 Create pubMobile-Staging-Replication.sql"…

Y es lo siguiente, normalmente cuando realizo pruebas, instalaciones etc, el idioma del sistema operativo y aplicaciones siempre utilizo en Inglés (por temas de parches etc)…

¿Pero que ocurre si la instalación se realiza en un SQL Server en castellano?

Pues ocurre lo siguiente nos va a saltar un error como una catedral al iniciar el Agente de instantáneas.

El nombre de objeto ‘distribution.dbo.MSsnapshot_agents’ no es válido.

Y es que la base de datos de distribución en la instalación de SQL Server en castellano se llama distribución con su acento y todo por lo que ANTES de ejecutar este script debemos modificar el nombre de dicha tabla en el script.

Localizamos el código (son las últimas sentencias del script) y los sustituimos por este (Ver que solo cambia distribution por [distribución])

DECLARE @JobName varchar(100);
SELECT @JobName = [name] FROM [distribución].dbo.MSsnapshot_agents
WHERE [publication] = N’SAPBOnes’;

PRINT ‘Ejecutando agente de instantáneas: ‘ + @JobName;

EXEC msdb.dbo.sp_start_job @JobName;
GO

Lo mismo nos ocurre con el tema de permisos deberíamos buscar y reemplazar en el script BUILTIN\Administrators por BUILTIN\Administradores

Si no iniciamos el Agente de instantáneas para que cree la primera instantánea cuando intentemos conectarnos desde el dispositivo para recuperar la base de datos nos dará un error y no podremos hacer nada. Así que si se trata de algo importante… y sobre todo por el hecho de que en las dos primeras líneas de comentarios del Script ya nos avisa de que el usuario corre con el RIESGO de utilizar este código… aquí la importancia de leérselo antes de hacer nada con el.

 
 

Enlazando el evento MenuItem.Click con Reflection

Las limitaciones a las que nos vemos sometidos habitualmente los desarrolladores de Compact Framework, sobre todo si trabajamos sobre código manejado, suelen resultar muchas veces frustrantes, frustantes en el sentido de que algo que podíamos hacer de una manera sencilla en cualquier aplicación de escritorio no funciona de igual modo en la plataforma móvil.

Una de esas cosas, que de paso utilizo para el ejemplo, es poder enlazar el evento Click de un elemento MenuItem del cual desconozco su método asociado (en este caso OnClick), desde una función en código.

Lo más sencillo sería, venga va, si tienes el código fuente pues no seas desastre y mira el método que tienes asociado al evento click del MenuItem y a correr… está claro que es lo más sencillo ¿no? Pero si estás desarrollando un control que requiere ejecutar lo que el desarrollador enlace al evento Click del MenuItem la cosa se complica. Resulta que el método OnClick del MenuItem en Compact Framework esta declarado internamente como "Protected Internal vitual" así que nos olvidamos de poder invocarlo… y tampoco podemos recuperar el EventHandle al que esta asociado el evento Click del MenuItem.

Código interno del metodo OnClick dentro del control MenuItem

protected internal virtual void OnClick(EventArgs e)
{
    if (this.Click != null)
    {
        this.Click(this, e);
    }
}

Pues utilizando un poquito de reflection, podemos asociar el evento a nuestro propio código utilizando tan solo unas líneas de código.

En el ejemplo estamos asociando que cuando se dispare nuestro metodo, al que hemos llamado quickMenuItem.click, se ejecute también el método OnClicK del MenuItem que pasemos por código y por consiguiente se dispare el EventHandle asociado al click del MenuItem

using System.Reflection;
(…)
//Creamos un EventHandler y lo instanciamos con la definición del evento Click del menuItem que deseemos
EventHandler click = (EventHandler)GetPrivateField(menuItemX, "Click");
quickMenuItem.Click += click;
(…)

//Recuperamos el campo privado a enlazar
private object GetCampoPrivado(object obj, string campo)
{

      //Prestar especial atención a los atributos
      FieldInfo fi = obj.GetType().GetField(campo, BindingFlags.NonPublic|BindingFlags.GetField|BindingFlags.Instance);
      return fi.GetValue(obj);
}

Esto es realmente sencillo, y nos muestra que muchas de las limitaciones con las que nos encontramos tienen una fácil solución.

 
Deja un comentario

Publicado por en 23 febrero, 2009 en Desarrollo, Trucos

 

Centinela Bluetooth para Windows Mobile, jugando con RegistryState

Se acabó el darte cuenta al llegar al trabajo que dejaste la mochila con el portátil en casa… y es que cansado ya de salir corriendo de casa y darme cuenta "demasiado tarde" de que no llevo el portátil encima se me ocurrió inspirado en la nueva idea de Nokia (bueno no tan nueva todos conocemos los busca llaves) que están desarrollando un sistema para localizar objetos con el móvil, el desarrollar algo similar para Windows Mobile y claro, sin tener que gastarme ni un euro que esta la cosa muy mal para hacer derroches.

image_thumb_1

El objetivo ha sido crear una aplicación capaz de avisarme en la PDA si me separo de mi manos libres Bluetooth, además el aviso debe saltar aunque la aplicación NO este corriendo en ese momento y aunque la PDA NO esté encendida… Con lo que dejando el manos libres en la mochila si me alejo saltara la alarma.

Así que manos a la obra, para hacerlo tan solo he necesitado en lo que a hardware se refiere mi PDA HTC P3300 con Windows Mobile 5.0 y el manos libres Bluetooth, para todo lo demás RegistryState de Microsoft.WindowsMobile.Status y algunas llamadas a Pinvoke.

Mediante RegistryState podemos detectar cuando se produce algún cambio en cualquier clave del registro de nuestro dispositivo, y además nos genera el evento correspondiente y nos provee de los métodos necesarios para recuperar los valores que deseemos, basándonos en esto, la clave del registro HKEY_LOCAL_MACHINE\System\State\Hardware\Bluetooth se actualiza con los cambios de estado del Bluetooth de nuestro dispositivo por lo que empezaremos por ahí.

image_thumb_2

En nuestra aplicación para poder capturar dichos cambios tan solo necesitamos crear lo siguiente:

//Como detectar los cambios producidos en el registro

(…)

    const string registryKey = @"HKEY_LOCAL_MACHINE\System\State\Hardware";
    const string registryValueName = @"Bluetooth";

    Microsoft.WindowsMobile.Status.RegistryState rg;    
    rg = new RegistryState(registryKey, registryValueName);                       
    rg.Changed += new ChangeEventHandler(rg_Changed); 
(…)

void rg_Changed(object sender, ChangeEventArgs args)
{  

}

De este modo cada vez que se produzca un cambio en esta clave (Activemos o desactivemos el Bluetooth, conectemos o desconectemos un dispositivo) se ejecutara en nuestro caso la función rg_Changed.

Así que con esto ya tenemos la primera parte resuelta, en caso de tener la PDA emparejada con el manos libres, si nos dejamos el manos libres en la mochila y nos alejamos se perderá la conexión y se producirá un cambio en el estado ejecutándose el método rg_Changed, y ahí podemos poner que vibre la PDA o que suene la flauta si hace falta, pero que ocurre si nuestra aplicación NO se está ejecutando en ese momento… pues obviamente que no funcionara, pero también lo podemos resolver con cuatro líneas de código gracias al método EnableApplicationLauncher que nos permite asociar una aplicación a un evento del sistema. Es decir que si ocurre un cambio, como puede ser el del estado del Bluetooth, que ejecute la aplicación que especificaremos por código.

Para ello agregaremos

//Como hacer que se ejecute una aplicación al detectar un cambio en el estado del dispositivo

const string appId = "DetectorBT";
const string applicationFileName = @"\Archivos de programa\DetectorBT\DetectorBT.exe";
rg.EnableApplicationLauncher(appId, applicationFileName);

Así aun cuando cerremos la aplicación si nuestra PDA está encendida si se ejecuta cualquier cambio en la clave Bluetooth nuestra aplicación se ejecutara y ya tenemos otro punto solucionado… pero ahora viene "lo gordo", está claro que si nos acordamos de encender la PDA para ver que no se nos olvida nada nos acordaremos del portatil y esta claro que a las 7 de la mañana no te vas a acordar de encender la PDA por lo que debemos implementar "algo" que active la PDA para que veamos el aviso.

El como encender la pda lo podemos resolver con dos llamadas a nativo PowerPolicyNotify y SetSystemPowerState como se muestra a continuación

//Como encender la PDA mediante código

[DllImport("coredll.dll", CharSet = CharSet.Unicode)]
private static extern bool PowerPolicyNotify(int dwMessage, int dwData);

[DllImport("coredll.dll", SetLastError = true)]
static extern int SetSystemPowerState(string psState, int StateFlags, int Options);

/// <summary>
/// Despierta el dispositivo
/// </summary>
public void WakeUpPDA()
{
    PowerPolicyNotify((int)PPN_Message.PPN_UNATTENDEDMODE, 1);
    int iReturnResult = SetSystemPowerState(null, (int)PowerState.POWER_STATE_ON, (int)PowerRequirement.POWER_FORCE);
}

Así que de este modo si llamamos a WakeUpPDA cuando por ejemplo perdamos el control del manos libres y el estado vuelva a encendido y en espera (valor 9) despertamos la PDA y veremos el aviso que hayamos creado.

Con todo esto os dejo la aplicación de ejemplo Centinela Bluetooth para que alguno se anime a mejorarla, está claro que lo genial sería que fuese capaz de calcular la distancia a la que se encuentra pero en 2 horas no me ha dado tiempo a mucho mas.

Una de las opciones que estaba barajando era la de intentar estimar a que distancia se encuentra el dispositivo pero dadas las características del protocolo bluetooth y del tipo de dispositivo que estoy utilizando (uno de tipo 3 con alcance hasta 100 metros) no ha sido posible.

Todo esto está desarrollado para Windows Mobile 5.0 de ahí que utilice RegistryState en lugar de SystemSate para poder utilizar esta aplicación como ejemplo.

Saludos!!!

José Antonio Gallego

Ups, casi se me olvida aquí os dejo la solución con el ejemplo para Visual Studio 2008 y Windows Mobile 5.0 (MobileNUG.DetectorBT);

 
Deja un comentario

Publicado por en 15 enero, 2009 en Artículo, Desarrollo

 

Personalizando un control Listview

Como la mayoría de los desarrolladores el sentido del diseño lo tuve aparcado durante algún tiempo, pero a medida que te involucras en los desarrollos, y sobre todo cuando estas cerca del cliente de das cuenta que una buena funcionalidad no lo es todo, el cliente/usuario final, no tiene porque comprender la complejidad de un desarrollo y posiblemente no sepa valorarla, en cambio una interfaz de usuario atractiva cambia las cosas, algunas de las principales novedades respecto a tecnología móvil en estos últimos tiempos ha ido principalmente en esa dirección, creando nuevos medios de interacción con el usuario, como pueden ser los acelerometros, o interfaces de usuario atractivas como el Touch flow de htc… pero eso lo estoy dejando para un post posterior.

Este fin de semana rastreando por la msdn e recopilado unos cuantos métodos para crear un control Listview personalizado para Compact Framework.

Curiosamente todas las funcionalidades que vamos a utilizar para la creación de este control YA están contenidas en el mismo de forma nativa, pero por algún motivo que aún no he descubierto, estas propiedades no están accesibles en el control desde código manejado, por lo que únicamente tendremos que enviar los mensajes necesarios para activar las funcionalidades que deseemos y obtener un resultado como el de la imagen… (insisto… no soy diseñador jeje)

image_thumb_1

Para poder crear nuestro propio control listView crearemos un control personalizado que herede del control ListView y a continuación declararemos la funciones que harán las llamadas a nativo, para esto tan solo necesitamos la invocación a SendMessage (Manejado , Nativo)

Una vez agregada la llamada declararemos las propiedades que extenderán nuestro control Gradient, GridLines, BackgroundImage y DoubleBuffering éstas funciones hacen relación con las constantes LVS_EX_GRADIENT, LVS_EX_GRIDLINES, LVM_SETBKIMAGE y LVS_EX_DOUBLEBUFFER respectivamente. Si queréis ver todas las posibilidades visitar este enlace.

Como no soy muy dado a andarme por las ramas aquí os dejo un ejemplo con el código fuente del control y la aplicación de ejemplo, lo único destacar lo siguiente, he buscado los ejemplos para mostrar como utilizar la funcionalidad bien mediante p/invoke o bien mediante MessageWindow.SendMessage desde el espacio de nombres Microsoft.WindowsCE.Forms.

MobileNug.Controles.ListviewEx.zip

Un saludo a todos y espero que os sea útil, por su puesto si lo ampliáis seria fantástico que lo compartáis. Esto mismo se puede hacer con otros controles. Así que adelante.

 
Deja un comentario

Publicado por en 3 enero, 2009 en Artículo, Desarrollo