Windows Forms – Jump List (enlaces internos)

En la publicación Windows Forms – Jump List (enlaces externos), se puede observar que un Jump List ejecuta la aplicación externa a base de argumentos desde línea de comandos.

El siguiente ejemplo está basado en el artículo Windows 7: JumpLists, en donde se usará la clase WindowsMessageHelper para enviar los parámetros a la aplicación como mensajes personalizados.

La aplicación consiste en un simple navegador con el cual se podrá cambiar de navegador haciendo uso del Jump List.

Como primera parte, se debe de agregar el paquete NuGet correspondiente a Windows API Code Pack.

Las siguientes referencias se deben de agregar manualmente en la pestaña del Explorador de soluciones. La razón de estas, es debido a que Windows API Code Pack utiliza algunos elementos de WPF para poder traer estas funcionalidades a Windows Forms.

  • PresentationCore
  • PresentationFrameWork
  • WindowsBase
  • System.Xaml

Crear una nueva clase con el nombre de WindowsMessageHelper, en el cual se agregarán las siguientes declaraciones al espacio de nombres.


using System;
using System.Runtime.InteropServices;

El código de la clase es el siguiente:


class WindowsMessageHelper
{
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    public static extern int RegisterWindowMessage(string msgName);

    public static int UsarGoogle;
    public static int UsarBing;
    public static int UsarDuckDuckGo;
    public static int UsarYahoo;

    static WindowsMessageHelper()
    {
        // Asignación de los mensajes a enviar a la aplicación
        UsarDuckDuckGo = WindowsMessageHelper.RegisterWindowMessage("Mensaje.UsarDuckDuckGo");
        UsarGoogle = WindowsMessageHelper.RegisterWindowMessage("Mensaje.UsarGoogle");
        UsarBing = WindowsMessageHelper.RegisterWindowMessage("Mensaje.UsarBing");
        UsarYahoo = WindowsMessageHelper.RegisterWindowMessage("Mensaje.UsarYahoo");

    }

    public static int RegisterMessage(string msgName)
    {
        return RegisterWindowMessage(msgName);
    }

    public static void SendMessage(string windowTitle, int msgId)
    {
        SendMessage(windowTitle, msgId, IntPtr.Zero, IntPtr.Zero);
    }

    public static bool SendMessage(string windowTitle, int msgId, IntPtr wParam, IntPtr lParam)
    {
        IntPtr WindowToFind = FindWindow(null, windowTitle);
        if (WindowToFind == IntPtr.Zero) return false;

        long result = SendMessage(WindowToFind, msgId, wParam, lParam);

        if (result == 0) return true;
        else return false;
    }
}

En esta ocasión se utilizará una clase para crear el Jump List de la aplicación, por lo que se agregará la clase ApplicationJumpList.cs al proyecto.


using System;
using System.Reflection;
using Microsoft.WindowsAPICodePack.Taskbar;

El código necesario para construir la lista es el siguiente.


class ApplicationJumpList
{
    private JumpList myJumpList;

    public ApplicationJumpList(IntPtr windowHandle)
    {
        // Crea un nuevo JumpList para la aplicación
        myJumpList = JumpList.CreateJumpListForIndividualWindow(TaskbarManager.Instance.ApplicationId, windowHandle);
        ConstruirLista();
    }

    private void ConstruirLista()
    {
        // Crea los link que ejecutarán la aplicación con la siguiente información:
        // el primero es la ruta completa al ejecutable
        // el segundo es el nombre que mostrará el Jump List
        // por último se necesita un argumento que será enviado a la aplicación al ejecutar el Jump List
        JumpListLink accionUsarGoogle = new JumpListLink(Assembly.GetEntryAssembly().Location, "Google");
        accionUsarGoogle.Arguments = "/g";

        JumpListLink accionUsarBing = new JumpListLink(Assembly.GetEntryAssembly().Location, "Bing");
        accionUsarBing.Arguments = "/b";

        JumpListLink accionUsarDuckDuckGo = new JumpListLink(Assembly.GetEntryAssembly().Location, "DuckDuckGo");
        accionUsarDuckDuckGo.Arguments = "/d";

        JumpListLink accionUsarYahoo = new JumpListLink(Assembly.GetEntryAssembly().Location, "Yahoo");
        accionUsarYahoo.Arguments = "/y";

        // Añade los links al Jump List
        myJumpList.AddUserTasks(accionUsarGoogle, accionUsarBing, accionUsarDuckDuckGo, accionUsarYahoo);
        myJumpList.Refresh();
    }
}

En el formulario se agregará un control WebBrowser y se añadirá el código necesario para interpretar el mensaje, así como también una variable pública, la cual tendrá asignado el valor del parámetro recibido en caso sea la primera instancia y esta fue ejecutada con un parámetro inicial.


public partial class MainForm : Form
{
    private ApplicationJumpList lista;
    public string PaginaInicio;

    public MainForm()
    {
        InitializeComponent();

        // Construir la lista
        lista = new ApplicationJumpList(this.Handle);
    }

    protected override void WndProc(ref Message m)
    {
        // En esta parte se interceptan los mensajes enviados a la aplicación.
        if (m.Msg == WindowsMessageHelper.UsarDuckDuckGo)
            webBrowser1.Navigate("www.duckduckgo.com");
        else if (m.Msg == WindowsMessageHelper.UsarGoogle)
            webBrowser1.Navigate("www.google.com");
        else if (m.Msg == WindowsMessageHelper.UsarBing)
            webBrowser1.Navigate("www.bing.com");
        else if (m.Msg == WindowsMessageHelper.UsarYahoo)
            webBrowser1.Navigate("www.yahoo.com");
        else
            base.WndProc(ref m);
    }

    private void MainForm_Load(object sender, EventArgs e)
    {
        // Evalúa el parámetro recibido en caso sea la primera instancia
        switch (PaginaInicio)
        {
            case "/g":
                webBrowser1.Navigate("www.google.com");
                break;
            case "/b":
                webBrowser1.Navigate("www.bing.com");
                break;
            case "/d":
                webBrowser1.Navigate("www.duckduckgo.com");
                break;
            case "/y":
                webBrowser1.Navigate("www.yahoo.com");
                break;
        }
    }
}

Para finalizar, se realizará una modificación a Program.cs para verificar si la aplicación se está ejecutando y de estarlo, enviar el mensaje correspondiente al argumento enviado por el Jump List.

En el espacio de nombres se agregará lo siguiente:

using System.Threading;

Comenté el código que se modificó en Program.cs para que se puedan adaptar a sus necesidades.


static class Program
{
   /// <summary>
   /// Punto de entrada principal para la aplicación.
   /// </summary>
   [STAThread]
   static void Main()
   {
      bool primeraInstancia = false;

      // Verifica si es la primera instancia de la aplicación, se usara un string que
      // representará el nombre de la aplicación, normalmente se usa un GUID
      Mutex mtx = new Mutex(true, "JumpListEnlacesInternos", out primeraInstancia);

      if (primeraInstancia)
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);

         MainForm frmMain = new MainForm();

         // De existir parametros, se asignaran a la variable PaginaInicio del formulario
         if (Environment.GetCommandLineArgs().Length > 1)
            frmMain.PaginaInicio = Environment.GetCommandLineArgs()[1];

         Application.Run(frmMain);
      }
      else
      {
         // De estar ejecutándose la aplicación, solamente se debe de procesar el mensaje
         // El string que se está enviando es el nombre del formulario
         if (Environment.GetCommandLineArgs().Length > 1)
         {
            switch (Environment.GetCommandLineArgs()[1])
            {
               case "/g":
               WindowsMessageHelper.SendMessage("JumpListEnlacesInternos", WindowsMessageHelper.UsarGoogle);
                  break;
               case "/b":
                  WindowsMessageHelper.SendMessage("JumpListEnlacesInternos", WindowsMessageHelper.UsarBing);
                  break;
               case "/d":
                  WindowsMessageHelper.SendMessage("JumpListEnlacesInternos", WindowsMessageHelper.UsarDuckDuckGo);
                  break;
               case "/y":
                  WindowsMessageHelper.SendMessage("JumpListEnlacesInternos", WindowsMessageHelper.UsarYahoo);
                  break;
            }
         }
      }
   }
}

Puntos a tomar en consideración

  • Al crear el mutex en Program.cs, se utiliza un string para representar a la aplicación.
  • Al utilizar la función SendMessage en Program.cs, se utiliza un string que tendrá el nombre del formulario que recibirá el mensaje.
  • En WindowsMessageHelper.cs al registrar los mensajes que serán enviados a la aplicación, se debe de utilizar un valor string para diferenciar cada uno de los mensajes.

Ejemplo

El resultado es una aplicación que permite alternar entre buscador por medio de las acciones que se agregaron al Jump List.

Jump List (enlaces internos)Al seleccionar un Jump List, la aplicación cambiará de buscador.

El pase de diapositivas requiere JavaScript.

Ejemplo – Jump List (enlaces internos)

 

 

Un comentario sobre “Windows Forms – Jump List (enlaces internos)”

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s