2 * PROJECT: ReactOS system libraries
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll\win32\stobject\stobject.c
5 * PURPOSE: Systray shell service object
6 * PROGRAMMERS: Copyright 2014 Robert Naumann
13 WINE_DEFAULT_DEBUG_CHANNEL(stobject
);
15 const GUID CLSID_SysTray
= { 0x35CEC8A3, 0x2BE6, 0x11D2, { 0x87, 0x73, 0x92, 0xE2, 0x20, 0x52, 0x41, 0x53 } };
17 class CShellTrayModule
: public CComModule
23 public CComCoClass
<CSysTray
, &CLSID_SysTray
>,
24 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
25 public IOleCommandTarget
27 // TODO: keep icon handlers here
31 virtual ~CSysTray() {}
33 // *** IOleCommandTarget methods ***
34 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
)
40 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
42 if (!IsEqualGUID(*pguidCmdGroup
, CGID_ShellServiceObject
))
47 case OLECMDID_NEW
: // init
48 DbgPrint("CSysTray Init TODO: Initialize tray icon handlers.\n");
50 case OLECMDID_SAVE
: // shutdown
51 DbgPrint("CSysTray Shutdown TODO: Shutdown.\n");
57 DECLARE_REGISTRY_RESOURCEID(IDR_SYSTRAY
)
58 DECLARE_NOT_AGGREGATABLE(CSysTray
)
59 DECLARE_PROTECT_FINAL_CONSTRUCT()
61 BEGIN_COM_MAP(CSysTray
)
62 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
67 BEGIN_OBJECT_MAP(ObjectMap
)
68 OBJECT_ENTRY(CLSID_SysTray
, CSysTray
)
71 CShellTrayModule gModule
;
73 HINSTANCE g_hInstance
;
75 HRESULT
RegisterShellServiceObject(REFGUID guidClass
, LPCWSTR lpName
, BOOL bRegister
)
77 const LPCWSTR strRegistryLocation
= L
"Software\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad";
79 OLECHAR strGuid
[128]; // shouldn't need so much!
82 if (StringFromGUID2(guidClass
, strGuid
, 128))
84 if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE
, strRegistryLocation
, 0, KEY_WRITE
, &hKey
))
88 LONG cbGuid
= (lstrlenW(strGuid
) + 1) * 2;
89 ret
= RegSetValueExW(hKey
, lpName
, 0, REG_SZ
, (const BYTE
*) strGuid
, cbGuid
);
93 ret
= RegDeleteValueW(hKey
, lpName
);
99 return /*HRESULT_FROM_NT*/(ret
); // regsvr32 considers anything != S_OK to be an error
103 void *operator new (size_t, void *buf
)
110 DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID fImpLoad
)
112 if (fdwReason
== DLL_PROCESS_ATTACH
)
114 /* HACK - the global constructors don't run, so I placement new them here */
115 new (&gModule
) CShellTrayModule
;
116 new (&_AtlWinModule
) CAtlWinModule
;
117 new (&_AtlBaseModule
) CAtlBaseModule
;
118 new (&_AtlComModule
) CAtlComModule
;
120 g_hInstance
= hinstDLL
;
121 DisableThreadLibraryCalls(g_hInstance
);
123 gModule
.Init(ObjectMap
, g_hInstance
, NULL
);
125 else if (fdwReason
== DLL_PROCESS_DETACH
)
135 DllCanUnloadNow(void)
137 return gModule
.DllCanUnloadNow();
141 DllRegisterServer(void)
143 HRESULT hr
= gModule
.DllRegisterServer(FALSE
);
147 return RegisterShellServiceObject(CLSID_SysTray
, L
"SysTray", TRUE
);
151 DllUnregisterServer(void)
153 RegisterShellServiceObject(CLSID_SysTray
, L
"SysTray", FALSE
);
155 return gModule
.DllUnregisterServer(FALSE
);
164 return gModule
.DllGetClassObject(rclsid
, riid
, ppv
);