tags:

views:

212

answers:

1

Hi

I'm trying to use the Windows 7 Taskbar API to set the overlay icon of the application icon on the taskbar.

I've downloaded the samples from Microsoft, but wanted to extract that particular piece of code that does that to avoid adding a reference to a huge brick of code that I won't use most of.

I have a simple WPF app in VS 2010 on Win 7 x64.

Code-behind for my Window1.xaml is like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Interop;

namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
 public Window1()
 {
  InitializeComponent();
 }

 private static ITaskbarList3 _taskbarList;
 internal static ITaskbarList3 TaskbarList
 {
  get
  {
   if (_taskbarList == null)
   {
    if (_taskbarList == null)
    {
     _taskbarList = (ITaskbarList3)new CTaskbarList();
     _taskbarList.HrInit();
    }
   }
   return _taskbarList;
  }
 }

 private void Button_Click(object sender, RoutedEventArgs e)
 {
  TaskbarList.SetOverlayIcon(new WindowInteropHelper(Application.Current.MainWindow).Handle, SystemIcons.Question.Handle, "Test");
 }
}

[ComImportAttribute()]
[GuidAttribute("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITaskbarList3
{
 // ITaskbarList
 [PreserveSig]
 void HrInit();
 [PreserveSig]
 void AddTab(IntPtr hwnd);
 [PreserveSig]
 void DeleteTab(IntPtr hwnd);
 [PreserveSig]
 void ActivateTab(IntPtr hwnd);
 [PreserveSig]
 void SetActiveAlt(IntPtr hwnd);

 void SetOverlayIcon(
  IntPtr hwnd,
  IntPtr hIcon,
  [MarshalAs(UnmanagedType.LPWStr)] string pszDescription);
}

[GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComImportAttribute()]
internal class CTaskbarList { }
  }

When I click the button, nothing happens. No error. Icon doesn't change.

I wonder if I'm passing the correct handle to the SetOverlayIcon method.

Anyone know how to fix this?

A: 

Your ITaskBarList3 interface is wrong. Here the correct one:

public enum TBPF
{
    TBPF_NOPROGRESS = 0,
    TBPF_INDETERMINATE = 0x1,
    TBPF_NORMAL = 0x2,
    TBPF_ERROR = 0x4,
    TBPF_PAUSED = 0x8
}

public enum TBATF
{
    TBATF_USEMDITHUMBNAIL = 0x1,
    TBATF_USEMDILIVEPREVIEW = 0x2
}

public enum THB : uint
{
    THB_BITMAP = 0x1,
    THB_ICON = 0x2,
    THB_TOOLTIP = 0x4,
    THB_FLAGS = 0x8
}

public enum THBF : uint
{
    THBF_ENABLED = 0,
    THBF_DISABLED = 0x1,
    THBF_DISMISSONCLICK = 0x2,
    THBF_NOBACKGROUND = 0x4,
    THBF_HIDDEN = 0x8
}

[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
public struct THUMBBUTTON
{
    public THB dwMask;
    public uint iId;
    public uint iBitmap;
    public IntPtr hIcon;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Windows.MAX_PATH)]
    public string szTip;
    public THBF dwFlags;
}

[ComImport]
[Guid("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITaskbarList3
{
    // ITaskbarList
    void HrInit();
    void AddTab(IntPtr hwnd);
    void DeleteTab(IntPtr hwnd);
    void ActivateTab(IntPtr hwnd);
    void SetActiveAlt(IntPtr hwnd);

    // ITaskbarList2
    void MarkFullscreenWindow(
        IntPtr hwnd,
        [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);

    // ITaskbarList3
    void SetProgressValue(IntPtr hwnd, ulong ullCompleted, ulong ullTotal);
    void SetProgressState(IntPtr hwnd, TBPF tbpFlags);
    void RegisterTab(IntPtr hwndTab, IntPtr hwndMDI);
    void UnregisterTab(IntPtr hwndTab);
    void SetTabOrder(IntPtr hwndTab, IntPtr hwndInsertBefore);
    void SetTabActive(IntPtr hwndTab, IntPtr hwndMDI, TBATF tbatFlags);

    void ThumbBarAddButtons(
        IntPtr hwnd,
        uint cButtons,
        [MarshalAs(UnmanagedType.LPArray)] THUMBBUTTON[] pButtons);

    void ThumbBarUpdateButtons(
        IntPtr hwnd,
        uint cButtons,
        [MarshalAs(UnmanagedType.LPArray)] THUMBBUTTON[] pButtons);

    void ThumbBarSetImageList(IntPtr hwnd, IntPtr himl);

    void SetOverlayIcon(
        IntPtr hwnd,
        IntPtr hIcon,
        [MarshalAs(UnmanagedType.LPWStr)] string pszDescription);

    void SetThumbnailTooltip(
        IntPtr hwnd,
        [MarshalAs(UnmanagedType.LPWStr)] string pszTip);

    void SetThumbnailClip(
        IntPtr hwnd,
        [MarshalAs(UnmanagedType.LPStruct)] Rectangle prcClip);
}
arbiter
I had to make a few modifications, but it solved my problem. Thanks.
MartinHN
Which modifications you made? It is interesting to me, because I use this code by myself (however I use it mostly for taskbar progressbar). I can see only one questionable place - methods with THUMBBUTTON.
arbiter