/**************************************************************************
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright 1997 Microsoft Corporation. All Rights Reserved.
**************************************************************************/
/**************************************************************************
File: CommBand.cpp
Description: Implements CCommBand
**************************************************************************/
/**************************************************************************
#include statements
**************************************************************************/
#include "CommBand.h"
#include "Guid.h"
/**************************************************************************
CCommBand::CCommBand()
**************************************************************************/
CCommBand::CCommBand()
{
m_pSite = NULL;
m_hWnd = NULL;
m_hwndParent = NULL;
m_bFocus = FALSE;
m_dwViewMode = 0;
m_dwBandID = 0;
m_ObjRefCount = 1;
g_DllRefCount++;
}
/**************************************************************************
CCommBand::~CCommBand()
**************************************************************************/
CCommBand::~CCommBand()
{
//this should have been freed in a call to SetSite(NULL), but just to be safe
if(m_pSite)
{
m_pSite->Release();
m_pSite = NULL;
}
g_DllRefCount--;
}
///////////////////////////////////////////////////////////////////////////
//
// IUnknown Implementation
//
/**************************************************************************
CCommBand::QueryInterface
**************************************************************************/
STDMETHODIMP CCommBand::QueryInterface(REFIID riid, LPVOID *ppReturn)
{
*ppReturn = NULL;
//IUnknown
if(IsEqualIID(riid, IID_IUnknown))
{
*ppReturn = this;
}
//IOleWindow
else if(IsEqualIID(riid, IID_IOleWindow))
{
*ppReturn = (IOleWindow*)this;
}
//IDockingWindow
else if(IsEqualIID(riid, IID_IDockingWindow))
{
*ppReturn = (IDockingWindow*)this;
}
//IInputObject
else if(IsEqualIID(riid, IID_IInputObject))
{
*ppReturn = (IInputObject*)this;
}
//IObjectWithSite
else if(IsEqualIID(riid, IID_IObjectWithSite))
{
*ppReturn = (IObjectWithSite*)this;
}
//IDeskBand
else if(IsEqualIID(riid, IID_IDeskBand))
{
*ppReturn = (IDeskBand*)this;
}
//IPersist
else if(IsEqualIID(riid, IID_IPersist))
{
*ppReturn = (IPersist*)this;
}
//IPersistStream
else if(IsEqualIID(riid, IID_IPersistStream))
{
*ppReturn = (IPersistStream*)this;
}
//IContextMenu
else if(IsEqualIID(riid, IID_IContextMenu))
{
*ppReturn = (IContextMenu*)this;
}
if(*ppReturn)
{
(*(LPUNKNOWN*)ppReturn)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
/**************************************************************************
CCommBand::AddRef
**************************************************************************/
STDMETHODIMP_(DWORD) CCommBand::AddRef()
{
return ++m_ObjRefCount;
}
/**************************************************************************
CCommBand::Release
**************************************************************************/
STDMETHODIMP_(DWORD) CCommBand::Release()
{
if(--m_ObjRefCount == 0)
{
delete this;
return 0;
}
return m_ObjRefCount;
}
///////////////////////////////////////////////////////////////////////////
//
// IOleWindow Implementation
//
/**************************************************************************
CCommBand::GetWindow()
**************************************************************************/
STDMETHODIMP CCommBand::GetWindow(HWND *phWnd)
{
*phWnd = m_hWnd;
return S_OK;
}
/**************************************************************************
CCommBand::ContextSensitiveHelp()
**************************************************************************/
STDMETHODIMP CCommBand::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
///////////////////////////////////////////////////////////////////////////
//
// IDockingWindow Implementation
//
/**************************************************************************
CCommBand::ShowDW()
**************************************************************************/
STDMETHODIMP CCommBand::ShowDW(BOOL fShow)
{
if(m_hWnd)
{
if(fShow)
{
//show our window
ShowWindow(m_hWnd, SW_SHOW);
}
else
{
//hide our window
ShowWindow(m_hWnd, SW_HIDE);
}
}
return S_OK;
}
/**************************************************************************
CCommBand::CloseDW()
**************************************************************************/
STDMETHODIMP CCommBand::CloseDW(DWORD dwReserved)
{
ShowDW(FALSE);
if(IsWindow(m_hWnd))
DestroyWindow(m_hWnd);
m_hWnd = NULL;
return S_OK;
}
/**************************************************************************
CCommBand::ResizeBorderDW()
**************************************************************************/
STDMETHODIMP CCommBand::ResizeBorderDW( LPCRECT prcBorder,
IUnknown* punkSite,
BOOL fReserved)
{
/*
This method is never called for Band Objects.
*/
return E_NOTIMPL;
}
///////////////////////////////////////////////////////////////////////////
//
// IInputObject Implementation
//
/**************************************************************************
CCommBand::UIActivateIO()
**************************************************************************/
STDMETHODIMP CCommBand::UIActivateIO(BOOL fActivate, LPMSG pMsg)
{
if(fActivate)
SetFocus(m_hWnd);
return S_OK;
}
/**************************************************************************
CCommBand::HasFocusIO()
If this window or one of its decendants has the focus, return S_OK. Return
S_FALSE if we don't have the focus.
**************************************************************************/
STDMETHODIMP CCommBand::HasFocusIO(void)
{
if(m_bFocus)
return S_OK;
return S_FALSE;
}
/**************************************************************************
CCommBand::TranslateAcceleratorIO()
If the accelerator is translated, return S_OK or S_FALSE otherwise.
**************************************************************************/
STDMETHODIMP CCommBand::TranslateAcceleratorIO(LPMSG pMsg)
{
return S_FALSE;
}
///////////////////////////////////////////////////////////////////////////
//
// IObjectWithSite implementations
//
/**************************************************************************
CCommBand::SetSite()
**************************************************************************/
STDMETHODIMP CCommBand::SetSite(IUnknown* punkSite)
{
//If a site is being held, release it.
if(m_pSite)
{
m_pSite->Release();
m_pSite = NULL;
}
//If punkSite is not NULL, a new site is being set.
if(punkSite)
{
//Get the parent window.
IOleWindow *pOleWindow;
m_hwndParent = NULL;
if(SUCCEEDED(punkSite->QueryInterface(IID_IOleWindow, (LPVOID*)&pOleWindow)))
{
pOleWindow->GetWindow(&m_hwndParent);
pOleWindow->Release();
}
if(!m_hwndParent)
return E_FAIL;
if(!RegisterAndCreateWindow())
return E_FAIL;
//Get and keep the IInputObjectSite pointer.
if(SUCCEEDED(punkSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&m_pSite)))
{
return S_OK;
}
return E_FAIL;
}
return S_OK;
}
/**************************************************************************
CCommBand::GetSite()
**************************************************************************/
STDMETHODIMP CCommBand::GetSite(REFIID riid, LPVOID *ppvReturn)
{
*ppvReturn = NULL;
if(m_pSite)
return m_pSite->QueryInterface(riid, ppvReturn);
return E_FAIL;
}
///////////////////////////////////////////////////////////////////////////
//
// IDeskBand implementation
//
/**************************************************************************
CCommBand::GetBandInfo()
**************************************************************************/
STDMETHODIMP CCommBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi)
{
if(pdbi)
{
m_dwBandID = dwBandID;
m_dwViewMode = dwViewMode;
if(pdbi->dwMask & DBIM_MINSIZE)
{
pdbi->ptMinSize.x = 0;
pdbi->ptMinSize.y = 30;
}
if(pdbi->dwMask & DBIM_MAXSIZE)
{
pdbi->ptMaxSize.x = -1;
pdbi->ptMaxSize.y = 30;
}
if(pdbi->dwMask & DBIM_INTEGRAL)
{
pdbi->ptIntegral.x = 1;
pdbi->ptIntegral.y = 1;
}
if(pdbi->dwMask & DBIM_ACTUAL)
{
pdbi->ptActual.x = 0;
pdbi->ptActual.y = 0;
}
if(pdbi->dwMask & DBIM_TITLE)
{
lstrcpyW(pdbi->wszTitle, L"");
}
if(pdbi->dwMask & DBIM_MODEFLAGS)
{
pdbi->dwModeFlags = DBIMF_NORMAL;
}
if(pdbi->dwMask & DBIM_BKCOLOR)
{
//Use the default background color by removing this flag.
pdbi->dwMask &= ~DBIM_BKCOLOR;
}
return S_OK;
}
return E_INVALIDARG;
}
///////////////////////////////////////////////////////////////////////////
//
// IPersistStream implementations
//
// This is only supported to allow the desk band to be dropped on the
// desktop and to prevent multiple instances of the desk band from showing
// up in the context menu. This desk band doesn't actually persist any data.
//
/**************************************************************************
CCommBand::GetClassID()
**************************************************************************/
STDMETHODIMP CCommBand::GetClassID(LPCLSID pClassID)
{
*pClassID = CLSID_SampleCommBand;
return S_OK;
}
/**************************************************************************
CCommBand::IsDirty()
**************************************************************************/
STDMETHODIMP CCommBand::IsDirty(void)
{
return S_FALSE;
}
/**************************************************************************
CCommBand::Load()
**************************************************************************/
STDMETHODIMP CCommBand::Load(LPSTREAM pStream)
{
return S_OK;
}
/**************************************************************************
CCommBand::Save()
**************************************************************************/
STDMETHODIMP CCommBand::Save(LPSTREAM pStream, BOOL fClearDirty)
{
return S_OK;
}
/**************************************************************************
CCommBand::GetSizeMax()
**************************************************************************/
STDMETHODIMP CCommBand::GetSizeMax(ULARGE_INTEGER *pul)
{
return E_NOTIMPL;
}
///////////////////////////////////////////////////////////////////////////
//
// IContextMenu Implementation
//
/**************************************************************************
CCommBand::QueryContextMenu()
**************************************************************************/
STDMETHODIMP CCommBand::QueryContextMenu( HMENU hMenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
if(!(CMF_DEFAULTONLY & uFlags))
{
InsertMenu( hMenu,
indexMenu,
MF_STRING | MF_BYPOSITION,
idCmdFirst + IDM_COMMAND,
"&Sample Comm Band Command");
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_COMMAND + 1));
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
}
/**************************************************************************
CCommBand::InvokeCommand()
**************************************************************************/
STDMETHODIMP CCommBand::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
{
switch (LOWORD(lpcmi->lpVerb))
{
case IDM_COMMAND:
MessageBox(lpcmi->hwnd, TEXT("Comm Band Command selected."), TEXT("Sample Comm Band"), MB_OK | MB_ICONINFORMATION);
break;
default:
return E_INVALIDARG;
}
return NOERROR;
}
/**************************************************************************
CCommBand::GetCommandString()
**************************************************************************/
STDMETHODIMP CCommBand::GetCommandString( UINT idCommand,
UINT uFlags,
LPUINT lpReserved,
LPSTR lpszName,
UINT uMaxNameLen)
{
HRESULT hr = E_INVALIDARG;
switch(uFlags)
{
case GCS_HELPTEXT:
switch(idCommand)
{
case IDM_COMMAND:
lstrcpy(lpszName, TEXT("Comm Band command help text"));
hr = NOERROR;
break;
}
break;
case GCS_VERB:
switch(idCommand)
{
case IDM_COMMAND:
lstrcpy(lpszName, TEXT("command"));
hr = NOERROR;
break;
}
break;
case GCS_VALIDATE:
hr = NOERROR;
break;
}
return hr;
}
///////////////////////////////////////////////////////////////////////////
//
// private method implementations
//
/**************************************************************************
CCommBand::WndProc()
**************************************************************************/
LRESULT CALLBACK CCommBand::WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
CCommBand *pThis = (CCommBand*)GetWindowLong(hWnd, GWL_USERDATA);
switch (uMessage)
{
case WM_NCCREATE:
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
pThis = (CCommBand*)(lpcs->lpCreateParams);
SetWindowLong(hWnd, GWL_USERDATA, (LONG)pThis);
//set the window handle
pThis->m_hWnd = hWnd;
}
break;
case WM_PAINT:
return pThis->OnPaint();
case WM_COMMAND:
return pThis->OnCommand(wParam, lParam);
case WM_SETFOCUS:
return pThis->OnSetFocus();
case WM_KILLFOCUS:
return pThis->OnKillFocus();
}
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}
/**************************************************************************
CCommBand::OnPaint()
**************************************************************************/
LRESULT CCommBand::OnPaint(void)
{
PAINTSTRUCT ps;
RECT rc;
BeginPaint(m_hWnd, &ps);
GetClientRect(m_hWnd, &rc);
SetTextColor(ps.hdc, RGB(0, 0, 0));
SetBkMode(ps.hdc, TRANSPARENT);
DrawText(ps.hdc, TEXT("Sample Comm Band"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(m_hWnd, &ps);
return 0;
}
/**************************************************************************
CCommBand::OnCommand()
**************************************************************************/
LRESULT CCommBand::OnCommand(WPARAM wParam, LPARAM lParam)
{
return 0;
}
/**************************************************************************
CCommBand::FocusChange()
**************************************************************************/
void CCommBand::FocusChange(BOOL bFocus)
{
m_bFocus = bFocus;
//inform the input object site that the focus has changed
if(m_pSite)
{
m_pSite->OnFocusChangeIS((IDockingWindow*)this, bFocus);
}
}
/**************************************************************************
CCommBand::OnSetFocus()
**************************************************************************/
LRESULT CCommBand::OnSetFocus(void)
{
FocusChange(TRUE);
return 0;
}
/**************************************************************************
CCommBand::OnKillFocus()
**************************************************************************/
LRESULT CCommBand::OnKillFocus(void)
{
FocusChange(FALSE);
return 0;
}
/**************************************************************************
CCommBand::RegisterAndCreateWindow()
**************************************************************************/
BOOL CCommBand::RegisterAndCreateWindow(void)
{
//If the window doesn't exist yet, create it now.
if(!m_hWnd)
{
//Can't create a child window without a parent.
if(!m_hwndParent)
{
return FALSE;
}
//If the window class has not been registered, then do so.
WNDCLASS wc;
if(!GetClassInfo(g_hInst, CB_CLASS_NAME, &wc))
{
ZeroMemory(&wc, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 192, 0));
wc.lpszMenuName = NULL;
wc.lpszClassName = CB_CLASS_NAME;
if(!RegisterClass(&wc))
{
//If RegisterClass fails, CreateWindow below will fail.
}
}
RECT rc;
GetClientRect(m_hwndParent, &rc);
//Create the window. The WndProc will set m_hWnd.
CreateWindowEx( 0,
CB_CLASS_NAME,
NULL,
WS_CHILD | WS_CLIPSIBLINGS | WS_BORDER,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
m_hwndParent,
NULL,
g_hInst,
(LPVOID)this);
}
return (NULL != m_hWnd);
}