I'm trying to create a simple 2d thingy.
My goal is to draw a column with bricks of various heights and be able to scale it.
Everything compiles when I don't include the DrawBrick() method.
edit: I may have inched a little closer by changing a couple things,
but on the line that reads: element.DrawBrick( XXXXXXXXX ); // I'm Not Sure What To Put Here
/*
Brick.src
Simple brick object with height scaled to suit element height
with respect to overall height of stack of bricks
Each brick has attributes of color, location and height
by John Siino
*/
int ColumnWidth = 20;
int ColumnHeight = 100;
int LineThickness = 1;
int TotalHeight;
int RunningHeight;
int BLACK;
int RED;
int GREEN;
int BLUE;
int YELLOW;
int PURPLE;
int BROWN;
int WHITE;
int GREY;
Class Brick
{
// member variables
int x, y; // upper left corner of brick
int h, w; // height & width of brick
int c; // color of brick
int hatch; // cross hatching of brick
enum hatching
{
NONE,
VERTICAL,
RIGHT,
HORIZONTAL,
LEFT
}
// member methods
declare Brick();
declare _Brick();
declare Setcolor( int cc );
declare Getcolor(), int;
declare SetHatch( hatching hat);
declare GetHatch(), hatching;
declare SetY( int yy);
declare GetY(), int;
declare SetX( int xx);
declare GetX(), int;
declare SetWidth( int ww );
declare GetWidth(), int;
declare SetHeight( int hh );
declare GetHeight(), int;
declare DrawBrick( CDialog mydlg ); // latest edit
}
Brick:: Brick()
{
x = 0;
y = 0;
h = 0;
w = 0;
color = RGB(0,0,0);
hatch = NONE;
}
Brick::_Brick()
{
}
Brick::Setcolor( int cc )
{
c = cc;
return;
}
Brick::SetHatch( hatching hat )
{
hatch=hat;
return;
}
Brick::SetY( int yy)
{
y=yy;
return;
}
Brick::SetX( int xx)
{
x=xx;
return;
}
Brick::SetWidth( int ww )
{
w=ww;
return;
}
Brick::SetHeight( int hh )
{
h=hh;
return;
}
Brick::Getcolor(), int
{
return c;
}
Brick::GetHatch(), hatching
{
return hatch;
}
Brick::GetY(), int
{
return y;
}
Brick::GetX(), int
{
return x;
}
Brick::GetHeight(), int
{
return h;
}
Brick::GetWidth(), int
{
return w;
}
Brick::DrawBrick( CDialog mydlg )
{
mydlg.DrawRect(x, y, w, h, RGB(0,0,0), c );
return;
}
class dlg:CDialog
{
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
}
dlg::OnClose(),int
{
CloseDialog(1);
return true;
}
dlg::OnInitDialog(),int
{
CenterWindow();
return true;
}
dlg::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
Brick element[3];
element[0].Setcolor(RED);
element[1].Setcolor(GREEN);
element[2].Setcolor(BROWN);
for (int i = 0; i < 3; i++)
{
element[i].SetWidth( ColumnWidth );
}
element[0].SetHeight(10);
element[1].SetHeight(15);
element[2].SetHeight(20);
TotalHeight = 0;
for (i = 0; i < 3; i++)
{
TotalHeight = TotalHeight + element[i].GetHeight();
}
RunningHeight = element[0].GetHeight() * ColumnHeight / TotalHeight;
element[0].SetHeight( RunningHeight );
element[0].SetY( 0 );
for (i = 1; i < 3; i++)
{
element[i].SetY( element[i-1].GetY() + element[i-1].GetHeight() );
element[i].SetHeight( element[i].GetHeight() * ColumnHeight / TotalHeight );
}
for (i = 0; i < 3; i++)
{
element[i].DrawBrick( XXXXXXXXX ); // I'm Not Sure What To Put Here
}
return true;
}
global sub main()
{
BLACK = RGB(0,0,0);
RED = RGB(255,0,0);
GREEN = RGB(0,255,0);
BLUE = RGB(0,0,255);
YELLOW = RGB(255,255,0);
PURPLE = RGB(255,0,255);
BROWN = RGB(0,255,255);
WHITE = RGB(255,255,255);
GREY = RGB(127,127,127);
dlg d1;
d1.Create(0,0,640,480,0x80C80080,0,"Bricks",0);
d1.DoModal();
return 0;
}
John,
Couple of problems.
1. Your DrawBrick method has a parameter but you're not calling it with one.
2. Your OnControl handler is being used for drawing which is very odd since you don't have any controls, you're not checking the control ID, and that handler will never be called anyway.
3. Dialogs are meant for controls. If you wan't to draw on something use a window or 2D screen. Technically you can draw on a dialogs background by overriding OnPaint, but that would be a bit unusual since again dialogs are meant as containers for controls.
So all on all I am not sure where you are headed with this one.
Paul.
Thanks for looking at it Paul,
I got this to compile but nothing was visible in my dialog. I was having difficulty getting the handle of my dialog. I had to use a CWindow pointer and use GetHandle() to assign the handle to the pointer. Now I have get my bricks to show up.
/*
Brick.src
Simple brick object with height scaled to suit element height
with respect to overall height of stack of bricks
Each brick has attributes of color, location and height
by John Siino
*/
int ColumnWidth = 20;
int ColumnHeight = 100;
int LineThickness = 1;
int TotalHeight;
int RunningHeight;
int BLACK;
int RED;
int GREEN;
int BLUE;
int YELLOW;
int PURPLE;
int BROWN;
int WHITE;
int GREY;
Class Brick
{
// member variables
int x, y; // upper left corner of brick
int h, w; // height & width of brick
int c; // color of brick
int hatch; // cross hatching of brick
enum hatching
{
NONE,
VERTICAL,
RIGHT,
HORIZONTAL,
LEFT
}
// member methods
declare Brick();
declare _Brick();
declare Setcolor( int cc );
declare Getcolor(), int;
declare SetHatch( hatching hat);
declare GetHatch(), hatching;
declare SetY( int yy);
declare GetY(), int;
declare SetX( int xx);
declare GetX(), int;
declare SetWidth( int ww );
declare GetWidth(), int;
declare SetHeight( int hh );
declare GetHeight(), int;
declare DrawBrick( CWindow mydlg );
}
Brick:: Brick()
{
x = 0;
y = 0;
h = 0;
w = 0;
color = RGB(0,0,0);
hatch = NONE;
}
Brick::_Brick()
{
}
Brick::Setcolor( int cc )
{
c = cc;
return;
}
Brick::SetHatch( hatching hat )
{
hatch=hat;
return;
}
Brick::SetY( int yy)
{
y=yy;
return;
}
Brick::SetX( int xx)
{
x=xx;
return;
}
Brick::SetWidth( int ww )
{
w=ww;
return;
}
Brick::SetHeight( int hh )
{
h=hh;
return;
}
Brick::Getcolor(), int
{
return c;
}
Brick::GetHatch(), hatching
{
return hatch;
}
Brick::GetY(), int
{
return y;
}
Brick::GetX(), int
{
return x;
}
Brick::GetHeight(), int
{
return h;
}
Brick::GetWidth(), int
{
return w;
}
Brick::DrawBrick( CWindow mydlg )
{
mydlg.DrawRect(x, y, w, h, RGB(0,0,0), c );
return;
}
class dlg:CDialog
{
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
CWindow *mydlg;
}
dlg::OnClose(),int
{
CloseDialog(1);
return true;
}
dlg::OnInitDialog(),int
{
mydlg = GetHandle();
CenterWindow();
return true;
}
dlg::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
Brick element[3];
element[0].Setcolor(RED);
element[1].Setcolor(GREEN);
element[2].Setcolor(BROWN);
for (int i = 0; i < 3; i++)
{
element[i].SetWidth( ColumnWidth );
}
element[0].SetHeight(10);
element[1].SetHeight(15);
element[2].SetHeight(20);
TotalHeight = 0;
for (i = 0; i < 3; i++)
{
TotalHeight = TotalHeight + element[i].GetHeight();
}
RunningHeight = element[0].GetHeight() * ColumnHeight / TotalHeight;
element[0].SetHeight( RunningHeight );
element[0].SetY( 0 );
for (i = 1; i < 3; i++)
{
element[i].SetY( element[i-1].GetY() + element[i-1].GetHeight() );
element[i].SetHeight( element[i].GetHeight() * ColumnHeight / TotalHeight );
}
for (i = 0; i < 3; i++)
{
element[i].DrawBrick( *mydlg );
}
return true;
}
global sub main()
{
BLACK = RGB(0,0,0);
RED = RGB(255,0,0);
GREEN = RGB(0,255,0);
BLUE = RGB(0,0,255);
YELLOW = RGB(255,255,0);
PURPLE = RGB(255,0,255);
BROWN = RGB(0,255,255);
WHITE = RGB(255,255,255);
GREY = RGB(127,127,127);
dlg d1;
d1.Create(0,0,640,480,0x80C80080,0,"Bricks",0);
d1.DoModal();
return 0;
}
Um. No.
GetHandle returns the windows HWND handle, not a pointer to your dialog. All you need is THIS my friend. In other words the this pointer.
And dialogs are not meant to be drawn into. They don't support the background bitmap that an autodrawn window uses. And you won't get anything to draw since you are trying to use OnControl for something it is not designed for.
If you really MUST use a dialog as a drawing surface you will have to override OnPaint to get anything to happen and make a few other changes...
Brick::DrawBrick( CWindow *win )
{
win->DrawRect(x, y, w, h, RGB(0,0,0), c );
return;
}
... in the OnPaint handler, which you have yet to create...
....
element.DrawBrick( this );
Thanks Paul,
I'll look at your paint example. I didn't realize that you can't draw in a dialog. i thought a CDialog was a child of CWindow and inheretted DrawRect
You are misunderstanding me. A dialog doesn't not create a bitmap, like a window does when using the AWS_AUTODRAWN style. In as much you have to follow normal Windows drawing methods if you want something other than controls in a dialog. You draw everything in OnPaint, it is an overridable handler just like OnControl, or OnLButtonDown, etc.
OnControl is called for control messages, it isn't meant to have drawing code in it regardless if you are using a window or dialog, unless it is in response to some control message. Same as it has been in IBasic, EBasic, Aurora, etc. The concepts are identical.
Thanks Paul,
I'm reviewing your simplepaint.src example right now and I am learning from it.
I am trying to create a little graphical representation of soil layers along with an embedded piling. The drawing part is not interactive. The program will size and stack the "brick" elements to represent the soil layers based on user input.
I got it to work!
// Schematic.src
#define DwgWidth 320
#define DwgHeight 640
#define BrickWdth DwgWidth-20
#define BrickHt DwgHeight-65
#define SCHEMATIC_Dwg 700
DECLARE IMPORT,GetSystemMetrics(nIndex as INT),INT;
class DrawWnd : CWindow
{
declare OnCreate(), int;
declare OnClose(), int;
}
Class Brick
{
// member variables
int l, t; // upper left corner of brick
int h, w; // height & width of brick
int c; // color of brick
int hatch; // cross hatching of brick
enum hatching
{
NONE,
VERTICAL,
RIGHT,
HORIZONTAL,
LEFT
}
// member methods
declare Brick();
declare _Brick();
declare Setcolor( int cc );
declare Getcolor(), int;
declare SetHatch( hatching hat);
declare GetHatch(), hatching;
declare SetT( int yy);
declare GetT(), int;
declare SetL( int xx);
declare GetL(), int;
declare SetWidth( int ww );
declare GetWidth(), int;
declare SetHeight( int hh );
declare GetHeight(), int;
declare DrawBrick( CWindow mywin );
}
int run;
int BLACK, RED, GREEN, BLUE, YELLOW, PURPLE, BROWN, WHITE, GREY;
float TotalHeight, RunningHeight, brickheight, RunningDepth;
global sub main()
{
run = 1;
int linesize;
WHITE = RGB(0,0,0);
RED = RGB(0,255,255);
GREEN = RGB(255,0,255);
BLUE = RGB(255,255,0);
YELLOW = RGB(0,0,255);
PURPLE = RGB(0,192,128);
BROWN = RGB(0,128,222);
BLACK = RGB(255,255,255);
GREY = RGB(127,127,127);
linesize = 2;
int lastone = 4;
DrawWnd dwg;
dwg.Create(0,0, DwgWidth, DwgHeight,AWS_CAPTION|AWS_SYSMENU|AWS_BORDER|AWS_SIZE|AWS_MINIMIZEBOX|
AWS_MAXIMIZEBOX|AWS_AUTODRAW,0,"Schematic of Soil", 0);
dwg.SetRasterOp(RMXORPEN);
dwg.ShowWindow(SWSHOW);
dwg.CenterWindow();
Brick soillayer[4];
soillayer[0].Setcolor(RED);
soillayer[1].Setcolor(GREEN);
soillayer[2].Setcolor(BROWN);
soillayer[3].Setcolor(BLUE);
soillayer[0].SetHeight(5);
soillayer[1].SetHeight(10);
soillayer[2].SetHeight(20);
soillayer[3].SetHeight(40);
TotalHeight = 0;
for (i = 0; i < lastone; i++)
{
TotalHeight = TotalHeight + soillayer[i].GetHeight();
}
RunningDepth = 0;
RunningHeight = soillayer[0].GetHeight() * (BrickHt) / TotalHeight;
dwg.DrawRect( 5, 10, BrickWdth, RunningHeight, BLACK, soillayer[0].GetColor());
dwg.FrontPen(0);
dwg.WriteText(BrickWdth-20, 10, "0 ft ");
dwg.WriteText(10, RunningHeight/2, " Soil Layer "+NumToStr(0+1)+": "+NumToStr(soillayer[0].GetHeight())+" ft thick ");
RunningDepth = soillayer[0].GetHeight();
for (i = 1; i < lastone; i++)
{
brickheight = soillayer[i].GetHeight() * (BrickHt) / TotalHeight;
dwg.DrawRect( 5, 10+RunningHeight, BrickWdth, brickheight, BLACK, soillayer[i].GetColor());
dwg.FrontPen(0);
dwg.WriteText(BrickWdth-20, 10+RunningHeight, NumToStr(RunningDepth)+" ft ");
dwg.WriteText(10, RunningHeight + brickheight/2, " Soil Layer " + NumToStr(i+1)+": " + NumToStr(soillayer[i].GetHeight()) + " ft thick ");
RunningDepth = RunningDepth + soillayer[i].GetHeight();
RunningHeight = RunningHeight + brickheight;
}
dwg.WriteText(BrickWdth-20, 10+RunningHeight, NumToStr(RunningDepth) + " ft ");
do {wait(); }until run = 0;
for (i = lastone-1; i >-1; i--)
{
soillayer[i]._Brick();
}
return 0;
}
DrawWnd::OnCreate(),int
{
FrontPen(0);
return true;
}
DrawWnd::OnClose(),int
{
run = 0;
return true;
}
Brick:: Brick()
{
l = 0;
t = 0;
h = 0;
w = 0;
color = RGB(0,0,0);
hatch = NONE;
}
Brick::_Brick()
{
}
Brick::Setcolor( int cc )
{
c = cc;
return;
}
Brick::SetHatch( hatching hat )
{
hatch=hat;
return;
}
Brick::SetT( int yy)
{
t=yy;
return;
}
Brick::SetL( int xx)
{
l=xx;
return;
}
Brick::SetWidth( int ww )
{
w=ww;
return;
}
Brick::SetHeight( int hh )
{
h=hh;
return;
}
Brick::Getcolor(), int
{
return c;
}
Brick::GetHatch(), hatching
{
return hatch;
}
Brick::GetT(), int
{
return t;
}
Brick::GetL(), int
{
return l;
}
Brick::GetHeight(), int
{
return h;
}
Brick::GetWidth(), int
{
return w;
}
Now I think I have a memory leak. I'm rewriting my code to be integrated into the main program and I get:
"The instruction at "0x7c9111de" referenced memory at "0x40418000", The memory could not be read."
I don't know how to use the debugger to track it down. Please help. Attached is the code.
The main program (for this test) is: "soil_schematic.src"
edit: I think I tracked it down to the indexing of my dynamic data array (I'm reporting the number of elements wrong)