custom class

A difficult question to ask… probably because I just misunderstood how to deal with.

Adding a custom canvas that has its methods, properties, etc., then putting an instance of this class in a window. Everything is ok.
Then in another window I need another canvas with many of the methods and properties of the custom canvas, so logically I will put there another instance of the original custom canvas.
The confusion comes with the Events. If in the Custom Canvas I’ve defined, for example, a Paint event, everything that happens there will then happens in each instance (will it?).
So, is the solution maybe just to raise in the Event Paint a myEventPaint and then allow for each instance do a different behavior? Or alternatively not to define any event in the Custom Canvas?
Which is the correct way? Or is there another better approach that I am missing?.

As far as understanding your question correctly, there shouldn’t be any problem with creating a custom (subclassed) Canvas control, with common logic in the Events of the subclassed control, then using each instance of your custom Canvas independently any number of times.

I think the only time you might get cross-over behaviour between each instance of your custom Canvas is if you use Static variables in the Events or Methods of your subclassed control - depending on how you use those Static vars of course.

I hope that helps.
Edited: hopefully for clarity.

umm, in the custom canvas I catch the mouse up event and this makes something happen in the canvas instance in window1, but the same thing also happens in the other instance in window2.

if you will reuse a event in the custom canvas control template make it inside.
if you like to have individual events you can do it there where you placed the control in the form,
and from there you could also call any method that do something.

i experienced that two (same) events is not possible in custom canvas template and in the used control.

then i would use the paint event in the form at the control and do what each need and do not use this event in the main control template.

if you use a event in the template control, yes this is used anywhere.
it can also be useful or you need to code the same again and again.

Hmm, maybe I’m not understand how you’re building your custom Canvas control or what you’re trying to achieve, but below is a link to a simple project that demonstrates Canvas Focus handling.


This project was from another discussion, but it shows a custom subclassed Canvas (called: CanvasButton in this case) with code in the Events, which are then reused for each of the three instances of the control in a window. Each of the custom Canvas’ behave independently when interacting with any of them.

Does that help to clarify what I mean?

Edited: project was built in 2019r3.1

Haven’t looked at your code, but if you implement the event inside the class itself, then that code is global to all instances, because it is inside the class. Normally, though, you want part or all of the event logic to reside in each instance. Then the code is local to the one instance only.

You achieve that by RaiseEvent. Example:

Function MouseMove(X as Integer, Y as Integer)
   // event code inside the class itself
End Function

This code is global to all instances. It also prevents you from adding a MouseDown event to any of the instances. Whereas

Function MouseMove(X as Integer, Y as Integer)
   // event code inside the class itself
   RaiseEvent MouseMove(X, Y)
End Function

This will allow each instance to implement local logic in addition to the logic in the class. Note that you also have to add the event definition to the class so it will be available to the instances.

Thanks all.
As Tim said, I should leave in the Custom al behavior that is common to all instances and raise events to allow each instance to do its own needs. But this means modifying a lot of code.

The question comes because I developed (badly as I see now) the custom canvas mainly thinking in the instance in the main window, and now, when I want to reuse it in another window, I see that, to do that, I must re-develop it, or create a new Custom Canvas with many of the methods duplicated (that is a thing always to avoid).
What is worse?, modifying all behavior on the original CustomCanvas or create a new one, and copy just the methods and properties needed?

What I would do is add the event definition to the class, move all the code from the class even to the instance. Put code in the class event to simply raise the event, so the instance event fires. Then slowly move common code back into the class event. Or skip that and copy/paste code from the main window instance to the other window instance and adjust the code to suit the new window.

Thanks Tim, this is what I just begin to do, with a lot of care.
Private properties on the Custom Canvas are not seen by the instance in the window, so I’ve had to make them public and refer with the “me.” to deal with them.
For example
in the instance I must use

me.mOldX = X

And the mOldX converted to public

Changing this will be a long and winding road.

my first class of canvas.checkbox

i don’t know how to differentiate the individual instances better.
In class I just asked for the name
but with every new instance a new query has to be added in the class.
How is it better

Thanks Rudolf, very interesting examples.

The most difficult thing for me is to know exactly where should things go. When a method is better placed in a module that in a window? Or, should it be better placed in the class? May a class method call a method from a module, or a method in a window? or use a property of the window? I know that all is possible, but is it convenient?.

As a rule, properties of a class should only be modified within the class, but most of the examples I saw don’t comply it.
Following this rule near all properties of a class should be computed properties with its Get/Set, but is someone doing this?

You will learn this by improving bad design decisions all the time.

And yes my properties almost always are private. I don’t do getters/setters but dedicated methods.

The book to learn about OOP is “Head First Design Patterns”. It doesn’t matter that the book is a bit older because it teaches principles. I’ve got the translated patterns at

[quote=489498:@Beatrix Willius]You will learn this by improving bad design decisions all the time.

And yes my properties almost always are private. I don’t do getters/setters but dedicated methods.

The book to learn about OOP is “Head First Design Patterns”. It doesn’t matter that the book is a bit older because it teaches principles. I’ve got the translated patterns at[/quote]

Yes you’re right it’s a question of err and learn of this.
I bought Head First Design Patterns when you recommended it some time ago, and I’m trying… to understand, not always with the success I will like to. It begins with a complicated situation, I never used the class interfaces because, maybe I didn’t need or I didn’t when to use it. (and that is Chapter one…)
Thanks Beatrix I know I need to study more.

I remember banging my head on that, too. The class interfaces make stuff look the same so that you can do different acts on the classes that implement them.

The classic OOP is animals. You have families, subfamilies and species (or whatever). That works up to a point.

The other way is through behaviour. To quote the book: if it quacks like a duck it may be a duck or a rubber one. You define the behaviour quacking. Each class that implements quacking can then say how they implement quacking. And then you let the patterns do their work by using the interface instead of the class.

2 examples:

  • My app archives emails. I have different email clients and IMAP accounts. These implement one interface. Now I can iterate over the list to archive and it doesn’t matter what is behind.
  • Then the app can write to Valentina, Filemaker or PDF. Here I have a factory. This is like an OOP if statement. Each format goes to a different class. I say “write an email to the database” and the factory handles the rest.

I understand the concepts (+/-), class interfaces, subclasses, etc., the difficulty comes at the real time. The animals case that quacks or, the person, and students and teachers are clear examples, as it is your email app, the difficult is to be able to see that this is that you need to implement in each case.
I’m reaching my objectives in the apps I develop but, I know that they could be done much better and with a cleaner code and that is always my dissatisfaction.

If you can achieve your goals then the design is okay. When you curse again and again or if you need to really really check what you did then it’s time for a redesign. I have an older design for my main window. It’s a bit creaky now but it works. The window still stay as is. My preferences window is as complex as the main window. This window is getting a complete overhaul because I can’t change the window as I want.

You need to start somewhere. Try to do an MVP so that the basis has a good architecture. The rest will come over time.

Thanks Beatrix,