post icon

Integrar Aplicaciones con el escritorio de Windows 7

Como todos saben, hace unos meses que Microsoft ha lanzado su nuevo sistema operativo llamado Windows 7, el cual nos trae un montón de mejoras en cuanto a la interfaz gráfica de usuarios y su facilidad de uso. Pero no sólo queda ahí, también nos ofrece unas API completas a los desarrolladores para explotar éstas características fácilmente:

  1. Barras de Progreso Integradas
  2. Vistas Previas
  3. Botones en Thumbnail
  4. Jump List
  5. Sobreposición de Iconos

Todo esto es posible hacerlo ya con nuestro IDE de Visual Studio 2008 (ni siquiera es necesario utilizar la versión 2010 aún). Lo primero que debemos hacer es crear un formulario de windows form con C# dentro de un proyecto llamado Windows7 y dejarlo como muestra la siguiente imagen

El siguiente paso, muy importante para el avance del ejemplo es agregar las referencias necesarias que son las siguientes:

  1. PresentationCore
  2. PresentationFramework
  3. WindowsBase

En la imagen se muestras 2 de las referencias

También es necesarios otras cuatro dll, que se descargan gratuitamente del sitio de microsoft, desde este enlace, en la sección downloads encontraran los fuentes, que se deben compilar con Visual Studio, son varios proyectos. Ahora si quieren evitar todo este trabajo me he tomado la molestia de hacerlo por ustedes y lo subí al servidor gratuito GigaSize, descarga desde aquí. Estos deben ser agregados desde la lengueta Examinar de la pantalla anterior.

Ahora agregamos los siguientes usos a nuestro formulario:

1
2
3
using Windows7.DesktopIntegration;
using Microsoft.WindowsAPICodePack.Taskbar;
using Microsoft.WindowsAPICodePack.Shell;

El primer componente con el que trabajeremos es el Jump List, ¿que es esto? Es el menú desplegable que nos aparece cuando damos click derecho sobre el icono de nuestra aplicación, el cual tiene una serie de opciones por omisión. Si ejecutamos ahora nuestra aplicación y llamamos al Jump List se vería así:

Con el fin de agregar el Jump List para integrarlo con el sistema operativo en el método click del boton Jump List escribiremos el siguiente código, veremos que es realmente sencillo 🙂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void btnJumpList_Click(object sender, EventArgs e)
private void btnJumpList_Click(object sender, EventArgs e)
{
	// Agregar Jump List
	JumpList jumpList = JumpList.CreateJumpList();
	// Asignamos el link
	JumpListLink link = new JumpListLink(@"http://www.devtroce.com/", ""Navegar en DevTroce.com");
 
	// agregar la tarea
	jumpList.AddUserTasks(link);
 
	// refrescar el JL, sino no se verá en pantalla
	// no basta con solo agregarlo..
	jumpList.Refresh();
}

Con esto obtendriamos este resultado:

Con esto tenemos listo nuestro Jump List, la siguiente tarea por hacer es la crear una sobreposición de iconos o más conocido como Overlay Icon en la barra de tareas, ¿cómo hacemos esto? Pues de la siguiente manera, insertamos un objeto de alcance para toda la clase asi,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace Windows7
{
    public partial class frmWindows7 : Form
    {
        /* Agregamos un stock de iconos, para utilizarlos
         * en varios lugares del form */
        StockIcons sicons = new StockIcons();
 
        public frmWindows7()
        {
           InitializeComponent();
        }
       .
       ...

Luego en el evento click del boton Sobreponer Icono escribimos esto, que hará que aparezca el icono de una impresora sobre el logo de DevTroce.com, pudiendose asignar cualquier otro icono del stock de iconos, o uno externo. Una utilidad interesante de esto es y dejando notificaciones ya desde la barra de tareas en nuestra aplicación asi el usuario no necesitará estar con el foco en la app, también evitamos el uso molestoso e innecesario de los globos de notificaciones.

1
2
3
4
private void btnSobrePonerIcono_Click(object sender, EventArgs e)
{
	TaskbarManager.Instance.SetOverlayIcon(sicons.Printer.Icon, "Imprimiendo Documento");
}

Esa fue probablemente la implementación más sencilla de todas, ahora veremos una caracteristica que a mi personalmente me ha gustado mucho, que es la Barra de Progreso ya en la barra de tareas, los que han usado Windows 7, se habrán dado cuenta que cuando el SO hace tareas predeterminadas como copiado, movida, eliminación de ficheros,el progreso del mismo ya se puede percibir en el icono en la barra, ademas que tiene la caracteristicas de mostrar estados, por ejemplo si ocurre un error se pinta de rojo, o si se pausa la actividad se pinta de amarillo, todas estas cosas veremos como hacerlas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// variables y constantes para utilizar la barra de progreso
int valorActual = 0;
const int MAX_PROGRESS_VAL = 100;
const int INCREMENT0 = 10;
private void btnBarraProgreso_Click(object sender, EventArgs e)
{
	// aumentamos el valor actual
	valorActual += INCREMENT0;
 
	// aumentamos el progreso en la barra de tareas
	TaskbarManager.Instance.SetProgressValue(valorActual, MAX_PROGRESS_VAL);
 
	/* esta seccion de codigo no tiene mucha logica en si
	 * pero muestra bastante bien como pueden ser utilizados
	 * en caso que los necesitemos, solo quedaria agregar
	 * un poco de ingenio de parte de ustedes */
	if (valorActual == 100)
	{
		// si supera 100% cambiamos a estado de error
		TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Error);
	}
	else if (valorActual == 110)
	{
		// reiniciamos el valor actual
		valorActual = 0;
		/* y asigamos el estado en indeterminado, util
		 * en caso que no sepamos cuanto es el maximo
		 * de nuestro progreso */
		TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Indeterminate);
	}
	else
	{
		// volvemos a la normalidad
		TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal;
	}
}

Los estados se verían así mas o menos:

La siguiente caracterista a ver es los botones en los thumbnails, probablemente han usado ya Windows Media Player o AIMP 2.6 y se habrán percado que al mostrarse la vista previa del programa, este tiene 3 botones de acción, ellos por ser reproductores tienen el boton de anterior música, reproducir/pause, y siguiente música, nosotros haremos algo parecido, pero no precisamente estas caracteristicas ya que no estamos haciendo un reproductor, en cambio crearemos 3 botones, de error, advertencia e información, a modo de ejemplo, para ello necesitaremos las siguientes lineas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public partial class frmWindows7 : Form
    {
        /* Agregamos un stock de iconos, para utilizarlos
         * en varios lugares del form */
        StockIcons sicons = new StockIcons();
        // agregamos los botones del thumbnail
        ThumbnailToolbarButton btnError, btnAdvertencia, btnInformación;
 
        public frmWindows7()
        {
            InitializeComponent();
        }
 
        private void InicializarThumbBotones()
        {
            // instaciamos los 3 botones de error, advertencia, e informacion
            btnError = new ThumbnailToolbarButton(sicons.Error.Icon, "Error");
            btnAdvertencia = new ThumbnailToolbarButton(sicons.Warning.Icon, "Advertencia");
            btnInformación = new ThumbnailToolbarButton(sicons.Info.Icon, "Información");
 
            // asignamos los eventHandler correspondientes a cada boton
            btnError.Click += btnControlador;
            btnAdvertencia.Click += btnControlador;
            btnInformación.Click += btnControlador;
 
            // asignamos al taskbar estos botones, a la ventana actual
            TaskbarManager.Instance.ThumbnailToolbars.AddButtons(this.Handle, btnError, btnAdvertencia, btnInformación);
        }
 
        private void btnControlador(object sender, ThumbnailButtonClickedEventArgs e)
        {
            // objeto icono de mensaje para hacer dinamico el juego
            MessageBoxIcon msgIcon = new MessageBoxIcon();
            // enviamos en evento a este boton
            ThumbnailToolbarButton btnElegido = sender as ThumbnailToolbarButton;
 
            // switcheamos que boton fue presionado
            switch (btnElegido.Tooltip)
            {
                case "Error":
                    msgIcon = MessageBoxIcon.Error;
                    break;
                case "Advertencia":
                    msgIcon = MessageBoxIcon.Warning;
                    break;
                case "Informacion":
                    msgIcon = MessageBoxIcon.Information;
                    break;
            }
 
            // emitimos el mensaje armado dinamicamente
            MessageBox.Show("Has presionado el boton de " + btnElegido.Tooltip, this.Name, MessageBoxButtons.OK, msgIcon);
        }
 
        private void btnBotonesThumb_Click(object sender, EventArgs e)
        {
            InicializarThumbBotones();
        }
        ...


Lo que sigue es explotar las vistas previas, como ya hemos visto, de por si el sistema operativo crea una vista previa, pero si han notado cuando navegamos con Internet Explorer 8 en Windows 7, por cada pestaña que tenemos abierta se crea una vista previa, y no solo una, es lo que haremos ahora, crearemos varias vistas previas a partir de un formulario, mostraremos las imagenes que estan en los PictureBox dentro de las paginas del TabControl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// objetos personalizados de ventanas
CustomWindowsManager cwm1, cwm2;
private void btnVistaPrevia_Click(object sender, EventArgs e)
{
	cwm1 = InicializarCWM(tabNavegador.TabPages[0], picGoogle.Image);
	cwm2 = InicializarCWM(tabNavegador.TabPages[1], picTwitter.Image);
}
 
private CustomWindowsManager InicializarCWM(TabPage tabPage, Image imagen)
{
	CustomWindowsManager CWM = CustomWindowsManager.CreateWindowsManager(tabPage.Handle, this.Handle);
 
	CWM.ThumbnailRequested += (o, e) =>
	{
		e.Bitmap = new Bitmap(imagen, e.Width, e.Height);
		e.DoNotMirrorBitmap = true;
	};
 
	CWM.PeekRequested += (o, e) =>
	{
		e.Bitmap = new Bitmap(imagen, e.Width, e.Height);
		e.DoNotMirrorBitmap = true;
	};
 
	return CWM;
}

El codigo completo quedaria asi, por si alguno no lo puede armar 😛

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
using System;
using System.Drawing;
using System.Windows.Forms;
using Windows7.DesktopIntegration;
using Microsoft.WindowsAPICodePack.Taskbar;
using Microsoft.WindowsAPICodePack.Shell;
 
namespace Windows7
{
    public partial class frmWindows7 : Form
    {
        /* Agregamos un stock de iconos, para utilizarlos
         * en varios lugares del form */
        StockIcons sicons = new StockIcons();
        // agregamos los botones del thumbnail
        ThumbnailToolbarButton btnError, btnAdvertencia, btnInformación;
 
        public frmWindows7()
        {
            InitializeComponent();
 
        }
 
        private void InicializarThumbBotones()
        {
            // instaciamos los 3 botones de error, advertencia, e informacion
            btnError = new ThumbnailToolbarButton(sicons.Error.Icon, "Error");
            btnAdvertencia = new ThumbnailToolbarButton(sicons.Warning.Icon, "Advertencia");
            btnInformación = new ThumbnailToolbarButton(sicons.Info.Icon, "Información");
 
            // asignamos los eventHandler correspondientes a cada boton
            btnError.Click += btnControlador;
            btnAdvertencia.Click += btnControlador;
            btnInformación.Click += btnControlador;
 
            // asignamos al taskbar estos botones, a la ventana actual
            TaskbarManager.Instance.ThumbnailToolbars.AddButtons(this.Handle, btnError, btnAdvertencia, btnInformación);
        }
 
        private void btnControlador(object sender, ThumbnailButtonClickedEventArgs e)
        {
            // objeto icono de mensaje para hacer dinamico el juego
            MessageBoxIcon msgIcon = new MessageBoxIcon();
            // enviamos en evento a este boton
            ThumbnailToolbarButton btnElegido = sender as ThumbnailToolbarButton;
 
            // switcheamos que boton fue presionado
            switch (btnElegido.Tooltip)
            {
                case "Error":
                    msgIcon = MessageBoxIcon.Error;
                    break;
                case "Advertencia":
                    msgIcon = MessageBoxIcon.Warning;
                    break;
                case "Informacion":
                    msgIcon = MessageBoxIcon.Information;
                    break;
            }
 
            // emitimos el mensaje armado dinamicamente
            MessageBox.Show("Has presionado el boton de " + btnElegido.Tooltip, this.Name, MessageBoxButtons.OK, msgIcon);
        }
 
        private void btnJumpList_Click(object sender, EventArgs e)
        {
            // Agregar Jump List
            JumpList jumpList = JumpList.CreateJumpList();
            // Asignamos el link
            JumpListLink link = new JumpListLink(@"http://www.devtroce.com/", "Navegar en DevTroce.com");
 
            // agregar la tarea
            jumpList.AddUserTasks(link);
 
            // refrescar el JL, sino no se verá en pantalla
            // no basta con solo agregarlo..
            jumpList.Refresh();
        }
 
        private void btnSobrePonerIcono_Click(object sender, EventArgs e)
        {
            TaskbarManager.Instance.SetOverlayIcon(sicons.Printer.Icon, "Imprimiendo Documento");
        }
 
        // variables y constantes para utilizar la barra de progreso
        int valorActual = 0;
        const int MAX_PROGRESS_VAL = 100;
        const int INCREMENT0 = 10;
        private void btnBarraProgreso_Click(object sender, EventArgs e)
        {
            // aumentamos el valor actual
            valorActual += INCREMENT0;
 
            // aumentamos el progreso en la barra de tareas
            TaskbarManager.Instance.SetProgressValue(valorActual, MAX_PROGRESS_VAL);
 
            /* esta seccion de codigo no tiene mucha logica en si
             * pero muestra bastante bien como pueden ser utilizados
             * en caso que los necesitemos, solo quedaria agregar
             * un poco de ingenio de parte de ustedes */
            if (valorActual == 100)
            {
                // si supera 100% cambiamos a estado de error
                TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Error);
            }
            else if (valorActual == 110)
            {
                // reiniciamos el valor actual
                valorActual = 0;
                /* y asigamos el estado en indeterminado, util
                 * en caso que no sepamos cuanto es el maximo
                 * de nuestro progreso */
                TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Indeterminate);
            }
            else
            {
                // volvemos a la normalidad
                TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal);
            }
        }
 
        private void btnBotonesThumb_Click(object sender, EventArgs e)
        {
            InicializarThumbBotones();
        }
 
        // objetos personalizados de ventanas
        CustomWindowsManager cwm1, cwm2;
        private void btnVistaPrevia_Click(object sender, EventArgs e)
        {
            cwm1 = InicializarCWM(tabNavegador.TabPages[0], picGoogle.Image);
            cwm2 = InicializarCWM(tabNavegador.TabPages[1], picTwitter.Image);
        }
 
        private CustomWindowsManager InicializarCWM(TabPage tabPage, Image imagen)
        {
            CustomWindowsManager CWM = CustomWindowsManager.CreateWindowsManager(tabPage.Handle, this.Handle);
 
            CWM.ThumbnailRequested += (o, e) =>
            {
                e.Bitmap = new Bitmap(imagen, e.Width, e.Height);
                e.DoNotMirrorBitmap = true;
            };
 
            CWM.PeekRequested += (o, e) =>
            {
                e.Bitmap = new Bitmap(imagen, e.Width, e.Height);
                e.DoNotMirrorBitmap = true;
            };
 
            return CWM;
        }
 
    }
}

Nota: Este ejemplo está basado en casi su totalidad en las enseñanzas del MVP Juan Carlos Luis Pacheco

Comentarios desde Facebook:

Sin Comentarios aun, puedes tú ser el primero en comentar!

Deja tu Comentario

Responder