I’ve tried to run one of my existing app that uses GDI+ (Advanced Graphics for Windows lib).
I’ll get an error in this line:
form = new GdiPlusStringFormat(StringFormatFlags.DirectionVertical or StringFormatFlags.NoClip)
Error: Undefined operator. Type GdiPlus.StringFormatFlags does not define “or” with type GdiPlus.StringFormatFlags.
StringFormatflags is a enum.
I know there are some changes in the Or functionality, but how do I solve this?
How about comparing Integer(StringformatFlags.DirectionVertical) or Integer(StringformatFlags.NoClip)?
@Ulrich Bogun That was also my first thought, but as GdiPlusStringFormat() takes a StringFormatFlags enum as parameter, it does not work. Did work in 2014r2.1. Sure hope this is a bug because this is something that I’ll do everywhere.
It isn’t; the previous behavior was a bug. Here’s the relevant release note from case 35645 :
@Joe Ranieri Not the answer I wanted to hear but thanks anyway. Switching to 2014R3 is going to be a huge untertaking for me. Pity we lost a great library like ‘Advanced Graphics for Windows’.
Personally I would switch away from using enums for this and switch to constants. Most of the work after that would be find/replace.
Something like this should work
form = new GdiPlusStringFormat( CType(StringFormatFlags.DirectionVertical, Integer) or CType(StringFormatFlags.NoClip,Integer))
[quote=149703:@Norman Palardy]Something like this should work
form = new GdiPlusStringFormat( CType(StringFormatFlags.DirectionVertical, Integer) or CType(StringFormatFlags.NoClip,Integer))[/quote]
Nope, you need to have another CType in there converting it back to a StringFormatFlags. The readability really stinks with this “fix.”
form = new GdiPlusStringFormat(CType(CType(StringFormatFlags.DirectionVertical, Integer) or CType(StringFormatFlags.NoClip,Integer), StringFormatFlags))
I’ve tried that also. No luck.
This lib was written by Aaron and has been a great asset for doing graphics in Windows. Unfortunately, there a lot of methods like this (very handy to use), and with a lot of overloading.
Sub Constructor(flags as StringFormatFlags, langId as UInt16 = 0)
Soft Declare Function GdipCreateStringFormat Lib kGdiPlusLib ( flags as StringFormatFlags, langId as UInt16, ByRef handle as Integer ) as Status
if IsGdiPlusSupported then
mLastResult = GdipCreateStringFormat( flags, langId, mHandle )
mLastResult = Status.UnsupportedGdiplusVersion
Soft Declare Function GdipCreateStringFormat Lib kGdiPlusLib ( flags as StringFormatFlags, langId as UInt16, ByRef handle as Integer )
could probably be rewritten as:
Soft Declare Function GdipCreateStringFormat Lib kGdiPlusLib ( flags as integer, langId as UInt16, ByRef handle as Integer )
And then use the integer() or CType() trick.
But as said, this lib is big. Aaron did a terrific job on this one.
@Bill Gookin Indeed very ugly, but this could at least save my current projects. Thank you very much!
My temporary fix for this is to create a method called “EnumOr” (I also have an EnumAdd) that is basically:
Function EnumOr(ParamArray varVals as Variant) As Integer
dim answer as Integer = 0
for i as Integer = 0 to varVals.ubound
answer = answer Or varVals(i)
That will Or as many as you put in, then you just have to CType it back once:
form = new GdiPlusStringFormat(CType(EnumOr(StringFormatFlags.DirectionVertical, StringFormatFlags.NoClip), StringFormatFlags))
At least it’s two fewer CTypes in there. I’m trying to figure out how I can convert to constants, but my PDF library is loaded with enum references in the methods, it’s going to be very difficult.
Indeed somewhat better. I’ll see tomorrow if I can come up with something, because this problem is going to repeat itself many times in my programs (750.000 lines of code total)
[quote=149731:@Bill Gookin]Nope, you need to have another CType in there converting it back to a StringFormatFlags. The readability really stinks with this “fix.”
form = new GdiPlusStringFormat(CType(CType(StringFormatFlags.DirectionVertical, Integer) or CType(StringFormatFlags.NoClip,Integer), StringFormatFlags))[/quote]
I did miss one to convert it back to the enum type
Please share if you do. My code is now hideous. (not that it was amazing before, but…)
I will if I find a more elegant solution!
@Bill Gookin just thinking something. Will the variant type you use not be depreciated in the long run? Hate to do all the work twice.
Variant will be around for some time on the same basis as string is
It doesn’t exist on iOS but I suspect thats really not a big deal for this code base
Indeed, it’s Windows only. Still, I think finding a elegant solution avoiding variant would be better, as that day will come eventually.
Enums you define are a new type
And there’s no means to define an Operator_Or for one (otherwise you could define it and be off to the races)
However, you could write an extension method that would OR two of you enums together and NOT use variants.
But the syntax would end up being slightly different than what you have currently but it would at least be type safe.
The change in the compiler prevents people from treating the new type, the enum you defined, as though it were just a simple integer variable and doing such fun things as
dim t as MyEnum = MyEnum.value + 7
which we’ve seen variations of and bug reports about
and you can imagine the other variations with all the numeric operators (and, or, not, xor, +, -, etc)
Something like (this IS forum code so its really the IDEA more than correct code)
Or( extends first as StringFormatFlags.DirectionVertical, second as StringFormatFlags.DirectionVertical) as StringFormatFlags.DirectionVertical
dim firstInt as integer =CType(StringFormatFlags.DirectionVertical, Integer)
dim secondInt as integer = CType(StringFormatFlags.NoClip,Integer)
return CType(firstInt or secondInt, StringFormatFlags)
Thanks for the tip @Norman Palardy I’ll look into that solution.