Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Resource ID Organiser Add-In for Visual C++ 5.0/6.0/.NET

, 10 Jan 2005
An application/add-in to organise and renumber resource symbol IDs
resorg103.zip
resorg104.zip
resorgaddinsetup.zip
resorgaddin_executables.zip
resorgnetaddinsetup.zip
resorgnetaddin_executables.zip
resorgnet_executables.zip
ResOrgNET_executables
CJ609LibVc7.dll
NGLib103Vc7.dll
QHTMLight.dll
ResOrg.cnt
resorg.fts
ResOrg.hlp
ResOrgNETAddIn.dll
ResOrgNETAddInToolWindows.ocx
ResOrgNETCore.dll
resorg_demo.zip
resorg_executables.zip
resorg_src.zip
BXFileDialog
BXFileDialog.dsp
Lib
Release
Res
bitmap2.bmp
FileOpen.bmp
filesave.bmp
CJLibrary
CJLibrary
CJLibrary.def
CJLibrary.dsp
CJLibrary.dsw
CJLibrarydep.jpg
CJLibraryStatic.dsp
Debug_Unicode
Release
Release_Unicode
res
Include
res
btn_arro.bmp
btn_explorer.bmp
button_images.bmp
cj_logo.bmp
dragging.cur
handcur.cur
headerba.bmp
hsplitba.cur
icr_hand.cur
nodraggi.cur
PushPin.bmp
Toolbar.bmp
vsplitba.cur
Lib
NGLibrary
Bin
NGLibrary.def
NGLibrary.dsp
NGLibrary.dsw
Release
Res
Drives.bmp
Release
ResOrgAddIn
Release
Res
HtmlDoc.ico
ResOrg.ico
ResOrgDoc.ico
TBarLrge.bmp
TBarMedm.bmp
Toolbar.bmp
WorkspaceTabs.bmp
ResOrgAddIn.def
ResOrgAddIn.dsp
ResOrgAddIn.odl
ResOrgAddIn_Res.hm
ResOrgApp
Lint
Release
Res
HtmlDoc.ico
MAINFRAM.BMP
ResOrg.ico
ResOrgDoc.ico
TBarLrge.bmp
TBarMedm.bmp
Toolbar.bmp
workspace.ico
WorkspaceTabs.bmp
ResOrgApp.dsp
ResOrgApp_Res.hm
ResOrgApp_Res.resorg
ResOrgCore
Lint
Release
Res
Anna.bmp
BuildOptions.ico
ComCtl Version Prompt.rtf
File Reload Warning Ex.rtf
File Reload Warning.rtf
Global Next Symbol Value Warning Prompt.rtf
information.ico
Invalid Symbol Name.rtf
Mailing List Prompt.rtf
Next Symbol Value Warning Prompt.rtf
project context menu.bmp
project.ico
RenumWiz Completion.rtf
Report.ico
ResOrg Logo.bmp
ResOrg Updated.rtf
ResOrg.ico
resource file.ico
riverblade_logo.bmp
solution.ico
Symbol Delete Warning.rtf
Symbol Name Warning.rtf
Symbol Rename Warning.rtf
SymbolFile.ico
Symbols Delete Warning.rtf
sym_binary.ico
sym_bitmap.ico
sym_command.ico
sym_control.ico
sym_dialog.ico
sym_icon.ico
sym_menu.ico
sym_prompt.ico
sym_resource.ico
sym_string.ico
Toolbar.bmp
VcAddIn.ico
VersionCheck.ico
warning.ico
WizardHeader256.bmp
WizardWatermark256.bmp
ResOrgCore.def
ResOrgCore.dsp
ResOrgCore_Res.hm
ResOrgCore_Res.resorg
Xml
ProblemSymbolReportHtml.xsl
SymbolsReportHtml.xsl
ResOrgNETAddIn
AddIn.def
Release
Res
AddIn.rgs
HtmlDoc.ico
ResOrg.ico
ResOrgDoc.ico
Toolbar.bmp
WorkspaceTabs.bmp
ResOrgNETAddInSetup
Banner.jpg
Intro screen.jpg
Licence.rtf
ReadMe.rtf
Release
ResOrg.ico
ResOrgNETAddInSetup.vdproj
ResOrgNETAddInToolWindows
Release
Res
Edit.ico
Properties.ico
Renumber.ico
ResOrgNETAddInToolWindows.ico
ResOrgNETAddInToolWindowsCtrl.bmp
ResOrgNETAddInToolWindows.def
SatelliteDll
Release
res
AboutBoxCmd.bmp
OpenResOrgCmd.bmp
OptionsCmd.bmp
ViewMainToolWinCmd.bmp
/*****************************************************************************
 *
 * Class:			CNGStatusBarPaneInfo, CNGStatusBar
 * Files:			CNGStatusBar.Cpp, CNGStatusBar.H
 * Description:	With this class complex status lines can be administered. 
 *					So can be represented in each Pane texts, bit-maps or 
 *					progress Bars, be gescrollt horizontal, vertically or diagonally 
 *					and be aligned left, on the right or centered. Also each time 
 *					between the individual modes can be shifted up and down. 
 *					For each Pane can be defined both switching on on and a switching 
 *					off text, - background or - bit-map. 
 *					
 * Functions:		operator=(), SetDefault(), SetFont(), SetMode(), 
 * (CNGStatusBarPaneInfo)		SetFgColor(), SetBkColor(), SetBitmap(), SetText(), 
 *					SetNumber(), HScroll(), VScroll(), 
 * Functions:		CreateStatusBar(), SetIndicators(), OnPaint(), 
 * (CNGStatusBar)		DrawSizing(), DrawTextPane(), DrawBitmapPane(), 
 *					DrawProgressPane(), GetCNGStatusBarPaneInfo(), OnTimer(), 
 *					SetStyle(), SetWidth(), GetStyle(), GetWidth(), GetID(), 
 *					OnDestroy(), SavePane(), RestorePane(), 
 *					GetPaneAtPosition(), OnMouseMove(),
 *					OnLButtonUp(), OnMButtonUp(), OnRButtonUp(), 
 *					OnLButtonDown(), OnMButtonDown(), OnRButtonDown(),
 *					OnLButtonDblClk(), OnMButtonDblClk(), OnRButtonDblClk(),
 *
 ****************************************************************************/

#include "StdAfx.h"
#include "NGStatusBar.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

volatile static char jrrcid[] = "%J%";

#define IDC_JRLIB_STATUSBAR_TIMER	20000

/*****************************************************************************
 * Klasse:		CNGStatusBarPaneInfo
 * Funktion:	CNGStatusBarPaneInfo, ~CNGStatusBarPaneInfo
 * Parameter:	-
 * Return:		
 *
 * The constructor initialize a Pane. In the Desturktor a possibly 
 * available progress check is again deleted. 
 * 
 ****************************************************************************/
CNGStatusBarPaneInfo::CNGStatusBarPaneInfo()
{
	progress	= NULL;
	hScrollPos	= 0;
	vScrollPos	= 0;

	SetDefault();
}

CNGStatusBarPaneInfo::CNGStatusBarPaneInfo(const CNGStatusBarPaneInfo& paneInfo)
{
	for (int i = 0; i < 2; i++)
	{
		fgColor[i]	= paneInfo.fgColor[i];
		bkColor[i]	= paneInfo.bkColor[i];
		string[i]	= paneInfo.string[i];
	}

	font			= paneInfo.font;
	mode			= paneInfo.mode;
	progress		= NULL;
	hScrollPos		= paneInfo.hScrollPos;
	vScrollPos		= paneInfo.vScrollPos;
}

CNGStatusBarPaneInfo::~CNGStatusBarPaneInfo()
{
	if (progress)	delete progress;
	progress = NULL;
}

/*****************************************************************************
 * Klasse:		CNGStatusBarPaneInfo
 * Funktion:	operator=
 * Parameter:	paneInfo	Zweites CNGStatusBarPaneInfo-Element, dessen Informationen
 *							kopiert werden.
 * Return:		Kopie des CNGStatusBarPaneInfo-Elements
 *
 * Allocation operator!!! NOTE!!! ' progress ' is not copied! Possibly
 * available progress bar one deletes 
 * 
 * 
 ****************************************************************************/
CNGStatusBarPaneInfo CNGStatusBarPaneInfo::operator=(const CNGStatusBarPaneInfo& paneInfo)
{
	for (int i = 0; i < 2; i++)
	{
		fgColor[i]	= paneInfo.fgColor[i];
		bkColor[i]	= paneInfo.bkColor[i];
		string[i]	= paneInfo.string[i];
	}

	font			= paneInfo.font;
	mode			= paneInfo.mode;
	hScrollPos		= paneInfo.hScrollPos;
	vScrollPos		= paneInfo.vScrollPos;

	if (progress)	delete progress;
	progress = NULL;

	return *this;
}

/*****************************************************************************
 * Klasse:		CNGStatusBarPaneInfo
 * Funktion:	SetDefault
 * Parameter:	-
 * Return:		-
 *
 * Here the Members is initialized
 ****************************************************************************/
void CNGStatusBarPaneInfo::SetDefault()
{
	bkColor[1]	= COLORREF(GetSysColor(COLOR_3DFACE));
	bkColor[0]	= bkColor[1];

	fgColor[1]	= GetSysColor(COLOR_BTNTEXT);
	fgColor[0]	= RGB(GetRValue(bkColor[1])/2, GetGValue(bkColor[1])/2, GetBValue(bkColor[1])/2);

	mode		= XSB_TEXT | DT_LEFT;
	SetFont(CFont::FromHandle((HFONT) GetStockObject(ANSI_VAR_FONT)));

	if (progress)	delete progress;
	progress = NULL;
}

/*****************************************************************************
 * Klasse:		CNGStatusBarPaneInfo
 * Funktion:	SetFont
 * Parameter:	name	Name der Schriftart (Bsp.: Arial)
 *				size	Gr��e der Schriftart in 1/10 Pt (Bsp.: 120)
 * Return:		-
 * 
 * The Font for a Pane sets on the basis the font name and the point size 
 * (10 * Point).
 ****************************************************************************/
void CNGStatusBarPaneInfo::SetFont(LPCSTR name, int size)
{
	CFont pointFont;
	pointFont.CreatePointFont(size, name);
	pointFont.GetLogFont(&font);
}

/*****************************************************************************
 * Klasse:		CNGStatusBarPaneInfo
 * Funktion:	SetMode
 * Parameter:	newMode		Neuer Anzeigemodus
 * Return:		-
 * 
 * Sets the mode for the current Pane. If this Pane were filled with progress 
 * CTRL before, this is deleted before.  
 * 
 ****************************************************************************/
void CNGStatusBarPaneInfo::SetMode(int newMode)
{
	if ((mode = newMode) & XSB_PROGRESS)
	{
		if (!progress)
		{
			UINT style = WS_VISIBLE | WS_CHILD;
			if (mode & XSB_SMOOTH) style |= PBS_SMOOTH;

			progress = new CProgressCtrl();
			progress->Create(style, CRect(0,0,0,0), CNGStatusBar::aktBar, 1);
		}
	}
	else if (progress)
	{
		delete progress;
		progress = NULL;
	}
}

/*****************************************************************************
 * Klasse:		CNGStatusBarPaneInfo
 * Funktion:	SetFgColor
 * Parameter:	on		Text-Farbe im aktiven Zustand
 *				off		Text-Farbe im inaktiven Zustand
 * Return:		-
 *
 * Defines the colours for a displayed text. Here two colours for the active 
 * and the inactive status can be defined. If the second colour is forgotten, 
 * it is pre-defined with the half intensity of the background colour. 
 ****************************************************************************/
void CNGStatusBarPaneInfo::SetFgColor(COLORREF on, COLORREF off)
{
	fgColor[1] = on;

	if (off != -1)
		fgColor[0] = off;
	else
	{
		COLORREF bk = GetSysColor(COLOR_3DFACE);
		fgColor[0] = RGB(GetRValue(bk)/2, GetGValue(bk)/2, GetBValue(bk)/2);
	}
}

/*****************************************************************************
 * Klasse:		CNGStatusBarPaneInfo
 * Funktion:	SetBkColor
 * Parameter:	on		Hintergrundfarbe im aktiven Zustand
 *				off		Hintergrundfarbe im inaktiven Zustand
 * Return:		-
 *
 * Defines the background colours for a displayed text. Here two colours for 
 * the active and the inactive status can be defined. If the second colour is 
 * forgotten, it is pre-defined with the background colour. 
 ****************************************************************************/
void CNGStatusBarPaneInfo::SetBkColor(COLORREF on, COLORREF off)
{
	bkColor[1] = on;
	if (off != -1)	bkColor[0] = off;
	else			bkColor[0] = GetSysColor(COLOR_3DFACE);
}

/*****************************************************************************
 * Klasse:		CNGStatusBarPaneInfo
 * Funktion:	SetBitmap, SetText, SetNumber
 * Parameter:	newBitmap		Name des im Pane anzuzeigenden Bitmaps
 *				newText			Im Pane anzuzeigender Text
 *				newNumber		Im Pane anzuzeigende Nummer
 * Return:		-
 *
 * With these functions the bit-maps, texts or numbers for the display
 * in the current Pane are set. 
 ****************************************************************************/
void CNGStatusBarPaneInfo::SetBitmap(LPCSTR newOnBitmap, LPCSTR newOffBitmap)
{
	string[1]	= newOnBitmap;
	string[0]	= newOffBitmap;
}

void CNGStatusBarPaneInfo::SetText(LPCSTR newOnText, LPCSTR newOffText)
{
	string[1]	= newOnText;
	string[0]	= newOffText;
}

void CNGStatusBarPaneInfo::SetIconAndText(DWORD iconResourceID, LPCSTR text)
{
	string[1].Format("%d", iconResourceID);
	string[0]	= text;
}

void CNGStatusBarPaneInfo::SetNumber(int newOnNumber, int newOffNumber)
{
	string[1].Format("%d", newOnNumber);
	string[0].Format("%d", newOffNumber);
}

/*****************************************************************************
 * Klasse:		CNGStatusBarPaneInfo
 * Funktion:	HScroll, VScroll
 * Parameter:	rect			Ausgaberechteck des aktuellen Panes
 *				maxWidth		Maximale Breite, bzw. H�he beim Scrollen
 *				maxHeight		(z. B. Textl�nge oder Bitmapbreite)
 *				nullValue		Wert f�r Turnaround
 * Return:		-
 *
 * Increments the respective Scrollvariable, so that the text or the bit-map 
 * of the current Panes is gescrollt represented. If the max. size is exceeded, 
 * the scrolling begins again from the front. 
 ****************************************************************************/
void CNGStatusBarPaneInfo::HScroll(CRect& rect, int maxWidth, int nullValue)
{
	if (++hScrollPos > maxWidth)	hScrollPos = nullValue;
	rect.left -= hScrollPos;
}

void CNGStatusBarPaneInfo::VScroll(CRect& rect, int maxHeight, int nullValue)
{
	if (++vScrollPos > maxHeight)	vScrollPos = nullValue;
	rect.top -= vScrollPos;
}

/*****************************************************************************
 * Klasse:		CNGStatusBarPaneInfo
 * Funktion:	Dump, AssertValid, operator<<
 * Parameter:	dc			CDumpContext
 *				paneInfo	Ausgabelement
 * Return:		-
 *
 * 
 * 
 * 
 ****************************************************************************/
#ifdef _DEBUG
void CNGStatusBarPaneInfo::Dump(CDumpContext& dc) const
{
	dc	<< "FgColor / BkColor / Value:\t"
	<< fgColor[1] << " - " << fgColor[0] << " / "
	<< bkColor[1] << " - " << bkColor[0] << " / "
	<< string[1]  << " - " << string[0]  << "\n"
	<< "Mode:\t"  << mode  << "\n";
}

void CNGStatusBarPaneInfo::AssertValid() const
{
	ASSERT((progress == NULL) || _CrtIsValidHeapPointer(progress));
}

CDumpContext& AFXAPI operator<<(CDumpContext& dc, CNGStatusBarPaneInfo& paneInfo)
{
	paneInfo.Dump(dc);
	return dc;
}
#endif // _DEBUG

//****************************************************************************
//****************************************************************************
//****************************************************************************

CNGStatusBar *CNGStatusBar::aktBar = NULL;

/*****************************************************************************
 * Klasse:		CNGStatusBar
 * Funktion:	CNGStatusBar, ~CNGStatusBar
 * Parameter:	-
 * Return:		
 *
 * Constructor and Destructor.
 ****************************************************************************/
CNGStatusBar::CNGStatusBar()
{
	aktBar		= this;
	timerID		= 0;
}

CNGStatusBar::~CNGStatusBar()
{}


BEGIN_MESSAGE_MAP(CNGStatusBar, CStatusBar)
//{{AFX_MSG_MAP(CNGStatusBar)
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_PAINT()
ON_WM_LBUTTONDBLCLK()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MBUTTONDBLCLK()
ON_WM_MBUTTONDOWN()
ON_WM_MBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDBLCLK()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_CREATE()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

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�r 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);
		COLORREF	oldFgColor	= pDC->SetTextColor(textColor);
		int			textAlign	= mode & XSB_ALIGN;
		

		CSize s = pDC->GetTextExtent(text);
		pDC->DrawText(text, rect, textAlign|DT_END_ELLIPSIS);
		pDC->SelectObject(oldFont);
		pDC->SetTextColor(oldFgColor);
		pDC->SetBkMode(oldBkMode);
	}

}

/*****************************************************************************
 * Klasse:		CNGStatusBar
 * Funktion:	DrawBitmapPane
 * Parameter:	pDC			Aktueller Device-Kstring[1]
 *				ix			Index des aktuellen Panes
 *				rect		Bounding Rectangle des aktuellen Panes
 *				aktPane		Aktueller Pane
 * Return:		-
 *
 * A bit-map in a Pane outputs. If, gescrollt can this bit-map in horizontal 
 * and/or vertical direction is required. The adjustment can take place left, 
 * on the right or centered or the bit-map can to the current Pane size be adapted 
 * (stretching). With the scrollen several pictures can be secondary or set, 
 * so that a continuous movement develops. 
 ****************************************************************************/
void CNGStatusBar::DrawBitmapPane(CDC *pDC, int ix, CRect& rect, CNGStatusBarPaneInfo& aktPane)
{
	UNUSED_ALWAYS(ix);

	CString		bmString	= aktPane.GetBitmap(on);
	if (bmString.IsEmpty())
		return;
	CDC			memDC;
	memDC.CreateCompatibleDC(pDC);
	CBitmap		bitmap;
	bitmap.LoadBitmap(bmString);
	BITMAP		bm;
	bitmap.GetBitmap(&bm);

	CBitmap		*oldBitmap	= memDC.SelectObject(&bitmap);
	const int	mode		= aktPane.GetMode();
	const int	hScroll		= mode & XSB_HSCROLL;
	const int	vScroll		= mode & XSB_VSCROLL;
	const int	repeat		= mode & XSB_REPEAT;
	const int	stretch		= mode & XSB_STRETCH;

	if (repeat)
	{
		if (hScroll)	
			aktPane.HScroll(rect, bm.bmWidth, 1);

		if (vScroll)	
			aktPane.VScroll(rect, bm.bmHeight, 1);

		if (hScroll && !vScroll)
		{
			for (int x = rect.left; x < rect.right; x += bm.bmWidth)
			{
				pDC->BitBlt(x, rect.top, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY);
			}
		}
		else if (vScroll && !hScroll)
		{
			for (int y = rect.top; y < rect.bottom; y += bm.bmHeight)
			{
				pDC->BitBlt(rect.left, y, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY);
			}
		}
		else
		{
			for (int x = rect.left; x < rect.right; x += bm.bmWidth)
			{
				for (int y = rect.top; y < rect.bottom; y += bm.bmHeight)
				{
					pDC->BitBlt(x, y, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY);
				}
			}
		}
	}
	else
	{
		if (hScroll)	
			aktPane.HScroll(rect, bm.bmWidth, -rect.Width());

		if (vScroll)	
			aktPane.VScroll(rect, bm.bmHeight, -rect.Height());

		if (hScroll || vScroll)
		{
			pDC->BitBlt(rect.left, rect.top, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY);
		}
		else if (stretch)
		{
			pDC->StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
		}
		else
		{
			if (mode & DT_RIGHT)	
				rect.left	= rect.right - bm.bmWidth;

			if (mode & DT_CENTER)	
				rect.left	= (rect.left + rect.right - bm.bmWidth) / 2;

			if (mode & DT_BOTTOM)	
				rect.top	= rect.bottom - bm.bmHeight;

			if (mode & DT_VCENTER)	
				rect.top	= (rect.top + rect.bottom - bm.bmHeight) / 2;

			pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
		}
	}

	memDC.SelectObject(oldBitmap);
}

/*****************************************************************************
 * Klasse:		CNGStatusBar
 * Funktion:	DrawProgressPane
 * Parameter:	pDC			Aktueller Device-Kstring[1]
 *				ix			Index des aktuellen Panes
 *				rect		Bounding Rectangle des aktuellen Panes
 *				aktPane		Aktueller Pane
 * Return:		-
 *
 * This function draws the progress check. For this only the definition of the size is necessary. 
 ****************************************************************************/
void CNGStatusBar::DrawProgressPane(CDC *pDC, int ix, CRect& rect, CNGStatusBarPaneInfo& aktPane)
{
	UNUSED_ALWAYS(pDC);
	UNUSED_ALWAYS(aktPane);
	rect.InflateRect(1, 1);
	GetProgressCtrl(ix)->MoveWindow(rect, FALSE);
}

/*****************************************************************************
 * Klasse:		CNGStatusBar
 * Funktion:	GetCNGStatusBarPaneInfo
 * Parameter:	ix
 * Return:		CNGStatusBarPaneInfo&
 *
 * This function returns the CNGStatusBarPaneInfo variable for the current Pane as reference,
 * so that the Members of this variables can be changed directly. 
 ****************************************************************************/
CNGStatusBarPaneInfo& CNGStatusBar::GetCNGStatusBarPaneInfo(int ix)
{
	ASSERT(ix < GetCount());
	return paneInfo[ix];
}

/*****************************************************************************
 * Klasse:		CNGStatusBar
 * Funktion:	OnTimer
 * Parameter:	nIDEvent	Aktuelle Timer-Event-ID
 * Return:		-
 *
 * After each timer vent ethose is again drawn status bar.
 ****************************************************************************/
void CNGStatusBar::OnTimer(UINT nIDEvent)
{
	if (nIDEvent == timerID)	Invalidate(FALSE);
}

/*****************************************************************************
 * Klasse:		CNGStatusBar
 * Funktion:	SetStyle, SetWidth, GetStyle, GetWidth, GetID
 * Parameter:	ix		Index des Panes
 *				style	Neuer Style f�r das Pane
 *				width	Neue Breite f�r das Pane
 * Return:		Vorheriger Style bzw. vorherige Breite des Panes bzw.
 *				gew�nschter Style
 *
 * Or new width for the indicated Pane sets a new Style or gives the value back 
 * 
 ****************************************************************************/
#define GET_PANE_INFO(ix)	ASSERT(ix < GetCount()); \
UINT id, style; int width; \
GetPaneInfo(ix, id, style, width)

UINT CNGStatusBar::SetStyle(int ix, UINT newStyle)
{
	GET_PANE_INFO(ix);
	SetPaneInfo(ix, id, newStyle, width);
	return style;
}
int  CNGStatusBar::SetWidth(int ix, int newWidth)
{
	GET_PANE_INFO(ix);
	SetPaneInfo(ix, id, style, newWidth);
	return width;
}
UINT CNGStatusBar::GetStyle(int ix)
{
	GET_PANE_INFO(ix);
	return style;
}
int  CNGStatusBar::GetWidth(int ix)
{
	GET_PANE_INFO(ix);
	return width;
}
UINT CNGStatusBar::GetID(int ix)
{
	GET_PANE_INFO(ix);
	return id;
}

#undef GET_PANE_INFO

/*****************************************************************************
 * Klasse:		CNGStatusBar
 * Funktion:	OnDestroy
 * Parameter:	-
 * Return:		-
 *
 * When destroying the status line the timer must be deleted. 
 ****************************************************************************/
void CNGStatusBar::OnDestroy()
{
	if (timerID)	KillTimer(timerID);
	timerID = 0;

	CStatusBar::OnDestroy();
}

/*****************************************************************************
 * Klasse:		CNGStatusBar
 * Funktion:	SavePane, RestorePane
 * Parameter:	ix		Aktueller Paneindex
 * Return:		-
 *
 * With these two functions the current status of a Panes can be restored 
 * temporarly secured and at a later point in time again, or into another Pane 
 * to be copied. This is then meaningful for example if in a Pane temporarily 
 * to another mode (for example a progress bar) is switched. For each Pane 
 * a buffer is available.
 ****************************************************************************/
void CNGStatusBar::SavePane(int ix)
{
	ASSERT(ix < GetCount());

	CNGStatusBarPaneInfo	value;
	if (!buffer.Lookup(ix, value))
		buffer[ix] = paneInfo[ix];
}

void CNGStatusBar::RestorePane(int ix)
{
	ASSERT(ix < GetCount());

	CNGStatusBarPaneInfo	value;
	if (buffer.Lookup(ix, value))
	{
		paneInfo[ix] = value;
		buffer.RemoveKey(ix);
	}

	Invalidate(FALSE);
}

/*****************************************************************************
 * Klasse:		CNGStatusBar
 * Funktion:	GetPaneAtPosition
 * Parameter:	point		Aktuelle Mausposition
 * Return:		Index des Panes, der unter der Maus liegt
 *
 * With this function one tests, which is to Pane under the mouse and which 
 * index of this Panes returned. It must be noted that the mouse position 
 * must be transferred to the status line in Client coordinates. If the father 
 * window is a dialog, a coordinate adjustment must be executed before the position 
 * examination. 
 ****************************************************************************/
int CNGStatusBar::GetPaneAtPosition(CPoint& point)
{
	if (pParent->IsKindOf(RUNTIME_CLASS(CDialog)))
	{
		pParent->ClientToScreen(&point);
		ScreenToClient(&point);
	}

	CRect rect;
	for (int i = 0, n = GetCount(); i < n; i++)
	{
		GetItemRect(i, rect);
		if (rect.PtInRect(point))	return i;
	}

	return -1;
}

/*****************************************************************************
 * Klasse:		CNGStatusBar
 * Funktion:	OnLButtonUp, OnMButtonUp, OnRButtonUp, OnMouseMove,
 *				OnLButtonDown, OnMButtonDown, OnRButtonDown,
 *				OnLButtonDblClk, OnMButtonDblClk, OnRButtonDblClk
 * Parameter:	nFlags		Zusatztasten bei der Mausoperation
 *				point		Aktuelle Mausposition
 * Return:		-
 *
 * These mouse functions pass the message on directly to the parent window. 
 * 
 ****************************************************************************/
#define TO_PARENT(fkt, event)	\
void CNGStatusBar::fkt(UINT nFlags, CPoint point) \
{ \
pParent->SendMessage(event, (WPARAM) nFlags, MAKELPARAM(point.x, point.y)); \
CStatusBar::fkt(nFlags, point); \
}

TO_PARENT(OnLButtonUp,		WM_LBUTTONUP);
TO_PARENT(OnMButtonUp,		WM_MBUTTONUP);
TO_PARENT(OnRButtonUp,		WM_RBUTTONUP);
TO_PARENT(OnLButtonDown,	WM_LBUTTONDOWN);
TO_PARENT(OnMButtonDown,	WM_MBUTTONDOWN);
TO_PARENT(OnRButtonDown,	WM_RBUTTONDOWN);
TO_PARENT(OnLButtonDblClk,	WM_LBUTTONDBLCLK);
TO_PARENT(OnMButtonDblClk,	WM_MBUTTONDBLCLK);
TO_PARENT(OnRButtonDblClk,	WM_RBUTTONDBLCLK);
TO_PARENT(OnMouseMove,		WM_MOUSEMOVE);

#undef TO_PARENT

BOOL CNGStatusBar::OnEraseBkgnd(CDC* pDC) 
{
	UNUSED_ALWAYS(pDC);
	
	return TRUE;//CMDIFrameWnd::OnEraseBkgnd(pDC);
}


/////////////////////////////////////////////////////////////////////////////
// Tool tip operations
void CNGStatusBar::AddToolTip(LPCTSTR lpszText, LPCRECT lpRectTool, UINT nIDTool)
{
	m_ToolTip.AddTool(this, lpszText, lpRectTool, nIDTool);
}

void CNGStatusBar::SetToolRects()
{
	CRect rect;
	for (int i = 1, n = GetCount(); i < n; i++)
	{
		GetItemRect(i, &rect);
		m_ToolTip.SetToolRect(this, i, &rect);
	}
}

void CNGStatusBar::UpdateTipText(LPCTSTR lpszText, UINT nIDTool)
{
	m_ToolTip.UpdateTipText(lpszText, this, nIDTool);
}

void CNGStatusBar::DeleteToolTip(UINT nIDTool)
{
	m_ToolTip.DelTool(this, nIDTool);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Anna-Jayne Metcalfe
Founder Riverblade Limited
United Kingdom United Kingdom
I haven't always written software for a living. When I graduated from Surrey University in 1989, it was with an Electronic Engineering degree, but unfortunately that never really gave me the opportunity to do anything particularly interesting (with the possible exception of designing Darth Vader's Codpiece * for the UK Army in 1990).
    * Also known as the Standard Army Bootswitch. But that's another story...
Since the opportunity arose to lead a software team developing C++ software for Avionic Test Systems in 1996, I've not looked back. More recently I've been involved in the development of subsea acoustic navigation systems, digital TV broadcast systems, port security/tracking systems, and most recently software development tools with my own company, Riverblade Ltd.
 
One of my personal specialities is IDE plug-in development. ResOrg was my first attempt at a plug-in, but my day to day work is with Visual Lint, an interactive code analysis tool environment with works within the Visual Studio and Eclipse IDEs or on build servers.
 
I love lots of things, but particularly music, photography and anything connected with history or engineering. I despise ignorant, intolerant and obstructive people - and it shows...I can be a bolshy cow if you wind me up the wrong way...Laugh | :laugh:
 
I'm currently based 15 minutes walk from the beach in Bournemouth on the south coast of England. Since I moved here I've grown to love the place - even if it is full of grockles in Summer!
Follow on   Twitter

| Advertise | Privacy | Mobile
Web01 | 2.8.140821.2 | Last Updated 10 Jan 2005
Article Copyright 2001 by Anna-Jayne Metcalfe
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid