From: Paulo on 24 Mar 2010 02:42 Hi to all, After searching the net for possible solutions and not finding anything useful I came for your advice. I have a collection of objects with the properties X and Y, which are the coordinates of vertices (points). I need to add an Index property to those objects. I know that the actual index of each vertex in the vertices collection may change after adding to or removing elements from the collection. Is it possible to retrieve the actual index of each vertex in the collection and assign it to a read-only property, an Index property? I tried the code below. Notice that "Friend Property Let Index" is declared as Friend. Unfortunately it is not possible working with this because the following error is raised: Run-time error '451': Property let procedure not defined and property get procedure did not return an object. It works fine if I declare "Public Property Let Index", but I want the property to be read-only to prevent the programmer (me!) from changing the Index value. Any advice, including a completely different approach? TIA, Paulo ----------------------------------------------------- Code for the Vertex Class (Global Multiuse) Class name is: Vertex Filename is: cls_Vertex.cls ----------------------------------------------------- Option Explicit Private mlng_Index As Long 'local copy Private mdbl_X As Double 'local copy Private mdbl_Y As Double 'local copy Public Property Let Y(ByVal Value As Double) mdbl_Y# = Value# End Property Public Property Get Y() As Double Y# = mdbl_Y# End Property Public Property Let X(ByVal Value As Double) mdbl_X# = Value# End Property Public Property Get X() As Double X# = mdbl_X# End Property Friend Property Let Index(ByVal Value As Long) mlng_Index& = Value& End Property Public Property Get Index() As Long Index& = mlng_Index& End Property ----------------------------------------------------- Code for the collection Vertices Class (Global Multiuse) Class name is: Vertices Filename is: cls_Vertices.cls ----------------------------------------------------- Option Explicit Private mCol As Collection Public Function Add(X As Double, Y As Double) As Vertex Dim obj_Vertex As Vertex Dim lng_Counter As Long Set obj_Vertex = New Vertex With obj_Vertex .X# = X# .Y# = Y# End With mCol.Add obj_Vertex For lng_Counter& = 1& To mCol.Count& mCol.Item(lng_Counter&).Index& = lng_Counter& Next lng_Counter& obj_Vertex.Index& = lng_Counter& - 1& Set Add = obj_Vertex Set obj_Vertex = Nothing End Function Public Property Get Item(Index As Long) As Vertex Set Item = mCol(Index&) End Property Public Property Get Count() As Long Count& = mCol.Count& End Property Public Sub Remove(Index As Long) Dim lng_Counter As Long mCol.Remove Index& If mCol.Count& > 0& Then For lng_Counter& = 1& To mCol.Count& mCol.Item(lng_Counter&).Index& = lng_Counter& Next lng_Counter& End If End Sub Public Property Get NewEnum() As IUnknown Set NewEnum = mCol.[_NewEnum] End Property Private Sub Class_Initialize() Set mCol = New Collection End Sub Private Sub Class_Terminate() Set mCol = Nothing End Sub ----------------------------------------------------- Code for testing: Paste the code to the declarations section of a form with a command button Command1, and two list boxes, List1 and List2. ----------------------------------------------------- Option Explicit Private Sub Command1_Click() Dim obj_Enum As Vertex Dim obj_Item As Vertex Dim col_Items As Vertices Dim str_Info As String Dim lng_Counter As Long Set col_Items = New Vertices For lng_Counter& = 1& To 5& Set obj_Item = New Vertex With obj_Item .X = CDbl(lng_Counter&) .Y = CDbl(lng_Counter&) col_Items.Add .X, .Y End With Next lng_Counter& If col_Items.Count > 0 Then For Each obj_Enum In col_Items With obj_Enum str_Info$ = Format$(.Index&, "000") & " - ( " & .X & " , " & .Y & " )" List1.AddItem str_Info$ End With Next obj_Enum End If col_Items.Remove 2 Set obj_Item = New Vertex With obj_Item .X = CDbl(100) .Y = CDbl(100) col_Items.Add .X, .Y End With If col_Items.Count > 0 Then For Each obj_Enum In col_Items With obj_Enum str_Info$ = Format$(.Index&, "000") & " - ( " & .X & " , " & .Y & " )" List2.AddItem str_Info$ End With Next obj_Enum End If End Sub -----------------------------------------------------
From: Ivar on 24 Mar 2010 05:14 I've not tried your code just had a read thru it. If you want to make a property Read Only then declare the Let as private This looks strange: For lng_Counter& = 1& To 5& Set obj_Item = New Vertex With obj_Item .X = CDbl(lng_Counter&) .Y = CDbl(lng_Counter&) col_Items.Add .X, .Y End With Next lng_Counter& Shouldn't it be just For lng_Counter& = 1& To 5& Set obj_Item = New Vertex col_Items.Add CDbl(lng_Counter&),CDbl(lng_Counter&) Next Maybe I'm missing something Ivar
From: Larry Serflaten on 24 Mar 2010 09:19 "Paulo" <nospam.pmpcosta(a)netcabo.pt> wrote in message > I tried the code below. Notice that "Friend Property Let Index" is declared > as Friend. Unfortunately it is not possible working with this because the > following error is raised: > > Run-time error '451': > Property let procedure not defined and property get procedure did not return > an object. > I tried a project with just the X and Y and Index properties and had no trouble setting the Let side to Friend (using VB5). However, one way to give your component special access to your objects (other classes) is to define a private interface and have your object(s) implement that interface. Then when you need access you route your calls through the interface. In your case your Vertex class would implement a second interface (IVertex) and contain only the Get side of the Index property. The interface would expose the Let side: Public Function Add(X As Double, Y As Double) As Vertex Dim obj_Vertex As Vertex Dim obj_Setter As IVertex Dim lng_Counter As Long Set obj_Vertex = New Vertex With obj_Vertex .X# = X# .Y# = Y# End With mCol.Add obj_Vertex Set Add = obj_Vertex ' Refactor the re-indexing ??? For lng_Counter& = 1& To mCol.Count& Set obj_Setter = mCol.Item(lng_Counter&) obj.Setter.Index = lng_Counter& Next lng_Counter& Set obj_Setter = Nothing Set obj_Vertex = Nothing End Function LFS
From: Paulo on 24 Mar 2010 16:08 "Ivar" <ivar.ekstromer000(a)ntlworld.com> wrote: > Shouldn't it be just > For lng_Counter& = 1& To 5& > Set obj_Item = New Vertex > col_Items.Add CDbl(lng_Counter&),CDbl(lng_Counter&) > Next > > Maybe I'm missing something Thanks, you're correct. I missed that part... Paulo
From: Paulo on 24 Mar 2010 16:30 Hi Larry, It works very good with one remark: the IVertex interface class may not to be Private, because of the compile error: �Private object modules cannot be used in public object modules as parameters or return types for public procedures, as public data members, or as fields of public user defined types.� But no problema with interface beeing visible. The Index property will be very usefull for my project. Thanks a lot for your advice, Larry. Paulo
|
Pages: 1 Prev: Position Combo on MSFlexgird specific row/column Next: GDI32 functions |