1366 lines
37 KiB
C++
1366 lines
37 KiB
C++
/******************************************************************************
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
Toolbar.cpp
|
|
|
|
Abstract:
|
|
This file contains the ActiveX control that makes Win32 ToolBars available to HTML.
|
|
|
|
Revision History:
|
|
Davide Massarenti (Dmassare) 03/04/2001
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include <comctrlp.h>
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define HISTORY_MENU__LIMIT (10) // Just pick a limited number of items.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static const MPC::StringToBitField c_Images[] =
|
|
{
|
|
{ L"BACK" , -1, 0, -1 },
|
|
{ L"FORWARD" , -1, 1, -1 },
|
|
{ L"HOME" , -1, 2, -1 },
|
|
{ L"INDEX" , -1, 3, -1 },
|
|
{ L"FAVORITES" , -1, 4, -1 },
|
|
{ L"HISTORY" , -1, 5, -1 },
|
|
{ L"SUPPORT" , -1, 6, -1 },
|
|
{ L"OPTIONS" , -1, 7, -1 },
|
|
{ L"ADDFAV" , -1, 8, -1 },
|
|
{ L"PRINT" , -1, 9, -1 },
|
|
{ L"LOCATE" , -1, 10, -1 },
|
|
|
|
{ L"LAYOUT_SMALL", -1, 11, -1 },
|
|
{ L"LAYOUT_LARGE", -1, 12, -1 },
|
|
|
|
{ NULL }
|
|
};
|
|
|
|
const MPC::StringToBitField CPCHToolBar::c_TypeLookup[] =
|
|
{
|
|
{ L"BACK" , -1, CPCHToolBar::TYPE_back , -1 },
|
|
{ L"FORWARD" , -1, CPCHToolBar::TYPE_forward , -1 },
|
|
{ L"SEPARATOR", -1, CPCHToolBar::TYPE_separator, -1 },
|
|
{ L"GENERIC" , -1, CPCHToolBar::TYPE_generic , -1 },
|
|
|
|
{ NULL }
|
|
};
|
|
|
|
CFG_BEGIN_FIELDS_MAP(CPCHToolBar::Button)
|
|
CFG_ATTRIBUTE ( L"ID" , wstring, m_strID ),
|
|
CFG_ATTRIBUTE ( L"ACCESSKEY" , WCHAR , m_wch ),
|
|
CFG_ATTRIBUTE ( L"ENABLED" , bool , m_fEnabled ),
|
|
CFG_ATTRIBUTE ( L"VISIBLE" , bool , m_fVisible ),
|
|
CFG_ATTRIBUTE ( L"HIDETEXT" , bool , m_fHideText ),
|
|
CFG_ATTRIBUTE ( L"SYSTEMMENU" , bool , m_fSystemMenu ),
|
|
|
|
CFG_ATTRIBUTE__BITFIELD( L"TYPE" , m_dwType , c_TypeLookup ),
|
|
|
|
CFG_ELEMENT ( L"IMAGE_NORMAL" , wstring, m_strImage_Normal ),
|
|
CFG_ELEMENT ( L"IMAGE_HOT" , wstring, m_strImage_Hot ),
|
|
CFG_ELEMENT ( L"TEXT" , wstring, m_strText ),
|
|
CFG_ELEMENT ( L"TOOLTIP" , wstring, m_strToolTip ),
|
|
CFG_END_FIELDS_MAP()
|
|
|
|
CFG_BEGIN_CHILD_MAP(CPCHToolBar::Button)
|
|
CFG_END_CHILD_MAP()
|
|
|
|
DEFINE_CFG_OBJECT(CPCHToolBar::Button,L"BUTTON")
|
|
|
|
DEFINE_CONFIG_METHODS__NOCHILD(CPCHToolBar::Button)
|
|
|
|
////////////////////
|
|
|
|
CFG_BEGIN_FIELDS_MAP(CPCHToolBar::Config)
|
|
CFG_ATTRIBUTE( L"WIDTH" , long, m_lWidth ),
|
|
CFG_ATTRIBUTE( L"HEIGHT" , long, m_lHeight ),
|
|
CFG_ATTRIBUTE( L"ICONSIZE", long, m_lIconSize ),
|
|
CFG_END_FIELDS_MAP()
|
|
|
|
CFG_BEGIN_CHILD_MAP(CPCHToolBar::Config)
|
|
CFG_CHILD(CPCHToolBar::Button)
|
|
CFG_END_CHILD_MAP()
|
|
|
|
DEFINE_CFG_OBJECT(CPCHToolBar::Config,L"TOOLBAR")
|
|
|
|
|
|
DEFINE_CONFIG_METHODS_CREATEINSTANCE_SECTION(CPCHToolBar::Config,tag,defSubType)
|
|
if(tag == _cfg_table_tags[0])
|
|
{
|
|
defSubType = &(*(m_lstButtons.insert( m_lstButtons.end() )));
|
|
return S_OK;
|
|
}
|
|
DEFINE_CONFIG_METHODS_SAVENODE_SECTION(CPCHToolBar::Config,xdn)
|
|
DEFINE_CONFIG_METHODS_END(CPCHToolBar::Config)
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CPCHToolBar::Button::Button()
|
|
{
|
|
// MPC::wstring m_strID;
|
|
m_wch = 0; // WCHAR m_wch;
|
|
m_fEnabled = false; // bool m_fEnabled;
|
|
m_fVisible = false; // bool m_fVisible;
|
|
m_fHideText = false; // bool m_fHideText;
|
|
m_fSystemMenu = false; // bool m_fSystemMenu;
|
|
// MPC::wstring m_strType;
|
|
//
|
|
// MPC::wstring m_strImage_Normal;
|
|
// MPC::wstring m_strImage_Hot;
|
|
// MPC::wstring m_strText;
|
|
// MPC::wstring m_strToolTip;
|
|
//
|
|
//
|
|
m_idCmd = 0; // int m_idCmd;
|
|
m_iImage_Normal = -1; // int m_iImage_Normal;
|
|
m_iImage_Hot = -1; // int m_iImage_Hot;
|
|
}
|
|
|
|
void CPCHToolBar::Button::UpdateState( /*[in]*/ HWND hwndTB )
|
|
{
|
|
LRESULT lResult = ::SendMessageW( hwndTB, TB_GETSTATE, m_idCmd, 0 );
|
|
|
|
lResult &= ~(TBSTATE_ENABLED | TBSTATE_INDETERMINATE | TBSTATE_HIDDEN);
|
|
|
|
lResult |= (m_fEnabled ? TBSTATE_ENABLED : TBSTATE_INDETERMINATE);
|
|
lResult |= (m_fVisible ? 0 : TBSTATE_HIDDEN );
|
|
|
|
::SendMessageW( hwndTB, TB_SETSTATE, m_idCmd, MAKELONG(lResult, 0) );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CPCHToolBar::Config::Config()
|
|
{
|
|
// long m_lWidth;
|
|
// long m_lHeight;
|
|
// long m_lIconSize;
|
|
//
|
|
m_mode = TB_SELECTED; // TB_MODE m_mode;
|
|
// ButtonList m_lstButtons;
|
|
//
|
|
m_himlNormal = NULL; // HIMAGELIST m_himlNormal;
|
|
m_himlHot = NULL; // HIMAGELIST m_himlHot;
|
|
|
|
if(CPCHOptions::s_GLOBAL)
|
|
{
|
|
m_mode = CPCHOptions::s_GLOBAL->TextLabels();
|
|
}
|
|
|
|
Reset();
|
|
}
|
|
|
|
CPCHToolBar::Button* CPCHToolBar::Config::LookupButton( /*[in]*/ LPCWSTR szID ,
|
|
/*[in]*/ int idCmd )
|
|
{
|
|
for(ButtonIter it = m_lstButtons.begin(); it != m_lstButtons.end(); it++)
|
|
{
|
|
Button& bt = *it;
|
|
|
|
if(szID != NULL && bt.m_strID == szID ) return &bt;
|
|
if(idCmd != -1 && bt.m_idCmd == idCmd) return &bt;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void CPCHToolBar::Config::Reset()
|
|
{
|
|
(void)::ImageList_Destroy( m_himlNormal );
|
|
(void)::ImageList_Destroy( m_himlHot );
|
|
|
|
m_lWidth = 0; // long m_lWidth;
|
|
m_lHeight = 0; // long m_lHeight;
|
|
m_lIconSize = 24; // long m_lIconSize;
|
|
m_fRTL = false; // bool m_fRTL;
|
|
//
|
|
m_lstButtons.clear(); // ButtonList m_lstButtons;
|
|
//
|
|
m_himlNormal = NULL; // HIMAGELIST m_himlNormal;
|
|
m_himlHot = NULL; // HIMAGELIST m_himlHot;
|
|
}
|
|
|
|
HRESULT CPCHToolBar::Config::Load( /*[in]*/ LPCWSTR szBaseURL ,
|
|
/*[in]*/ LPCWSTR szDefinition ,
|
|
/*[in]*/ LPCWSTR szDir )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHToolBar::Config::Load" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IStream> stream;
|
|
|
|
|
|
Reset();
|
|
|
|
m_fRTL = (MPC::StrICmp( szDir, L"RTL" ) == 0);
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::HTML::OpenStream( szBaseURL, szDefinition, stream ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::Config::LoadStream( this, stream ));
|
|
|
|
//
|
|
// Load all the images.
|
|
//
|
|
{
|
|
COLORREF crMask = RGB( 255, 0, 255 );
|
|
LPCWSTR szDef;
|
|
LPCWSTR szHot;
|
|
int cx;
|
|
|
|
if(m_lIconSize == 24)
|
|
{
|
|
szDef = MAKEINTRESOURCEW(IDB_TB_DEF_24);
|
|
szHot = MAKEINTRESOURCEW(IDB_TB_HOT_24);
|
|
cx = 24;
|
|
}
|
|
else
|
|
{
|
|
szDef = MAKEINTRESOURCEW(IDB_TB_DEF_16);
|
|
szHot = MAKEINTRESOURCEW(IDB_TB_HOT_16);
|
|
cx = 16;
|
|
}
|
|
|
|
m_himlNormal = ::ImageList_LoadImageW( ::GetModuleHandle( NULL ), szDef, cx, 0, crMask, IMAGE_BITMAP, LR_CREATEDIBSECTION );
|
|
m_himlHot = ::ImageList_LoadImageW( ::GetModuleHandle( NULL ), szHot, cx, 0, crMask, IMAGE_BITMAP, LR_CREATEDIBSECTION );
|
|
|
|
for(ButtonIter it = m_lstButtons.begin(); it != m_lstButtons.end(); it++)
|
|
{
|
|
Button& bt = *it;
|
|
|
|
if(bt.m_strImage_Normal.size())
|
|
{
|
|
if(bt.m_strImage_Hot.length() == 0) bt.m_strImage_Hot = bt.m_strImage_Normal;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MergeImage( szBaseURL, bt.m_strImage_Normal.c_str(), m_himlNormal, bt.m_iImage_Normal ));
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MergeImage( szBaseURL, bt.m_strImage_Hot .c_str(), m_himlHot , bt.m_iImage_Hot ));
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(FAILED(hr)) Reset();
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT CPCHToolBar::Config::CreateButtons( /*[in]*/ HWND hwndTB )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHToolBar::Config::CreateButtons" );
|
|
|
|
HRESULT hr;
|
|
TBBUTTON* tbs = NULL;
|
|
int iNum = m_lstButtons.size();
|
|
int iCmd = 1;
|
|
|
|
//
|
|
// Remove previous buttons.
|
|
//
|
|
{
|
|
INT_PTR nCount = ::SendMessageW( hwndTB, TB_BUTTONCOUNT, 0, 0L );
|
|
|
|
while(nCount-- > 0) ::SendMessageW( hwndTB, TB_DELETEBUTTON, nCount, 0L );
|
|
}
|
|
|
|
if(iNum)
|
|
{
|
|
TBBUTTON* ptr;
|
|
ButtonIter it;
|
|
|
|
__MPC_EXIT_IF_ALLOC_FAILS(hr, tbs, new TBBUTTON[iNum]);
|
|
|
|
::SendMessageW( hwndTB, TB_SETIMAGELIST , 0, (LPARAM)m_himlNormal );
|
|
::SendMessageW( hwndTB, TB_SETHOTIMAGELIST, 0, (LPARAM)m_himlHot );
|
|
|
|
for(ptr = tbs, it = m_lstButtons.begin(); it != m_lstButtons.end(); ptr++, it++)
|
|
{
|
|
Button& bt = *it; ::ZeroMemory( ptr, sizeof(TBBUTTON) );
|
|
|
|
bt.m_idCmd = iCmd++;
|
|
|
|
ptr->iBitmap = I_IMAGECALLBACK;
|
|
ptr->idCommand = bt.m_idCmd;
|
|
ptr->fsState = (bt.m_fEnabled ? TBSTATE_ENABLED : TBSTATE_INDETERMINATE) | (bt.m_fVisible ? 0 : TBSTATE_HIDDEN) | TBSTATE_ELLIPSES;
|
|
ptr->fsStyle |= BTNS_AUTOSIZE;
|
|
|
|
if(bt.m_strText.size())
|
|
{
|
|
switch(m_mode)
|
|
{
|
|
case TB_NONE:
|
|
break;
|
|
|
|
case TB_SELECTED:
|
|
if(bt.m_fHideText) break;
|
|
|
|
case TB_ALL:
|
|
ptr->iString = (INT_PTR)bt.m_strText.c_str();
|
|
ptr->fsStyle |= BTNS_SHOWTEXT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch(bt.m_dwType)
|
|
{
|
|
case TYPE_back : ptr->fsStyle |= BTNS_DROPDOWN; break;
|
|
case TYPE_forward : ptr->fsStyle |= BTNS_DROPDOWN; break;
|
|
case TYPE_separator: ptr->fsStyle |= BTNS_SEP ; ptr->fsStyle &= ~(BTNS_AUTOSIZE | BTNS_SHOWTEXT); break;
|
|
case TYPE_generic : break;
|
|
}
|
|
}
|
|
|
|
::SendMessageW( hwndTB, TB_ADDBUTTONSW, iNum, (LPARAM)tbs );
|
|
}
|
|
|
|
::SendMessageW( hwndTB, TB_AUTOSIZE, 0, 0 );
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
delete [] tbs;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
void CPCHToolBar::Config::UpdateSize( /*[in]*/ HWND hwndTB, /*[in]*/ HWND hwndRB, /*[out]*/ SIZEL& ptIdeal )
|
|
{
|
|
REBARBANDINFOW rbbi; ::ZeroMemory( &rbbi, sizeof(rbbi) );
|
|
RECT rcMax = { 0, 0, 0, 0 };
|
|
|
|
for(ButtonIter it = m_lstButtons.begin(); it != m_lstButtons.end(); it++)
|
|
{
|
|
Button& bt = *it;
|
|
RECT rc;
|
|
|
|
if(::SendMessage( hwndTB, TB_GETRECT, bt.m_idCmd, (LPARAM)&rc ))
|
|
{
|
|
if(rcMax.left > rc.left ) rcMax.left = rc.left ;
|
|
if(rcMax.right < rc.right ) rcMax.right = rc.right ;
|
|
if(rcMax.top > rc.top ) rcMax.top = rc.top ;
|
|
if(rcMax.bottom < rc.bottom) rcMax.bottom = rc.bottom;
|
|
}
|
|
}
|
|
|
|
ptIdeal.cx = rcMax.right - rcMax.left;
|
|
ptIdeal.cy = rcMax.bottom - rcMax.top;
|
|
|
|
if(hwndRB)
|
|
{
|
|
rbbi.cbSize = sizeof(REBARBANDINFOW);
|
|
rbbi.fMask = RBBIM_IDEALSIZE;
|
|
|
|
::SendMessage( hwndRB, RB_GETBANDINFOW, 0, (LPARAM)&rbbi );
|
|
|
|
if(rbbi.cxIdeal != ptIdeal.cx)
|
|
{
|
|
rbbi.cxIdeal = ptIdeal.cx;
|
|
|
|
::SendMessage( hwndRB, RB_SETBANDINFOW, 0, (LPARAM)&rbbi );
|
|
}
|
|
}
|
|
}
|
|
|
|
HRESULT CPCHToolBar::Config::MergeImage( /*[in ]*/ LPCWSTR szBaseURL ,
|
|
/*[in ]*/ LPCWSTR szRelativeURL ,
|
|
/*[in ]*/ HIMAGELIST himl ,
|
|
/*[out]*/ int& iImage )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHToolBar::Config::MergeImage" );
|
|
|
|
HRESULT hr;
|
|
HBITMAP hBMP = NULL;
|
|
|
|
|
|
if(wcschr( szRelativeURL, '#' ))
|
|
{
|
|
DWORD dwImage = -1;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertStringToBitField( &szRelativeURL[1], dwImage, c_Images, /*fUseTilde*/false ));
|
|
|
|
iImage = dwImage;
|
|
}
|
|
else
|
|
{
|
|
COLORREF crMask = RGB( 255, 0, 255 );
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::HTML::DownloadBitmap( szBaseURL, szRelativeURL, crMask, hBMP ));
|
|
|
|
iImage = ::ImageList_GetImageCount( himl );
|
|
|
|
::ImageList_AddMasked( himl, (HBITMAP)hBMP, crMask );
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hBMP) ::DeleteObject( hBMP );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CPCHToolBar::CPCHToolBar()
|
|
{
|
|
m_bWindowOnly = TRUE; // Inherited from CComControlBase
|
|
|
|
|
|
m_parent = NULL; // CPCHHelpCenterExternal* m_parent;
|
|
m_hwndRB = NULL; // HWND m_hwndRB;
|
|
m_hwndTB = NULL; // HWND m_hwndTB;
|
|
//
|
|
// Config m_cfg;
|
|
m_fLoaded = false; // bool m_fLoaded;
|
|
|
|
{
|
|
SIZE ptIdeal;
|
|
|
|
ptIdeal.cx = 30;
|
|
ptIdeal.cy = 30;
|
|
|
|
AtlPixelToHiMetric( &ptIdeal, &m_sizeExtent );
|
|
}
|
|
}
|
|
|
|
CPCHToolBar::~CPCHToolBar()
|
|
{
|
|
}
|
|
|
|
STDMETHODIMP CPCHToolBar::SetClientSite( IOleClientSite *pClientSite )
|
|
{
|
|
CComQIPtr<IServiceProvider> sp = pClientSite;
|
|
|
|
if(m_parent)
|
|
{
|
|
CComQIPtr<IPCHHelpCenterExternalPrivate> hcep = m_parent;
|
|
|
|
if(hcep)
|
|
{
|
|
hcep->RegisterForMessages( this, /*fRemove*/true );
|
|
}
|
|
}
|
|
|
|
MPC::Release( (IUnknown*&)m_parent );
|
|
|
|
|
|
if(sp && SUCCEEDED(sp->QueryService( SID_SElementBehaviorFactory, IID_IPCHHelpCenterExternal, (void **)&m_parent )))
|
|
{
|
|
CComQIPtr<IPCHHelpCenterExternalPrivate> hcep = m_parent;
|
|
|
|
if(hcep)
|
|
{
|
|
hcep->RegisterForMessages( this, /*fRemove*/false );
|
|
}
|
|
}
|
|
|
|
return IOleObjectImpl<CPCHToolBar>::SetClientSite( pClientSite );
|
|
}
|
|
|
|
STDMETHODIMP CPCHToolBar::GetExtent( DWORD dwDrawAspect, SIZEL *psizel )
|
|
{
|
|
if(SUCCEEDED(Config_Load()))
|
|
{
|
|
UpdateSize();
|
|
|
|
if(m_cfg.m_lWidth || m_cfg.m_lHeight)
|
|
{
|
|
SIZE ptIdeal;
|
|
SIZEL sizeExtent;
|
|
|
|
ptIdeal.cx = m_cfg.m_lWidth;
|
|
ptIdeal.cy = m_cfg.m_lHeight;
|
|
|
|
AtlPixelToHiMetric( &ptIdeal, &sizeExtent );
|
|
|
|
if(m_cfg.m_lWidth != 0) m_sizeExtent.cx = sizeExtent.cx;
|
|
if(m_cfg.m_lHeight != 0) m_sizeExtent.cy = sizeExtent.cy;
|
|
}
|
|
}
|
|
|
|
return IOleObjectImpl<CPCHToolBar>::GetExtent( dwDrawAspect, psizel );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static bool local_IsButtonObscured( /*[in]*/ HWND hwnd, /*[in]*/ RECT& rcSrc, /*[in]*/ UINT_PTR iCmd )
|
|
{
|
|
UINT_PTR iButton = (UINT_PTR)::SendMessage( hwnd, TB_COMMANDTOINDEX, iCmd, 0 );
|
|
|
|
if(iButton != -1)
|
|
{
|
|
RECT rcItem;
|
|
|
|
if(::SendMessage( hwnd, TB_GETITEMRECT, iButton, (LPARAM)&rcItem ))
|
|
{
|
|
if(rcSrc.left <= rcItem.left &&
|
|
rcSrc.right >= rcItem.right &&
|
|
rcSrc.top <= rcItem.top &&
|
|
rcSrc.bottom >= rcItem.bottom )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
BOOL CPCHToolBar::ProcessWindowMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID )
|
|
{
|
|
lResult = 0;
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_THEMECHANGED:
|
|
case WM_SYSCOLORCHANGE:
|
|
UpdateSize();
|
|
break;
|
|
|
|
case WM_SETTINGCHANGE:
|
|
// (weizhao) Relay message to the toolbar control for appropriate handling of settings change.
|
|
::SendMessageW( m_hwndTB, uMsg, wParam, lParam);
|
|
UpdateSize();
|
|
break;
|
|
|
|
case WM_NOTIFYFORMAT:
|
|
if(lParam == NF_QUERY)
|
|
{
|
|
lResult = NFR_UNICODE;
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_CREATE:
|
|
if(SUCCEEDED(Rebar_Create ()) &&
|
|
SUCCEEDED(Toolbar_Create()) &&
|
|
SUCCEEDED(Rebar_AddBand ()) )
|
|
{
|
|
;
|
|
}
|
|
return TRUE;
|
|
|
|
|
|
case WM_SIZE:
|
|
{
|
|
int nWidth = LOWORD(lParam); // width of client area
|
|
int nHeight = HIWORD(lParam); // height of client area
|
|
|
|
if(m_hwndRB)
|
|
{
|
|
RECT rc;
|
|
int nClientWidth;
|
|
int nClientHeight;
|
|
|
|
::GetClientRect( m_hwndRB, &rc );
|
|
|
|
nClientWidth = rc.right - rc.left;
|
|
nClientHeight = rc.bottom - rc.top;
|
|
|
|
// resize the width of the toolbar
|
|
if(nClientWidth != nWidth ||
|
|
nClientHeight != nHeight )
|
|
{
|
|
::SetWindowPos( m_hwndRB, NULL, 0, 0, nWidth, nHeight, SWP_NOZORDER|SWP_NOACTIVATE );
|
|
}
|
|
}
|
|
|
|
if(m_parent) (void)m_parent->RefreshLayout();
|
|
}
|
|
return TRUE;
|
|
|
|
|
|
case WM_DESTROY:
|
|
m_hwndRB = NULL;
|
|
m_hwndTB = NULL;
|
|
return TRUE;
|
|
|
|
|
|
case WM_COMMAND:
|
|
switch( HIWORD(wParam) )
|
|
{
|
|
case BN_CLICKED:
|
|
(void)Fire_onCommand( LOWORD(wParam) );
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_SYSCOMMAND:
|
|
{
|
|
for(Config::ButtonIter it = m_cfg.m_lstButtons.begin(); it != m_cfg.m_lstButtons.end(); it++)
|
|
{
|
|
Button& bt = *it;
|
|
|
|
if(bt.m_idCmd == LOWORD(wParam))
|
|
{
|
|
(void)Fire_onCommand( LOWORD(wParam) );
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch( ((LPNMHDR)lParam)->code )
|
|
{
|
|
case TBN_GETINFOTIPW:
|
|
(void)OnTooltipRequest( (int)wParam, (LPNMTBGETINFOTIPW)lParam );
|
|
return TRUE;
|
|
|
|
case TBN_GETDISPINFOW:
|
|
(void)OnDispInfoRequest( (int)wParam, (LPNMTBDISPINFOW)lParam );
|
|
return TRUE;
|
|
|
|
case TBN_DROPDOWN:
|
|
(void)OnDropDown( (int)wParam, (LPNMTOOLBAR)lParam );
|
|
return TRUE;
|
|
|
|
case RBN_CHEVRONPUSHED:
|
|
(void)OnChevron( (int)wParam, (LPNMREBARCHEVRON)lParam );
|
|
return TRUE;
|
|
|
|
}
|
|
break;
|
|
|
|
case WM_SYSCHAR:
|
|
if(ProcessAccessKey( uMsg, wParam, lParam ))
|
|
{
|
|
lResult = TRUE;
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return CComControl<CPCHToolBar>::ProcessWindowMessage( hWnd, uMsg, wParam, lParam, lResult, dwMsgMapID );
|
|
}
|
|
|
|
BOOL CPCHToolBar::ProcessAccessKey( UINT uMsg, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
if(m_hwndTB && ::IsWindowVisible( m_hwndTB ))
|
|
{
|
|
WCHAR rgBuf1[2]; rgBuf1[0] = (WCHAR)wParam; rgBuf1[1] = 0; ::CharUpperW( rgBuf1 );
|
|
WCHAR rgBuf2[2]; rgBuf2[1] = 0;
|
|
|
|
for(Config::ButtonIter it = m_cfg.m_lstButtons.begin(); it != m_cfg.m_lstButtons.end(); it++)
|
|
{
|
|
Button& bt = *it;
|
|
|
|
rgBuf2[0] = bt.m_wch; ::CharUpperW( rgBuf2 );
|
|
if(rgBuf1[0] == rgBuf2[0])
|
|
{
|
|
LRESULT lState = ::SendMessageW( m_hwndTB, TB_GETSTATE, bt.m_idCmd, 0 );
|
|
|
|
if(!(lState & TBSTATE_HIDDEN ) &&
|
|
(lState & TBSTATE_ENABLED) )
|
|
{
|
|
// (tnoonan) - it feels kinda cheesy to send mouse messages, but
|
|
// I don't know of a cleaner way which will accomplish what we
|
|
// want (like deal with split buttons, mutually exclusive
|
|
// buttons, etc.).
|
|
RECT rc;
|
|
|
|
::SendMessage( m_hwndTB, TB_GETRECT, bt.m_idCmd, (LPARAM)&rc );
|
|
|
|
::SendMessage( m_hwndTB, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(rc.left, rc.top) );
|
|
::SendMessage( m_hwndTB, WM_LBUTTONUP , 0 , MAKELONG(rc.left, rc.top) );
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CPCHToolBar::Fire_onCommand( /*[in]*/ Button* bt )
|
|
{
|
|
if(bt)
|
|
{
|
|
CComVariant pvars[2];
|
|
|
|
pvars[1] = this;
|
|
pvars[0] = bt->m_strID.c_str();
|
|
|
|
(void)FireAsync_Generic( DISPID_PCH_TBE__ONCOMMAND, pvars, ARRAYSIZE( pvars ), NULL );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CPCHToolBar::Fire_onCommand( /*[in]*/ UINT_PTR iCmd )
|
|
{
|
|
return Fire_onCommand( m_cfg.LookupButton( NULL, iCmd ) );
|
|
}
|
|
|
|
////////////////////
|
|
|
|
HRESULT CPCHToolBar::OnTooltipRequest( int idCtrl, LPNMTBGETINFOTIPW tool )
|
|
{
|
|
Button* bt = m_cfg.LookupButton( NULL, tool->iItem );
|
|
|
|
if(bt)
|
|
{
|
|
wcsncpy( tool->pszText, bt->m_strToolTip.c_str(), tool->cchTextMax - 1 );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CPCHToolBar::OnDispInfoRequest( int idCtrl, LPNMTBDISPINFOW info )
|
|
{
|
|
Button* bt = m_cfg.LookupButton( NULL, info->idCommand );
|
|
|
|
if(bt)
|
|
{
|
|
if(info->dwMask & TBNF_IMAGE)
|
|
{
|
|
info->iImage = bt->m_iImage_Normal;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CPCHToolBar::OnDropDown( int idCtrl, LPNMTOOLBAR tool )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHToolBar::OnDropDown" );
|
|
|
|
HRESULT hr;
|
|
Button* bt = m_cfg.LookupButton( NULL, tool->iItem );
|
|
HMENU hMenu = NULL;
|
|
|
|
if(bt)
|
|
{
|
|
if(m_parent)
|
|
{
|
|
CPCHHelpSession* hs = m_parent->HelpSession();
|
|
if(hs && hs->IsTravelling() == false)
|
|
{
|
|
CPCHHelpSessionItem* item = hs->Current();
|
|
|
|
if(item)
|
|
{
|
|
int iCount = 0;
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hMenu = ::CreatePopupMenu()));
|
|
|
|
while((item = (bt->m_dwType == TYPE_back ? item->Previous() : item->Next())))
|
|
{
|
|
if(iCount++ < HISTORY_MENU__LIMIT)
|
|
{
|
|
CComBSTR bstrTitle;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, item->get_Title( &bstrTitle ));
|
|
|
|
if(bstrTitle.Length() == 0) MPC::LocalizeString( IDS_HELPCTR_HIST_NOTITLE, bstrTitle );
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::AppendMenuW( hMenu, MF_STRING, iCount, bstrTitle ));
|
|
}
|
|
}
|
|
|
|
if(iCount)
|
|
{
|
|
::MapWindowPoints( tool->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&tool->rcButton, 2 );
|
|
|
|
iCount = ::TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY,
|
|
tool->rcButton.left, tool->rcButton.bottom, 0, m_hWnd, NULL );
|
|
|
|
if(iCount != 0)
|
|
{
|
|
if(bt->m_dwType == TYPE_back) hs->Back ( iCount );
|
|
else hs->Forward( iCount );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hMenu) ::DestroyMenu( hMenu );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT CPCHToolBar::OnChevron( int idCtrl, LPNMREBARCHEVRON chev )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHToolBar::OnChevron" );
|
|
|
|
HRESULT hr;
|
|
RECT rcSrc;
|
|
HMENU hMenu = NULL;
|
|
bool fFound = false;
|
|
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hMenu = ::CreatePopupMenu()));
|
|
|
|
::GetClientRect( m_hwndTB, &rcSrc );
|
|
for(Config::ButtonIter it = m_cfg.m_lstButtons.begin(); it != m_cfg.m_lstButtons.end(); it++)
|
|
{
|
|
Button& bt = *it;
|
|
|
|
if(bt.m_fVisible && bt.m_fEnabled && bt.m_strText.size() && local_IsButtonObscured( m_hwndTB, rcSrc, bt.m_idCmd ))
|
|
{
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::AppendMenuW( hMenu, MF_STRING, bt.m_idCmd, bt.m_strText.c_str() ));
|
|
|
|
fFound = true;
|
|
}
|
|
}
|
|
|
|
if(fFound)
|
|
{
|
|
int iSelected;
|
|
|
|
::MapWindowPoints( chev->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&chev->rc, 2 );
|
|
|
|
iSelected = ::TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, chev->rc.left, chev->rc.bottom, 0, m_hWnd, NULL );
|
|
if(iSelected != 0)
|
|
{
|
|
(void)Fire_onCommand( iSelected );
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hMenu) ::DestroyMenu( hMenu );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CPCHToolBar::UpdateSize()
|
|
{
|
|
if(m_hwndTB)
|
|
{
|
|
SIZE ptIdeal;
|
|
SIZEL sizeExtent;
|
|
|
|
m_cfg.UpdateSize( m_hwndTB, m_hwndRB, ptIdeal );
|
|
|
|
AtlPixelToHiMetric( &ptIdeal, &sizeExtent );
|
|
|
|
if(m_cfg.m_lHeight == 0) m_sizeExtent.cy = sizeExtent.cy;
|
|
|
|
{
|
|
CComPtr<IHTMLElement> elem;
|
|
CComQIPtr<IHTMLElement2> elem2;
|
|
|
|
if(SUCCEEDED(FindElementThroughThunking( elem )) && (elem2 = elem))
|
|
{
|
|
CComPtr<IHTMLCurrentStyle> style1;
|
|
CComPtr<IHTMLStyle> style2;
|
|
|
|
if(SUCCEEDED(elem2->get_currentStyle( &style1 )) && style1 &&
|
|
SUCCEEDED(elem ->get_style ( &style2 )) && style2 )
|
|
{
|
|
CComVariant v1;
|
|
CComVariant v2;
|
|
WCHAR rgBuf[64]; swprintf( rgBuf, L"%ldpx", ptIdeal.cy );
|
|
|
|
v2 = rgBuf;
|
|
|
|
style1->get_height( &v1 );
|
|
if(v1 != v2)
|
|
{
|
|
style2->put_height( v2 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(m_parent && m_parent->Window())
|
|
{
|
|
HMENU hSys = NULL;
|
|
|
|
for(Config::ButtonIter it = m_cfg.m_lstButtons.begin(); it != m_cfg.m_lstButtons.end(); it++)
|
|
{
|
|
Button& bt = *it;
|
|
|
|
if(bt.m_fSystemMenu)
|
|
{
|
|
if(!hSys)
|
|
{
|
|
HMENU hTop;
|
|
MENUITEMINFO mii;
|
|
CComBSTR bstrTitle; MPC::LocalizeString( IDS_HELPCTR_SYSMENU_GOTO, bstrTitle );
|
|
|
|
::ZeroMemory( &mii, sizeof(mii) );
|
|
|
|
mii.cbSize = sizeof(mii);
|
|
mii.fMask = MIIM_ID | MIIM_STRING | MIIM_SUBMENU;
|
|
mii.fType = MFT_STRING;
|
|
mii.wID = 1;
|
|
mii.dwTypeData = bstrTitle;
|
|
mii.hSubMenu = hSys = ::CreatePopupMenu();
|
|
|
|
(void) ::GetSystemMenu( m_parent->Window(), TRUE );
|
|
hTop = ::GetSystemMenu( m_parent->Window(), FALSE );
|
|
|
|
::AppendMenuW ( hTop, MF_SEPARATOR, 0, 0 );
|
|
::InsertMenuItem( hTop, ::GetMenuItemCount(hTop), TRUE, &mii );
|
|
}
|
|
|
|
if(hSys)
|
|
{
|
|
switch(bt.m_dwType)
|
|
{
|
|
case TYPE_separator:
|
|
(void)::AppendMenuW( hSys, MF_SEPARATOR, 0, 0 );
|
|
break;
|
|
|
|
case TYPE_back :
|
|
case TYPE_forward:
|
|
case TYPE_generic:
|
|
(void)::AppendMenuW( hSys, MF_STRING | (bt.m_fEnabled ? 0 : MF_GRAYED), bt.m_idCmd, bt.m_strText.c_str() );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPCHToolBar::Config_Clear()
|
|
{
|
|
m_cfg.Reset();
|
|
m_fLoaded = false;
|
|
}
|
|
|
|
HRESULT CPCHToolBar::Config_Load()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHToolBar::Config_Load" );
|
|
|
|
HRESULT hr;
|
|
|
|
if(!m_fLoaded)
|
|
{
|
|
CComPtr<IServiceProvider> sp;
|
|
CComPtr<IHTMLDocument2> doc2;
|
|
CComPtr<IHTMLDocument3> doc3;
|
|
CComBSTR bstrBase;
|
|
CComBSTR bstrDir;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_spAmbientDispatch->QueryInterface( IID_IServiceProvider, (void**)&sp ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, sp->QueryService( SID_SContainerDispatch, IID_IHTMLDocument2, (void **)&doc2 ));
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, doc2->get_URL( &bstrBase ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, sp->QueryService( SID_SContainerDispatch, IID_IHTMLDocument3, (void **)&doc3 ));
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, doc3->get_dir( &bstrDir ));
|
|
|
|
Config_Clear();
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_cfg.Load( bstrBase, m_bstrDefinition, bstrDir ));
|
|
m_fLoaded = true;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
Config_Clear();
|
|
}
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT CPCHToolBar::Toolbar_Create()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHToolBar::Toolbar_Create" );
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
if(FAILED(Config_Load()))
|
|
{
|
|
; // Empty toolbar...
|
|
}
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, Rebar_Create());
|
|
|
|
if(m_hwndRB && !m_hwndTB)
|
|
{
|
|
DWORD dwStyle = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
|
|
TBSTYLE_TOOLTIPS | TBSTYLE_FLAT |
|
|
CCS_NORESIZE | CCS_NODIVIDER | CCS_NOPARENTALIGN;
|
|
|
|
DWORD dwStyleEx = TBSTYLE_EX_DRAWDDARROWS | TBSTYLE_EX_HIDECLIPPEDBUTTONS | TBSTYLE_EX_DOUBLEBUFFER;
|
|
|
|
|
|
if(m_cfg.m_mode == TB_SELECTED)
|
|
{
|
|
dwStyle |= TBSTYLE_LIST;
|
|
}
|
|
|
|
|
|
m_hwndTB = ::CreateWindowEx( WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL, dwStyle, 0, 0, 0, 0, m_hwndRB, NULL, NULL, NULL );
|
|
if(m_hwndTB == NULL)
|
|
{
|
|
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, ::GetLastError());
|
|
}
|
|
|
|
|
|
::SendMessageW( m_hwndTB, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON) , 0 );
|
|
::SendMessageW( m_hwndTB, TB_SETEXTENDEDSTYLE, dwStyleEx , dwStyleEx );
|
|
::SendMessageW( m_hwndTB, TB_SETMAXTEXTROWS , 1 , 0 );
|
|
::SendMessageW( m_hwndTB, TB_SETDROPDOWNGAP , ::GetSystemMetrics( SM_CXEDGE ) / 2, 0 );
|
|
::SendMessageW( m_hwndTB, CCM_SETVERSION , COMCTL32_VERSION , 0 );
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_cfg.CreateButtons( m_hwndTB ));
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT CPCHToolBar::Rebar_Create()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHToolBar::Rebar_Create" );
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
if(m_hWnd && !m_hwndRB)
|
|
{
|
|
DWORD dwStyle = RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE |
|
|
WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
|
|
CCS_NODIVIDER | CCS_NOPARENTALIGN;
|
|
|
|
DWORD dwStyleEx = WS_EX_TOOLWINDOW;
|
|
|
|
if(m_cfg.m_fRTL) dwStyleEx |= WS_EX_LAYOUTRTL;
|
|
|
|
m_hwndRB = ::CreateWindowEx( dwStyleEx, REBARCLASSNAME, NULL, dwStyle, 0, 0, 24, 24, m_hWnd, NULL, NULL, NULL );
|
|
if(m_hwndRB == NULL)
|
|
{
|
|
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, ::GetLastError());
|
|
}
|
|
|
|
::SendMessageW( m_hwndRB, RB_SETTEXTCOLOR, 0 , CLR_DEFAULT );
|
|
::SendMessageW( m_hwndRB, RB_SETBKCOLOR , 0 , CLR_DEFAULT );
|
|
::SendMessageW( m_hwndRB, CCM_SETVERSION , COMCTL32_VERSION, 0 );
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT CPCHToolBar::Rebar_AddBand()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHToolBar::Rebar_AddBand" );
|
|
|
|
HRESULT hr;
|
|
|
|
if(m_hwndRB && m_hwndTB)
|
|
{
|
|
REBARBANDINFOW rbbi; ::ZeroMemory( &rbbi, sizeof(rbbi) );
|
|
SIZE ptIdeal;
|
|
|
|
m_cfg.UpdateSize( m_hwndTB, NULL, ptIdeal );
|
|
|
|
rbbi.cbSize = sizeof(rbbi);
|
|
rbbi.fMask = RBBIM_ID | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_SIZE | RBBIM_STYLE | RBBIM_IDEALSIZE;
|
|
rbbi.fStyle = RBBS_NOGRIPPER | RBBS_USECHEVRON/* | RBBS_CHILDEDGE | RBBS_FIXEDBMP*/;
|
|
rbbi.hwndChild = m_hwndTB;
|
|
rbbi.cx = 0;
|
|
rbbi.cxMinChild = 0;
|
|
rbbi.cyMinChild = ptIdeal.cy;
|
|
rbbi.cxIdeal = ptIdeal.cx;
|
|
|
|
::SendMessageW( m_hwndRB, RB_INSERTBANDW, 0, (LPARAM)&rbbi );
|
|
::SendMessageW( m_hwndRB, RB_SHOWBAND , 0, (LPARAM)TRUE );
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
////#define CH_PREFIX TEXT('&')
|
|
////
|
|
////static WCHAR local_GetAccelerator( LPCWSTR sz, BOOL bUseDefault )
|
|
////{
|
|
//// WCHAR ch = (TCHAR)-1;
|
|
//// LPCWSTR szAccel = sz;
|
|
////
|
|
//// // then prefixes are allowed.... see if it has one
|
|
//// do
|
|
//// {
|
|
//// szAccel = StrChrW( szAccel, CH_PREFIX );
|
|
//// if(szAccel)
|
|
//// {
|
|
//// szAccel++;
|
|
////
|
|
//// // handle having &&
|
|
//// if(*szAccel != CH_PREFIX)
|
|
//// {
|
|
//// ch = *szAccel;
|
|
//// }
|
|
//// else
|
|
//// {
|
|
//// szAccel++;
|
|
//// }
|
|
//// }
|
|
//// } while (szAccel && (ch == (WCHAR)-1));
|
|
////
|
|
//// if((ch == (WCHAR)-1) && bUseDefault)
|
|
//// {
|
|
//// ch = *sz;
|
|
//// }
|
|
////
|
|
//// return ch;
|
|
////}
|
|
|
|
BOOL CPCHToolBar::PreTranslateAccelerator( LPMSG pMsg, HRESULT& hRet )
|
|
{
|
|
// Give toolbar a chance.
|
|
if(m_hwndTB)
|
|
{
|
|
if(::SendMessage( m_hwndTB, TB_TRANSLATEACCELERATOR, 0, (LPARAM)pMsg )) return TRUE;
|
|
|
|
if(::SendMessage( m_hwndTB, WM_FORWARDMSG, 0, (LPARAM)pMsg )) return TRUE;
|
|
|
|
//// if(pMsg->message == WM_SYSCHAR)
|
|
//// {
|
|
//// UINT idBtn;
|
|
////
|
|
//// if(::SendMessage( m_hwndTB, TB_MAPACCELERATOR, pMsg->wParam, (LPARAM)&idBtn ))
|
|
//// {
|
|
//// WCHAR rgButtonText[MAX_PATH];
|
|
////
|
|
//// // comctl says this one is the one, let's make sure we aren't getting
|
|
//// // one of the unwanted "use the first letter" accelerators that it
|
|
//// // will return.
|
|
//// if((::SendMessage( m_hwndTB, TB_GETBUTTONTEXTW, idBtn, (LPARAM)rgButtonText ) > 0) &&
|
|
//// (local_GetAccelerator( rgButtonText, FALSE ) != (WCHAR)-1))
|
|
//// {
|
|
//// // (tnoonan) - it feels kinda cheesy to send mouse messages, but
|
|
//// // I don't know of a cleaner way which will accomplish what we
|
|
//// // want (like deal with split buttons, mutually exclusive
|
|
//// // buttons, etc.).
|
|
//// RECT rc;
|
|
////
|
|
//// ::SendMessage( m_hwndTB, TB_GETRECT, idBtn, (LPARAM)&rc );
|
|
////
|
|
//// ::SendMessage( m_hwndTB, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(rc.left, rc.top) );
|
|
//// ::SendMessage( m_hwndTB, WM_LBUTTONUP , 0 , MAKELONG(rc.left, rc.top) );
|
|
////
|
|
//// return TRUE;
|
|
//// }
|
|
//// }
|
|
//// }
|
|
}
|
|
|
|
return CComControl<CPCHToolBar>::PreTranslateAccelerator( pMsg, hRet );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CPCHToolBar::get_Definition( /*[out, retval]*/ BSTR *pVal )
|
|
{
|
|
return MPC::GetBSTR( m_bstrDefinition, pVal );
|
|
}
|
|
|
|
STDMETHODIMP CPCHToolBar::put_Definition( /*[in]*/ BSTR newVal )
|
|
{
|
|
Config_Clear();
|
|
|
|
return MPC::PutBSTR( m_bstrDefinition, newVal );
|
|
}
|
|
|
|
STDMETHODIMP CPCHToolBar::get_Mode( /*[out, retval]*/ TB_MODE *pVal )
|
|
{
|
|
if(!pVal) return E_POINTER;
|
|
|
|
*pVal = m_cfg.m_mode;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CPCHToolBar::put_Mode( /*[in]*/ TB_MODE newVal )
|
|
{
|
|
bool fRecreate = false;
|
|
|
|
switch(newVal)
|
|
{
|
|
case TB_ALL :
|
|
case TB_SELECTED:
|
|
case TB_NONE : break;
|
|
default: return E_INVALIDARG;
|
|
}
|
|
|
|
//
|
|
// Adjust style.
|
|
//
|
|
if(m_hwndRB && (m_cfg.m_mode != newVal))
|
|
{
|
|
::DestroyWindow( m_hwndRB );
|
|
|
|
m_hwndRB = NULL;
|
|
m_hwndTB = NULL;
|
|
|
|
fRecreate = true;
|
|
}
|
|
|
|
m_cfg.m_mode = newVal;
|
|
|
|
if(fRecreate)
|
|
{
|
|
if(SUCCEEDED(Rebar_Create ()) &&
|
|
SUCCEEDED(Toolbar_Create()) &&
|
|
SUCCEEDED(Rebar_AddBand ()) &&
|
|
m_hwndRB )
|
|
{
|
|
RECT rc;
|
|
|
|
::GetClientRect( m_hWnd, &rc );
|
|
|
|
::SetWindowPos( m_hwndRB, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER|SWP_NOACTIVATE );
|
|
|
|
UpdateSize();
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CPCHToolBar::SetState( /*[in]*/ BSTR bstrText, /*[in]*/ VARIANT_BOOL fEnabled )
|
|
{
|
|
if(SUCCEEDED(Config_Load()))
|
|
{
|
|
Button* bt = m_cfg.LookupButton( bstrText, -1 );
|
|
|
|
if(bt)
|
|
{
|
|
bt->m_fEnabled = (fEnabled == VARIANT_TRUE);
|
|
|
|
bt->UpdateState( m_hwndTB );
|
|
|
|
UpdateSize();
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CPCHToolBar::SetVisibility( /*[in]*/ BSTR bstrText, /*[in]*/ VARIANT_BOOL fVisible )
|
|
{
|
|
if(SUCCEEDED(Config_Load()))
|
|
{
|
|
Button* bt = m_cfg.LookupButton( bstrText, -1 );
|
|
|
|
if(bt)
|
|
{
|
|
bt->m_fVisible = (fVisible == VARIANT_TRUE);
|
|
|
|
bt->UpdateState( m_hwndTB );
|
|
|
|
UpdateSize();
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// This is ugly, but unless we find a better way to get the HTML element for our site it's our only hope..
|
|
//
|
|
HRESULT CPCHToolBar::FindElementThroughThunking( /*[out]*/ CComPtr<IHTMLElement>& elem )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHToolBar::FindElementThroughThunking" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IServiceProvider> sp;
|
|
CComPtr<IHTMLDocument2> doc2;
|
|
CComPtr<IHTMLElementCollection> coll;
|
|
MPC::HTML::IHTMLElementList lst;
|
|
|
|
|
|
elem.Release();
|
|
|
|
|
|
//
|
|
// Get Document element.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_spAmbientDispatch->QueryInterface( IID_IServiceProvider, (void**)&sp ));
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, sp->QueryService( SID_SContainerDispatch, IID_IHTMLDocument2, (void **)&doc2 ));
|
|
|
|
//
|
|
// Get list of OBJECT elements.
|
|
//
|
|
MPC_SCRIPTHELPER_GET__DIRECT__NOTNULL(coll, doc2, all);
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::HTML::EnumerateCollection( lst, coll, L"<OBJECT" ));
|
|
|
|
//
|
|
// Try to locate ourself.
|
|
//
|
|
for(MPC::HTML::IHTMLElementIter it=lst.begin(); it != lst.end(); it++)
|
|
{
|
|
CComQIPtr<IPCHToolBarPrivate> tb = *it;
|
|
|
|
if(tb && SUCCEEDED(tb->SameObject( this )))
|
|
{
|
|
elem = *it;
|
|
break;
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
MPC::ReleaseAll( lst );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|