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.
 
 
 
 
 
 

924 lines
22 KiB

/**************************************************************************
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR TFPLIED, INCLUDING BUT NOT LIMITED TO
THE TFPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright 1997 Microsoft Corporation. All Rights Reserved.
**************************************************************************/
/**************************************************************************
File: DeskBand.cpp
Description: Implements CDeskBand
**************************************************************************/
/**************************************************************************
include statements
**************************************************************************/
#include "private.h"
#include "DeskBand.h"
#include "tipbar.h"
#include "Guid.h"
#include <shlapip.h>
extern CTipbarWnd *g_pTipbarWnd;
const IID IID_IDeskBandEx = {
0x5dd6b79a,
0x3ab7,
0x49c0,
{0xab,0x82,0x6b,0x2d,0xa7,0xd7,0x8d,0x75}
};
/**************************************************************************
CDeskBand::CDeskBand()
**************************************************************************/
CDeskBand::CDeskBand()
{
m_pSite = NULL;
m_hwndParent = NULL;
m_bFocus = FALSE;
m_dwViewMode = 0;
m_dwBandID = -1;
m_ObjRefCount = 1;
g_DllRefCount++;
}
/**************************************************************************
CDeskBand::~CDeskBand()
**************************************************************************/
CDeskBand::~CDeskBand()
{
// 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
//
/**************************************************************************
CDeskBand::QueryInterface
**************************************************************************/
STDMETHODIMP CDeskBand::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;
}
//IDeskBandEx
else if(IsEqualIID(riid, IID_IDeskBandEx))
{
*ppReturn = (IDeskBandEx*)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_FAIL;
}
/**************************************************************************
CDeskBand::AddRef
**************************************************************************/
STDMETHODIMP_(DWORD) CDeskBand::AddRef()
{
return ++m_ObjRefCount;
}
/**************************************************************************
CDeskBand::Release
**************************************************************************/
STDMETHODIMP_(DWORD) CDeskBand::Release()
{
if(--m_ObjRefCount == 0)
{
delete this;
return 0;
}
return m_ObjRefCount;
}
///////////////////////////////////////////////////////////////////////////
//
// IOleWindow Implementation
//
/**************************************************************************
CDeskBand::GetWindow()
**************************************************************************/
STDMETHODIMP CDeskBand::GetWindow(HWND *phWnd)
{
if (!g_pTipbarWnd)
*phWnd = NULL;
else
*phWnd = g_pTipbarWnd->GetWnd();
return S_OK;
}
/**************************************************************************
CDeskBand::ContextSensitiveHelp()
**************************************************************************/
STDMETHODIMP CDeskBand::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
///////////////////////////////////////////////////////////////////////////
//
// IDockingWindow Implementation
//
/**************************************************************************
CDeskBand::ShowDW()
**************************************************************************/
STDMETHODIMP CDeskBand::ShowDW(BOOL fShow)
{
if (!g_pTipbarWnd)
return S_OK;
if (g_pTipbarWnd->GetWnd())
{
g_pTipbarWnd->Show(fShow);
}
return S_OK;
}
/**************************************************************************
CDeskBand::CloseDW()
**************************************************************************/
STDMETHODIMP CDeskBand::CloseDW(DWORD dwReserved)
{
if (m_fInCloseDW)
return S_OK;
AddRef();
m_fInCloseDW = TRUE;
ShowDW(FALSE);
if(g_pTipbarWnd && IsWindow(g_pTipbarWnd->GetWnd()))
{
ClosePopupTipbar();
}
m_fInCloseDW = FALSE;
Release();
return S_OK;
}
/**************************************************************************
CDeskBand::ResizeBorderDW()
**************************************************************************/
STDMETHODIMP CDeskBand::ResizeBorderDW( LPCRECT prcBorder,
IUnknown* punkSite,
BOOL fReserved)
{
// This method is never called for Band Objects.
return E_NOTIMPL;
}
///////////////////////////////////////////////////////////////////////////
//
// IInputObject Implementation
//
/**************************************************************************
CDeskBand::UIActivateIO()
**************************************************************************/
STDMETHODIMP CDeskBand::UIActivateIO(BOOL fActivate, LPMSG pMsg)
{
#if 1
//
// we don't have keyboard access to the language bar, yet.
// however the accessibility requires it. when it is done, this can be
// implemented.
//
return E_NOTIMPL;
#else
if(g_pTipbarWnd && fActivate)
SetFocus(g_pTipbarWnd->GetWnd());
return S_OK;
#endif
}
/**************************************************************************
CDeskBand::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 CDeskBand::HasFocusIO(void)
{
if(m_bFocus)
return S_OK;
return S_FALSE;
}
/**************************************************************************
CDeskBand::TranslateAcceleratorIO()
If the accelerator is translated, return S_OK or S_FALSE otherwise.
**************************************************************************/
STDMETHODIMP CDeskBand::TranslateAcceleratorIO(LPMSG pMsg)
{
return S_FALSE;
}
///////////////////////////////////////////////////////////////////////////
//
// IObjectWithSite implementations
//
/**************************************************************************
CDeskBand::SetSite()
**************************************************************************/
STDMETHODIMP CDeskBand::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;
}
/**************************************************************************
CDeskBand::GetSite()
**************************************************************************/
STDMETHODIMP CDeskBand::GetSite(REFIID riid, LPVOID *ppvReturn)
{
*ppvReturn = NULL;
if(m_pSite)
return m_pSite->QueryInterface(riid, ppvReturn);
return E_FAIL;
}
///////////////////////////////////////////////////////////////////////////
//
// IDeskBand implementation
//
/**************************************************************************
CDeskBand::GetBandInfo()
**************************************************************************/
STDMETHODIMP CDeskBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi)
{
if(pdbi)
{
BOOL bVertical = FALSE;
m_dwBandID = dwBandID;
m_dwViewMode = dwViewMode;
if (DBIF_VIEWMODE_VERTICAL & dwViewMode)
{
bVertical = TRUE;
}
UINT cxSmIcon;
UINT cySmIcon;
UINT cxSize;
UINT cySize;
cxSmIcon = GetSystemMetrics(SM_CXSMICON);
cySmIcon = GetSystemMetrics(SM_CYSMICON);
cxSize = cxSmIcon;
if (g_pTipbarWnd)
{
g_pTipbarWnd->InitMetrics();
cySize = g_pTipbarWnd->GetTipbarHeight();
}
else
cySize = cySmIcon + cySmIcon / 3;
if(pdbi->dwMask & DBIM_MINSIZE)
{
if(DBIF_VIEWMODE_FLOATING & dwViewMode)
{
pdbi->ptMinSize.x = 200;
pdbi->ptMinSize.y = 400;
}
else
{
pdbi->ptMinSize.x = cxSize;
pdbi->ptMinSize.y = cySize + 2;
}
}
if(pdbi->dwMask & DBIM_MAXSIZE)
{
pdbi->ptMaxSize.x = -1;
pdbi->ptMaxSize.y = -1;
}
if(pdbi->dwMask & DBIM_INTEGRAL)
{
pdbi->ptIntegral.x = cxSize;
pdbi->ptIntegral.y = cySize;
}
if(pdbi->dwMask & DBIM_ACTUAL)
{
pdbi->ptActual.x = cxSize;
pdbi->ptActual.y = cySize + 2;
}
if(pdbi->dwMask & DBIM_TITLE)
{
pdbi->dwMask &= ~DBIM_TITLE;
StringCchCopyW(pdbi->wszTitle,
ARRAYSIZE(pdbi->wszTitle),
CRStr(IDS_LANGBAR));
}
if(pdbi->dwMask & DBIM_MODEFLAGS)
{
pdbi->dwModeFlags = DBIMF_NORMAL;
pdbi->dwModeFlags |= DBIMF_VARIABLEHEIGHT;
}
if(pdbi->dwMask & DBIM_BKCOLOR)
{
//Use the default background color by removing this flag.
pdbi->dwMask &= ~DBIM_BKCOLOR;
}
//
// Don't pulls language band into desktop window.
//
//pdbi->dwModeFlags |= DBIMF_UNDELETEABLE;
if (g_pTipbarWnd)
{
if (!bVertical)
{
g_pTipbarWnd->SetVertical(FALSE);
}
else
{
g_pTipbarWnd->SetVertical(TRUE);
}
}
return S_OK;
}
return E_INVALIDARG;
}
///////////////////////////////////////////////////////////////////////////
//
// IDeskBandEx implementation
//
/**************************************************************************
CDeskBand::MoveBand()
**************************************************************************/
STDMETHODIMP CDeskBand::MoveBand(void)
{
if (g_pTipbarWnd)
{
g_pTipbarWnd->GetLangBarMgr()->ShowFloating(TF_SFT_SHOWNORMAL);
//
// Don't need ask remove language deskband since we do it by calling
// ShowFloating().
//
return S_FALSE;
}
else
{
//
// Let's Explorer remove language deskband.
//
return S_OK;
}
}
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
/**************************************************************************
CDeskBand::GetClassID()
**************************************************************************/
STDMETHODIMP CDeskBand::GetClassID(LPCLSID pClassID)
{
*pClassID = CLSID_MSUTBDeskBand;
return S_OK;
}
/**************************************************************************
CDeskBand::IsDirty()
**************************************************************************/
STDMETHODIMP CDeskBand::IsDirty(void)
{
return S_FALSE;
}
/**************************************************************************
CDeskBand::Load()
**************************************************************************/
STDMETHODIMP CDeskBand::Load(LPSTREAM pStream)
{
return S_OK;
}
/**************************************************************************
CDeskBand::Save()
**************************************************************************/
STDMETHODIMP CDeskBand::Save(LPSTREAM pStream, BOOL fClearDirty)
{
return S_OK;
}
/**************************************************************************
CDeskBand::GetSizeMax()
**************************************************************************/
STDMETHODIMP CDeskBand::GetSizeMax(ULARGE_INTEGER *pul)
{
return E_NOTIMPL;
}
///////////////////////////////////////////////////////////////////////////
//
// IContextMenu Implementation
//
/**************************************************************************
CDeskBand::QueryContextMenu()
**************************************************************************/
STDMETHODIMP CDeskBand::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,
CRStr(IDS_RESTORE));
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_COMMAND + 1));
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
}
/**************************************************************************
CDeskBand::InvokeCommand()
**************************************************************************/
STDMETHODIMP CDeskBand::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
{
switch (LOWORD(lpcmi->lpVerb))
{
case IDM_COMMAND:
//
// Load floating language bar and close language band.
//
if (g_pTipbarWnd)
{
g_pTipbarWnd->GetLangBarMgr()->ShowFloating(TF_SFT_SHOWNORMAL);
}
//
// Need to remove language band here
//
break;
default:
return E_INVALIDARG;
}
return NOERROR;
}
/**************************************************************************
CDeskBand::GetCommandString()
**************************************************************************/
STDMETHODIMP CDeskBand::GetCommandString( UINT_PTR idCommand,
UINT uFlags,
LPUINT lpReserved,
LPSTR lpszName,
UINT uMaxNameLen)
{
HRESULT hr = E_INVALIDARG;
switch(uFlags)
{
case GCS_HELPTEXT:
switch(idCommand)
{
case IDM_COMMAND:
StringCchCopy(lpszName, uMaxNameLen, "Desk Band command help text");
hr = NOERROR;
break;
}
break;
case GCS_VERB:
switch(idCommand)
{
case IDM_COMMAND:
StringCchCopy(lpszName, uMaxNameLen, "command");
hr = NOERROR;
break;
}
break;
case GCS_VALIDATE:
hr = NOERROR;
break;
}
return hr;
}
///////////////////////////////////////////////////////////////////////////
//
// private method implementations
//
/**************************************************************************
CDeskBand::FocusChange()
**************************************************************************/
void CDeskBand::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);
}
}
/**************************************************************************
CDeskBand::OnSetFocus(HWND hWnd)
**************************************************************************/
void CDeskBand::OnSetFocus(HWND hWndvoid)
{
FocusChange(TRUE);
return;
}
/**************************************************************************
CDeskBand::OnKillFocus(HWND hWnd)
**************************************************************************/
void CDeskBand::OnKillFocus(HWND hWndvoid)
{
FocusChange(FALSE);
return;
}
/**************************************************************************
CDeskBand::RegisterAndCreateWindow()
**************************************************************************/
BOOL CDeskBand::RegisterAndCreateWindow(void)
{
// If the window doesn't exist yet, create it now.
if (!g_pTipbarWnd)
{
m_fTipbarCreating = TRUE;
GetTipbarInternal(m_hwndParent, 0, this);
m_fTipbarCreating = FALSE;
}
if (!g_pTipbarWnd)
return FALSE;
return (NULL != g_pTipbarWnd->GetWnd());
}
/**************************************************************************
CDeskBand::ResizeRebar()
**************************************************************************/
BOOL CDeskBand::ResizeRebar(HWND hwnd, int nSize, BOOL fFit)
{
RECT rc0;
RECT rc1;
//
// id is not initialized yet.
//
if (m_dwBandID == -1)
{
return FALSE;
}
GetWindowRect(hwnd, &rc0);
GetWindowRect(m_hwndParent, &rc1);
//
// if the current size is nSize, we don't need to do anything.
//
int nCurSize;
if (DBIF_VIEWMODE_VERTICAL & m_dwViewMode)
nCurSize = rc0.bottom - rc0.top;
else
nCurSize = rc0.right - rc0.left;
if (nCurSize == nSize)
return TRUE;
//
// if the current size is bigger than nSize, we don't need to do anything.
//
if (!fFit && (nCurSize > nSize))
return TRUE;
//
// start pos and end pos is offset of Rebar window.
//
LPARAM lStart;
LPARAM lEnd;
if (DBIF_VIEWMODE_VERTICAL & m_dwViewMode)
{
int nStart = rc0.top - rc1.top;
int nEnd = nStart + nCurSize - nSize;
lStart = MAKELPARAM(1, nStart);
lEnd = MAKELPARAM(1, nEnd);
}
else
{
int nStart;
int nEnd;
if (g_dwWndStyle & UIWINDOW_LAYOUTRTL)
{
nStart = rc1.right - rc0.right;
nEnd = nStart + nCurSize - nSize;
}
else
{
nStart = rc0.left - rc1.left;
nEnd = nStart + nCurSize - nSize;
}
lStart = MAKELPARAM(nStart, 1);
lEnd = MAKELPARAM(nEnd, 1);
}
//
// #560192
//
// SendMessage() can yield another message in this thread and
// this could be a request to remove langband. So this pointer
// can be gone while the calls.
// We want to finish the series of SendMessage() so keep the window
// handle in the stack.
//
HWND hwndParent = m_hwndParent;
int nIndex = (int)SendMessage(hwndParent, RB_IDTOINDEX, m_dwBandID, 0);
if (nIndex == -1)
return FALSE;
//
// move the deskband.
//
SendMessage(hwndParent, RB_BEGINDRAG, nIndex, lStart);
SendMessage(hwndParent, RB_DRAGMOVE, 0, lEnd);
SendMessage(hwndParent, RB_ENDDRAG, 0, 0);
return TRUE;
}
/**************************************************************************
CDeskBand::DeleteBand()
**************************************************************************/
void CDeskBand::DeleteBand()
{
HWND hwndParent = m_hwndParent;
int nIndex = (int)SendMessage(hwndParent, RB_IDTOINDEX, m_dwBandID, 0);
if (nIndex == -1)
return;
SendMessage(hwndParent, RB_DELETEBAND, nIndex, 0);
}