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.
2680 lines
83 KiB
2680 lines
83 KiB
/////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 1993-1996 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// MODULE: itbar.cpp
|
|
//
|
|
// PURPOSE: Implements the sizable coolbar window.
|
|
//
|
|
|
|
/********************************************************************************
|
|
Please do not make any changes to this file because this file is going to be
|
|
deleted from this project soon
|
|
Instead add the changes to tbbands.cpp and tbbands.h
|
|
*********************************************************************************/
|
|
|
|
#include "pch.hxx"
|
|
#include "ourguid.h"
|
|
#include "browser.h"
|
|
#include <resource.h>
|
|
#include "itbar.h"
|
|
#include "strconst.h"
|
|
#include "thormsgs.h"
|
|
#include <error.h>
|
|
#include "xpcomm.h"
|
|
#include "conman.h"
|
|
#include "mailnews.h"
|
|
#include "shared.h"
|
|
#include <shlwapi.h>
|
|
#include "statnery.h"
|
|
#include "goptions.h"
|
|
#include "menuutil.h"
|
|
#include "menures.h"
|
|
#include <shlobjp.h>
|
|
#include <shlguidp.h>
|
|
#include "demand.h"
|
|
#include "baui.h"
|
|
|
|
UINT GetCurColorRes(void);
|
|
|
|
CCoolbar::CCoolbar() : m_cRef(1), m_yCapture(-1)
|
|
{
|
|
DOUTL(1, TEXT("ctor CCoolbar %x"), this);
|
|
|
|
m_cRef = 1;
|
|
m_ptbSite = NULL;
|
|
m_cxMaxButtonWidth = 70;
|
|
m_ftType = FOLDER_TYPESMAX;
|
|
m_ptai = NULL;
|
|
m_fSmallIcons = FALSE;
|
|
|
|
m_hwndParent = NULL;
|
|
m_hwndTools = NULL;
|
|
m_hwndBrand = NULL;
|
|
m_hwndSizer = NULL;
|
|
m_hwndRebar = NULL;
|
|
|
|
ZeroMemory(&m_cbsSavedInfo, sizeof(COOLBARSAVE));
|
|
m_csSide = COOLBAR_TOP;
|
|
m_dwState = 0;
|
|
|
|
m_idbBack = 0;
|
|
m_hbmBack = NULL;
|
|
m_hbmBrand = NULL;
|
|
Assert(2 == CIMLISTS);
|
|
m_rghimlTools[IMLIST_DEFAULT] = NULL;
|
|
m_rghimlTools[IMLIST_HOT] = NULL;
|
|
|
|
m_hpal = NULL;
|
|
m_hdc = NULL;
|
|
m_xOrg = 0;
|
|
m_yOrg = 0;
|
|
m_cxBmp = 0;
|
|
m_cyBmp = 0;
|
|
m_cxBrand = 0;
|
|
m_cyBrand = 0;
|
|
m_cxBrandExtent = 0;
|
|
m_cyBrandExtent = 0;
|
|
m_cyBrandLeadIn = 0;
|
|
m_rgbUpperLeft = 0;
|
|
|
|
m_pMenuBand = NULL;
|
|
m_pDeskBand = NULL;
|
|
m_pShellMenu = NULL;
|
|
m_pWinEvent = NULL;
|
|
m_mbCallback = NULL;
|
|
|
|
m_xCapture = -1;
|
|
m_yCapture = -1;
|
|
|
|
// Bug #12953 - Try to load the localized max button width from the resources
|
|
TCHAR szBuffer[32];
|
|
if (AthLoadString(idsMaxCoolbarBtnWidth, szBuffer, ARRAYSIZE(szBuffer)))
|
|
{
|
|
m_cxMaxButtonWidth = StrToInt(szBuffer);
|
|
if (m_cxMaxButtonWidth == 0)
|
|
m_cxMaxButtonWidth = 70;
|
|
}
|
|
}
|
|
|
|
|
|
CCoolbar::~CCoolbar()
|
|
{
|
|
int i;
|
|
|
|
DOUTL(1, TEXT("dtor CCoolbar %x"), this);
|
|
|
|
if (m_ptbSite)
|
|
{
|
|
AssertSz(m_ptbSite == NULL, _T("CCoolbar::~CCoolbar() - For some reason ")
|
|
_T("we still have a pointer to the site."));
|
|
m_ptbSite->Release();
|
|
m_ptbSite = NULL;
|
|
}
|
|
|
|
if (m_hpal)
|
|
DeleteObject(m_hpal);
|
|
if (m_hdc)
|
|
DeleteDC(m_hdc);
|
|
if (m_hbmBrand)
|
|
DeleteObject(m_hbmBrand);
|
|
if ( m_hbmBack )
|
|
DeleteObject( m_hbmBack );
|
|
|
|
for (i = 0; i < CIMLISTS; i++)
|
|
{
|
|
if (m_rghimlTools[i])
|
|
ImageList_Destroy(m_rghimlTools[i]);
|
|
}
|
|
|
|
SafeRelease(m_pDeskBand);
|
|
SafeRelease(m_pMenuBand);
|
|
SafeRelease(m_pWinEvent);
|
|
SafeRelease(m_pShellMenu);
|
|
SafeRelease(m_mbCallback);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::HrInit()
|
|
//
|
|
// PURPOSE: Initializes the coolbar with the information needed to load
|
|
// any persisted reg settings and the correct arrays of buttons
|
|
// to display.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> idBackground - Resource ID of the background bitmap to use.
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK - Everything initialized correctly.
|
|
//
|
|
HRESULT CCoolbar::HrInit(DWORD idBackground, HMENU hmenu)
|
|
{
|
|
DWORD cbData;
|
|
DWORD dwType;
|
|
|
|
// Save the path and value so we can save ourselves on exit
|
|
m_idbBack = idBackground;
|
|
|
|
// See if we can get the previously saved information first
|
|
ZeroMemory(&m_cbsSavedInfo, sizeof(COOLBARSAVE));
|
|
|
|
cbData = sizeof(COOLBARSAVE);
|
|
AthUserGetValue(NULL, c_szRegCoolbarLayout, &dwType, (LPBYTE)&m_cbsSavedInfo, &cbData);
|
|
|
|
if (m_cbsSavedInfo.dwVersion != COOLBAR_VERSION)
|
|
{
|
|
// Either the version didn't match, or we didn't read anything. Use
|
|
// default values
|
|
m_cbsSavedInfo.dwVersion = COOLBAR_VERSION;
|
|
m_cbsSavedInfo.csSide = COOLBAR_TOP;
|
|
|
|
m_cbsSavedInfo.bs[0].wID = CBTYPE_MENUBAND;
|
|
m_cbsSavedInfo.bs[0].dwStyle = RBBS_GRIPPERALWAYS;
|
|
|
|
m_cbsSavedInfo.bs[1].wID = CBTYPE_BRAND;
|
|
|
|
m_cbsSavedInfo.bs[2].wID = CBTYPE_TOOLS;
|
|
m_cbsSavedInfo.bs[2].dwStyle = RBBS_BREAK;
|
|
|
|
m_cbsSavedInfo.dwState |= CBSTATE_COMPRESSED;
|
|
}
|
|
|
|
m_csSide = m_cbsSavedInfo.csSide;
|
|
m_dwState = m_cbsSavedInfo.dwState;
|
|
|
|
m_hMenu = hmenu;
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
HRESULT CCoolbar::QueryInterface(REFIID riid, LPVOID * ppvObj)
|
|
{
|
|
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IOleWindow)
|
|
|| IsEqualIID(riid, IID_IDockingWindow))
|
|
{
|
|
*ppvObj = (IDockingWindow*)this;
|
|
m_cRef++;
|
|
DOUTL(2, TEXT("CCoolbar::QI(IID_IDockingWindow) called. _cRef=%d"), m_cRef);
|
|
return S_OK;
|
|
}
|
|
else if (IsEqualIID(riid, IID_IObjectWithSite))
|
|
{
|
|
*ppvObj = (IObjectWithSite*)this;
|
|
m_cRef++;
|
|
DOUTL(2, TEXT("CCoolbar::QI(IID_IObjectWithSite) called. _cRef=%d"), m_cRef);
|
|
return S_OK;
|
|
}
|
|
else if (IsEqualIID(riid, IID_IShellMenuCallback))
|
|
{
|
|
*ppvObj = (IShellMenuCallback*)this;
|
|
m_cRef++;
|
|
DOUTL(2, TEXT("CCoolbar::QI(IID_IShellCallback) called. _cRef=%d"), m_cRef);
|
|
return S_OK;
|
|
}
|
|
|
|
*ppvObj = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
ULONG CCoolbar::AddRef()
|
|
{
|
|
m_cRef++;
|
|
DOUTL(4, TEXT("CCoolbar::AddRef() - m_cRef = %d"), m_cRef);
|
|
return m_cRef;
|
|
}
|
|
|
|
ULONG CCoolbar::Release()
|
|
{
|
|
m_cRef--;
|
|
DOUTL(4, TEXT("CCoolbar::Release() - m_cRef = %d"), m_cRef);
|
|
|
|
if (m_cRef > 0)
|
|
return m_cRef;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::GetWindow()
|
|
//
|
|
// PURPOSE: Returns the window handle of the top side rebar.
|
|
//
|
|
HRESULT CCoolbar::GetWindow(HWND * lphwnd)
|
|
{
|
|
if (m_hwndSizer)
|
|
{
|
|
*lphwnd = m_hwndSizer;
|
|
return (S_OK);
|
|
}
|
|
else
|
|
{
|
|
*lphwnd = NULL;
|
|
return (E_FAIL);
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT CCoolbar::ContextSensitiveHelp(BOOL fEnterMode)
|
|
{
|
|
return (E_NOTIMPL);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::SetSite()
|
|
//
|
|
// PURPOSE: Allows the owner of the coolbar to tell it what the current
|
|
// IDockingWindowSite interface to use is.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> punkSite - Pointer of the IUnknown to query for IDockingWindowSite.
|
|
// If this is NULL, we just release our current pointer.
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK - Everything worked
|
|
// E_FAIL - Could not get IDockingWindowSite from the punkSite provided.
|
|
//
|
|
HRESULT CCoolbar::SetSite(IUnknown* punkSite)
|
|
{
|
|
// If we had a previous pointer, release it.
|
|
if (m_ptbSite)
|
|
{
|
|
m_ptbSite->Release();
|
|
m_ptbSite = NULL;
|
|
}
|
|
|
|
// If a new site was provided, get the IDockingWindowSite interface from it.
|
|
if (punkSite)
|
|
{
|
|
if (FAILED(punkSite->QueryInterface(IID_IDockingWindowSite,
|
|
(LPVOID*) &m_ptbSite)))
|
|
{
|
|
Assert(m_ptbSite);
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
HRESULT CCoolbar::GetSite(REFIID riid, LPVOID *ppvSite)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::ShowDW()
|
|
//
|
|
// PURPOSE: Causes the coolbar to be either shown or hidden.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> fShow - TRUE if the coolbar should be shown, FALSE to hide.
|
|
//
|
|
// RETURN VALUE:
|
|
// HRESULT
|
|
//
|
|
#define SIZABLECLASS TEXT("SizableRebar")
|
|
HRESULT CCoolbar::ShowDW(BOOL fShow)
|
|
{
|
|
HRESULT hres = S_OK;
|
|
int i = 0, j = 0;
|
|
|
|
// Check to see if our window has been created yet. If not, do that first.
|
|
if (!m_hwndSizer && m_ptbSite)
|
|
{
|
|
m_hwndParent = NULL;
|
|
hres = m_ptbSite->GetWindow(&m_hwndParent);
|
|
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
WNDCLASSEX wc;
|
|
|
|
// Check to see if we need to register our window class
|
|
wc.cbSize = sizeof(WNDCLASSEX);
|
|
if (!GetClassInfoEx(g_hInst, SIZABLECLASS, &wc))
|
|
{
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = SizableWndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = g_hInst;
|
|
wc.hCursor = NULL;
|
|
wc.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName = SIZABLECLASS;
|
|
wc.hIcon = NULL;
|
|
wc.hIconSm = NULL;
|
|
|
|
RegisterClassEx(&wc);
|
|
}
|
|
|
|
// Load the background bitmap to use for the coolbar and also get
|
|
// a handle to the HDC and Palette for the coolbar. This will be
|
|
// used to draw the animated logo later.
|
|
m_hdc = CreateCompatibleDC(NULL);
|
|
if (GetDeviceCaps(m_hdc, RASTERCAPS) & RC_PALETTE)
|
|
m_hpal = SHCreateShellPalette(m_hdc);
|
|
|
|
// If we're trying to show the coolbar, then create the rebar and
|
|
// add it's bands based on information saved in the registry.
|
|
if (SUCCEEDED(CreateRebar(fShow)))
|
|
{
|
|
for (i = 0; i < (int) CBANDS; i++)
|
|
{
|
|
switch (m_cbsSavedInfo.bs[i].wID)
|
|
{
|
|
case CBTYPE_BRAND:
|
|
hres = ShowBrand();
|
|
break;
|
|
|
|
case CBTYPE_MENUBAND:
|
|
hres = CreateMenuBand(&m_cbsSavedInfo.bs[i]);
|
|
break;
|
|
|
|
case CBTYPE_TOOLS:
|
|
hres = AddTools(&(m_cbsSavedInfo.bs[i]));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set our state flags. If we're going to hide, then also save our current
|
|
// settings in the registry.
|
|
|
|
/*
|
|
if (fShow)
|
|
ClearFlag(CBSTATE_HIDDEN);
|
|
else
|
|
{
|
|
SetFlag(CBSTATE_HIDDEN);
|
|
//SaveSettings();
|
|
}
|
|
*/
|
|
|
|
// Resize the rebar based on it's new hidden / visible state and also
|
|
// show or hide the window.
|
|
if (m_hwndSizer)
|
|
{
|
|
ResizeBorderDW(NULL, NULL, FALSE);
|
|
//ShowWindow(m_hwndSizer, fShow ? SW_SHOW : SW_HIDE);
|
|
}
|
|
|
|
if (g_pConMan)
|
|
g_pConMan->Advise(this);
|
|
|
|
return hres;
|
|
}
|
|
|
|
void CCoolbar::HideToolbar(DWORD dwBandID)
|
|
{
|
|
REBARBANDINFO rbbi = {0};
|
|
DWORD cBands;
|
|
DWORD iBand;
|
|
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_ID | RBBIM_STYLE;
|
|
|
|
// Find the band
|
|
cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
for (iBand = 0; iBand < cBands; iBand++)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi);
|
|
if (rbbi.wID == dwBandID)
|
|
{
|
|
if (rbbi.fStyle & RBBS_HIDDEN)
|
|
{
|
|
rbbi.fStyle &= ~RBBS_HIDDEN;
|
|
}
|
|
else
|
|
{
|
|
rbbi.fStyle |= RBBS_HIDDEN;
|
|
}
|
|
|
|
rbbi.fMask = RBBIM_STYLE;
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, iBand, (LPARAM) &rbbi);
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::CloseDW()
|
|
//
|
|
// PURPOSE: Destroys the coolbar.
|
|
//
|
|
HRESULT CCoolbar::CloseDW(DWORD dwReserved)
|
|
{
|
|
if (m_hwndSizer)
|
|
{
|
|
SaveSettings();
|
|
DestroyWindow(m_hwndSizer);
|
|
m_hwndSizer = NULL;
|
|
}
|
|
|
|
|
|
if (m_pDeskBand)
|
|
{
|
|
IInputObject *pinpobj;
|
|
|
|
if (SUCCEEDED(m_pDeskBand->QueryInterface(IID_IInputObject, (LPVOID*)&pinpobj)))
|
|
{
|
|
pinpobj->UIActivateIO(FALSE, NULL);
|
|
pinpobj->Release();
|
|
}
|
|
|
|
IObjectWithSite *pobjsite;
|
|
|
|
if (SUCCEEDED(m_pDeskBand->QueryInterface(IID_IObjectWithSite, (LPVOID*)&pobjsite)))
|
|
{
|
|
pobjsite->SetSite(NULL);
|
|
pobjsite->Release();
|
|
}
|
|
m_pDeskBand->ShowDW(FALSE);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::ResizeBorderDW()
|
|
//
|
|
// PURPOSE: This is called when the coolbar needs to resize. The coolbar
|
|
// in return figures out how much border space will be required
|
|
// from the parent frame and tells the parent to reserve that
|
|
// space. The coolbar then resizes itself to those dimensions.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> prcBorder - Rectangle containing the border space for the
|
|
// parent.
|
|
// <in> punkToolbarSite - Pointer to the IDockingWindowSite that we are
|
|
// part of.
|
|
// <in> fReserved - Ignored.
|
|
//
|
|
// RETURN VALUE:
|
|
// HRESULT
|
|
//
|
|
HRESULT CCoolbar::ResizeBorderDW(LPCRECT prcBorder,
|
|
IUnknown* punkToolbarSite,
|
|
BOOL fReserved)
|
|
{
|
|
const DWORD c_cxResizeBorder = 3;
|
|
const DWORD c_cyResizeBorder = 3;
|
|
|
|
HRESULT hres = S_OK;
|
|
RECT rcRequest = { 0, 0, 0, 0 };
|
|
|
|
// If we don't have a stored site pointer, we can't resize.
|
|
if (!m_ptbSite)
|
|
{
|
|
AssertSz(m_ptbSite, _T("CCoolbar::ResizeBorderDW() - Can't resize ")
|
|
_T("without an IDockingWindowSite interface to call."));
|
|
return (E_INVALIDARG);
|
|
}
|
|
|
|
// If we're visible, then calculate our border rectangle.
|
|
/*
|
|
if (IsFlagClear(CBSTATE_HIDDEN))
|
|
{
|
|
*/
|
|
RECT rcBorder, rcRebar, rcT;
|
|
int cx, cy;
|
|
|
|
// Get the size this rebar currently is
|
|
GetWindowRect(m_hwndRebar, &rcRebar);
|
|
cx = rcRebar.right - rcRebar.left;
|
|
cy = rcRebar.bottom - rcRebar.top;
|
|
|
|
// Find out how big our parent's border space is
|
|
m_ptbSite->GetBorderDW((IDockingWindow*) this, &rcBorder);
|
|
|
|
// If we're vertical, then we need to adjust our height to
|
|
// match what the parent has. If we're horizontal, then
|
|
// adjust our width.
|
|
if (VERTICAL(m_csSide))
|
|
cy = rcBorder.bottom - rcBorder.top;
|
|
else
|
|
cx = rcBorder.right - rcBorder.left;
|
|
|
|
// Bug #31007 - There seems to be a problem in commctrl
|
|
// IEBug #5574 either with the REBAR or with the Toolbar
|
|
// when they are vertical. If the we try to
|
|
// size them to 2 or less, we lock up. This
|
|
// is a really poor fix, but there's no way
|
|
// to get commctrl fixed this late in the game.
|
|
if (cy < 5) cy = 10;
|
|
if (cx < 5) cx = 10;
|
|
|
|
// Move the rebar to the new position.
|
|
if (m_csSide == COOLBAR_LEFT || m_csSide == COOLBAR_TOP)
|
|
{
|
|
SetWindowPos(m_hwndRebar, NULL, 0, 0, cx, cy,
|
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
|
}
|
|
else
|
|
{
|
|
if (m_csSide == COOLBAR_BOTTOM)
|
|
SetWindowPos(m_hwndRebar, NULL, 0, c_cyResizeBorder,
|
|
cx, cy, SWP_NOZORDER | SWP_NOACTIVATE);
|
|
else
|
|
SetWindowPos(m_hwndRebar, NULL, c_cxResizeBorder, 0,
|
|
cx, cy, SWP_NOZORDER | SWP_NOACTIVATE);
|
|
}
|
|
|
|
// Figure out how much border space to ask the site for
|
|
GetWindowRect(m_hwndRebar, &rcRebar);
|
|
switch (m_csSide)
|
|
{
|
|
case COOLBAR_TOP:
|
|
rcRequest.top = rcRebar.bottom - rcRebar.top + c_cxResizeBorder;
|
|
break;
|
|
|
|
case COOLBAR_LEFT:
|
|
rcRequest.left = rcRebar.right - rcRebar.left + c_cyResizeBorder;
|
|
break;
|
|
|
|
case COOLBAR_BOTTOM:
|
|
rcRequest.bottom = rcRebar.bottom - rcRebar.top + c_cxResizeBorder;
|
|
break;
|
|
|
|
case COOLBAR_RIGHT:
|
|
rcRequest.right = rcRebar.right - rcRebar.left + c_cyResizeBorder;
|
|
break;
|
|
|
|
default:
|
|
AssertSz(FALSE, _T("CCoolbar::ResizeBorderDW() - What other")
|
|
_T(" sides are there???"));
|
|
break;
|
|
}
|
|
|
|
// Ask the site for that border space
|
|
if (SUCCEEDED(m_ptbSite->RequestBorderSpaceDW((IDockingWindow*) this, &rcRequest)))
|
|
{
|
|
// Position the window based on the area given to us
|
|
switch (m_csSide)
|
|
{
|
|
case COOLBAR_TOP:
|
|
SetWindowPos(m_hwndSizer, NULL,
|
|
rcBorder.left,
|
|
rcBorder.top,
|
|
rcRebar.right - rcRebar.left,
|
|
rcRequest.top + rcBorder.top,
|
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
|
break;
|
|
|
|
case COOLBAR_LEFT:
|
|
SetWindowPos(m_hwndSizer, NULL,
|
|
rcBorder.left,
|
|
rcBorder.top,
|
|
rcRequest.left,
|
|
rcBorder.bottom - rcBorder.top,
|
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
|
break;
|
|
|
|
case COOLBAR_BOTTOM:
|
|
SetWindowPos(m_hwndSizer, NULL,
|
|
rcBorder.left,
|
|
rcBorder.bottom - rcRequest.bottom,
|
|
rcBorder.right - rcBorder.left,
|
|
rcRequest.bottom,
|
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
|
GetClientRect(m_hwndSizer, &rcT);
|
|
break;
|
|
|
|
case COOLBAR_RIGHT:
|
|
SetWindowPos(m_hwndSizer, NULL,
|
|
rcBorder.right - rcRequest.right,
|
|
rcBorder.top,
|
|
rcRequest.right,
|
|
rcBorder.bottom - rcBorder.top,
|
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
|
break;
|
|
}
|
|
}
|
|
/*
|
|
}
|
|
*/
|
|
|
|
// Now tell the site how much border space we're using.
|
|
m_ptbSite->SetBorderSpaceDW((IDockingWindow*) this, &rcRequest);
|
|
|
|
return hres;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::Invoke()
|
|
//
|
|
// PURPOSE: Allows the owner of the coolbar to force the coolbar to do
|
|
// something.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> id - ID of the command the caller wants the coolbar to do.
|
|
// <in> pv - Pointer to any parameters the coolbar might need to carry
|
|
// out the command.
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK - The command was carried out.
|
|
//
|
|
// COMMENTS:
|
|
// <???>
|
|
//
|
|
HRESULT CCoolbar::Invoke(DWORD id, LPVOID pv)
|
|
{
|
|
switch (id)
|
|
{
|
|
// Starts animating the logo
|
|
case idDownloadBegin:
|
|
StartDownload();
|
|
break;
|
|
|
|
// Stops animating the logo
|
|
case idDownloadEnd:
|
|
StopDownload();
|
|
break;
|
|
|
|
// Update the enabled / disabled state of buttons on the toolbar
|
|
case idStateChange:
|
|
{
|
|
// pv is a pointer to a COOLBARSTATECHANGE struct
|
|
COOLBARSTATECHANGE* pcbsc = (COOLBARSTATECHANGE*) pv;
|
|
SendMessage(m_hwndTools, TB_ENABLEBUTTON, pcbsc->id,
|
|
MAKELONG(pcbsc->fEnable, 0));
|
|
break;
|
|
}
|
|
|
|
case idToggleButton:
|
|
{
|
|
COOLBARSTATECHANGE* pcbsc = (COOLBARSTATECHANGE *) pv;
|
|
SendMessage(m_hwndTools, TB_CHECKBUTTON, pcbsc->id,
|
|
MAKELONG(pcbsc->fEnable, 0));
|
|
break;
|
|
}
|
|
|
|
case idBitmapChange:
|
|
{
|
|
// pv is a pointer to a COOLBARBITMAPCHANGE struct
|
|
COOLBARBITMAPCHANGE *pcbc = (COOLBARBITMAPCHANGE*) pv;
|
|
|
|
SendMessage(m_hwndTools, TB_CHANGEBITMAP, pcbc->id, MAKELPARAM(pcbc->index, 0));
|
|
break;
|
|
}
|
|
|
|
// Sends a message directly to the toolbar.
|
|
case idSendToolMessage:
|
|
#define ptm ((TOOLMESSAGE *)pv)
|
|
ptm->lResult = SendMessage(m_hwndTools, ptm->uMsg, ptm->wParam, ptm->lParam);
|
|
break;
|
|
#undef ptm
|
|
|
|
case idCustomize:
|
|
SendMessage(m_hwndTools, TB_CUSTOMIZE, 0, 0);
|
|
break;
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::StartDownload()
|
|
//
|
|
// PURPOSE: Starts animating the logo.
|
|
//
|
|
void CCoolbar::StartDownload()
|
|
{
|
|
if (m_hwndBrand)
|
|
{
|
|
SetFlag(CBSTATE_ANIMATING);
|
|
SetFlag(CBSTATE_FIRSTFRAME);
|
|
m_yOrg = 0;
|
|
SetTimer(m_hwndSizer, ANIMATION_TIMER, 100, NULL);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::StopDownload()
|
|
//
|
|
// PURPOSE: Stops animating the logo. Restores the logo to it's default
|
|
// first frame.
|
|
//
|
|
void CCoolbar::StopDownload()
|
|
{
|
|
int i, cBands;
|
|
REBARBANDINFO rbbi;
|
|
|
|
// Set the background colors for this band back to the first frame
|
|
cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_ID;
|
|
|
|
for (i = 0; i < cBands; i++)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
|
|
if (CBTYPE_BRAND == rbbi.wID)
|
|
{
|
|
rbbi.fMask = RBBIM_COLORS;
|
|
rbbi.clrFore = m_rgbUpperLeft;
|
|
rbbi.clrBack = m_rgbUpperLeft;
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM) &rbbi);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Reset the state flags
|
|
ClearFlag(CBSTATE_ANIMATING);
|
|
ClearFlag(CBSTATE_FIRSTFRAME);
|
|
|
|
KillTimer(m_hwndSizer, ANIMATION_TIMER);
|
|
InvalidateRect(m_hwndBrand, NULL, FALSE);
|
|
UpdateWindow(m_hwndBrand);
|
|
}
|
|
|
|
BOOL CCoolbar::CheckForwardWinEvent(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plres)
|
|
{
|
|
HWND hwndForward = NULL;
|
|
switch(uMsg)
|
|
{
|
|
case WM_NOTIFY:
|
|
hwndForward = ((LPNMHDR)lParam)->hwndFrom;
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
hwndForward = GET_WM_COMMAND_HWND(wParam, lParam);
|
|
break;
|
|
|
|
case WM_SYSCOLORCHANGE:
|
|
case WM_WININICHANGE:
|
|
case WM_PALETTECHANGED:
|
|
hwndForward = m_hwndRebar;
|
|
break;
|
|
}
|
|
|
|
if (hwndForward && m_pWinEvent && m_pWinEvent->IsWindowOwner(hwndForward) == S_OK)
|
|
{
|
|
LRESULT lres;
|
|
m_pWinEvent->OnWinEvent(hwndForward, uMsg, wParam, lParam, &lres);
|
|
if (plres)
|
|
*plres = lres;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::SizableWndProc()
|
|
//
|
|
// PURPOSE: Handles messages sent to the coolbar root window.
|
|
//
|
|
LRESULT EXPORT_16 CALLBACK CCoolbar::SizableWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CCoolbar* pitbar = (CCoolbar*)GetProp(hwnd, TEXT("CCoolbar"));
|
|
DWORD dw;
|
|
|
|
if (!pitbar)
|
|
goto CallDWP;
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_SYSCOLORCHANGE:
|
|
// Reload the graphics
|
|
LoadGlyphs(pitbar->m_hwndTools, CIMLISTS, pitbar->m_rghimlTools, (fIsWhistler() ? TB_BMP_CX : TB_BMP_CX_W2K),
|
|
(fIsWhistler() ? ((GetCurColorRes() > 24) idb32256Browser : idbBrowser) :
|
|
((GetCurColorRes() > 8) ? idbNW256Browser : idbNWBrowser)));
|
|
pitbar->UpdateToolbarColors();
|
|
InvalidateRect(pitbar->m_hwndTools, NULL, TRUE);
|
|
pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, NULL);
|
|
break;
|
|
|
|
case WM_WININICHANGE:
|
|
case WM_FONTCHANGE:
|
|
// Forward this to our child windows
|
|
LoadGlyphs(pitbar->m_hwndTools, CIMLISTS, pitbar->m_rghimlTools, (fIsWhistler() ? TB_BMP_CX : TB_BMP_CX_W2K),
|
|
(fIsWhistler() ? ((GetCurColorRes() > 24) idb32256Browser : idbBrowser) :
|
|
((GetCurColorRes() > 8) ? idbNW256Browser : idbNWBrowser)));
|
|
SendMessage(pitbar->m_hwndTools, uMsg, wParam, lParam);
|
|
InvalidateRect(pitbar->m_hwndTools, NULL, TRUE);
|
|
pitbar->SetMinDimensions();
|
|
pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, NULL);
|
|
break;
|
|
|
|
case WM_SETCURSOR:
|
|
// We play with the cursor a bit to make the resizing cursor show
|
|
// up when the user is over the edge of the coolbar that allows
|
|
// them to drag to resize etc.
|
|
if ((HWND) wParam == hwnd)
|
|
{
|
|
if (pitbar->m_dwState & CBSTATE_INMENULOOP)
|
|
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
|
else
|
|
SetCursor(LoadCursor(NULL,
|
|
VERTICAL(pitbar->m_csSide) ? IDC_SIZEWE : IDC_SIZENS));
|
|
return (TRUE);
|
|
}
|
|
return (FALSE);
|
|
|
|
case WM_LBUTTONDOWN:
|
|
// The user is about to resize the bar. Capture the cursor so we
|
|
// can watch the changes.
|
|
if (VERTICAL(pitbar->m_csSide))
|
|
pitbar->m_xCapture = GET_X_LPARAM(lParam);
|
|
else
|
|
pitbar->m_yCapture = GET_Y_LPARAM(lParam);
|
|
SetCapture(hwnd);
|
|
break;
|
|
|
|
case WM_MOUSEMOVE:
|
|
// The user is resizing the bar. Handle updating the sizes as
|
|
// they drag.
|
|
if (VERTICAL(pitbar->m_csSide))
|
|
{
|
|
if (pitbar->m_xCapture != -1)
|
|
{
|
|
if (hwnd != GetCapture())
|
|
pitbar->m_xCapture = -1;
|
|
else
|
|
pitbar->TrackSlidingX(GET_X_LPARAM(lParam));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pitbar->m_yCapture != -1)
|
|
{
|
|
if (hwnd != GetCapture())
|
|
pitbar->m_yCapture = -1;
|
|
else
|
|
pitbar->TrackSlidingY(GET_Y_LPARAM(lParam));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_LBUTTONUP:
|
|
// The user is done resizing. release our capture and reset our
|
|
// state.
|
|
if (pitbar->m_yCapture != -1 || pitbar->m_xCapture != -1)
|
|
{
|
|
ReleaseCapture();
|
|
pitbar->m_yCapture = -1;
|
|
pitbar->m_xCapture = -1;
|
|
}
|
|
break;
|
|
|
|
case WM_VKEYTOITEM:
|
|
case WM_CHARTOITEM:
|
|
// We must swallow these messages to avoid infinit SendMessage
|
|
break;
|
|
|
|
case WM_DRAWITEM:
|
|
// Draws the animating brand
|
|
if (wParam == idcBrand)
|
|
pitbar->DrawBranding((LPDRAWITEMSTRUCT) lParam);
|
|
break;
|
|
|
|
case WM_MEASUREITEM:
|
|
// Draws the animating brand
|
|
if (wParam == idcBrand)
|
|
{
|
|
((LPMEASUREITEMSTRUCT) lParam)->itemWidth = pitbar->m_cxBrand;
|
|
((LPMEASUREITEMSTRUCT) lParam)->itemHeight = pitbar->m_cyBrand;
|
|
}
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
// This timer fires every time we need to draw the next frame in
|
|
// animating brand.
|
|
if (wParam == ANIMATION_TIMER)
|
|
{
|
|
if (pitbar->m_hwndBrand)
|
|
{
|
|
pitbar->m_yOrg += pitbar->m_cyBrand;
|
|
if (pitbar->m_yOrg >= pitbar->m_cyBrandExtent)
|
|
pitbar->m_yOrg = pitbar->m_cyBrandLeadIn;
|
|
|
|
InvalidateRect(pitbar->m_hwndBrand, NULL, FALSE);
|
|
UpdateWindow(pitbar->m_hwndBrand);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
LRESULT lres;
|
|
if (pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, &lres))
|
|
return lres;
|
|
return pitbar->OnNotify(hwnd, lParam);
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
LRESULT lres;
|
|
if (pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, &lres))
|
|
return lres;
|
|
return SendMessage(pitbar->m_hwndParent, WM_COMMAND, wParam, lParam);
|
|
}
|
|
|
|
case WM_CONTEXTMENU:
|
|
pitbar->OnContextMenu((HWND) wParam, LOWORD(lParam), HIWORD(lParam));
|
|
break;
|
|
|
|
case WM_PALETTECHANGED:
|
|
// BUGBUG: we could optimize this by realizing and checking the
|
|
// return value
|
|
//
|
|
// for now we will just invalidate ourselves and all children...
|
|
RedrawWindow(pitbar->m_hwndSizer, NULL, NULL,
|
|
RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
|
|
break;
|
|
|
|
case CM_CONNECT:
|
|
// wParam is hMenuConnect, lParam is CmdID
|
|
g_pConMan->Connect((HMENU) wParam, lParam, pitbar->m_hwndParent);
|
|
g_pConMan->FreeConnectMenu((HMENU) wParam);
|
|
break;
|
|
|
|
case TT_ISTEXTVISIBLE:
|
|
return (!(pitbar->m_dwState & CBSTATE_COMPRESSED));
|
|
|
|
case WM_DESTROY:
|
|
// Clean up our pointers
|
|
RemoveProp(hwnd, TEXT("CCoolbar"));
|
|
pitbar->Release(); // Corresponding to AddRef at SetProp
|
|
|
|
DOUTL(1, _T("CCoolbar::WM_DESTROY - Called RemoveProp. Called")
|
|
_T(" Release() new m_cRef=%d"), pitbar->m_cRef);
|
|
|
|
//Unregister with the connection manager
|
|
if (g_pConMan)
|
|
g_pConMan->Unadvise(pitbar);
|
|
|
|
// fall through
|
|
|
|
default:
|
|
CallDWP:
|
|
return(DefWindowProc(hwnd, uMsg, wParam, lParam));
|
|
}
|
|
|
|
return 0L;
|
|
}
|
|
|
|
HRESULT CCoolbar::OnCommand(HWND hwnd, int idCmd, HWND hwndControl, UINT cmd)
|
|
{
|
|
LPTSTR pszTest;
|
|
|
|
switch (idCmd)
|
|
{
|
|
case idcBrand: // click on the spinning globe
|
|
OnHelpGoto(hwnd, ID_MSWEB_PRODUCT_NEWS);
|
|
break;
|
|
|
|
case ID_CUSTOMIZE:
|
|
SendMessage(m_hwndTools, TB_CUSTOMIZE, 0, 0);
|
|
break;
|
|
|
|
case ID_TOOLBAR_TOP:
|
|
//case ID_TOOLBAR_LEFT:
|
|
case ID_TOOLBAR_BOTTOM:
|
|
//case ID_TOOLBAR_RIGHT:
|
|
{
|
|
// There's a painting problem that occurs going from top to bottom
|
|
// and vice versa. If that's what we're doing, we repaint when
|
|
// we're done.
|
|
BOOL fRepaint;
|
|
fRepaint = (VERTICAL(m_csSide) == VERTICAL(idCmd - ID_TOOLBAR_TOP));
|
|
|
|
m_csSide = (COOLBAR_SIDE) (idCmd - ID_TOOLBAR_TOP);
|
|
ChangeOrientation();
|
|
|
|
if (fRepaint)
|
|
InvalidateRect(m_hwndTools, NULL, FALSE);
|
|
}
|
|
break;
|
|
|
|
case ID_TEXT_LABELS:
|
|
CompressBands(!IsFlagSet(CBSTATE_COMPRESSED));
|
|
break;
|
|
|
|
default:
|
|
return S_FALSE;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CCoolbar::OnInitMenuPopup(HMENU hMenuContext)
|
|
{
|
|
CheckMenuRadioItem(hMenuContext, ID_TOOLBAR_TOP, ID_TOOLBAR_RIGHT,
|
|
ID_TOOLBAR_TOP + m_csSide, MF_BYCOMMAND);
|
|
|
|
CheckMenuItem(hMenuContext, ID_TEXT_LABELS,
|
|
MF_BYCOMMAND | IsFlagSet(CBSTATE_COMPRESSED) ? MF_UNCHECKED : MF_CHECKED);
|
|
return S_OK;
|
|
}
|
|
|
|
LRESULT CCoolbar::OnNotify(HWND hwnd, LPARAM lparam)
|
|
{
|
|
NMHDR *lpnmhdr = (NMHDR*)lparam;
|
|
|
|
switch (lpnmhdr->idFrom)
|
|
{
|
|
case idcCoolbar:
|
|
switch (lpnmhdr->code)
|
|
{
|
|
case RBN_HEIGHTCHANGE:
|
|
ResizeBorderDW(NULL, NULL, FALSE);
|
|
break;
|
|
|
|
case RBN_CHILDSIZE:
|
|
NMREBARCHILDSIZE *lpchildsize = (NMREBARCHILDSIZE*)lparam;
|
|
if (lpchildsize->wID == CBTYPE_TOOLS)
|
|
{
|
|
SetWindowPos(m_hwndTools, NULL, lpchildsize->rcChild.left, lpchildsize->rcChild.right,
|
|
lpchildsize->rcChild.right - lpchildsize->rcChild.left,
|
|
lpchildsize->rcChild.bottom - lpchildsize->rcChild.top,
|
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
|
|
|
}
|
|
else
|
|
if (lpchildsize->wID == CBTYPE_BRAND)
|
|
{
|
|
SetWindowPos(m_hwndBrand, NULL, lpchildsize->rcChild.left, lpchildsize->rcChild.right,
|
|
lpchildsize->rcChild.right - lpchildsize->rcChild.left,
|
|
lpchildsize->rcChild.bottom - lpchildsize->rcChild.top,
|
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case idcToolbar:
|
|
if (lpnmhdr->code == TBN_GETBUTTONINFOA)
|
|
return OnGetButtonInfo((TBNOTIFY*) lparam);
|
|
|
|
if (lpnmhdr->code == TBN_QUERYDELETE)
|
|
return (TRUE);
|
|
|
|
if (lpnmhdr->code == TBN_QUERYINSERT)
|
|
return (TRUE);
|
|
|
|
if (lpnmhdr->code == TBN_ENDADJUST)
|
|
{
|
|
IAthenaBrowser *psbwr;
|
|
|
|
// Update the size of the sizer
|
|
SetMinDimensions();
|
|
ResizeBorderDW(NULL, NULL, FALSE);
|
|
|
|
// check IDockingWindowSite
|
|
if (m_ptbSite)
|
|
{
|
|
// get IAthenaBrowser interface
|
|
if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IAthenaBrowser,(void**)&psbwr)))
|
|
{
|
|
psbwr->UpdateToolbar();
|
|
psbwr->Release();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (lpnmhdr->code == TBN_RESET)
|
|
{
|
|
// Remove all the buttons from the toolbar
|
|
int cButtons = SendMessage(m_hwndTools, TB_BUTTONCOUNT, 0, 0);
|
|
while (--cButtons >= 0)
|
|
SendMessage(m_hwndTools, TB_DELETEBUTTON, cButtons, 0);
|
|
|
|
// Set the buttons back to the default
|
|
SendMessage(m_hwndTools, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
|
|
SendMessage(m_hwndTools, TB_ADDBUTTONS, m_ptai->cDefButtons,
|
|
(LPARAM) m_ptai->rgDefButtons);
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
if (lpnmhdr->code == TBN_CUSTHELP)
|
|
{
|
|
// WinHelp(m_hwndTools, c_szMailHelpFile, HELP_CONTEXT, IDH_NEWS_COMM_GROUPBOX);
|
|
OEHtmlHelp(m_hwndTools, c_szCtxHelpFileHTMLCtx, HH_DISPLAY_TOPIC, (DWORD) (LPCSTR) "idh_proced_cust_tool.htm");
|
|
return (TRUE);
|
|
}
|
|
|
|
if (lpnmhdr->code == TBN_DROPDOWN)
|
|
{
|
|
return OnDropDown(hwnd, lpnmhdr);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return (0L);
|
|
}
|
|
|
|
|
|
LRESULT CCoolbar::OnDropDown(HWND hwnd, LPNMHDR lpnmh)
|
|
{
|
|
HMENU hMenuPopup = NULL;
|
|
TBNOTIFY *ptbn = (TBNOTIFY *)lpnmh ;
|
|
UINT uiCmd = ptbn->iItem ;
|
|
RECT rc;
|
|
DWORD dwCmd = 0;
|
|
IAthenaBrowser *pBrowser;
|
|
BOOL fPostCmd = TRUE;
|
|
IOleCommandTarget *pTarget;
|
|
|
|
// Load and initialize the appropriate dropdown menu
|
|
switch (uiCmd)
|
|
{
|
|
case ID_POPUP_LANGUAGE:
|
|
{
|
|
// check IDockingWindowSite
|
|
if (m_ptbSite)
|
|
{
|
|
// get IAthenaBrowser interface
|
|
if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IAthenaBrowser, (void**) &pBrowser)))
|
|
{
|
|
// get language menu from shell/browser
|
|
pBrowser->GetLanguageMenu(&hMenuPopup, 0);
|
|
pBrowser->Release();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ID_NEW_MSG_DEFAULT:
|
|
GetStationeryMenu(&hMenuPopup);
|
|
|
|
/* $INFOCOLUMN
|
|
// Disable Send Instant Msg item
|
|
if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IAthenaBrowser, (void**) &pBrowser)))
|
|
{
|
|
CInfoColumn * pInfoColumn = NULL;
|
|
if(SUCCEEDED(pBrowser->GetInfoColumn(&pInfoColumn)))
|
|
{
|
|
IMsgrAb * pMsgrAb = pInfoColumn->GetBAComtrol();
|
|
if(pMsgrAb)
|
|
{
|
|
BOOL fRet;
|
|
pMsgrAb->get_InstMsg(&fRet);
|
|
if(fRet == FALSE)
|
|
EnableMenuItem(hMenuPopup, ID_SEND_INSTANT_MESSAGE, MF_BYCOMMAND | MF_GRAYED);
|
|
}
|
|
pInfoColumn->Release();
|
|
}
|
|
pBrowser->Release();
|
|
}
|
|
*/
|
|
break;
|
|
|
|
case ID_PREVIEW_PANE:
|
|
{
|
|
// Load the menu
|
|
hMenuPopup = LoadPopupMenu(IDR_PREVIEW_POPUP);
|
|
if (!hMenuPopup)
|
|
break;
|
|
|
|
// check IDockingWindowSite
|
|
if (m_ptbSite)
|
|
{
|
|
// get IAthenaBrowser interface
|
|
if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IOleCommandTarget, (void**) &pTarget)))
|
|
{
|
|
MenuUtil_EnablePopupMenu(hMenuPopup, pTarget);
|
|
pTarget->Release();
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
AssertSz(FALSE, "CCoolbar::OnDropDown() - Unhandled TBN_DROPDOWN notification");
|
|
return (TBDDRET_NODEFAULT);
|
|
}
|
|
|
|
// If we loaded a menu, then go ahead and display it
|
|
if (hMenuPopup)
|
|
{
|
|
SendMessage(m_hwndTools, TB_GETRECT, ptbn->iItem, (LPARAM)&rc);
|
|
MapWindowRect(m_hwndTools, HWND_DESKTOP, &rc);
|
|
|
|
SetFlag(CBSTATE_INMENULOOP);
|
|
dwCmd = TrackPopupMenuEx(hMenuPopup, TPM_RETURNCMD | TPM_LEFTALIGN,
|
|
rc.left, rc.bottom, m_hwndParent, NULL);
|
|
ClearFlag(CBSTATE_INMENULOOP);
|
|
}
|
|
|
|
// Clean up anything needing to be cleaned up
|
|
switch (uiCmd)
|
|
{
|
|
case ID_LANGUAGE:
|
|
break;
|
|
|
|
case ID_NEW_MSG_DEFAULT:
|
|
DestroyMenu(hMenuPopup);
|
|
break;
|
|
}
|
|
|
|
if (fPostCmd && dwCmd)
|
|
PostMessage(m_hwndSizer, WM_COMMAND, dwCmd, 0);
|
|
|
|
return (TBDDRET_DEFAULT);
|
|
}
|
|
|
|
|
|
void CCoolbar::OnContextMenu(HWND hwndFrom, int xPos, int yPos)
|
|
{
|
|
HMENU hMenu, hMenuContext;
|
|
TCHAR szBuf[256];
|
|
HWND hwnd;
|
|
HWND hwndSizer = GetParent(hwndFrom);
|
|
POINT pt = {xPos, yPos};
|
|
|
|
// Make sure the context menu only appears on the toolbar bars
|
|
hwnd = WindowFromPoint(pt);
|
|
/*
|
|
if (GetClassName(hwnd, szBuf, ARRAYSIZE(szBuf)))
|
|
if (0 != lstrcmpi(szBuf, TOOLBARCLASSNAME))
|
|
return;
|
|
*/
|
|
if (hwnd == m_hwndTools)
|
|
{
|
|
if (NULL != (hMenu = LoadMenu(g_hLocRes, MAKEINTRESOURCE(IDR_TOOLBAR_POPUP))))
|
|
{
|
|
hMenuContext = GetSubMenu(hMenu, 0);
|
|
OnInitMenuPopup(hMenuContext);
|
|
|
|
SetFlag(CBSTATE_INMENULOOP);
|
|
TrackPopupMenu(hMenuContext, TPM_RIGHTBUTTON, xPos, yPos, 0,
|
|
hwndFrom, NULL);
|
|
ClearFlag(CBSTATE_INMENULOOP);
|
|
DestroyMenu(hMenu);
|
|
}
|
|
}
|
|
else
|
|
if (hwnd == m_hwndMenuBand)
|
|
{
|
|
HandleCoolbarPopup(xPos, yPos);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::OnGetButtonInfo()
|
|
//
|
|
// PURPOSE: Handles the TBN_GETBUTTONINFO notification by returning
|
|
// the buttons availble for the toolbar.
|
|
//
|
|
// PARAMETERS:
|
|
// ptbn - pointer to the TBNOTIFY struct we need to fill in.
|
|
//
|
|
// RETURN VALUE:
|
|
// Returns TRUE to tell the toolbar to use this button, or FALSE
|
|
// otherwise.
|
|
//
|
|
LRESULT CCoolbar::OnGetButtonInfo(TBNOTIFY* ptbn)
|
|
{
|
|
// Start by returning information for the first array of
|
|
// buttons
|
|
if ((ptbn->iItem < (int) m_ptai->cDefButtons && (ptbn->iItem >= 0)))
|
|
{
|
|
// Grab the button info out of the array
|
|
ptbn->tbButton = m_ptai->rgDefButtons[ptbn->iItem];
|
|
|
|
// Return the string info from the string resource. Note,
|
|
// pszText already points to a buffer allocated by the
|
|
// control and cchText has the length of that buffer.
|
|
LoadString(g_hLocRes, m_ptai->rgidsButtons[ptbn->tbButton.iString],
|
|
ptbn->pszText, ptbn->cchText);
|
|
return (TRUE);
|
|
}
|
|
else
|
|
{
|
|
// Now return information for the extra buttons not on the `
|
|
// toolbar by default.
|
|
if (ptbn->iItem < (int) (m_ptai->cDefButtons + m_ptai->cExtraButtons))
|
|
{
|
|
ptbn->tbButton = m_ptai->rgExtraButtons[ptbn->iItem - m_ptai->cDefButtons];
|
|
|
|
// The control has already created a buffer for us to copy
|
|
// the string into.
|
|
LoadString(g_hLocRes, m_ptai->rgidsButtons[ptbn->tbButton.iString],
|
|
ptbn->pszText, ptbn->cchText);
|
|
return (TRUE);
|
|
}
|
|
else
|
|
{
|
|
// No more buttons to add, so return FALSE.
|
|
return (FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT CCoolbar::ShowBrand(void)
|
|
{
|
|
REBARBANDINFO rbbi;
|
|
|
|
// create branding window
|
|
/*
|
|
m_hwndBrand = CreateWindow(TEXT("button"), NULL,WS_CHILD | BS_OWNERDRAW,
|
|
0, 0, 400, 200, m_hwndRebar, (HMENU) idcBrand,
|
|
g_hInst, NULL);
|
|
*/
|
|
m_hwndBrand = CreateWindow(TEXT("button"), NULL,WS_CHILD | BS_OWNERDRAW,
|
|
0, 0, 0, 0, m_hwndRebar, (HMENU) idcBrand,
|
|
g_hInst, NULL);
|
|
|
|
if (!m_hwndBrand)
|
|
{
|
|
DOUTL(1, TEXT("!!!ERROR!!! CITB:Show CreateWindow(BRANDING) failed"));
|
|
return(E_OUTOFMEMORY);
|
|
}
|
|
|
|
LoadBrandingBitmap();
|
|
|
|
// add branding band
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_STYLE | RBBIM_COLORS | RBBIM_CHILD | RBBIM_ID;
|
|
rbbi.fStyle = RBBS_FIXEDSIZE;
|
|
rbbi.wID = CBTYPE_BRAND;
|
|
rbbi.clrFore = m_rgbUpperLeft;
|
|
rbbi.clrBack = m_rgbUpperLeft;
|
|
rbbi.hwndChild = m_hwndBrand;
|
|
|
|
|
|
SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT) -1, (LPARAM) (LPREBARBANDINFO) &rbbi);
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
HRESULT CCoolbar::LoadBrandingBitmap()
|
|
{
|
|
HKEY hKey;
|
|
DIBSECTION dib;
|
|
DWORD dwcbData;
|
|
DWORD dwType = 0;
|
|
BOOL fReg = FALSE;
|
|
BOOL fRegLoaded = FALSE;
|
|
TCHAR szScratch[MAX_PATH];
|
|
TCHAR szExpanded[MAX_PATH];
|
|
LPTSTR psz;
|
|
|
|
if (m_hbmBrand)
|
|
{
|
|
DeleteObject(m_hbmBrand);
|
|
m_hbmBrand = NULL;
|
|
}
|
|
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegKeyCoolbar, 0, KEY_QUERY_VALUE, &hKey))
|
|
{
|
|
fReg = TRUE;
|
|
dwcbData = MAX_PATH;
|
|
if (fReg && (ERROR_SUCCESS == RegQueryValueEx(hKey, IsFlagSet(CBSTATE_COMPRESSED) ? c_szValueSmBrandBitmap : c_szValueBrandBitmap, NULL, &dwType,
|
|
(LPBYTE)szScratch, &dwcbData)))
|
|
{
|
|
if (REG_EXPAND_SZ == dwType)
|
|
{
|
|
ExpandEnvironmentStrings(szScratch, szExpanded, ARRAYSIZE(szExpanded));
|
|
psz = szExpanded;
|
|
}
|
|
else
|
|
psz = szScratch;
|
|
|
|
m_hbmBrand = (HBITMAP) LoadImage(NULL, psz, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_LOADFROMFILE);
|
|
|
|
if (m_hbmBrand)
|
|
fRegLoaded = TRUE;
|
|
}
|
|
}
|
|
|
|
if (!m_hbmBrand)
|
|
{
|
|
int id = IsFlagSet(CBSTATE_COMPRESSED) ? (fIsWhistler() ? idbHiBrand26 : idbBrand26) :
|
|
(fIsWhistler() ? idbHiBrand38 : idbBrand38);
|
|
m_hbmBrand = (HBITMAP)LoadImage(g_hLocRes, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
|
|
}
|
|
|
|
GetObject(m_hbmBrand, sizeof(DIBSECTION), &dib);
|
|
m_cxBrandExtent = dib.dsBm.bmWidth;
|
|
m_cyBrandExtent = dib.dsBm.bmHeight;
|
|
|
|
m_cxBrand = m_cxBrandExtent;
|
|
|
|
dwcbData = sizeof(DWORD);
|
|
|
|
if (!fRegLoaded || (ERROR_SUCCESS != RegQueryValueEx(hKey, IsFlagSet(CBSTATE_COMPRESSED) ? c_szValueSmBrandHeight : c_szValueBrandHeight, NULL, &dwType,
|
|
(LPBYTE)&m_cyBrand, &dwcbData)))
|
|
m_cyBrand = m_cxBrandExtent;
|
|
|
|
|
|
if (!fRegLoaded || (ERROR_SUCCESS != RegQueryValueEx(hKey, IsFlagSet(CBSTATE_COMPRESSED) ? c_szValueSmBrandLeadIn : c_szValueBrandLeadIn, NULL, &dwType,
|
|
(LPBYTE)&m_cyBrandLeadIn, &dwcbData)))
|
|
m_cyBrandLeadIn = 4;
|
|
|
|
m_cyBrandLeadIn *= m_cyBrand;
|
|
|
|
SelectObject(m_hdc, m_hbmBrand);
|
|
|
|
m_rgbUpperLeft = GetPixel(m_hdc, 1, 1);
|
|
|
|
if (fReg)
|
|
RegCloseKey(hKey);
|
|
|
|
// now look for old branding entries for IE2.0 and, if found, stick them
|
|
// in the first frame of the animation sequence
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyIEMain, 0, KEY_QUERY_VALUE, &hKey))
|
|
{
|
|
dwcbData = MAX_PATH;
|
|
|
|
if (ERROR_SUCCESS == RegQueryValueEx(hKey, IsFlagSet(CBSTATE_COMPRESSED) ? c_szValueSmallBitmap : c_szValueLargeBitmap, NULL, &dwType,
|
|
(LPBYTE)szScratch, &dwcbData))
|
|
{
|
|
if (REG_EXPAND_SZ == dwType)
|
|
{
|
|
ExpandEnvironmentStrings(szScratch, szExpanded, ARRAYSIZE(szExpanded));
|
|
psz = szExpanded;
|
|
}
|
|
else
|
|
psz = szScratch;
|
|
|
|
HBITMAP hbmOld = (HBITMAP) LoadImage(NULL, psz, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_LOADFROMFILE);
|
|
|
|
if (hbmOld)
|
|
{
|
|
HDC hdcOld = CreateCompatibleDC(m_hdc);
|
|
|
|
if (hdcOld)
|
|
{
|
|
GetObject(hbmOld, sizeof(DIBSECTION), &dib);
|
|
SelectObject(hdcOld, hbmOld);
|
|
m_rgbUpperLeft = GetPixel(hdcOld, 1, 1);
|
|
StretchBlt(m_hdc, 0, 0, m_cxBrandExtent, m_cyBrand, hdcOld, 0, 0,
|
|
dib.dsBm.bmWidth, dib.dsBm.bmHeight, SRCCOPY);
|
|
DeleteDC(hdcOld);
|
|
}
|
|
|
|
DeleteObject(hbmOld);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
void CCoolbar::DrawBranding(LPDRAWITEMSTRUCT lpdis)
|
|
{
|
|
HPALETTE hpalPrev;
|
|
int x, y, cx, cy;
|
|
int yOrg = 0;
|
|
|
|
if (IsFlagSet(CBSTATE_ANIMATING))
|
|
yOrg = m_yOrg;
|
|
|
|
if (IsFlagSet(CBSTATE_FIRSTFRAME))
|
|
{
|
|
REBARBANDINFO rbbi;
|
|
int cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_ID;
|
|
|
|
for (int i = 0; i < cBands; i++)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
|
|
|
|
if (CBTYPE_BRAND == rbbi.wID)
|
|
{
|
|
rbbi.fMask = RBBIM_COLORS;
|
|
rbbi.clrFore = m_rgbUpperLeft;
|
|
rbbi.clrBack = m_rgbUpperLeft;
|
|
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM) &rbbi);
|
|
break;
|
|
}
|
|
}
|
|
|
|
ClearFlag(CBSTATE_FIRSTFRAME);
|
|
}
|
|
|
|
if (m_hpal)
|
|
{
|
|
hpalPrev = SelectPalette(lpdis->hDC, m_hpal, TRUE);
|
|
RealizePalette(lpdis->hDC);
|
|
}
|
|
|
|
x = lpdis->rcItem.left;
|
|
cx = lpdis->rcItem.right - x;
|
|
y = lpdis->rcItem.top;
|
|
cy = lpdis->rcItem.bottom - y;
|
|
|
|
if (m_cxBrand > m_cxBrandExtent)
|
|
{
|
|
HBRUSH hbrBack = CreateSolidBrush(m_rgbUpperLeft);
|
|
int xRight = lpdis->rcItem.right;
|
|
|
|
x += (m_cxBrand - m_cxBrandExtent) / 2;
|
|
cx = m_cxBrandExtent;
|
|
lpdis->rcItem.right = x;
|
|
FillRect(lpdis->hDC, &lpdis->rcItem, hbrBack);
|
|
lpdis->rcItem.right = xRight;
|
|
lpdis->rcItem.left = x + cx;
|
|
FillRect(lpdis->hDC, &lpdis->rcItem, hbrBack);
|
|
|
|
DeleteObject(hbrBack);
|
|
}
|
|
|
|
BitBlt(lpdis->hDC, x, y, cx, cy, m_hdc, 0, yOrg, SRCCOPY);
|
|
|
|
if (m_hpal)
|
|
{
|
|
SelectPalette(lpdis->hDC, hpalPrev, TRUE);
|
|
RealizePalette(lpdis->hDC);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL CCoolbar::SetMinDimensions(void)
|
|
{
|
|
REBARBANDINFO rbbi;
|
|
LRESULT lButtonSize;
|
|
int i, cBands;
|
|
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
|
|
cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
|
|
for (i = 0; i < cBands; i++)
|
|
{
|
|
rbbi.fMask = RBBIM_ID;
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
|
|
|
|
switch (rbbi.wID)
|
|
{
|
|
case CBTYPE_BRAND:
|
|
rbbi.cxMinChild = m_cxBrand;
|
|
rbbi.cyMinChild = m_cyBrand;
|
|
break;
|
|
|
|
case CBTYPE_TOOLS:
|
|
case CBTYPE_MENUBAND:
|
|
lButtonSize = SendMessage(m_hwndTools, TB_GETBUTTONSIZE, 0, 0L);
|
|
rbbi.cxMinChild = VERTICAL(m_csSide) ? HIWORD(lButtonSize) : LOWORD(lButtonSize);
|
|
rbbi.cyMinChild = VERTICAL(m_csSide) ? LOWORD(lButtonSize) : HIWORD(lButtonSize);
|
|
break;
|
|
|
|
}
|
|
|
|
rbbi.fMask = RBBIM_CHILDSIZE;
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM)&rbbi);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CCoolbar::CompressBands(BOOL fCompress)
|
|
{
|
|
LRESULT lTBStyle = 0;
|
|
int i, cBands;
|
|
REBARBANDINFO rbbi;
|
|
|
|
if (!!fCompress == IsFlagSet(CBSTATE_COMPRESSED))
|
|
// no change -- return immediately
|
|
return(FALSE);
|
|
|
|
if (fCompress)
|
|
SetFlag(CBSTATE_COMPRESSED);
|
|
else
|
|
ClearFlag(CBSTATE_COMPRESSED);
|
|
|
|
m_yOrg = 0;
|
|
LoadBrandingBitmap();
|
|
|
|
cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
for (i = 0; i < cBands; i++)
|
|
{
|
|
rbbi.fMask = RBBIM_ID;
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
|
|
|
|
if (fCompress)
|
|
{
|
|
switch (rbbi.wID)
|
|
{
|
|
case CBTYPE_TOOLS:
|
|
SendMessage(m_hwndTools, TB_SETMAXTEXTROWS, 0, 0L);
|
|
SendMessage(m_hwndTools, TB_SETBUTTONWIDTH, 0, (LPARAM) MAKELONG(0,MAX_TB_COMPRESSED_WIDTH));
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (rbbi.wID)
|
|
{
|
|
case CBTYPE_TOOLS:
|
|
SendMessage(m_hwndTools, TB_SETMAXTEXTROWS,
|
|
VERTICAL(m_csSide) ? MAX_TB_TEXT_ROWS_VERT : MAX_TB_TEXT_ROWS_HORZ, 0L);
|
|
SendMessage(m_hwndTools, TB_SETBUTTONWIDTH, 0, (LPARAM) MAKELONG(0, m_cxMaxButtonWidth));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
SetMinDimensions();
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
void CCoolbar::TrackSlidingX(int x)
|
|
{
|
|
int cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0L);
|
|
int cRows = SendMessage(m_hwndRebar, RB_GETROWCOUNT, 0, 0L);
|
|
int cxRow = SendMessage(m_hwndRebar, RB_GETROWHEIGHT, cBands - 1, 0L); // This should work correctly if vertical
|
|
REBARBANDINFO rbbi;
|
|
RECT rc;
|
|
int cxBefore;
|
|
BOOL fChanged = FALSE;
|
|
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_STYLE;
|
|
|
|
GetWindowRect(m_hwndRebar, &rc);
|
|
cxBefore = rc.right - rc.left;
|
|
|
|
if (((m_csSide == COOLBAR_LEFT) && (x < (m_xCapture - (cxRow / 2)))) ||
|
|
((m_csSide == COOLBAR_RIGHT) && (x > (m_xCapture + (cxRow / 2)))))
|
|
{
|
|
if (cRows == 1)
|
|
fChanged = CompressBands(TRUE);
|
|
/*
|
|
else
|
|
{
|
|
while (0 > --cBands)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, cBands, (LPARAM) &rbbi);
|
|
if (fChanged = (rbbi.fStyle & RBBS_BREAK))
|
|
{
|
|
rbbi.fStyle &= ~RBBS_BREAK;
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, cBands, (LPARAM) &rbbi);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
else if (((m_csSide == COOLBAR_LEFT) && (x > (m_xCapture + (cxRow / 2)))) ||
|
|
((m_csSide == COOLBAR_RIGHT) && (x < (m_xCapture - (cxRow / 2)))))
|
|
{
|
|
/*
|
|
if (!(fChanged = CompressBands(FALSE)) && (cRows < (cBands - 1)))
|
|
{
|
|
while (0 > --cBands)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, cBands, (LPARAM) &rbbi);
|
|
if (fChanged = !(rbbi.fStyle & (RBBS_BREAK | RBBS_FIXEDSIZE)))
|
|
{
|
|
rbbi.fStyle |= RBBS_BREAK;
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, cBands, (LPARAM) &rbbi);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
// TODO: There is a drawing glitch when you resize from 3 bars (No Text) to 3 bars
|
|
// with text. The _yCapture gets set to a value greater than y. So on the
|
|
// next MOUSEMOVE it figures that the user moved up and switches from 3 bars with text
|
|
// to 2 bars with text.
|
|
if (fChanged)
|
|
{
|
|
GetWindowRect(m_hwndRebar, &rc);
|
|
m_xCapture += (rc.right - rc.left) - cxBefore;
|
|
}
|
|
}
|
|
|
|
|
|
void CCoolbar::TrackSlidingY(int y)
|
|
{
|
|
int cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0L);
|
|
int cRows = SendMessage(m_hwndRebar, RB_GETROWCOUNT, 0, 0L);
|
|
int cyRow = SendMessage(m_hwndRebar, RB_GETROWHEIGHT, cBands - 1, 0L);
|
|
REBARBANDINFO rbbi;
|
|
RECT rc;
|
|
int cyBefore;
|
|
BOOL fChanged = FALSE;
|
|
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_STYLE;
|
|
|
|
GetWindowRect(m_hwndRebar, &rc);
|
|
cyBefore = rc.bottom - rc.top;
|
|
|
|
if (((m_csSide == COOLBAR_TOP) && (y < (m_yCapture - (cyRow / 2)))) ||
|
|
((m_csSide == COOLBAR_BOTTOM) && (y > (m_yCapture + (cyRow / 2)))))
|
|
{
|
|
if (cRows == 1)
|
|
fChanged = CompressBands(TRUE);
|
|
/*
|
|
else
|
|
{
|
|
while (0 > --cBands)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, cBands, (LPARAM) &rbbi);
|
|
if (fChanged = (rbbi.fStyle & RBBS_BREAK))
|
|
{
|
|
rbbi.fStyle &= ~RBBS_BREAK;
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, cBands, (LPARAM) &rbbi);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
else if (((m_csSide == COOLBAR_TOP) && (y > (m_yCapture + (cyRow / 2)))) ||
|
|
((m_csSide == COOLBAR_BOTTOM) && (y < (m_yCapture - (cyRow / 2)))))
|
|
{
|
|
/*
|
|
if (!(fChanged = CompressBands(FALSE)) && (cRows < (cBands - 1)))
|
|
{
|
|
while (0 > --cBands)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, cBands, (LPARAM) &rbbi);
|
|
if (fChanged = !(rbbi.fStyle & (RBBS_BREAK | RBBS_FIXEDSIZE)))
|
|
{
|
|
rbbi.fStyle |= RBBS_BREAK;
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, cBands, (LPARAM) &rbbi);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
// TODO: There is a drawing glitch when you resize from 3 bars (No Text) to 3 bars
|
|
// with text. The _yCapture gets set to a value greater than y. So on the
|
|
// next MOUSEMOVE it figures that the user moved up and switches from 3 bars with text
|
|
// to 2 bars with text.
|
|
if (fChanged)
|
|
{
|
|
GetWindowRect(m_hwndRebar, &rc);
|
|
m_yCapture += (rc.bottom - rc.top) - cyBefore;
|
|
}
|
|
}
|
|
|
|
|
|
// Flips the rebar from being horizontal to to vertical or the other way.
|
|
BOOL CCoolbar::ChangeOrientation()
|
|
{
|
|
LONG lStyle, lTBStyle;
|
|
|
|
lTBStyle = SendMessage(m_hwndTools, TB_GETSTYLE, 0, 0L);
|
|
lStyle = GetWindowLong(m_hwndRebar, GWL_STYLE);
|
|
SendMessage(m_hwndTools, WM_SETREDRAW, 0, 0L);
|
|
|
|
if (VERTICAL(m_csSide))
|
|
{
|
|
// Moving to Vertical
|
|
lStyle |= CCS_VERT;
|
|
lTBStyle |= TBSTYLE_WRAPABLE;
|
|
}
|
|
else
|
|
{
|
|
// Moving to Horizontal
|
|
lStyle &= ~CCS_VERT;
|
|
lTBStyle &= ~TBSTYLE_WRAPABLE;
|
|
}
|
|
|
|
SendMessage(m_hwndTools, TB_SETSTYLE, 0, lTBStyle);
|
|
SendMessage(m_hwndTools, WM_SETREDRAW, 1, 0L);
|
|
SetWindowLong(m_hwndRebar, GWL_STYLE, lStyle);
|
|
|
|
SetMinDimensions();
|
|
ResizeBorderDW(NULL, NULL, FALSE);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::CreateRebar(BOOL fVisible)
|
|
//
|
|
// PURPOSE: Creates a new rebar and sizer window.
|
|
//
|
|
// RETURN VALUE:
|
|
// Returns S_OK if the bar was created and inserted correctly,
|
|
// hrAlreadyExists if a band already is in that position,
|
|
// E_OUTOFMEMORY if a window couldn't be created.
|
|
//
|
|
HRESULT CCoolbar::CreateRebar(BOOL fVisible)
|
|
{
|
|
if (m_hwndSizer)
|
|
return (hrAlreadyExists);
|
|
|
|
// $TODO: Only give the bar with the address bar the WS_TABSTOP style.
|
|
m_hwndSizer = CreateWindowEx(0, SIZABLECLASS, NULL, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (fVisible ? WS_VISIBLE : 0),
|
|
0, 0, 100, 36, m_hwndParent, (HMENU) 0, g_hInst, NULL);
|
|
if (m_hwndSizer)
|
|
{
|
|
DOUTL(4, TEXT("Calling SetProp. AddRefing new m_cRef=%d"), m_cRef + 1);
|
|
AddRef(); // Note we Release in WM_DESTROY
|
|
SetProp(m_hwndSizer, TEXT("CCoolbar"), this);
|
|
|
|
/*
|
|
m_hwndRebar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
|
|
RBS_FIXEDORDER | RBS_VARHEIGHT | RBS_BANDBORDERS | WS_VISIBLE |
|
|
WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
|
|
CCS_NODIVIDER | CCS_NOPARENTALIGN | (VERTICAL(m_csSide) ? CCS_VERT : 0),
|
|
0, 0, 100, 136, m_hwndSizer, (HMENU) idcCoolbar, g_hInst, NULL);
|
|
*/
|
|
m_hwndRebar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
|
|
RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_DBLCLKTOGGLE |
|
|
WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPCHILDREN |
|
|
WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NOPARENTALIGN |
|
|
(VERTICAL(m_csSide) ? CCS_VERT : 0),
|
|
0, 0, 100, 136, m_hwndSizer, (HMENU) idcCoolbar, g_hInst, NULL);
|
|
if (m_hwndRebar)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_SETTEXTCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNTEXT));
|
|
SendMessage(m_hwndRebar, RB_SETBKCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNFACE));
|
|
//SendMessage(m_hwndRebar, RB_SETEXTENDEDSTYLE, RBS_EX_OFFICE9, RBS_EX_OFFICE9);
|
|
|
|
return (S_OK);
|
|
}
|
|
}
|
|
|
|
DestroyWindow(m_hwndSizer);
|
|
return (E_OUTOFMEMORY);
|
|
}
|
|
|
|
void SendSaveRestoreMessage(HWND hwnd, const TOOLBARARRAYINFO *ptai, BOOL fSave)
|
|
{
|
|
TBSAVEPARAMS tbsp;
|
|
char szSubKey[MAX_PATH], sz[MAX_PATH];
|
|
DWORD dwType;
|
|
DWORD dwVersion;
|
|
DWORD cbData = sizeof(DWORD);
|
|
DWORD dwError;
|
|
|
|
tbsp.hkr = AthUserGetKeyRoot();
|
|
AthUserGetKeyPath(sz, ARRAYSIZE(sz));
|
|
if (ptai->pszRegKey != NULL)
|
|
{
|
|
wnsprintf(szSubKey, ARRAYSIZE(szSubKey),c_szPathFileFmt, sz, ptai->pszRegKey);
|
|
tbsp.pszSubKey = szSubKey;
|
|
}
|
|
else
|
|
{
|
|
tbsp.pszSubKey = sz;
|
|
}
|
|
tbsp.pszValueName = ptai->pszRegValue;
|
|
|
|
// First check to see if the version has changed
|
|
if (!fSave)
|
|
{
|
|
if (ERROR_SUCCESS == AthUserGetValue(ptai->pszRegKey, c_szRegToolbarVersion, &dwType, (LPBYTE) &dwVersion, &cbData))
|
|
{
|
|
if (dwVersion == COOLBAR_VERSION)
|
|
SendMessage(hwnd, TB_SAVERESTORE, (WPARAM)fSave, (LPARAM)&tbsp);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwVersion = COOLBAR_VERSION;
|
|
SendMessage(hwnd, TB_SAVERESTORE, (WPARAM)fSave, (LPARAM)&tbsp);
|
|
dwError = AthUserSetValue(ptai->pszRegKey, c_szRegToolbarVersion, REG_DWORD, (LPBYTE) &dwVersion, cbData);
|
|
}
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::SaveSettings()
|
|
//
|
|
// PURPOSE: Called when we should save our state out to the specified reg
|
|
// key.
|
|
//
|
|
void CCoolbar::SaveSettings(void)
|
|
{
|
|
char szSubKey[MAX_PATH], sz[MAX_PATH];
|
|
DWORD iBand;
|
|
REBARBANDINFO rbbi;
|
|
HKEY hKey;
|
|
DWORD cBands;
|
|
|
|
// If we don't have the window, there is nothing to save.
|
|
if (!m_hwndRebar || !m_ptai)
|
|
return;
|
|
|
|
ZeroMemory(&rbbi, sizeof(REBARBANDINFO));
|
|
|
|
cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
|
|
// Collect the bar-specific information
|
|
m_cbsSavedInfo.dwVersion = COOLBAR_VERSION;
|
|
m_cbsSavedInfo.dwState = m_dwState;
|
|
m_cbsSavedInfo.csSide = m_csSide;
|
|
|
|
// Loop through the bands and save their information as well
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_SIZE | RBBIM_ID;
|
|
|
|
for (iBand = 0; iBand < cBands; iBand++)
|
|
{
|
|
Assert(IsWindow(m_hwndRebar));
|
|
if (SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi))
|
|
{
|
|
// Save the information that we care about with this band
|
|
m_cbsSavedInfo.bs[iBand].cx = rbbi.cx;
|
|
m_cbsSavedInfo.bs[iBand].dwStyle = rbbi.fStyle;
|
|
m_cbsSavedInfo.bs[iBand].wID = rbbi.wID;
|
|
|
|
// If this band has a toolbar, then we should instruct the toolbar
|
|
// to save it's information now
|
|
if (m_cbsSavedInfo.bs[iBand].wID == CBTYPE_TOOLS)
|
|
{
|
|
SendSaveRestoreMessage(rbbi.hwndChild, m_ptai, TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Default Values
|
|
m_cbsSavedInfo.bs[iBand].wID = CBTYPE_NONE;
|
|
m_cbsSavedInfo.bs[iBand].dwStyle = 0;
|
|
m_cbsSavedInfo.bs[iBand].cx = 0;
|
|
}
|
|
}
|
|
|
|
// We have all the information collected, now save that to the specified
|
|
// registry location
|
|
AthUserSetValue(NULL, c_szRegCoolbarLayout, REG_BINARY, (const LPBYTE)&m_cbsSavedInfo, sizeof(COOLBARSAVE));
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CCoolbar::AddTools()
|
|
//
|
|
// PURPOSE: Inserts the primary toolbar into the coolbar.
|
|
//
|
|
// PARAMETERS:
|
|
// pbs - Pointer to a PBANDSAVE struct with the styles and size of the
|
|
// band to insert.
|
|
//
|
|
// RETURN VALUE:
|
|
// Returns an HRESULT signifying success or failure.
|
|
//
|
|
HRESULT CCoolbar::AddTools(PBANDSAVE pbs)
|
|
{
|
|
REBARBANDINFO rbbi;
|
|
|
|
// add tools band
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_SIZE | RBBIM_ID | RBBIM_STYLE;
|
|
rbbi.fStyle = pbs->dwStyle;
|
|
rbbi.cx = pbs->cx;
|
|
// rbbi.wID = CBTYPE_TOOLS;
|
|
rbbi.wID = pbs->wID;
|
|
|
|
if (IsFlagClear(CBSTATE_NOBACKGROUND) && !m_hbmBack && m_idbBack)
|
|
m_hbmBack = (HBITMAP) LoadImage(g_hLocRes, MAKEINTRESOURCE(m_idbBack),
|
|
IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
|
|
|
|
if (m_hbmBack)
|
|
{
|
|
rbbi.fMask |= RBBIM_BACKGROUND;
|
|
rbbi.fStyle |= RBBS_FIXEDBMP;
|
|
rbbi.hbmBack = m_hbmBack;
|
|
}
|
|
else
|
|
{
|
|
rbbi.fMask |= RBBIM_COLORS;
|
|
rbbi.clrFore = GetSysColor(COLOR_BTNTEXT);
|
|
rbbi.clrBack = GetSysColor(COLOR_BTNFACE);
|
|
}
|
|
|
|
SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT) -1, (LPARAM) (LPREBARBANDINFO) &rbbi);
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT CCoolbar::SetFolderType(FOLDERTYPE ftType)
|
|
{
|
|
TCHAR szToolsText[(MAX_TB_TEXT_LENGTH+2) * MAX_TB_BUTTONS];
|
|
int i, cBands;
|
|
REBARBANDINFO rbbi;
|
|
HWND hwndDestroy = NULL;
|
|
|
|
// If we haven't created the rebar yet, this will fail. Call ShowDW() first.
|
|
if (!IsWindow(m_hwndRebar))
|
|
return (E_FAIL);
|
|
|
|
// Check to see if this would actually be a change
|
|
if (ftType == m_ftType)
|
|
return (S_OK);
|
|
|
|
// First find the band with the toolbar
|
|
cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_ID;
|
|
|
|
for (i = 0; i < cBands; i++)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
|
|
if (CBTYPE_TOOLS == rbbi.wID)
|
|
break;
|
|
}
|
|
|
|
// We didn't find it.
|
|
if (i >= cBands)
|
|
return (E_FAIL);
|
|
|
|
// Destroy the old toolbar if it exists
|
|
if (IsWindow(m_hwndTools))
|
|
{
|
|
// Save it's button configuration
|
|
SendSaveRestoreMessage(m_hwndTools, m_ptai, TRUE);
|
|
|
|
SendMessage(m_hwndTools, TB_SETIMAGELIST, 0, NULL);
|
|
SendMessage(m_hwndTools, TB_SETHOTIMAGELIST, 0, NULL);
|
|
hwndDestroy = m_hwndTools;
|
|
}
|
|
|
|
// Update our internal state information with the new folder type
|
|
Assert(ftType < FOLDER_TYPESMAX);
|
|
m_ftType = ftType;
|
|
m_ptai = &(g_rgToolbarArrayInfo[m_ftType]);
|
|
|
|
// Create a new toolbar
|
|
m_hwndTools = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL,
|
|
WS_CHILD | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS
|
|
| WS_CLIPCHILDREN | WS_CLIPSIBLINGS
|
|
| CCS_NODIVIDER | CCS_NOPARENTALIGN
|
|
| CCS_ADJUSTABLE | CCS_NORESIZE |
|
|
(VERTICAL(m_csSide) ? TBSTYLE_WRAPABLE : 0),
|
|
0, 0, 0, 0, m_hwndRebar, (HMENU) idcToolbar,
|
|
g_hInst, NULL);
|
|
|
|
Assert(m_hwndTools);
|
|
if (!m_hwndTools)
|
|
{
|
|
DOUTL(1, TEXT("CCoolbar::SetFolderType() CreateWindow(TOOLBAR) failed"));
|
|
return(E_OUTOFMEMORY);
|
|
}
|
|
|
|
InitToolbar();
|
|
|
|
// If we have previously save configuration info for this toolbar, load it
|
|
SendSaveRestoreMessage(m_hwndTools, m_ptai, FALSE);
|
|
|
|
// First find the band with the toolbar
|
|
cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_ID;
|
|
|
|
for (i = 0; i < cBands; i++)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
|
|
if (CBTYPE_TOOLS == rbbi.wID)
|
|
break;
|
|
}
|
|
|
|
|
|
// Add the toolbar to the rebar
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_CHILD;
|
|
rbbi.hwndChild = m_hwndTools;
|
|
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, (UINT) i, (LPARAM) (LPREBARBANDINFO) &rbbi);
|
|
if (hwndDestroy)
|
|
DestroyWindow(hwndDestroy);
|
|
SetMinDimensions();
|
|
ResizeBorderDW(NULL, NULL, FALSE);
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
void CCoolbar::SetSide(COOLBAR_SIDE csSide)
|
|
{
|
|
m_csSide = csSide;
|
|
ChangeOrientation();
|
|
}
|
|
|
|
void CCoolbar::SetText(BOOL fText)
|
|
{
|
|
CompressBands(!fText);
|
|
}
|
|
|
|
|
|
UINT GetCurColorRes(void)
|
|
{
|
|
HDC hdc;
|
|
UINT uColorRes;
|
|
|
|
hdc = GetDC(NULL);
|
|
uColorRes = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
|
|
ReleaseDC(NULL, hdc);
|
|
|
|
return uColorRes;
|
|
}
|
|
|
|
/* InitToolbar:
|
|
**
|
|
** Purpose:
|
|
** makes decisions about small/large bitmaps and which
|
|
** imagelist given the colordepth, then calls the
|
|
** barutil InitToolbar
|
|
*/
|
|
void CCoolbar::InitToolbar()
|
|
{
|
|
TCHAR szToolsText[(MAX_TB_TEXT_LENGTH+2) * MAX_TB_BUTTONS];
|
|
HKEY hKey;
|
|
TCHAR szValue[32];
|
|
DWORD cbValue = sizeof(szValue);
|
|
int idBmp;
|
|
|
|
// Check to see if the user has decided to use that crazy 16x16 images
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegSmallIconsPath,
|
|
0, KEY_READ, &hKey))
|
|
{
|
|
if (ERROR_SUCCESS == RegQueryValueEx(hKey, c_szRegSmallIconsValue, 0,
|
|
0, (LPBYTE) szValue, &cbValue))
|
|
{
|
|
// people in IE decided it would be cool to store a boolean
|
|
// value as REG_SZ "Yes" and "No". Lovely.
|
|
m_fSmallIcons = !lstrcmpi(szValue, c_szYes);
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
if (m_fSmallIcons)
|
|
{
|
|
idBmp = (fIsWhistler() ? ((GetCurColorRes() > 24) ? idb32SmBrowser : idbSmBrowser): idbNWSmBrowser);
|
|
}
|
|
|
|
// Check to see what our color depth is
|
|
else if (GetCurColorRes() > 24)
|
|
{
|
|
idBmp = (fIsWhistler() ? idb32256Browser : idbNW256Browser);
|
|
}
|
|
else if (GetCurColorRes() > 8)
|
|
{
|
|
idBmp = (fIsWhistler() ? idb256Browser : idbNW256Browser);
|
|
}
|
|
else
|
|
{
|
|
idBmp = (fIsWhistler() ? idbBrowser : idbNWBrowser);
|
|
}
|
|
|
|
LoadToolNames((UINT*) m_ptai->rgidsButtons, m_ptai->cidsButtons, szToolsText);
|
|
SendMessage(m_hwndTools, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS);
|
|
|
|
::InitToolbar(m_hwndTools, CIMLISTS, m_rghimlTools, m_ptai->cDefButtons,
|
|
m_ptai->rgDefButtons, szToolsText,
|
|
m_fSmallIcons ? TB_SMBMP_CX : (fIsWhistler() ? TB_BMP_CX : TB_BMP_CX_W2K),
|
|
m_fSmallIcons ? TB_SMBMP_CY : TB_BMP_CY,
|
|
IsFlagSet(CBSTATE_COMPRESSED) ? MAX_TB_COMPRESSED_WIDTH : m_cxMaxButtonWidth,
|
|
idBmp,
|
|
IsFlagSet(CBSTATE_COMPRESSED), VERTICAL(m_csSide));
|
|
|
|
//Register with the connection manager
|
|
if (g_pConMan)
|
|
{
|
|
//If Work offline is set then we should check the work offline button
|
|
SendMessage(m_hwndTools, TB_CHECKBUTTON, ID_WORK_OFFLINE, (LPARAM)(MAKELONG(g_pConMan->IsGlobalOffline(), 0)));
|
|
}
|
|
}
|
|
|
|
|
|
void CCoolbar::UpdateToolbarColors(void)
|
|
{
|
|
REBARBANDINFO rbbi;
|
|
UINT i;
|
|
UINT cBands;
|
|
|
|
// First find the band with the toolbar
|
|
cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_ID;
|
|
|
|
for (i = 0; i < cBands; i++)
|
|
{
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
|
|
if (CBTYPE_TOOLS == rbbi.wID)
|
|
break;
|
|
}
|
|
|
|
// add tools band
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_COLORS;
|
|
rbbi.clrFore = GetSysColor(COLOR_BTNTEXT);
|
|
rbbi.clrBack = GetSysColor(COLOR_BTNFACE);
|
|
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM) (LPREBARBANDINFO) &rbbi);
|
|
}
|
|
|
|
|
|
HRESULT CCoolbar::OnConnectionNotify(CONNNOTIFY nCode,
|
|
LPVOID pvData,
|
|
CConnectionManager *pConMan)
|
|
{
|
|
if ((m_hwndTools) && (nCode == CONNNOTIFY_WORKOFFLINE))
|
|
{
|
|
SendMessage(m_hwndTools, TB_CHECKBUTTON, ID_WORK_OFFLINE, (LPARAM)MAKELONG((BOOL)pvData, 0));
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: InitToolbar()
|
|
//
|
|
// PURPOSE: Given all the parameters needed to configure a toolbar,
|
|
// this function loads the image lists and configures the
|
|
// toolbar.
|
|
//
|
|
// PARAMETERS:
|
|
// hwnd - Handle of the toolbar window to init.
|
|
// phiml - Array of imagelists where the hot, disabled, and normal
|
|
// buttons are returned.
|
|
// nBtns - The number of buttons in the ptbb array.
|
|
// ptbb - Array of buttons to add to the toolbar.
|
|
// pStrings - List of toolbar button / tooltip strings to add.
|
|
// cx, cy - Size of the bitmaps being added to the toolbar.
|
|
// cxMax - Maximum button width.
|
|
// idBmp - Resource id of the first image list to load.
|
|
//
|
|
|
|
void InitToolbar(const HWND hwnd, const int cHiml, HIMAGELIST *phiml,
|
|
UINT nBtns, const TBBUTTON *ptbb,
|
|
const TCHAR *pStrings,
|
|
const int cxImg, const int cyImg, const int cxMax,
|
|
const int idBmp, const BOOL fCompressed,
|
|
const BOOL fVertical)
|
|
{
|
|
int nRows;
|
|
|
|
if (fCompressed)
|
|
nRows = 0;
|
|
else
|
|
nRows = fVertical ? MAX_TB_TEXT_ROWS_VERT : MAX_TB_TEXT_ROWS_HORZ;
|
|
|
|
LoadGlyphs(hwnd, cHiml, phiml, cxImg, idBmp);
|
|
|
|
// this tells the toolbar what version we are
|
|
SendMessage(hwnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
|
|
|
|
SendMessage(hwnd, TB_SETMAXTEXTROWS, nRows, 0L);
|
|
SendMessage(hwnd, TB_SETBITMAPSIZE, 0, MAKELONG(cxImg, cyImg));
|
|
SendMessage(hwnd, TB_SETBUTTONWIDTH, 0, MAKELONG(0, cxMax));
|
|
if (pStrings) SendMessage(hwnd, TB_ADDSTRING, 0, (LPARAM) pStrings);
|
|
if (nBtns) SendMessage(hwnd, TB_ADDBUTTONS, nBtns, (LPARAM) ptbb);
|
|
}
|
|
|
|
|
|
void LoadGlyphs(const HWND hwnd, const int cHiml, HIMAGELIST *phiml, const int cx,
|
|
const int idBmp)
|
|
{
|
|
const UINT uFlags = LR_LOADMAP3DCOLORS | LR_CREATEDIBSECTION;
|
|
HIMAGELIST LocHiml[CIMLISTS];
|
|
|
|
if (phiml == NULL)
|
|
{
|
|
phiml = LocHiml;
|
|
}
|
|
|
|
for (int i = 0; i < cHiml; i++)
|
|
{
|
|
if (phiml[i])
|
|
ImageList_Destroy(phiml[i]);
|
|
phiml[i] = ImageList_LoadImage(g_hLocRes,
|
|
MAKEINTRESOURCE(idBmp + i), cx, 0, RGB(255, 0, 255),
|
|
IMAGE_BITMAP, uFlags);
|
|
|
|
}
|
|
|
|
SendMessage(hwnd, TB_SETIMAGELIST, 0, (LPARAM) phiml[IMLIST_DEFAULT]);
|
|
|
|
// if we weren't given a full set of lists to do, then don't set this
|
|
if (CIMLISTS == cHiml)
|
|
{
|
|
SendMessage(hwnd, TB_SETHOTIMAGELIST, 0, (LPARAM) phiml[IMLIST_HOT]);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL LoadToolNames(const UINT *rgIds, const UINT cIds, TCHAR *szTools)
|
|
{
|
|
for (UINT i = 0; i < cIds; i++)
|
|
{
|
|
LoadString(g_hLocRes, rgIds[i], szTools, MAX_TB_TEXT_LENGTH);
|
|
szTools += lstrlen(szTools) + 1;
|
|
}
|
|
|
|
*szTools = TEXT('\0');
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
HRESULT CCoolbar::Update(void)
|
|
{
|
|
DWORD cButtons = 0;
|
|
OLECMD *rgCmds;
|
|
TBBUTTON tb;
|
|
DWORD cCmds = 0;
|
|
IOleCommandTarget *pTarget = NULL;
|
|
DWORD i;
|
|
DWORD dwState;
|
|
|
|
// Get the number of buttons on the toolbar
|
|
cButtons = SendMessage(m_hwndTools, TB_BUTTONCOUNT, 0, 0);
|
|
if (0 == cButtons)
|
|
return (S_OK);
|
|
|
|
// Allocate an array of OLECMD structures for the buttons
|
|
if (!MemAlloc((LPVOID *) &rgCmds, sizeof(OLECMD) * cButtons))
|
|
return (E_OUTOFMEMORY);
|
|
|
|
// Loop through the buttons and get the ID for each
|
|
for (i = 0; i < cButtons; i++)
|
|
{
|
|
if (SendMessage(m_hwndTools, TB_GETBUTTON, i, (LPARAM) &tb))
|
|
{
|
|
// Toolbar returns zero for seperators
|
|
if (tb.idCommand)
|
|
{
|
|
rgCmds[cCmds].cmdID = tb.idCommand;
|
|
rgCmds[cCmds].cmdf = 0;
|
|
cCmds++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// I don't see how this can be false
|
|
Assert(m_ptbSite);
|
|
|
|
// Do the QueryStatus thing
|
|
if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IOleCommandTarget, (void**) &pTarget)))
|
|
{
|
|
if (SUCCEEDED(pTarget->QueryStatus(NULL, cCmds, rgCmds, NULL)))
|
|
{
|
|
// Go through the array now and do the enable / disable thing
|
|
for (i = 0; i < cCmds; i++)
|
|
{
|
|
// Get the current state of the button
|
|
dwState = SendMessage(m_hwndTools, TB_GETSTATE, rgCmds[i].cmdID, 0);
|
|
|
|
// Update the state with the feedback we've been provided
|
|
if (rgCmds[i].cmdf & OLECMDF_ENABLED)
|
|
dwState |= TBSTATE_ENABLED;
|
|
else
|
|
dwState &= ~TBSTATE_ENABLED;
|
|
|
|
if (rgCmds[i].cmdf & OLECMDF_LATCHED)
|
|
dwState |= TBSTATE_CHECKED;
|
|
else
|
|
dwState &= ~TBSTATE_CHECKED;
|
|
|
|
// Radio check has no meaning here.
|
|
Assert(0 == (rgCmds[i].cmdf & OLECMDF_NINCHED));
|
|
|
|
SendMessage(m_hwndTools, TB_SETSTATE, rgCmds[i].cmdID, dwState);
|
|
|
|
// If this is the work offline button, we need to do a bit more work
|
|
if (rgCmds[i].cmdID == ID_WORK_OFFLINE)
|
|
{
|
|
_UpdateWorkOffline(rgCmds[i].cmdf);
|
|
}
|
|
}
|
|
}
|
|
|
|
pTarget->Release();
|
|
}
|
|
|
|
MemFree(rgCmds);
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
void CCoolbar::_UpdateWorkOffline(DWORD cmdf)
|
|
{
|
|
TBBUTTONINFO tbbi = { 0 };
|
|
TCHAR szRes[CCHMAX_STRINGRES];
|
|
int idString;
|
|
|
|
// Because we change the text and image for the "Work Offline" button,
|
|
// we need to do some work here based on whether or not the button is
|
|
// checked or not.
|
|
|
|
if (cmdf & OLECMDF_LATCHED)
|
|
{
|
|
idString = idsWorkOnline;
|
|
tbbi.iImage = iCBWorkOnline;
|
|
}
|
|
else
|
|
{
|
|
idString = idsWorkOffline;
|
|
tbbi.iImage = iCBWorkOffline;
|
|
}
|
|
|
|
// Load the new string
|
|
AthLoadString(idString, szRes, ARRAYSIZE(szRes));
|
|
|
|
// Fill in the struct
|
|
tbbi.cbSize = sizeof(TBBUTTONINFO);
|
|
tbbi.dwMask = TBIF_IMAGE | TBIF_TEXT;
|
|
tbbi.pszText = szRes;
|
|
|
|
// Update the button
|
|
SendMessage(m_hwndTools, TB_SETBUTTONINFO, ID_WORK_OFFLINE, (LPARAM) &tbbi);
|
|
}
|
|
|
|
HRESULT CCoolbar::CreateMenuBand(PBANDSAVE pbs)
|
|
{
|
|
HRESULT hres;
|
|
HWND hwndBrowser;
|
|
HMENU hMenu;
|
|
IShellMenu *pShellMenu;
|
|
|
|
//Get the hwnd for the browser
|
|
if (g_pBrowser)
|
|
{
|
|
hres = g_pBrowser->GetWindow(&hwndBrowser);
|
|
if (hres != S_OK)
|
|
return hres;
|
|
}
|
|
|
|
//hMenu = ::GetMenu(hwndBrowser);
|
|
|
|
//Cocreate menuband
|
|
hres = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER, IID_IShellMenu, (LPVOID*)&m_pShellMenu);
|
|
if (hres != S_OK)
|
|
{
|
|
return hres;
|
|
}
|
|
|
|
/*
|
|
m_mbCallback = new CMenuCallback;
|
|
if (m_mbCallback == NULL)
|
|
{
|
|
hres = S_FALSE;
|
|
return hres;
|
|
}
|
|
*/
|
|
|
|
m_pShellMenu->Initialize(m_mbCallback, -1, ANCESTORDEFAULT, SMINIT_DEFAULTTOTRACKPOPUP | SMINIT_HORIZONTAL |
|
|
/*SMINIT_USEMESSAGEFILTER|*/ SMINIT_TOPLEVEL);
|
|
|
|
m_pShellMenu->SetMenu(m_hMenu, hwndBrowser, SMSET_DONTOWN);
|
|
|
|
hres = AddMenuBand(pbs);
|
|
|
|
return hres;
|
|
}
|
|
|
|
HRESULT CCoolbar::AddMenuBand(PBANDSAVE pbs)
|
|
{
|
|
REBARBANDINFO rbbi;
|
|
HRESULT hres;
|
|
HWND hwndMenuBand = NULL;
|
|
IObjectWithSite *pObj;
|
|
|
|
hres = m_pShellMenu->QueryInterface(IID_IDeskBand, (LPVOID*)&m_pDeskBand);
|
|
if (FAILED(hres))
|
|
return hres;
|
|
|
|
hres = m_pShellMenu->QueryInterface(IID_IMenuBand, (LPVOID*)&m_pMenuBand);
|
|
if (FAILED(hres))
|
|
return hres;
|
|
|
|
hres = m_pDeskBand->QueryInterface(IID_IWinEventHandler, (LPVOID*)&m_pWinEvent);
|
|
if (FAILED(hres))
|
|
return hres;
|
|
|
|
hres = m_pDeskBand->QueryInterface(IID_IObjectWithSite, (LPVOID*)&pObj);
|
|
if (FAILED(hres))
|
|
return hres;
|
|
|
|
pObj->SetSite((IDockingWindow*)this);
|
|
pObj->Release();
|
|
|
|
m_pDeskBand->GetWindow(&m_hwndMenuBand);
|
|
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_SIZE | RBBIM_ID | RBBIM_STYLE | RBBIM_CHILD;
|
|
rbbi.fStyle = pbs->dwStyle;
|
|
rbbi.cx = pbs->cx;
|
|
rbbi.wID = pbs->wID;
|
|
rbbi.hwndChild = m_hwndMenuBand;
|
|
|
|
SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT)-1, (LPARAM)(LPREBARBANDINFO)&rbbi);
|
|
|
|
HWND hwndBrowser;
|
|
if (g_pBrowser)
|
|
{
|
|
hres = g_pBrowser->GetWindow(&hwndBrowser);
|
|
if (hres != S_OK)
|
|
return hres;
|
|
}
|
|
|
|
SetForegroundWindow(hwndBrowser);
|
|
|
|
/*
|
|
IInputObject* pio;
|
|
if (SUCCEEDED(m_pDeskBand->QueryInterface(IID_IInputObject, (void**)&pio)))
|
|
{
|
|
pio->UIActivateIO(TRUE, NULL);
|
|
pio->Release();
|
|
}
|
|
*/
|
|
m_pDeskBand->ShowDW(TRUE);
|
|
|
|
SetNotRealSite();
|
|
|
|
//Get Bandinfo and set
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CCoolbar::TranslateMenuMessage(MSG *pmsg, LRESULT *lpresult)
|
|
{
|
|
if (m_pMenuBand)
|
|
return m_pMenuBand->TranslateMenuMessage(pmsg, lpresult);
|
|
else
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT CCoolbar::IsMenuMessage(MSG *lpmsg)
|
|
{
|
|
if (m_pMenuBand)
|
|
return m_pMenuBand->IsMenuMessage(lpmsg);
|
|
else
|
|
return S_FALSE;
|
|
}
|
|
|
|
void CCoolbar::SetNotRealSite()
|
|
{
|
|
IOleCommandTarget *pOleCmd;
|
|
|
|
if (m_pDeskBand->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&pOleCmd) == S_OK)
|
|
{
|
|
//pOleCmd->Exec(&CGID_MenuBand, MBANDCID_NOTAREALSITE, TRUE, NULL, NULL);
|
|
pOleCmd->Exec(&CLSID_MenuBand, 3, TRUE, NULL, NULL);
|
|
pOleCmd->Release();
|
|
}
|
|
}
|
|
|
|
void CCoolbar::HandleCoolbarPopup(UINT xPos, UINT yPos)
|
|
{
|
|
// Load the context menu
|
|
HMENU hMenu = LoadPopupMenu(IDR_COOLBAR_POPUP);
|
|
if (!hMenu)
|
|
return;
|
|
|
|
// Loop through the bands and see which ones are visible
|
|
DWORD cBands, iBand;
|
|
REBARBANDINFO rbbi = {0};
|
|
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_STYLE | RBBIM_ID;
|
|
|
|
cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
for (iBand = 0; iBand < cBands; iBand++)
|
|
{
|
|
if (SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi))
|
|
{
|
|
if (!(rbbi.fStyle & RBBS_HIDDEN))
|
|
{
|
|
switch (rbbi.wID)
|
|
{
|
|
case CBTYPE_TOOLS:
|
|
CheckMenuItem(hMenu, ID_COOLTOOLBAR, MF_BYCOMMAND | MF_CHECKED);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SetFlag(CBSTATE_INMENULOOP);
|
|
DWORD cmd;
|
|
cmd = TrackPopupMenuEx(hMenu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
|
|
xPos, yPos, m_hwndSizer, NULL);
|
|
|
|
if (cmd != 0)
|
|
{
|
|
switch (cmd)
|
|
{
|
|
case ID_COOLTOOLBAR:
|
|
HideToolbar(CBTYPE_TOOLS);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
ClearFlag(CBSTATE_INMENULOOP);
|
|
|
|
if (hMenu)
|
|
DestroyMenu(hMenu);
|
|
}
|