windows-nt/Source/XPSP1/NT/enduser/netmeeting/ui/conf/nmchannelappshare.cpp

386 lines
8 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
#include "Precomp.h"
#include "Resource.h"
#include "confroom.h"
#include "ias.h"
#include "NmEnum.h"
#include "SDKInternal.h"
#include "NmConference.h"
#include "NmChannel.h"
#include "NmChannelAppShare.h"
#include "NmSharableApp.h"
#include "SDKWindow.h"
CNmChannelAppShareObj::CNmChannelAppShareObj()
{
DBGENTRY(CNmChannelAppShareObj::CNmChannelAppShareObj);
DBGEXIT(CNmChannelAppShareObj::CNmChannelAppShareObj);
}
CNmChannelAppShareObj::~CNmChannelAppShareObj()
{
DBGENTRY(CNmChannelAppShareObj::~CNmChannelAppShareObj);
for(int j = 0; j < m_ArySharableApps.GetSize(); ++j)
{
m_ArySharableApps[j]->Release();
}
m_ArySharableApps.RemoveAll();
DBGEXIT(CNmChannelAppShareObj::~CNmChannelAppShareObj);
}
//static
HRESULT CNmChannelAppShareObj::CreateInstance(CNmConferenceObj* pConfObj, INmChannel** ppChannel)
{
DBGENTRY(CNmChannelAppShareObj::CreateInstance);
HRESULT hr = S_OK;
typedef CNmChannel<CNmChannelAppShareObj, &IID_INmChannelAppShare, NMCH_SHARE> channel_type;
channel_type* p = NULL;
p = new CComObject<channel_type>(NULL);
if (p != NULL)
{
if(ppChannel)
{
p->SetVoid(NULL);
hr = p->QueryInterface(IID_INmChannel, reinterpret_cast<void**>(ppChannel));
if(SUCCEEDED(hr))
{
// We don't have to RefCount this because our lifetime is
// contained in the CConf's lifetime
p->m_pConfObj = pConfObj;
}
if(FAILED(hr))
{
delete p;
*ppChannel = NULL;
}
}
else
{
hr = E_POINTER;
}
}
else
{
hr = E_OUTOFMEMORY;
}
DBGEXIT_HR(CNmChannelAppShareObj::CreateInstance,hr);
return hr;
}
///////////////////////////////////////////////////////////////////////////////////
// INmChannelAppShare methods
///////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CNmChannelAppShareObj::GetState(NM_SHARE_STATE *puState)
{
DBGENTRY(CNmChannelAppShareObj::GetState);
HRESULT hr = E_UNEXPECTED;
INmMember* pMember = GetConfObj()->GetLocalSDKMember();
if(pMember)
{
hr = pMember->GetShareState(puState);
}
DBGEXIT_HR(CNmChannelAppShareObj::GetState,hr);
return hr;
}
STDMETHODIMP CNmChannelAppShareObj::SetState(NM_SHARE_STATE uState)
{
DWORD uf;
HRESULT hr = S_OK;
if (!(S_OK == IsActive()))
return E_FAIL;
if(!GetConfObj() || !GetConfObj()->GetLocalSDKMember())
{
return E_UNEXPECTED;
}
if(NM_SHARE_UNKNOWN)
{
return E_FAIL;
}
else
{
if(NM_SHARE_WORKING_ALONE == uState)
{
return ::AllowControl(false);
}
if(NM_SHARE_COLLABORATING == uState)
{
return ::AllowControl(true);
}
if(NM_SHARE_IN_CONTROL == uState)
{
NM_SHARE_STATE uCurrentState;
if(SUCCEEDED(hr = GetState(&uCurrentState)))
{
if(NM_SHARE_COLLABORATING == uCurrentState)
{
// Yank control from the person that is controlling you
return ::RevokeControl(0);
}
}
else
{
return hr;
}
return ::AllowControl(true);
}
}
return E_UNEXPECTED;
}
//static
HRESULT CNmChannelAppShareObj::GetSharableAppName(HWND hWnd, LPTSTR sz, UINT cchMax)
{
HRESULT hr = S_OK;
ASSERT(sz);
::GetWindowText(hWnd, sz, cchMax);
return hr;
}
static INmSharableApp* _SharableAppAryHasThisHWND(CSimpleArray<INmSharableApp*>& ArySharableApps, HWND hWnd)
{
for(int i = 0; i < ArySharableApps.GetSize(); ++i)
{
HWND h;
if(SUCCEEDED(ArySharableApps[i]->GetHwnd(&h)))
{
if(hWnd == h) return ArySharableApps[i];
}
}
return NULL;
}
STDMETHODIMP CNmChannelAppShareObj::EnumSharableApp(IEnumNmSharableApp **ppEnum)
{
DBGENTRY(CNmChannelAppShareObj::EnumSharableApp);
HRESULT hr = E_UNEXPECTED;
IAS_HWND_ARRAY* pAry;
hr = ::GetShareableApps(&pAry);
if(SUCCEEDED(hr))
{
for(UINT i = 0; i < pAry->cEntries; ++i)
{
HWND hWnd = pAry->aEntries[i].hwnd;
TCHAR szName[MAX_PATH];
if(!_SharableAppAryHasThisHWND(m_ArySharableApps, hWnd))
{
hr = GetSharableAppName(hWnd, szName, CCHMAX(szName));
if(FAILED(hr)) goto end;
INmSharableApp* pApp;
hr = CNmSharableAppObj::CreateInstance(hWnd, szName, &pApp);
if(SUCCEEDED(hr))
{
m_ArySharableApps.Add(pApp);
}
}
}
hr = CreateEnumFromSimpleAryOfInterface<IEnumNmSharableApp, INmSharableApp>(m_ArySharableApps, ppEnum);
FreeShareableApps(pAry);
}
end:
DBGEXIT_HR(CNmChannelAppShareObj::EnumSharableApp,hr);
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// IInternalChannelObj methods
///////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CNmChannelAppShareObj::GetInternalINmChannel(INmChannel** ppChannel)
{
DBGENTRY(CNmChannelAppShareObj::GetInternalINmChannel);
HRESULT hr = S_OK;
if(ppChannel)
{
hr = GetUnknown()->QueryInterface(IID_INmChannel, reinterpret_cast<void**>(ppChannel));
}
else
{
hr = E_POINTER;
}
DBGEXIT_HR(CNmChannelAppShareObj::GetInternalINmChannel,hr);
return hr;
}
HRESULT CNmChannelAppShareObj::ChannelRemoved()
{
HRESULT hr = S_OK;
RemoveMembers();
CNmConferenceObj* pConfObj = GetConfObj();
if(pConfObj)
{
hr = pConfObj->Fire_ChannelChanged(NM_CHANNEL_REMOVED, com_cast<INmChannel>(GetUnknown()));
}
else
{
ERROR_OUT(("ChannelRemoved, but no ConfObject"));
hr = E_UNEXPECTED;
}
return hr;
}
// interface INmChannelAppShareNotify methods
STDMETHODIMP CNmChannelAppShareObj::StateChanged(NM_SHAPP_STATE uState,INmSharableApp *pApp)
{
if(pApp)
{
HWND hWnd;
if(SUCCEEDED(pApp->GetHwnd(&hWnd)))
{
INmSharableApp* pExistingApp = _SharableAppAryHasThisHWND(m_ArySharableApps, hWnd);
if(!pExistingApp)
{
pExistingApp = pApp;
pExistingApp->AddRef();
m_ArySharableApps.Add(pExistingApp);
}
Fire_StateChanged(uState, pExistingApp);
}
}
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////////////////////////////
HRESULT CNmChannelAppShareObj::Fire_MemberChanged(NM_MEMBER_NOTIFY uNotify, INmMember *pMember)
{
DBGENTRY(CNmChannelAppShareObj::Fire_MemberChanged);
HRESULT hr = S_OK;
/////////////////////////////////////////////////////
// INmChannelNotify
/////////////////////////////////////////////////////
IConnectionPointImpl<CNmChannelAppShareObj, &IID_INmChannelNotify, CComDynamicUnkArray>* pCP = this;
for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
{
INmChannelNotify* pNotify = reinterpret_cast<INmChannelNotify*>(pCP->m_vec.GetAt(i));
if(pNotify)
{
pNotify->MemberChanged(uNotify, pMember);
}
}
/////////////////////////////////////////////////////
// INmChannelNotify2
/////////////////////////////////////////////////////
IConnectionPointImpl<CNmChannelAppShareObj, &IID_INmChannelAppShareNotify, CComDynamicUnkArray>* pCP2 = this;
for(i = 0; i < pCP2->m_vec.GetSize(); ++i )
{
INmChannelAppShareNotify* pNotify2 = reinterpret_cast<INmChannelAppShareNotify*>(pCP2->m_vec.GetAt(i));
if(pNotify2)
{
pNotify2->MemberChanged(uNotify, pMember);
}
}
DBGEXIT_HR(CNmChannelAppShareObj::Fire_MemberChanged,hr)
return hr;
}
extern bool g_bSDKPostNotifications;
HRESULT CNmChannelAppShareObj::Fire_StateChanged(NM_SHAPP_STATE uNotify, INmSharableApp *pApp)
{
DBGENTRY(CNmChannelAppShareObj::Fire_StateChanged);
HRESULT hr = S_OK;
if(!g_bSDKPostNotifications)
{
/////////////////////////////////////////////////////
// INmChannelAppShareNotify
/////////////////////////////////////////////////////
IConnectionPointImpl<CNmChannelAppShareObj, &IID_INmChannelAppShareNotify, CComDynamicUnkArray>* pCP2 = this;
for(int i = 0; i < pCP2->m_vec.GetSize(); ++i )
{
INmChannelAppShareNotify* pNotify2 = reinterpret_cast<INmChannelAppShareNotify*>(pCP2->m_vec.GetAt(i));
if(pNotify2)
{
pNotify2->StateChanged(uNotify, pApp);
}
}
}
else
{
CSDKWindow::PostStateChanged(this, uNotify, pApp);
}
DBGEXIT_HR(CNmChannelAppShareObj::Fire_StateChanged,hr)
return hr;
}
HRESULT CNmChannelAppShareObj::_IsActive()
{
DBGENTRY(CNmChannelAppShareObj::_IsActive);
return GetbActive() ? S_OK : S_FALSE;
}
HRESULT CNmChannelAppShareObj::_SetActive(BOOL bActive)
{
if (GetbActive() == bActive)
return S_FALSE;
return E_FAIL;
}