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.
1716 lines
49 KiB
1716 lines
49 KiB
#include "pch.hxx"
|
|
#include <resource.h>
|
|
#include "error.h"
|
|
#include "treeview.h"
|
|
#include "inpobj.h"
|
|
#include "infcolum.h"
|
|
#include "goptions.h"
|
|
#include "strconst.h"
|
|
#include "menuutil.h"
|
|
#include "fldbar.h"
|
|
#include "ourguid.h"
|
|
#include "baui.h"
|
|
|
|
CInfoColumn::~CInfoColumn()
|
|
{
|
|
DOUTL(1, TEXT("CInfoColulmn::~CInfoColumn: %x"), this);
|
|
|
|
SafeRelease(m_pDwSite);
|
|
SafeRelease(m_pTreeView);
|
|
m_hwndParent = 0;
|
|
|
|
if (m_hwndInfoColumn)
|
|
{
|
|
DestroyWindow(m_hwndInfoColumn);
|
|
}
|
|
|
|
//Destroy image list if we have one.
|
|
if (m_himl)
|
|
{
|
|
ImageList_Destroy(m_himl);
|
|
m_himl = 0;
|
|
}
|
|
|
|
if (m_hfIcon)
|
|
DeleteObject(m_hfIcon);
|
|
|
|
SafeRelease(m_pMsgrAb);
|
|
}
|
|
|
|
CInfoColumn::CInfoColumn ()
|
|
{
|
|
m_hwndInfoColumn = 0;
|
|
m_hwndRebar = 0;
|
|
m_fShow = 0;
|
|
m_hwndParent = 0;
|
|
m_CurFocus = 0;
|
|
m_pDwSite = 0;
|
|
m_cRef = 1;
|
|
m_xWidth = DwGetOption(OPT_TREEWIDTH);
|
|
m_himl = 0;
|
|
m_pTreeView = 0;
|
|
m_pMsgrAb = 0;
|
|
m_hfIcon = NULL;
|
|
m_fRebarDragging = FALSE;
|
|
m_pFolderBar = NULL;
|
|
m_cVisibleBands = 0;
|
|
ZeroMemory(m_BandList, sizeof(m_BandList));
|
|
ZeroMemory(m_CacheCmdTarget, sizeof(m_CacheCmdTarget));
|
|
m_fDragging = FALSE;
|
|
}
|
|
|
|
HRESULT CInfoColumn::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("CInfoColumn::QI(IID_IDockingWindow) called. _cRef=%d"), m_cRef);
|
|
return S_OK;
|
|
}
|
|
else if (IsEqualIID(riid, IID_IInputObject))
|
|
{
|
|
*ppvObj = (IInputObject*)this;
|
|
m_cRef++;
|
|
DOUTL(2, TEXT("CInfoColumn::QI(IID_IInputObject) called. _cRef=%d"), m_cRef);
|
|
return S_OK;
|
|
}
|
|
else if (IsEqualIID(riid, IID_IObjectWithSite))
|
|
{
|
|
*ppvObj = (IObjectWithSite*)this;
|
|
m_cRef++;
|
|
DOUTL(2, TEXT("CInfoColumn::QI(IID_IObjectWithSite) called. _cRef=%d"), m_cRef);
|
|
return S_OK;
|
|
}
|
|
else if (IsEqualIID(riid, IID_IInputObjectSite))
|
|
{
|
|
*ppvObj = (IInputObjectSite*)this;
|
|
m_cRef++;
|
|
DOUTL(2, TEXT("CInfoColumn::QI(IID_IInputObjectSite) called. _cRef=%d"), m_cRef);
|
|
return S_OK;
|
|
}
|
|
else if (IsEqualIID(riid, IID_IOleCommandTarget))
|
|
{
|
|
*ppvObj = (IOleCommandTarget*)this;
|
|
m_cRef++;
|
|
DOUTL(2, TEXT("CInfoColumn::QI(IID_IOleCommandTarget) called. _cRef=%d"), m_cRef);
|
|
return S_OK;
|
|
}
|
|
*ppvObj = 0;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
ULONG CInfoColumn::AddRef()
|
|
{
|
|
m_cRef++;
|
|
DOUTL(4, TEXT("CInfoColumn::AddRef() - m_cRef = %d"), m_cRef);
|
|
return m_cRef;
|
|
}
|
|
|
|
ULONG CInfoColumn::Release()
|
|
{
|
|
DOUTL(4, TEXT("CInfoColumn::Release() - m_cRef = %d"), m_cRef);
|
|
|
|
if (--m_cRef == 0)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return m_cRef;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CInfoColumn::GetWindow()
|
|
//
|
|
// PURPOSE: Returns the window handle of the top side rebar.
|
|
//
|
|
HRESULT CInfoColumn::GetWindow(HWND * lphwnd)
|
|
{
|
|
if (m_hwndRebar)
|
|
{
|
|
*lphwnd = m_hwndRebar;
|
|
return (S_OK);
|
|
}
|
|
else
|
|
{
|
|
*lphwnd = 0;
|
|
return (E_FAIL);
|
|
}
|
|
}
|
|
|
|
HRESULT CInfoColumn::ContextSensitiveHelp(BOOL fEnterMode)
|
|
{
|
|
return (E_NOTIMPL);
|
|
}
|
|
|
|
#define INFOCOLUMNCLASS TEXT("InfoColumn")
|
|
HRESULT CInfoColumn::CreateInfoColumn(BOOL fVisible)
|
|
{
|
|
if (m_hwndInfoColumn)
|
|
return (hrAlreadyExists);
|
|
|
|
m_hwndInfoColumn = CreateWindowEx(WS_EX_CONTROLPARENT, INFOCOLUMNCLASS, 0,
|
|
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (fVisible ? WS_VISIBLE : 0),
|
|
0, 0, 100, 200, m_hwndParent, (HMENU) 0, g_hInst, this);
|
|
if (!m_hwndInfoColumn)
|
|
{
|
|
DWORD err;
|
|
err = GetLastError();
|
|
AssertSz(0, _T("CInfoColumn::CreateInfoColumn() - Failed to create a window"));
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CInfoColumn::InfoColumnWndProc()
|
|
//
|
|
// PURPOSE: Handles messages sent to the InfoColumn root window.
|
|
//
|
|
LRESULT CALLBACK EXPORT_16 CInfoColumn::InfoColumnWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CInfoColumn *pInfoColumn = 0;
|
|
|
|
if (uMsg == WM_NCCREATE)
|
|
{
|
|
pInfoColumn = (CInfoColumn*)((LPCREATESTRUCT) lParam)->lpCreateParams;
|
|
SetWindowLong(hwnd, GWL_USERDATA, (LPARAM)pInfoColumn);
|
|
}
|
|
else
|
|
{
|
|
pInfoColumn = (CInfoColumn*)GetWindowLong(hwnd, GWL_USERDATA);
|
|
}
|
|
|
|
Assert (pInfoColumn);
|
|
|
|
return pInfoColumn->PrivateProcessing(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
|
|
|
|
//IDockingWindow::ShowDw
|
|
HRESULT CInfoColumn::ShowDW(BOOL fShow)
|
|
{
|
|
HRESULT hres = S_OK;
|
|
int i = 0,
|
|
j = 0;
|
|
|
|
m_fShow = fShow;
|
|
// Check to see if our window has been created yet. If not, do that first.
|
|
if (!m_hwndInfoColumn && m_pDwSite)
|
|
{
|
|
m_hwndParent = 0;
|
|
hres = m_pDwSite->GetWindow(&m_hwndParent);
|
|
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
#ifndef WIN16 // WNDCLASSEX
|
|
WNDCLASSEX wc;
|
|
#else
|
|
WNDCLASS wc;
|
|
#endif
|
|
|
|
// Check to see if we need to register our window class
|
|
#ifndef WIN16
|
|
wc.cbSize = sizeof(WNDCLASSEX);
|
|
if (!GetClassInfoEx(g_hInst, INFOCOLUMNCLASS, &wc))
|
|
#else
|
|
if (!GetClassInfo(g_hInst, INFOCOLUMNCLASS, &wc))
|
|
#endif
|
|
{
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = InfoColumnWndProc;
|
|
wc.cbClsExtra = 0;
|
|
#ifndef WIN16
|
|
wc.cbWndExtra = 0;
|
|
#else
|
|
wc.cbWndExtra = 4;
|
|
#endif
|
|
wc.hInstance = g_hInst;
|
|
wc.hCursor = LoadCursor(0, IDC_SIZEWE);
|
|
wc.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
|
|
wc.lpszMenuName = 0;
|
|
wc.lpszClassName = INFOCOLUMNCLASS;
|
|
wc.hIcon = 0;
|
|
#ifndef WIN16
|
|
wc.hIconSm = 0;
|
|
|
|
RegisterClassEx(&wc);
|
|
#else
|
|
RegisterClass(&wc);
|
|
#endif
|
|
}
|
|
|
|
hres = CreateInfoColumn(fShow);
|
|
if (FAILED(hres))
|
|
return E_FAIL;
|
|
}
|
|
|
|
m_hwndRebar = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT, REBARCLASSNAME, 0,
|
|
RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_DBLCLKTOGGLE | RBS_FIXEDORDER
|
|
| WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
|
|
CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_VERT, 0, 0, 0, 0,
|
|
m_hwndInfoColumn, (HMENU)0, g_hInst, 0);
|
|
if (!m_hwndRebar)
|
|
{
|
|
DestroyWindow(m_hwndInfoColumn);
|
|
return E_FAIL;
|
|
}
|
|
|
|
hres = CreateBands();
|
|
Assert(SUCCEEDED(hres));
|
|
|
|
GetFontParams();
|
|
//SendMessage(m_hwndRebar, RB_SETEXTENDEDSTYLE, RBS_EX_OFFICE9, RBS_EX_OFFICE9);
|
|
}
|
|
|
|
// Resize the rebar based on it's new hidden / visible state and also
|
|
// show or hide the window.
|
|
if (m_hwndInfoColumn)
|
|
{
|
|
/*
|
|
if(fShow)
|
|
{
|
|
//If #of visible bands is zero, this means we were hidden before in options.
|
|
if (!m_cVisibleBands)
|
|
ShowAllBands();
|
|
}
|
|
else
|
|
{
|
|
//We are being hidden
|
|
m_cVisibleBands = 0;
|
|
}
|
|
*/
|
|
ResizeBorderDW(0, 0, FALSE);
|
|
ShowWindow(m_hwndInfoColumn, fShow ? SW_SHOW : SW_HIDE);
|
|
|
|
hres = S_OK;
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
void CInfoColumn::ShowAllBands()
|
|
{
|
|
int Count;
|
|
REBARBANDINFO rbbinfo;
|
|
|
|
Count = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
m_cVisibleBands = Count;
|
|
|
|
for (--Count; Count >= 0; Count--)
|
|
{
|
|
ZeroMemory(&rbbinfo, sizeof(REBARBANDINFO));
|
|
rbbinfo.cbSize = sizeof(REBARBANDINFO);
|
|
rbbinfo.fMask = RBBIM_STYLE;
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, Count, (LPARAM)&rbbinfo);
|
|
|
|
rbbinfo.fStyle &= ~RBBS_HIDDEN;
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, Count, (LPARAM)&rbbinfo);
|
|
}
|
|
}
|
|
|
|
HRESULT CInfoColumn::AddMsgrAb(DWORD dwSize, BOOL fVisible)
|
|
{
|
|
HRESULT hres = E_FAIL;
|
|
|
|
if(!fVisible)
|
|
return hres;
|
|
|
|
hres = CreateMsgrAbCtrl(&m_pMsgrAb);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
IInputObject *pObj;
|
|
if (SUCCEEDED(hres = m_pMsgrAb->QueryInterface(IID_IInputObject, (LPVOID*)&pObj)))
|
|
{
|
|
if (SUCCEEDED(hres = AddObject(pObj, m_fShow)))
|
|
{
|
|
REBARBANDINFO bandinfo = {0};
|
|
IOleWindow *pOleWindow;
|
|
|
|
if (SUCCEEDED(m_pMsgrAb->QueryInterface(IID_IOleWindow, (LPVOID*)&pOleWindow)))
|
|
{
|
|
if (SUCCEEDED(pOleWindow->GetWindow(&bandinfo.hwndChild)))
|
|
{
|
|
char BandTitle[CCHMAX_STRINGRES];
|
|
ZeroMemory(BandTitle, sizeof (BandTitle));
|
|
|
|
if (g_hLocRes)
|
|
LoadString(g_hLocRes, idsABBandTitle, BandTitle, sizeof(BandTitle));
|
|
|
|
bandinfo.cbSize = sizeof (REBARBANDINFO);
|
|
bandinfo.fMask = RBBIM_CHILD | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE |
|
|
RBBIM_CHILDSIZE | RBBIM_TEXT | RBBIM_LPARAM;
|
|
bandinfo.fStyle = RBBS_VARIABLEHEIGHT | (fVisible ? 0 : RBBS_HIDDEN);
|
|
bandinfo.wID = ICBLAB;
|
|
//Height
|
|
bandinfo.cx = dwSize;
|
|
bandinfo.cxMinChild = 0;
|
|
//Width
|
|
bandinfo.cyMinChild = m_xWidth - GetSystemMetrics(SM_CXFRAME);
|
|
bandinfo.cyChild = m_xWidth - GetSystemMetrics(SM_CXFRAME);
|
|
bandinfo.cyMaxChild = MAX_WIDTH;
|
|
|
|
bandinfo.lpText = BandTitle;
|
|
|
|
IDropDownFldrBar *pddf;
|
|
m_pMsgrAb->QueryInterface(IID_IDropDownFldrBar, (void**)&pddf);
|
|
bandinfo.lParam = (LPARAM)pddf;
|
|
|
|
SendMessage(m_hwndRebar, RB_INSERTBAND, -1, (LPARAM)&bandinfo);
|
|
|
|
if (fVisible)
|
|
++m_cVisibleBands;
|
|
|
|
hres = S_OK;
|
|
}
|
|
pOleWindow->Release();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_pMsgrAb->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&m_CacheCmdTarget[ITB_BUDDYADDRBOOK - ITB_INFOCOL_BASE]) != S_OK)
|
|
{
|
|
m_CacheCmdTarget[ITB_BUDDYADDRBOOK - ITB_INFOCOL_BASE] = NULL;
|
|
}
|
|
}
|
|
return hres;
|
|
}
|
|
|
|
void CInfoColumn::GetFontParams()
|
|
{
|
|
//Get the Icon font and save it
|
|
ICONMETRICS icm;
|
|
|
|
icm.cbSize = sizeof(ICONMETRICS);
|
|
SystemParametersInfo(SPI_GETICONMETRICS,
|
|
sizeof(ICONMETRICS),
|
|
(LPVOID) &icm, FALSE);
|
|
|
|
if (m_hfIcon)
|
|
DeleteObject(m_hfIcon);
|
|
|
|
m_hfIcon = CreateFontIndirect(&(icm.lfFont));
|
|
if (m_hfIcon)
|
|
{
|
|
SendMessage(m_hwndRebar, WM_SETFONT, (WPARAM) m_hfIcon, MAKELPARAM(TRUE, 0));
|
|
}
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CInfoColumn::CloseDW()
|
|
//
|
|
// PURPOSE: Destroys the InfoColumnWindow.
|
|
//
|
|
//IDockingWindow::CloseDW
|
|
HRESULT CInfoColumn::CloseDW(DWORD dwReserved)
|
|
{
|
|
IObjectWithSite *pObject = 0;
|
|
|
|
// Save our settings before we close anything
|
|
SaveSettings();
|
|
|
|
//Go through the list of objects and deactivate them.
|
|
for (DWORD index = 0; index < IC_MAX_OBJECTS; index++)
|
|
{
|
|
if (m_BandList[index].pBandObj)
|
|
{
|
|
m_BandList[index].pBandObj->UIActivateIO(FALSE, 0);
|
|
|
|
if (SUCCEEDED(m_BandList[index].pBandObj->QueryInterface(IID_IObjectWithSite, (LPVOID *) &pObject)))
|
|
{
|
|
pObject->SetSite(0);
|
|
pObject->Release();
|
|
}
|
|
SafeRelease(m_BandList[index].pBandObj);
|
|
}
|
|
SafeRelease(m_CacheCmdTarget[index]);
|
|
}
|
|
|
|
//Go through the bands and release lParam pointer
|
|
CleanupLParam();
|
|
|
|
if (m_pTreeView)
|
|
{
|
|
m_pTreeView->SetSite(0);
|
|
m_pTreeView->DeInit();
|
|
}
|
|
SafeRelease(m_pTreeView);
|
|
SafeRelease(m_CurFocus);
|
|
|
|
if (m_hwndInfoColumn)
|
|
{
|
|
DestroyWindow(m_hwndInfoColumn);
|
|
m_hwndInfoColumn = 0;
|
|
}
|
|
SafeRelease(m_CurFocus);
|
|
return S_OK;
|
|
}
|
|
|
|
void CInfoColumn::CleanupLParam()
|
|
{
|
|
int count = 0;
|
|
REBARBANDINFO rbbinfo;
|
|
|
|
count = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
for (--count; count >= 0; count--)
|
|
{
|
|
ZeroMemory(&rbbinfo, sizeof(REBARBANDINFO));
|
|
rbbinfo.cbSize = sizeof(REBARBANDINFO);
|
|
rbbinfo.fMask = RBBIM_LPARAM;
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, count, (LPARAM)&rbbinfo);
|
|
if (rbbinfo.lParam)
|
|
{
|
|
((IDropDownFldrBar*)rbbinfo.lParam)->Release();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CInfoColumn::ResizeBorderDW()
|
|
//
|
|
// PURPOSE: This is called by the browser or dockwindow site when InfoColumn needs to resize.
|
|
// The Infocolumn in return figures out how much border space will be required
|
|
// from the parent frame and tells the parent to reserve that
|
|
// space. The InfoColumn 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 CInfoColumn::ResizeBorderDW(LPCRECT prcBorder,
|
|
IUnknown* punkToolbarSite,
|
|
BOOL fReserved)
|
|
{
|
|
|
|
const DWORD c_cxResizeBorder = 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_pDwSite)
|
|
{
|
|
AssertSz(m_pDwSite, _T("CInfoColumn::ResizeBorderDW() - Can't resize ")
|
|
_T("without an IDockingWindowSite interface to call."));
|
|
return (E_INVALIDARG);
|
|
}
|
|
|
|
// If we're visible, then calculate our border rectangle.
|
|
if ((m_fShow) && (m_hwndInfoColumn))
|
|
{
|
|
if (!prcBorder)
|
|
{
|
|
RECT rcBorder;
|
|
|
|
// Find out how big our parent's border space is
|
|
m_pDwSite->GetBorderDW((IDockingWindow*) this, &rcBorder);
|
|
prcBorder = &rcBorder;
|
|
Assert (prcBorder);
|
|
}
|
|
|
|
RECT rcRebar = {0};
|
|
if (IsWindow(m_hwndRebar))
|
|
{
|
|
GetWindowRect(m_hwndRebar, &rcRebar);
|
|
POINT pt;
|
|
pt.x = rcRebar.right;
|
|
pt.y = rcRebar.top;
|
|
if (!ScreenToClient(m_hwndRebar, &pt))
|
|
return E_FAIL;
|
|
rcRebar.right = pt.x;
|
|
}
|
|
|
|
rcRequest.left = min(prcBorder->right - prcBorder->left, rcRebar.right + GetSystemMetrics(SM_CXFRAME));
|
|
|
|
hres = m_pDwSite->RequestBorderSpaceDW((IDockingWindow*)this, &rcRequest);
|
|
|
|
}
|
|
m_pDwSite->SetBorderSpaceDW((IDockingWindow*) this, &rcRequest);
|
|
|
|
//We should set the border space before we set the window pos. Because resizing will call this function
|
|
//again and the last SetBorderSpaceDW from us will be with the co-ordinates before re-sizing. This will be bad
|
|
if (SUCCEEDED(hres) && m_hwndInfoColumn && m_fShow)
|
|
{
|
|
if (!SetWindowPos(m_hwndInfoColumn,
|
|
0,
|
|
prcBorder->left,
|
|
prcBorder->top,
|
|
rcRequest.left,
|
|
prcBorder->bottom - prcBorder->top,
|
|
SWP_NOZORDER | SWP_NOACTIVATE))
|
|
{
|
|
AssertSz(FALSE, _T("Setwindowpos failed"));
|
|
}
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
//IObjectWithSite::SetSite
|
|
HRESULT CInfoColumn::SetSite(IUnknown *pUnkSite)
|
|
{
|
|
if (m_pDwSite)
|
|
{
|
|
m_pDwSite->Release();
|
|
m_pDwSite = 0;
|
|
}
|
|
|
|
if (pUnkSite)
|
|
{
|
|
if (FAILED(pUnkSite->QueryInterface(IID_IDockingWindowSite, (LPVOID*)&m_pDwSite)))
|
|
{
|
|
Assert (m_pDwSite);
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
//IObjectWithSite::GetSite
|
|
HRESULT CInfoColumn::GetSite(REFIID riid, LPVOID *ppvSite)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IInputObject
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CInfoColumn::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
|
|
{
|
|
if (fActivate)
|
|
{
|
|
UnkOnFocusChangeIS(m_pDwSite, (IInputObject*)this, TRUE);
|
|
SetFocus(m_hwndRebar);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CInfoColumn::HasFocusIO(void)
|
|
{
|
|
if ( m_hwndRebar == 0 )
|
|
return( S_FALSE );
|
|
HWND hwndFocus = GetFocus();
|
|
return ((hwndFocus && (hwndFocus == m_hwndRebar || IsChild(m_hwndRebar, hwndFocus)))) ? S_OK : S_FALSE;
|
|
}
|
|
|
|
HRESULT CInfoColumn::TranslateAcceleratorIO(LPMSG pMsg)
|
|
{
|
|
//Cycle through all the child windows and forward this if they have focus
|
|
for (DWORD i = 0; i < IC_MAX_OBJECTS; i++)
|
|
{
|
|
if (m_BandList[i].pBandObj && UnkHasFocusIO(m_BandList[i].pBandObj) == S_OK)
|
|
{
|
|
if (UnkTranslateAcceleratorIO(m_BandList[i].pBandObj, pMsg) == S_OK)
|
|
{
|
|
return S_OK;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return (S_FALSE);
|
|
}
|
|
|
|
//IInputObjectSite
|
|
HRESULT CInfoColumn::OnFocusChangeIS(IUnknown *punk, BOOL fSetFocus)
|
|
{
|
|
HRESULT hres = S_OK;
|
|
IInputObject *prevfocus;
|
|
|
|
if (punk)
|
|
{
|
|
if (fSetFocus)
|
|
{
|
|
prevfocus = m_CurFocus;
|
|
HRESULT hres = punk->QueryInterface(IID_IInputObject, (LPVOID*)&m_CurFocus);
|
|
if (FAILED(hres))
|
|
{
|
|
//reset Cur focus back to the previous one
|
|
m_CurFocus = prevfocus;
|
|
return hres;
|
|
}
|
|
|
|
//We should also let the browser know that we have the focus now
|
|
IInputObjectSite *pinpsite;
|
|
if (SUCCEEDED(m_pDwSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&pinpsite)))
|
|
{
|
|
pinpsite->OnFocusChangeIS((IDockingWindow*)this, fSetFocus);
|
|
pinpsite->Release();
|
|
}
|
|
|
|
if (prevfocus)
|
|
{
|
|
prevfocus->UIActivateIO(FALSE, 0);
|
|
prevfocus->Release();
|
|
}
|
|
|
|
hres = S_OK;
|
|
}
|
|
}
|
|
else
|
|
hres = E_INVALIDARG;
|
|
|
|
return hres;
|
|
}
|
|
|
|
//IDropTarget
|
|
HRESULT CInfoColumn::DragEnter( IDataObject *pDataObject,
|
|
DWORD grfKeyState,
|
|
POINTL pt,
|
|
DWORD *pdwEffect)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT CInfoColumn::DragOver( DWORD grfKeyState,
|
|
POINTL pt,
|
|
DWORD *pdwEffect )
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT CInfoColumn::DragLeave(void)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CInfoColumn::Drop( IDataObject *pDataObject,
|
|
DWORD grfKeyState,
|
|
POINTL pt,
|
|
DWORD *pdwEffect)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Private Methods
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
LRESULT CInfoColumn::PrivateProcessing(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (msg)
|
|
{
|
|
HANDLE_MSG(hwnd, WM_CREATE, OnCreate);
|
|
HANDLE_MSG(hwnd, WM_LBUTTONDOWN, OnLButtonDown);
|
|
HANDLE_MSG(hwnd, WM_MOUSEMOVE, OnMouseMove);
|
|
HANDLE_MSG(hwnd, WM_LBUTTONUP, OnLButtonUp);
|
|
HANDLE_MSG(hwnd, WM_SIZE, OnSize);
|
|
HANDLE_MSG(hwnd, WM_CONTEXTMENU, OnContextMenu);
|
|
|
|
case WM_NOTIFY:
|
|
return OnNotify(hwnd, wParam, (LPNMHDR) lParam);
|
|
|
|
case WM_NCDESTROY:
|
|
RevokeDragDrop(hwnd);
|
|
SetWindowLong(hwnd, GWL_USERDATA, 0);
|
|
m_hwndInfoColumn = 0;
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
if (m_hwndRebar && ((HWND)wParam) != m_hwndRebar)
|
|
{
|
|
SetFocus(m_hwndRebar);
|
|
}
|
|
UnkOnFocusChangeIS(m_pDwSite, (IDockingWindow*)this, TRUE);
|
|
return 0;
|
|
|
|
case WMR_CLICKOUTSIDE:
|
|
{
|
|
BOOL fHide = FALSE;
|
|
|
|
if (wParam == CLK_OUT_KEYBD || wParam == CLK_OUT_DEACTIVATE)
|
|
fHide = TRUE;
|
|
else if (wParam == CLK_OUT_MOUSE)
|
|
fHide = !IsOurWindow((HWND)lParam);
|
|
//fHide = ((HWND) lParam != m_hwndRebar && (HWND) lParam != m_hwndInfoColumn);
|
|
|
|
if (fHide)
|
|
m_pFolderBar->KillScopeDropDown();
|
|
return (fHide);
|
|
}
|
|
}
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
}
|
|
|
|
BOOL CInfoColumn::IsOurWindow(HWND hwnd)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
if ((hwnd != m_hwndInfoColumn) && (hwnd != m_hwndRebar))
|
|
{
|
|
int BandCount;
|
|
REBARBANDINFO rbbinfo;
|
|
|
|
BandCount = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
for (--BandCount; BandCount >= 0; BandCount--)
|
|
{
|
|
ZeroMemory(&rbbinfo, sizeof(REBARBANDINFO));
|
|
rbbinfo.cbSize = sizeof(REBARBANDINFO);
|
|
rbbinfo.fMask = RBBIM_CHILD;
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, BandCount, (LPARAM)&rbbinfo);
|
|
if ((rbbinfo.hwndChild == hwnd) ||
|
|
(IsChild(rbbinfo.hwndChild, hwnd)))
|
|
{
|
|
bRet = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
void CInfoColumn::OnLButtonDown(HWND hwnd,
|
|
BOOL fDoubleClick,
|
|
int x,
|
|
int y,
|
|
UINT keyFlags)
|
|
{
|
|
if ((!m_fRebarDragging) && (GetParent(m_hwndInfoColumn) == m_hwndParent))
|
|
{
|
|
// Capture the mouse
|
|
SetCapture(m_hwndInfoColumn);
|
|
|
|
// Start dragging
|
|
m_fDragging = TRUE;
|
|
}
|
|
}
|
|
|
|
void CInfoColumn::OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
|
|
{
|
|
HCURSOR hcur;
|
|
POINT pt = {x, y};
|
|
RECT rcClient;
|
|
|
|
// If we're dragging, update the the window sizes
|
|
if (m_fDragging)
|
|
{
|
|
// Make sure the tree is still a little bit visible
|
|
if (x > 32)
|
|
{
|
|
SetDwOption(OPT_TREEWIDTH, x, 0, 0);
|
|
ResizeBands(x - GetSystemMetrics(SM_CXFRAME));
|
|
ResizeBorderDW(0, 0, FALSE);
|
|
}
|
|
}
|
|
|
|
if(m_fRebarDragging)
|
|
{
|
|
//This is a temporary hack while the shell team fixes the RB_FIXEDORDER style in their code.
|
|
//BUG#12591
|
|
//This is bug has been fixed and verified as of 7/14/98. Hence removing the hack
|
|
//if (y >= 5)
|
|
SendMessage(m_hwndRebar, RB_DRAGMOVE, 0, MAKELPARAM(1, y));
|
|
}
|
|
}
|
|
|
|
|
|
void CInfoColumn::OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
|
|
{
|
|
if (m_fDragging)
|
|
{
|
|
ReleaseCapture();
|
|
m_fDragging = FALSE;
|
|
}
|
|
|
|
if (m_fRebarDragging)
|
|
{
|
|
m_fRebarDragging = FALSE;
|
|
SendMessage(m_hwndRebar, RB_ENDDRAG, 0, 0);
|
|
if (GetCapture() == hwnd)
|
|
{
|
|
ReleaseCapture();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CInfoColumn::ResizeBands(int cx)
|
|
{
|
|
UINT uBandCount;
|
|
UINT Index;
|
|
REBARBANDINFO rbbinfo = {0};
|
|
|
|
uBandCount = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
for (Index = 0; Index < uBandCount; Index++)
|
|
{
|
|
//We do this in order to get CxMinChild. Execpt for OE TOday band this value
|
|
//is set to zero at this point of time.
|
|
rbbinfo.cbSize = sizeof(REBARBANDINFO);
|
|
rbbinfo.fMask = RBBIM_CHILDSIZE;
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, Index, (LPARAM)&rbbinfo);
|
|
|
|
rbbinfo.cyChild = cx;
|
|
rbbinfo.cyMinChild = cx;
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, Index, (LPARAM)&rbbinfo);
|
|
}
|
|
}
|
|
|
|
BOOL CInfoColumn::OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
REBARINFO rebarinfo;
|
|
|
|
#ifdef NEVER
|
|
|
|
m_himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idbInfoColumn), 16, 0, RGB(255, 0, 255));
|
|
|
|
rebarinfo.cbSize = sizeof (REBARINFO);
|
|
rebarinfo.fMask = RBIM_IMAGELIST;
|
|
rebarinfo.himl = m_himl;
|
|
SendMessage (m_hwndRebar, RB_SETBARINFO, 0, (LPARAM)&rebarinfo);
|
|
#endif NEVER
|
|
|
|
RegisterDragDrop(hwnd, this);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CInfoColumn::OnSize(HWND hwnd, UINT state, int cxClient, int cyClient)
|
|
{
|
|
if (m_hwndRebar && IsWindow(m_hwndRebar))
|
|
{
|
|
|
|
if (m_hwndParent != GetParent(m_hwndInfoColumn))
|
|
{
|
|
//This is being called by Folder Bar
|
|
ResizeBands(cxClient);
|
|
}
|
|
cxClient = cxClient - GetSystemMetrics(SM_CXFRAME);
|
|
if (!SetWindowPos(m_hwndRebar, 0, 0, 0,
|
|
cxClient,
|
|
cyClient,
|
|
SWP_NOZORDER | SWP_NOACTIVATE))
|
|
DWORD err = GetLastError();
|
|
|
|
}
|
|
}
|
|
|
|
LRESULT CInfoColumn::OnNotify(HWND hwnd, WPARAM wParam, LPNMHDR lpnmh)
|
|
{
|
|
LRESULT retval = 0;
|
|
|
|
switch (lpnmh->code)
|
|
{
|
|
case RBN_BEGINDRAG:
|
|
retval = OnICBeginDrag((LPNMREBAR)lpnmh);
|
|
break;
|
|
|
|
case RBN_LAYOUTCHANGED:
|
|
retval = TRUE;
|
|
break;
|
|
|
|
case RBN_HEIGHTCHANGE:
|
|
if (m_hwndParent == GetParent (m_hwndInfoColumn))
|
|
ResizeBorderDW(0, 0, FALSE);
|
|
retval = TRUE;
|
|
break;
|
|
|
|
case NM_KILLFOCUS:
|
|
if (m_pFolderBar)
|
|
m_pFolderBar->KillScopeDropDown();
|
|
break;
|
|
|
|
case NM_SETFOCUS:
|
|
UnkOnFocusChangeIS(m_pDwSite, (IDockingWindow*)this, TRUE);
|
|
break;
|
|
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
LRESULT CInfoColumn::OnICBeginDrag(LPNMREBAR pnm)
|
|
{
|
|
SetCapture(m_hwndInfoColumn);
|
|
SendMessage(m_hwndRebar, RB_BEGINDRAG, pnm->uBand, (LPARAM)-2);
|
|
m_fRebarDragging = TRUE;
|
|
return 1;
|
|
}
|
|
|
|
HRESULT CInfoColumn::HrInit(IAthenaBrowser *pBrowser,
|
|
ITreeViewNotify *ptvNotify)
|
|
{
|
|
HRESULT hres = E_FAIL;
|
|
|
|
if (pBrowser && ptvNotify)
|
|
{
|
|
if(m_pTreeView = new CTreeView(ptvNotify))
|
|
//Add the treeview before OEToday since we navigate to the front page using TreeView.
|
|
hres = m_pTreeView->HrInit(0, pBrowser);
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
HRESULT CInfoColumn::AddTreeView(DWORD dwSize, BOOL fVisible)
|
|
{
|
|
REBARBANDINFO bandinfo = {0};
|
|
RECT rctree;
|
|
int cxFrame;
|
|
int iWidth;
|
|
char BandTitle[CCHMAX_STRINGRES];
|
|
HRESULT hres = E_FAIL;
|
|
IInputObject *pObj;
|
|
|
|
if (SUCCEEDED(m_pTreeView->QueryInterface(IID_IInputObject, (LPVOID*)&pObj)))
|
|
{
|
|
if (SUCCEEDED(hres = AddObject(pObj, m_fShow)))
|
|
{
|
|
cxFrame = GetSystemMetrics(SM_CXFRAME);
|
|
iWidth = m_xWidth - cxFrame;
|
|
|
|
if (SUCCEEDED(m_pTreeView->GetWindow(&bandinfo.hwndChild)))
|
|
{
|
|
/*
|
|
if (dwSize == 0)
|
|
{
|
|
//We make the TreeView atleast half of the InfoColumn window. Starting up
|
|
//with the TreeView minimized is confusing out people
|
|
GetClientRect(m_hwndInfoColumn, &rctree);
|
|
dwSize = rctree.bottom / 2;
|
|
}
|
|
*/
|
|
if (g_hLocRes)
|
|
{
|
|
LoadString(g_hLocRes, idsMNBandTitle, BandTitle, sizeof(BandTitle));
|
|
}
|
|
|
|
bandinfo.cbSize = sizeof (REBARBANDINFO);
|
|
bandinfo.fMask = RBBIM_CHILD | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE
|
|
| RBBIM_CHILDSIZE | RBBIM_TEXT | RBBIM_LPARAM;
|
|
bandinfo.fStyle = RBBS_VARIABLEHEIGHT | (fVisible ? 0 : RBBS_HIDDEN);
|
|
bandinfo.wID = ICTREEVIEW;
|
|
//Height
|
|
bandinfo.cx = dwSize;
|
|
//Width
|
|
bandinfo.cyMinChild = (UINT)iWidth;
|
|
bandinfo.cyChild = (UINT)iWidth;
|
|
bandinfo.cyMaxChild = MAX_WIDTH;
|
|
bandinfo.lpText = BandTitle;
|
|
|
|
IDropDownFldrBar *pddf;
|
|
m_pTreeView->QueryInterface(IID_IDropDownFldrBar, (void**)&pddf);
|
|
bandinfo.lParam = (LPARAM)pddf;
|
|
|
|
SendMessage(m_hwndRebar, RB_INSERTBAND, -1, (LPARAM)&bandinfo);
|
|
if (fVisible)
|
|
{
|
|
++m_cVisibleBands;
|
|
}
|
|
hres = S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_pTreeView->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&m_CacheCmdTarget[ITB_TREE - ITB_INFOCOL_BASE]) != S_OK)
|
|
{
|
|
m_CacheCmdTarget[ITB_TREE - ITB_INFOCOL_BASE] = NULL;
|
|
}
|
|
return hres;
|
|
}
|
|
|
|
void CInfoColumn::AddOETodayBand(DWORD dwSize, BOOL fVisible)
|
|
{
|
|
REBARBANDINFO bandinfo = {0};
|
|
char BandTitle[CCHMAX_STRINGRES] = {0};
|
|
|
|
|
|
//Add Outlook Express band
|
|
if (g_hLocRes)
|
|
{
|
|
LoadString(g_hLocRes, idsOEBandTitle, BandTitle, sizeof(BandTitle));
|
|
}
|
|
bandinfo.cbSize = sizeof (REBARBANDINFO);
|
|
bandinfo.fMask = RBBIM_STYLE | RBBIM_ID | RBBIM_TEXT | RBBIM_SIZE
|
|
| RBBIM_CHILDSIZE | RBBIM_TEXT;
|
|
bandinfo.fStyle = RBBS_FIXEDSIZE | (fVisible ? 0 : RBBS_HIDDEN);
|
|
bandinfo.cyMinChild = m_xWidth - GetSystemMetrics(SM_CXFRAME);
|
|
bandinfo.cxMinChild = 0;
|
|
bandinfo.cx = 0;
|
|
bandinfo.wID = ICOETODAY;
|
|
bandinfo.lpText = BandTitle;
|
|
SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT) -1, (LPARAM)&bandinfo);
|
|
if (fVisible)
|
|
++m_cVisibleBands;
|
|
}
|
|
|
|
CTreeView* CInfoColumn::GetTreeView()
|
|
{
|
|
Assert(m_pTreeView);
|
|
m_pTreeView->AddRef();
|
|
return m_pTreeView;
|
|
}
|
|
|
|
HRESULT CInfoColumn::AddObject(IInputObject *pinpobj, DWORD fShow)
|
|
{
|
|
DWORD dwIndex;
|
|
HRESULT hres;
|
|
|
|
if (SUCCEEDED(FindBandListIndex(&dwIndex)))
|
|
{
|
|
m_BandList[dwIndex].fShow = fShow;
|
|
m_BandList[dwIndex].pBandObj = pinpobj;
|
|
|
|
IObjectWithSite *pObject = 0;
|
|
hres = pinpobj->QueryInterface(IID_IObjectWithSite, (LPVOID *) &pObject);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
pObject->SetSite((IDockingWindow *) this);
|
|
pObject->Release();
|
|
}
|
|
|
|
m_BandList[dwIndex].pBandObj->UIActivateIO(fShow, 0);
|
|
|
|
hres = S_OK;
|
|
|
|
}
|
|
else
|
|
hres = E_FAIL;
|
|
|
|
return hres;
|
|
|
|
}
|
|
|
|
DWORD CInfoColumn::FindBandObject(IInputObject *pinpobj)
|
|
{
|
|
if (pinpobj)
|
|
{
|
|
DWORD index;
|
|
for (index = 0; index < IC_MAX_OBJECTS; index++)
|
|
{
|
|
if (pinpobj == m_BandList[index].pBandObj)
|
|
return index;
|
|
}
|
|
}
|
|
return INVALID_BAND_INDEX;
|
|
}
|
|
|
|
HRESULT CInfoColumn::FindBandListIndex(DWORD *pdwindex)
|
|
{
|
|
DWORD index;
|
|
|
|
for (index = 0; index < IC_MAX_OBJECTS; index++)
|
|
{
|
|
if (!m_BandList[index].pBandObj)
|
|
{
|
|
*pdwindex = index;
|
|
return S_OK;
|
|
}
|
|
}
|
|
return E_FAIL;
|
|
}
|
|
|
|
BOOL CInfoColumn::CycleFocus(BOOL fReverse)
|
|
{
|
|
DWORD Index;
|
|
BOOL fRet = FALSE;
|
|
|
|
if (m_CurFocus)
|
|
{
|
|
Index = FindBandObject(m_CurFocus);
|
|
if (fReverse)
|
|
{
|
|
Index--;
|
|
}
|
|
else
|
|
{
|
|
Index++;
|
|
}
|
|
fRet = SetCycledFocus(Index, fReverse);
|
|
}
|
|
return fRet;
|
|
}
|
|
|
|
BOOL CInfoColumn::CycleFocus(DWORD LastorFirst, BOOL fReverse)
|
|
{
|
|
DWORD Index;
|
|
BOOL fRet = FALSE;
|
|
|
|
if (LastorFirst == INFOCOLUMN_FIRST)
|
|
{
|
|
Index = GetFirstBand();
|
|
fRet = SetCycledFocus(Index, fReverse);
|
|
}
|
|
else
|
|
if (LastorFirst == INFOCOLUMN_LAST)
|
|
{
|
|
Index = GetLastBand();
|
|
fRet = SetCycledFocus(Index, fReverse);
|
|
}
|
|
return fRet;
|
|
}
|
|
|
|
BOOL CInfoColumn::SetCycledFocus(DWORD Index, BOOL fReverse)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
|
|
if ((Index >= 0) && (Index < IC_MAX_OBJECTS) && m_BandList[Index].pBandObj)
|
|
{
|
|
|
|
IOleWindow *pOleWnd;
|
|
if (SUCCEEDED(m_BandList[Index].pBandObj->QueryInterface(IID_IOleWindow, (LPVOID*)&pOleWnd)))
|
|
{
|
|
HWND hwnd;
|
|
if (SUCCEEDED(pOleWnd->GetWindow(&hwnd)))
|
|
{
|
|
RECT Clientrc;
|
|
|
|
GetClientRect(hwnd, &Clientrc);
|
|
if (Clientrc.bottom)
|
|
{
|
|
SetFocus(hwnd);
|
|
fRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
fRet = SetCycledFocus(fReverse ? --Index : ++Index, fReverse);
|
|
}
|
|
}
|
|
pOleWnd->Release();
|
|
}
|
|
}
|
|
return fRet;
|
|
}
|
|
|
|
DWORD CInfoColumn::GetFirstBand()
|
|
{
|
|
DWORD Index;
|
|
|
|
for (Index = 0; Index < IC_MAX_OBJECTS; Index++)
|
|
{
|
|
if (m_BandList[Index].pBandObj)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return Index;
|
|
}
|
|
|
|
DWORD CInfoColumn::GetLastBand()
|
|
{
|
|
DWORD Index;
|
|
|
|
for (Index = 0; Index < IC_MAX_OBJECTS; Index++)
|
|
{
|
|
if (!m_BandList[Index].pBandObj)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return (--Index);
|
|
}
|
|
|
|
|
|
void CInfoColumn::ForwardMessages(UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
|
|
SendMessage(m_hwndRebar, msg, wParam, lParam);
|
|
|
|
for (DWORD Index = 0; Index < IC_MAX_OBJECTS; Index++)
|
|
{
|
|
if(m_BandList[Index].pBandObj)
|
|
{
|
|
IOleWindow *polewnd;
|
|
if(SUCCEEDED(m_BandList[Index].pBandObj->QueryInterface(IID_IOleWindow, (LPVOID*)&polewnd)))
|
|
{
|
|
HWND hwnd;
|
|
if (SUCCEEDED(polewnd->GetWindow(&hwnd)))
|
|
{
|
|
SendMessage(hwnd, msg, wParam, lParam);
|
|
}
|
|
}
|
|
polewnd->Release();
|
|
}
|
|
}
|
|
GetFontParams();
|
|
|
|
}
|
|
|
|
|
|
HRESULT CInfoColumn::SaveSettings(void)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
DWORD iBand;
|
|
DWORD cBands;
|
|
HKEY hKey = 0;
|
|
HKEY hSubKey = 0;
|
|
REBARBANDINFO rbbi;
|
|
TCHAR szSubKey[CCHMAX_STRINGRES];
|
|
BOOL fVisible = TRUE;
|
|
DWORD dwDisposition = 0;
|
|
DWORD dwResult;
|
|
DWORD VersionID;
|
|
|
|
// If we don't have a rebar control, then there's nothing to save
|
|
if (!m_hwndRebar)
|
|
return (S_FALSE);
|
|
|
|
// Zero - init this structure
|
|
ZeroMemory(&rbbi, sizeof(REBARBANDINFO));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_SIZE | RBBIM_ID;
|
|
|
|
// Delete the old key so there's no leftover information
|
|
AthUserDeleteKey(c_szRegInfoColumn);
|
|
|
|
// Get the reg key we need
|
|
if (ERROR_SUCCESS != AthUserCreateKey(c_szRegInfoColumn, KEY_ALL_ACCESS, &hKey, &dwDisposition))
|
|
goto exit;
|
|
|
|
VersionID = LEFTPANE_VERSION;
|
|
AthUserSetValue(c_szRegInfoColumn, "Version", REG_BINARY, (const LPBYTE)&VersionID, sizeof(DWORD));
|
|
|
|
// Get the number of bands from the rebar
|
|
cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
|
|
// Loop through bands we know about
|
|
for (iBand = 0; iBand < cBands; iBand++)
|
|
{
|
|
// Get the band information
|
|
if (SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi))
|
|
{
|
|
fVisible = !(rbbi.fStyle & RBBS_HIDDEN);
|
|
|
|
// Open a subkey for this one
|
|
wnsprintf(szSubKey, ARRAYSIZE(szSubKey),c_szRegICBand, iBand);
|
|
dwResult = RegCreateKeyEx(hKey, szSubKey, 0, 0, REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, 0, &hSubKey, &dwDisposition);
|
|
if (ERROR_SUCCESS == dwResult)
|
|
{
|
|
RegSetValueEx(hSubKey, c_szRegICBandID, 0, REG_DWORD, (const LPBYTE) &(rbbi.wID), sizeof(UINT));
|
|
RegSetValueEx(hSubKey, c_szRegICBandSize, 0, REG_DWORD, (const LPBYTE) &(rbbi.cx), sizeof(UINT));
|
|
RegSetValueEx(hSubKey, c_szRegICBandVisible, 0, REG_DWORD, (const LPBYTE) &fVisible, sizeof(BOOL));
|
|
|
|
RegCloseKey(hSubKey);
|
|
}
|
|
}
|
|
}
|
|
|
|
exit:
|
|
if (hKey)
|
|
RegCloseKey(hKey);
|
|
|
|
return (hr);
|
|
}
|
|
|
|
|
|
HRESULT CInfoColumn::CreateBands(void)
|
|
{
|
|
HRESULT hr;
|
|
HKEY hKey = 0;
|
|
HKEY hSubKey = 0;
|
|
DWORD iBand;
|
|
DWORD cBands = IC_MAX_OBJECTS;
|
|
TCHAR szSubKey[CCHMAX_STRINGRES];
|
|
LONG lResult;
|
|
DWORD dwType;
|
|
DWORD dwID;
|
|
DWORD dwHeight;
|
|
DWORD dwVisible;
|
|
DWORD cbData;
|
|
|
|
// First see if we have any persisted settings. If not, then
|
|
// create the default band set.
|
|
lResult = AthUserOpenKey(c_szRegInfoColumn, KEY_READ | KEY_QUERY_VALUE, &hKey);
|
|
if (lResult != ERROR_SUCCESS)
|
|
return CreateDefaultBands();
|
|
|
|
//See if the version numbers match
|
|
DWORD VersionID = 0;
|
|
cbData = sizeof(DWORD);
|
|
lResult = AthUserGetValue(c_szRegInfoColumn, "Version", &dwType, (LPBYTE)&VersionID, &cbData);
|
|
if ((lResult != ERROR_SUCCESS) || (VersionID != LEFTPANE_VERSION))
|
|
{
|
|
RegCloseKey(hKey);
|
|
hKey = 0;
|
|
return CreateDefaultBands();
|
|
}
|
|
|
|
// If we have saved information, figure out how many bands are saved
|
|
if (hKey)
|
|
{
|
|
RegQueryInfoKey(hKey, 0, 0, 0, &cBands, 0, 0, 0, 0, 0, 0, 0);
|
|
|
|
// If there are not any bands saved, then we use defaults
|
|
if (!cBands)
|
|
{
|
|
RegCloseKey(hKey);
|
|
hKey = 0;
|
|
hr = CreateDefaultBands();
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
// Loop through the bands in the registry
|
|
for (iBand = 0; iBand < cBands; iBand++)
|
|
{
|
|
// Open the band's subkey
|
|
wnsprintf(szSubKey,ARRAYSIZE(szSubKey), c_szRegICBand, iBand);
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey))
|
|
{
|
|
// Read the band ID. If this ain't valid, we skip the whole band.
|
|
cbData = sizeof(DWORD);
|
|
lResult = RegQueryValueEx(hSubKey, c_szRegICBandID, 0, &dwType,
|
|
(LPBYTE) &dwID, &cbData);
|
|
if (lResult != ERROR_SUCCESS || dwID > IC_MAX_OBJECTS)
|
|
continue;
|
|
|
|
// Read the band height
|
|
lResult = RegQueryValueEx(hSubKey, c_szRegICBandSize, 0, &dwType,
|
|
(LPBYTE) &dwHeight, &cbData);
|
|
if (lResult != ERROR_SUCCESS)
|
|
dwHeight = 0;
|
|
|
|
// Read the visibility status
|
|
lResult = RegQueryValueEx(hSubKey, c_szRegICBandVisible, 0, &dwType,
|
|
(LPBYTE) &dwVisible, &cbData);
|
|
if (lResult != ERROR_SUCCESS)
|
|
dwVisible = TRUE;
|
|
|
|
// Now that we have all of this lovely information, create the
|
|
// band.
|
|
switch (dwID)
|
|
{
|
|
case ICOETODAY:
|
|
break;
|
|
|
|
case ICTREEVIEW:
|
|
AddTreeView(dwHeight, dwVisible);
|
|
break;
|
|
|
|
case ICBLAB:
|
|
AddMsgrAb(dwHeight, dwVisible);
|
|
break;
|
|
|
|
default:
|
|
AssertSz(FALSE, "CInfoColumn::CreateBands() - Unknown band ID.");
|
|
}
|
|
|
|
// Close the reg key
|
|
RegCloseKey(hSubKey);
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
exit:
|
|
if (hKey)
|
|
RegCloseKey(hKey);
|
|
|
|
return (hr);
|
|
}
|
|
|
|
|
|
HRESULT CInfoColumn::CreateDefaultBands(void)
|
|
{
|
|
// Loop through the bands and create one of each
|
|
for (UINT id = 0; id < IC_MAX_OBJECTS; id++)
|
|
{
|
|
switch (id)
|
|
{
|
|
case ICOETODAY:
|
|
break;
|
|
|
|
case ICTREEVIEW:
|
|
{
|
|
//Poeple want to see the TreeView the first time they start up
|
|
RECT rctree = {0};
|
|
if (m_hwndInfoColumn)
|
|
{
|
|
GetClientRect(m_hwndInfoColumn, &rctree);
|
|
}
|
|
|
|
AddTreeView(rctree.bottom / 2);
|
|
break;
|
|
}
|
|
case ICBLAB:
|
|
AddMsgrAb();
|
|
break;
|
|
|
|
default:
|
|
AssertSz(FALSE, "CInfoColumn::CreateBands() - Unknown band ID.");
|
|
}
|
|
}
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
void CInfoColumn::OnContextMenu(HWND hwnd, HWND hwndContext, UINT xPos, UINT yPos)
|
|
{
|
|
// Load the context menu
|
|
HMENU hMenu = LoadPopupMenu(IDR_INFOCOLUMN_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 ICBLAB:
|
|
CheckMenuItem(hMenu, ID_INFOCOLUMN_CONTACTS, MF_BYCOMMAND | MF_CHECKED);
|
|
break;
|
|
|
|
case ICTREEVIEW:
|
|
CheckMenuItem(hMenu, ID_INFOCOLUMN_FOLDER_LIST, MF_BYCOMMAND | MF_CHECKED);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DWORD cmd;
|
|
cmd = TrackPopupMenuEx(hMenu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
|
|
xPos, yPos, m_hwndInfoColumn, NULL);
|
|
|
|
if (cmd != 0)
|
|
{
|
|
switch (cmd)
|
|
{
|
|
case ID_INFOCOLUMN_CONTACTS:
|
|
if (m_pMsgrAb)
|
|
{
|
|
ShowHideBand(ICBLAB);
|
|
}
|
|
else
|
|
{
|
|
AddMsgrAb();
|
|
}
|
|
break;
|
|
|
|
case ID_INFOCOLUMN_FOLDER_LIST:
|
|
if (m_pTreeView)
|
|
{
|
|
ShowHideBand(ICTREEVIEW);
|
|
}
|
|
else
|
|
{
|
|
AddTreeView();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//If none of the bands is visible, hide the InfoColumn too
|
|
if (!m_cVisibleBands)
|
|
{
|
|
//We can't afford to hide all the bands as it will shrink the Rebar window itself
|
|
//so we make all the bands visible, but hide the InfoColumn Window
|
|
ShowAllBands();
|
|
if (GetParent(m_hwndInfoColumn) != m_hwndParent && m_pFolderBar)
|
|
m_pFolderBar->KillScopeDropDown();
|
|
|
|
g_pBrowser->SetViewLayout(DISPID_MSGVIEW_FOLDERLIST, LAYOUT_POS_NA, FALSE, 0, 0);
|
|
}
|
|
}
|
|
|
|
|
|
void CInfoColumn::ShowHideBand(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;
|
|
++m_cVisibleBands;
|
|
}
|
|
else
|
|
{
|
|
rbbi.fStyle |= RBBS_HIDDEN;
|
|
--m_cVisibleBands;
|
|
}
|
|
|
|
SendMessage(m_hwndRebar, RB_SETBANDINFO, iBand, (LPARAM) &rbbi);
|
|
return;
|
|
}
|
|
}
|
|
|
|
AssertSz(FALSE, "Failed to find the requested band.");
|
|
}
|
|
//Called by the Folder Bar as a drop down pane
|
|
HRESULT CInfoColumn::RegisterFlyOut(CFolderBar *pFolderBar)
|
|
{
|
|
Assert(m_pFolderBar == NULL);
|
|
|
|
//If all our bands are hidden then make all of them visible.
|
|
//This happens only when the user hides all the bands making the
|
|
//InfoColumn disappear, which causes the drop down to be visible
|
|
//from folder bar.
|
|
if (!m_cVisibleBands)
|
|
{
|
|
ShowAllBands();
|
|
}
|
|
m_pFolderBar = pFolderBar;
|
|
m_pFolderBar->AddRef();
|
|
RegisterChildren(pFolderBar, TRUE);
|
|
RegisterGlobalDropDown(m_hwndInfoColumn);
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CInfoColumn::RevokeFlyOut(void)
|
|
{
|
|
if (m_pFolderBar)
|
|
{
|
|
m_pFolderBar->Release();
|
|
m_pFolderBar = NULL;
|
|
}
|
|
RegisterChildren(NULL, FALSE);
|
|
UnregisterGlobalDropDown(m_hwndInfoColumn);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//Called by Folder Bar for drop down scope
|
|
HRESULT CInfoColumn::GetInfoColWnd(HWND * lphwnd)
|
|
{
|
|
if (m_hwndInfoColumn)
|
|
{
|
|
*lphwnd = m_hwndInfoColumn;
|
|
return (S_OK);
|
|
}
|
|
else
|
|
{
|
|
*lphwnd = 0;
|
|
return (E_FAIL);
|
|
}
|
|
}
|
|
|
|
HRESULT CInfoColumn::RegisterChildren(CFolderBar *pFolder, BOOL Register)
|
|
{
|
|
int BandCount;
|
|
REBARBANDINFO rbbinfo;
|
|
|
|
|
|
BandCount = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
|
|
|
|
for (--BandCount; BandCount >= 0; BandCount--)
|
|
{
|
|
ZeroMemory(&rbbinfo, sizeof(REBARBANDINFO));
|
|
rbbinfo.fMask = RBBIM_LPARAM;
|
|
SendMessage(m_hwndRebar, RB_GETBANDINFO, BandCount, (LPARAM)&rbbinfo);
|
|
|
|
if (rbbinfo.lParam)
|
|
{
|
|
if (Register)
|
|
((IDropDownFldrBar*)rbbinfo.lParam)->RegisterFlyOut(pFolder);
|
|
else
|
|
((IDropDownFldrBar*)rbbinfo.lParam)->RevokeFlyOut();
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CInfoColumn::HasFocus(UINT itb)
|
|
{
|
|
HRESULT hres = S_FALSE;
|
|
IInputObject *pinpobj = NULL;
|
|
|
|
switch (itb)
|
|
{
|
|
case ITB_TREE:
|
|
if (m_pTreeView && SUCCEEDED(m_pTreeView->QueryInterface(IID_IInputObject, (void**)&pinpobj)))
|
|
{
|
|
hres = pinpobj->HasFocusIO();
|
|
}
|
|
break;
|
|
|
|
case ITB_BUDDYADDRBOOK:
|
|
if (m_pMsgrAb && SUCCEEDED(m_pMsgrAb->QueryInterface(IID_IInputObject, (void**)&pinpobj)))
|
|
{
|
|
hres = pinpobj->HasFocusIO();
|
|
}
|
|
break;
|
|
}
|
|
if (pinpobj)
|
|
pinpobj->Release();
|
|
return hres;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CInfoColumn::QueryStatus(const GUID *pguidCmdGroup,
|
|
ULONG cCmds,
|
|
OLECMD *prgCmds,
|
|
OLECMDTEXT *pCmdText)
|
|
{
|
|
// Always let all bands have a shot at this
|
|
for (UINT i = 0; i < IC_MAX_OBJECTS; i++)
|
|
{
|
|
// Check to see if we have a command target for this band.
|
|
if (m_CacheCmdTarget[i])
|
|
m_CacheCmdTarget[i]->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CInfoColumn::Exec(const GUID *pguidCmdGroup,
|
|
DWORD nCmdID,
|
|
DWORD nCmdExecOpt,
|
|
VARIANTARG *pvaIn,
|
|
VARIANTARG *pvaOut)
|
|
{
|
|
IOleCommandTarget *pcmdTarget = NULL;
|
|
HRESULT hr = S_FALSE;
|
|
|
|
// Loop through all the bands to see if this is their command
|
|
for (UINT i = 0; i < IC_MAX_OBJECTS; i++)
|
|
{
|
|
// Check to see if we have a command target for this band
|
|
if (m_CacheCmdTarget[i])
|
|
{
|
|
// See if the command belongs to this band
|
|
if (SUCCEEDED(hr = m_CacheCmdTarget[i]->Exec(pguidCmdGroup, nCmdID,
|
|
nCmdExecOpt, pvaIn, pvaOut)))
|
|
{
|
|
return (hr);
|
|
}
|
|
}
|
|
}
|
|
|
|
return (OLECMDERR_E_NOTSUPPORTED);
|
|
}
|
|
|