Problems with changing Realbasic program to Xojo

Sometime ago, I wrote an App for doing engineering calculations in Real basic. The input data is is entered in one window and the calculation performed with the press of a button. The output is too extensive to fit on the same window so I use another window to display the output. I use a menu item to call the second window. Without showing you with all the code, this is an example of what I have done:

Window2.show

Window2.canvas1.graphics.drawstring “Magnification Factor”, 20,30
Window2.canvas1.graphics.drawstring “=”, 270, 30
Window2.canvas1.graphics.drawstring str(m) , 300,30 //m is calculated in window1.

This used to work well in Real basic but when I try and run it in Xojo, all I get is a blank canvas.

Has anyone got any suggestions?

PS

Drawing commands must be done INSIDE the Paint Event of a CANVAS, access to the graphics property of a CANVAS from outside the PAINT event has not been supported for a number of versions now. (And while it will require refactoring your program, it is a GOOD thing in the end)

Add m as a property on Window2 and set its value when Window 2 opens. Then in the Paint event of Canvas1 you would have:

g.drawstring "Magnification Factor", 20,30 g.drawstring "=", 270, 30 g.drawstring str(m) , 300,30

use a tabpanel to display the results on the same window but on the second panel
then you will have to deal with only one window.

It is not recommended to draw like this outside of the paint event. But if you have a lot of these, what you can do is draw into the backdrop picture. It maybe easier than to refactor everything in the Paint event.

  • Create a backdrop picture to Canvas 1 in its Open event
  • myPic is a Picture property of the window, or subclass the canvas.

myPic = New Picture(me.width, me.height) // Use GDIPlus if on PC me.backdrop = myPic
Then in your program, you can do :

Window2.canvas1.backdrop.graphics.drawstring "=", 270, 30 Window2.canvas1.invalidate // To make sure it updates graphics

As you see, it is almost the same syntax, and you can probably proceed with a simple search&replace.

Since no one else has asked, I guess I will.
Is there any particular reason why you want to display the text in a canvas instead of a text field?
I’m guessing that there are graphics in there as well, but it seems worthwhile to ask.

Firstly, thank you to Dave and Richard. They both explained the cause of my problem and brief play around with the code has shown that I should be able to make it work. With regard to the other questions: Robert, the shear number of data outputs plays against the use of text boxes in another window: Jean-Yves, I could use a tabpanel but the visual appearance of the white canvas with text is visually better; Michael your suggestion is noted - thank you.

What this issue has done is highlight to me another potential problem. I have another program where I make calculations and then plot a graph on a canvas which sits in the same window. When I open the window, the canvas opens with gridlines and X and Y markers. It is only after I press a button that the graph is drawn. This does not appear to be possible with the Paint event.

It is.

If you have 2 routines that draw into the canvas when you press the button based on some variables:
Have a variable that determines whether you are ready to draw or not, default to false.
When you have all the info you need and the button is pressed, set the variable to true

In the paint event, you get a g as graphics parameter.
Put your drawing code into the paint event.
All your current drawing which looks like this: Window2.canvas1.graphics.drawstring “Magnification Factor”, 20,30

replace Window2.canvas1.graphics with g
making it into g.drawstring “Magnification Factor”, 20,30

And thats it.

then you can put a canvas inside the tabpanel !

Another thing you CAN do,

  • create a PICTURE object… this also has a “graphics” property that works the same as that of a canvas
  • route all you drawing routines to draw on “pic.graphics”
  • then in the PAINT EVENT of the actual canvas… simply put “g.drawpicture pic,0,0,g.width,g.height”
  • and use INVALIDATE on the canvas when ever you want it to be updated.

Thanks fellas. I think I have confused things by adding an additional problem regarding the graph. I’ll have to look at your suggestion Dave but I am struggling to understand how this will work when the paint event occurs when the canvas is opened. I need to change the canvas or picture after I calculate the graph.

With regard to the original problem, I have managed to get it to work but I have had to make a lot of global properties which might come and bite me at a later date. The other thing a forgot to mention is that I have four windows for performing four different set of calculations and I use the same window for displaying the output. The display is different for each set of calculations. How will I differentiate between the output from the different windows?