2016-01-13 26 views
8

Ho un'applicazione desktop WPF che sta spingendo alcune notifiche utilizzando:come mostrare punta Balloon come Windows 10 Balloon punta senza stiramento icona

NotifyIcon.ShowBalloonTip(,,,ToolTipIcon.None).

Il problema è:

di Windows 10 utilizza la nuova "10 rettangolo di Windows con immagine e testo" stile per le notifiche Balloon (non so esattamente come si chiama).

Se il parametro I use ToolTipIcon.None, ottiene l'icona dell'applicazione impostata su NotifyIcon.Icon e lo visualizza in questa notifica. E questa icona è sfuocata/allungata (come se fosse stata presa un'icona troppo piccola e stirata a misura che è necessaria per l'immagine di questo pallone).

Il mio file ico contiene diverse dimensioni: 16*16, 32*32, 128*128, 256*256 ecc. Ho già provato a impostare il file dell'icona con una sola dimensione 128*128, ma non ha funzionato.

Dovrebbe funzionare?

Grazie.

+0

sai che è possibile che questo non sia possibile – tofutim

+0

https://msdn.microsoft.com/en-us/library/windows/desktop/ee330740(v=vs.85).aspx # install_icon mostra una bella icona personalizzata, quindi è possibile – tofutim

+0

Per un riferimento al problema - vedi http://stackoverflow.com/questions/35242400/windows-10-notifyicon-icon-always-looks-very-pixilated – tofutim

risposta

2

La seguente classe dovrebbe visualizzare un'icona regolare e grande nella punta del palloncino in Windows 10. Non è affatto lucido, ma dovrebbe dimostrare il concetto. Una buona parte del codice viene copiata direttamente dalla classe Microsoft NotifyIcon decompilata.

Le variazioni principali tra la classe NotifyIcon originale e questo sono:

  1. L'aggiunta (e uso) dell'elemento NOTIFYICONDATA.hBalloonIcon.
  2. L'impostazione di nOTIFYICONDATA.dwInfoFlags = NIIF_LARGE_ICON | NIIF_USER, anziché NIIF_NONE.

È possibile leggere le specifiche della struttura NOTIFYICONDATA here, ma il succo è:

  • hBalloonIcon è stato aggiunto in Vista, specificatamente per l'uso al di fuori della barra delle applicazioni.
  • NIIF_USER dice di utilizzare l'icona in hBalloonIcon come icona del fumetto.
  • NIIF_LARGE_ICON dice che l'icona del fumetto dovrebbe essere grande. Classe

NotifyIconLarge:

using System; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 

namespace BalloonNotification 
{ 
    public class NotifyIconLarge : IDisposable 
    { 
     [DllImport("shell32.dll", CharSet = CharSet.Auto)] 
     public static extern int Shell_NotifyIcon(int message, NOTIFYICONDATA pnid); 

     [DllImport("Comctl32.dll", CharSet = CharSet.Unicode)] 
     private static extern IntPtr LoadIconWithScaleDown(IntPtr hinst, string pszName, int cx, int cy, out IntPtr phico); 

     [DllImport("user32.dll", SetLastError = true)] 
     static extern bool DestroyIcon(IntPtr hIcon); 

     private const int NIIF_LARGE_ICON = 0x00000020; 
     private const int NIIF_USER = 0x00000004; 

     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
     public class NOTIFYICONDATA 
     { 
      public int cbSize = Marshal.SizeOf(typeof(NOTIFYICONDATA)); 
      public IntPtr hWnd; 
      public int uID; 
      public int uFlags; 
      public int uCallbackMessage; 
      public IntPtr hIcon; 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
      public string szTip; 
      public int dwState; 
      public int dwStateMask; 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] 
      public string szInfo; 
      public int uTimeoutOrVersion; 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] 
      public string szInfoTitle; 
      public int dwInfoFlags; 
      Guid guidItem; 
      public IntPtr hBalloonIcon; 
     } 

     private IntPtr _windowHandle; 
     private IntPtr _hIcon; 
     private bool _added; 
     private int _id = 1; 
     private string _tipText; 

     public NotifyIconLarge(IntPtr windowHandle, string iconFile, int iconSize, string tipText) 
     { 
      _windowHandle = windowHandle; 
      _tipText = tipText; 
      IntPtr result = LoadIconWithScaleDown(IntPtr.Zero, iconFile, iconSize, iconSize, out _hIcon); 
      UpdateIcon(true); 
     } 

     private void UpdateIcon(bool showIconInTray) 
     { 
      NOTIFYICONDATA nOTIFYICONDATA = new NOTIFYICONDATA(); 
      nOTIFYICONDATA.uCallbackMessage = 2048; 
      nOTIFYICONDATA.uFlags = 1; 
      nOTIFYICONDATA.hWnd = _windowHandle; 
      nOTIFYICONDATA.uID = _id; 
      nOTIFYICONDATA.hIcon = IntPtr.Zero; 
      nOTIFYICONDATA.szTip = null; 
      if (_hIcon != IntPtr.Zero) 
      { 
       nOTIFYICONDATA.uFlags |= 2; 
       nOTIFYICONDATA.hIcon = _hIcon; 
      } 
      nOTIFYICONDATA.uFlags |= 4; 
      nOTIFYICONDATA.szTip = _tipText; 
      nOTIFYICONDATA.hBalloonIcon = _hIcon; 
      if (showIconInTray && _hIcon != IntPtr.Zero) 
      { 
       if (!_added) 
       { 
        Shell_NotifyIcon(0, nOTIFYICONDATA); 
        _added = true; 
       } 
       else 
       { 
        Shell_NotifyIcon(1, nOTIFYICONDATA); 
       } 
      } 
      else 
      { 
       if (_added) 
       { 
        Shell_NotifyIcon(2, nOTIFYICONDATA); 
        _added = false; 
       } 
      } 
     } 

     public void ShowBalloonTip(int timeout, string tipTitle, string tipText, ToolTipIcon tipIcon) 
     { 
      NOTIFYICONDATA nOTIFYICONDATA = new NOTIFYICONDATA(); 
      nOTIFYICONDATA.hWnd = _windowHandle; 
      nOTIFYICONDATA.uID = _id; 
      nOTIFYICONDATA.uFlags = 16; 
      nOTIFYICONDATA.uTimeoutOrVersion = timeout; 
      nOTIFYICONDATA.szInfoTitle = tipTitle; 
      nOTIFYICONDATA.szInfo = tipText; 
      switch (tipIcon) 
      { 
       case ToolTipIcon.None: 
        nOTIFYICONDATA.dwInfoFlags = NIIF_LARGE_ICON | NIIF_USER; 
        break; 
       case ToolTipIcon.Info: 
        nOTIFYICONDATA.dwInfoFlags = 1; 
        break; 
       case ToolTipIcon.Warning: 
        nOTIFYICONDATA.dwInfoFlags = 2; 
        break; 
       case ToolTipIcon.Error: 
        nOTIFYICONDATA.dwInfoFlags = 3; 
        break; 
      } 
      int ret = Shell_NotifyIcon(1, nOTIFYICONDATA); 
     } 

     public void RemoveFromTray() 
     { 
      UpdateIcon(false); 
      if (_hIcon != IntPtr.Zero) 
       DestroyIcon(_hIcon); 
     } 

     ~NotifyIconLarge() 
     { 
      Dispose(false); 
     } 

     public void Dispose() 
     { 
      Dispose(true); 
      GC.SuppressFinalize(this); 
     } 

     public void Dispose(bool disposing) 
     { 
      RemoveFromTray(); 
     } 
    } 
} 

Dichiarare da qualche parte:

private NotifyIconLarge _nil; 

Quindi utilizzare in questo modo:

string fileName = @"C:\path_to_some_icon.ico"; 
_nil = new NotifyIconLarge(Handle, fileName, 64, "Icon Tip"); 
_nil.ShowBalloonTip(10000, "Balloon Title", "Balloon Text", ToolTipIcon.None); 

Al termine, rimuovere l'icona della barra:

_nil.RemoveFromTray(); 
+0

Sweet - Stavo solo temendo per questo approccio - lo verificherà. – tofutim