|
|
// coming soon: new deskbar (old deskbar moved to browbar base class)
#include "priv.h"
#include "sccls.h"
#include "resource.h"
#include "browbs.h"
#include "browbar.h"
#include "theater.h"
#include "shbrows2.h"
#include "varutil.h"
#ifdef UNIX
#include <mainwin.h>
#endif
#define SUPERCLASS CDockingBar
static const WCHAR c_szExplorerBars[] = TEXT("Software\\Microsoft\\Internet Explorer\\Explorer Bars\\");
//*** CBrowserBar_CreateInstance --
//
STDAPI CBrowserBar_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppunk, LPCOBJECTINFO poi) { // aggregation checking is handled in class factory
CBrowserBar *pwbar = new CBrowserBar(); if (pwbar) { *ppunk = SAFECAST(pwbar, IDockingWindow*); return S_OK; }
return E_OUTOFMEMORY; }
//***
// NOTES
// this creates the BrowserBar (infobar) and sets up it's specific style
// such as captionless rebar and such
HRESULT BrowserBar_Init(CBrowserBar* pdb, IUnknown** ppbs, int idBar) { HRESULT hr; if (ppbs) *ppbs = NULL; CBrowserBandSite *pcbs = new CBrowserBandSite(); if (pcbs) { IDeskBarClient *pdbc = SAFECAST(pcbs, IDeskBarClient*); BANDSITEINFO bsinfo; bsinfo.dwMask = BSIM_STYLE; bsinfo.dwStyle = BSIS_NOGRIPPER | BSIS_LEFTALIGN; pcbs->SetBandSiteInfo(&bsinfo); hr = pdb->SetClient(pdbc); if (SUCCEEDED(hr)) { if (ppbs) { *ppbs = pdbc; pdbc->AddRef(); } } pdbc->Release(); ASSERT(idBar == IDBAR_VERTICAL || idBar == IDBAR_HORIZONTAL); pdb->SetIdBar(idBar); } else { hr = E_OUTOFMEMORY; } return hr; }
//*** CBrowserBar::IPersistStream*::* {
HRESULT CBrowserBar::GetClassID(CLSID *pClassID) { *pClassID = CLSID_BrowserBar; return S_OK; }
HRESULT CBrowserBar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut) { if (!pguidCmdGroup) { // nothing
} else if (IsEqualGUID(CGID_Explorer, *pguidCmdGroup)) { return IUnknown_Exec(_punkChild, pguidCmdGroup, nCmdID, nCmdexecopt, pvarargIn, pvarargOut); } else if (IsEqualGUID(CGID_DeskBarClient, *pguidCmdGroup)) { switch (nCmdID) { case DBCID_EMPTY: if (_ptbSite) { // if we have no bands left, hide
VARIANT var = {VT_UNKNOWN}; var.punkVal = SAFECAST(this, IDeskBar*); AddRef();
_StopCurrentBand(); IUnknown_Exec(_ptbSite, &CGID_Explorer, SBCMDID_TOOLBAREMPTY, nCmdexecopt, &var, NULL); VariantClearLazy(&var); } break;
case DBCID_RESIZE: goto ForwardUp; break;
case DBCID_CLSIDOFBAR: ASSERT(nCmdexecopt == 0 || nCmdexecopt == 1); if (nCmdexecopt == 0) { //bar is being hidden
_StopCurrentBand(); _clsidCurrentBand = GUID_NULL; } else if (pvarargIn && pvarargIn->vt == VT_BSTR) { CLSID clsidTemp;
GUIDFromString(pvarargIn->bstrVal, &clsidTemp);
//if given a clsid and it's a new one, save the old one's settings
//then set it as the current clsid
if (!IsEqualIID(clsidTemp, _clsidCurrentBand)) { _PersistState(_hwnd, TRUE); _StopCurrentBand(); } _clsidCurrentBand = clsidTemp;
if (_hwnd && IsWindow(_hwnd)) { UINT uiNewWidthOrHeight = _PersistState(_hwnd, FALSE); RECT rc = {0};
GetWindowRect(_hwnd, &rc); if (_idBar == IDBAR_VERTICAL) rc.right = rc.left + uiNewWidthOrHeight; else rc.top = rc.bottom - uiNewWidthOrHeight; SetWindowPos(_hwnd, NULL, 0, 0, RECTWIDTH(rc), RECTHEIGHT(rc), SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE); } } else if (!pvarargIn && pvarargOut) { return InitBSTRVariantFromGUID(pvarargOut, _clsidCurrentBand); } else ASSERT(FALSE); break; } return S_OK; } else if (IsEqualGUID(CGID_Theater, *pguidCmdGroup)) { switch (nCmdID) { case THID_ACTIVATE: // if we're on a small monitor, start off as autohide
_fTheater = TRUE; ResizeBorderDW(NULL, NULL, FALSE); _OnSize();
// pass back pin button's state
pvarargOut->vt = VT_I4; pvarargOut->lVal = !_fNoAutoHide;
break;
case THID_DEACTIVATE: _fTheater = FALSE; // if we're on a small monitor, restore to theater default width
_szChild.cx = _iTheaterWidth; _AdjustToChildSize(); break;
case THID_SETBROWSERBARAUTOHIDE: // pvarargIn->lVal contains new _fAutoHide.
// fake message pin button was pressed only when _fNoAutoHide == pvarargIn->lVal
// which means new _fNoAutoHide != old _fNoAutoHide
if ((_fNoAutoHide && pvarargIn->lVal) || !(_fNoAutoHide || pvarargIn->lVal)) { // first update state and change bitmap
_fNoAutoHide = !pvarargIn->lVal;
// then notify theater mode manager because it owns the msg hook and does
// the hiding
IUnknown_Exec(_ptbSite, &CGID_Theater, THID_SETBROWSERBARAUTOHIDE, 0, pvarargIn, NULL);
// negotiate with the browser for space
_Recalc(); _PersistState(_hwnd, FALSE); } break; default: goto ForwardUp; } IUnknown_Exec(_punkChild, pguidCmdGroup, nCmdID, nCmdexecopt, pvarargIn, pvarargOut);
} ForwardUp: return SUPERCLASS::Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvarargIn, pvarargOut); }
#define ABS(i) (((i) < 0) ? -(i) : (i))
void CBrowserBar::_HandleWindowPosChanging(LPWINDOWPOS pwp) { if (_fDragging) { int cxMin = GetSystemMetrics(SM_CXVSCROLL) * 4; if (pwp->cx < cxMin) pwp->cx = cxMin; } }
LRESULT CBrowserBar::v_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_NCHITTEST: { LRESULT lres = _OnNCHitTest(wParam, lParam); #ifdef DEBUG
// non-LHS bar useful for testing discussion bar etc. stuff
// so allow drag to get it there
if (0) #endif
{ // don't allow drag in browbar
if (lres == HTCAPTION) lres = HTCLIENT; } return lres; } case WM_ERASEBKGND: if (_fTheater) { HDC hdc = (HDC) wParam; RECT rc; GetClientRect(hwnd, &rc); SHFillRectClr(hdc, &rc, RGB(0,0,0)); return 1; } break; case WM_EXITSIZEMOVE: { // save explorer bar's new width to registry
_PersistState(hwnd, TRUE); } break;
case WM_SIZE: { // browser bandsite needs to hear about resizing
LRESULT lres; _CheckForwardWinEvent(uMsg, wParam, lParam, &lres); } break; } return SUPERCLASS::v_WndProc(hwnd, uMsg, wParam, lParam); }
BOOL CBrowserBar::_CheckForwardWinEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plres) { HWND hwnd = NULL;
switch (uMsg) { case WM_SIZE: { // HACKHACK: munge the size so that width is browbandsite's
// new width. bbs needs to hear about resizing so that it
// can reposition its close/autohide window.
POINT pt = {LOWORD(lParam), HIWORD(lParam)}; pt.x -= 4 * GetSystemMetrics(SM_CXEDGE); lParam = MAKELONG(pt.x, pt.y); hwnd = _hwndChild; break; } }
if (hwnd && _pWEH && _pWEH->IsWindowOwner(hwnd) == S_OK) { _pWEH->OnWinEvent(_hwnd, uMsg, wParam, lParam, plres); return TRUE; } return SUPERCLASS::_CheckForwardWinEvent(uMsg, wParam, lParam, plres); }
void CBrowserBar::_GetChildPos(LPRECT prc) { GetClientRect(_hwnd, prc); if (_fTheater) prc->right--; else { // Make room for the resizing bar and make sure the right scrollbar is
// tucked under the right edge of the parent if we are on the top or bottom
switch(_uSide) { case ABE_TOP: prc->bottom -= GetSystemMetrics(SM_CYFRAME); prc->right += GetSystemMetrics(SM_CXFRAME); break; case ABE_BOTTOM: prc->top += GetSystemMetrics(SM_CYFRAME); prc->right += GetSystemMetrics(SM_CXFRAME); break; case ABE_LEFT: prc->right -= GetSystemMetrics(SM_CXFRAME); break; case ABE_RIGHT: prc->left += GetSystemMetrics(SM_CXFRAME); break; } }
if (prc->left > prc->right) prc->right = prc->left; if (prc->top > prc->bottom) prc->bottom = prc->top; }
void CBrowserBar::_GetStyleForMode(UINT eMode, LONG* plStyle, LONG *plExStyle, HWND* phwndParent) { *plStyle = WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS; *plExStyle= 0; *phwndParent = PARENT_BBTMMOST(); }
// bSetNewRect controls whether we override the current rect or autohide setting
UINT CBrowserBar::_PersistState(HWND hwnd, BOOL bSetNewRect) { BROWBARSAVE bbs = {0}; RECT rc = {0}; UINT retval = 0;
if (IsEqualIID(_clsidCurrentBand, GUID_NULL)) { //FEATURE: this assert is getting hit, why?
//ASSERT(FALSE); //do we even need to check this anymore?
return 0; }
// use current uiWidthOrHeight and fAutoHide in case there is no value in registry yet
if (hwnd) { GetWindowRect(hwnd, &rc); // bad hack
if (_idBar == IDBAR_VERTICAL) bbs.uiWidthOrHeight = RECTWIDTH(rc); else bbs.uiWidthOrHeight = RECTHEIGHT(rc); } bbs.fAutoHide = !_fNoAutoHide;
WCHAR wszClsid[GUIDSTR_MAX]; DWORD dwType = REG_BINARY; DWORD cbSize = SIZEOF(BROWBARSAVE); SHStringFromGUID(_clsidCurrentBand, wszClsid, ARRAYSIZE(wszClsid));
WCHAR wszKeyPath[MAX_PATH]; StrCpyN(wszKeyPath, c_szExplorerBars, ARRAYSIZE(wszKeyPath)); StrCatBuff(wszKeyPath, wszClsid, ARRAYSIZE(wszKeyPath)); SHRegGetUSValueW(wszKeyPath, L"BarSize", &dwType, (LPBYTE)&bbs, &cbSize, FALSE, NULL, 0);
//if there is no window yet and no saved size, pick a reasonable default
if (bbs.uiWidthOrHeight == 0) bbs.uiWidthOrHeight = (IDBAR_VERTICAL == _idBar) ? COMMBAR_HEIGHT : INFOBAR_WIDTH;
if (bSetNewRect) { if (_idBar == IDBAR_VERTICAL) { bbs.uiWidthOrHeight = RECTWIDTH(rc); retval = RECTWIDTH(rc); } else { bbs.uiWidthOrHeight = RECTHEIGHT(rc); retval = RECTHEIGHT(rc); } } else { bbs.fAutoHide = !_fNoAutoHide; retval = bbs.uiWidthOrHeight; }
if (bSetNewRect) SHRegSetUSValueW(wszKeyPath, L"BarSize", dwType, (LPBYTE)&bbs, cbSize, SHREGSET_FORCE_HKCU);
return retval; }
void CBrowserBar::_StopCurrentBand() { //stop any streaming content or navigations, except for the search band if we stop it
// then we could have incompletely loaded ui
if (!IsEqualGUID(CLSID_SearchBand, _clsidCurrentBand)) { IUnknown_Exec(_punkChild, NULL, OLECMDID_STOP, 0, NULL, NULL); } }
// }
|