Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows 8 Tray notification bug

I'm trying to create simple Powershell script on Windows 8, that will notify me via system tray notification balloon. Code is very simple:

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon

$objNotifyIcon.Icon = "D:\1.ico"
$objNotifyIcon.BalloonTipIcon = "Info"
$objNotifyIcon.BalloonTipText = "I'm there"
$objNotifyIcon.BalloonTipTitle = "Hello!"

$objNotifyIcon.Visible = $True
$objNotifyIcon.ShowBalloonTip(10000)

1.ico is custom icon really existing on disc.

It works as it should except one small thing. I prefer to have taskbar on top of my window and it seems to make troubles for balloon: it is painted under taskbar (screen: https://dl.dropbox.com/u/1138313/systraybug.PNG). I made test application in C# with notifyIcon and got same result. But another applications like Dropbox or Skydrive haven't such problem and my script with taskbar on bottom works perfect too. I didn't find any style options in docs for NotifyIcon. Is it annoying bug or I can fix it?

Regards.

UPS: It seems, that however Dropbox app has same problem (shame on me, didn't see at first time). So this is system bug, I guess.

like image 494
Bohdan Ivanov Avatar asked Nov 20 '12 21:11

Bohdan Ivanov


1 Answers

This is known bug in Windows. The only way you may be able to override the behavior of the taskbar is to find the handle of the balloon and then use SetWindowPos to make it topmost:

BOOL WINAPI SetWindowPos(
  _In_      HWND hWnd,
  _In_opt_  HWND hWndInsertAfter,
  _In_      int X,
  _In_      int Y,
  _In_      int cx,
  _In_      int cy,
  _In_      UINT uFlags
);

MSDN: "A window can be made a topmost window either by setting the hWndInsertAfter parameter to HWND_TOPMOST and ensuring that the SWP_NOZORDER flag is not set, or by setting a window's position in the Z order so that it is above any existing topmost windows. When a non-topmost window is made topmost, its owned windows are also made topmost. Its owners, however, are not changed." See SetWindowPos for more info.

Another strategy is to demote the taskbar. Use this code to find the topmost window:

HWND FindMyTopMostWindow()
{
    DWORD dwProcID = GetCurrentProcessId();
    HWND hWnd = GetTopWindow(GetDesktopWindow());
    while(hWnd)
    {
        DWORD dwWndProcID = 0;
        GetWindowThreadProcessId(hWnd, &dwWndProcID);
        if(dwWndProcID == dwProcID)
            return hWnd;            
        hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
    }
    return NULL;
 }

Then demote the window or set the zorder of your window higher.

like image 88
Tyler Durden Avatar answered Oct 13 '22 22:10

Tyler Durden