/*
* 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");
return hr;
}
- return S_OK;
+ return InitNetShell();
}
HRESULT CSysTray::ShutdownIcons()
return hr;
}
- return S_OK;
+ return ShutdownNetShell();
}
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 = { 0 };
TRACE("NotifyIcon code=%d, uId=%d, hIcon=%p, szTip=%S\n", code, uId, hIcon, szTip);
- nim.cbSize = sizeof(NOTIFYICONDATA);
+ nim.cbSize = sizeof(nim);
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)
switch (uMsg)
{
+ case WM_NCCREATE:
+ case WM_NCDESTROY:
+ return FALSE;
+
case WM_CREATE:
InitIcons();
SetTimer(1, 2000, NULL);
return TRUE;
+
case WM_TIMER:
- UpdateIcons();
+ if (wParam == 1)
+ UpdateIcons();
+ else
+ ProcessIconMessage(uMsg, wParam, lParam, lResult);
return TRUE;
+
case WM_DESTROY:
KillTimer(1);
ShutdownIcons();
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);
}