×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Class object as array

Class object as array

Class object as array

(OP)
Hi,

I have a custom class called shpNode, what I want to be able to do is create a number of objects based on this class into an array.

I can create the objects doing it this way;

WITH thisform.Container1
FOR _x = 1 to 10
cName = "shpNode" + ALLTRIM(STR(_x))
.NewObject(cName, "shpNode", "mClass")
cComm = "." + cName + ".Top = 50 + (_x * 10)"
&cComm
cComm = "." + cName + ".Left = 50 + (_x * 10)"
&cComm
cComm = "." + cName + ".Visible = .T."
&cComm
ENDFOR
ENDWITH

This all works fine, but ideally would like to reference the objects as array elements, have tried things like;

ADD OBJECT cName(_x) as shpNode
cName(_x) = .NewObject(cName, "shpNode", "mClass")

Am sure I am close, but can't figure it out and although been using VFP on and off for 20 years have never really used classes before!!!

Thanks

Darren

RE: Class object as array

Hello Darren and welcome to the forum.

I think the following should put you on the right lines:

CODE -->

DIMENSION laNodes(10)
FOR _x = 1 TO 10
  laNodes(_x) = CREATEOBJECT("shpNode")
  laNodes(_x).Top = 50 + (_x * 10)
  * set other properties in the same way
ENDFOR 


Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: Class object as array

(OP)
Hi Mike,

Thanks for the welcome, have been using the VFP forum on here for years under the username 'DarrenWard', VFP wasn't my native programming language but use it to write a large accounts and ERP application for the company I work for after attending a DevUK event back in the early 2000's hosted by Marcia Akins and Andy Kramek.

Have seen and admired your posts and commitment to the VFP community over the years. So not technically a newbie, but my questions will lead you to question that smile

So, to prove that point, had already dimensioned the array and if do the above, the code runs but the objects do not appear on the form, I assume I have to make reference to a parent class somewhere, in this instance thisform.container1 as I want the class objects (which are modified Shape objects) to appear within a container object places on a form using the form designer.

Also tried things like;

cName = "shpNode" + ALLTRIM(STR(_x))
laNodes(_x) = thisform.Container1.NewObject("cName", "shpNodes", "mClass")

although am not happy with the "cName" clause but it executes but just populates the array with .T. and is not referenceable as an object.

Need to do a little more reading up on ADD OBJECT and .NewObject I think.

You don't fancy coming out of retirement smile

Darren



RE: Class object as array

Quote (D--Ward)

code runs but the objects do not appear on the form

That's the key. Form elements must be names in the tree starting at the root thisform and every further name can have numbers, but can't be an array.
Even when you use native things that have a count, like an option group, the option buttons it creates are named option1, option2, option3 and not available as array option(n).

So all you can do is have a double way of referencing the object, storing them into an array aside from adding objects to the form.

One more interesting way to address objects in a container or form (or anything that can host controls) is using the Objects property. You can do a FOR EACH loControl IN thisform.container1.Objects, for example, and then don't need an array or index to go through a series of elements, especially if all objects in this container will be your shape class. If there's a mix of controls, you can of course check the loControl.class to be your class and skip over controls that are not your class.

Chriss

RE: Class object as array

I hadn't taken in that these objects were members of the form.

Basically, you have two approaches. You can stick with my original suggestion, except that the array would be an array property of the form. You create array properties in the same way as other properties, but you include a subscript in the name. In other words, in the form designer, go to forms / New Property, and then enter the names as something line aNodes(10).

Then, whenever you reference the array, you precede it with THISFORM. So the loop becomes something like:

CODE -->

FOR _x = 1 TO 10
  THISfORM.aNodes(_x) = CREATEOBJECT("shpNode")
  THISFORM.aNodes(_x).Top = 50 + (_x * 10)
  * set other properties in the same way
ENDFOR 


The point about that approach is that the objects are not really members of the form. They simply a bunch of objects that you happen to store in the form. In most cases, that's fine. But there is another approach.

To understand that, keep in mind that the form (like all container objects) already has a built in array that holds the individual controls on the form. It is called "controls", and you can address it by reference to THISFORM.Controls(_x) (where _x is a subscript).

This code will add the ten nodes directly to your form:

CODE -->

WITH thisform
  FOR _x = 1 TO 10
     lcName = "shpNode" + TRANSFORM(_x)
     .AddObject(lcName, "shpNode")
     loObj = EVALUATE("thisform.shpNode" + TRANSFORM(_x))
     loObj.top = 50 + (_x * 10)
     loObj.Left = 50 + (_x * 10)
    loObj.Visible = .t.
    ENDFOR 
ENDWITH 


If you then want to loop through the nodes in some way, you can do so using FOR EACH:

CODE -->

FOR EACH loNode IN THISFORM.Controls
  IF LEFT(loNode.Name, 7) = "shpNode"
    loNode.ForeColor = RGB(128, 128, 128)  && for example
   ENDIF
ENDFOR 


You need the test for loNode.Name because the Controls array will also contain all the other controls on the form, so you will need to make sure your code disregards these.

I hope this makes sense and that I haven't made it more confusing than it needs to be.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: Class object as array

I should add that, with my second approach (using AddObject), you can also address an object individually rather than as a member of an array. For example, if you want to do something special with the seventh shape, you could simply reference it as THISFORM.Shape7.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: Class object as array

(OP)
Hi Chris,

Thanks for the reply, think that is where I am/was getting confused. I understand the concept of root and elemental hierarchies, but was hoping there was a way of creating an array of classes and 'binding' them to a parent object/class.

I can do what I need to do with macro substitution, so applying the "thisform.ParentObject.MyClass" + str(_x) + ".property = " + _nValue and then running the macro, just looks messy to me in code so was hoping to use an array as looks more elegant and is how I have handled these issues with similar project types I have coded in the past.

The main application I have has hundreds of forms so use the FOR EACH loControl approach for loading things like form themes etc. for different users, so that didn't occur to use a similar approach for this, but seems like something worth exploring.

I may be back a bit, as am looking to achieve a lot that is new to me in VFP as the C# full stack developers I have working for me tell me it can't be done in VFP, and I do like a challenge. Am already ahead of them in terms of the backend data management and starting to assemble elements of the GUI. One of the firmware guys (we are creating our own hardware for this project) asked me this afternoon after seeing my progress if he could still get hold and VFP to take a look at it smile

Darren
p.s. sorry to drone on and get off topic, am not low level VFP technical but know how powerful it can be so get 'passionate' when people dismiss it without understand how versatile it is, and what a travesty it was that it dropped so long ago.

RE: Class object as array

Instead of iterating controls via Objects, another approach to reach all controls is via SetAll(). You can create a cascading "event", by adding a property you set via SetAll in all instances of a control of a specific class and then have a property assign method that is triggered by setting that property. It wouldn't even matter what value you set if you're only interested in catching all controls with this mechanism and let each of them act for itself.

It's a bit like the windows messages system redone in VFP style.

As an example, that's usually done in the init phase of controls/forms, think of translating any label caption, tool tip text, etc. to the currently selected language of an international application.
Let each control have a property translate with translate_assign method, then do thisform.SetAll("translate",.t.) and in the translate_assign method you lookup texts for label captions etc. and set them. Each control in itself best knows which labels of it need which translation, think of compound controls that are a bit more complex, for example a calendar month with many labels for weekdays.

One advantage of doing it that way instead of at init is you can switch language at any time and cascade the change to all currently open forms, each only needing one SetAll call.

I also think that's how Steven Blacks INTL toolkit does it.

Chriss

RE: Class object as array

I just want to add one more point. If this were my code, and I wanted to loop through and find all of these, I wouldn't rely on their names. Instead, I'd look for objects of this class:

CODE -->

FOR EACH loNode IN THISFORM.Controls
  IF UPPER(loNode.Class) = "SHPNODE"
    loNode.ForeColor = RGB(128, 128, 128)  && for example
   ENDIF
ENDFOR 

That, of course, assumes you want to hit all items of this class and not just a subset that have a particular name scheme. Also, Chriss is right that SetAll is better for simple tasks.

Tamar

RE: Class object as array

(OP)
Thanks all. I have used most of the above in one shape or form, think I just got fixated on the one path, but can see there are better ways of doing this.

Putting some context on what I am doing, I have a drawing of a building that I can pan/zoom within a container, during a physical commissioning process I am adding 'hardware' to the drawing represented by shapes. These shapes have different properties so will be different sizes, colours etc. As I pan/zoom the drawing the shapes need to resize and re-position, I never know how many elements there are going to be so they need to be dynamically added/deleted and changed, both individually and collectively.

I did this many years ago in VB 6.0 and way before that in a DOS CAD application I wrote, but that was all done with pure graphical elements, so the whole schema had to be re-drawn each time something changed, looked at the shape object this time around to take advantage if it's properties and methods rather than having to cycle through data/coordinates to see if mouse event etc. interact with pseudo objects.

I may revert back to old code I have elsewhere and convert it from VB to VFP as a lot of similarities in context especially with the graphical engine.

RE: Class object as array

Good to hear that this has been useful to you, Darren. It sounds like a perfect reason to use OOP. Tamar did a conference session a few years ago that might be relevant to your application. See Getting Your Head Around Business Objects

Quote:

VFP wasn't my native programming language but use it to write a large accounts and ERP application for the company I work for after attending a DevUK event back in the early 2000's hosted by Marcia Akins and Andy Kramek.

I might have met you at that event. My memory is fading, but I do recall attending (and speaking at) some conferences at the Microsoft campus in Reading, which Andy and Marcia attended. Or it might have been somewhere else.

Thank you for your kind words, by the way.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: Class object as array

I think that's quite simple. All shapes would need to react to a change of zoom factor by computing their default top,left,width, and height with the zoom factor. Panning becomes a step after that.
If shapes are child objects off a container, they are also clipped by it. so you can have negative coordinates by panning or coordinates becoming larger than container size by zooming or panning.

That's doable with the SetAll approach.

Chriss

RE: Class object as array

What you're doing reminds me of a project I worked on (that's referenced in the paper Mike linked). We were dealing with multiplexers and adding circuit boards to them and needed to show the whole thing graphically. The article talks only about the business object side of the thing, though it has some images of what I built. (Check out especially figures 2 and 5 of that article.)

The article doesn't talk about how I did the graphical stuff. I built a bunch of classes to represent the objects of interest and I used BindEvents() and Access and Assign methods to make containers filled with other containers and shapes and labels act like single objects. The paper does talk about how to link your business objects with your graphical objects.

Tamar

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close