Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
4.6 KiB

  1. #include "stdafx.h"
  2. #include "stobject.h"
  3. #include "systray.h"
  4. #include <initguid.h>
  5. // 7007ACCF-3202-11D1-AAD2-00805FC1270E CLSID_ConnectionTray
  6. DEFINE_GUID(CLSID_ConnectionTray, 0x7007ACCF,0x3202,0x11D1,0xAA,0xD2,0x00,0x80,0x5F,0xC1,0x27,0x0E);
  7. IOleCommandTarget *g_pctNetShell = NULL;
  8. extern "C"
  9. {
  10. void StartNetShell()
  11. {
  12. ASSERT(!g_pctNetShell);
  13. HRESULT hr = CoCreateInstance(CLSID_ConnectionTray, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
  14. IID_IOleCommandTarget, (void **)&g_pctNetShell);
  15. if (SUCCEEDED(hr))
  16. {
  17. g_pctNetShell->Exec(&CGID_ShellServiceObject, SSOCMDID_OPEN, 0, NULL, NULL);
  18. }
  19. }
  20. void StopNetShell()
  21. {
  22. if (g_pctNetShell)
  23. {
  24. g_pctNetShell->Exec(&CGID_ShellServiceObject, SSOCMDID_CLOSE, 0, NULL, NULL);
  25. g_pctNetShell->Release();
  26. g_pctNetShell = NULL;
  27. }
  28. }
  29. } // extern C
  30. /************************************************************************************
  31. IUnknown Implementation
  32. ************************************************************************************/
  33. HRESULT CSysTray::QueryInterface(REFIID iid, void** ppvObject)
  34. {
  35. HRESULT hr = S_OK;
  36. if ((iid == IID_IOleCommandTarget) || (iid == IID_IUnknown))
  37. {
  38. *ppvObject = (IOleCommandTarget*) this;
  39. }
  40. else
  41. {
  42. *ppvObject = NULL;
  43. hr = E_NOINTERFACE;
  44. }
  45. if (hr == S_OK)
  46. {
  47. ((IUnknown*) (*ppvObject))->AddRef();
  48. }
  49. return hr;
  50. }
  51. ULONG CSysTray::AddRef()
  52. {
  53. return InterlockedIncrement(&m_cRef);
  54. }
  55. ULONG CSysTray::Release()
  56. {
  57. if (InterlockedDecrement(&m_cRef) == 0)
  58. {
  59. delete this;
  60. return 0;
  61. }
  62. return m_cRef;
  63. }
  64. /************************************************************************************
  65. IOleCommandTarget Implementation
  66. ************************************************************************************/
  67. HRESULT CSysTray::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText)
  68. {
  69. HRESULT hr = OLECMDERR_E_UNKNOWNGROUP;
  70. if (*pguidCmdGroup == CGID_ShellServiceObject)
  71. {
  72. // We like Shell Service Object notifications...
  73. hr = S_OK;
  74. }
  75. return hr;
  76. }
  77. HRESULT CSysTray::Exec(const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG* pvaIn, VARIANTARG* pvaOut)
  78. {
  79. HRESULT hr = OLECMDERR_E_UNKNOWNGROUP;
  80. if (*pguidCmdGroup == CGID_ShellServiceObject)
  81. {
  82. // Handle Shell Service Object notifications here.
  83. switch (nCmdID)
  84. {
  85. case SSOCMDID_OPEN:
  86. hr = CreateSysTrayThread();
  87. break;
  88. case SSOCMDID_CLOSE:
  89. hr = DestroySysTrayWindow();
  90. break;
  91. default:
  92. hr = S_OK;
  93. break;
  94. }
  95. }
  96. return hr;
  97. }
  98. /************************************************************************************
  99. Constructor/Destructor Implementation
  100. ************************************************************************************/
  101. CSysTray::CSysTray(BOOL fRunTrayOnConstruct)
  102. {
  103. m_cRef = 1;
  104. InterlockedIncrement(&g_cLocks);
  105. if (fRunTrayOnConstruct)
  106. {
  107. // We are being called through SHLoadInProc - Launch the systray thread immediately
  108. CreateSysTrayThread();
  109. }
  110. }
  111. CSysTray::~CSysTray()
  112. {
  113. InterlockedDecrement(&g_cLocks);
  114. }
  115. /************************************************************************************
  116. Private Function Implementation
  117. ************************************************************************************/
  118. HRESULT CSysTray::CreateSysTrayThread()
  119. {
  120. HRESULT hr = S_OK;
  121. HANDLE hThread;
  122. DWORD dwThreadId;
  123. hThread = CreateThread(NULL, 0, CSysTray::SysTrayThreadProc, NULL, 0, &dwThreadId);
  124. if (hThread != NULL)
  125. {
  126. CloseHandle(hThread);
  127. }
  128. else
  129. hr = E_FAIL;
  130. return hr;
  131. }
  132. DWORD CSysTray::SysTrayThreadProc(void* lpv)
  133. {
  134. // We pass a "" for the command line to so that the tray applets dont' start.
  135. TCHAR szModule[MAX_PATH];
  136. GetModuleFileName(g_hinstDll, szModule, ARRAYSIZE(szModule));
  137. HINSTANCE hInstThis = LoadLibrary(szModule);
  138. int Result = SysTrayMain(g_hinstDll, NULL, TEXT(""), SW_SHOWNORMAL);
  139. FreeLibraryAndExitThread(hInstThis, (DWORD) Result);
  140. // Never gets here
  141. return 0;
  142. }
  143. HRESULT CSysTray::DestroySysTrayWindow()
  144. {
  145. HWND hExistWnd = FindWindow(SYSTRAY_CLASSNAME, NULL);
  146. if (hExistWnd)
  147. {
  148. // Destroy the window. Note that we can't use DestroyWindow since
  149. // the window is on a different thread and DestroyWindow fails.
  150. SendMessage(hExistWnd, WM_CLOSE, 0, 0);
  151. }
  152. return S_OK;
  153. }