The <> operator doesn't work when…

The <> operator doesn’t work when comparing BevelButton icons. The = operator works in this snippet for 8 BevelButton members using icons to represent their state:

if BtnBand(index).icon = Icon1 or BtnBand(index).icon = Icon2 then //do nothing else if index=0 then PopupPatches.enabled = false For i As integer=1 to 7 EfMouseCtrls(i).enabled = false next BtnBand(index).icon = Icon1 else BtnBand(index).icon = Icon1 end if

The following snippet using <> should accomplish the same thing but doesn’t.

if BtnBand(index).icon <> Icon1 or BtnBand(index).icon <> Icon2 then if index=0 then PopupPatches.enabled = false For i As integer=1 to 7 EfMouseCtrls(i).enabled = false next BtnBand(index).icon = Icon1 else BtnBand(index).icon = Icon1 end if

Is this a bug or am I misunderstanding the use of <>?

I can’t imagine that <> would work for comparing pictures.

A simple workaround would be to make your own bevelButton subclass with an additional property where you could store a value that indicates the current state (i.e. whatever the icon represents). Then you could compare that property instead of the icon values.

That’s a good idea Marc however I still don’t understand why = works while <> doesn’t.

I’m not sure about that, either. It’s not something I’ve ever tried. In theory it’s not comparing the actual picture data but simply the reference, just like it does with objects (when you say if object1 <> object2 then...), but <> works in that case, so I don’t know why it wouldn’t here. Perhaps it’s a bug?

= and <> compare object references not the data

Norm, that’s my misunderstanding, I don’t know whatexactly is an objects reference. What for example would be the reference for an icon?

In your first block, the code will do nothing if either of the icons is a match. It will only do something if neither match.

In your second block, the code will do something if either of the icons don’t match, so it’s a change in logic. Could that have something to do with what you’re seeing?

The first block is my workaround for the second block. Of course it’s a change in logic but the question is why does = work while <> doesn’t. Give the replies thus far, reason tells me neither should work.

BTW Marc, I should have mentioned that any one of the 8 BevelButtons can have any one of the icons assigned to it depending on how the user clicks on them. For example, clicking on a button changes its icon as does Option-clicking or Command-clicking on them. So I’m not sure your workaround would work because I would still need to compare which button currently has which icon. So I’m back to square one in having to compare Icons.

But are you sure “=” is working? Are there times when your code doesn’t run in the first block? (Are the times when it doesn’t get to the code in the first “else” block?)

To answer your question about references, let’s say you have a class with one property, a double. Your constructor is:

Class DoubleClass
  Constructor (value as double)
    mValue = double
  End

Now you create an instance of that class:

myClass = new DoubleClass( 5.0 )

Then you assign it to another variable:

myClass2 = myClass

At this point, you do not have two copies of the object, you have one object that is assigned to two variables. Since it’s the same object, and what each variable holds is a reference to that object, then myClass = myClass2. Now let’s say you do this:

myClass = new DoubleClass( 5.0 )
myClass2 = new DoubleClass( 5.0 )

Even though the values they hold are exactly the same, the objects are different, the references to the objects are different, so myClass <> myClass2.

In your example, you are trying to compare pictures, but unless the pictures are the same object (not just the same picture), it will always say they are not equal.

OK
So lets try this code

   dim d1 as new date
   dim d2 as date = d1

The first line creates a new date that holds todays date
The second line creates a new reference to the SAME date (object)
Now if you do

d2.totalseconds = d2.totalseconds + 86400

this would make D2 hold the date for the next day
BUT - and heres the trick - D1 also refers to the same object (basically there are 2 “names” for the same thing)
So if you were to look at the date that D1 supposedly holds it will be the same as D2’s because they both refer to the same object
For instance some people might call you “Peter” and others might call you “Pete” - two names same object.

If you then do

if d1= d2 then
    msgbox "d1 IS the  same object as d2"
end if

This will be true because they both refer to the same object (which also means they represent the same date)

Now if we do this a little different

   dim d1 as new date
   dim d2 as new date

The first line creates a new date that holds todays date
The second line creates a new date that holds todays date
Now if you do

d1.totalseconds = d2.totalseconds

they both have data that represents the exact same date
But if you then do

if d1= d2 then
    msgbox "d1 IS the  same object as d2"
end if

This will be NOT true because while they both refer to the same date they are two different objects

See page 125 of the User Guide - Fundamentals book about this

Well, so far it works perfectly every time.

Thank you and Norman for the explanation.

Maybe a better question would be how do I compare whether two icons are the same or not.

[quote=23707:@Peter Gattignolo]Well, so far it works perfectly every time.

Thank you and Norman for the explanation.

Maybe a better question would be how do I compare whether two icons are the same or not.[/quote]

It depends on what you mean by “the same”?

  • they point to the same picture object in memory?
  • they point to different picture objects, but the actual picture data is the same? (not the same object, but an exact copy of it)
  • etc.

Well Michael, for my needs it would be pointing to the same picture object in memory. Is that what I would compare, its location in memory?

You should be able to use the equals sign.

I suspect, however, that if you set the BevelButton.Icon in the IDE, that the IDE may actually make a copy of the picture object when the code runs, in which case the equals sign won’t work.

One way around this would be to set the icon at runtime:

BevelButton1.Open
  me.icon = TheIconPicture

On a side note: it sounds as if you are using the icon as a flag to control some other program behavior. While not exactly wrong, this may end up being an inelegant design in the long run - it might be cleaner to have some other variable which indicates the state or mode your UI is set to.

If you want to determine whether two references refer to the same in-memory object, use the Is operator:

if BtnBand(index).icon Is Icon1 or BtnBand(index).icon Is Icon2  then  if index=0 then

Michael, that’s exactly what I’m doing, visual feedback to the user as to the state of the button.

While I agree with everybody’s in-depth analysis of object comparisons, I believe you have a simple programming logic error. The inverse of

if BtnBand(index).icon = Icon1 or BtnBand(index).icon = Icon2 then
is
[/code]
if BtnBand(index).icon <> Icon1 AND BtnBand(index).icon <> Icon2 then
[/code]

Andrew, I’m certainly going to try it, hope the ‘is not’ operator works as well.

My suggestion was based on you setting the subclass’s property with whatever value would equate to the picture value. For example, let’s say you add an integer property called “myState” to the subclass. Whenever you set an item to icon1, you would also do myState = 1, and so on. Thus the myState property would track whatever the current icon is, without you actually having to compare the icons themselves.

It’s a tiny bit of extra work compared to just tracking the icons, but it seems more reliable.