📄 ngstatusbar.cpp
字号:
int CNGStatusBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CStatusBar::OnCreate(lpCreateStruct) == -1)
return -1;
CStatusBarCtrl & rCtrl = GetStatusBarCtrl();
rCtrl.SetMinHeight(22);
m_ToolTip.Create(this, TTS_ALWAYSTIP );
m_ToolTip.SetDelayTime(250); //delay before tip appears
m_ToolTip.SetDelayTime(4000, TTDT_AUTOPOP); // linger time once tip is up
m_IconImageList.Create(16,16,ILC_MASK|ILC_COLOR, 0, 1);
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// PreTranslateMessage() - standard handler.
BOOL CNGStatusBar::PreTranslateMessage(MSG* pMsg)
{
// Because modal dialogs will cause all CToolTipCtrls to get deactivated,
// the tool tip control needs to be manually reactivated.
// TT 3 TT Step 6
m_ToolTip.Activate(TRUE);
// RelayEvent is required for CToolTipCtrl objects -
// it passes mouse messages on to the tool tip control
// so it can decide when to show the tool tip
// TT 3 TT Step 4
m_ToolTip.RelayEvent(pMsg);
return CStatusBar::PreTranslateMessage(pMsg);
}
/*****************************************************************************
* Klasse: CNGStatusBar
* Funktion: CreateStatusBar
* Parameter: lpIDArray Array mit den ID's der einzelnen Panes
* nIDCount Anzahl der Panes in der Statuszeile
* pane0Style Zusatzstyle f黵 Pane 0 (normalerweise SBPS_STRETCH)
* Return: true wenn die Erzeugung erfolgreich war, sonst false
*
* Produces a status line at the lower edge of window. Here all necessary steps
* in a function are united: Produce the Toolbar, define the individual Panes,
* possibly a changing of the 0-Panes over.
****************************************************************************/
bool CNGStatusBar::CreateStatusBar(CWnd *pWnd, const UINT* lpIDArray, int nIDCount, UINT pane0Style)
{
bool ret = (Create(pParent = pWnd) &&
SetIndicators(lpIDArray, nIDCount));
if (ret) SetStyle(0, pane0Style);
else AfxMessageBox("Unable to create Statusbar.");
return ret;
}
/*****************************************************************************
* Klasse: CNGStatusBar
* Funktion: SetIndicators
* Parameter: lpIDArray
* nIDCount
* Return: BOOL
*
* This (overridden) function produces the einzlenen Panes and defines then
* for each Pane a CNGStatusBarPaneInfo variable in a list. Additionally a timer defined
* for scrolling.
****************************************************************************/
BOOL CNGStatusBar::SetIndicators(const UINT* lpIDArray, int nIDCount)
{
CNGStatusBarPaneInfo defaultInfo;
paneInfo.RemoveAll();
paneInfo.SetSize(nIDCount);
for (int i = 0; i < nIDCount; i++)
paneInfo[i] = defaultInfo;
BOOL ret = CStatusBar::SetIndicators(lpIDArray, nIDCount);
return ret;
}
/*****************************************************************************
* Klasse: CNGStatusBar
* Funktion: OnPaint
* Parameter: -
* Return: -
*
* Here the actual status line is produced. For this first the background is
* deleted and drawn then on each Pane a 3D-Rechteck and output the information.
* Over flickering the picture to avoid takes place the entire output first in
* a MemoryDC and into the actual PaintDC is only then copied.
****************************************************************************/
void CNGStatusBar::OnPaint()
{
CPaintDC dc(this);
CRect client;
GetClientRect(client);
CDC memDC;
memDC.CreateCompatibleDC(&dc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc, client.Width(), client.Height());
CBitmap *oldBitmap = (CBitmap *) memDC.SelectObject(&bitmap);
COLORREF hell = GetSysColor(COLOR_3DHILIGHT);
COLORREF dunkel = GetSysColor(COLOR_3DSHADOW);
memDC.FillSolidRect(client, GetSysColor(COLOR_3DFACE));
//========================================================================
// Zeichne alle Pane-Rechtecke mit ihrem Inhalt
//========================================================================
bool scroll = false;
for (int i = 0, n = paneInfo.GetSize(); i < n; i++)
{
CNGStatusBarPaneInfo &aktPane = paneInfo[i];
CRect rect;
GetItemRect(i, rect);
UINT style = GetPaneStyle(i);
if (style & SBPS_POPOUT)
memDC.Draw3dRect(rect, hell, dunkel);
else if (!(style & SBPS_NOBORDERS))
memDC.Draw3dRect(rect, dunkel, hell);
on = (GetPaneStyle(i) & SBPS_DISABLED) == 0;
rect.DeflateRect(1, 1);
memDC.FillSolidRect(rect, aktPane.GetBkColor(on));
CRgn clip;
clip.CreateRectRgnIndirect(&rect);
memDC.SelectClipRgn(&clip);
rect.DeflateRect(1,1);
switch (aktPane.GetMode() & XSB_MODE)
{
case XSB_TEXT:
case XSB_NUMBER:
DrawTextPane( &memDC, i, rect, aktPane);
break;
case XSB_BITMAP:
DrawBitmapPane( &memDC, i, rect, aktPane);
break;
case XSB_ICON_AND_TEXT:
DrawIconAndText( &memDC, i, rect, aktPane);
break;
case XSB_PROGRESS:
DrawProgressPane(&memDC, i, rect, aktPane);
break;
default:
break;
}
if (aktPane.GetMode() & XSB_SCROLL) scroll = true;
memDC.SelectClipRgn(NULL);
}
if (scroll && (timerID == 0))
{
timerID = SetTimer(IDC_JRLIB_STATUSBAR_TIMER, 100, NULL);
}
else if (!scroll && (timerID != 0))
{
KillTimer(timerID);
timerID = 0;
}
if (!GetParent()->IsZoomed())
{
DrawSizing(&memDC);
}
dc.BitBlt(0, 0, client.Width(), client.Height(), &memDC, 0, 0, SRCCOPY);
memDC.SelectObject(oldBitmap);
}
/*****************************************************************************
* Klasse: CNGStatusBar
* Funktion: DrawSizing
* Parameter: pDC aktueller Device-Kstring[1]
* Return: -
*
* This function draws the diagonal lines at the right, lower edge of window.
****************************************************************************/
void CNGStatusBar::DrawSizing(CDC *pDC)
{
CRect rect;
GetWindowRect(&rect);
rect.OffsetRect(-rect.left, -rect.top);
CPen hellPen(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
CPen dunkelPen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
CPen *oldPen = pDC->SelectObject(&dunkelPen);
for (int i = 1; i < 16; i++)
{
switch (i % 4)
{
case 0:
pDC->SelectObject(&dunkelPen);
break;
case 1:
pDC->SelectObject(&hellPen);
break;
case 2:
continue;
case 3:
pDC->SelectObject(&dunkelPen);
break;
}
CPoint from(rect.right-1 - i, rect.bottom-1);
CPoint to(rect.right-1, rect.bottom-1 - i);
pDC->MoveTo(from);
pDC->LineTo(to);
}
pDC->SelectObject(oldPen);
}
/*****************************************************************************
* Klasse: CNGStatusBar
* Funktion: DrawTextPane
* Parameter: pDC Aktueller Device-Kstring[1]
* ix Index des aktuellen Panes
* rect Bounding Rectangle des aktuellen Panes
* aktPane Aktueller Pane
* Return: -
*
* Outputs a text in a Pane. If required, can this text in horizontal and/or
* vertical direction are gescrollt or aligned left, on the right or centered.
* With the Scrollen several copies of the text secondary or one above the other
* can be set, so that a continuous movement develops.
****************************************************************************/
void CNGStatusBar::DrawTextPane(CDC *pDC, int ix, CRect& rect, CNGStatusBarPaneInfo& aktPane)
{
CString text = aktPane.GetText(on);
if (text.IsEmpty())
text = GetPaneText(ix);
if (text.IsEmpty())
return;
CFont font;
font.CreateFontIndirect(&aktPane.GetFont());
COLORREF textColor = aktPane.GetFgColor(on);
CFont *oldFont = pDC->SelectObject(&font);
int oldBkMode = pDC->SetBkMode(TRANSPARENT);
COLORREF oldFgColor = pDC->SetTextColor(textColor);
const int mode = aktPane.GetMode();
const int repeat = mode & XSB_REPEAT;
const int hScroll = mode & XSB_HSCROLL;
const int vScroll = mode & XSB_VSCROLL;
int textAlign = mode & XSB_ALIGN;
if (hScroll)
textAlign &= ~(DT_CENTER | DT_RIGHT);
if (repeat)
{
text += " ";
CSize s = pDC->GetTextExtent(text);
if (hScroll)
aktPane.HScroll(rect, s.cx, 1);
if (vScroll)
aktPane.VScroll(rect, s.cy, 1);
int y = rect.top;
if (hScroll && vScroll)
{
for ( ; rect.left <= rect.right; rect.left += s.cx)
{
for (rect.top = y ; rect.top <= rect.bottom; rect.top += s.cy)
{
pDC->DrawText(text, rect, textAlign);
}
}
}
else if (hScroll)
{
for ( ; rect.left <= rect.right; rect.left += s.cx)
{
pDC->DrawText(text, rect, textAlign);
}
}
else if (vScroll)
{
for ( ; rect.top <= rect.bottom; rect.top += s.cy)
{
pDC->DrawText(text, rect, textAlign);
}
}
else
{
pDC->DrawText(text, rect, textAlign);
}
}
else
{
CSize s = pDC->GetTextExtent(text);
if (hScroll)
aktPane.HScroll(rect, s.cx, -rect.Width());
if (vScroll)
aktPane.VScroll(rect, s.cy, -rect.Height());
pDC->DrawText(text, rect, textAlign);
}
pDC->SelectObject(oldFont);
pDC->SetTextColor(oldFgColor);
pDC->SetBkMode(oldBkMode);
}
/*****************************************************************************
* Klasse: CNGStatusBar
* Funktion: DrawIconAndText
* Parameter: pDC Aktueller Device-Kstring[1]
* ix Index des aktuellen Panes
* rect Bounding Rectangle des aktuellen Panes
* aktPane Aktueller Pane
* Return: -
*
* Outputs icon and text in a Pane.
****************************************************************************/
void CNGStatusBar::DrawIconAndText(CDC *pDC, int ix, CRect& rect, CNGStatusBarPaneInfo& aktPane)
{
CSize iconSize(16,16);
int nIndex = m_IconImageList.AddIcon(aktPane.GetIcon());
m_IconImageList.Draw(pDC, nIndex, rect.TopLeft(), ILD_NORMAL|ILD_TRANSPARENT);
rect.left += iconSize.cx + 3;
//::DestroyIcon(hIcon);
CString text = aktPane.GetIconText();
if (text.IsEmpty())
{
text = GetPaneText(ix);
}
if (!text.IsEmpty())
{
CFont font;
font.CreateFontIndirect(&aktPane.GetFont());
COLORREF textColor = aktPane.GetFgColor(on);
const int mode = aktPane.GetMode();
CFont *oldFont = pDC->SelectObject(&font);
int oldBkMode = pDC->SetBkMode(TRANSPARENT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -