Thibault Falise
Thibault Falise

Reputation: 5885

Flags in VB6 does not return a correct value

I am currently trying to use a bit flag enum in a VB6 / COM project. However, when trying to read values from the enum, I get inconsistent results.

Here is the enum definition :

Enum Fruits
    None = 0
    Apple = 1
    Strawberry = 2
    Lemon = 4
End Enum

I have an object which exposes a property of type Fruits

Public Get AvailableFruits as Fruits

The code that should be able to read the value is used to show / hide a label depending on the values of each bit of the enum :

lblAppleAvailable.Visible = basket.AvailableFruits And Fruits.Apple

When this code is executed and I have basket.AvailableFruits = 0, I get True as result.

Any idea of what could cause this behavior ?

Edit :

I have tried with the different values of the enum :

basket.AvailableFruits = 0
basket.AvailableFruits And Apple        // Returns True
basket.AvailableFruits And Strawberry   // Returns True
basket.AvailableFruits And Lemon        // Returns False

As a side node, when debugging the code, If I put the expression in a watch expression, I get the correct value; but when the expression is evaluated in my code, it still returns True.

I tried using a different check syntax :

(basket.AvailableFruits And Fruits.Apple) = Fruits.Apple

Still getting True when basket.AvailableFruits = 0 :-(

Solution

After having tested different solutions, I have been able to narrow the problem to the COM component. The original coder of this component had a pointer set to 0 instead of returning 0 as a value, which caused the problem when trying to read the value.

I have selected FlipScript answer because of the helper function which seems a good tip to improve the readability of the code.

Upvotes: 7

Views: 1798

Answers (2)

Flipster
Flipster

Reputation: 4401

To test the value of the flag, use something like this:

lblAppleAvailable.Visible = (basket.AvailableFruits And Fruits.Apple) = Fruits.Apple

After you do the "AND", you still need to see if the resulting value equals the flag value (or anything other than 0, really).

You could also create a little helper function:

Private Function HasFruitFlag(Check As Fruits, Flag As Fruits) As Boolean
    HasFruitFlag (Check And Flag) = Flag
End Function

And you could call it like this:

lblAppleAvailable.Visible = HasFruitFlag(basket.AvailableFruits, Fruits.Apple)

Upvotes: 8

wqw
wqw

Reputation: 11991

Try using a local var

    Dim LocalFruits As Fruits

    LocalFruits = basket.AvailableFruits
    Debug.Print (LocalFruits And Apple) <> 0
    Debug.Print (LocalFruits And Strawberry) <> 0
    Debug.Print (LocalFruits And Lemon) <> 0

Also, you might want to use a less error-prone declaration of the enum like this

Enum Fruits
    Apple = 2 ^ 0
    Strawberry = 2 ^ 1
    Lemon = 2 ^ 2
End Enum

Upvotes: 0

Related Questions