Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: How to set pixels ...OnPaint...OnCreate MoveTo ..Line


This question is answered.


Permlink Replies: 6 - Last Post: Jan 21, 2016 2:31 PM Last Post By: Rowland Stevens Threads: [ Previous | Next ]
Rowland Stevens

Posts: 6
Registered: 2/27/14
How to set pixels ...OnPaint...OnCreate MoveTo ..Line  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 1, 2016 3:36 PM
Thanks again so much for previous help. I use Builder 3. Now I want to translate results of computations as they develope into a simple line graph directly I hope by setting three lines and then setting pixels reflecting the comp value at any particular time,l as the user modifies some of the comp so they can see their change effect the result. I know how to use a graph component when I store data and then display a traditional graph. But this is a dynamic real time on going result on what to display. So I prepared a simple program to try and understand On Create and OnPaint, just simply in terms of setting pixel colors and MoveTo and Line To. So I prepared the following simple code:

#include <Printers.hpp>
#include <condefs.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <sys\types.h>
#include <iostream.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
#include <dString.h>
int L13=0;
int L2=0;
int FormPaintPoling=0;
int GraphSet=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{

String S;
S=GraphSet;
Form1->Label3->Caption=S;
Form1->Canvas->Pen->Color=clRed;
Form1->Canvas->MoveTo(400,130);
Form1->Canvas->LineTo(500,130);
Canvas->Pen->Color=clRed;
Canvas->MoveTo(400,230);
Canvas->LineTo(500,240);
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Label6->Caption="This text created with FormCreate Event";
Canvas->Pen->Color=clRed;
Canvas->MoveTo(400,150);
Canvas->LineTo(500,150);
}
void __fastcall TForm1::FormPaint(TObject *Sender)
{
String S;
FormPaintPoling++;
S=FormPaintPoling;
Form1->Label1->Caption=S;
if(GraphSet==0) Form1->Label15->Caption="0000";
if(GraphSet==2)
{
Form1->Label15->Caption="2";
Label2->Caption="GraphSet=2 Code Draws Red Line";
Canvas->Pen->Color=clRed;
Canvas->MoveTo(400,130);
Canvas->LineTo(500,130);
}
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
GraphSet=2;
String S=GraphSet;
Form1->Label4->Caption=S;
}

void __fastcall TForm1::Button2Click(TObject *Sender)
{
GraphSet=3;
String S=GraphSet;
Form1->Label9->Caption=S;

Form1->Label15->Caption="3";
Form1->Label14->Caption="GraphSet=3 Code Draws 3 Lines";
Form1->Canvas->Pen->Color=clBlue;
Form1->Canvas->MoveTo(400,250);
Form1->Canvas->LineTo(500,250);

Form1->Canvas->Pen->Color=clYellow;
Form1->Canvas->MoveTo(400,260);
Form1->Canvas->LineTo(500,260);

Form1->Canvas->Pen->Color=clRed;
Form1->Canvas->MoveTo(400,270);
Form1->Canvas->LineTo(500,270);
}
//---------------------------------------------------------------------------
I find starters On Create will fill in a beginning label but will not then continue with drawing the base lines for the display.????
And MoveTo and LineTo don't work for me when put in the main form?????.

Then I thought I will use the Variable GraphSet in the OnPaint Function which I determines is continually polled .... am I correct? Except in my real program I have a button that creates starts the comp loop and goes to several sub functions to make the comps. Am I correct that I get the impression when I debug and use break points that during the button looping that the "OnPaint" Function is not Poled?

And then when I change the value of GraphSet then during the poling my thought was that sub function of the OnPaint function of that "if "statement would be executed.
Buy tho the button click loops through to its total number and in each loop the appropriate GraphSet Number for what I want drawn is set. In the above program that function is done by the two buttons provided.
In this version the first button sets GraphSet=2 which relates to that OnPaint "if" condition. On the Form then it changes Label 15 to 2 but does not draw the lines??????

. I have tried Form1->Canvas versus just Canvas. (among other things not quite certain when you need to add Form1 or just use Canvas.
The second button did the same thing with the same result.
So I changed the second button click to draw them which it did

Why can't I get MoveTo LineTo to work in main form??? and Why won't OnPaint draw the lines?
But button click does?

Appreciate any insight you can give me of what I may be missing out on understanding about the basic graph capability of Builder 3. Rowland

.

Edited by: Rowland Stevens on Jan 5, 2016 9:18 AM

Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: How to set pixels ...OnPaint...OnCreate MoveTo ..Line  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 2, 2016 2:32 PM   in response to: Rowland Stevens in response to: Rowland Stevens
El 02/01/2016 a las 0:36, Rowland Stevens escribió:
Thanks again so much for previous help. I use Builder 3.

What do you mean, C++Builder 3 or C++Builder XE3?

So I prepared a simple program to try and understand On Create and OnPaint, just simply in terms of setting pixel colors and MoveTo and Line To. So I prepared the following simple code:

1) You should not use the Form1 global variable to access class elements from methods of the TForm1 class. You can use
the "this" keyword:

    this->Label1->Caption= S;


or just nothing:
    Label1->Caption= S;


2) The Canvas object should be used in the OnPaint event only. It is not valid at any other time.

3) What you draw on the canvas is not persistent. You need to draw all elements each time the OnPaint event is called.

4) Call TForm::Invalidate() function to force repainting the content of the form.

5) You don't need to create an OnCreate event (or OnDestroy event) in C++Builder. Move the code from the OnCreate event to the class constructor (and the code from de OnDestroy event to the class destructor).

6) Don't change the properties of other components especially the descendants of TGraphicControl (like TLabel) from within the OnPaint event. Just draw the content of the form in the OnPaint event.

__fastcall TForm4::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    Label3->Caption= GraphSet;
}
 
void __fastcall TForm1::FormPaint(TObject *Sender)
{
    if(GraphSet==0)
    {
       Canvas->Pen->Color=clRed;
       Canvas->MoveTo(400,130);
       Canvas->LineTo(500,130);
 
       Canvas->Pen->Color=clRed;
       Canvas->MoveTo(400,230);
       Canvas->LineTo(500,240);
 
       Canvas->Pen->Color=clRed;
       Canvas->MoveTo(400,150);
       Canvas->LineTo(500,150);
    }
    else if(GraphSet==2)
    {
       Canvas->Pen->Color=clRed;
       Canvas->MoveTo(400,130);
       Canvas->LineTo(500,130);
    }
    else if (GraphSet== 3)
    {
       Canvas->Pen->Color=clBlue;
       Canvas->MoveTo(400,250);
       Canvas->LineTo(500,250);
 
       Canvas->Pen->Color=clYellow;
       Canvas->MoveTo(400,260);
       Canvas->LineTo(500,260);
 
       Canvas->Pen->Color=clRed;
       Canvas->MoveTo(400,270);
       Canvas->LineTo(500,270);
    }
 
}
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    GraphSet=2;
    Label4->Caption= GraphSet;
    Invalidate();
}
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    GraphSet=3;
    Label4->Caption= GraphSet;
    Invalidate();
}
Rowland Stevens

Posts: 6
Registered: 2/27/14
Re: How to set pixels ...OnPaint...OnCreate MoveTo ..Line  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 4, 2016 3:24 PM   in response to: Antonio Estevez in response to: Antonio Estevez
Thank you very much for helping me get Borland to do what I want. I am using Borland C++ Builder 3. In fact Last year I purchased XE5 in a moment of "getting up to date: But, it's slow enough trying to deal with 3. But when I get my current list of projects done .... I look forward in doing so.
I was not aware of 'Invalidate()". using your suggestion got OnPaint to work. But I need to, if I can, to continually go back and simply continue with the graph based on whatever mod the user makes to the basic computation process. And not have to rewrite the entire code each time I add some graph data. And Likewise that the red line would remain uneffected by a change in the 3 lines.

Here's the current version that works in that each time button 2 is clicked the blue line is extended while at the same time the red line created by clicking button 1 is not eliminated. which is what i need to have happen.But that leaves me with a question. When I first created it, in line with your suggestion to only use "Canvas" in the OnPaint function .... it created an error ie: MoveTo(500,250) as with Pen and LineTo led to "call to undefined function "MoveTo" And using a Form "OnPaint" Event was apparently not necessary???? I assume other components like button click have graphic aspect that recognizes MoveTo Line To and Pen

More generally, is there a file on my Builder Disk or the Program or a place in help or another book I can get that describes two things One. that sets forth the events or other ground work that has been included in a component. As for example, where can I find the info that a Button component includes recognition of MoveTo and LineTo and Pen? Or is there something I am missing that makes such a question inappropriate? Am I correct that Pen, LineTo and MoveTo are "Methods" that is "code" that accomplishes what they say. But as I found out yes you can use these "methods" in Button Click but I also found you CAN NOT use them directly in the Main Form. Or am I incorrect. And Am I correct that I now understand that "Invalidated" in the ButtonClick Function causes all all graphic material on the relevant form to be deleted? On does it require that the Form OnPaint Event to do the deleting?

Two, the header files are of course readable. Is the same true of the supporting code or is it binary? And if readable is it somewhere I can read it?

My main reference materials at the moment are the borland disk, Kent Reisdorph's 14 and 21 day books and of course the Program Help index. And I suppose help in XE5.

In any event thanks Antonio for your response which helped me change direction to something I hope continues to work.
Rowland
int x;
int GraphSet=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
String S;
S=GraphSet;
Label3->Caption=S;
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
GraphSet=2;

Label4->Caption=GraphSet;
Label15->Caption="2";
Label2->Caption="GraphSet=2 Code Draws Red Line";
Canvas->Pen->Color=clRed;
Canvas->MoveTo(400,130);
Canvas->LineTo(500,130);
GraphSet=10;

}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
GraphSet=3;
String S=GraphSet;
Label9->Caption=S;

Label15->Caption="3";
Label14->Caption="GraphSet=3 ButtonClick for loop 3 extends line 3 times";
x++;

if(x==1)
{

Canvas->Pen->Color=clBlue;
Canvas->MoveTo(400,250);
Canvas->LineTo(500,250);
}
else
if(x==2)
{
Canvas->Pen->Color=clBlue;
Canvas->MoveTo(500,250);
Canvas->LineTo(600,250);
}
else
{
if(x==3)
{
Canvas->Pen->Color=clBlue;
Canvas->MoveTo(600,250);
Canvas->LineTo(700,250);
}
}
}

{code}
Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: How to set pixels ...OnPaint...OnCreate MoveTo ..Line  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 5, 2016 5:51 AM   in response to: Rowland Stevens in response to: Rowland Stevens
El 5/1/16 a las 0:24, Rowland Stevens escribió:
Thank you very much for helping me get Borland to do what I want.

Here's the current version that works in that each time button 2 is clicked the blue line is extended while at the same time the red line created by clicking button 1 is not eliminated. which is what i need to have happen.

Are you sure? Try to minimize and restore the window. As you can see, the line is missing after restoring the window.

After that, try the following:

int x;
int GraphSet=0;
 
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    Label3->Caption=GraphSet;
}
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    GraphSet= 2;
    Label4->Caption=GraphSet;
    Label15->Caption="2";
    Label2->Caption="GraphSet=2 Code Draws Red Line";
 
    Invalidate();
}
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    GraphSet= 3;
    String S=GraphSet;
    Label9->Caption=S;
 
    Label15->Caption="3";
    Label14->Caption="GraphSet=3 ButtonClick for loop 3   extends line 3 times";
 
    if (x==3)
       x= 0;
    x++;
 
    Invalidate();
}
 
void __fastcall TForm1::FormPaint(TObject *Sender)
{
    if (GraphSet==2)
    {
        Canvas->Pen->Color=clRed;
        Canvas->MoveTo(400,130);
        Canvas->LineTo(500,130);
    }
    else if (GraphSet==3)
    {
       if(x==1)
       {
          Canvas->Pen->Color=clBlue;
          Canvas->MoveTo(400,250);
          Canvas->LineTo(500,250);
       }
       else if(x==2)
       {
          Canvas->Pen->Color=clBlue;
          Canvas->MoveTo(400,250);
          Canvas->LineTo(600,250);
       }
       else if(x==3)
       {
          Canvas->Pen->Color=clBlue;
          Canvas->MoveTo(400,250);
          Canvas->LineTo(700,250);
       }
    }
}

But that leaves me with a question. When I first created it, in line with your suggestion to only use "Canvas" in the OnPaint function .... it created an error ie: MoveTo(500,250) as with Pen and LineTo led to "call to undefined function "MoveTo"

You must be doing something wrong. Please show an example that produces the error.

And using a Form "OnPaint" Event was apparently not necessary????

Yes it is necessary as I have just shown to you. The OnPaint event is called each time that the system needs to repaint
the window content.

I assume other components like button click have graphic aspect that recognizes MoveTo Line To and Pen

No, Button1Click and Button2Click are functions of the TForm1 class which inherits many functions and properties from
the TForm class and from its ancestors (like the Canvas object).

Both MoveTo and LineTo are function of the TCanvas class; Pen is a property of the TCanvas class which contains a
pointer to an object of the TPen class.

I think the first thing you should do is read a C++ tutorial. And you should learn the concepts of class, objects,
encapsulation, inheritance, polymorphism, etc.
Rowland Stevens

Posts: 6
Registered: 2/27/14
Re: How to set pixels ...OnPaint...OnCreate MoveTo ..Line  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 5, 2016 10:25 AM   in response to: Antonio Estevez in response to: Antonio Estevez
You're right. When I minimize and then recall it Borland's Program chooses to delete what I want produced even tho I did not ask it be deleted.

Your suggested replacement works as you wrote it but unfortunately you repaint the entire button 2 from the beginning each time which I preferred not to do ;and the Invalidate() code of button 2 also chooses to delete the previous drawing of the red line made by button click 1 which I did not want it to do. In my real program there may be hundreds of previous graph entries that do not change.Only the new ones are effected by the comp change after the user modifies the computation program, as the whole purposes is to have several graphs available to compare . Maybe I can find a way to not have a minimize button
Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: How to set pixels ...OnPaint...OnCreate MoveTo ..Line
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 5, 2016 10:52 AM   in response to: Rowland Stevens in response to: Rowland Stevens
El 5/1/16 a las 19:25, Rowland Stevens escribió:
You're right. When I minimize and then recall it Borland's Program chooses to delete what I want produced even tho I did not ask it be deleted.

Your suggested replacement works as you wrote it but unfortunately you repaint the entire button 2 from the beginning each time which I preferred not to do ;and the Invalidate() code of button 2 also chooses to delete the previous drawing of the red line made by button click 1 which I did not want it to do. In my real program there may be hundreds of previous graph entries that do not change.Only the new ones are effected by the comp change after the user modifies the computation program, as the whole p
urposes is to have several graphs available to compare . Maybe I can find a way to not have a minimize button

As I said to you in my firt post: what you draw in the form's canvas is not persistent and you must draw all elements
each time that the system needed it.

Put a TImage component in your form (Image1) and use its Canvas property to draw on it.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Image1->Canvas->Pen->Color=clRed;
    Image1->Canvas->MoveTo(400,130);
    Image1->Canvas->LineTo(500,130);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    x++;
 
    TCanvas *Canvas= Image1->Canvas;
    if(x==1)
    {
       Canvas->Pen->Color=clBlue;
       Canvas->MoveTo(400,250);
       Canvas->LineTo(500,250);
    }
    else if(x==2)
    {
       Canvas->Pen->Color=clBlue;
       Canvas->MoveTo(500,250);
       Canvas->LineTo(600,250);
    }
    else if(x==3)
    {
       Canvas->Pen->Color=clBlue;
       Canvas->MoveTo(600,250);
       Canvas->LineTo(700,250);
    }
}
 
Rowland Stevens

Posts: 6
Registered: 2/27/14
Re: How to set pixels ...OnPaint...OnCreate MoveTo ..Line  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 21, 2016 2:31 PM   in response to: Antonio Estevez in response to: Antonio Estevez
Hi Antonio;
Thank you for your very prompt replies. Other things got in the way of really coming to further grips with this particular activity of mine, for a while . But now with your help I understand a lot better what I was trying to do and find that your "Image" solution works great. Thanks so much for your help, I really appreciate it. Rowland
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02