[STOBJECT] Revert b7c3398 because it was not the cause of the original problem I...
[reactos.git] / dll / shellext / stobject / csystray.cpp
index 1aec9fa..89bd5c5 100644 (file)
@@ -1,27 +1,52 @@
 /*
 * PROJECT:     ReactOS system libraries
 * LICENSE:     GPL - See COPYING in the top level directory
-* FILE:        dll\win32\stobject\csystray.cpp
+* FILE:        dll/shellext/stobject/csystray.cpp
 * PURPOSE:     Systray shell service object implementation
 * PROGRAMMERS: David Quintana <gigaherz@gmail.com>
+*              Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
 */
 
 #include "precomp.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(stobject);
+#include <undocshell.h>
+#include <shellutils.h>
 
 SysTrayIconHandlers_t g_IconHandlers [] = {
-        { Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message }
+        { Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message },
+        { Hotplug_Init, Hotplug_Shutdown, Hotplug_Update, Hotplug_Message },
+        { Power_Init, Power_Shutdown, Power_Update, Power_Message }
 };
-const int             g_NumIcons = _countof(g_IconHandlers);
-
-const GUID CLSID_SysTray = { 0x35CEC8A3, 0x2BE6, 0x11D2, { 0x87, 0x73, 0x92, 0xE2, 0x20, 0x52, 0x41, 0x53 } };
+const int g_NumIcons = _countof(g_IconHandlers);
 
 CSysTray::CSysTray() {}
 CSysTray::~CSysTray() {}
 
+HRESULT CSysTray::InitNetShell()
+{
+    HRESULT hr = CoCreateInstance(CLSID_ConnectionTray, 0, 1u, IID_PPV_ARG(IOleCommandTarget, &pctNetShell));
+    if (FAILED(hr))
+        return hr;
+
+    return pctNetShell->Exec(&CGID_ShellServiceObject,
+                             OLECMDID_NEW,
+                             OLECMDEXECOPT_DODEFAULT, NULL, NULL);
+}
+
+HRESULT CSysTray::ShutdownNetShell()
+{
+    if (!pctNetShell)
+        return S_FALSE;
+    HRESULT hr = pctNetShell->Exec(&CGID_ShellServiceObject,
+                                   OLECMDID_SAVE,
+                                   OLECMDEXECOPT_DODEFAULT, NULL, NULL);
+    pctNetShell.Release();
+    return hr;
+}
+
 HRESULT CSysTray::InitIcons()
 {
+    TRACE("Initializing Notification icons...\n");
     for (int i = 0; i < g_NumIcons; i++)
     {
         HRESULT hr = g_IconHandlers[i].pfnInit(this);
@@ -29,11 +54,12 @@ HRESULT CSysTray::InitIcons()
             return hr;
     }
 
-    return S_OK;
+    return InitNetShell();
 }
 
 HRESULT CSysTray::ShutdownIcons()
 {
+    TRACE("Shutting down Notification icons...\n");
     for (int i = 0; i < g_NumIcons; i++)
     {
         HRESULT hr = g_IconHandlers[i].pfnShutdown(this);
@@ -41,11 +67,12 @@ HRESULT CSysTray::ShutdownIcons()
             return hr;
     }
 
-    return S_OK;
+    return ShutdownNetShell();
 }
 
 HRESULT CSysTray::UpdateIcons()
 {
+    TRACE("Updating Notification icons...\n");
     for (int i = 0; i < g_NumIcons; i++)
     {
         HRESULT hr = g_IconHandlers[i].pfnUpdate(this);
@@ -56,31 +83,55 @@ HRESULT CSysTray::UpdateIcons()
     return S_OK;
 }
 
-HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
+HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
 {
     for (int i = 0; i < g_NumIcons; i++)
     {
-        HRESULT hr = g_IconHandlers[i].pfnMessage(this, uMsg, wParam, lParam);
+        HRESULT hr = g_IconHandlers[i].pfnMessage(this, uMsg, wParam, lParam, lResult);
         if (FAILED(hr))
             return hr;
 
-        if (hr != S_FALSE)
+        if (hr == S_OK)
             return hr;
     }
 
-    return S_OK;
+    // Not handled by anyone, so return accordingly.
+    return S_FALSE;
 }
 
-HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip)
+/*++
+* @name NotifyIcon
+*
+* Basically a Shell_NotifyIcon wrapper.
+* Based on the parameters provided, it changes the current state of the notification icon.
+*
+* @param code
+*        Determines whether to add, delete or modify the notification icon (represented by uId).
+* @param uId
+*        Represents the particular notification icon.
+* @param hIcon
+*        A handle to an icon for the notification object.
+* @param szTip
+*        A string for the tooltip of the notification.
+* @param dwstate
+*        Determines whether to show or hide the notification icon.
+*
+* @return The error code.
+*
+*--*/
+HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip, DWORD dwstate)
 {
-    NOTIFYICONDATA nim;
+    NOTIFYICONDATA nim = { 0 };
+
+    TRACE("NotifyIcon code=%d, uId=%d, hIcon=%p, szTip=%S\n", code, uId, hIcon, szTip);
+
     nim.cbSize = sizeof(NOTIFYICONDATA);
-    nim.uFlags = NIF_ICON | NIF_STATE | NIF_TIP;
+    nim.uFlags = NIF_MESSAGE | NIF_ICON | NIF_STATE | NIF_TIP;
     nim.hIcon = hIcon;
     nim.uID = uId;
     nim.uCallbackMessage = uId;
-    nim.dwState = 0;
-    nim.dwStateMask = 0;
+    nim.dwState = dwstate;
+    nim.dwStateMask = NIS_HIDDEN;
     nim.hWnd = m_hWnd;
     nim.uVersion = NOTIFYICON_VERSION;
     if (szTip)
@@ -180,26 +231,29 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
 
     switch (uMsg)
     {
+    case WM_NCCREATE:
+    case WM_NCDESTROY:
+        return FALSE;
+
     case WM_CREATE:
         InitIcons();
         SetTimer(1, 2000, NULL);
         return TRUE;
+
     case WM_TIMER:
         UpdateIcons();
         return TRUE;
     case WM_DESTROY:
+        KillTimer(1);
         ShutdownIcons();
         return TRUE;
     }
 
     TRACE("SysTray message received %u (%08p %08p)\n", uMsg, wParam, lParam);
 
-    hr = ProcessIconMessage(uMsg, wParam, lParam);
+    hr = ProcessIconMessage(uMsg, wParam, lParam, lResult);
     if (FAILED(hr))
         return FALSE;
 
-    if (hr == S_FALSE)
-        return FALSE;
-
-    return TRUE;
+    return (hr == S_OK);
 }