mirror of https://github.com/lianthony/NT4.0
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.
755 lines
18 KiB
755 lines
18 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Microsoft Foundation Classes Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Microsoft Foundation Classes product.
|
|
|
|
#include "stdafx.h"
|
|
|
|
#ifdef AFX_CORE3_SEG
|
|
#pragma code_seg(AFX_CORE3_SEG)
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CStatusBar creation, etc
|
|
|
|
#define SBPF_UPDATE 0x0001 // pending update of text
|
|
|
|
struct AFX_STATUSPANE
|
|
{
|
|
UINT nID; // IDC of indicator: 0 => normal text area
|
|
int cxText; // width of string area in pixels
|
|
// on both sides there is a 3 pixel gap and
|
|
// a one pixel border, making a pane 6 pixels wider
|
|
UINT nStyle; // style flags (SBPS_*)
|
|
UINT nFlags; // state flags (SBPF_*)
|
|
CString strText; // text in the pane
|
|
};
|
|
|
|
inline AFX_STATUSPANE* CStatusBar::_GetPanePtr(int nIndex) const
|
|
{
|
|
ASSERT((nIndex >= 0 && nIndex < m_nCount) || m_nCount == 0);
|
|
return ((AFX_STATUSPANE*)m_pData) + nIndex;
|
|
}
|
|
|
|
#ifdef AFX_INIT_SEG
|
|
#pragma code_seg(AFX_INIT_SEG)
|
|
#endif
|
|
|
|
#define CX_PANE_BORDER 6 // 3 pixels on each side of each pane
|
|
|
|
CStatusBar::CStatusBar()
|
|
{
|
|
// setup default border/margin depending on type of system
|
|
m_cyTopBorder = 2;
|
|
if (afxData.bWin4)
|
|
{
|
|
m_cxLeftBorder = 0;
|
|
m_cxRightBorder = 0;
|
|
m_cyBottomBorder = 0;
|
|
}
|
|
else
|
|
{
|
|
m_cxLeftBorder = 2;
|
|
m_cxRightBorder = 2;
|
|
m_cyBottomBorder = 1;
|
|
}
|
|
// minimum height set with SB_SETMINHEIGHT is cached
|
|
m_nMinHeight = 0;
|
|
}
|
|
|
|
CStatusBar::~CStatusBar()
|
|
{
|
|
AllocElements(0, 0); // destroys existing elements
|
|
}
|
|
|
|
BOOL CStatusBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
|
|
{
|
|
ASSERT_VALID(pParentWnd); // must have a parent
|
|
|
|
// save the style (some of these style bits are MFC specific)
|
|
m_dwStyle = (UINT)dwStyle;
|
|
|
|
// translate MFC style bits to windows style bits
|
|
dwStyle &= ~CBRS_ALL;
|
|
dwStyle |= CCS_NOPARENTALIGN|CCS_NOMOVEY|CCS_NODIVIDER|CCS_NORESIZE;
|
|
if (pParentWnd->GetStyle() & WS_THICKFRAME)
|
|
dwStyle |= SBARS_SIZEGRIP;
|
|
|
|
// initialize common controls
|
|
VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTLS_REG));
|
|
|
|
// create the HWND
|
|
CRect rect; rect.SetRectEmpty();
|
|
return CWnd::Create(STATUSCLASSNAME, NULL, dwStyle, rect, pParentWnd, nID);
|
|
}
|
|
|
|
BOOL CStatusBar::PreCreateWindow(CREATESTRUCT& cs)
|
|
{
|
|
// in Win4, status bars do not have a border at all, since it is
|
|
// provided by the client area.
|
|
if (afxData.bWin4 &&
|
|
(m_dwStyle & (CBRS_ALIGN_ANY|CBRS_BORDER_ANY)) == CBRS_BOTTOM)
|
|
{
|
|
m_dwStyle &= ~(CBRS_BORDER_ANY|CBRS_BORDER_3D);
|
|
}
|
|
return CControlBar::PreCreateWindow(cs);
|
|
}
|
|
|
|
BOOL CStatusBar::SetIndicators(const UINT* lpIDArray, int nIDCount)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(nIDCount >= 1); // must be at least one of them
|
|
ASSERT(lpIDArray == NULL ||
|
|
AfxIsValidAddress(lpIDArray, sizeof(UINT) * nIDCount, FALSE));
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
// first allocate array for panes and copy initial data
|
|
if (!AllocElements(nIDCount, sizeof(AFX_STATUSPANE)))
|
|
return FALSE;
|
|
ASSERT(nIDCount == m_nCount);
|
|
|
|
// copy initial data from indicator array
|
|
BOOL bResult = TRUE;
|
|
if (lpIDArray != NULL)
|
|
{
|
|
HFONT hFont = (HFONT)SendMessage(WM_GETFONT);
|
|
CClientDC dcScreen(NULL);
|
|
HGDIOBJ hOldFont = NULL;
|
|
if (hFont != NULL)
|
|
hOldFont = dcScreen.SelectObject(hFont);
|
|
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(0);
|
|
for (int i = 0; i < nIDCount; i++)
|
|
{
|
|
pSBP->nID = *lpIDArray++;
|
|
pSBP->nFlags |= SBPF_UPDATE;
|
|
if (pSBP->nID != 0)
|
|
{
|
|
if (!pSBP->strText.LoadString(pSBP->nID))
|
|
{
|
|
TRACE1("Warning: failed to load indicator string 0x%04X.\n",
|
|
pSBP->nID);
|
|
bResult = FALSE;
|
|
break;
|
|
}
|
|
pSBP->cxText = dcScreen.GetTextExtent(pSBP->strText).cx;
|
|
ASSERT(pSBP->cxText >= 0);
|
|
if (!SetPaneText(i, pSBP->strText, FALSE))
|
|
{
|
|
bResult = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// no indicator (must access via index)
|
|
// default to 1/4 the screen width (first pane is stretchy)
|
|
pSBP->cxText = ::GetSystemMetrics(SM_CXSCREEN)/4;
|
|
if (i == 0)
|
|
pSBP->nStyle |= (SBPS_STRETCH | SBPS_NOBORDERS);
|
|
}
|
|
++pSBP;
|
|
}
|
|
if (hOldFont != NULL)
|
|
dcScreen.SelectObject(hOldFont);
|
|
}
|
|
UpdateAllPanes(TRUE, TRUE);
|
|
|
|
return bResult;
|
|
}
|
|
|
|
BOOL CStatusBar::AllocElements(int nElements, int cbElement)
|
|
{
|
|
// destruct old elements
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(0);
|
|
for (int i = 0; i < m_nCount; i++)
|
|
{
|
|
pSBP->strText.Empty();
|
|
++pSBP;
|
|
}
|
|
|
|
// allocate new elements
|
|
if (!CControlBar::AllocElements(nElements, cbElement))
|
|
return FALSE;
|
|
|
|
// construct new elements
|
|
pSBP = _GetPanePtr(0);
|
|
for (i = 0; i < m_nCount; i++)
|
|
{
|
|
memcpy(&pSBP->strText, &afxEmptyString, sizeof(CString));
|
|
++pSBP;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void CStatusBar::CalcInsideRect(CRect& rect, BOOL bHorz) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
ASSERT(bHorz); // vertical status bar not supported
|
|
|
|
// subtract standard CControlBar borders
|
|
CControlBar::CalcInsideRect(rect, bHorz);
|
|
|
|
// subtract size grip if present
|
|
if ((GetStyle() & SBARS_SIZEGRIP) && !::IsZoomed(::GetParent(m_hWnd)))
|
|
{
|
|
// get border metrics from common control
|
|
int rgBorders[3];
|
|
CStatusBar* pBar = (CStatusBar*)this;
|
|
pBar->DefWindowProc(SB_GETBORDERS, 0, (LPARAM)&rgBorders);
|
|
|
|
// size grip uses a border + size of scrollbar + cx border
|
|
rect.right -= rgBorders[0] + ::GetSystemMetrics(SM_CXVSCROLL) +
|
|
::GetSystemMetrics(SM_CXBORDER) * 2;
|
|
}
|
|
}
|
|
|
|
void CStatusBar::UpdateAllPanes(BOOL bUpdateRects, BOOL bUpdateText)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
// update the status pane locations
|
|
if (bUpdateRects)
|
|
{
|
|
// get border information and client work area
|
|
CRect rect; GetWindowRect(rect);
|
|
rect.OffsetRect(-rect.left, -rect.top);
|
|
CalcInsideRect(rect, TRUE);
|
|
int rgBorders[3];
|
|
VERIFY((BOOL)DefWindowProc(SB_GETBORDERS, 0, (LPARAM)&rgBorders));
|
|
|
|
// determine extra space for stretchy pane
|
|
int cxExtra = rect.Width() + rgBorders[2];
|
|
int nStretchyCount = 0;
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(0);
|
|
for (int i = 0; i < m_nCount; i++)
|
|
{
|
|
if (pSBP->nStyle & SBPS_STRETCH)
|
|
++nStretchyCount;
|
|
cxExtra -= (pSBP->cxText+CX_PANE_BORDER + rgBorders[2]);
|
|
++pSBP;
|
|
}
|
|
|
|
// determine right edge of each pane
|
|
int* rgRights = (int*)_alloca(m_nCount * sizeof(int));
|
|
int right = rgBorders[0];
|
|
pSBP = _GetPanePtr(0);
|
|
for (i = 0; i < m_nCount; i++)
|
|
{
|
|
// determine size of the pane
|
|
ASSERT(pSBP->cxText >= 0);
|
|
right += pSBP->cxText+CX_PANE_BORDER;
|
|
if ((pSBP->nStyle & SBPS_STRETCH) && cxExtra > 0)
|
|
{
|
|
ASSERT(nStretchyCount != 0);
|
|
int cxAddExtra = cxExtra / nStretchyCount;
|
|
right += cxAddExtra;
|
|
--nStretchyCount;
|
|
cxExtra -= cxAddExtra;
|
|
}
|
|
rgRights[i] = right;
|
|
|
|
// next pane
|
|
++pSBP;
|
|
right += rgBorders[2];
|
|
}
|
|
|
|
// set new right edges for all panes
|
|
DefWindowProc(SB_SETPARTS, m_nCount, (LPARAM)rgRights);
|
|
}
|
|
|
|
// update text in the status panes if specified
|
|
if (bUpdateText)
|
|
{
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(0);
|
|
for (int i = 0; i < m_nCount; i++)
|
|
{
|
|
if (pSBP->nFlags & SBPF_UPDATE)
|
|
SetPaneText(i, pSBP->strText);
|
|
++pSBP;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef AFX_CORE3_SEG
|
|
#pragma code_seg(AFX_CORE3_SEG)
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CStatusBar attribute access
|
|
|
|
int CStatusBar::CommandToIndex(UINT nIDFind) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_nCount <= 0)
|
|
return -1;
|
|
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(0);
|
|
for (int i = 0; i < m_nCount; i++, pSBP++)
|
|
if (pSBP->nID == nIDFind)
|
|
return i;
|
|
|
|
return -1;
|
|
}
|
|
|
|
UINT CStatusBar::GetItemID(int nIndex) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
return _GetPanePtr(nIndex)->nID;
|
|
}
|
|
|
|
void CStatusBar::GetItemRect(int nIndex, LPRECT lpRect) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
CStatusBar* pBar = (CStatusBar*)this;
|
|
if (!pBar->DefWindowProc(SB_GETRECT, nIndex, (LPARAM)lpRect))
|
|
::SetRectEmpty(lpRect);
|
|
}
|
|
|
|
UINT CStatusBar::GetPaneStyle(int nIndex) const
|
|
{
|
|
return _GetPanePtr(nIndex)->nStyle;
|
|
}
|
|
|
|
void CStatusBar::SetPaneStyle(int nIndex, UINT nStyle)
|
|
{
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
|
|
if (pSBP->nStyle != nStyle)
|
|
{
|
|
// use SetPaneText, since it updates the style and text
|
|
if ((pSBP->nStyle ^ nStyle) & SBPS_STRETCH)
|
|
{
|
|
pSBP->nStyle = nStyle;
|
|
UpdateAllPanes(TRUE, FALSE);
|
|
}
|
|
else
|
|
{
|
|
pSBP->nStyle = nStyle;
|
|
pSBP->nFlags |= SBPF_UPDATE;
|
|
SetPaneText(nIndex, pSBP->strText);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStatusBar::GetPaneInfo(int nIndex, UINT& nID, UINT& nStyle,
|
|
int& cxWidth) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
|
|
nID = pSBP->nID;
|
|
nStyle = pSBP->nStyle;
|
|
cxWidth = pSBP->cxText;
|
|
}
|
|
|
|
void CStatusBar::SetPaneInfo(int nIndex, UINT nID, UINT nStyle, int cxWidth)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
BOOL bChanged = FALSE;
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
|
|
pSBP->nID = nID;
|
|
if (pSBP->nStyle != nStyle)
|
|
{
|
|
if ((pSBP->nStyle ^ nStyle) & SBPS_STRETCH)
|
|
bChanged = TRUE;
|
|
else
|
|
{
|
|
pSBP->nStyle = nStyle;
|
|
pSBP->nFlags |= SBPF_UPDATE;
|
|
SetPaneText(nIndex, pSBP->strText);
|
|
}
|
|
pSBP->nStyle = nStyle;
|
|
}
|
|
if (cxWidth != pSBP->cxText)
|
|
{
|
|
// change width of one pane -> invalidate the entire status bar
|
|
pSBP->cxText = cxWidth;
|
|
bChanged = TRUE;
|
|
}
|
|
if (bChanged)
|
|
UpdateAllPanes(TRUE, FALSE);
|
|
}
|
|
|
|
void CStatusBar::GetPaneText(int nIndex, CString& s) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
|
|
s = pSBP->strText;
|
|
}
|
|
|
|
CString CStatusBar::GetPaneText(int nIndex) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
|
|
return pSBP->strText;
|
|
}
|
|
|
|
BOOL CStatusBar::SetPaneText(int nIndex, LPCTSTR lpszNewText, BOOL bUpdate)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
|
|
|
|
if (!(pSBP->nFlags & SBPF_UPDATE) &&
|
|
((lpszNewText == NULL && pSBP->strText.IsEmpty()) ||
|
|
(lpszNewText != NULL && pSBP->strText.Compare(lpszNewText) == 0)))
|
|
{
|
|
// nothing to change
|
|
return TRUE;
|
|
}
|
|
|
|
TRY
|
|
{
|
|
if (lpszNewText != NULL)
|
|
pSBP->strText = lpszNewText;
|
|
else
|
|
pSBP->strText.Empty();
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// Note: DELETE_EXCEPTION(e) not required
|
|
return FALSE;
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
if (!bUpdate)
|
|
{
|
|
// can't update now, wait until later
|
|
pSBP->nFlags |= SBPF_UPDATE;
|
|
return TRUE;
|
|
}
|
|
|
|
pSBP->nFlags &= ~SBPF_UPDATE;
|
|
DefWindowProc(SB_SETTEXT, ((WORD)pSBP->nStyle)|nIndex,
|
|
(pSBP->nStyle & SBPS_DISABLED) ? NULL :
|
|
(LPARAM)(LPCTSTR)pSBP->strText);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CStatusBar implementation
|
|
|
|
CSize CStatusBar::CalcFixedLayout(BOOL, BOOL bHorz)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
// determinme size of font being used by the status bar
|
|
TEXTMETRIC tm;
|
|
{
|
|
CClientDC dc(NULL);
|
|
HFONT hFont = (HFONT)SendMessage(WM_GETFONT);
|
|
HGDIOBJ hOldFont = NULL;
|
|
if (hFont != NULL)
|
|
hOldFont = dc.SelectObject(hFont);
|
|
VERIFY(dc.GetTextMetrics(&tm));
|
|
if (hOldFont != NULL)
|
|
dc.SelectObject(hOldFont);
|
|
}
|
|
|
|
// get border information
|
|
CRect rect; rect.SetRectEmpty();
|
|
CalcInsideRect(rect, bHorz);
|
|
int rgBorders[3];
|
|
DefWindowProc(SB_GETBORDERS, 0, (LPARAM)&rgBorders);
|
|
|
|
// determine size, including borders
|
|
CSize size;
|
|
size.cx = 32767;
|
|
size.cy = tm.tmHeight - tm.tmInternalLeading - 1
|
|
+ rgBorders[1] * 2 + ::GetSystemMetrics(SM_CYBORDER) * 2
|
|
- rect.Height();
|
|
if (size.cy < m_nMinHeight)
|
|
size.cy = m_nMinHeight;
|
|
|
|
return size;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CStatusBar message handlers
|
|
|
|
BEGIN_MESSAGE_MAP(CStatusBar, CControlBar)
|
|
//{{AFX_MSG_MAP(CStatusBar)
|
|
ON_WM_NCHITTEST()
|
|
ON_WM_NCPAINT()
|
|
ON_WM_PAINT()
|
|
ON_WM_NCCALCSIZE()
|
|
ON_WM_SIZE()
|
|
ON_WM_WINDOWPOSCHANGING()
|
|
ON_MESSAGE(WM_SETTEXT, OnSetText)
|
|
ON_MESSAGE(WM_GETTEXT, OnGetText)
|
|
ON_MESSAGE(WM_GETTEXTLENGTH, OnGetTextLength)
|
|
ON_MESSAGE(SB_SETMINHEIGHT, OnSetMinHeight)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
UINT CStatusBar::OnNcHitTest(CPoint)
|
|
{
|
|
UINT nResult = (UINT)Default();
|
|
if (nResult == HTBOTTOMRIGHT)
|
|
return HTBOTTOMRIGHT;
|
|
else
|
|
return HTCLIENT;
|
|
}
|
|
|
|
void CStatusBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* lpncsp)
|
|
{
|
|
// calculate border space (will add to top/bottom, subtract from right/bottom)
|
|
CRect rect; rect.SetRectEmpty();
|
|
CControlBar::CalcInsideRect(rect, TRUE);
|
|
ASSERT(rect.top >= 2);
|
|
|
|
// adjust non-client area for border space
|
|
lpncsp->rgrc[0].left += rect.left;
|
|
lpncsp->rgrc[0].top += rect.top - 2;
|
|
lpncsp->rgrc[0].right += rect.right;
|
|
lpncsp->rgrc[0].bottom += rect.bottom;
|
|
}
|
|
|
|
void CStatusBar::OnBarStyleChange(DWORD dwOldStyle, DWORD dwNewStyle)
|
|
{
|
|
if (m_hWnd != NULL &&
|
|
((dwOldStyle & CBRS_BORDER_ANY) != (dwNewStyle & CBRS_BORDER_ANY)))
|
|
{
|
|
// recalc non-client area when border styles change
|
|
SetWindowPos(NULL, 0, 0, 0, 0,
|
|
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_DRAWFRAME);
|
|
}
|
|
}
|
|
|
|
void CStatusBar::OnNcPaint()
|
|
{
|
|
EraseNonClient();
|
|
}
|
|
|
|
// Derived class is responsible for implementing all of these handlers
|
|
// for owner/self draw controls.
|
|
void CStatusBar::DrawItem(LPDRAWITEMSTRUCT)
|
|
{
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
BOOL CStatusBar::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
|
{
|
|
if (message != WM_DRAWITEM)
|
|
return CWnd::OnChildNotify(message, wParam, lParam, pResult);
|
|
|
|
ASSERT(pResult == NULL);
|
|
UNUSED(pResult); // unused in release builds
|
|
DrawItem((LPDRAWITEMSTRUCT)lParam);
|
|
return TRUE;
|
|
}
|
|
|
|
void CStatusBar::OnPaint()
|
|
{
|
|
UpdateAllPanes(FALSE, TRUE);
|
|
|
|
Default();
|
|
}
|
|
|
|
void CStatusBar::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
CControlBar::OnSize(nType, cx, cy);
|
|
|
|
// need to adjust pane right edges (because of stretchy pane)
|
|
UpdateAllPanes(TRUE, FALSE);
|
|
}
|
|
|
|
void CStatusBar::OnWindowPosChanging(LPWINDOWPOS lpWndPos)
|
|
{
|
|
// not necessary to invalidate the borders
|
|
DWORD dwStyle = m_dwStyle;
|
|
m_dwStyle &= ~(CBRS_BORDER_ANY);
|
|
CControlBar::OnWindowPosChanging(lpWndPos);
|
|
m_dwStyle = dwStyle;
|
|
}
|
|
|
|
LRESULT CStatusBar::OnSetText(WPARAM, LPARAM lParam)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
int nIndex = CommandToIndex(0);
|
|
if (nIndex < 0)
|
|
return -1;
|
|
return SetPaneText(nIndex, (LPCTSTR)lParam) ? 0 : -1;
|
|
}
|
|
|
|
LRESULT CStatusBar::OnGetText(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
int nMaxLen = (int)wParam;
|
|
if (nMaxLen == 0)
|
|
return 0; // nothing copied
|
|
LPTSTR lpszDest = (LPTSTR)lParam;
|
|
|
|
int nLen = 0;
|
|
int nIndex = CommandToIndex(0); // use pane with ID zero
|
|
if (nIndex >= 0)
|
|
{
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
|
|
nLen = pSBP->strText.GetLength();
|
|
if (nLen > nMaxLen)
|
|
nLen = nMaxLen - 1; // number of characters to copy (less term.)
|
|
memcpy(lpszDest, (LPCTSTR)pSBP->strText, nLen*sizeof(TCHAR));
|
|
}
|
|
lpszDest[nLen] = '\0';
|
|
return nLen+1; // number of bytes copied
|
|
}
|
|
|
|
LRESULT CStatusBar::OnGetTextLength(WPARAM, LPARAM)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
int nLen = 0;
|
|
int nIndex = CommandToIndex(0); // use pane with ID zero
|
|
if (nIndex >= 0)
|
|
{
|
|
AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
|
|
nLen = pSBP->strText.GetLength();
|
|
}
|
|
return nLen;
|
|
}
|
|
|
|
LRESULT CStatusBar::OnSetMinHeight(WPARAM wParam, LPARAM)
|
|
{
|
|
LRESULT lResult = Default();
|
|
if (lResult)
|
|
m_nMinHeight = wParam;
|
|
return lResult;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CStatusBar idle update through CStatusCmdUI class
|
|
|
|
class CStatusCmdUI : public CCmdUI // class private to this file!
|
|
{
|
|
public: // re-implementations only
|
|
virtual void Enable(BOOL bOn);
|
|
virtual void SetCheck(int nCheck);
|
|
virtual void SetText(LPCTSTR lpszText);
|
|
};
|
|
|
|
void CStatusCmdUI::Enable(BOOL bOn)
|
|
{
|
|
m_bEnableChanged = TRUE;
|
|
CStatusBar* pStatusBar = (CStatusBar*)m_pOther;
|
|
ASSERT(pStatusBar != NULL);
|
|
ASSERT_KINDOF(CStatusBar, pStatusBar);
|
|
ASSERT(m_nIndex < m_nIndexMax);
|
|
|
|
UINT nNewStyle = pStatusBar->GetPaneStyle(m_nIndex) & ~SBPS_DISABLED;
|
|
if (!bOn)
|
|
nNewStyle |= SBPS_DISABLED;
|
|
pStatusBar->SetPaneStyle(m_nIndex, nNewStyle);
|
|
}
|
|
|
|
void CStatusCmdUI::SetCheck(int nCheck) // "checking" will pop out the text
|
|
{
|
|
CStatusBar* pStatusBar = (CStatusBar*)m_pOther;
|
|
ASSERT(pStatusBar != NULL);
|
|
ASSERT_KINDOF(CStatusBar, pStatusBar);
|
|
ASSERT(m_nIndex < m_nIndexMax);
|
|
|
|
UINT nNewStyle = pStatusBar->GetPaneStyle(m_nIndex) & ~SBPS_POPOUT;
|
|
if (nCheck != 0)
|
|
nNewStyle |= SBPS_POPOUT;
|
|
pStatusBar->SetPaneStyle(m_nIndex, nNewStyle);
|
|
}
|
|
|
|
void CStatusCmdUI::SetText(LPCTSTR lpszText)
|
|
{
|
|
CStatusBar* pStatusBar = (CStatusBar*)m_pOther;
|
|
ASSERT(pStatusBar != NULL);
|
|
ASSERT_KINDOF(CStatusBar, pStatusBar);
|
|
ASSERT(m_nIndex < m_nIndexMax);
|
|
|
|
pStatusBar->SetPaneText(m_nIndex, lpszText);
|
|
}
|
|
|
|
void CStatusBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
|
|
{
|
|
CStatusCmdUI state;
|
|
state.m_pOther = this;
|
|
state.m_nIndexMax = (UINT)m_nCount;
|
|
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
|
|
state.m_nIndex++)
|
|
{
|
|
state.m_nID = _GetPanePtr(state.m_nIndex)->nID;
|
|
|
|
// allow the statusbar itself to have update handlers
|
|
if (CWnd::OnCmdMsg(state.m_nID, CN_UPDATE_COMMAND_UI, &state, NULL))
|
|
continue;
|
|
|
|
// allow target (owner) to handle the remaining updates
|
|
state.DoUpdate(pTarget, FALSE);
|
|
}
|
|
|
|
// update the dialog controls added to the status bar
|
|
UpdateDialogControls(pTarget, bDisableIfNoHndler);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CStatusBar diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CStatusBar::AssertValid() const
|
|
{
|
|
CControlBar::AssertValid();
|
|
}
|
|
|
|
void CStatusBar::Dump(CDumpContext& dc) const
|
|
{
|
|
CControlBar::Dump(dc);
|
|
|
|
if (dc.GetDepth() > 0)
|
|
{
|
|
for (int i = 0; i < m_nCount; i++)
|
|
{
|
|
dc << "\nstatus pane[" << i << "] = {";
|
|
dc << "\n\tnID = " << _GetPanePtr(i)->nID;
|
|
dc << "\n\tnStyle = " << _GetPanePtr(i)->nStyle;
|
|
dc << "\n\tcxText = " << _GetPanePtr(i)->cxText;
|
|
dc << "\n\tstrText = " << _GetPanePtr(i)->strText;
|
|
dc << "\n\t}";
|
|
}
|
|
}
|
|
dc << "\n";
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
#ifdef AFX_INIT_SEG
|
|
#pragma code_seg(AFX_INIT_SEG)
|
|
#endif
|
|
|
|
IMPLEMENT_DYNAMIC(CStatusBar, CControlBar)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|