Oberon Community Platform Forum

Development => ETH Zonnon => Topic started by: GDC on October 30, 2010, 09:47:15 PM



Title: Problem with Enumeration type variables
Post by: GDC on October 30, 2010, 09:47:15 PM
Hello,

I'm having a hard time setting a specific shortcut key combination (i.e. Ctrl+N) in a menu item control.

Class 'System.Windows.Forms.ToolStripMenuItem' has a property called 'ShortcutKeys' which is of type 'Keys'.
'Keys' is an enumeration type containing all the possible keys you can press on a keyboard.

I have no problem assigning such a key when it's only one key.
e.g. MyMenuItem1.ShortcutKeys := Forms.Keys.F1;

The problem is when it's a combination of keys, like Ctrl+N. The combined key is the bitwise OR of both keys.

The following statement does not work (no '+', 'OR' or '|' operator defined on enum types)
  MyMenuItem1.ShortcutKeys := Forms.Keys.Control + Forms.Keys.N;

Converting using the type name (as per section 5.3.12.1 in the Zonnon Language Report) does not work either
  MyMenuItem1.ShortcutKeys := Forms.Keys(integer(Forms.Keys.Control) + integer(Forms.Keys.N));

Does anybody know how this can be accomplished in Zonnon ?

Thanks,


Title: Re: Problem with Enumeration type variables
Post by: cfbsoftware on October 30, 2010, 11:56:52 PM
In Component Pascal for .NET I use the 'Shortcut' ENUM already defined in Windows Forms. I guess in Zonnon it would be something like:

MyMenuItem1.ShortcutKeys := Forms.Shortcut.CtrlN;



Title: Re: Problem with Enumeration type variables
Post by: GDC on October 31, 2010, 04:35:55 PM
Thanks for the tip.

Unfortunately this does not work either. 'Keys' and 'Shortcut' are two distinct enum types and are therefore not assignment compatible.

I could use the (depreciated) 'MenuItem' control instead of the newer 'ToolStripMenuItem', but that would be a step back. ('MenuItem' uses the 'Shortcut' enum type instead of the 'Keys' enum type).

I may eventually go that route, but still: How can you 'type cast' an enum variable in Zonnon ?

I tried the following statement:
  MyMenuItem1.ShortcutKeys := Forms.Keys.ToObject(Forms.Keys,integer(Forms.Keys.Control) + integer(Forms.Keys.N));

No luck. Compiler says “Types 'Keys' and 'Object' are not assignment compatible”


Title: Re: Problem with Enumeration type variables
Post by: cfbsoftware on November 02, 2010, 12:29:04 AM
Sorry for the false hope. Component Pascal just treats .NET enumerated types as named constants so there is no type-checking involved.

I've not been able to find any way in Zonnon of converting one enumerated type to another. You can convert an enumerated type to an integer, but I also can't find a way of converting an integer to an enumerated type.


Title: Re: Problem with Enumeration type variables
Post by: cfbsoftware on November 03, 2010, 04:10:48 AM
Until somebody comes up with something better you can reference the attached C# function to do the type conversion for you. In your Zonnon code you then have something like:

import Cfb, System.Windows.Forms as Wfm;

var
  k: Wfm.Keys;

  k := Cfb.Convert.ToKeys(Wfm.Shortcut.CtrlO);


Title: Re: Problem with Enumeration type variables
Post by: GDC on November 04, 2010, 03:41:40 AM
Thanks for all the help.

I adjusted the Zonnon code, build a dll file from the cs file, added a 'reference' to the dll file in Zonnon Builder, compiled the Zonnon code and got the following error: 'Internal error in compiler (Unresolved assembly reference not allowed: System.Windows.Forms.)'

When I comment out the C# call, it compiles just fine.

Zonnon code:
Code:
module Main;

import
 System.Windows.Forms.Keys as Keys,
 System.Windows.Forms.KeysConverter as KeysConverter,
 Cfb,
 System.Windows.Forms as Forms;

var
 k1, k2, k3: Keys;
 i1, i2, i3: integer;
 KC: KeysConverter;

begin
 k1 := Keys.Control;
 k2 := Keys.N;

(* Convert Keys to integer *)
 i1 := integer(k1);
 i2 := integer(k2);
 KC := new KeysConverter;
 writeln("k1 = ":5,KC.ConvertToString(k1):1," (":2,i1:1,")":1);
 writeln("k2 = ":5,KC.ConvertToString(k2):1," (":2,i2:1,")":1);
 writeln;

(* Convert integer to Keys *)
 i3 := i1 + i2;
 writeln("i3 = ":5,i3:1);
 k3 := Cfb.Convert.ToKeys(i3);

(* Validate conversion *)
 writeln("k3 = ":5,KC.ConvertToString(k3):1," (":2,integer(k3):1,")":1);
 readln
end Main.

PS. I modified the C# program slightly so that it would convert from Int32 instead of Shortcut.
Code:
using System;
using System.Windows.Forms;

namespace Cfb
{
    public class Convert
    {
        public static Keys ToKeys(Int32 i)
        {
            return (Keys)i;
        }
    }
}


Title: Re: Problem with Enumeration type variables
Post by: GDC on November 06, 2010, 03:47:14 AM
Finally got this to work.

This has been quite a frustrating experience. Just wanted to share some of the issues I encountered and how I got past it.

1. There seems to be no clean, elegant way in Zonnon to convert an integer into an Enum type variable. You could argue that Zonnon, being a descendant of Pascal, Modula and Oberon, is a strongly typed language and as such does not allow this kind of conversions. However, there are situations where this comes in handy. I my case, to generate the Ctrl+N shortcut key. To get this to work in Zonnon you need to use the C# function provided by Chris Burrows. Thanks Chris !

2. There are some obscure rules governing 'reference' compatibility between an external C# assembly and the Zonnon generated assembly. This is probably more a .NET issue and not really Zonnon specific. The compiler generated error 'Internal error in compiler (Unresolved assembly reference not allowed: System.Windows.Forms.)' wasn't that helpful either. Being a newbie, and not understanding .NET assemblies that well, trial-and-error got me past this problem. I tried a lot of things including removing all 'references' that are not needed but got included by Visual C# Express.

3. The Cfb.dll file needs to be located in the same directory as the Zonnon executable. This does not generate a compiler error but you will get a runtime error indicating that the Cfb.dll assembly could not be found.

Hope this helps.