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.

385 lines
8.0 KiB

  1. #include "Precomp.h"
  2. #include "Resource.h"
  3. #include "confroom.h"
  4. #include "ias.h"
  5. #include "NmEnum.h"
  6. #include "SDKInternal.h"
  7. #include "NmConference.h"
  8. #include "NmChannel.h"
  9. #include "NmChannelAppShare.h"
  10. #include "NmSharableApp.h"
  11. #include "SDKWindow.h"
  12. CNmChannelAppShareObj::CNmChannelAppShareObj()
  13. {
  14. DBGENTRY(CNmChannelAppShareObj::CNmChannelAppShareObj);
  15. DBGEXIT(CNmChannelAppShareObj::CNmChannelAppShareObj);
  16. }
  17. CNmChannelAppShareObj::~CNmChannelAppShareObj()
  18. {
  19. DBGENTRY(CNmChannelAppShareObj::~CNmChannelAppShareObj);
  20. for(int j = 0; j < m_ArySharableApps.GetSize(); ++j)
  21. {
  22. m_ArySharableApps[j]->Release();
  23. }
  24. m_ArySharableApps.RemoveAll();
  25. DBGEXIT(CNmChannelAppShareObj::~CNmChannelAppShareObj);
  26. }
  27. //static
  28. HRESULT CNmChannelAppShareObj::CreateInstance(CNmConferenceObj* pConfObj, INmChannel** ppChannel)
  29. {
  30. DBGENTRY(CNmChannelAppShareObj::CreateInstance);
  31. HRESULT hr = S_OK;
  32. typedef CNmChannel<CNmChannelAppShareObj, &IID_INmChannelAppShare, NMCH_SHARE> channel_type;
  33. channel_type* p = NULL;
  34. p = new CComObject<channel_type>(NULL);
  35. if (p != NULL)
  36. {
  37. if(ppChannel)
  38. {
  39. p->SetVoid(NULL);
  40. hr = p->QueryInterface(IID_INmChannel, reinterpret_cast<void**>(ppChannel));
  41. if(SUCCEEDED(hr))
  42. {
  43. // We don't have to RefCount this because our lifetime is
  44. // contained in the CConf's lifetime
  45. p->m_pConfObj = pConfObj;
  46. }
  47. if(FAILED(hr))
  48. {
  49. delete p;
  50. *ppChannel = NULL;
  51. }
  52. }
  53. else
  54. {
  55. hr = E_POINTER;
  56. }
  57. }
  58. else
  59. {
  60. hr = E_OUTOFMEMORY;
  61. }
  62. DBGEXIT_HR(CNmChannelAppShareObj::CreateInstance,hr);
  63. return hr;
  64. }
  65. ///////////////////////////////////////////////////////////////////////////////////
  66. // INmChannelAppShare methods
  67. ///////////////////////////////////////////////////////////////////////////////////
  68. STDMETHODIMP CNmChannelAppShareObj::GetState(NM_SHARE_STATE *puState)
  69. {
  70. DBGENTRY(CNmChannelAppShareObj::GetState);
  71. HRESULT hr = E_UNEXPECTED;
  72. INmMember* pMember = GetConfObj()->GetLocalSDKMember();
  73. if(pMember)
  74. {
  75. hr = pMember->GetShareState(puState);
  76. }
  77. DBGEXIT_HR(CNmChannelAppShareObj::GetState,hr);
  78. return hr;
  79. }
  80. STDMETHODIMP CNmChannelAppShareObj::SetState(NM_SHARE_STATE uState)
  81. {
  82. DWORD uf;
  83. HRESULT hr = S_OK;
  84. if (!(S_OK == IsActive()))
  85. return E_FAIL;
  86. if(!GetConfObj() || !GetConfObj()->GetLocalSDKMember())
  87. {
  88. return E_UNEXPECTED;
  89. }
  90. if(NM_SHARE_UNKNOWN)
  91. {
  92. return E_FAIL;
  93. }
  94. else
  95. {
  96. if(NM_SHARE_WORKING_ALONE == uState)
  97. {
  98. return ::AllowControl(false);
  99. }
  100. if(NM_SHARE_COLLABORATING == uState)
  101. {
  102. return ::AllowControl(true);
  103. }
  104. if(NM_SHARE_IN_CONTROL == uState)
  105. {
  106. NM_SHARE_STATE uCurrentState;
  107. if(SUCCEEDED(hr = GetState(&uCurrentState)))
  108. {
  109. if(NM_SHARE_COLLABORATING == uCurrentState)
  110. {
  111. // Yank control from the person that is controlling you
  112. return ::RevokeControl(0);
  113. }
  114. }
  115. else
  116. {
  117. return hr;
  118. }
  119. return ::AllowControl(true);
  120. }
  121. }
  122. return E_UNEXPECTED;
  123. }
  124. //static
  125. HRESULT CNmChannelAppShareObj::GetSharableAppName(HWND hWnd, LPTSTR sz, UINT cchMax)
  126. {
  127. HRESULT hr = S_OK;
  128. ASSERT(sz);
  129. ::GetWindowText(hWnd, sz, cchMax);
  130. return hr;
  131. }
  132. static INmSharableApp* _SharableAppAryHasThisHWND(CSimpleArray<INmSharableApp*>& ArySharableApps, HWND hWnd)
  133. {
  134. for(int i = 0; i < ArySharableApps.GetSize(); ++i)
  135. {
  136. HWND h;
  137. if(SUCCEEDED(ArySharableApps[i]->GetHwnd(&h)))
  138. {
  139. if(hWnd == h) return ArySharableApps[i];
  140. }
  141. }
  142. return NULL;
  143. }
  144. STDMETHODIMP CNmChannelAppShareObj::EnumSharableApp(IEnumNmSharableApp **ppEnum)
  145. {
  146. DBGENTRY(CNmChannelAppShareObj::EnumSharableApp);
  147. HRESULT hr = E_UNEXPECTED;
  148. IAS_HWND_ARRAY* pAry;
  149. hr = ::GetShareableApps(&pAry);
  150. if(SUCCEEDED(hr))
  151. {
  152. for(UINT i = 0; i < pAry->cEntries; ++i)
  153. {
  154. HWND hWnd = pAry->aEntries[i].hwnd;
  155. TCHAR szName[MAX_PATH];
  156. if(!_SharableAppAryHasThisHWND(m_ArySharableApps, hWnd))
  157. {
  158. hr = GetSharableAppName(hWnd, szName, CCHMAX(szName));
  159. if(FAILED(hr)) goto end;
  160. INmSharableApp* pApp;
  161. hr = CNmSharableAppObj::CreateInstance(hWnd, szName, &pApp);
  162. if(SUCCEEDED(hr))
  163. {
  164. m_ArySharableApps.Add(pApp);
  165. }
  166. }
  167. }
  168. hr = CreateEnumFromSimpleAryOfInterface<IEnumNmSharableApp, INmSharableApp>(m_ArySharableApps, ppEnum);
  169. FreeShareableApps(pAry);
  170. }
  171. end:
  172. DBGEXIT_HR(CNmChannelAppShareObj::EnumSharableApp,hr);
  173. return hr;
  174. }
  175. ///////////////////////////////////////////////////////////////////////////////
  176. // IInternalChannelObj methods
  177. ///////////////////////////////////////////////////////////////////////////////
  178. STDMETHODIMP CNmChannelAppShareObj::GetInternalINmChannel(INmChannel** ppChannel)
  179. {
  180. DBGENTRY(CNmChannelAppShareObj::GetInternalINmChannel);
  181. HRESULT hr = S_OK;
  182. if(ppChannel)
  183. {
  184. hr = GetUnknown()->QueryInterface(IID_INmChannel, reinterpret_cast<void**>(ppChannel));
  185. }
  186. else
  187. {
  188. hr = E_POINTER;
  189. }
  190. DBGEXIT_HR(CNmChannelAppShareObj::GetInternalINmChannel,hr);
  191. return hr;
  192. }
  193. HRESULT CNmChannelAppShareObj::ChannelRemoved()
  194. {
  195. HRESULT hr = S_OK;
  196. RemoveMembers();
  197. CNmConferenceObj* pConfObj = GetConfObj();
  198. if(pConfObj)
  199. {
  200. hr = pConfObj->Fire_ChannelChanged(NM_CHANNEL_REMOVED, com_cast<INmChannel>(GetUnknown()));
  201. }
  202. else
  203. {
  204. ERROR_OUT(("ChannelRemoved, but no ConfObject"));
  205. hr = E_UNEXPECTED;
  206. }
  207. return hr;
  208. }
  209. // interface INmChannelAppShareNotify methods
  210. STDMETHODIMP CNmChannelAppShareObj::StateChanged(NM_SHAPP_STATE uState,INmSharableApp *pApp)
  211. {
  212. if(pApp)
  213. {
  214. HWND hWnd;
  215. if(SUCCEEDED(pApp->GetHwnd(&hWnd)))
  216. {
  217. INmSharableApp* pExistingApp = _SharableAppAryHasThisHWND(m_ArySharableApps, hWnd);
  218. if(!pExistingApp)
  219. {
  220. pExistingApp = pApp;
  221. pExistingApp->AddRef();
  222. m_ArySharableApps.Add(pExistingApp);
  223. }
  224. Fire_StateChanged(uState, pExistingApp);
  225. }
  226. }
  227. return S_OK;
  228. }
  229. ///////////////////////////////////////////////////////////////////////////////
  230. // Helpers
  231. ///////////////////////////////////////////////////////////////////////////////
  232. HRESULT CNmChannelAppShareObj::Fire_MemberChanged(NM_MEMBER_NOTIFY uNotify, INmMember *pMember)
  233. {
  234. DBGENTRY(CNmChannelAppShareObj::Fire_MemberChanged);
  235. HRESULT hr = S_OK;
  236. /////////////////////////////////////////////////////
  237. // INmChannelNotify
  238. /////////////////////////////////////////////////////
  239. IConnectionPointImpl<CNmChannelAppShareObj, &IID_INmChannelNotify, CComDynamicUnkArray>* pCP = this;
  240. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  241. {
  242. INmChannelNotify* pNotify = reinterpret_cast<INmChannelNotify*>(pCP->m_vec.GetAt(i));
  243. if(pNotify)
  244. {
  245. pNotify->MemberChanged(uNotify, pMember);
  246. }
  247. }
  248. /////////////////////////////////////////////////////
  249. // INmChannelNotify2
  250. /////////////////////////////////////////////////////
  251. IConnectionPointImpl<CNmChannelAppShareObj, &IID_INmChannelAppShareNotify, CComDynamicUnkArray>* pCP2 = this;
  252. for(i = 0; i < pCP2->m_vec.GetSize(); ++i )
  253. {
  254. INmChannelAppShareNotify* pNotify2 = reinterpret_cast<INmChannelAppShareNotify*>(pCP2->m_vec.GetAt(i));
  255. if(pNotify2)
  256. {
  257. pNotify2->MemberChanged(uNotify, pMember);
  258. }
  259. }
  260. DBGEXIT_HR(CNmChannelAppShareObj::Fire_MemberChanged,hr)
  261. return hr;
  262. }
  263. extern bool g_bSDKPostNotifications;
  264. HRESULT CNmChannelAppShareObj::Fire_StateChanged(NM_SHAPP_STATE uNotify, INmSharableApp *pApp)
  265. {
  266. DBGENTRY(CNmChannelAppShareObj::Fire_StateChanged);
  267. HRESULT hr = S_OK;
  268. if(!g_bSDKPostNotifications)
  269. {
  270. /////////////////////////////////////////////////////
  271. // INmChannelAppShareNotify
  272. /////////////////////////////////////////////////////
  273. IConnectionPointImpl<CNmChannelAppShareObj, &IID_INmChannelAppShareNotify, CComDynamicUnkArray>* pCP2 = this;
  274. for(int i = 0; i < pCP2->m_vec.GetSize(); ++i )
  275. {
  276. INmChannelAppShareNotify* pNotify2 = reinterpret_cast<INmChannelAppShareNotify*>(pCP2->m_vec.GetAt(i));
  277. if(pNotify2)
  278. {
  279. pNotify2->StateChanged(uNotify, pApp);
  280. }
  281. }
  282. }
  283. else
  284. {
  285. CSDKWindow::PostStateChanged(this, uNotify, pApp);
  286. }
  287. DBGEXIT_HR(CNmChannelAppShareObj::Fire_StateChanged,hr)
  288. return hr;
  289. }
  290. HRESULT CNmChannelAppShareObj::_IsActive()
  291. {
  292. DBGENTRY(CNmChannelAppShareObj::_IsActive);
  293. return GetbActive() ? S_OK : S_FALSE;
  294. }
  295. HRESULT CNmChannelAppShareObj::_SetActive(BOOL bActive)
  296. {
  297. if (GetbActive() == bActive)
  298. return S_FALSE;
  299. return E_FAIL;
  300. }