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.
854 lines
22 KiB
854 lines
22 KiB
/////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 1993-1999 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// MODULE: StatBar.cpp
|
|
//
|
|
// PURPOSE: Implements the CStatusBar class which manipulates the apps
|
|
// status bar.
|
|
//
|
|
|
|
#include "pch.hxx"
|
|
#include "statbar.h"
|
|
#include "menures.h"
|
|
#include <oerules.h>
|
|
#include <demand.h>
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// The order here needs to match the DELIVERYNOTIFYTYPE enumeration from
|
|
// mailnews\spooler\spoolapi.h. If there is a zero in the below array, then
|
|
// the status area should be cleared out.
|
|
|
|
const int c_rgidsSpoolerNotify[DELIVERY_NOTIFY_ALLDONE + 1][2] = {
|
|
/* DELIVERY_NOTIFY_STARTING */ { 0, 0 },
|
|
/* DELIVERY_NOTIFY_CONNECTING */ { idsSBConnecting, STATUS_IMAGE_CONNECTED },
|
|
/* DELIVERY_NOTIFY_SECURE */ { 0, 0 },
|
|
/* DELIVERY_NOTIFY_UNSECURE */ { 0, 0 },
|
|
/* DELIVERY_NOTIFY_AUTHORIZING */ { idsAuthorizing, STATUS_IMAGE_AUTHORIZING },
|
|
/* DELIVERY_NOTIFY_CHECKING */ { idsSBChecking, STATUS_IMAGE_CHECKING },
|
|
/* DELIVERY_NOTIFY_CHECKING_NEWS */ { idsSBCheckingNews, STATUS_IMAGE_CHECKING_NEWS },
|
|
/* DELIVERY_NOTIFY_SENDING */ { idsSBSending, STATUS_IMAGE_SENDING },
|
|
/* DELIVERY_NOTIFY_SENDING_NEWS */ { idsSBSendingNews, STATUS_IMAGE_SENDING },
|
|
/* DELIVERY_NOTIFY_RECEIVING */ { idsSBReceiving, STATUS_IMAGE_RECEIVING },
|
|
/* DELIVERY_NOTIFY_RECEIVING_NEWS */ { idsSBReceivingNews, STATUS_IMAGE_RECEIVING },
|
|
/* DELIVERY_NOTIFY_COMPLETE */ { 0, 0 },
|
|
/* DELIVERY_NOTIFY_RESULT */ { 0, 0 },
|
|
/* DELIVERY_NOTIFY_ALLDONE */ { idsSBNewMsgsControl, STATUS_IMAGE_NEWMSGS }
|
|
};
|
|
|
|
const int c_rgidsConnected[][2] = {
|
|
{ idsWorkingOffline, STATUS_IMAGE_OFFLINE },
|
|
{ idsWorkingOnline, STATUS_IMAGE_ONLINE },
|
|
{ idsNotConnected, STATUS_IMAGE_DISCONNECTED }
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Constructors etc.
|
|
|
|
CStatusBar::CStatusBar()
|
|
{
|
|
m_cRef = 1;
|
|
m_hwnd = 0;
|
|
m_hwndProg = 0;
|
|
m_tidOwner = 0;
|
|
m_dwFlags = 0;
|
|
m_himl = 0;
|
|
ZeroMemory(m_rgIcons, sizeof(HICON) * STATUS_IMAGE_MAX);
|
|
m_cxFiltered = 0;
|
|
m_cxSpooler = 0;
|
|
m_cxConnected = 0;
|
|
m_cxProgress = 0;
|
|
m_fInSimple = FALSE;
|
|
m_ridFilter = RULEID_VIEW_ALL;
|
|
m_statusConn = CONN_STATUS_WORKOFFLINE;
|
|
m_typeDelivery = DELIVERY_NOTIFY_STARTING;
|
|
m_cMsgsDelivery = 0;
|
|
}
|
|
|
|
CStatusBar::~CStatusBar()
|
|
{
|
|
// Free the image list
|
|
if (m_himl)
|
|
ImageList_Destroy(m_himl);
|
|
|
|
// Free our icons
|
|
for (UINT i = 0; i < STATUS_IMAGE_MAX; i++)
|
|
{
|
|
if (m_rgIcons[i])
|
|
DestroyIcon(m_rgIcons[i]);
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IUnknown
|
|
//
|
|
|
|
HRESULT CStatusBar::QueryInterface(REFIID riid, LPVOID *ppvObj)
|
|
{
|
|
*ppvObj = NULL;
|
|
|
|
if (IsEqualIID(riid, IID_IUnknown))
|
|
*ppvObj = (LPVOID) (IUnknown *) this;
|
|
else if (IsEqualIID(riid, IID_IStatusBar))
|
|
*ppvObj = (LPVOID) (IStatusBar *) this;
|
|
|
|
if (NULL == *ppvObj)
|
|
return (E_NOINTERFACE);
|
|
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
ULONG CStatusBar::AddRef(void)
|
|
{
|
|
return InterlockedIncrement((LONG *) &m_cRef);
|
|
}
|
|
|
|
|
|
ULONG CStatusBar::Release(void)
|
|
{
|
|
InterlockedDecrement((LONG *) &m_cRef);
|
|
if (0 == m_cRef)
|
|
{
|
|
delete this;
|
|
return (0);
|
|
}
|
|
return (m_cRef);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::Initialize()
|
|
//
|
|
// PURPOSE: Creates and initializes the status bar window.
|
|
//
|
|
// PARAMETERS:
|
|
// [in] hwndParent - Handle of the window that will be this control's parent
|
|
// [in] dwFlags - Determine which parts will be displayed
|
|
//
|
|
// RETURN VALUE:
|
|
// E_OUTOFMEMORY, S_OK
|
|
//
|
|
HRESULT CStatusBar::Initialize(HWND hwndParent, DWORD dwFlags)
|
|
{
|
|
TraceCall("CStatusBar::Initialize");
|
|
|
|
// This is now the thread that owns the class
|
|
m_tidOwner = GetCurrentThreadId();
|
|
|
|
// Keep these around
|
|
m_dwFlags = dwFlags;
|
|
|
|
// Create the status window
|
|
m_hwnd = CreateStatusWindow(WS_CHILD | SBARS_SIZEGRIP | WS_CLIPSIBLINGS | SBT_TOOLTIPS,
|
|
NULL, hwndParent, IDC_STATUS_BAR);
|
|
if (!m_hwnd)
|
|
return (E_OUTOFMEMORY);
|
|
|
|
// Calculate the widths of the various areas we support
|
|
_UpdateWidths();
|
|
|
|
// Load the image list too
|
|
m_himl = ImageList_LoadImage(g_hLocRes, MAKEINTRESOURCE(idbStatus), 16,
|
|
0, RGB(255, 0, 255), IMAGE_BITMAP, 0);
|
|
|
|
// Note - We don't need to add any parts here since we do that in the
|
|
// OnSize() call.
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::ShowStatus()
|
|
//
|
|
// PURPOSE: Shows or hides the status bar.
|
|
//
|
|
// PARAMETERS:
|
|
// [in] fShow - TRUE to show the bar, FALSE to hide it.
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
//
|
|
HRESULT CStatusBar::ShowStatus(BOOL fShow)
|
|
{
|
|
TraceCall("CStatusBar::ShowStatus");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
if (IsWindow(m_hwnd))
|
|
ShowWindow(m_hwnd, fShow ? SW_SHOW : SW_HIDE);
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::OnSize()
|
|
//
|
|
// PURPOSE: Tells the status bar that the parent window resized. In return
|
|
// the status bar updates it's own width to match.
|
|
//
|
|
// PARAMETERS:
|
|
// [in] cx - New width of the paret
|
|
//
|
|
// RETURN VALUE:
|
|
// HRESULT
|
|
//
|
|
HRESULT CStatusBar::OnSize(int cx, int cy)
|
|
{
|
|
int rgcx[SBP_MAX];
|
|
int * prgcx = rgcx;
|
|
DWORD cVisible = 1;
|
|
DWORD cPart = SBP_MAX - 1;
|
|
BOOL dwNoProgress = 0;
|
|
int cxProgress = 0;
|
|
int cxFiltered = 0;
|
|
int cxConnected = 0;
|
|
int cxSpooler = 0;
|
|
|
|
TraceCall("CStatusBar::OnSize");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
// Forward a WM_SIZE message off to the status bar
|
|
SendMessage(m_hwnd, WM_SIZE, SIZE_RESTORED, MAKELPARAM(cx, cy));
|
|
|
|
// Check to see if the progress bar is visible
|
|
dwNoProgress = !IsWindow(m_hwndProg);
|
|
|
|
// Figure out our widths
|
|
if (IsWindow(m_hwndProg))
|
|
{
|
|
cxProgress = m_cxProgress;
|
|
cVisible++;
|
|
}
|
|
|
|
if ((0 == (m_dwFlags & SBI_HIDE_FILTERED)) && (RULEID_VIEW_ALL != m_ridFilter))
|
|
{
|
|
cxFiltered = m_cxFiltered;
|
|
cVisible++;
|
|
}
|
|
|
|
if (0 == (m_dwFlags & SBI_HIDE_CONNECTED))
|
|
{
|
|
cxConnected = m_cxConnected;
|
|
cVisible++;
|
|
}
|
|
|
|
if (0 == (m_dwFlags & SBI_HIDE_SPOOLER))
|
|
{
|
|
cxSpooler = m_cxSpooler;
|
|
cVisible++;
|
|
}
|
|
|
|
// If we have a filter turned on
|
|
if ((0 == (m_dwFlags & SBI_HIDE_FILTERED)) && (RULEID_VIEW_ALL != m_ridFilter))
|
|
{
|
|
*prgcx = cxFiltered;
|
|
prgcx++;
|
|
}
|
|
|
|
// For general area
|
|
*prgcx = cx - cxProgress - cxConnected - cxSpooler;
|
|
prgcx++;
|
|
|
|
// If we have progress
|
|
if (0 != cxProgress)
|
|
{
|
|
*prgcx = cx - cxConnected - cxSpooler;
|
|
prgcx++;
|
|
}
|
|
|
|
// For connected state
|
|
*prgcx = cx - cxSpooler;
|
|
prgcx++;
|
|
|
|
// For spooler state
|
|
*prgcx = cx;
|
|
prgcx++;
|
|
|
|
// Tell the status bar to update
|
|
SendMessage(m_hwnd, SB_SETPARTS, cVisible, (LPARAM) rgcx);
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::GetHeight()
|
|
//
|
|
// PURPOSE: Allows the caller to find out how tall the status bar is.
|
|
//
|
|
// PARAMETERS:
|
|
// [out] pcy - Returns the height.
|
|
//
|
|
// RETURN VALUE:
|
|
// HRESULT
|
|
//
|
|
HRESULT CStatusBar::GetHeight(int *pcy)
|
|
{
|
|
RECT rc;
|
|
|
|
TraceCall("CStatusBar::GetHeight");
|
|
|
|
if (!pcy)
|
|
return (E_INVALIDARG);
|
|
|
|
if (IsWindowVisible(m_hwnd))
|
|
{
|
|
GetClientRect(m_hwnd, &rc);
|
|
*pcy = rc.bottom;
|
|
}
|
|
else
|
|
*pcy = 0;
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::ShowSimpleText()
|
|
//
|
|
// PURPOSE: Puts the status bar into simple mode and displays the
|
|
// specified string.
|
|
//
|
|
// PARAMETERS:
|
|
// [in] pszText - String or resource ID of the string to display
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
//
|
|
HRESULT CStatusBar::ShowSimpleText(LPTSTR pszText)
|
|
{
|
|
TCHAR szBuf[CCHMAX_STRINGRES] = "";
|
|
|
|
TraceCall("CStatusBar::ShowSimpleText");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
// If we have a progress bar visible, hide it first
|
|
if (IsWindow(m_hwndProg))
|
|
ShowWindow(m_hwndProg, SW_HIDE);
|
|
|
|
// Check to see if we need to load the string
|
|
if (IS_INTRESOURCE(pszText) && pszText != 0)
|
|
{
|
|
LoadString(g_hLocRes, PtrToUlong(pszText), szBuf, ARRAYSIZE(szBuf));
|
|
pszText = szBuf;
|
|
}
|
|
|
|
// Tell the status bar to go into simple mode
|
|
SendMessage(m_hwnd, SB_SIMPLE, (WPARAM) TRUE, 0);
|
|
m_fInSimple = TRUE;
|
|
|
|
// Set the status text
|
|
SendMessage(m_hwnd, SB_SETTEXT, SBT_NOBORDERS | 255, (LPARAM) pszText);
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::HideSimpleText()
|
|
//
|
|
// PURPOSE: Tells the status bar to stop displaying simple mode.
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
//
|
|
HRESULT CStatusBar::HideSimpleText(void)
|
|
{
|
|
TraceCall("CStatusBar::HideSimpleText");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
// Tell the status bar to leave simple mode
|
|
SendMessage(m_hwnd, SB_SIMPLE, (WPARAM) FALSE, 0);
|
|
m_fInSimple = FALSE;
|
|
|
|
// If we had a progress bar before, show it again
|
|
if (IsWindow(m_hwndProg))
|
|
ShowWindow(m_hwndProg, SW_SHOW);
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::SetStatusText()
|
|
//
|
|
// PURPOSE: Sets the text for the SBP_GENERAL area
|
|
//
|
|
// PARAMETERS:
|
|
// [in] pszText - String or resource ID of the string to display
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
//
|
|
HRESULT CStatusBar::SetStatusText(LPTSTR pszText)
|
|
{
|
|
TCHAR szBuf[CCHMAX_STRINGRES];
|
|
|
|
TraceCall("CStatusBar::SetStatusText");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
DWORD dwPos = SBP_GENERAL;
|
|
if ((m_dwFlags & SBI_HIDE_FILTERED) || (RULEID_VIEW_ALL == m_ridFilter))
|
|
{
|
|
dwPos--;
|
|
}
|
|
|
|
// Check to see if we need to load the string
|
|
if (IS_INTRESOURCE(pszText))
|
|
{
|
|
AthLoadString(PtrToUlong(pszText), szBuf, ARRAYSIZE(szBuf));
|
|
pszText = szBuf;
|
|
}
|
|
|
|
// Set the status text
|
|
SendMessage(m_hwnd, SB_SETTEXT, dwPos, (LPARAM) pszText);
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::ShowProgress()
|
|
//
|
|
// PURPOSE: Adds the progress bar area to the status bar.
|
|
//
|
|
// PARAMETERS:
|
|
// [in] dwRange - Maximum range for the progress bar control
|
|
//
|
|
// RETURN VALUE:
|
|
// E_OUTOFMEMORY, S_OK
|
|
//
|
|
HRESULT CStatusBar::ShowProgress(DWORD dwRange)
|
|
{
|
|
TraceCall("CStatusBar::ShowProgress");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
// Create the progress bar control
|
|
m_hwndProg = CreateWindow(PROGRESS_CLASS, 0, WS_CHILD | PBS_SMOOTH,
|
|
0, 0, 10, 10, m_hwnd, (HMENU) IDC_STATUS_PROGRESS,
|
|
g_hInst, NULL);
|
|
if (!m_hwndProg)
|
|
return (E_OUTOFMEMORY);
|
|
|
|
DWORD dwPos = SBP_PROGRESS;
|
|
if ((m_dwFlags & SBI_HIDE_FILTERED) || (RULEID_VIEW_ALL == m_ridFilter))
|
|
{
|
|
dwPos--;
|
|
}
|
|
|
|
// Hit the status bar with a size to force it to add the progress bar area
|
|
RECT rc;
|
|
GetClientRect(m_hwnd, &rc);
|
|
OnSize(rc.right, rc.bottom);
|
|
|
|
SendMessage(m_hwndProg, PBM_SETRANGE32, 0, dwRange);
|
|
|
|
// Now size the progress bar to sit inside the status bar
|
|
SendMessage(m_hwnd, SB_GETRECT, dwPos, (LPARAM) &rc);
|
|
SetWindowPos(m_hwndProg, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
|
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
|
|
|
// If we're not in simple mode, show it
|
|
if (!m_fInSimple)
|
|
ShowWindow(m_hwndProg, SW_SHOW);
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::SetProgress()
|
|
//
|
|
// PURPOSE: Set's the progress bar position.
|
|
//
|
|
// PARAMETERS:
|
|
// [in] dwPos - New progress bar position
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
//
|
|
HRESULT CStatusBar::SetProgress(DWORD dwPos)
|
|
{
|
|
TraceCall("CStatusBar::SetProgress");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
// Update the progress bar
|
|
if (IsWindow(m_hwndProg))
|
|
{
|
|
SendMessage(m_hwndProg, PBM_SETPOS, dwPos, 0);
|
|
}
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::HideProgress()
|
|
//
|
|
// PURPOSE: Hides the progress bar.
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
//
|
|
HRESULT CStatusBar::HideProgress(void)
|
|
{
|
|
TraceCall("CStatusBar::HideProgress");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
if (IsWindow(m_hwndProg))
|
|
{
|
|
// Destroy the progress bar
|
|
DestroyWindow(m_hwndProg);
|
|
m_hwndProg = 0;
|
|
|
|
// Hit the status bar with a size to have it remove the well
|
|
RECT rc;
|
|
GetClientRect(m_hwnd, &rc);
|
|
OnSize(rc.right, rc.bottom);
|
|
}
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::SetConnectedStatus()
|
|
//
|
|
// PURPOSE: Updates the status in the SBP_CONNECTED area
|
|
//
|
|
// PARAMETERS:
|
|
// [in] status - New status
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
//
|
|
HRESULT CStatusBar::SetConnectedStatus(CONN_STATUS status)
|
|
{
|
|
TraceCall("SetConnectedStatus");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
// First job is to figure out the position
|
|
DWORD dwPos = SBP_CONNECTED - (!IsWindow(m_hwndProg));
|
|
if ((m_dwFlags & SBI_HIDE_FILTERED) || (RULEID_VIEW_ALL == m_ridFilter))
|
|
{
|
|
dwPos--;
|
|
}
|
|
|
|
// Next, load the appropriate string for this new status
|
|
TCHAR szRes[CCHMAX_STRINGRES];
|
|
|
|
Assert(status < CONN_STATUS_MAX);
|
|
AthLoadString(c_rgidsConnected[status][0], szRes, ARRAYSIZE(szRes));
|
|
|
|
// Also need to load the right picture
|
|
HICON hIcon = _GetIcon(c_rgidsConnected[status][1]);
|
|
|
|
// Tell the status bar to update
|
|
SendMessage(m_hwnd, SB_SETTEXT, dwPos, (LPARAM) szRes);
|
|
SendMessage(m_hwnd, SB_SETICON, dwPos, (LPARAM) hIcon);
|
|
|
|
// Cache the connection status
|
|
m_statusConn = status;
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::SetSpoolerStatus()
|
|
//
|
|
// PURPOSE: Updates the spooler area.
|
|
//
|
|
// PARAMETERS:
|
|
// [in] type - New status
|
|
//
|
|
// RETURN VALUE:
|
|
// HRESULT
|
|
//
|
|
HRESULT CStatusBar::SetSpoolerStatus(DELIVERYNOTIFYTYPE type, DWORD cMsgs)
|
|
{
|
|
TCHAR szRes[CCHMAX_STRINGRES] = "";
|
|
HICON hIcon;
|
|
DWORD dwPos;
|
|
|
|
TraceCall("CStatusBar::SetSpoolerStatus");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
Assert(type <= DELIVERY_NOTIFY_ALLDONE);
|
|
|
|
// First job is to figure out the position
|
|
dwPos = SBP_SPOOLER - (0 != (m_dwFlags & SBI_HIDE_CONNECTED)) - (!IsWindow(m_hwndProg));
|
|
if ((m_dwFlags & SBI_HIDE_FILTERED) || (RULEID_VIEW_ALL == m_ridFilter))
|
|
{
|
|
dwPos--;
|
|
}
|
|
|
|
// If we are at the ALLDONE state, we do some extra work
|
|
if (type == DELIVERY_NOTIFY_ALLDONE)
|
|
{
|
|
if (-1 == cMsgs)
|
|
{
|
|
// Some error occured
|
|
hIcon = _GetIcon(STATUS_IMAGE_ERROR);
|
|
AthLoadString(idsErrorText, szRes, ARRAYSIZE(szRes));
|
|
}
|
|
else if (0 == cMsgs)
|
|
{
|
|
hIcon = _GetIcon(STATUS_IMAGE_NOMSGS);
|
|
AthLoadString(idsSBNoNewMsgs, szRes, ARRAYSIZE(szRes));
|
|
}
|
|
else
|
|
{
|
|
TCHAR szBuf[CCHMAX_STRINGRES];
|
|
|
|
hIcon = _GetIcon(STATUS_IMAGE_NEWMSGS);
|
|
AthLoadString(idsSBNewMsgsControl, szBuf, ARRAYSIZE(szBuf));
|
|
wnsprintf(szRes, ARRAYSIZE(szRes), szBuf, cMsgs);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hIcon = _GetIcon(c_rgidsSpoolerNotify[type][1]);
|
|
if (c_rgidsSpoolerNotify[type][0])
|
|
AthLoadString(c_rgidsSpoolerNotify[type][0], szRes, ARRAYSIZE(szRes));
|
|
}
|
|
|
|
// Tell the status bar to update
|
|
if (*szRes != 0)
|
|
{
|
|
SendMessage(m_hwnd, SB_SETTEXT, dwPos, (LPARAM) szRes);
|
|
SendMessage(m_hwnd, SB_SETICON, dwPos, (LPARAM) hIcon);
|
|
}
|
|
else
|
|
{
|
|
SendMessage(m_hwnd, SB_SETTEXT, dwPos, (LPARAM) szRes);
|
|
SendMessage(m_hwnd, SB_SETICON, dwPos, 0);
|
|
}
|
|
|
|
// Cache the delivery info
|
|
m_typeDelivery = type;
|
|
m_cMsgsDelivery = cMsgs;
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::OnNotify()
|
|
//
|
|
// PURPOSE: Sends notifications to the status bar
|
|
//
|
|
// PARAMETERS:
|
|
// NMHDR *pnmhdr
|
|
//
|
|
// RETURN VALUE:
|
|
// HRESULT
|
|
//
|
|
HRESULT CStatusBar::OnNotify(NMHDR *pNotify)
|
|
{
|
|
DWORD dwPoints;
|
|
POINT pt;
|
|
RECT rc;
|
|
DWORD dwSpoolerPos;
|
|
DWORD dwConnectPos;
|
|
|
|
TraceCall("CStatusBar::OnNotify");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
if (m_dwFlags & SBI_HIDE_SPOOLER)
|
|
{
|
|
dwSpoolerPos = -1;
|
|
}
|
|
else
|
|
{
|
|
dwSpoolerPos = SBP_SPOOLER - (!IsWindow(m_hwndProg));
|
|
|
|
if ((m_dwFlags & SBI_HIDE_FILTERED) || (RULEID_VIEW_ALL == m_ridFilter))
|
|
{
|
|
dwSpoolerPos--;
|
|
}
|
|
}
|
|
|
|
dwConnectPos = (m_dwFlags & SBI_HIDE_CONNECTED) ? -1 : dwSpoolerPos - 1;
|
|
|
|
if (pNotify->idFrom == IDC_STATUS_BAR)
|
|
{
|
|
if (NM_DBLCLK == pNotify->code)
|
|
{
|
|
dwPoints = GetMessagePos();
|
|
pt.x = LOWORD(dwPoints);
|
|
pt.y = HIWORD(dwPoints);
|
|
ScreenToClient(m_hwnd, &pt);
|
|
SendMessage(m_hwnd, SB_GETRECT, dwSpoolerPos, (LPARAM)&rc);
|
|
if (PtInRect(&rc, pt))
|
|
{
|
|
g_pSpooler->StartDelivery(GetParent(m_hwnd), NULL, FOLDERID_INVALID, DELIVER_SHOW);
|
|
}
|
|
else
|
|
{
|
|
SendMessage(m_hwnd, SB_GETRECT, dwConnectPos, (LPARAM)&rc);
|
|
if (PtInRect(&rc, pt))
|
|
{
|
|
PostMessage(GetParent(m_hwnd), WM_COMMAND, ID_WORK_OFFLINE, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::SetFilter()
|
|
//
|
|
// PURPOSE: Sets the filter for the SBP_FILTERED area
|
|
//
|
|
// PARAMETERS:
|
|
// [in] ridFilter - ID for the current filter
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
//
|
|
HRESULT CStatusBar::SetFilter(RULEID ridFilter)
|
|
{
|
|
RECT rc;
|
|
TCHAR szBuf[CCHMAX_STRINGRES];
|
|
DWORD dwPos;
|
|
|
|
TraceCall("CStatusBar::SetFilter");
|
|
Assert(GetCurrentThreadId() == m_tidOwner);
|
|
|
|
// Get the data
|
|
dwPos = SBP_GENERAL;
|
|
if ((m_dwFlags & SBI_HIDE_FILTERED) || (RULEID_VIEW_ALL == m_ridFilter))
|
|
{
|
|
dwPos--;
|
|
}
|
|
|
|
// Get the status text
|
|
SendMessage(m_hwnd, SB_GETTEXT, dwPos, (LPARAM) szBuf);
|
|
|
|
// Cache the rule
|
|
m_ridFilter = ridFilter;
|
|
|
|
// Resize the status bar
|
|
GetClientRect(m_hwnd, &rc);
|
|
OnSize(rc.right, rc.bottom);
|
|
|
|
dwPos = SBP_GENERAL;
|
|
if ((m_dwFlags & SBI_HIDE_FILTERED) || (RULEID_VIEW_ALL == m_ridFilter))
|
|
{
|
|
dwPos--;
|
|
}
|
|
|
|
// Set the status text
|
|
SendMessage(m_hwnd, SB_SETTEXT, dwPos, (LPARAM) szBuf);
|
|
SendMessage(m_hwnd, SB_SETICON, dwPos, (LPARAM) NULL);
|
|
|
|
AthLoadString(idsViewFiltered, szBuf, ARRAYSIZE(szBuf));
|
|
|
|
// Set the data into the status bar
|
|
if ((0 == (m_dwFlags & SBI_HIDE_FILTERED)) && (RULEID_VIEW_ALL != m_ridFilter))
|
|
{
|
|
SendMessage(m_hwnd, SB_SETTEXT, SBP_FILTERED, (LPARAM) szBuf);
|
|
}
|
|
|
|
if (0 == (m_dwFlags & SBI_HIDE_SPOOLER))
|
|
{
|
|
SetConnectedStatus(m_statusConn);
|
|
}
|
|
|
|
if (0 == (m_dwFlags & SBI_HIDE_CONNECTED))
|
|
{
|
|
SetSpoolerStatus(m_typeDelivery, m_cMsgsDelivery);
|
|
}
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CStatusBar::_UpdateWidths()
|
|
//
|
|
// PURPOSE: Calculates the widths of each of the different areas of the
|
|
// status bar.
|
|
//
|
|
void CStatusBar::_UpdateWidths(void)
|
|
{
|
|
HDC hdc;
|
|
TCHAR szBuf[CCHMAX_STRINGRES];
|
|
SIZE size;
|
|
int i;
|
|
|
|
TraceCall("CStatusBar::_UpdateWidths");
|
|
|
|
// Get the DC from the status bar
|
|
hdc = GetDC(m_hwnd);
|
|
|
|
// Now we need to figure out how big our parts are going to be.
|
|
|
|
// Figure out the space needed for the filtered state
|
|
AthLoadString(idsViewFiltered, szBuf, ARRAYSIZE(szBuf));
|
|
GetTextExtentPoint32(hdc, szBuf, lstrlen(szBuf), &size);
|
|
m_cxFiltered = size.cx;
|
|
|
|
// Add some padding and space for the icon
|
|
m_cxFiltered += (2 * GetSystemMetrics(SM_CXEDGE));
|
|
|
|
// Figure out the space needed for the spooler state
|
|
for (i = 0; i < ARRAYSIZE(c_rgidsSpoolerNotify); i++)
|
|
{
|
|
if (c_rgidsSpoolerNotify[i][0])
|
|
{
|
|
AthLoadString(c_rgidsSpoolerNotify[i][0], szBuf, ARRAYSIZE(szBuf));
|
|
GetTextExtentPoint32(hdc, szBuf, lstrlen(szBuf), &size);
|
|
if (size.cx > m_cxSpooler)
|
|
m_cxSpooler = size.cx;
|
|
}
|
|
}
|
|
|
|
// Add some padding and space for the icon and the grippy thing
|
|
m_cxSpooler += (2 * GetSystemMetrics(SM_CXEDGE)) + 24 + 16;
|
|
|
|
// Do the same for the connected part
|
|
for (i = 0; i < ARRAYSIZE(c_rgidsConnected); i++)
|
|
{
|
|
if (c_rgidsConnected[i][0])
|
|
{
|
|
LoadString(g_hLocRes, c_rgidsConnected[i][0], szBuf, ARRAYSIZE(szBuf));
|
|
GetTextExtentPoint32(hdc, szBuf, lstrlen(szBuf), &size);
|
|
if (size.cx > m_cxConnected)
|
|
m_cxConnected = size.cx;
|
|
}
|
|
}
|
|
|
|
// Add some padding and space for the icon
|
|
m_cxConnected += (2 * GetSystemMetrics(SM_CXEDGE)) + 24;
|
|
|
|
// Let's say that the progress is always equal to
|
|
// the space for the connected area
|
|
m_cxProgress = m_cxConnected;
|
|
|
|
ReleaseDC(m_hwnd, hdc);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
HICON CStatusBar::_GetIcon(DWORD iIndex)
|
|
{
|
|
// Make sure the index is valid
|
|
if (iIndex > STATUS_IMAGE_MAX)
|
|
return 0;
|
|
|
|
// Check to see if we've already created this one
|
|
if (m_rgIcons[iIndex])
|
|
return (m_rgIcons[iIndex]);
|
|
|
|
// Otherwise, create it.
|
|
m_rgIcons[iIndex] = ImageList_GetIcon(m_himl, iIndex, ILD_TRANSPARENT);
|
|
return (m_rgIcons[iIndex]);
|
|
}
|
|
|