Leaked source code of windows server 2003
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.
 
 
 
 
 
 

534 lines
12 KiB

// MstscMhst.cpp : Implementation of CMstscMhst
// Multi host control for TS activeX control.
// contains multiple instances of the activeX control. Used by the MMC control
// Copyright(C) Microsoft Corporation 2000
// nadima
#include "stdafx.h"
#include "multihst.h"
//Pos/width of sessions that are not active
#define X_POS_DISABLED -10
#define Y_POS_DISABLED -10
#define X_WIDTH_DISABLED 5
#define Y_WIDTH_DISABLED 5
/////////////////////////////////////////////////////////////////////////////
// CMstscMhst
/*
*Function Name:Add
*
*Parameters: (out) ppMstsc pointer to newly added TS control
*
*Description: Add's a new TS ActiveX control to the multihost
*
*Returns: HRESULT
*
*/
STDMETHODIMP CMstscMhst::Add(IMsRdpClient** ppMstsc)
{
if (::IsWindow(m_hWnd))
{
CAxWindow* pAxWnd = new CAxWindow();
ATLASSERT(pAxWnd);
if (!pAxWnd)
{
return E_OUTOFMEMORY;
}
RECT rc;
GetClientRect(&rc);
//
// Window is created invisible and disabled...
// Must be made with active client for it to become enabled and visible
//
if (!pAxWnd->Create( m_hWnd, rc, MSTSC_CONTROL_GUID,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0))
{
delete pAxWnd;
return E_FAIL;
}
CComPtr<IMsRdpClient> tsClientPtr;
if (FAILED(pAxWnd->QueryControl( &tsClientPtr)))
{
delete pAxWnd;
return E_FAIL;
}
//
// Store the pointer to the control
//
m_coll.push_back( pAxWnd);
//If no MSTSC windows are active then make this first
//one the active window
if (!m_pActiveWindow)
{
SwitchCurrentActiveClient( pAxWnd);
}
if (ppMstsc)
{
//
// return the pointer, Detach does not decrement the ref count
// so we still hold a reference to the control from the QueryControl
// that is the +1 refcount needed to pass the pointer as an out
// parameter.
//
*ppMstsc = (IMsRdpClient*)tsClientPtr.Detach();
}
return S_OK;
}
else
{
return E_FAIL;
}
}
/*
*Function Name:get_Item
*
*Parameters: (in) Index (index of the item to return)
* (out) ppMstsc pointer to the TS control returned
*
*Description: returns the TS control at a particular index
*
*Returns: HRESULT
*
*/
STDMETHODIMP CMstscMhst::get_Item(long Index, IMsRdpClient** ppMstsc)
{
if (Index <0 || Index >= m_coll.size())
{
ATLASSERT(Index > 0 && Index < m_coll.size());
return E_INVALIDARG;
}
if (!ppMstsc)
{
return E_INVALIDARG;
}
//Return the interface pointer associated
//with the AxWindow container
CAxWindow* pAxWnd = m_coll[Index];
if (!pAxWnd)
{
return E_FAIL;
}
CComPtr<IMsRdpClient> tsClientPtr;
if (FAILED(pAxWnd->QueryControl( &tsClientPtr)))
{
delete pAxWnd;
return E_FAIL;
}
//
// Return the pointer to the ts control. Detach does not
// decrement the AddRef from QueryControl so the refcount is
// correctly incremented by one for the out parameter
//
*ppMstsc = (IMsRdpClient*)tsClientPtr.Detach();
return S_OK;
}
/*
*Function Name:get_Count
*
*Parameters: (out) pCount
*
*Description: returns number of items in the collection
*
*Returns: HRESULT
*
*/
STDMETHODIMP CMstscMhst::get_Count(long* pCount)
{
if (!pCount)
{
return E_INVALIDARG;
}
*pCount = m_coll.size();
return S_OK;
}
/*
*Function Name:put_ActiveClientIndex
*
*Parameters: (in) ClientIndex
*
*Description: sets the active client by Index
*
*Returns: HRESULT
*
*/
STDMETHODIMP CMstscMhst::put_ActiveClientIndex(long ClientIndex)
{
if (ClientIndex < 0 || ClientIndex >= m_coll.size())
{
return E_INVALIDARG;
}
CAxWindow* pNewClientWnd = m_coll[ClientIndex];
if (!pNewClientWnd)
{
return E_FAIL;
}
if (SwitchCurrentActiveClient(pNewClientWnd))
{
m_ActiveClientIndex = ClientIndex;
return S_OK;
}
else
{
return E_FAIL;
}
}
/*
*Function Name:get_ActiveClient
*
*Parameters: (out) ppMstsc pointer to active client
*
*Description: returns the ActiveClient
*
*Returns: HRESULT
*
*/
STDMETHODIMP CMstscMhst::get_ActiveClient(IMsRdpClient** ppMstsc)
{
if (!ppMstsc)
{
return E_INVALIDARG;
}
if (!m_pActiveWindow)
{
*ppMstsc = NULL;
return S_OK;
}
CComPtr<IMsRdpClient> tsClientPtr;
if (FAILED(m_pActiveWindow->QueryControl( &tsClientPtr)))
{
return E_FAIL;
}
//
// Detach keeps the +1 ref from QueryControl
//
*ppMstsc = (IMsRdpClient*)tsClientPtr.Detach();
return S_OK;
}
/*
*Function Name:put_ActiveClient
*
*Parameters: ppMstsc
*
*Description: sets the active client given a pointer to
* to the client instance
*
*Returns: HRESULT
*
*/
STDMETHODIMP CMstscMhst::put_ActiveClient(IMsRdpClient* ppMstsc)
{
CAxWindow* pAxWnd = NULL;
//find AxWindow that hosts this client
//in the collection
std::vector<CAxWindow*>::iterator iter;
for (iter = m_coll.begin(); iter != m_coll.end(); iter++)
{
CComPtr<IMsRdpClient> tsClientPtr;
HRESULT hr = (*iter)->QueryControl( &tsClientPtr);
if (FAILED(hr))
{
return hr;
}
if (tsClientPtr == ppMstsc)
{
pAxWnd = *iter;
break;
}
}
if (!pAxWnd)
{
//We were given a control reference that could not be found
return E_INVALIDARG;
}
if (!SwitchCurrentActiveClient(pAxWnd))
{
return E_FAIL;
}
return S_OK;
}
/*
*Function Name:SwitchCurrentActiveClient
*
*Parameters: (in) newHostWindow - AxWindow that will become
* the active window
*
*Description: sets the active client given a pointer to
* to the client instance
*
*Returns: success flag
*
*/
BOOL CMstscMhst::SwitchCurrentActiveClient(CAxWindow* newHostWindow)
{
//Switch the current active client window
if (!newHostWindow)
{
return FALSE;
}
m_pActiveWindow = newHostWindow;
//
// Make sure the window is sized properly
//
RECT rcClient;
GetClientRect(&rcClient);
m_pActiveWindow->MoveWindow(rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
m_pActiveWindow->SetFocus();
//
// This window is made the active child window by brining
// it to the top of the Z-order of child windows
//
newHostWindow->BringWindowToTop();
return TRUE;
}
/*
*Function Name:RemoveIndex
*
*Parameters: ClientIndex
*
*Description: removes a client by index
*
*Returns: HRESULT
*
*/
STDMETHODIMP CMstscMhst::RemoveIndex(long ClientIndex)
{
HRESULT hr;
CComPtr<IMsRdpClient> tsClientPtr;
hr = get_Item(ClientIndex, (IMsRdpClient**) (&tsClientPtr));
if (FAILED(hr))
{
return hr;
}
//Pass in interface pointer without addref'ing
hr = Remove( (IMsRdpClient*)tsClientPtr);
return hr;
}
/*
*Function Name:Remove
*
*Parameters: (in) ppMsts client to remove
*
*Description: removes a client from the collection
*
*Returns: HRESULT
*
*/
STDMETHODIMP CMstscMhst::Remove(IMsRdpClient* ppMstsc)
{
//Look for the ax window container and if found delete it
//also, remove the entry from the collection
//find AxWindow that hosts this client
CAxWindow* pAxWnd = NULL;
std::vector<CAxWindow*>::iterator iter;
for (iter = m_coll.begin(); iter != m_coll.end(); iter++)
{
CComPtr<IMsRdpClient> tsClientPtr;
HRESULT hr = (*iter)->QueryControl( &tsClientPtr);
if (FAILED(hr))
{
return hr;
}
if (tsClientPtr == ppMstsc)
{
pAxWnd = *iter;
break;
}
}
if (!pAxWnd)
{
//We were given a control reference that could not be found
return E_INVALIDARG;
}
m_coll.erase(iter);
return DeleteAxContainerWnd(pAxWnd);
}
/*
*Function Name:DeleteAxContainerWnd
*
*Parameters: (in) pAxWnd CAxWindow to delete
*
*Description: deletes an activeX container window
*
*Returns: HRESULT
*
*/
HRESULT CMstscMhst::DeleteAxContainerWnd(CAxWindow* pAxWnd)
{
if (!pAxWnd)
{
return E_FAIL;
}
if (m_pActiveWindow == pAxWnd)
{
m_pActiveWindow = NULL;
}
if (!pAxWnd->DestroyWindow())
{
return E_FAIL;
}
delete pAxWnd;
return S_OK;
}
//
// OnCreate Handler
//
LRESULT CMstscMhst::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
::SetWindowLong(m_hWnd, GWL_STYLE,
::GetWindowLong(m_hWnd, GWL_STYLE) | WS_CLIPCHILDREN);
if (!AtlAxWinInit())
{
return -1;
}
return 0;
}
/*
*Function Name:OnDestroy
*
*Parameters:
*
*Description: handler for WM_DESTROY
*
*Returns:
*
*/
LRESULT CMstscMhst::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_pActiveWindow = NULL;
if (!AtlAxWinTerm())
{
return -1;
}
//
// Delete everything in the collection
//
std::vector<CAxWindow*>::iterator iter;
for (iter = m_coll.begin(); iter != m_coll.end(); iter++)
{
//
// This frees any remaining controls
//
DeleteAxContainerWnd(*iter);
}
//
// Erase the CAxWindow items in the collection
//
m_coll.erase(m_coll.begin(), m_coll.end());
return 0;
}
/**PROC+*********************************************************************/
/* Name: OnFrameWindowActivate */
/* */
/* Purpose: Override IOleInPlaceActiveObject::OnFrameWindowActivate */
/* to set the focus on the core container window when the control */
/* gets activated */
/* */
/**PROC-*********************************************************************/
STDMETHODIMP CMstscMhst::OnFrameWindowActivate(BOOL fActivate )
{
if (fActivate && IsWindow() && m_pActiveWindow)
{
m_pActiveWindow->SetFocus();
}
return S_OK;
}
LRESULT CMstscMhst::OnGotFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE("CMstscMhst::OnGotFocus");
if (m_pActiveWindow)
{
m_pActiveWindow->SetFocus();
}
return 0;
}
LRESULT CMstscMhst::OnLostFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE("CMstscMhst::OnLostFocus");
return 0;
}
LRESULT CMstscMhst::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
RECT rcClient;
if (m_pActiveWindow)
{
GetClientRect(&rcClient);
m_pActiveWindow->MoveWindow(rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
}
return 0;
}