Funcionalidades que no se ejecutan correctamente en Virtual PC 2007

A la hora de trabajar con máquinas virtuales, Virtual PC 2007 es una herramienta que soluciona muchas facetas de este campo. Pero a la hora de instalar dicha herramienta parece que todo funciona de forma correcta. Te descargas la última versión, creas la correspondiente máquina virtual. A la hora de empezar a trabajar con ella te encuentras, que muchas de las características que solías tener en versiones anteriores no funcionan, como por ejemplo el funcionamiento del ratón dentro de la ventana de nuestra máquina, el poder arrastrar elementos al escritorio, cambiar el tamaño de la ventana a nuestro antojo etc. Cómo podemos solucionar este pequeño inconveniente, al descargar la versión más reciente, también te descargas un complemento importante Virtual Machine Additions, dicho añadido lo podemos encontrar en forma de ISO en C:Program FilesMicrosoft Virtual PCVirtual Machine Additions. El paso que debemos ejecutar es iniciar el sistema operativo de la correspondiente máquina virtual, seguidamente ir a las opciones de configuración de la ventana de nuestra máquina virtual. Seleccionaremos Cd-> Capturar imagen ISO para después navegar hasta la ruta indicada con anterioridad e instalar el complemento citado.

De este modo Virtual Machine Additions añade las siguientes características:

  • Drag and drop
  • Folder sharing
  • Integrated mouse
  • Optimized video drivers
  • Time synchronization
  • Clipboard sharing
  • Improved operating system performance
  • Dynamic resizing of the virtual machine window, which automatically adjusts the size of the guest operating system desktop
  • Sound driver compatible with Windows Vista

 

Introducir el control SaveFileDialog en Silverlight 3

En la siguiente entrada voy a describir la inclusión de una utilidad de uso frecuente, el SaveFileDialog, en una aplicación web creada con Silverlight 3.

Empezaré con la creación de los controles con los que va interactuar el usuario. En este caso son un botón, que ejercerá de desencadenante de la acción descrita con anterioridad y un TextBlock que se encargará de mostrar los posibles mensajes de error.

<UserControl

x:Class=»SaveDialog.MainPage»

xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»

xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»

xmlns:navigation=»clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation»

xmlns:uriMapper=»clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation»

xmlns:d=»http://schemas.microsoft.com/expression/blend/2008″ xmlns:mc=»http://schemas.openxmlformats.org/markup-compatibility/2006″

mc:Ignorable=»d» d:DesignWidth=»640″ d:DesignHeight=»480″>

 

<Canvas x:Name=»LayoutRoot» Background=»White»>

<Button x:Name=»btnSaveFile» Width=»100″ Height=»20″

Content=»Guardar Archivo» Click=»btnSaveFile_Click»

Canvas.Top=»10″ Canvas.Left=»10″></Button>

<TextBlock x:Name=»tblError» Canvas.Top=»40″ Canvas.Left=»10″></TextBlock>

</Canvas>

 

</UserControl>

El código que cobra una verdadera importancia es el siguiente código Behind:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.IO;

using SaveDialog.FilesServiceReference;

 

namespace SaveDialog

{

public partial class MainPage : UserControl

{

#region Fields

private SaveFileDialog dialog;

#endregion

 

#region Constructors

public MainPage()

{

InitializeComponent();

 

this.dialog = new SaveFileDialog();

 

try

{

this.dialog.DefaultExt = «.txt»;

this.dialog.Filter = «Archivos de Texto|*.txt|Archivos de Registro|*.log|Todos los Archivos|*.*»;

this.dialog.FilterIndex = 2;

}

catch (Exception ex)

{

this.tblError.Text = «Error al configurar el SaveFileDialog: « + ex.Message;

}

}

#endregion

 

#region Handlers

private void btnSaveFile_Click(object sender, RoutedEventArgs e)

{

bool? dialogResult = this.dialog.ShowDialog();

 

if (dialogResult == true)

{

try

{

FilesServiceReference.FilesClient fileClient

= new FilesClient();

fileClient.GetFileCompleted

+= new EventHandler<GetFileCompletedEventArgs>(

fileClient_GetFileCompleted);

fileClient.GetFileAsync();

 

this.tblError.Text = «Opteniendo Archivo desde el Servidor…»;

}

catch (Exception ex)

{

this.tblError.Text = «Error de llamada al Servicio: « + ex.Message;

}

}

}

void fileClient_GetFileCompleted(object sender, GetFileCompletedEventArgs e)

{

try

{

byte[] fileBytes = e.Result as byte[];

 

using (Stream fs = (Stream)this.dialog.OpenFile())

{

fs.Write(fileBytes, 0, fileBytes.Length);

fs.Close();

 

this.tblError.Text = «El Archivo ha sido guardado correctamente!»;

}

}

catch (Exception ex)

{

this.tblError.Text = «Error Al obtener el resultado: « + ex.Message;

}

}

#endregion

 

}

}

¿Demasiado código que no entiendes? Tranquilo, como puedes observar, he reseñado las partes que son pieza clave en este conjunto de código y te las voy a explicar detalladamente.

Para que mi aplicación se ponga en marcha lo primero es crear una instancia de la clase SaveFileDialog:

private SaveFileDialog dialog;

Seguidamente tengo que tenerlo incializado en el constructor.

this.dialog = new SaveFileDialog();

Ahora voy a cambiar algunas de las propiedades originales del objeto SaveFileDialog del siguiente modo:

this.dialog.DefaultExt = «.txt»;

this.dialog.Filter = «Archivos de Texto|*.txt|Archivos de Registro|*.log|Todos los Archivos|*.*»;

this.dialog.FilterIndex = 2;

 

La primera propiedad que he modificado es la extensión del archivo que guardará por defecto,en este caso .txt.La segunda propiedad,es el filtro que va aplicar nuestro control, a la hora de visualizar los archivos que mi equipo contiene.La última propiedad es el indice del formato de texto que aparecerá en nuestro control, en este caso me aparecerá por defecto Archivos de Registro ya que he elegido la opción dos,cabe destacar que el indice no comienza en cero.

 

Continuando, al presionar sobre el botón para guardar el archivo, este realiza una llamada al método ShowDialog de la clase SaveFileDialog().

 

bool? dialogResult = this.dialog.ShowDialog();

Después compruebo que es verdadera la petición realizada con anterioridad.

if (dialogResult == true)

 

Al ser verdadero el resultado devuelto, realizo una llamada al servicio para obtener un archivo de texto desde el servidor.

Este archivo es tomado como un Array de Bytes, que escribiremos y devolveremos a través del método OpenFile de la clase SaveFileDialog.

 

using (Stream fs = (Stream)this.dialog.OpenFile())

{

fs.Write(fileBytes, 0, fileBytes.Length);

fs.Close();

this.tblError.Text = «El Archivo ha sido guardado correctamente!»;

}

 

Por último informaré al usuario que el archivo ha sido guardado correctamente, mediante un mesaje mostrandolo en pantalla.

Para finalizar como veis, a través de silverlight3 podemos utilizar un control que se usa con asidua frecuencia en la realización de las tareas diarias de nuestro trabajo, sin demasiada complejidad a la hora de crear el citado control.

Rasca y gana con InkCanvas

A través del control InkCanvas de Windows Presentation Foundation. Deseo mostrar una aplicación que pretende imitar a un décimo del rasca y gana o por podernos imaginar un cristal lleno de vaho que pretendemos limpiar para vernos reflejados. ¿Cómo vamos a lograrlo?, la solución es la utilización de uno de los controles del XAML de WPF (InkCanvas). Este se situará detrás de la imagen, así será invisible para el usuario pero nosotros podemos aprovechar todas las posibilidades que este control nos ofrece. Para asegurarnos que los clic del usuario se realicen sobre InkCanvas y nos sobre la propia imagen, tenemos que establecer la propiedad IsHitTestVisible como False.

El siguiente paso que debemos seguir es la inclusión el control VisualBrush dentro de la propiedad OpacityMask de la imagen. Para que la imagen sea visible a medida que se pinta, tenemos que pintar sobre el InkCanvas directamente. Esta funcionalidad la conseguiremos enlazando la propiedad Visual del control VisualBrush con InkCanvas (<VisualBrush Visual="{Binding ElementName=inkCanvas}"/>).

Por defecto el fondo de Inkcanvas es blanco y esta es una de las razones por las que imagen se muestra. Para evitar que se vea la imagen deberemos establecer la propiedad Background a transparente otorgándole el valor x:Null (Background="{x:Null}). También debemos otorgarle el mismo valor al Background en el Grid que contiene los controles citados con anterioridad.

Como inicialmente el grosor del pincel es demasiado pequeño, debemos aumentar el tamaño de este para que no se haga tan pesado quitar la capa que tapa la imagen, para ello utilizaremos los atributos de dibujo del InkCanvas (<DrawingAttributes Height="25" Width="25"/>).

Por último añadimos un borde para dar aspecto de un marco en un espejo o el borde del rasca y gana.

El código completo del proyecto es el siguiente:

<Window x:Class="Brush.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Window1" Height="300" Width="300">

<Border Background="#FF909090" BorderBrush="#FF000000"

BorderThickness="2,2,2,2">

<Grid Width="Auto" Height="Auto" Background="{x:Null}">

<InkCanvas x:Name="inkCanvas"

Background="{x:Null}">

<InkCanvas.DefaultDrawingAttributes>

<DrawingAttributes Height="25" Width="25"/>

</InkCanvas.DefaultDrawingAttributes>

</InkCanvas>

<Image IsHitTestVisible="False"

Source="Cein.JPG" Stretch="Fill">

<Image.OpacityMask>

<VisualBrush

Visual="{Binding ElementName=inkCanvas}"/>

</Image.OpacityMask>

</Image>

</Grid>

</Border>

 

 

</Window>

 

El resultado visual de nuestro proyecto es el siguiente:

 

 1

 

 

Servicio de traducción Bing integrado en Silverlight 3

La puesta en marcha del nuevo navegador de Microsoft «Bing«, trae consigo un API de la que podemos sacar cierto provecho. En esta entrada vamos a centrarnos en el servicio de traducción que ofrece la mencionada API. Comenzaremos con la obtención de un AppID a través del registro mediante Live ID, de este modo podremos empezar a desarrollar nuestro proyecto.

 0

El acceso a los servicios de Bing lo podemos conseguir de tres formas distintas:

De las tres opciones nos quedamos con SOAP para desarrollar el proyecto que nos ocupa. Abrimos Visual Studio 2008, creamos un nuevo proyecto de Silverlight 3. El siguiente paso que debemos seguir es agregar la referencia del servicio que vamos a utilizar, la url que utilizamos en el servicio de traducción de Bing es la siguiente: http://api.microsofttranslator.com/V1/SOAP.svc.

 

 1

Seguidamente creamos nuestra interfaz para poder realizar la traducción a través de XAML en MainPage.Xaml introduciendo el siguiente texto:

<StackPanel HorizontalAlignment=»Center»>

 

<TextBlock>Idioma Original</TextBlock>

<ComboBox x:Name=»comboOrigen»

Width=»250″></ComboBox>

 

<TextBlock>Texto Original</TextBlock>

<TextBox x:Name=»textoOrigen»

Height=»56″ Width=»250″ FontSize=»34″/>

 

<TextBlock>Idioma de traducción</TextBlock>

<ComboBox x:Name=»comboDestino»

Width=»250″></ComboBox>

 

<TextBlock>Texto traducido</TextBlock>

<TextBox x:Name=»textoDestino»

Height=»56″ Width=»250″ FontSize=»34″/>

 

<Button x:Name=»botonTraducir»

Click=»botonTraducir_Click»

Content=»Traducir» Width=»50″/>

 

</StackPanel>

Como podemos observar la interfaz está compuesta de un ComboBox para elegir el idioma original y el idioma de la traducción y dos bloques de texto para introducir el texto que queremos traducir y el resultado de la traducción. Por último incluimos un botón para lanzar el servicio de traducción.

Nos situamos en MainPage.Xaml.cs e introducimos las librerías que nos van hacer falta para que nuestro proyecto se ejecute de forma correcta.

 

using System.Collections.ObjectModel;

 

 

using traductorBing.traductor;

 

 

Debemos declarar una serie de variables, que serán importantes en los siguientes pasos de nuestro proyecto, cabe destacar la utilización del AppID obtenido con anterioridad, en dicha declaración.

// Referenciar el servicio SOAP de traducción en nuestro proyecto

traductor.LanguageServiceClient lt = new LanguageServiceClient();

// AppId para autentificar los servicios de Bing

string AppId = «XXXXXXXXXXXXXXXXXXXXXXXXXXXXX»;

// Collecion de Idiomas

ObservableCollection<string> langcodes;

Debido a que el servicio utiliza métodos asincronos debemos generar los Handlers que son necesarios, realizamos la acción mencionada en el Load de nuestra aplicación.

private void UserControl_Loaded(object sender, RoutedEventArgs e)

{

// Handlers

lt.TranslateCompleted +=

new EventHandler<TranslateCompletedEventArgs>

(lt_TranslateCompleted);

lt.GetLanguageNamesCompleted +=

new EventHandler<GetLanguageNamesCompletedEventArgs>

(lt_GetLanguageNamesCompleted);

lt.GetLanguagesCompleted +=

new EventHandler<GetLanguagesCompletedEventArgs>

(lt_GetLanguagesCompleted);

}

Sin abandonar el Load de la aplicación, vamos a introducir los diferentes idiomas en los combos.A la vez guardamos las claves de los mismos con el fin de saber que idiomas deseamos pasar al servicio.

// Evento encargado de guardar la lista de idiomas disponibles

// Nos suministra el código del Idioma

lt.GetLanguageNamesAsync(AppId, Language.IetfLanguageTag);

 

// Evento encargado de llenar los combos de Idiomas

// Nos suministra la descripción del Idioma

lt.GetLanguagesAsync(AppId);

El siguiente paso es la creación de los Handlers que se encargarán de suministrarnos los diferentes idiomas.

// Guarda la lista de idiomas disponibles

protected void lt_GetLanguagesCompleted(object sender,

GetLanguagesCompletedEventArgs e)

{

if (e.Error == null)

{

langcodes = e.Result;

}

}

 

// Llena los combos de Idiomas

protected void lt_GetLanguageNamesCompleted(Object sender,

GetLanguageNamesCompletedEventArgs e)

{

if (e.Error == null)

{

comboOrigen.ItemsSource = e.Result;

comboDestino.ItemsSource = e.Result;

 

// El Origen por defecto es Inglés

comboOrigen.SelectedIndex =

langcodes.IndexOf(«en»);

// El Destino por defecto es Español

comboDestino.SelectedIndex =

langcodes.IndexOf(«es»);

}

}

Como guinda del pastel, vamos a realizar la parte que permite realizar la traducción.Al presionar el correspondiente botón, este llamará a un método que realiza la acción mencionada con anterioridad.Como es asincrono, cuando termine se encargará de llamar al Handler que hemos creado en el Load de nuestra aplicación.

private void botonTraducir_Click(object sender,

RoutedEventArgs e)

{

if (comboOrigen.SelectedItem != null &&

comboDestino.SelectedItem != null)

{

lt.TranslateAsync(AppId, textoOrigen.Text,

(langcodes[comboOrigen.SelectedIndex].ToString()),

(langcodes[comboDestino.SelectedIndex].ToString()));

}

}

 

// Recibe el texto traducido del Servicio

protected void ls_TranslateCompleted(Object sender,

TranslateCompletedEventArgs e)

{

if (e.Error == null)

{

textoDestino.Text = e.Result;

}

}

Este es el resultado de la utilización del servicio de traducción que nos ofrece el nuevo buscador de Microsoft.

 

 2