Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bargraphs in VC++ 6.0

8 views
Skip to first unread message

Kahlua

unread,
Jan 16, 2008, 10:20:14 AM1/16/08
to
Can anyone please explain how to make my bargraph properly using GDI calls
and where to put it?
I want it as simple as possible.
Thanks


>>>There are few flaws in it.
>>>1. The first and most important thing is that the drawing part of this
>>>code
>>>should be in the OnPaint of the child control (IDC_PICT), and not the
>>>dialog. Because if it is not in the OnPaint of the control, then when
>>>the
>>>dialog is covered by another window it will not repaint itself when it is
>>>uncovered.
>>>2. The fact that it's not scaleable with the data might become a problem
>>>later, only 10 items......
>>>3. It is not releasing the DC of the child control, which causes a
>>>resource
>>>leak.
>>>4. It is not scalable when it comes to the size of the control.
>>>5. It doesn't have any labels or axes markers.
>>>
>>>Otherwise, if you like it feel free to use it.
>>>
>>>AliR.


"Kahlua" <kah...@right.here> wrote in message
news:G%7jj.10188$ac7.2274@trndny03...
> "Kahlua" <kah...@right.here> wrote in message
> news:zb6jj.7554$6F6.4662@trndny09...
>> Can anyone show me how to display a bargraph within my mfc app?
>> Or direct me to the resource to do it.
>> Lets say I have an unsigned char string of 16bytes of data ranging in
>> value from 01h to FFh.
>> I want to display a bargraph with the 16 vertical bars reflecting the
>> data value.
>> Height and width of bargraph not important at this time.
>> Thanks in advance.
>>
>>
>
> I found this simple code that seems to work ok.
> Anything wrong with it?
> Why should I not use it?
>
> void CBar1Dlg::OnBar()
> {
> unsigned char bar[10];
> int numbars=10;
> int a,b,c,d,i;
>
> for (i=0;i<10;i++) //initialize
> bargraph values for testing
> bar[i]=i*10;
>
> CRect cr;
> CBrush grn(RGB(100,255,100));
> c=15,b=5; //initialize
> positions
> GetDlgItem(IDC_PIC)->GetClientRect(cr); //get drawing area of PIC
> CWnd* pWnd=GetDlgItem(IDC_PIC);
>
> pControlDC=pWnd->GetDC();
>
> d = (cr.Width()-20)/numbars;
> pControlDC->SelectObject(wht); //draw
> background
> pControlDC->Rectangle(0,0,cr.Width(), cr.Height());
>
> pControlDC->SelectObject(grn); //select color of
> bar
> for (b=0; b<numkeys; b++)
> {
> a = bar[b];
> pControlDC->Rectangle (c, cr.Height(), c+10, cr.Height()-a);
> c+=d;
> }
> pControlDC->SelectStockObject(BLACK_BRUSH);
> }
>
>

David Wilkinson

unread,
Jan 16, 2008, 11:08:48 AM1/16/08
to
Kahlua wrote:
> Can anyone please explain how to make my bargraph properly using GDI calls
> and where to put it?
> I want it as simple as possible.

Kahlua:

Reading about CBrush, CDC::SelectObject() and CDC::Rectangle() would be
a good start for a very simple bar graph.

--
David Wilkinson
Visual C++ MVP

AliR (VC++ MVP)

unread,
Jan 16, 2008, 11:37:07 AM1/16/08
to
You can start reading through this set of documents:
http://msdn2.microsoft.com/en-us/library/ms536795(VS.85).aspx


Why aren't you using one of the chart controls posted on code project?
http://www.codeproject.com/KB/miscctrl/CBarChart.aspx

There are tons of them here on CodeGuru:
http://www.codeguru.com/cpp/controls/controls/


AliR.


"Kahlua" <kah...@right.here> wrote in message

news:Ogpjj.14360$Y63.1295@trnddc03...

Kahlua

unread,
Jan 16, 2008, 1:00:28 PM1/16/08
to
Every one of these links you give me are projects full of lots of bell and
whistles which makes it impossible to just find the simple bargraph portion.
I guess it seems nobody here really knows how to do this task simply.
All I want to do is take a simple string of bytes and translate to a simple
bargraph within a defined area of screen.
I have ways that do work but I am told they are troublesome, yet no one
explains how to do it correctly.
When I do it the only way I know works (which is trouble according to lots
of people) it doesnt re-draw when a window overlaps it.
You keep telling me that I need to do something in the OnPaint() routing but
dont say what.
This is NOT a school project or anything.
It is simply something I am trying to learn to do the right way.
Please someone help me.


"AliR (VC++ MVP)" <Al...@online.nospam> wrote in message
news:Toqjj.33375$4V6....@newssvr14.news.prodigy.net...

David Wilkinson

unread,
Jan 16, 2008, 2:40:54 PM1/16/08
to
Kahlua wrote:
> Every one of these links you give me are projects full of lots of bell and
> whistles which makes it impossible to just find the simple bargraph portion.
> I guess it seems nobody here really knows how to do this task simply.
> All I want to do is take a simple string of bytes and translate to a simple
> bargraph within a defined area of screen.
> I have ways that do work but I am told they are troublesome, yet no one
> explains how to do it correctly.
> When I do it the only way I know works (which is trouble according to lots
> of people) it doesnt re-draw when a window overlaps it.
> You keep telling me that I need to do something in the OnPaint() routing but
> dont say what.
> This is NOT a school project or anything.
> It is simply something I am trying to learn to do the right way.
> Please someone help me.

Kahlua:

For the simplest bar graph, just use CDC::Rectangle() to draw a series
of rectangles of the correct height.

Yes, you must do your painting in OnPaint() or OnDraw() if you want your
window to repaint after being covered. This is how the Windows printing
model works.

AliR (VC++ MVP)

unread,
Jan 16, 2008, 3:15:09 PM1/16/08
to
You might think that this is simple task, and indeed it is a simple task to
just draw some rectangles.
But the implementation of the plotter depends on your data storage and how
you want it to be presented. So it is fairly difficult for someone to just
give you a simple piece of code to does exactly what you want. (Other than
pointing you to the controls that we have given you links to).

In order to accomplish what you want you will need to know how to make some
GDI calls to draw rectangles using brushes and pens, which I gave you link
for that. Take a look at the documentation for CDC and you should have
everything you need in order to do what you want.

The code that you posted does most of the work, but it had a resource leak,
which can be fixed by calling ReleaseDC at the end. But again the drawing
portion of that code should be in the OnPaint method of the control, and not
in the dialogbox.

I'll try to put an example together.

AliR.

"Kahlua" <kah...@right.here> wrote in message

news:0Drjj.5944$YW6.1505@trndny07...

AliR (VC++ MVP)

unread,
Jan 16, 2008, 3:27:48 PM1/16/08
to
Here is a very simple one, using the same code that you posted.

//////////////////////////////////////////////////////////////////////////
// BarChart.h
#pragma once

#include <afxtempl.h>

// CBarChart
typedef CArray <int> IntArray;


class CBarChart : public CStatic
{
DECLARE_DYNAMIC(CBarChart)

public:
CBarChart();
virtual ~CBarChart();

void SetNumData(int NumData);
void SetData(int Index,int Value);
protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()

private:
IntArray m_Array;
};

///////////////////////////////////////////////////////////////////////
// BarChart.cpp : implementation file
//

#include "stdafx.h"
#include "BarChart.h"


// CBarChart

IMPLEMENT_DYNAMIC(CBarChart, CStatic)
CBarChart::CBarChart()
{
}

CBarChart::~CBarChart()
{
}


BEGIN_MESSAGE_MAP(CBarChart, CStatic)
ON_WM_PAINT()
END_MESSAGE_MAP()

// CBarChart message handlers
void CBarChart::SetNumData(int NumData)
{
m_Array.SetSize(NumData);
}

void CBarChart::SetData(int Index,int Value)
{
if (Index < m_Array.GetCount())
{
m_Array.SetAt(Index,Value);
}
}


void CBarChart::OnPaint()
{
CPaintDC dc(this); // device context for painting

int SavedDC = dc.SaveDC();

CRect cr;
GetClientRect(&cr);

CBrush GreenBrush(RGB(100,255,100));
CBrush WhiteBrush(RGB(255,255,255));

int c=15,b=5;
int d = (cr.Width()-20)/m_Array.GetCount();

dc.SelectObject(WhiteBrush);
dc.Rectangle(0,0,cr.Width(), cr.Height());

dc.SelectObject(GreenBrush);
for (b=0; b<m_Array.GetCount(); b++)
{
int a = m_Array.GetAt(b);
dc.Rectangle(c, cr.Height(), c+20, cr.Height()-a);
c+=d;
}

dc.RestoreDC(SavedDC);
}


Put a Static control on your dialog, give an id other than IDC_STATIC. Then
attach a variable to it. Change the variable type from CStatic to
CBarChart. Then call SetNumData and SetData in your OnInitDialog

m_BarChart.SetNumData(5);
m_BarChart.SetData(0,10);
m_BarChart.SetData(1,20);
m_BarChart.SetData(2,50);
m_BarChart.SetData(3,100);
m_BarChart.SetData(4,35);

AliR.


"AliR (VC++ MVP)" <Al...@online.nospam> wrote in message

news:hBtjj.38666$lD6....@newssvr27.news.prodigy.net...

0 new messages