150
Lescasse Consulting Using .Net with cse Made Easy! March 25, 2014 GalleryOne, Fort Lauderdale, Florida by Eric Lescasse Lescasse Consulting 18 rue de la Belle Feuille 92100 Boulogne France Tel : (+33) 1 48 25 40 23 Mobile : (+33) 6 47 98 13 61 [email protected] http://www.lescasse.com

Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

  • Upload
    buinhu

  • View
    221

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Lescasse Consulting

Using .Net with ⎕⎕⎕⎕cse Made Easy!

March 25, 2014

GalleryOne, Fort Lauderdale, Florida

by Eric Lescasse

Lescasse Consulting

18 rue de la Belle Feuille

92100 Boulogne

France

Tel : (+33) 1 48 25 40 23

Mobile : (+33) 6 47 98 13 61

[email protected]

http://www.lescasse.com

Page 2: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 2

Table of Contents

Introduction .............................................................................................................................................................. 4

The Basic Idea ........................................................................................................................................................... 4

First a little Background History ............................................................................................................................... 5

Part 1: APL+Win Objects........................................................................................................................................... 7

Understanding APL*Win Custom Objects ................................................................................................................ 7

zObjects ................................................................................................................................................................ 7

Anatomy of a zObject ........................................................................................................................................... 7

Documentation................................................................................................................................................... 11

Creating our First Custom Objects ......................................................................................................................... 13

Using zObject Technology for Visual Objects ......................................................................................................... 19

MultiCast Events ............................................................................................................................................. 22

Analyzing the zzsimpleedit function ................................................................................................................... 23

The wherelc property ..................................................................................................................................... 23

Using more zObjects properties and methods ............................................................................................... 24

Notes about the wherelc property ................................................................................................................. 25

The margins and gaps properties ................................................................................................................... 26

The Anchor property ...................................................................................................................................... 27

The MinimumSize property ............................................................................................................................ 30

A more sophisticated example ............................................................................................................................... 31

zEdit and zEditNum ........................................................................................................................................ 35

Part 2: Creating APL+Win .Net Objects using ⎕cse ............................................................................................... 40

Introduction ............................................................................................................................................................ 40

The Challenge ......................................................................................................................................................... 40

The Constraints ...................................................................................................................................................... 40

The zzCSE Utility ..................................................................................................................................................... 41

On our way to building a zNetControlTemplate object ......................................................................................... 41

Supporting the wherelc and anchor properties with ⎕cse .Net controls ............................................................. 46

Raising the Bar ........................................................................................................................................................ 48

First Example ...................................................................................................................................................... 49

Creating the Visual Studio User Control DLL Project ...................................................................................... 49

Compiling the DLL ........................................................................................................................................... 52

First Use of our Calculator User Control in APL .............................................................................................. 53

Page 3: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 3

Using the Verbose User Defined Property ..................................................................................................... 55

The verbose property lets you see what ⎕cse instructions are run in the background when you use your

object. ............................................................................................................................................................. 56

Using zCalculatorDX Properties and Methods ............................................................................................... 56

Defining APL Object Properties in zCalculatorDX ........................................................................................... 61

Raising the Bar one Step further: on our way to an Object Code Generator ........................................................ 64

The zReflection object ............................................................................................................................................ 64

Automatically Retrieving Documentation ...................................................................................................... 66

Ready for developing a Code Generator ........................................................................................................ 68

Enums ................................................................................................................................................................. 74

The zCommonDialog Object ............................................................................................................................... 77

Type Conversion: the zConverters object .............................................................................................................. 81

The zConverters C# class .................................................................................................................................... 82

Using the zGenerate Class ...................................................................................................................................... 87

Converting .Net Forms or Dialog Boxes ............................................................................................................. 87

Common Dialog Boxes .................................................................................................................................... 87

A complete and fully functional Rich Text Editor ........................................................................................... 87

Converting Standard .Net Framework Controls ................................................................................................. 90

Getting the list of standard .Net Framework Controls ................................................................................... 90

The zLinkLabel and zWebBrowser Example ................................................................................................... 92

The zCheckedListBox Example ....................................................................................................................... 95

The zNotifyIcon Example ................................................................................................................................ 98

Other Examples ............................................................................................................................................ 100

Converting Third Party Controls ....................................................................................................................... 100

Examples Shown Earlier ................................................................................................................................... 101

The zMapDXControl example ....................................................................................................................... 101

The zSpreadsheetDXControl example .......................................................................................................... 107

Converting Non Visual Controls: the zRegex example ..................................................................................... 114

Conclusion ............................................................................................................................................................ 118

Appendix 1: Sample C# .Net Framework Object converted to an APL+Win zObject ........................................... 119

Appendix 2: The C# zRegex Class ......................................................................................................................... 147

Appendix 3: Installing the zObjects software ...................................................................................................... 150

Page 4: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 4

Introduction

Let’s start with an unusual introduction!

The title of my Paper is not quite proper!

Let it be straight: it is not going to be “easy” to use ⎕cse unless you know quite a bit of C# and of the .Net

Framework.

But, what I have done and what you’ll discover in this Paper may make your life much easier if you want to

benefit from .Net through the use of APL+Win v14+ ⎕cse and the benefits you can get from .Net as an

APL+Win User are immense!

So the title of my Paper should have rather been:

Using .Net with ⎕⎕⎕⎕cse Made Easier!

There will be 2 parts in this paper

1. The first part will talk about the Object technology in APL+Win: it will introduce all the concepts and

techniques we will then use in the second part when we talk about ⎕cse and turn “⎕cse objects” into

“⎕wi objects”. The first part will only talk about APL.

2. The second part of this paper will show how you can automatically generate and use “⎕cse objects” as

if they were “⎕wi objects” using the Object technology described in Part One. The second part will

talk about APL and .Net.

Appendix #3 describes how to install the zObjects software delivered to all Conference attendees and what

are its requirements.

The Basic Idea

Everything in life starts with an Idea.

We, APL+Win Users, all know how to create User Interfaces using ⎕wi. Basically, we all know how to use

⎕wi to manipulate the objects provided by the APL+Win System (Form, Edit, Button, Combo, etc). Many

of us also know that it is possible to create our own custom Objects in APL+Win and that we can use them

with ⎕wi in a very similar manner as we are using the standard APL+Win Objects. We also all know that

we can use ActiveX in APL+Win and that again we use ⎕wi the same way to manipulate these ActiveX.

So ⎕wi is a central feature of the APL+Win System: it is easy to use and we all know how to use it.

Now to my basic idea:

Since it is possible to create custom objects in APL+Win, why not hide the complexity (or most of the

complexity) of ⎕cse behind such custom objects which we would use with ⎕wi instead?

When I say “complexity of ⎕cse”, I do not mean just ⎕cse because ⎕cse in itself is easy to use, but I mean

“the complexity of ⎕cse + C# + Visual Studio + .Net Framework all combined together” especially for those

with little .Net experience.

Page 5: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 5

When we’ve got an idea, the next step is to put it to practice and here is generally where the difficulties

start to arise and pile up.

First a little Background History

The reason I have been having the above idea is surely because I have been developing in the past a

product called “APL+Win Objects” which is a collection of 160 Custom Objects designed to speed up

APL+Win application development as well as making it much easier and more re-usable.

This “APL+Win Objects” product has been bought by many APL developers around the world and is still

available.

But time has passed and I have started to be interested in C# around 2006: since then, I have been studying

C# and the .Net Framework and have written several hundred C# DLLs, C# applications and several C#

based products.

At the beginning, it was mostly curiosity, probably influenced by things I had heard at APL2000

Conferences, by the fact Dyalog had a .Net C# Interface, by work done by Gert Glantz in Sweden, etc.

The things that really got me definitely sold to C# and .Net are the following:

1. I found, in the first month I was studying C# and the .Net Framework, that I could succeed in writing

very useful things using C#, even small C# applications that could solve some APL customer

problems. I have frankly been very surprised how easy this has proved to be, especially as I was not

expecting it to be the case. It is definitely easy and much easier than learning APL for sure.

2. I also quickly found out that it was simple to interface APL+Win and C# in multiple manners

(including ClickOnce Client Server Internet based applications) and that this could be done without

any compromise, with a great efficiency

3. I finally discovered that C# was a fast, clean and pure language (just like APL) that included an

incredible amount of nice features. I also quickly got to love Microsoft Visual Studio which is the

C# development environment.

A couple of things were not perfect though: it was easy (for example, using NetAccess) to write C# ActiveX

DLLs that any APL+Win developer could use from APL+Win, but:

1. These C# ActiveX DLLs needed to be properly registered before one could use them in an APL+Win

application: not a big deal generally, but sometimes registration pauses some problems. And it is

just a little pain to have to register things, all the time.

2. In some rare cases, there could be some keyboard related problems when using C# DLLs containing

C# Forms or C# User Controls and combining them with APL Forms in an APL application. In one

case, I just could not solve the problem and this was when trying to make the KeyTips work in a C#

Ribbon ActiveX Control embedded in an APL+Win form.

The new APL+Win v13+ ⎕cse solves mostly these 2 problems.

Page 6: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 6

So, all this is to say that, having both this Custom APL+Win Objects background and this C# background,

explains why I got the idea exposed in the previous paragraph.

Before I can show you what I have done concerning ⎕cse, let me describe in detail the APL+Win Object

technology we are going to use.

Page 7: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 7

Part 1: APL+Win Objects

Understanding APL*Win Custom Objects

To put my idea in practice, let’s refresh our memory about how one can write a Custom Object in APL+Win.

This will take some time, but this will allow you to create your own objects, if you do not yet know how to

do it.

zObjects

First, to allow you to better understand what follows, here are the rules and conventions I have established

for what I have developed:

• I have called my workspace: zObjects.W3

• All my custom objects start with a z followed by an uppercase letter (example: zForm, zButton, …)

The advantage of doing this, is that they would appear at the end of an )fns list and would not be

mixed with the other application functions.

• Utilities which are not Custom Objects start with zz (example: zzInit)

• The zObjects need a single APL function called zzInit to initialize the system

So, if one wants to use just a handful of zObjects in a workspace (say: zForm, zButton, zEdit), one

needs to just copy zForm, zButton, zEdit and zzInit. After running zzInit, the zObjects can be used.

• zObjects can use Inheritance and all the zObjects inherit from at least one object called: zObject

• zzInit creates an instance of zObject and this instance is called: zz

In the following, I will use the term zObject in place of Custom Object.

Anatomy of a zObject

A basic zObject has the following structure:

� a zTemplate b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io ;arg1;arg2;arg3;result [1] %� a zTemplate b -- The zTemplate Object is REPLACEME [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013 Eric Lescasse [10] %� ELE10nov13 [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b

Page 8: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 8

[16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zTemplate [19] %� Example: [20] %� 'zt'�wi'*Create' 'zTemplate' [21] z/a�wi'*Create' 'Menu' [22] z/a�wi'*onAction'(L'zTemplate' 'zObject',¨N'"Action"',�tcnl) [23] z/a�wi'*onClick' 'zTemplate"onClick"' [24] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [25] :return [26] %�------------------------------------------------class [27] Eclass: [28] �wres/'zTemplate' [29] :return [30] %�------------------------------------------------help [31] Ehelp: [32] %� 0 0Ρ'zt'�wi'*Create' 'zTemplate' [33] �wres/�wi'GetHelp' 'help' [34] :return [35] %�------------------------------------------------onClick [36] EonClick: [37] �/'The onClick event fired!' [38] :return [39] %�------------------------------------------------property [40] Eproperty: [41] %� Comment describing the property [42] %� Syntax: {value/}'obj'�wi'property'{value} [43] %� value: describe the property value [44] %� Example: [45] %� 'myobj'�wi'property'1234 [46] :if 1=Ρ�warg [47] �wres/�wi'*∆∆property' [48] :else [49] z/�wi'*∆∆property'(1X�warg) [50] :endif [51] :return [52] %�------------------------------------------------Method [53] EMethod: [54] %� Comment describing the Method [55] %� Syntax: {result/}'obj'�wi'Method'{arg1}{arg2}...{argN} [56] %� arg1: describe the method 1st argument [57] %� arg2: describe the method 2nd argument [58] %� ... [59] %� argN: describe the method Nth argument [60] %� result: describe the method result if any [61] %� Example: [62] %� 'myobj'�wi'Method'1234'Test'(2 2ΡΙ4) [63] (arg1 arg2 arg3)/1X�warg [64] % do some processing [65] % optionally calculate the result (if any) and return it: [66] �wres/result/arg1 arg2 arg3 [67] :return [68] [69] [70] %------------------------------------------------- [71] EEHelp: [72] �wres/�wi'GetHelp'(('?'=Cb)Xb) [73] :return [74] %------------------------------------------------- [75] EEInherit: [76] �wres/�wi'*' �

Page 9: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 9

Note that:

A zObject like zTemplate is self-contained: it encapsulates all its Properties, Methods and Events.

The New method is the Constructor and is the code which is executed when you create an instance of the

object:

'zt'�wi'*Create' 'zTemplate'

For a Custom Object to work in APL+Win, you must create an instance of a standard APL+Win object in the

constructor. When your Custom Object is not a Visual Object directly based on a standard APL+Win object

(like Form, Button, etc.) we use the APL+Win Menu object (as done on line 21) because it can be a top level

object, not directly visible, and because it is the standard APL+Win object that has the smallest memory

footprint.

Line 22 is essential: this is where you define inheritance and this is the one that allows your custom

Properties and Methods to be called. In zTemplate we indicate that zTemplate inherits from zObject. If

we needed zTemplate to inherit from zObject1, zObject2 and zObject, line 22 would read:

[22] z/a�wi'*onAction'(L'zTemplate' 'zObject1' 'zObject2' 'zObject',¨N'"Action"',

�tcnl)

The remaining of our template object contains properties (class, help, property), an event (onClick) and a

sample method (Method).

To use a custom object, you must first have executed zzInit once in your APL Session to initialize the

zObjects System: you can then create an instance of your object and start using its properties, methods and

events:

zzInit 'zt'�wi'*Create' 'zTemplate' zt 'zt'�wi'property'(Ι10) 'zt'�wi'property' 1 2 3 4 5 6 7 8 9 10 'zt'�wi'Method'10 20 30 10 20 30

So, all this is very simple.

If you try to call a property which is not defined in your object itself, the system does not find a label

corresponding to the property and falls through to execute line 76. This results in starting searching for a

label corresponding to the property you’re calling in the next function in the inheritance tree (in our case,

in zObject).

Example:

'zt'�wi'version' 1.83

Page 10: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 10

The version property does not exist in zTemplate, but is defined in zObject which zTemplate inherits from,

so we can use it.

If you try using a property or method which is neither defined in your object nor in any of the objects it

inherits from, you get an error:

'zt'�wi'NonExistingMethod' Unknown Method: NonExistingMethod. Did you intend to use: *NonExistingMethod instead?

The reason you get this message is that there is still the possibility that you intended to use a property or

Method defined in the underlying APL+Win standard object (here: Menu) your custom object is based on.

If this is the case, you must prefix the property or method you’re calling with a * to indicate to APL+Win

your intention. This bypasses searching your hierarchy of custom objects and directly calls the property or

Method in the underlying APL+Win standard object.

Example:

'zt'�wi'*Click' The onClick event fired!

Note that the Menu object standard Click method is indeed called and we can see that, because it does

result in firing the onClick event which in turns branches to line 36 in zTemplate and executes line 37.

This custom object mechanism which APL2000 has built into APL+Win is very solid, is working extremely

well and fast and I have developed many APL applications (some large containing hundreds of very complex

Dialog Boxes and Forms of all kinds) where everything is a Custom Object using the above described

technology.

There are many advantages of using custom objects written the way zTemplate is written:

Those objects are self-contained, i.e. are easily reusable.

All you need to do is copying the object (and the zzInit function) into another workspace and start using it:

you don’t have to copy myriads of subroutines or event handlers, which generally make things very hard to

reuse

They are very maintainable.

The structure is very clear, each event, property and method being clearly isolated and encapsulated inside

the object. Additionally, I pay a lot of attention in respecting the following rules:

• all my Event handlers are defined first

• then all my properties are defined

• then all my Methods are defined

and I get sure to sort them alphabetically. Sometimes custom objects may be quite huge if they have tons

of events, properties and methods and following the above rules systematically, makes them very

manageable even when very large.

Page 11: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 11

Documentation

Another very nice aspect of custom objects defined on the zTemplate model is that you can easily

document all your properties, methods and events. Moreover the documentation is inserted inside the

events, properties and methods themselves which makes maintenance and comprehension of the software

easy.

To retrieve the documentation of a given event, property or method, all you have to do is prefix the event,

property or method which a question mark:

'zt'�wi'?property' Comment describing the property Syntax: {value/}'obj'�wi'property'{value} value: describe the property value Example: 'myobj'�wi'property'1234 'zt'�wi'?Method' Comment describing the Method Syntax: {result/}'obj'�wi'Method'{arg1}{arg2}...{argN} arg1: describe the method 1st argument arg2: describe the method 2nd argument ... argN: describe the method Nth argument result: describe the method result if any Example: 'myobj'�wi'Method'1234'Test'(2 2ΡΙ4)

It is important to include a description of the syntax, of each argument, of the results and to include one or

more examples showing how to use the events, properties and methods.

It takes time to write that documentation, because soon, you may end up with hundreds of objects which

means thousands of properties and methods to document.

But if you make the effort of writing this documentation, you could give your workspace full of objects to

someone else without telling him anything about your system and he should be able to dig into it easily all

the information he needs to use it, provided you give him the following pieces of advice

First, run zzInit to initialize the custom objects system

Then, do:

'#'�wi'newclasses' zButton zCheck zCombo zCommandBar zCommandButton zConverters zDateTime zD ialogBox zEdit zEditNum zForm zFrame zGenerate zGrid zImagelist zInfo zLab el zList zListview zMDIForm zMapDXControl zMapControl zMapsDX zMaskedTextB ox zMedia zMenu zReflection zOption zObject zPage zPrinter zProgress zPict ure zRibbonDX zRibbonDXControl zRichEdit zRichEditDX zRichEditDXForm zSele ctor zScroll zSpreadsheetDXControl zSpinner zSplitContainer zSpreadsheetDX Form zSSGear zStatus zTabControl zTemplateCase zTimer zToolbox zTrackbar z Tree zUserControl zZip zexCommandBar zexGrid zexList zexMapsDX zexMedia ze xOption zexPrinter zexProgress zexRibbonDX zexRibbonDXControl zexRichEdit zexSplitContainer zexScroll zexSpinner zexSSGear zexSpreadsheetDXControl z exStatus zexTabControl zexTimer zexToolbox zexTrackbar zexTree zexZip zTem plate

to get a list of all the objects in your system

Page 12: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 12

Then, to create an instance of an object:

'ff'�wi'*Create' 'zForm' ff

Then, once you get an instance of the object, you can query its properties, methods and events:

'ff'�wi'properties' class dialogresult esc gaps help margins 'ff'�wi'*properties' bars barwrap border caption children class color data ddeTopic def edge enabled events extent font help helpcontext hwnd icon instance keys limitwhere li nks methods mode modified modifystop name noredraw opened place pointer pr ompt properties scale scrollaccel scrollmargin self size state style suppr ess targetformats theme tooltipenabled tooltiptime tooltipwidth translate value visible where ∆∆sysmenu ∆∆∆size 'ff'�wi'methods' New 'ff'�wi'*methods' Close ContextHelpMode Create Defer Delete Draw Event Exec Focus Help Hide Info Modify New Open Paint Popup Ref Resize Send Set SetLinks Show Wait 'ff'�wi'events' onClose onFocus onResize onUnfocus 'ff'�wi'*events' Action Close ContextMenu DdeConnect DdeDisconnect DdeExecute Delete Destroy Dra gEnter DragLeave DragOver Drop DropDown ExitError Focus Help Hide KeyDown KeyPress KeyUp Modified MouseDouble MouseDown MouseDrag MouseEnter MouseLe ave MouseMove MouseUp Move Open Paint Reopen Resize Send Show Unfocus Wait

Note that, when you do not prefix properties, methods or events with a *, you only get the custom

properties, methods or events that you have defined inside your custom objects.

Knowing the properties, methods and events names, one can then easily get their documentation:

'ff'�wi'?margins' Gets or sets the margins between controls and container edges Syntax: {margins/}'obj'�wi'margins'{margins} margins: a 2-element integer vector [0]= the vertical margin (default: 10) [1]= the horizontal margin (default: 10) Example: 'ff'�wi'margins'8 12

And start using them:

'ff'�wi'margins'20 20

Page 13: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 13

Creating our First Custom Objects

Let’s put what we learnt so far to practice.

Let’s write a simple model with 4 custom objects:

• zEmployee

• zManager

• zSalesPerson

• zAccountant

zManager, zAccountant and zSalesPerson are employees so they’ll inherit from zEmployee.

zEmployee will have a name property, a salary property and GetTotalWages method

zManager will have a bonus property and a GetTotalWages method

zSalesPerson will have a sales property and a GetTotalWages method

zAccountant will have a WagesReport method

To create a new custom class, you can call the zObject Derive method and indicate the template you want

to use:

'zz'�wi'Derive' 'zEmployee' 'Menu' 'zTemplate' Class <zEmployee> successfully created and registered! 'zz'�wi'Derive' 'zManager' 'Menu' 'zTemplate' Class <zManager> successfully created and registered! 'zz'�wi'Derive' 'zSalesPerson' 'Menu' 'zTemplate' Class <zSalesPerson> successfully created and registered! 'zz'�wi'Derive' 'zAccountant' 'Menu' 'zTemplate' Class <zAccountant> successfully created and registered!

We then customize our zEmployee, zManager, zSalesPerson and zAccountant classes by coding the

necessary properties and methods and by documenting them:

� a zEmployee b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io ;arg1;arg2;arg3;result [1] %� a zEmployee b -- The zEmployee Object is an object representing an Employee [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013-2014 Eric Lescasse [10] %� ELE25jan14 [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zEmployee

Page 14: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 14

[19] %� Example: [20] %� 'zt'�wi'*Create' 'zEmployee' [21] z/a�wi'*Create' 'Menu' [22] z/a�wi'*onAction'(L'zEmployee' 'zObject',¨N'"Action"',�tcnl) [23] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [24] :return [25] %�------------------------------------------------class [26] Eclass: [27] �wres/'zEmployee' [28] :return [29] %�------------------------------------------------help [30] Ehelp: [31] %� 0 0Ρ'emp1'�wi'*Create' 'zEmployee' [32] �wres/�wi'GetHelp' 'help' [33] :return [34] %�------------------------------------------------name [35] Ename: [36] %� Get or set the employee Name [37] %� Syntax: {value/}'obj'�wi'name'{value} [38] %� value: the employee first name [39] %� Example: [40] %� 'emp1'�wi'name' 'Eric' [41] :if 1=Ρ�warg [42] �wres/�wi'*∆∆name' [43] :else [44] z/�wi'*∆∆name'(2c�warg) [45] :endif [46] :return [47] %�------------------------------------------------salary [48] Esalary: [49] %� Get or set the employee Salary [50] %� Syntax: {value/}'obj'�wi'salary'{value} [51] %� value: the employee salary (floating point) [52] %� Example: [53] %� 'emp1'�wi'salary'10000.50 [54] :if 1=Ρ�warg [55] �wres/�wi'*∆∆salary' [56] :else [57] z/�wi'*∆∆salary'(2c�warg) [58] :endif [59] :return [60] %�------------------------------------------------GetTotalWages [61] EGetTotalWages: [62] %� Returns the Employee total wages [63] %� Syntax: result/'obj'�wi'GetTotalWages' [64] %� result: the total Manager wages [65] %� Example: [66] %� 'man1'�wi'GetTotalWages' [67] �wres/�wi'salary' [68] :return [69] [70] %------------------------------------------------- [71] EEHelp: [72] �wres/�wi'GetHelp'(('?'=Cb)Xb) [73] :return [74] %------------------------------------------------- [75] EEInherit: [76] �wres/�wi'*' �

Page 15: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 15

� a zManager b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io ;arg1;arg2;arg3;result [1] %� a zManager b -- The zManager Object is an object representing a Manager [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013-2014 Eric Lescasse [10] %� ELE25jan14 [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zManager [19] %� Example: [20] %� 'zt'�wi'*Create' 'zManager' [21] z/a�wi'*Create' 'Menu' [22] z/a�wi'*onAction'(L'zManager' 'zEmployee' 'zObject',¨N'"Action"',�tcnl) [23] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [24] :return [25] %�------------------------------------------------class [26] Eclass: [27] �wres/'zManager' [28] :return [29] %�------------------------------------------------help [30] Ehelp: [31] %� 0 0Ρ'zt'�wi'*Create' 'zManager' [32] �wres/�wi'GetHelp' 'help' [33] :return [34] %�------------------------------------------------bonus [35] Ebonus: [36] %� Get or sets the manager bonus [37] %� Syntax: {value/}'obj'�wi'bonus'{value} [38] %� value: the manager bonus (floating point) [39] %� Example: [40] %� 'myobj'�wi'bonus'20000 [41] :if 1=Ρ�warg [42] �wres/�wi'*∆∆bonus' [43] :else [44] z/�wi'*∆∆bonus'(2c�warg) [45] :endif [46] :return [47] %�------------------------------------------------GetTotalWages [48] EGetTotalWages: [49] %� Returns the Manager total wages [50] %� Syntax: result/'obj'�wi'GetTotalWages' [51] %� result: the total Manager wages [52] %� Example: [53] %� 'man1'�wi'GetTotalWages' [54] �wres/(�wi'salary')+�wi'bonus' [55] :return [56] [57] [58] %------------------------------------------------- [59] EEHelp: [60] �wres/�wi'GetHelp'(('?'=Cb)Xb)

Page 16: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 16

[61] :return [62] %------------------------------------------------- [63] EEInherit: [64] �wres/�wi'*' � � a zSalesPerson b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io ;arg1;arg2;arg3;result [1] %� a zSalesPerson b -- The zSalesPerson Object is an object representing a SalesPerson [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013-2014-1014 Eric Lescasse [10] %� ELE25jan14 [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zSalesPerson [19] %� Example: [20] %� 'zt'�wi'*Create' 'zSalesPerson' [21] z/a�wi'*Create' 'Menu' [22] z/a�wi'*onAction'(L'zSalesPerson' 'zEmployee' 'zObject',¨N'"Action"',�tcnl) [23] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [24] :return [25] %�------------------------------------------------class [26] Eclass: [27] �wres/'zSalesPerson' [28] :return [29] %�------------------------------------------------help [30] Ehelp: [31] %� 0 0Ρ'zt'�wi'*Create' 'zSalesPerson' [32] �wres/�wi'GetHelp' 'help' [33] :return [34] %�------------------------------------------------onClick [35] EonClick: [36] �/'The onClick event fired!' [37] :return [38] %�------------------------------------------------sales [39] Esales: [40] %� Get or Set the list of sales made by SalesPerson [41] %� Syntax: {value/}'obj'�wi'sales'{value} [42] %� sales: an integer vector of sales [43] %� Example: [44] %� 'spe1'�wi'sales'10 20 30 40 [45] :if 1=Ρ�warg [46] �wres/�wi'*∆∆sales' [47] :else [48] z/�wi'*∆∆sales'(1X�warg) [49] :endif [50] :return [51] %�------------------------------------------------GetTotalWages [52] EGetTotalWages: [53] %� Returns the SalesPerson total wages

Page 17: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 17

[54] %� Syntax: result/'obj'�wi'GetTotalWages' [55] %� result: the total SalesPerson wages (salary + 10% of all his sales) [56] %� Example: [57] %� 'man1'�wi'GetTotalWages'.1 [58] �wres/(�wi'salary')+.1×+/�wi'sales' [59] :return [60] [61] [62] %------------------------------------------------- [63] EEHelp: [64] �wres/�wi'GetHelp'(('?'=Cb)Xb) [65] :return [66] %------------------------------------------------- [67] EEInherit: [68] �wres/�wi'*' � � a zAccountant b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io ;arg1;arg2;arg3;result [1] %� a zAccountant b -- The zAccountant Object is an object representing an Accountant [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013-2014-1014 Eric Lescasse [10] %� ELE25jan14 [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zAccountant [19] %� Example: [20] %� 'zt'�wi'*Create' 'zAccountant' [21] z/a�wi'*Create' 'Menu' [22] z/a�wi'*onAction'(L'zAccountant' 'zEmployee' 'zObject',¨N'"Action"',�tcnl) [23] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [24] :return [25] %�------------------------------------------------class [26] Eclass: [27] �wres/'zAccountant' [28] :return [29] %�------------------------------------------------help [30] Ehelp: [31] %� 0 0Ρ'zt'�wi'*Create' 'zAccountant' [32] �wres/�wi'GetHelp' 'help' [33] :return [34] %�------------------------------------------------WagesReport [35] EWagesReport: [36] %� Returns a Report about all Employees, Managers and SalesPersons [37] %� Syntax: result/'obj'�wi'WagesReport' [38] %� result: a character string report [39] %� Example: [40] %� 'man1'�wi'WagesReport' [41] o/'#'�wi'children' [42] c/o�wi¨N'class'

Page 18: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 18

[43] d/cL'zEmployee' 'zManager' 'zSalesPerson' 'zAccountant' [44] o/d/o [45] c/d/c [46] r/'' [47] :for i :inΙΡo [48] r,/(1Xicc),' ',((ico)�wi'name'),' has won a total of: ',((ico)�wi'GetTotalWages'),�tcnl [49] :endfor [50] �wres/r [51] :return [52] [53] [54] %------------------------------------------------- [55] EEHelp: [56] �wres/�wi'GetHelp'(('?'=Cb)Xb) [57] :return [58] %------------------------------------------------- [59] EEInherit: [60] �wres/�wi'*' �

Now that we have our various zObjects defined, we can start using them:

'emp1'�wi'*Create' 'zEmployee'('name' 'eric')('salary'1000) 'emp2'�wi'*Create' 'zSalesPerson'('name' 'sonia')('salary'800)('sales'100 400 300) 'acc1'�wi'*Create' 'zAccountant'('name' 'doug')('salary'2000) 'mgr1'�wi'*Create' 'zManager'('name' 'joe')('salary'2000)('bonus'8000)

(any resemblance to real persons, living or dead, is of course purely coincidental) 'emp1'�wi'name' eric 'emp1'�wi'salary' 1000 'emp1'�wi'GetTotalWages' 1000 'emp2'�wi'salary' 800 'emp2'�wi'sales' 100 400 300 'emp2'�wi'GetTotalWages' 880 'acc1'�wi'GetTotalWages' 2000 'mgr1'�wi'GetTotalWages' 10000 'acc1'�wi'WagesReport' Employee eric has won a total of: 1000 SalesPerson sonia has won a total of: 880 Manager joe has won a total of: 10000 Accountant doug has won a total of: 2000

Note that we did not define a GetTotalWages method in zAccountant, but we could call this method on

our zAccountant because it was inherited from zEmployee.

Note however that the Manager (Joe) cannot run the WagesReport method:

'mgr1'�wi'WagesReport' Unknown Method: WagesReport. Did you intend to use: *WagesReport instead?

Page 19: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 19

This is probably an error and we can fix it by making the zManager class also inherit from zAccountant.

Just change line 22 in zManager to read:

z/a�wi'*onAction'(L'zManager' 'zAccountant' 'zEmployee' 'zObject',¨N'"Action"', �tcnl)

After you’ve done that, we need to recreate an instance of the zManager and are able to call the

WagesReport inherited method:

'mgr1'�wi'*Create' 'zManager'('name' 'joe')('salary'2000)('bonus'8000) mgr1 'mgr1'�wi'WagesReport' Employee eric has won a total of: 1000 SalesPerson john has won a total of: 880 Accountant doug has won a total of: 2000 Manager joe has won a total of: 10000

In these examples, you learnt:

1. how to create objects by deriving from a template object (zTemplate)

2. how to use inheritance (the zManager, zSalesPerson and zAccountant could use the name and

salary properties even though these properties are not defined in their class, because they all

inherit from zEmployee)

3. how to use polymorphism (the GetTotalWages method could be used by each class, but had a

different meaning and different way of calculating total wages for each class)

4. how to make a class inherit from multiple classes (the zManager inherited from zAccountant,

zEmployee and zObject)

Using zObject Technology for Visual Objects

Creating zObjects is not limited to non-visual objects like the ones we just created (zEmployee, zManager,

zSalesPerson, zAccountant).

You can use the same technology to create Visual Objects.

Let’s create a simple zSimpleEdit object: we want it to be similar to the APL+Win standard Edit object, with

the following exceptions:

1. We want its border to always be a thin border

2. We want it to get a yellow background when it gets focus

3. We want to get a white background when it loses focus

Let’s start by creating a zSimpleEdit object that inherits from Edit:

'zz'�wi'Derive' 'zSimpleEdit' 'Edit' 'zAPLControlTemplate' Class <zSimpleEdit> successfully created and registered!

Page 20: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 20

Let’s look at the created class:

� a zSimpleEdit b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io [1] %� a zSimpleEdit b -- The zSimpleEdit Object is the zObjects implementation of an APL+Win Edit object [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013-2014 Eric Lescasse [10] %� ELE25jan14 [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zSimpleEdit [19] %� Example: [20] %� 'zt'�wi'*Create' 'zSimpleEdit' [21] z/a�wi'*Create' 'Edit'('*scale'5) [22] z/a�wi'*onAction'(L'zSimpleEdit' 'zObject',¨N'"Action"',�tcnl) [23] z/a�wi'*∆∆anchor'1 2 [24] z/a�wi'clipsiblings'1 [25] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [26] :return [27] %�------------------------------------------------class [28] Eclass: [29] �wres/'zSimpleEdit' [30] :return [31] %�------------------------------------------------help [32] Ehelp: [33] %� 0 0Ρ'zt'�wi'*Create' 'zSimpleEdit' [34] �wres/�wi'GetHelp' 'help' [35] :return [36] [37] %------------------------------------------------- [38] EEHelp: [39] �wres/�wi'GetHelp'(('?'=Cb)Xb) [40] :return [41] %------------------------------------------------- [42] EEInherit: [43] �wres/�wi'*' �

An object derived from zAPLControlTemplate is very similar to an object derived from zTemplate: it just

has:

1. A scale property set to 5

2. A *∆∆anchor user defined property set to 1 2 (i.e. the object is by default attached to the left and

top borders of its container)

3. A clipsiblings property set to 1 (this allows to hide another object that might be placed at the same

location in the same container object)

Page 21: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 21

So, let’s now change our zSimpleEdit object so that it includes the behavior described at the beginning of

this section:

� a zSimpleEdit b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io

[1] %� a zSimpleEdit b -- The zSimpleEdit Object is the zObjects implementation of an

APL+Win Edit object

[2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013-2014 Eric Lescasse [10] %� ELE25jan14 [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zSimpleEdit [19] %� Example: [20] %� 'zt'�wi'*Create' 'zSimpleEdit' [21] z/a�wi'*Create' 'Edit'('*scale'5)('*border'1)('*edge'0) [22] z/a�wi'*onAction'(L'zSimpleEdit' 'zObject',¨N'"Action"',�tcnl) [23] z/a�wi'*∆∆anchor'1 2 [24] z/a�wi'clipsiblings'1 [25] z/a�wi'AddHandler' 'onFocus' 'zSimpleEdit"onFocus"' [26] z/a�wi'AddHandler' 'onUnfocus' 'zSimpleEdit"onUnfocus"' [27] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [28] :return [29] %�------------------------------------------------class [30] Eclass: [31] �wres/'zSimpleEdit' [32] :return [33] %�------------------------------------------------help [34] Ehelp: [35] %� 0 0Ρ'zt'�wi'*Create' 'zSimpleEdit' [36] �wres/�wi'GetHelp' 'help' [37] :return [38] %�------------------------------------------------onFocus [39] EonFocus: [40] z/�wi'*color'255 255 0 [41] :return [42] %�------------------------------------------------onUnfocus [43] EonUnfocus: [44] z/�wi'*color'255 255 255 [45] :return [46] [47] %------------------------------------------------- [48] EEHelp: [49] �wres/�wi'GetHelp'(('?'=Cb)Xb) [50] :return [51] %------------------------------------------------- [52] EEInherit: [53] �wres/�wi'*' �

Page 22: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 22

I have highlighted the changes in yellow.

Let’s now put this object to work with the following function:

� zzsimpleedit;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zSimpleEdit example')('*size'200 300) [2] z/'ff'�wi'*.ed1.Create' 'zSimpleEdit'('wherelc'h h 18 200) [3] z/'ff'�wi'*.ed2.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [4] z/'ff'�wi'*Wait' �

Let’s try it:

As we can see, the 2 Edit controls have a single non-3D border, and the Edit field that has the Focus has a

yellow background.

Using zSimpleEdit throughout an application will ensure that all Edit controls have a consistent look and

feel, while using zSimpleEdit will remain as simple as using Edit.

MultiCast Events

You may have noticed that I defined the onFocus and onUnfocus events on lines 25 and 26, using the

AddHandler method.

Just like .Net supports multi-cast delegates, the AddHandler method allows to define multi-cast events in

APL+Win zObjects.

It is a good idea to define ALL your events using the AddHandler method, when using zObjects.

The reason is the following: you may want to create some objects that will inherit from zSimpleEdit later on

and you may need to handle the onFocus and/or onUnfocus events in these objects. If you do not use

AddHandler to declare them, the onFocus and onUnfocus events will replace the ones you defined in

zSimpleEdit, thus breaking the zSimpleEdit behavior.

When you use AddHandler to declare an event like onFocus, your onFocus event handler is just appended

to whatever onFocus even handler is already defined on your object at a higher level of inheritance. Thus,

when the onFocus event fires, both onFocus event handlers are executed, one after the other.

Page 23: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 23

We will see that in action later on.

Analyzing the zzsimpleedit function

The zzsimpleedit function uses another zObject called zForm.

It also uses a property called wherelc to allow positioning controls perfectly and easily on your forms

without the need of any Visual Editor like ]wed.

The wherelc property

The wherelc property is extremely easy to use and extremely powerful.

It accepts from 4 to 8 arguments.

The first 4 ones are similar to the standard APL+Win where property arguments.

The last 4 ones are optional and are adjustments in pixels that are added to the first 4 arguments.

So, assuming the 8 arguments are called a b c d e f g h:

• a is the vertical position of the control in the form (or in its container, maybe a Frame)

• b is the horizontal position of the control in the form (or in its container, maybe a Frame)

• c is the control height

• d is the control width

• e is the number of pixels (positive or negative) to add to a

• f is the number of pixels (positive or negative) to add to b

• g is the number of pixels (positive or negative) to add to c

• h is the number of pixels (positive or negative) to add to d

You can use various symbols for a b c and d:

⍬ means: use a default value

for a: position the current control at the top margin property value

for b: position the current control at the left margin property value

for c: use the default height for the control

for d: use the default width for the control ‘>’ means:

for a: position the current control vertically below the previous one

for b: position the current control horizontally after the previous one

‘=’ means:

for a: position the current control at the same vertical position as the previous one

for b: position the current control at the same horizontal position as the previous one

for c: use the same height as the previous control

for d: use the same width as the previous control

There are many other symbols that can be used to extremely fine tune Controls positions in a zForm, but

with just the above 3 symbols you can create absolutely perfect forms with no efforts.

Page 24: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 24

Using more zObjects properties and methods

Let’s improve our zzsimpleedit function by using a number of zObjects properties and methods:

� zzsimpleedit;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zSimpleEdit example') [2] z/'ff'�wi'*.ed1.Create' 'zSimpleEdit'('wherelc'h h 18 200) [3] z/'ff'�wi'*.ed2.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [4] z/'ff'�wi'*.ed3.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [5] z/'ff'�wi'*.ed4.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [6] z/'ff'�wi'*.ed5.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [7] z/'ff'�wi'*.ed6.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [8] z/'ff'�wi'*.ok.Create' 'zButton'('wherelc' '=ed1' '>'h h ¯1)('*caption' 'OK')('*onClick' '�wi"*:Close"') [9] z/'ff'�wi'AutoSize' [10] z/'ff'�wi'CenterScreen' [11] z/'ff'�wi'*Wait' �

If you now run this function, you’ll see a zForm being displayed which is:

• Perfectly dimensioned (i.e. not wider than what’s needed to just contain its controls)

• Perfectly centered on the screen

Here is it:

The AutoSize method (which is inherited from zObject) forces the zForm to get automatically resized to a

minimum size.

The CenterScreen method (which is also inherited from zObject) forces the zForm to be centered on the

screen.

Note that, thanks to the fact we are using ‘=’ for the zSimpleEdit widths, we would need only one change in

the function for changing the width of all the zSimpleEdit controls at once.

Page 25: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 25

Example:

� zzsimpleedit;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zSimpleEdit example') [2] z/'ff'�wi'*.ed1.Create' 'zSimpleEdit'('wherelc'h h 18 400) [3] z/'ff'�wi'*.ed2.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [4] z/'ff'�wi'*.ed3.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [5] z/'ff'�wi'*.ed4.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [6] z/'ff'�wi'*.ed5.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [7] z/'ff'�wi'*.ed6.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [8] z/'ff'�wi'*.ok.Create' 'zButton'('wherelc' '=ed1' '>'h h ¯1)('*caption' 'OK')('*onClick' '�wi"*:Close"') [9] z/'ff'�wi'AutoSize' [10] z/'ff'�wi'CenterScreen' [11] z/'ff'�wi'*Wait' �

Note that I have had to change only one character (highlighted in yellow) in the whole function to make

this change!

Notes about the wherelc property

The wherelc property is really very nice and powerful.

Imagine that someone requests that you insert a zCombo object between ed2 and ed3.

All you have to do is to copy line 4 and paste it as line 4.5, change ed2 to cb1 and zSimpleEdit to zCombo

and you’re done:

� zzsimpleedit;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zSimpleEdit example')('margins'10 10)('gaps'2 10) [2] z/'ff'�wi'*.ed1.Create' 'zSimpleEdit'('wherelc'h h 18 400)('anchor'1 2 3) [3] z/'ff'�wi'*.ed2.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [4] z/'ff'�wi'*.cb1.Create' 'zCombo' ('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [5] z/'ff'�wi'*.ed3.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [6] z/'ff'�wi'*.ed4.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [7] z/'ff'�wi'*.ed5.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [8] z/'ff'�wi'*.ed6.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 4 3) [9] z/'ff'�wi'*.ok.Create' 'zButton'('wherelc' '=ed1' '>'h h ¯1)('*caption' 'OK')('*onClick' '�wi"*:Close"')('anchor'2 3) [10] z/'ff'�wi'AutoSize' [11] z/'ff'�wi'CenterScreen' [12] z/'ff'�wi'*Wait' �

Page 26: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 26

All the controls below the inserted zCombo control automatically adjust their positions and you don’t have

to recalculate them!

The wherelc property has many other features which would be too long to describe here.

The margins and gaps properties

A zForm object has a margins property and a gaps property.

The margins property helps you define what the default top and left margins are (the right margin is then

made equal to the left margin and the bottom margin made equal to the top margin).

Example:

� zzsimpleedit;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zSimpleEdit example')('margins'30 30) [2] z/'ff'�wi'*.ed1.Create' 'zSimpleEdit'('wherelc'h h 18 400) [3] z/'ff'�wi'*.ed2.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [4] z/'ff'�wi'*.ed3.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [5] z/'ff'�wi'*.ed4.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [6] z/'ff'�wi'*.ed5.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [7] z/'ff'�wi'*.ed6.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [8] z/'ff'�wi'*.ok.Create' 'zButton'('wherelc' '=ed1' '>'h h ¯1)('*caption' 'OK')('*onClick' '�wi"*:Close"') [9] z/'ff'�wi'AutoSize' [10] z/'ff'�wi'CenterScreen' [11] z/'ff'�wi'*Wait' �

Page 27: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 27

The gaps property allows you to define the default vertical and horizontal gaps separating controls.

Example:

� zzsimpleedit;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zSimpleEdit example')('margins'30 30)('gaps'2 30) [2] z/'ff'�wi'*.ed1.Create' 'zSimpleEdit'('wherelc'h h 18 400) [3] z/'ff'�wi'*.ed2.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [4] z/'ff'�wi'*.ed3.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [5] z/'ff'�wi'*.ed4.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [6] z/'ff'�wi'*.ed5.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [7] z/'ff'�wi'*.ed6.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=') [8] z/'ff'�wi'*.ok.Create' 'zButton'('wherelc' '=ed1' '>'h h ¯1)('*caption' 'OK')('*onClick' '�wi"*:Close"') [9] z/'ff'�wi'AutoSize' [10] z/'ff'�wi'CenterScreen' [11] z/'ff'�wi'*Wait' �

Having set the gaps property to 2 30, the zSimpleEdit controls are much closer to each other vertically

speaking and the OK button is further away to the right of the zSimpleEdit controls.

The Anchor property

All this would not be perfect if controls would not adjust their positions and sizes automatically when

resizing the form.

Let’s try to resize our form. Here is what we get when shrinking the form:

Page 28: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 28

and what we get when making it wider:

We’d like the OK button to be attached to the right hand side of the form and the zSimpleEdit controls to

automatically horizontally shrink or expand as we resize the form.

This can be done using the anchor property (similar to the .Net well known Windows Forms Anchor

property):

� zzsimpleedit;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zSimpleEdit example')('margins'10 10)('gaps'2 10) [2] z/'ff'�wi'*.ed1.Create' 'zSimpleEdit'('wherelc'h h 18 400)('anchor'1 2 3) [3] z/'ff'�wi'*.ed2.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [4] z/'ff'�wi'*.ed3.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [5] z/'ff'�wi'*.ed4.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [6] z/'ff'�wi'*.ed5.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [7] z/'ff'�wi'*.ed6.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 4 3) [8] z/'ff'�wi'*.ok.Create' 'zButton'('wherelc' '=ed1' '>'h h ¯1)('*caption' 'OK')('*onClick' '�wi"*:Close"')('anchor'2 3) [9] z/'ff'�wi'AutoSize' [10] z/'ff'�wi'CenterScreen' [11] z/'ff'�wi'*Wait' �

Let’s display the form:

Page 29: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 29

and shrink it horizontally :

or expand it horizontally :

or expand it both horizontally and vertically:

Note that the ed6 control had an anchor set to 1 4 3 instead of 1 2 3, so it is attached to the bottom (4) of

the Form rather than to the top (2) of the form.

The anchor property values mean:

1 means: attach control its container left border

2 means: attach control its container top border

3 means: attach control its container right border

Page 30: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 30

4 means: attach control its container bottom border

Note that the anchor property is recursive: so you can have zObjects (controls) in a zFrame which is

contained in another zFrame which is contained in a zSelector which is contained in a zForm and all those

controls will resize perfectly and automatically as long as you set their anchor properties correctly.

The MinimumSize property

Finally, we need one more property for being able to create perfect forms.

If you currently shrink the zzsimpleedit form a lot vertically and horizontally, here is what you get:

i.e. the bottom most zSimpleEdit control may overlap with some of the previous zSimpleEdit controls.

So we just need to set a minimumsize property on the zForm object to solve that problem.

To do that properly, let’s start the application:

zzsimpleedit

Then resize the form to whatever you want the minimum size to be and query the size:

(2Ρ'#'�wi'units')×2X'ff'�wi'*where' 176 312

Then, edit zzsimpleedit and set the minimumsize property to 176 312:

� zzsimpleedit;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zSimpleEdit example')('margins'10 10)('gaps'2 10) [2] z/'ff'�wi'minimumsize'176 312 [3] z/'ff'�wi'*.ed1.Create' 'zSimpleEdit'('wherelc'h h 18 400)('anchor'1 2 3) [4] z/'ff'�wi'*.ed2.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [5] z/'ff'�wi'*.ed3.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [6] z/'ff'�wi'*.ed4.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [7] z/'ff'�wi'*.ed5.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [8] z/'ff'�wi'*.ed6.Create' 'zSimpleEdit'('wherelc' '>' '=' '=' '=')('anchor'1 4 3) [9] z/'ff'�wi'*.ok.Create' 'zButton'('wherelc' '=ed1' '>'h h ¯1)('*caption' 'OK')('*onClick' '�wi"*:Close"')('anchor'2 3) [10] z/'ff'�wi'AutoSize' [11] z/'ff'�wi'CenterScreen' [12] z/'ff'�wi'*Wait' �

Page 31: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 31

Now, if you run zzsimpleedit, you’ll see you cannot resize the form to a size smaller than 176 312 pixels.

A more sophisticated example

Up to now, we’ve created very simple objects.

Here is a more sophisticated example using Visual Inheritance which demonstrates the power of using

objects.

The zObjects collection contains a zEdit object which inherits from the standard APL+Win Edit objects.

zEdit is much more powerful than Edit:

1. it contains a validate property (inherited from zObject)

2. it contains a value property (inherited from zObject)

3. it contains 2 methods: HideErrorIcon, ShowErrorIcon

4. it contains the following event handlers: onChange, onFocus, onExit, onExitError

So a zEdit control is an APL+Win Edit control but with powerful validation capabilities.

Let’s use it:

� zzedit;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zEditNum Demo')('*size'200 300)('ontop'1)'*Hide' [2] z/'ff'�wi'*.ed1.Create' 'zEdit'('wherelc'h h 20 200)('anchor'1 2 3) [3] z/'ff'�wi'.ed1.validate' '(Nv)L"x" "y" "xy"' 'Value must be x, y or xy!' [4] z/'ff'�wi'*.ed2.Create' 'zEdit'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [5] z/'ff'�wi'.ed2.validate' '((Ρv)<3)kv@"exit"' 'You must enter 1 or 2 characters or the word: exit!' [6] z/'ff'�wi'*onShow' '"ff"�wi"*.ed1.Focus"' [7] z/'ff'�wi'CenterScreen' [8] z/'ff'�wi'*Show' � zzedit

Let’s enter correct data in the 2 fields (x in the 1st field and 56 in the 2nd field):

Now, type some invalid data in the 1st field, like apl:

Page 32: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 32

when you press Tab to tab to the 2nd field:

• an blinking error icon appears

• the 1st field is slightly shrunk to make room for the error icon

• the previous valid value (x) is displayed

• and if you hover your mouse over the error icon an error message is displayed

• the focus stays in the 1st field

There’s a bit of code necessary to handle all that properly.

If you use zEdit throughout your application all your Edit controls will inherit these validation capabilities.

That’s fine, but, in many applications, you need to enter numeric data (and only numeric data) in Edit fields.

So it makes sense to create a zEditNum control that will inherit from zEdit and that will only accept numeric

values.

The role of zEditNum is to control that data entered in the zEdit field is numeric. Its role is also to display

the numeric values appropriately. As far as validation is concerned, zEditNum will inherit everything from

zEdit and there won’t be any duplicate code.

So zEditNum:

1. Right aligns its content

2. Has a format property to allow formatting the data entered in the control

3. Internally retains all the decimals entered in the field

4. Does not accept non numeric characters

5. Checks that the entered data is a valid numeric value

6. Forces the value property to return a numeric value

Example:

� zzeditnum;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zEditNum Demo')('ontop'1)'*Hide' [2] z/'ff'�wi'*.ed1.Create' 'zEditNum'('wherelc'h h 20 200)('anchor'1 2 3) [3] z/'ff'�wi'*.ed2.Create' 'zEditNum'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [4] z/'ff'�wi'.ed2.format' 'M<(>N<)>CF12.2' [5] z/'ff'�wi'CenterScreen' [6] z/'ff'�wi'AutoSize' [7] z/'ff'�wi'*onShow' '"ff"�wi"*.ed1.Focus"' [8] z/'ff'�wi'*Show' �

Page 33: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 33

Note that when I tab out of the 2nd field the format property is automatically applied:

And that when I tab back to the 2nd field to edit the value, all the decimals are displayed again (i.e. a

zEditNum object retains full precision about the number it displays):

If I type any character (which is not a digit) in the field, a beep sound is played and the character I typed is

rejected.

If I query the value property, I get a numeric value and that the value for the 2nd field includes all the

decimals:

'ff.ed1'�wi'value' 678 100×'ff.ed1'�wi'value' 67800 'ff.ed2'�wi'value' 6767.897675765

But since zEditNum inherits from zEdit, I can also validate my entries using the validate property:

� zzeditnum;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zEditNum Demo')('*size'200 300)('ontop'1)'*Hide' [2] z/'ff'�wi'*.ed1.Create' 'zEditNum'('wherelc'h h 20 200)('anchor'1 2 3) [3] z/'ff'�wi'*.ed2.Create' 'zEditNum'('wherelc' '>' '=' '=' '=')('anchor'1 2 3) [4] z/'ff'�wi'.ed2.format' 'M<(>N<)>CF12.2' [5] z/'ff'�wi'.ed1.validate' 'v<100' 'Please enter a value less than 100!' [6] z/'ff'�wi'.ed2.validate' '(vm10)nvo20' 'Please enter a value between 10 and 20!' [7] z/'ff'�wi'CenterScreen' [8] z/'ff'�wi'AutoSize' [9] z/'ff'�wi'*onShow' '"ff"�wi"*.ed1.Focus"' [10] z/'ff'�wi'*Show' �

Page 34: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 34

And if I enter a value outside of the 10,20 range in the 2nd field:

If you would like to also benefit from the zSimpleEdit behavior we created earlier, all you have to do is

specify that you also want to inherit from zSimpleEdit, so you would change the zEditNum constructor

from:

%�------------------------------------------------New ENew: %� Create a new instance of zEditNum %� Example: %� 'ff.ze'�wi'*Create' 'zEditNum' z/a�wi'*Create' 'zEdit'('*style'2) z/a�wi'*onAction'(L'zEditNum' 'zEdit' 'zObject',¨N'"Action"',�tcnl) :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif % Events z/a�wi'*onChange' 'zEditNum"onChange"' z/a�wi'AddHandler' 'onExit' 'zEditNum"onExit"'1 z/a�wi'AddHandler' 'onFocus' 'zEditNum"onFocus"' z/a�wi'AddHandler' 'onKeyDown' 'zEditNum"onKeyDown"' z/a�wi'AddHandler' 'onKeyPress' 'zEditNum"onKeyPress"' :return

to:

%�------------------------------------------------New ENew: %� Create a new instance of zEditNum %� Example: %� 'ff.ze'�wi'*Create' 'zEditNum' z/a�wi'*Create' 'zSimpleEdit'('*style'2) z/a�wi'*onAction'(L'zEditNum' 'zSimpleEdit' 'zEdit' 'zObject',¨N'"Action"',�tcnl) :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif % Events z/a�wi'*onChange' 'zEditNum"onChange"' z/a�wi'AddHandler' 'onExit' 'zEditNum"onExit"'1 z/a�wi'AddHandler' 'onFocus' 'zEditNum"onFocus"' z/a�wi'AddHandler' 'onKeyDown' 'zEditNum"onKeyDown"' z/a�wi'AddHandler' 'onKeyPress' 'zEditNum"onKeyPress"' :return

Page 35: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 35

and that’s all you have to do.

If you now use zzeditnum, here is what you see:

This is Visual Inheritance: the numeric edit boxes now have a single non-3D border and they become

yellow when they get the focus!

zEdit and zEditNum

In case you are interested, here is the code for the zEdit and zEditnum objects:

� a zEdit b;c;d;e;f;g;h;m;n;p;q;s;t;z;�io [1] %� a zEdit b -- The zEdit Object is a cover object adding validation behavior to the APL+Win Edit object [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zzDEB zObject zzWORDREPL [8] %� zObjects v1.83 [9] %� Copyright(c)2013 Eric Lescasse [10] %� ELE10nov13 [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zEdit [19] %� Example: [20] %� 'zt'�wi'*Create' 'zEdit' [21] z/a�wi'*Create' 'Edit'('*scale'5) [22] z/a�wi'*onAction'(L'zEdit' 'zObject',¨N'"Action"',�tcnl) [23] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [24] z/a�wi'*∆∆anchor'1 2 [25] z/a�wi'*∆∆validate' '' '' [26] z/a�wi'*∆∆value' '' [27] z/a�wi'*∆∆∆oldvalue' '' [28] z/a�wi'clipsiblings'1 [29] % Events [30] z/a�wi'AddHandler' 'onChange' 'zEdit"onChange"' [31] z/a�wi'AddHandler' 'onFocus' 'zEdit"onFocus"' [32] z/a�wi'AddHandler' 'onExit' 'zEdit"onExit"' [33] z/a�wi'AddHandler' 'onExitError' 'zEdit"onExitError"' [34] :return [35] %�------------------------------------------------class [36] Eclass: [37] �wres/'zEdit' [38] :return [39] %�------------------------------------------------help

Page 36: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 36

[40] Ehelp: [41] %� 0 0Ρ'zt'�wi'*Create' 'zEdit' [42] �wres/�wi'GetHelp' 'help' [43] :return [44] %�------------------------------------------------HideErrorIcon [45] EHideErrorIcon: [46] %� Hides the error icon displayed to the right of the control [47] %� Syntax: 'obj'�wi'HideErrorIcon' [48] %� Example: [49] %� 'ff.ed2'�wi'HideErrorIcon' [50] :ifp0@h/�wi'*∆∆∆oldwhere' [51] z/�wi'*where'h [52] z/�wi'*∆∆oldwhere'0 [53] n/�wself,'Pic' % zPicture object name [54] z/n�wi'*Delete' [55] :endif [56] :return [57] %�------------------------------------------------ShowErrorIcon [58] EShowErrorIcon: [59] %� Displays the error icon to the right of the control [60] %� Syntax: 'obj'�wi'ShowErrorIcon'errormessage [61] %� errormessage: character string error message to be displayed in error icon tooltip [62] %� Example: [63] %� 'ff.ed2'�wi'ShowErrorIcon' 'Please enter a value less than 100!' [64] m/2c�warg [65] :ifp0@h/�wi'*∆∆∆oldwhere' ? z/�wi'*where'h ? :endif [66] (c d e f)/�wi'*where' [67] s/�wi'*∆∆∆oldwhere'c d e f [68] z/�wi'*where'(0 0 0 ¯20+c d e f) [69] p/q/zzErrorIcon [70] q[;]/256qr256 256 256s�wcall'GetSysColor' 'COLOR_BTNFACE' [71] n/�wself,'Pic' % zPicture object name [72] z/n�wi'*Create' 'zPicture'('*style'0)('*border'0)('*where'(c)(d+f-18)16 16)('*imagesize'16 16)('*tooltip'm) [73] z/n�wi'*bitmap'p?z/�dl.1 [74] z/n�wi'*bitmap'q?z/�dl.1 [75] z/n�wi'*bitmap'p?z/�dl.1 [76] z/n�wi'*bitmap'q?z/�dl.1 [77] z/n�wi'*bitmap'p?z/�dl.1 [78] z/n�wi'*bitmap'q?z/�dl.1 [79] z/n�wi'*bitmap'p?z/�dl.1 [80] z/�wi'*∆∆∆error'1 [81] :return [82] %�------------------------------------------------onChange [83] EonChange: [84] :if 1=Ρt/�wi'*text' ? t/Ct ? :endif [85] z/�wi'*∆∆value't [86] :return [87] %�------------------------------------------------onExit [88] EonExit: [89] (e m)/�wi'*∆∆validate' [90] :ifp0LΡe/zzDEB e [91] f/"u'v'u'zEz1'u""v""u""zEz1"""zzWORDREPL e [92] f/"uvu(�wi'*∆∆value')"zzWORDREPL f [93] f/"u'zEz1'u'v'u""zEz1""u""v"""zzWORDREPL f [94] :try * [95] g/CJf [96] :ifpgL0 1 [97] �error'Validation expression: ',e,' does not evaluate to a boolean scalar!' [98] :endif

Page 37: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 37

[99] :catchall [100] c/¯1+(d/"u(�wi'*∆∆value')uv"zzWORDREPL �dm)Ι�tcnl [101] �error(cCd), ' in validation expression: ',e,cXd [102] :endtry [103] :if g [104] z/�wi'HideErrorIcon' [105] :else [106] �wres/m [107] :endif [108] :endif [109] :return [110] %�------------------------------------------------onFocus [111] EonFocus: [112] :if 1=Ρt/�wi'*text' ? t/Ct ? :endif [113] z/�wi'*∆∆∆oldvalue't [114] :return [115] %�------------------------------------------------onExitError [116] EonExitError: [117] z/�wi'*text'('u¯u-'zzTEXTREPLv�wi'*∆∆∆oldvalue') [118] z/�wi'ShowErrorIcon'�warg [119] % z/�wcall'MessageBox'((�wi'parentform')�wi'*hwnd')�warg'Validation Error' 'MB_OK MB_ICONSTOP' [120] z/�wi'*Focus' [121] :return [122] [123] %------------------------------------------------- [124] EEHelp: [125] �wres/�wi'GetHelp'(('?'=Cb)Xb) [126] :return [127] %------------------------------------------------- [128] EEInherit: [129] �wres/�wi'*' �

Page 38: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 38

� a zEditNum b;c;d;e;f;g;h;i;t;v;z;�io [1] %� a zEditNum b -- The zEditNum Object is a Numeric zEdit control [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zzDEB zObject zzTEXTREPL [8] %� zObjects v1.83 [9] %� Copyright(c)2013 Eric Lescasse [10] %� ELE15nov13 [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zEditNum [19] %� Example: [20] %� 'ff.ze'�wi'*Create' 'zEditNum' [21] z/a�wi'*Create' 'zSimpleEdit'('*style'2) [22] z/a�wi'*onAction'(L'zEditNum' 'zSimpleEdit' 'zEdit' 'zObject',¨N'"Action"',�tcnl) [23] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [24] % Events [25] z/a�wi'*onChange' 'zEditNum"onChange"' [26] z/a�wi'AddHandler' 'onExit' 'zEditNum"onExit"'1 [27] z/a�wi'AddHandler' 'onFocus' 'zEditNum"onFocus"' [28] z/a�wi'AddHandler' 'onKeyDown' 'zEditNum"onKeyDown"' [29] z/a�wi'AddHandler' 'onKeyPress' 'zEditNum"onKeyPress"' [30] :return [31] %�------------------------------------------------class [32] Eclass: [33] �wres/'zEditNum' [34] :return [35] %�------------------------------------------------help [36] Ehelp: [37] %� 0 0Ρ'ff.ze'�wi'*Create' 'zEditNum' [38] �wres/�wi'GetHelp' 'help' [39] :return [40] %�------------------------------------------------format [41] Eformat: [42] %� Get or set the �fmt format string to be used to format the value [43] %� Syntax: {format/}'obj'�wi'format'{format} [44] %� format: a valid �fmt format string [45] %� Example: [46] %� 'ff'�wi'.ed1.format' 'M<(>N<)>CI12' [47] z/(1=Ρ�warg :then �wres/�wi'*∆∆format' :else z/�wi'*∆∆format'(2c�warg)) [48] :return [49] %�------------------------------------------------onChange [50] EonChange: [51] :ifC�vi t/(tL'-¯.0123456789')/t/'u-u¯'zzTEXTREPL�wi'*text' [52] z/�wi'*∆∆value'(C�fi t) [53] :endif [54] :return [55] %�------------------------------------------------onExit [56] EonExit: [57] :ifp0@f/�wi'*∆∆format' [58] v/'u¯u-'zzTEXTREPL zzDEB,f�fmt�wi'*∆∆value' [59] :if(v@'')k'*'k.Gvp' ' [60] z/�wi'HideErrorIcon'

Page 39: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 39

[61] :else [62] �wres/'Format overflow: use a wider <format> property!' [63] :return [64] :endif [65] z/�wi'*suppress'1 [66] z/�wi'*text'v [67] z/�wi'*suppress'0 [68] :endif [69] :return [70] %�------------------------------------------------onFocus [71] EonFocus: [72] v/�wi'*∆∆value' [73] z/�wi'*∆∆∆oldvalue'v [74] z/�wi'*suppress'1 [75] z/�wi'*text'(t/'u¯u-'zzTEXTREPLvv) [76] z/�wi'*selection'0,Ρt [77] z/�wi'*suppress'0 [78] :return [79] %�------------------------------------------------onKeyDown [80] EonKeyDown: [81] % Allow only certain Virtual Keys [82] (c d e f g h i)/�warg [83] :if iL8 16 35 36 45 46 ? :return ? :endif % 8=backspace, 16=shift, 35=end, 36=home, 45=ins, 46=del [84] :if iL37 38 39 40 ? :return ? :endif % 37=left, 38=up, 39=right, 40=down [85] :if iL47+Ι10 ? :return ? :endif % 0-9 [86] :if iL190 54 ? :return ? :endif % . - [87] �wres/¯2 [88] :return [89] %�------------------------------------------------onKeyPress [90] EonKeyPress: [91] % Allow only backspace, 0-9, - and . [92] :ifp�wargL8 45 46,47+Ι10 ? �wres/¯2 ? :endif [93] :return [94] [95] %------------------------------------------------- [96] EEHelp: [97] �wres/�wi'GetHelp'(('?'=Cb)Xb) [98] :return [99] %------------------------------------------------- [100] EEInherit: [101] �wres/�wi'*' �

Page 40: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 40

Part 2: Creating APL+Win .Net Objects using ⎕⎕⎕⎕cse

Introduction

Our goal now is to be able to use the Objects Technology exposed in Part 1 to create .Net objects that use

⎕cse.

What we would like to ultimately achieve is to create zObjects that we could use with ⎕wi without ever

having to use ⎕cse, thus entirely remaining “in APL” and hiding the (relative) complexity of having to use

⎕cse.

We will first try to create .Net User Controls and later on .Net Windows Forms and non-visual .Net objects.

The Challenge

Our goal is a challenge because the APL+Win Objects technology requires that you create an instance of a

standard APL+Win object in the constructor of any zObject!

In other words, we cannot base our zObject on a .Net object created with ⎕cse: we have to base our

zObject on an instance of an APL+Win standard object instead. However, nothing can prevent us from also

creating an instance of the .Net desired object later on in the Constructor.

But, when we use a property or method of our zObject, we do not want it to be applied to the APL+Win

standard object created in the constructor (which would normally be the case), but instead to the ⎕cse

object that we also create in the constructor.

Moreover, we would like to be able to use our very powerful:

1. wherelc property

2. anchor property

directly on the ⎕cse object.

Finally, the onAction which fires when a custom property, method or event is used has to work with the

⎕cse object.

The Constraints

After a good amount of searching, it appears that the following constraints must be fulfilled:

1. We need an underlying standard APL+Win object which has a small memory footprint

2. We need an underlying standard APL+Win object that has an hwnd property

(because we need to support the clipsiblings property)

3. We need an underlying standard APL+Win object that has a where property

(because of our need to support the wherelc and anchor properties and to support the onMove and

onResize events [we’ll see later why we need to support these events])

Page 41: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 41

Therefore, we cannot use Menu for our APL+Win underlying object as it does not support hwnd, does not

have a where property and does not support onMove and onResize.

More searching demonstrates that the best and maybe only APL+Win standard object that fulfills our

constraints is a Label object.

The zzCSE Utility

In the following of this paper, I will be using the zzCSE APL function instead of ⎕cse. So just understand

zzCSE as being ⎕cse.

zzCSE is just a cover function for ⎕cse that allows to optionally display the ⎕cse arguments depending on

a verbose user defined property.

Here is the zzCSE function:

� z/o zzCSE s [1] :if�monadic [2] :if'#'�wi'*∆∆verbose' ? z/�cse �/s ? :else ? z/�cse s ? :endif [3] :else [4] :if'#'�wi'*∆∆verbose' ? z/o�cse �/s ? :else ? z/o�cse s ? :endif [5] :endif �

On our way to building a zNetControlTemplate object

In Part 1 of this paper we displayed the zAPLControlTemplate object which served as a model to create APL

zObject Controls (using the Derive method). We’d now like to create a similar zNetControlTemplate that

could serve as a model for creating any ⎕cse based .Net object.

Let’s get interested to the top of this function and see how we should change it to support .Net objects

using ⎕cse.

The top part of zAPLControlTemplate reads (I have omitted the top comments):

� a zAPLControlTemplate b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io [1] %� w [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zAPLControlTemplate [19] %� Example: [20] %� 'zt'�wi'*Create' 'zAPLControlTemplate' [21] z/a�wi'*Create' '{1}'('*scale'5) [22] z/a�wi'*onAction'(L'zAPLControlTemplate' 'zObject',¨N'"Action"',�tcnl) [23] z/a�wi'*∆∆anchor'1 2 [24] z/a�wi'clipsiblings'1 [25] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [26] :return

Page 42: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 42

where '{1}' on line 21 was to be replaced by the APL+Win object from which we derived (this was

automatically done by the Derive method).

We need to change it to:

� a zNetControlTemplate b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io [1] %� w [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zNetControlTemplate [19] %� Example: [20] %� 'zt'�wi'*Create' 'zNetControlTemplate' [21] z/a�wi'*Create' 'Label'('*scale'5) [22] z/a�wi'*onAction'(L'zNetControlTemplate' 'zObject',¨N'"Action"',�tcnl) [23] z/a�wi'*∆∆anchor'1 2 [24] z/a�wi'clipsiblings'1 [25] % Find the name of the parent APL Form and of the �cse control [26] % Dispose of any �cse object with the same name [27] % Create an instance of the �cse object here [28] % Get the <handle> property of this �cse object [29] % Set its <Name> property [30] % Force it to become a child of the APL parent Form, using the <SetParent> API [31] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [32] :return

A little more research lead us to develop lines 25 to 30 as follows:

� a zNetControlTemplate b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io [1] %� w [11] [12] �io/1 [13] :if �monadic ? a/�wself ? :endif [14] :if b@'Action' ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [15] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [16] %�------------------------------------------------New [17] ENew: [18] %� Create a new instance of zNetControlTemplate [19] %� Example: [20] %� 'zt'�wi'*Create' 'zNetControlTemplate' [21] z/a�wi'*Create' 'Label'('*scale'5) [22] z/a�wi'*onAction'(L'zNetControlTemplate' 'zObject',¨N'"Action"',�tcnl) [23] z/a�wi'*∆∆anchor'1 2 [24] z/a�wi'clipsiblings'1 [25] c/rn\raG'.' [26] d/¯1X(pc)/a % parent name [27] e/c/a % top level name for C# object [28] :try * [29] z/�cse'ExecStmt'(e,'.Dispose();') [30] :catchall [31] :endtry [32] z/�cse'ExecStmt'('zNetControlTemplate ',e,' = new zNetControlTemplate();') [33] h/�cse'GetValue'('(int)',e,'.Handle') [34] :try * [35] z/�cse'ExecStmt'(e,'.Name = "',e,'";') [36] :catchall [37] :endtry

Page 43: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 43

[38] % Force it to become a child of the APL parent Form, using the <SetParent> API [39] z/�wcall'SetParent'h(d�wi'*hwnd') [40] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [41] :return

The zNetControlTemplate left argument will represent a Label in some kind of container (often a Form), so

will be of the form: 'containerName.labelName' (example: 'ff.ss').

We separate the container name and the Label name on lines 25-27 so that we could use the Label name

(ss in our example) as the ⎕cse object instance name.

Line 29 calls ⎕cse to dispose of any object that would have this name.

Line 32 is the line that creates an instance of our zNetControlTemplate object (remember that this function

is only a Template and that zNetControlTemplate will be replaced later by the name of a real .Net Control

object).

Then on line 33 we get its Handle (similar to the APL+Win hwnd property).

Then on line 35 we set the .Net object Name to be e ('ss' in our case)

Finally on line 39 we force the .Net object to become a child of the container object (in our example: 'ff')

But all this is not enough.

We must also change the lines at the top of the template function for several reasons:

• First, when a property or method is called, ⎕wself will be equal to 'ff.ss' (in our example, i.e.

representing the Label) while we indeed want to apply the property or method to 'ss' only (as we

named our .Net control 'ss')

So we must fool the system into thinking it is applying a property or method to the Label while, in

reality, it will apply it to a .Net object. This is easily done by changing the object name on the fly.

• Second, when an event handler fires with a normal zObject like zEditNum, the right argument, b,

just contains the name of the event (example: 'onExit'): however, when a ⎕cse event fires, the

right argument b contains a ⎕cse 6-element nested array, such as the following:

b zcsedx rib ButtonItemClick cseEvt_9 Name Home_Clipboard_Copy ]display b .0-----------------------------------------------------------------------. y.0-----..0--..0--------------..0-------..0--------------------------..z.y yyzcsedxyyribyyButtonItemClickyycseEvt_9yX.0---..0------------------.yy yy y'------''---''---------------''--------'yyNameyyHome_Clipboard_Copyyy'-'y y y'----''-------------------'y y y 'L--------------------------' y 'L-----------------------------------------------------------------------'

Page 44: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 44

So we must change the very top of the zNetControlTemplate function to:

� a zNetControlTemplate b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;Ewarg;�io [1] %� ... [11] [12] �io/1 [13] �cself/'zcsedx' [14] :if �monadic ? a/�wself ? :endif [15] :if'Action'@Ewarg/b ? 0('?'=Cb/C�warg)ΡEEHelp ? :endif [16] :if(�dr b)L326 807 ? :andif 6=Ρb ? b/'on',3cb ? :endif [17] 0(8G''Ρ�idloc'E',b)ΡEEInherit [18] :if'New'Pb ? a/(rn\raG'.')/a ? :endif [19] 0J'E',b [20] %�------------------------------------------------New [21] ENew: [22] %� Create a new instance of zForm [23] %� Example: [24] %� 'ff'�wi'*Create' 'zNetControlTemplate' [25] z/a�wi'*Create' 'Label'('*scale'5)('*caption' '') [26] z/a�wi'*onAction'(L'zNetControlTemplate' 'zUserControl' 'zConverters' 'zObject',¨N'"Action"',�tcnl) [27] z/a�wi'*∆∆anchor'1 2 [28] z/a�wi'clipsiblings'1 [29] :try * [30] z/zzCSE'ExecStmt'(a,'.Dispose();') [31] :catchall [32] :endtry [33] c/rn\raG'.' [34] d/¯1X(pc)/a % parent name [35] e/c/a % top level name for C# object [36] z/zzCSE'ExecStmt'('zNetControlTemplate ',e,' = new zNetControlTemplate();') [37] h/zzCSE'GetValue'('(int)',e,'.Handle') [38] :try * [39] z/zzCSE'ExecStmt'(e,'.Name = "',e,'";') [40] :catchall [41] :endtry [42] z/�wcall'SetParent'h(d�wi'*hwnd') [43] z/a�wi'*∆∆∆isnetcontrol'1 [44] :return

Line 13 sets ⎕cself to the ⎕cse instance we want to use (more on that later)

Then on line 15 we save the content of b (i.e. of the event arguments) to variable ⍙⍙⍙⍙warg as we will need it

in event handlers.

On line 16 we detect if b is an argument coming from a ⎕cse event that just fired and we reset be to be

the event name prefixed by 'on' just to make it look like an APL+Win event name.

Line 18 is essential and is the line that changes the name of the object from 'ff.ss' to 'ss': from that point

on, the system thinks it works on an APL+Win Label object (⎕wself is still equal to 'ff.ss') but any property

or method will be applied to the .Net 'ss' object instead!

Finally, at the end of the Constructor, I am setting a User Defined property called ∆∆∆isnetcontrol to 1.

This will help inherited methods to know that they are dealing with a .Net Control rather than an APL

Control.

Page 45: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 45

We now have an almost complete zNetControlTemplate function ready to serve as a model for any .Net

Control we want to use in an APL+Win form, and here it is:

� a zNetControlTemplate b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;Ewarg;�io

[1] %� a zNetControlTemplate b -- The zNetControlTemplate Object is the zObjects implementation of a .Net Control [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013 Eric Lescasse [10] %� ELE21nov13 [11] [12] �io/1 [13] �cself/'zcsedx' [14] :if �monadic ? a/�wself ? :end [15] :if'Action'@Ewarg/b ? 0('?'=Cb/C�warg)ΡEEHelp ? :end [16] :if(�dr b)L326 807 ? :andif 6=Ρb ? b/'on',3cb ? :endif [17] 0(8G''Ρ�idloc'E',b)ΡEEInherit [18] :if'New'Pb ? a/(rn\raG'.')/a ? :endif [19] 0J'E',b [20] %�------------------------------------------------New [21] ENew: [22] %� Create a new instance of zForm [23] %� Example: [24] %� 'ff'�wi'*Create' 'zNetControlTemplate' [25] z/a�wi'*Create' 'Label'('*scale'5)('*caption' '') [26] z/a�wi'*onAction'(L'zNetControlTemplate' 'zObject',¨N'"Action"',�tcnl) [27] z/a�wi'*∆∆anchor'1 2 [28] z/a�wi'clipsiblings'1 [29] :try * [30] z/zzCSE'ExecStmt'(a,'.Dispose();') [31] :catchall [32] :endtry [33] c/rn\raG'.' [34] d/¯1X(pc)/a % parent name [35] e/c/a % top level name for C# object [36] z/zzCSE'ExecStmt'('zNetControlTemplate ',e,' = new zNetControlTemplate();') [37] h/zzCSE'GetValue'('(int)',e,'.Handle') [38] :try * [39] z/zzCSE'ExecStmt'(e,'.Name = "',e,'";') [40] :catchall [41] :endtry [42] z/�wcall'SetParent'h(d�wi'*hwnd') [43] z/a�wi'*∆∆∆isnetcontrol'1 [44] z/a�wi'*onMove' 'zObject"onMove"' [45] z/a�wi'*onResize' 'zObject"onResize"' [46] :return [47] %�------------------------------------------------class [48] Eclass: [49] �wres/'zNetControlTemplate' [50] :return [51] %�------------------------------------------------help [52] Ehelp: [53] %� 0 0Ρ'ff'�wi'*Create' 'zNetControlTemplate' [54] �wres/�wi'GetHelp' 'help' [55] :return

Page 46: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 46

[56] [57] %�================================================Protected Code [58] %�================================================Protected Code [59] [60] %�================================================Generated Code [61] %�================================================Generated Code [62] [63] %------------------------------------------------- [64] EEHelp: [65] �wres/�wi'GetHelp'(('?'=Cb)Xb) [66] :return [67] %------------------------------------------------- [68] EEInherit: [69] �wres/�wi'*' �

Supporting the wherelc and anchor properties with ⎕⎕⎕⎕cse .Net controls

The next step is to support the wherelc and anchor properties for our ⎕cse .Net controls.

I searched quite a while on this before the lightning struck my head.

Since I am using a Label object as the underlying object that allows the ⎕cse object to behave as if it were

a simple ⎕wi object, and since the wherelc and anchor property already worked perfectly on ⎕wi objects,

why not take advantage of that?

Maybe all I would have to do is to:

1. Indeed set the wherelc and anchor property on the Label itself rather than trying to set them on the

⎕cse object; this way the invisible Label would get positioned and resized perfectly

2. Then, handle the Label onMove and onResize event, so that, when the Label gets repositioned and/or

resized due to the use of wherelc and/or anchor, I would just need to force the ⎕cse object to get the

same position and size as the Label

This really simple strategy has proved to work like a charm!

All I have had to do is add the following code to the zNetControlTemplate (highlighted in yellow below):

� a zNetControlTemplate b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;Ewarg;�io [1] %� a zNetControlTemplate b -- The zNetControlTemplate Object is the zObjects implementation of a .Net Control [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013 Eric Lescasse [10] %� ELE21nov13 [11] [12] �io/1 [13] �cself/'zcsedx' [14] :if �monadic ? a/�wself ? :end [15] :if'Action'@Ewarg/b ? 0('?'=Cb/C�warg)ΡEEHelp ? :end

Page 47: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 47

[16] :if(�dr b)L326 807 ? :andif 6=Ρb ? b/'on',3cb ? :endif [17] 0(8G''Ρ�idloc'E',b)ΡEEInherit [18] :if'New'Pb ? a/(rn\raG'.')/a ? :endif [19] 0J'E',b [20] %�------------------------------------------------New [21] ENew: [22] %� Create a new instance of zForm [23] %� Example: [24] %� 'ff'�wi'*Create' 'zNetControlTemplate' [25] z/a�wi'*Create' 'Label'('*scale'5)('*caption' '') [26] z/a�wi'*onAction'(L'zNetControlTemplate' 'zObject',¨N'"Action"',�tcnl) [27] z/a�wi'*∆∆anchor'1 2 [28] z/a�wi'clipsiblings'1 [29] :try * [30] z/zzCSE'ExecStmt'(a,'.Dispose();') [31] :catchall [32] :endtry [33] c/rn\raG'.' [34] d/¯1X(pc)/a % parent name [35] e/c/a % top level name for C# object [36] z/zzCSE'ExecStmt'('zNetControlTemplate ',e,' = new zNetControlTemplate();') [37] h/zzCSE'GetValue'('(int)',e,'.Handle') [38] :try * [39] z/zzCSE'ExecStmt'(e,'.Name = "',e,'";') [40] :catchall [41] :endtry [42] z/�wcall'SetParent'h(d�wi'*hwnd') [43] z/a�wi'*∆∆∆isnetcontrol'1 [44] z/a�wi'*onMove' 'zObject"onMove"' [45] z/a�wi'*onResize' 'zObject"onResize"' [46] :return [47] %�------------------------------------------------class [48] Eclass: [49] �wres/'zNetControlTemplate' [50] :return [51] %�------------------------------------------------help [52] Ehelp: [53] %� 0 0Ρ'ff'�wi'*Create' 'zNetControlTemplate' [54] �wres/�wi'GetHelp' 'help' [55] :return [56] [57] %�================================================Protected Code [58] %�================================================Protected Code [59] [60] %�================================================Generated Code [61] %�================================================Generated Code [62] [63] %------------------------------------------------- [64] EEHelp: [65] �wres/�wi'GetHelp'(('?'=Cb)Xb) [66] :return [67] %------------------------------------------------- [68] EEInherit: [69] �wres/�wi'*' �

I handle the onMove and onResize Label events in the zObject object (the object from which everything

inherits) rather than in the zNetControlTemplate itself. This way I’ll be able to create as many different

⎕cse .Net controls as I want and wherelc and anchor will work for all of them.

Page 48: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 48

Moreover the code necessary to handle the onMove and onResize event in zObject is absolutely simple

and minimal:

[1379] %�------------------------------------------------onMove, onResize [1380] EonMove: [1381] EonResize: [1382] :if�wi'*∆∆∆isnetcontrol' [1383] c/(rn\raG'.')/a % .Net zzCSE control name [1384] (d e f g)/a�wi'*where' [1385] z/zzCSE'ExecStmt'(c,'.Location = new Point(',(ve),',',(vd),');') [1386] z/zzCSE'ExecStmt'(c,'.Size = new Size(',(vg),',',(vf),');') [1387] z/�wi'*Defer' "�wi'*:Paint'" % make sure child .Net control gets displayed ontop of form [1388] :endif [1389] :return

Line 1384 gets the position and dimension of the Label using its standard where property

Line 1385 uses ⎕cse to set the .Net control position to the same position (using its Location property)

Line 1386 uses ⎕cse to set the .Net control size the same size (using its Size property)

The only little trick I had to add was line 1387: this is because for some reason the .Net child control would

not always get repainted correctly when resizing its parent form. Line 1387 solves this problem.

Raising the Bar

We now have a template function (zNetControlTemplate) that could serve as an object model for any .Net

User Control that we want to embed in an APL+Win Form.

However, most of the time, we will want to develop our .Net User Control in the standard .Net

development environment which is Microsoft Visual Studio.

There is a free version of Visual Studio, called Visual Studio Express, which is quite good enough for that.

The reason we want to use Visual Studio are twofold:

• First, Visual Studio is the nicest development environment ever made by human beings on this

earth

• Second, we will be able to use Intellisense

So, the steps are the following:

1. We will develop a User Control project in Visual Studio

2. We will create our own Properties, Methods and Events in this User Control

3. We will compile it and obtain a .Net DLL

But how are we going to use this DLL with ⎕cse from APL+Win?

Well: for that, our goal is to use ⎕wi in our APL application instead of ⎕cse.

Page 49: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 49

First Example

First, let’s do a complete walkthrough about creating a C# User Control DLL (that we could use in APL+Win)

with Visual Studio. This will take a few pages, since I need to explain mostly everything for novice C#

developers. But it will help better understand what follows this first example.

Creating the Visual Studio User Control DLL Project

1. Start Visual Studio (I’ll be using Visual Studio 2012 Premium here but you could use any version of

Visual Studio or Visual Studio Express [VS2010, VS2012 or VS2013]).

We refer to Visual Studio as VS hereafter.

2. Select File / New Project

3. First be sure to select .Net Framework 4.5 in the top Combo Box (as the CSE System supports only

the .Net Framework 4.5 and above)

4. Then select: Windows Forms Control Library in the list of Templates (as we want to create a User

Control DLL)

5. Select a Location for your Visual Studio (VS) Solution (here: D:\Documents\Visual Studio

2012\Projects\LC\)

6. Enter a Name for your Solution (here: zObjectUC)

Page 50: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 50

7. Click OK

This create a new Solution (= set of C# files that will, when compiled, produce a DLL). The solution

files are displayed on the right hand pane.

The created User Control appears in the middle VS pane:

8. Let’s drag and drop a DevExpress1 CalcEdit control onto our User Control. You should see

something like what’s displayed on next page.

9. Note that this drag and drop operation, not only adds a new control to our User Control, but

automatically adds references to some DevExpress DLLs under References in Solution Explorer,

namely:

• DevExpress.Data.v13.2 (.dll)

• DevExpress.Printing.v13.2.Core (.dll)

• DevExpress.Sparkline.v13.2.Core (.dll)

• DevExpress.Utils.v13.2 (.dll)

• DevExpress.XtraEditors.v13.2 (.dll)

1 DevExpress is a library of very nice third party controls developed by DevExpress, a US Company based in Glendale, CA.

Page 51: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 51

We now want the container User Control to be no larger than the CalcEdit control it contains.

10. The CalcEdit object being selected (you should see calcEdit1 displayed in the Combo Box at the top

of the Properties2 pane), select its Size property in the Properties pane. You should see:

11. Now click on the User Control itself (or select UserControl1 in the combo box at the top of the

Properties pane on the right hand side of the screen) and change its Size to be equal to: 100, 20 in

order to match the calcEdit1 Size.

12. You should now see something like this in the middle pane:

2 If you do not see the Properties pane on your screen, select VIEW / Properties Window

Page 52: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 52

13. Now make sure calcEdit1 is selected in the Properties pane

14. Find its Dock property and set it to Fill

15. Righ click UserControl1 in Solution Explorer, select Rename and rename it to: zCalculatorDX3

Solution Explorer should now display:

16. When prompted to rename all references, click Yes:

Compiling the DLL

Before we compile the DLL, click on each of the DevExpress DLLs appearing under References in Solution

Explorer and then set its Copy Local property to true in the Properties pane. This will result in the

DevExpress DLLs be automatically copied from the GAC to the bin\debug folder when you compile your

project. This way all the DLLs you’ll need will be placed in the same bin\debug folder as your DLL.

Select BUILD / Build Solution (or press F6)

Ensure that Build Succeeded is displayed at the left of the VS Status Bar

3 Note: the DX suffix stands for DevExpress to remind us that this control is a DevExpress control

Page 53: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 53

Your Solution has been compiled successfully and a DLL called zObjectsUC.dll has been created in the

bin\debug folder of your Solution

First Use of our Calculator User Control in APL

1. Load APL+Win v14

2. Load the zObjects workspace (use load, not xload, so that the ⎕lx function which runs zzInit be

executed)

3. Create a new zObject called zCalculatorDX that derives from zNetControlTemplate:

'zz'�wi'Derive' 'zCalculatorDX' 'zObjectsUC.Calculator' 'zNetControlTemplate'

Class <zCalculatorDX> successfully created and registered!

4. Before we can use our zCalculatorDX object, we need to create an instance of ⎕cse that loads our

zObjectsUC.dll and all the other necessary DevExpress DLLs. For that, we can create an APL function,

for example called zzInitObjectsUC, reading as follows:

� zzInitObjectsUC;c;d;p;s;z

[1] c/'zcsedx'

[2] p/'D:\Documents\Visual Studio

2012\Projects\LC\zObjectsUC\zObjectsUC\bin\Debug\'

[3] d/''

[4] d,/N'DevExpress.Data.v13.2'

[5] d,/N'DevExpress.Printing.v13.2.Core'

[6] d,/N'DevExpress.Sparkline.v13.2.Core'

[7] d,/N'DevExpress.Utils.v13.2'

[8] d,/N'DevExpress.XtraEditors.v13.2'

[9] d/(Np),¨d,¨N'.dll'

[10] z/c zzCSE'Init' 'System' 'System.Windows.Forms' 'System.Drawing',d

[11] z/c zzCSE'LoadAssembly'(p,'zObjectsUC.dll')

[12] z/c zzCSE'returnonerror'1

[13] z/c zzCSE'transpose'0

[14] s/''

[15] s,/N'using System;'

[16] s,/N'using System.Drawing;'

[17] s,/N'using zObjectsUC;'

[18] s/cs

[19] z/c zzCSE'Exec's

Note that this is maybe the most difficult part when having little experience with .Net and C#.

How do I know the names of the DLLs I must pass to the Init method?

The answer is that the ones you have to pass is a subset of the ones appearing under References in

Solution Explorer in your project: in fact, when a Visual Studio project is created, Visual Studio

references by default a good number of DLLs, but not all of them are used by your project. You do not

need to pass to Init the ones which are not used by your project. In doubt, you can pass to Init all the

DLLs you see displayed under References in Solution Explorer.

Page 54: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 54

Then the next question is: how do I know which using statements I must execute?

The answer is first that you do not need any using statement provided you fully qualify your type

names in your C# code.

For example, the wherelc and anchor properties use the .Net Point property to position controls in the

Form. But Point is a class in the System.Drawing namespace.

So, if you use: System.Drawing.Point (i.e. if you use a fully qualified object name) every time you

need to use Point in your code, then you do not need to add the: using System.Drawing; statement

However, if you want so simply use Point in your code, then you need to add the using

System.Drawing; statement.

5. Let’s now use our first .Net Control in an APL+Win Form using zObjects:

'ff'�wi'*Create' 'zForm'('*size'200 300)('*caption' 'zCalculatorDX

Demo')'Show'

'ff'�wi'*.calc.Create' 'zCalculatorDX'('wherelc'h h h 200)('anchor'1 2 3)

And now, if you click on the zCalculatorDX Combo button, you see a marvelous .Net Calculator in

your APL+Win Form:

Page 55: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 55

Note that, although the zCalculatorDX is a .Net User Control:

- we can use it with ⎕wi instead of ⎕cse

- the wherelc and anchor properties work perfectly with this .Net control

Let’s for example use our mouse to widen the form:

Using the Verbose User Defined Property

If we want to see what ⎕cse is doing when running our application, all we have to do is set the verbose

user defined property to 1 (I have created a ]verbose User Command to make this easier):

]verbose 1

Then let’s run everything again:

zzInitObjectsUC Init System System.Windows.Forms System.Drawing D:\Documents\Visual Studio 2012 \Projects\LC\zObjectsUC\zObjectsUC\bin\Debug\DevExpress.Data.v13.2.dll D:\ Documents\Visual Studio 2012\Projects\LC\zObjectsUC\zObjectsUC\bin\Debug\D evExpress.Printing.v13.2.Core.dll D:\Documents\Visual Studio 2012\Projects \LC\zObjectsUC\zObjectsUC\bin\Debug\DevExpress.Sparkline.v13.2.Core.dll D:

Page 56: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 56

\Documents\Visual Studio 2012\Projects\LC\zObjectsUC\zObjectsUC\bin\Debug\ DevExpress.Utils.v13.2.dll D:\Documents\Visual Studio 2012\Projects\LC\zOb jectsUC\zObjectsUC\bin\Debug\DevExpress.XtraEditors.v13.2.dll LoadAssembly D:\Documents\Visual Studio 2012\Projects\LC\zObjectsUC\zObjectsUC\ bin\Debug\zObjectsUC.dll returnonerror 1 transpose 0 Exec using System; using System.Drawing; using zObjectsUC; 'ff'�wi'*Create' 'zForm'('*size'200 300)('*caption' 'zCalculatorDX Demo')'Show' ff 'ff'�wi'*.calc.Create' 'zCalculatorDX'('wherelc'h h h 200)('anchor'1 2 3) ExecStmt calc.Dispose(); ExecStmt zCalculatorDX calc = new zCalculatorDX(); GetValue (int)calc.Handle ExecStmt calc.Name = "calc"; GetValue calc.Height ExecStmt calc.Location = new Point(10,10); ExecStmt calc.Size = new Size(200,20); ExecStmt calc.Location = new Point(10,10); ExecStmt calc.Size = new Size(200,20); ff.calc

and, when resizing the APL Form:

ExecStmt calc.Location = new Point(10,10); ExecStmt calc.Size = new Size(327,20);

The verbose property lets you see what ⎕cse instructions are run in the background when you use your

object.

Using zCalculatorDX Properties and Methods

Using Properties with ⎕⎕⎕⎕cse

What if we want to now use zCalculatorDX properties?

Well, we can first try using ⎕cse.

We can first query the names of the available Properties:

c�cse'GetProperties' 'calc' System.Windows.Forms.AccessibleObject AccessibilityObject{get; } System.String AccessibleDefaultActionDescription{get; set;} System.String AccessibleDescription{get; set;} System.String AccessibleName{get; set;} System.Windows.Forms.AccessibleRole AccessibleRole{get; set;} System.Windows.Forms.Control ActiveControl{get; set;} System.Boolean AllowDrop{get; set;} System.Windows.Forms.AnchorStyles Anchor{get; set;} System.Drawing.SizeF AutoScaleDimensions{get; set;} System.Windows.Forms.AutoScaleMode AutoScaleMode{get; set;} System.Boolean AutoScroll{get; set;} System.Drawing.Size AutoScrollMargin{get; set;} System.Drawing.Size AutoScrollMinSize{get; set;} System.Drawing.Point AutoScrollOffset{get; set;}

Page 57: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 57

System.Drawing.Point AutoScrollPosition{get; set;} System.Boolean AutoSize{get; set;} System.Windows.Forms.AutoSizeMode AutoSizeMode{get; set;} System.Windows.Forms.AutoValidate AutoValidate{get; set;} System.Drawing.Color BackColor{get; set;} System.Drawing.Image BackgroundImage{get; set;} System.Windows.Forms.ImageLayout BackgroundImageLayout{get; set;} System.Windows.Forms.BindingContext BindingContext{get; set;} System.Windows.Forms.BorderStyle BorderStyle{get; set;} System.Int32 Bottom{get; } System.Drawing.Rectangle Bounds{get; set;} System.Boolean CanFocus{get; } System.Boolean CanSelect{get; } System.Boolean Capture{get; set;} System.Boolean CausesValidation{get; set;} System.Drawing.Rectangle ClientRectangle{get; } System.Drawing.Size ClientSize{get; set;} System.String CompanyName{get; } System.ComponentModel.IContainer Container{get; } System.Boolean ContainsFocus{get; } System.Windows.Forms.ContextMenu ContextMenu{get; set;} System.Windows.Forms.ContextMenuStrip ContextMenuStrip{get; set;} System.Windows.Forms.Control+ControlCollection Controls{get; } System.Boolean Created{get; } System.Drawing.SizeF CurrentAutoScaleDimensions{get; } System.Windows.Forms.Cursor Cursor{get; set;} System.Windows.Forms.ControlBindingsCollection DataBindings{get; } System.Drawing.Rectangle DisplayRectangle{get; } System.Boolean Disposing{get; } System.Windows.Forms.DockStyle Dock{get; set;} System.Windows.Forms.ScrollableControl+DockPaddingEdges DockPadding{get; } System.Boolean Enabled{get; set;} System.Boolean Focused{get; } System.Drawing.Font Font{get; set;} System.Drawing.Color ForeColor{get; set;} System.IntPtr Handle{get; } System.Boolean HasChildren{get; } System.Int32 Height{get; set;} System.Windows.Forms.HScrollProperties HorizontalScroll{get; } System.Windows.Forms.ImeMode ImeMode{get; set;} System.Boolean InvokeRequired{get; } System.Boolean IsAccessible{get; set;} System.Boolean IsDisposed{get; } System.Boolean IsHandleCreated{get; } System.Boolean IsMirrored{get; } System.Windows.Forms.Layout.LayoutEngine LayoutEngine{get; } System.Int32 Left{get; set;} System.Drawing.Point Location{get; set;} System.Windows.Forms.Padding Margin{get; set;} System.Drawing.Size MaximumSize{get; set;} System.Drawing.Size MinimumSize{get; set;} System.String Name{get; set;} System.Windows.Forms.Padding Padding{get; set;} System.Windows.Forms.Control Parent{get; set;} System.Windows.Forms.Form ParentForm{get; } System.Drawing.Size PreferredSize{get; } System.String ProductName{get; } System.String ProductVersion{get; } System.Boolean RecreatingHandle{get; } System.Drawing.Region Region{get; set;} System.Int32 Right{get; } System.Windows.Forms.RightToLeft RightToLeft{get; set;}

Page 58: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 58

System.ComponentModel.ISite Site{get; set;} System.Drawing.Size Size{get; set;} System.Int32 TabIndex{get; set;} System.Boolean TabStop{get; set;} System.Object Tag{get; set;} System.String Text{get; set;} System.Int32 Top{get; set;} System.Windows.Forms.Control TopLevelControl{get; } System.Boolean UseWaitCursor{get; set;} System.Windows.Forms.VScrollProperties VerticalScroll{get; } System.Boolean Visible{get; set;} System.Int32 Width{get; set;} System.Windows.Forms.IWindowTarget WindowTarget{get; set;}

I voluntarily displayed all of the properties because this is interesting.

For each property you get:

1. Its .Net type (System.Int32, System.Drawing.Size, etc.)

2. Its Name (Location, Padding, Text, …)

3. Whether the property can be get and/or set

Let’s try to use some properties with ⎕cse:

�cse'GetValue' 'calc.Width' 327 �cse'GetValue' 'calc.Height' 20 �cse'GetValue' 'calc.ProductName' zObjectsUC �cse'GetValue' 'calc.ProductVersion' 1.0.0.0 �cse'GetValue' 'calc.Visible' 1

Great! Great! We can query properties of a .Net object embedded in a .Net User Control!

And you can try setting some of these properties as well (the one that have a set; in their above definition):

�cse'SetValue' 'calc.Visible'0

Great! Everything seems to work!

Page 59: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 59

Let’s do some more trials:

�cse'GetValue' 'calc.Anchor' 5 % still great! but what does 5 mean? �cse'GetValue' 'calc.BackColor' ¯2147483633 % half great! a negative color!?

and even more trials:

�cse'GetValue' 'calc.Location' CSE ERROR: Bad variable type. �cse'GetValue' 'calc.Handle' CSE ERROR: Bad variable type. �cse'GetValue' 'calc.Handle' CSE ERROR: Bad variable type.

Oops! Pretty bad this time!

The reason we cannot use the above properties is that their .Net type does not correspond to any type that

APL can understand: in APL we have only 4 types as you know:

• Boolean matches the .Net boolean type

• Character matches the .Net string type

• Integer matches the .Net Int32 (or just int) type

• Floating Point matches the .Net double type

But the .Net Framework include more than 10000 (ten thousands) types!

And whenever a .Net object property returns one of the 10000 types which is not boolean, string, Int32 or

double, we cannot retrieve it in APL! We will see how to cope with that later.

Using Methods with ⎕⎕⎕⎕cse

Let’s query the available methods for our calc (instance of zCalculatorDX) object:

c�cse'GetMethods' 'calc' System.IAsyncResult BeginInvoke(System.Delegate method) System.IAsyncResult BeginInvoke(System.Delegate method,System.Object[] args) System.Void BringToFront() System.Boolean Contains(System.Windows.Forms.Control ctl) System.Void CreateControl() System.Drawing.Graphics CreateGraphics() System.Runtime.Remoting.ObjRef CreateObjRef(System.Type requestedType) System.Void Dispose() System.Windows.Forms.DragDropEffects DoDragDrop(System.Object data,System.Windows.Forms.DragDropEffects allowedEffects) System.Void DrawToBitmap(System.Drawing.Bitmap bitmap,System.Drawing.Rectangle targetBounds) System.Object EndInvoke(System.IAsyncResult asyncResult) System.Boolean Equals(System.Object obj) System.Windows.Forms.Form FindForm() System.Boolean Focus() System.Windows.Forms.Control GetChildAtPoint(System.Drawing.Point pt,System.Windows.Forms.GetChildAtPointSkip skipValue) System.Windows.Forms.Control GetChildAtPoint(System.Drawing.Point pt) System.Windows.Forms.IContainerControl GetContainerControl() System.Int32 GetHashCode()

Page 60: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 60

System.Object GetLifetimeService() System.Windows.Forms.Control GetNextControl(System.Windows.Forms.Control ctl,Boolean forward) System.Drawing.Size GetPreferredSize(System.Drawing.Size proposedSize) System.Type GetType() System.Void Hide() System.Object InitializeLifetimeService() System.Void Invalidate(System.Drawing.Rectangle rc) System.Void Invalidate() System.Void Invalidate(Boolean invalidateChildren) System.Void Invalidate(System.Drawing.Rectangle rc,Boolean invalidateChildren) System.Void Invalidate(System.Drawing.Region region) System.Void Invalidate(System.Drawing.Region region,Boolean invalidateChildren) System.Object Invoke(System.Delegate method,System.Object[] args) System.Object Invoke(System.Delegate method) System.Void PerformAutoScale() System.Void PerformLayout(System.Windows.Forms.Control affectedControl,System.String affectedProperty) System.Void PerformLayout() System.Drawing.Point PointToClient(System.Drawing.Point p) System.Drawing.Point PointToScreen(System.Drawing.Point p) System.Windows.Forms.PreProcessControlState PreProcessControlMessage(System.Windows.Forms.Message& msg) System.Boolean PreProcessMessage(System.Windows.Forms.Message& msg) System.Drawing.Rectangle RectangleToClient(System.Drawing.Rectangle r) System.Drawing.Rectangle RectangleToScreen(System.Drawing.Rectangle r) System.Void Refresh() System.Void ResetBackColor() System.Void ResetBindings() System.Void ResetCursor() System.Void ResetFont() System.Void ResetForeColor() System.Void ResetImeMode() System.Void ResetRightToLeft() System.Void ResetText() System.Void ResumeLayout() System.Void ResumeLayout(Boolean performLayout) System.Void Scale(System.Drawing.SizeF factor) System.Void Scale(Single ratio) System.Void Scale(Single dx,Single dy) System.Void ScrollControlIntoView(System.Windows.Forms.Control activeControl) System.Void Select() System.Boolean SelectNextControl(System.Windows.Forms.Control ctl,Boolean forward,Boolean tabStopOnly,Boolean nested,Boolean wrap) System.Void SendToBack() System.Void SetAutoScrollMargin(Int32 x,Int32 y) System.Void SetBounds(Int32 x,Int32 y,Int32 width,Int32 height) System.Void SetBounds(Int32 x,Int32 y,Int32 width,Int32 height,System.Windows.Forms.BoundsSpecified specified) System.Void Show() System.Void SuspendLayout() System.String ToString() System.Void Update() System.Boolean Validate() System.Boolean Validate(Boolean checkAutoValidate) System.Boolean ValidateChildren(System.Windows.Forms.ValidationConstraints validationConstraints) System.Boolean ValidateChildren()

Page 61: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 61

We can use some of the methods with no problem:

�cse'ExecStmt' 'calc.Hide();' �cse'ExecStmt' 'calc.Show();' �cse'ExecStmt' 'string str = calc.ToString();' �cse'GetValue' 'str' zObjectsUC.zCalculatorDX �cse'ExecStmt' 'int hashCode = calc.GetHashCode();' �cse'GetValue' 'hashCode' 65344633

But many methods either accept arguments that are not compatible with APL types or return results that

are not compatible with APL types.

We can still call some of those methods, but that requires more than a single instruction.

Example:

�cse'ExecStmt' 'Point pt = new Point(10,10);' �cse'ExecStmt' 'Point resultPt = calc.PointToScreen(pt);' �cse'GetValue' 'resultPt.X' ¯1161 �cse'GetValue' 'resultPt.Y' ¯401

In any case, all this requires using one or sometimes several ⎕cse instructions involving C# statements and

our goal is rather to be able to use ⎕wi to do the same things.

Defining APL Object Properties in zCalculatorDX

Well, we know how to do that!

We can simply add a few properties and methods in zCalculatorDX, as follows:

%�================================================Protected Code %�------------------------------------------------visible Evisible: %� Get or Set the control visibility %� Syntax: {visible/}'obj'�wi'visible'{visible} %� visible: a boolean scalar indicating if the control is visible (1) or not (0) %� Example: %� 'ff.calc'�wi'visible'0 :if 1=Ρ�warg �wres/�cse'GetValue' 'calc.Visible' :else z/�cse'SetValue' 'calc.Visible'(1@2c�warg) :endif :return %�------------------------------------------------width Ewidth: %� Returns the control width %� Syntax: {width/}'obj'�wi'width'{width} %� width: the control width in pixels %� Example: %� 'ff.calc'�wi'width'50 :if 1=Ρ�warg �wres/�cse'GetValue' 'calc.Width' :else

Page 62: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 62

z/�cse'SetValue' 'calc.Width'(2c�warg) :endif :return %�------------------------------------------------PointToScreen EPointToScreen: %� Converts a y,x control point coordinate into an y,x screen coordinate %� Syntax: yxScreen/'obj'�wi'PointToScreen'yxControl %� yxControl: 2-element integer vector %� [1]= y coordinate in pixel of a control point %� [2]= x coordinate in pixel of a control point %� yxScreen: 2-element integer vector %� [1]= yxControl[1] converted to screen y coordinate %� [2]= yxControl[2] converted to screen x coordinate %� Example: %� 'ff.calc'�wi'PointToScreen'10 10 (y x)/1X�warg z/�cse'ExecStmt'('Point yxControl = new Point(',(vx),',',(vy),');') z/�cse'ExecStmt'('Point yxScreen = calc.PointToScreen(yxControl);') �wres/(�cse'GetValue' 'yxScreen.Y'),(�cse'GetValue' 'yxScreen.X') :return %�================================================Protected Code

Note that:

1. We have put these properties and methods inside a Protected Code section (we’ll see why later)

2. We have documented our properties and method

We can now use these properties and methods with ⎕wi and forget about C# and the relative ⎕cse

complexity:

]verbose 0 zzInitObjectsUC 'ff'�wi'*Create' 'zForm'('*size'200 300)('*caption' 'zCalculatorDX Demo')('ontop'1)'Show' ff 'ff.calc'�wi'*Create' 'zCalculatorDX'('wherelc'h h h 200)('anchor'1 2 3) ff.calc 'ff.calc'�wi'visible' 1 'ff.calc'�wi'visible'0 'ff.calc'�wi'visible'1 'ff.calc'�wi'width' 200 'ff.calc'�wi'width'50 'ff.calc'�wi'width'150 'ff.calc'�wi'width' 150 'ff.calc'�wi'PointToScreen'10 10 183 726

So suddenly, everything becomes much easier: we can use ⎕wi instead of the more obscure ⎕cse syntax.

It’s beautiful: all this works exactly as expected.

Important note: you may have noticed that we have set the ontop property to 1 on the line that created

an instance of the zForm form. Because of this, if you click on the zCalculatorDX combo button, you will

NOT see the calculator dropdown because it will be displayed behind the zForm which is ontop! I have set

the ontop property to 1 so that you could immediately see the effect of setting the visible and width

Page 63: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 63

properties on the zCalculatorDX control, but if you want to use the zCalculatorDX object in an APL+Win

application, do not make the Form ontop.

Additionally to calling the properties and methods, we can also retrieve their documentation, of course:

'ff.calc'�wi'?PointToScreen' Converts a y,x control point coordinate into an y,x screen coordinate Syntax: yxScreen/'obj'�wi'PointToScreen'yxControl yxControl: 2-element integer vector [1]= y coordinate in pixel of a control point [2]= x coordinate in pixel of a control point yxScreen: 2-element integer vector [1]= yxControl[1] converted to screen y coordinate [2]= yxControl[2] converted to screen x coordinate Example: 'ff.calc'�wi'PointToScreen'10 10 'ff.calc'�wi'?width' Returns the control width Syntax: {width/}'obj'�wi'width'{width} width: the control width in pixels Example: 'ff.calc'�wi'width'50

Page 64: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 64

Raising the Bar one Step further: on our way to an Object Code Generator

Having successfully reached this point, and seeing that we can retrieve some information about the

zCalculatorDX object programmatically (i.e. getting its properties, and its methods, etc.) the idea gets

formed to maybe be able to automatically generate the entire code of our zCalculatorDX object, including

all its .Net properties and the methods in the way described above.

The zReflection object

For that purpose we need to get a lot of information about the C# object (here zCalculatorDX). ⎕cse could

provide us with some of these information (the zCalculatorDX list of properties, methods, events for

example), but we need to retrieve more information.

We can use the .Net Framework Reflection namespace which contains a lot of different methods allowing

us to get very detailed information about .Net types.

So I have created a C# zObjects DLL and have developed a zReflection.cs class in this solution.

This zReflection C# class contains methods like:

• GetAssembly

• GetBaseDirectory

• GetControlTypes

• GetEnum

• GetEvents

• GetMethods

• GetProperties

• GetTypes

• LoadXmlDocument

I have then created an APL object also called zReflection that uses the C# zReflection object to retrieve

information about any given C# type.

My zReflection APL object starts like this:

� a zReflection b;c;d;m;r;s;t;z;Ewarg;�io;p;h;x;q;y;w;v;j;k;f;g [1] %� r/a zReflection b -- The zReflection Object is the zObjects implementation of a Form object [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013-2014 Eric Lescasse [10] %� ELE26oct13 [11] [12] �io/1 [13] r/0 0Ρ'' ? �cself/'zcse' [14] :if �monadic ? a/�wself ? :end [15] :if'Action'@Ewarg/b ? 0('?'=Cb/C�warg)ΡEEHelp ? :end

Page 65: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 65

[16] :if(�dr b)L326 807 ? :andif 6=Ρb ? b/(2cb),'_',3cb ? :endif [17] 0(8G''Ρ�idloc'E',b)ΡEEInherit ? 0J'E',b [18] %�------------------------------------------------New [19] ENew: [20] %� Create a new instance of zReflection [21] %� Example: [22] %� 'ff'�wi'*Create' 'zReflection' [23] z/a�wi'*Create' 'Menu' [24] z/a�wi'*onAction'(L'zReflection' 'zObject',¨N'"Action"',�tcnl) [25] p/a�wi'appdir' [26] z/'zcsedx'zzCSE'ExecStmt' 'using zObjects;' [27] z/'zcsedx'zzCSE'ExecStmt' 'zReflection zref = new zReflection();' [28] :return [29] %�------------------------------------------------class [30] Eclass: [31] �wres/'zReflection' [32] :return [33] w

So, as you can see, zReflection has the structure of an APL Custom Object as described earlier.

Its constructor just uses ⎕cse to create an instance of the C# zReflection object (lines 26 and 27).

Then, the zReflection APL object has methods such as GetMethods, which reads:

%�------------------------------------------------GetMethods EGetMethods: %� Returns the complete list of public methods available for the specified .Net type %� Syntax: meths/'obj'�wi'GetMethods'type{method} %� type: character string (an existing .Net type) %� method: method name (optional: if specified only method overloads with that name are retrieved) %� meths: an 9-column nested matrix with one method per line %� [;1]= method modifier(s) %� [;2]= method return type %� [;3]= method return fully qualified type %� [;4]= method name %� [;5]= method argument(s) %� [;6]= module in which the method is defined %� [;7]= reflected type (class used to get method info) %� [;8]= declaring type (class that declares this method) %� [;9]= method description %� Example: %� 'zref'�wi'GetMethods' 'TextBox' %� 'zref'�wi'GetMethods' 'TextBox' 'Invalidate' :if 2=Ρ�warg :try * t/2c�warg % .Net Framework type (example: 'Form') �wres/'zcsedx'zzCSE'GetValue'('zref.GetMethods("',t,'");') :catchall �wres/0 9Ρ'' :endtry :else :try * (t m)/1X�warg �wres/'zcsedx'zzCSE'GetValue'('zref.GetMethods("',t,'","',m,'")') :catchall �wres/0 9Ρ'' :endtry :endif :return

Page 66: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 66

As you can see above, the GetMethods APL method calls the C# zReflection GetMethods method which

returns a 9-columns matrix containing detailed information about methods contained in the .Net type we

are interested in (here: zCalculatorDX).

Example:

�pw/80 'zref'�wi'*Create' 'zReflection' zref Ρ'zref'�wi'GetMethods' 'zCalculatorDX' 70 9 (Ι9)|4C[1]'zref'�wi'GetMethods' 'zCalculatorDX' 1 2 3 4 public IAsyncResult System.IAsyncResult BeginInvoke public virtual IAsyncResult System.IAsyncResult BeginInvoke (Delegate public void System.Void BringToFront public bool System.Boolean Contains 5 6 7 8 (Delegate method) System.Windows.Forms.dll zCalculatorDX Control method, object[] args) System.Windows.Forms.dll zCalculatorDX Control () System.Windows.Forms.dll zCalculatorDX Control (Control ctl) System.Windows.Forms.dll zCalculatorDX Control 9 System.Windows.Forms.Control.BeginInvoke(System.Delegate) System.Windows.Forms.Control.BeginInvoke(System.Delegate,System.Object[]) System.Windows.Forms.Control.BringToFront() System.Windows.Forms.Control.Contains(System.Windows.Forms.Control)

We get information not only about the zCalculatorDX control itself but also about the .Net type it inherits

from (which is: UserControl).

The zReflection APL object contains a number of other methods (GetProperties, GetEvents, etc.) which are

similar to the GetMethods method displayed above and which allow to retrieve information about any C#

type.

Automatically Retrieving Documentation

If you have ever used Visual Studio to write some C# code, you know that Visual Studio provides you with a

lot of information in its Intellisense system.

Assuming you have created an instance of a Form called form1 in Visual Studio, when you type a dot after

form1, you see an Intellisense popup window which presents you with all the available methods, properties

and events that can be used for a Form.

Page 67: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 67

Example:

In fact Visual Studio also uses Reflection to retrieve all these information about the available Form

properties, methods and events.

But as you can see above, it is also able to retrieve documentation about properties, methods and events:

in the above example, the AcceptButton property is described by:

Gets or sets the button on the form that is clicked when the user presses the ENTER key

So if Visual Studio is able to do that, why shouldn’t we be able to do it as well?

A little searching leads to discover that these documentation strings are contained in some XML files

provided with the .Net Framework and that these files are located in the following folder:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\

Thus it has been possible to develop the following C# methods in zReflection.cs:

• GetPropertyDescription

• GetMethodDescription

• GetEventDescription

Once done, it is easy to create methods with the same name in the APL zReflection object to help retrieve

the documentation.

Here is the code for the GetPropertyDescription APL method:

%�------------------------------------------------GetPropertyDescription EGetPropertyDescription: %� Returns the property description for the specified property %� Syntax: descriptions/'obj'�wi'GetPropertyDescription'type property{xmlFile} %� type: character string (an existing .Net Framework type) %� property: an existing property name for this type %� xmlFile: full path name of the XML file containing the C# type documentation %� or 'ms' (default) as a shortcut for the Microsoft XML documentation file %� descriptions: a $-separated segmented string containing the full property name and its documentation %� Example: %� 'obj'�wi'GetPropertyDescription' 'Form' 'AcceptButton' 'ms' %� $P:System.Windows.Forms.Form.AcceptButton$Gets or sets the button on the form that is clicked when the user presses the ENTER key (t m x)/3Cc,(Ρc/1X�warg)X'' '' 'ms'

Page 68: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 68

�wres/'zcsedx'zzCSE'GetValue'('zref.GetPropertyDescription("',t,'","',m,'",@"',x,'")') :return

Note that this method calls the C# zReflection GetPropertyDescription method through ⎕cse on the next

to last line.

We can now automatically retrieve the documentation of any C# property, method or event.

Example:

'zref'�wi'GetPropertyDescription' 'Form' 'AcceptButton' 'ms' $P:System.Windows.Forms.Form.AcceptButton$Gets or sets the button on the form that is clicked when the user presses the ENTER key

The ‘ms’ argument is a shortcut meaning: go use the .Net Framework XML documentation files.

Ready for developing a Code Generator

Thanks to the C# and APL zReflection objects, we can now obtain all the information we need in order to

build a Code Generator.

The Code Generator: zGenerate

Based on all the knowledge we have acquired about APL Objects, zObjects, C# types, etc. in the previous

pages of this paper, it is now possible to write a zGenerate APL object capable of auto-creating C# zObjects.

It is out of the scope of this paper to explain the details of the zGenerate object, but it is included in the

zObjects.w3 workspace provided with the Conference support material.

Let’s simply say, for now, that it includes a Generate method which can transform a Microsoft .Net

Framework object or Third Party object into an APL zObject that you can use with ⎕wi.

Let’s take a simple example to make us better understood. A lot more examples are included later on in

this paper.

The .Net Framework contains an object (we say type rather than object in C#) called FolderBrowserDialog.

Let’s auto-generate an APL object called zFolderBrowserDialog that would let us use the C#

FolderBrowserDialog in APL using only ⎕wi.

Here is how you can generate this object:

'zgen'�wi'*Create' 'zGenerate' 'zgen'�wi'Generate' 'zFolderBrowserDialog' 'FolderBrowserDialog' 'FolderBrowserDialog' 0'ms'

After a couple of seconds the name of the created object is displayed in the APL Session:

zFolderBrowserDialog

Let’s look at the generated code:

Page 69: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 69

� a zFolderBrowserDialog b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;Ewarg;�io [1] %� r/a zFolderBrowserDialog b -- The zFolderBrowserDialog Object is the zObjects implementation of a .Net Framework FolderBrowserDialog object [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.0 [9] %� Copyright(c)2014 Eric Lescasse [10] %� ELE15feb14 [11] [12] �io/1 [13] �cself/'zcsedx' [14] :if �monadic ? a/�wself ? :end [15] :if'Action'@Ewarg/b ? 0('?'=Cb/C�warg)ΡEEHelp ? :end [16] :if(�dr b)L326 807 ? :andif 6=Ρb ? b/'on',3cb ? :endif [17] 0(8G''Ρ�idloc'E',b)ΡEEInherit [18] :if'New'Pb ? a/(rn\raG'.')/a ? :endif [19] 0J'E',b [20] %�------------------------------------------------New [21] ENew: [22] %� Create a new instance of zFolderBrowserDialog [23] %� Example: [24] %� 'ff'�wi'*Create' 'zFolderBrowserDialog' [25] z/a�wi'*Create' 'zForm' '*Hide' [26] z/a�wi'*onAction'(L'zFolderBrowserDialog' 'zCommonDialog' 'zConverters' 'zObject',¨N'"Action"',�tcnl) [27] c/rn\raG'.' [28] d/¯1X(pc)/a % parent name [29] e/c/a % top level name for C# object [30] :try * [31] z/zzCSE'ExecStmt'(e,'.Dispose();') [32] :catchall [33] :endtry [34] z/zzCSE'ExecStmt'('FolderBrowserDialog ',e,' = new FolderBrowserDialog();') [35] :try * [36] z/zzCSE'ExecStmt'(e,'.Name = "',e,'";') [37] :catchall [38] :endtry [39] z/a�wi'*∆∆∆isnetcontrol'1 [40] % z/�wi'AddHandler' 'Disposed' [41] % z/�wi'AddHandler' 'HelpRequest' [42] :return [43] %�------------------------------------------------class [44] Eclass: [45] �wres/'zFolderBrowserDialog' [46] :return [47] %�------------------------------------------------help [48] Ehelp: [49] %� 0 0Ρ'ff'�wi'*Create' 'zFolderBrowserDialog' [50] �wres/�wi'GetHelp' 'help' [51] :return [52] [53] %�================================================Protected Code [54] %�================================================Protected Code [55] [56] %�================================================Generated Code [57] %�------------------------------------------------description [58] Edescription:

Page 70: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 70

[59] %� Gets or sets the descriptive text displayed above the tree view control in the dialog box [60] %� Syntax: {value/}'obj'�wi'Description'{value} [61] %� value: (System.String) [62] %� Example: [63] %� 'obj'�wi'Description'value [64] %� 'obj'�wi'Description' [65] :if 1=Ρ�warg [66] �wres/�wi'Getstring'(a,'.Description') [67] :else [68] z/�wi'Setstring'(a,'.Description')(''zzWarg�warg) [69] :endif [70] :return [71] %�------------------------------------------------rootfolder [72] Erootfolder: [73] %� Gets or sets the root folder where the browsing starts from [74] %� Syntax: {value/}'obj'�wi'RootFolder'{value} [75] %� value: (System.SpecialFolder) [76] %� 0= SpecialFolder.Desktop [77] %� 2= SpecialFolder.Programs [78] %� 5= SpecialFolder.MyDocuments [79] %� 5= SpecialFolder.Personal [80] %� 6= SpecialFolder.Favorites [81] %� 7= SpecialFolder.Startup [82] %� 8= SpecialFolder.Recent [83] %� 9= SpecialFolder.SendTo [84] %� 11= SpecialFolder.StartMenu [85] %� 13= SpecialFolder.MyMusic [86] %� 14= SpecialFolder.MyVideos [87] %� 16= SpecialFolder.DesktopDirectory [88] %� 17= SpecialFolder.MyComputer [89] %� 19= SpecialFolder.NetworkShortcuts [90] %� 20= SpecialFolder.Fonts [91] %� 21= SpecialFolder.Templates [92] %� 22= SpecialFolder.CommonStartMenu [93] %� 23= SpecialFolder.CommonPrograms [94] %� 24= SpecialFolder.CommonStartup [95] %� 25= SpecialFolder.CommonDesktopDirectory [96] %� 26= SpecialFolder.ApplicationData [97] %� 27= SpecialFolder.PrinterShortcuts [98] %� 28= SpecialFolder.LocalApplicationData [99] %� 32= SpecialFolder.InternetCache [100] %� 33= SpecialFolder.Cookies [101] %� 34= SpecialFolder.History [102] %� 35= SpecialFolder.CommonApplicationData [103] %� 36= SpecialFolder.Windows [104] %� 37= SpecialFolder.System [105] %� 38= SpecialFolder.ProgramFiles [106] %� 39= SpecialFolder.MyPictures [107] %� 40= SpecialFolder.UserProfile [108] %� 41= SpecialFolder.SystemX86 [109] %� 42= SpecialFolder.ProgramFilesX86 [110] %� 43= SpecialFolder.CommonProgramFiles [111] %� 44= SpecialFolder.CommonProgramFilesX86 [112] %� 45= SpecialFolder.CommonTemplates [113] %� 46= SpecialFolder.CommonDocuments [114] %� 47= SpecialFolder.CommonAdminTools [115] %� 48= SpecialFolder.AdminTools [116] %� 53= SpecialFolder.CommonMusic [117] %� 54= SpecialFolder.CommonPictures [118] %� 55= SpecialFolder.CommonVideos [119] %� 56= SpecialFolder.Resources

Page 71: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 71

[120] %� 57= SpecialFolder.LocalizedResources [121] %� 58= SpecialFolder.CommonOemLinks [122] %� 59= SpecialFolder.CDBurning [123] %� Example: [124] %� 'obj'�wi'RootFolder'value [125] %� 'obj'�wi'RootFolder' [126] :if 1=Ρ�warg [127] �wres/�wi'Getint'(a,'.RootFolder') [128] :else [129] z/�wi'Setint'(a,'.RootFolder')(''zzWarg�warg) [130] :endif [131] :return [132] %�------------------------------------------------selectedpath [133] Eselectedpath: [134] %� Gets or sets the path selected by the user [135] %� Syntax: {value/}'obj'�wi'SelectedPath'{value} [136] %� value: (System.String) [137] %� Example: [138] %� 'obj'�wi'SelectedPath'value [139] %� 'obj'�wi'SelectedPath' [140] :if 1=Ρ�warg [141] �wres/�wi'Getstring'(a,'.SelectedPath') [142] :else [143] z/�wi'Setstring'(a,'.SelectedPath')(''zzWarg�warg) [144] :endif [145] :return [146] %�------------------------------------------------shownewfolderbutton [147] Eshownewfolderbutton: [148] %� Gets or sets a value indicating whether the New Folder button appears in the folder browser dialog box [149] %� Syntax: {value/}'obj'�wi'ShowNewFolderButton'{value} [150] %� value: (System.Boolean) [151] %� Example: [152] %� 'obj'�wi'ShowNewFolderButton'value [153] %� 'obj'�wi'ShowNewFolderButton' [154] :if 1=Ρ�warg [155] �wres/�wi'Getbool'(a,'.ShowNewFolderButton') [156] :else [157] z/�wi'Setbool'(a,'.ShowNewFolderButton')(''zzWarg�warg) [158] :endif [159] :return [160] %�------------------------------------------------Reset [161] EReset: [162] %� Resets properties to their default values [163] %� Syntax: 'obj'�wi'Reset' [164] z/zzCSE'ExecStmt'(a,'.Reset();') [165] :return [166] %�------------------------------------------------onDisposed [167] EonDisposed: [168] %� (missing XML documentation) [169] %� Syntax: 'obj'�wi'onDisposed'sender e [170] %� sender: (System.Object) [171] %� e: (System.EventArgs) [172] �/Ewarg [173] :return [174] %�------------------------------------------------onHelpRequest [175] EonHelpRequest: [176] %� (missing XML documentation) [177] %� Syntax: 'obj'�wi'onHelpRequest'sender e [178] %� sender: (System.Object) [179] %� e: (System.EventArgs) [180] �/Ewarg

Page 72: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 72

[181] :return [182] %�================================================Generated Code [183] [184] %------------------------------------------------- [185] EEHelp: [186] �wres/�wi'GetHelp'(('?'=Cb)Xb) [187] :return [188] %------------------------------------------------- [189] EEInherit: [190] �wres/�wi'*' �

All this code has been automatically generated by the zGenerate object, using information retrieved by the

zReflection object.

Let’s immediately use our new APL zFolderBrowserDialog object:

'zfbd'�wi'*Create' 'zFolderBrowserDialog' zfbd 'zfbd'�wi'ShowDialog'

After selecting a folder and clicking OK, we get the following result in the APL Session:

1

What does 1 mean? It clearly is the result of the ShowDialog method, but what does it mean?

We’ll see that in a moment, but first how do we retrieve the folder the user has selected?

Page 73: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 73

Let’s look at the available zFolderBrowserDialog properties:

'zfbd'�wi'properties' class description help rootfolder selectedpath shownewfolderbutton

We see that there is a selectedpath property. Let’s use it:

'zfbd'�wi'selectedpath' D:\APLWIN14\Docs

Similarly we could have used the description and shownewfolderbutton properties before displaying the

dialog.

Example:

'zfbd'�wi'*Create' 'zFolderBrowserDialog' zfbd 'zfbd'�wi'shownewfolderbutton'0 'zfbd'�wi'description' 'Please select a folder...' 'zfbd'�wi'ShowDialog'

As you can see, Please select a folder… is now displayed at the top of the dialog and the Make New Folder

button did no longer display.

So using the C# FolderBrowserDialog object has now become extremely simple by only using ⎕wi: of

course ⎕cse is used in this whole process, but only behind the scene and its complexity is totally hidden to

the user.

Page 74: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 74

Enums

The .Net Framework makes a very large use of Enums.

Enums are synonyms to constants.

APL developers are used to create code similar to:

:select myVar :case 0 ? w :case 1 ? w :case 2 ? w :case 3 ? w :case 4 ? w :case 5 ? w :case 6 ? w :case 7 ? w :endselect

The problem of using constants (0, 1, 2, … 7) is that it makes programs hard to read and maintain because

those constant values do not carry any semantic information.

Of course, an APL developer could write:

(None OK Cancel Abort Retry Ignore Yes No)/¯1+Ι8

And then:

:select myVar :case None ? :case OK ? :case Cancel ? :case Abort ? :case Retry ? :case Ignore ? :case Yes ? :case No ? :endselect

This is much better and makes programs much easier to read, but with the disadvantage of cluttering up

the Symbol Table. Moreover, what should you do about those variables (None, OK, Cancel …)?

If you localize them in the program that uses them, then you have to recreate them in any other program

that will need them.

If you do not localize them, it is worse: you are creating global variables in your workspace which is a VERY

BAD habit. If you do that and have a need for a good number of “Enums” you’ll quickly clutter your

workspace with hundreds of global variables.

There is a solution to this Enum problem and this solution is very simple!

The zGenerate function has not only generated the zFolderBrowserDialog but has automatically generated

APL enums in the zzEnums APL function for any C# Enum used by FolderBrowserDialog methods or

properties.

Page 75: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 75

Looking at zzEnums we see that the following code has been automatically added:

DialogResult/�mom'' '' DialogResult.None/0 DialogResult.OK/1 DialogResult.Cancel/2 DialogResult.Abort/3 DialogResult.Retry/4 DialogResult.Ignore/5 DialogResult.Yes/6 DialogResult.No/7

So the :select … :case … :case examples above becomes:

:select myVar :case DialogResult.None ? :case DialogResult.OK ? :case DialogResult.Cancel ? :case DialogResult.Abort ? :case DialogResult.Retry ? :case DialogResult.Ignore ? :case DialogResult.Yes ? :case DialogResult.No ? :endselect

The solution is not perfect because it does create a global object (“variable”) called DialogResult in the

workspace, but it creates 1 instead of 8 globals. Moreover it groups all the possible values in a single

construct so it is easy to find out what all the possible values are.

This now allows us to write some very readable object oriented code (similar to C# code) such as:

:if DialogResult.OK@'zfbd'�wi'ShowDialog' folder/'zfbd'�wi'selectedpath' :endif

You may also have noticed that the auto-generated zFolderBrowserDialog object includes information

about enums and enum values in its properties/methods documentation.

Let’s for example retrieve the documentation of the rootfolder property:

'zfbd'�wi'?rootfolder' Gets or sets the root folder where the browsing starts from Syntax: {value/}'obj'�wi'RootFolder'{value} value: (System.SpecialFolder) 0= SpecialFolder.Desktop 2= SpecialFolder.Programs 5= SpecialFolder.MyDocuments 5= SpecialFolder.Personal 6= SpecialFolder.Favorites 7= SpecialFolder.Startup 8= SpecialFolder.Recent 9= SpecialFolder.SendTo 11= SpecialFolder.StartMenu 13= SpecialFolder.MyMusic 14= SpecialFolder.MyVideos 16= SpecialFolder.DesktopDirectory 17= SpecialFolder.MyComputer 19= SpecialFolder.NetworkShortcuts

Page 76: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 76

20= SpecialFolder.Fonts 21= SpecialFolder.Templates 22= SpecialFolder.CommonStartMenu 23= SpecialFolder.CommonPrograms 24= SpecialFolder.CommonStartup 25= SpecialFolder.CommonDesktopDirectory 26= SpecialFolder.ApplicationData 27= SpecialFolder.PrinterShortcuts 28= SpecialFolder.LocalApplicationData 32= SpecialFolder.InternetCache 33= SpecialFolder.Cookies 34= SpecialFolder.History 35= SpecialFolder.CommonApplicationData 36= SpecialFolder.Windows 37= SpecialFolder.System 38= SpecialFolder.ProgramFiles 39= SpecialFolder.MyPictures 40= SpecialFolder.UserProfile 41= SpecialFolder.SystemX86 42= SpecialFolder.ProgramFilesX86 43= SpecialFolder.CommonProgramFiles 44= SpecialFolder.CommonProgramFilesX86 45= SpecialFolder.CommonTemplates 46= SpecialFolder.CommonDocuments 47= SpecialFolder.CommonAdminTools 48= SpecialFolder.AdminTools 53= SpecialFolder.CommonMusic 54= SpecialFolder.CommonPictures 55= SpecialFolder.CommonVideos 56= SpecialFolder.Resources 57= SpecialFolder.LocalizedResources 58= SpecialFolder.CommonOemLinks 59= SpecialFolder.CDBurning Example: 'obj'�wi'RootFolder'value 'obj'�wi'RootFolder'

So, if we retrieve the value of the rootfolder property:

'zfbd'�wi'rootfolder' 0

We can immediately know that 0 means SpecialFolder.Desktop.

If we want to display the FolderBrowserDialog starting at any of these rootfolder we could write:

'zfbd'�wi'*Create' 'zFolderBrowserDialog' zfbd 'zfbd'�wi'rootfolder'42 'zfbd'�wi'ShowDialog'

Page 77: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 77

which indeed start at Program Files (x86), but who understands what 42 means?

So it would make your program much more understandable and maintainable if you write:

'zfbd'�wi'*Create' 'zFolderBrowserDialog' zfbd 'zfbd'�wi'rootfolder' SpecialFolder.ProgramFilesX86 'zfbd'�wi'ShowDialog'

using our auto-generated Enum.

The zCommonDialog Object

The first time I created the zFolderBrowserDialog object (my first C# object automatically converted to an

APL+Win object) using zGenerate, I was pretty happy and full of enthusiasm, but when I tried:

'zfbd'�wi'*Create' 'zFolderBrowserDialog' zfbd 'zfbd'�wi'rootfolder' SpecialFolder.ProgramFilesX86 'zfbd'�wi'ShowDialog'

It failed because it did not know the ShowDialog method.

So I looked at the zFolderBrowserDialog generated code and indeed there was no ShowDialog method

automatically created in it.

During a few seconds this did surprise me, as I am used to call ShowDialog on a FolderBrowserDialog when

I develop C# applications or DLLs, and of course it works well.

Page 78: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 78

A little bit of searching indicates that all .Net framework dialogs (ColorDialog, FontDialog,

PageSetupDialog, OpenFileDialog, PrintPreviewDialog and SaveFileDialog) inherit from a .Net Framework

type called CommonDialog. This makes a lot of sense, when you think of it: if all these .Net Framework

dialogs did not inherit from CommonDialog, Microsoft would have had to add a ShowDialog method to ALL

of them, unnecessarily duplicating code, which also is a VERY BAD habit. We do NOT want to do that in our

zObjects either, of course.

So what did I have to do to make things work like it does in C#?

First, I auto-generated a zCommonDialog object with the following instructions:

'zgen'�wi'*Create' 'ZGenerate' 'zgen'�wi'Generate' 'zCommonDialog' 'CommonDialog' 'CommonDialog' 0'ms'

Then, I included the following code (highlighted in yellow) in the zFolderBrowserDialog to make the APL

zFolderBrowserDialog inherit from zCommonDialog:

[20] %�------------------------------------------------New [21] ENew: [22] %� Create a new instance of zFolderBrowserDialog [23] %� Example: [24] %� 'ff'�wi'*Create' 'zFolderBrowserDialog' [25] z/a�wi'*Create' 'zForm' '*Hide' [26] z/a�wi'*onAction'(L'zFolderBrowserDialog' 'zCommonDialog' 'zConverters' 'zObject',¨N'"Action"',�tcnl) [27] c/rn\raG'.' [28] d/¯1X(pc)/a % parent name [29] e/c/a % top level name for C# object [30] :try * [31] z/zzCSE'ExecStmt'(e,'.Dispose();') [32] :catchall [33] :endtry [34] z/zzCSE'ExecStmt'('FolderBrowserDialog ',e,' = new FolderBrowserDialog();') [35] :try * [36] z/zzCSE'ExecStmt'(e,'.Name = "',e,'";') [37] :catchall [38] :endtry [39] z/a�wi'*∆∆∆isnetcontrol'1 [40] % z/�wi'AddHandler' 'Disposed' [41] % z/�wi'AddHandler' 'HelpRequest' [42] :return

This took me a total of 10 to 20 seconds and suddenly I could fully use zFolderBrowserDialog in APL with

⎕wi, calling its ShowDialog method.

Beautiful!

If you are curious, here is the auto-generated code for the zCommonDialog object:

Page 79: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 79

� a zCommonDialog b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;Ewarg;�io [1] %� r/a zCommonDialog b -- The zCommonDialog Object is the zObjects implementation of a .Net Framework CommonDialog object [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2014 Eric Lescasse [10] %� ELE12feb14 [11] [12] �io/1 [13] �cself/'zcsedx' [14] :if �monadic ? a/�wself ? :end [15] :if'Action'@Ewarg/b ? 0('?'=Cb/C�warg)ΡEEHelp ? :end [16] :if(�dr b)L326 807 ? :andif 6=Ρb ? b/'on',3cb ? :endif [17] 0(8G''Ρ�idloc'E',b)ΡEEInherit [18] :if'New'Pb ? a/(rn\raG'.')/a ? :endif [19] 0J'E',b [20] %�------------------------------------------------New [21] ENew: [22] %� Create a new instance of zForm [23] %� Example: [24] %� 'ff'�wi'*Create' 'zCommonDialog' [25] z/a�wi'*Create' 'Label'('*scale'5)('*caption' '') [26] z/a�wi'*onAction'(L'zCommonDialog' 'zUserControl' 'zConverters' 'zObject',¨N'"Action"',�tcnl) [27] z/a�wi'clipsiblings'1 [28] c/rn\raG'.' [29] d/¯1X(pc)/a % parent name [30] e/c/a % top level name for C# object [31] :try * [32] z/zzCSE'ExecStmt'(e,'.Dispose();') [33] :catchall [34] :endtry [35] z/zzCSE'ExecStmt'('CommonDialog ',e,' = new CommonDialog();') [36] h/zzCSE'GetValue'('(int)',e,'.Handle') [37] :try * [38] z/zzCSE'ExecStmt'(e,'.Name = "',e,'";') [39] :catchall [40] :endtry [41] z/�wcall'SetParent'h(d�wi'*hwnd') [42] z/a�wi'*∆∆∆isnetcontrol'1 [43] z/a�wi'*∆∆∆defaultheight'(zzCSE'GetValue'(e,'.Height')) [44] z/a�wi'*onMove' 'zObject"onMove"' [45] z/a�wi'*onResize' 'zObject"onResize"' [46] % z/�wi'AddHandler' 'Disposed' [47] % z/�wi'AddHandler' 'HelpRequest' [48] :return [49] %�------------------------------------------------class [50] Eclass: [51] �wres/'zCommonDialog' [52] :return [53] %�------------------------------------------------help [54] Ehelp: [55] %� 0 0Ρ'ff'�wi'*Create' 'zCommonDialog' [56] �wres/�wi'GetHelp' 'help' [57] :return [58] [59] %�================================================Protected Code

Page 80: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 80

[60] %�================================================Protected Code [61] [62] %�================================================Generated Code [63] %�------------------------------------------------tag [64] Etag: [65] %� Gets or sets an object that contains data about the control [66] %� Syntax: {value/}'obj'�wi'Tag'{value} [67] %� value: (System.Object) [68] %� Example: [69] %� 'obj'�wi'Tag'value [70] %� 'obj'�wi'Tag' [71] :if 1=Ρ�warg [72] �wres/�wi'Getobject'(a,'.Tag') [73] :else [74] z/�wi'Setobject'(a,'.Tag')(''zzWarg�warg) [75] :endif [76] :return [77] %�------------------------------------------------Reset [78] EReset: [79] %� When overridden in a derived class, resets the properties of a common dialog box to their default values [80] %� Syntax: 'obj'�wi'Reset' [81] z/zzCSE'ExecStmt'(a,'.Reset();') [82] :return [83] %�------------------------------------------------ShowDialog [84] EShowDialog: [85] %� Runs a common dialog box with a default owner [86] %� Syntax: result/'obj'�wi'ShowDialog' [87] %� result: (System.Windows.Forms.DialogResult) [88] %� 0= DialogResult.None [89] %� 1= DialogResult.OK [90] %� 2= DialogResult.Cancel [91] %� 3= DialogResult.Abort [92] %� 4= DialogResult.Retry [93] %� 5= DialogResult.Ignore [94] %� 6= DialogResult.Yes [95] %� 7= DialogResult.No [96] z/zzCSE'ExecStmt' 'DialogResult result;' [97] z/zzCSE'ExecStmt'('result = ',a,'.ShowDialog();') [98] �wres/�wi'Getint' 'result' [99] :return [100] %�------------------------------------------------onDisposed [101] EonDisposed: [102] %� (missing XML documentation) [103] %� Syntax: 'obj'�wi'onDisposed'sender e [104] %� sender: (System.Object) [105] %� e: (System.EventArgs) [106] �/Ewarg [107] :return [108] %�------------------------------------------------onHelpRequest [109] EonHelpRequest: [110] %� (missing XML documentation) [111] %� Syntax: 'obj'�wi'onHelpRequest'sender e [112] %� sender: (System.Object) [113] %� e: (System.EventArgs) [114] �/Ewarg [115] :return [116] %�================================================Generated Code [117] [118] %------------------------------------------------- [119] EEHelp: [120] �wres/�wi'GetHelp'(('?'=Cb)Xb)

Page 81: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 81

[121] :return [122] %------------------------------------------------- [123] EEInherit: [124] �wres/�wi'*' �

Type Conversion: the zConverters object

If you have carefully looked at the properties and methods contained in zFolderBrowserDialog and in

zCommonDialog, you must have seen that I have been using things like:

⎕wi'Getbool'

⎕wi'Setbool'

⎕wi'Getint'

⎕wi'Setint'

⎕wi'Getstring'

⎕wi'Setstring'

⎕wi'Getobject'

⎕wi'Setobject'

The reason is the following:

• As we said, APL contains 4 data types (boolean, integer, floating point and character)

• The .Net Framework contains between 10000 and 20000 types, not counting all the third party

vendor types (hundreds of thousands of them) and all the ones you build yourself4

Among all those types, APL basically understands only 4!

So, if a C#5 method or property returns a type which is not one of those 4, there’s no way you can directly

get the result in APL, unfortunately!

But things are not as bad as you may think!

A lot of C# types could be resolved to things compatible with APL.

For example, C# Forms and Controls have a Location type and a Size type:

• The Location type has an X and a Y property which are integers

• The Size type has a Height and a Width property which are integers

So a Location could be expressed in APL as a vector of 2 integers (Y, X), shouldn’t it?

4 Every class you create in C# becomes a new type that is then used in the same exact manner as you use the .Net

Framework types.

5 When I say C#, understand “the .Net Framework”: I use C# as an alias just because it is faster to type.

Page 82: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 82

And Size could also be expressed in APL a vector of 2 integers (Height, Width) as well.

All we need is a Converter that is able to automatically convert a Location to a vector of 2 integers and

another Converter which converts a Size into a vector of 2 integers.

There are many other C# types that can indeed be converted to some APL data type structure.

So the whole idea is to build Converters to be able to convert as many C# types to APL as possible (back and

forth).

The zConverters C# class

Therefore I have developed a zConverters C# class in the zObjects DLL.

It contains converters for many types.

Here is an example:

public static int[] FromSize(Size c)

{ return new int[] { c.Height, c.Width };

}

public static Size ToSize(int[] v)

{ return new Size(v[1], v[0]);

}

The FromSize method converts a C# Size type into a vector of integers.

The ToSize method converts a vector of 2 integers into a C# Size object.

Really easy, isn’t it?

Note the order I have been using: I have been using Height first and Width second, to mimic what we are

used to in APL where the Height is used first, before Width (for example in the APL where and size

properties) whereas in the C# world Width is always used first.

But it is not enough to be able to convert one Size to a vector of 2 integers.

What if you need to convert 1000 Size objects? You sure don’t want to have to call the FromSize method

1000 times.

So, all my converters work with rank-0, rank-1 and rank-2 arrays.

It is not very much more difficult to develop C# Converters that handle vectors and matrices.

Hence, as an example, here are my FromSize and ToSize C# converters:

Page 83: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 83

#region----------------------------------------------------------------FromSize, ToSize

public static int[] FromSize(Size c) {

return new int[] { c.Height, c.Width };

}

public static int[,] FromSize(Size[] c)

{

int[,] result = new int[c.Length, 2];

for (int i = 0; i < c.Length; i++)

{ result[i, 0] = c[i].Height;

result[i, 1] = c[i].Width;

}

return result;

}

public static int[, ,] FromSize(Size[,] c) {

int[, ,] result = new int[c.GetLength(0), c.GetLength(1), 2];

for (int i = 0; i < c.GetLength(0); i++)

{

for (int j = 0; j < c.GetLength(1); j++)

{

result[i, j, 0] = c[i, j].Height; result[i, j, 1] = c[i, j].Width;

}

}

return result;

}

public static Size ToSize(int[] v)

{

return new Size(v[1], v[0]);

}

public static Size[] ToSize(int[,] v)

{ Size[] result = new Size[v.GetLength(0)];

for (int i = 0; i < v.GetLength(0); i++)

result[i] = new Size(v[i, 1], v[i, 0]); return result;

}

public static Size[,] ToSize(int[, ,] v)

{

Size[,] result = new Size[v.GetLength(0), v.GetLength(1)];

for (int i = 0; i < v.GetLength(0); i++) for (int j = 0; j < v.GetLength(1); j++)

result[i, j] = new Size(v[i, j, 1], v[i, j, 0]);

return result;

}

#endregion-------------------------------------------------------------FromSize, ToSize

Of course, I have had to create a zConverters APL class as well to allow calling the methods in the C#

zConverters class easily, in an APL way, using ⎕wi.

Each type converter includes a Getxxxx and a Setxxxx method where xxxx is the type name.

So, for example, here are the APL converters for the Size C# type:

Page 84: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 84

%�------------------------------------------------GetSize EGetSize: �wres/zzTranspose zzCSE'GetValue'('zConverters.FromSize(',(2c�warg),');') :return %�------------------------------------------------SetSize ESetSize: (c d)/1X�warg (f g)/(eCc)(cX�e/¯1+cΙ'[') :if''@g/gp' ' z/zzCSE'ExecStmt'(((p'.'Lf)/'Size '),f,' = new Size(',('/¯/-'zzTEXTREPLvd[2]),',',('/¯/-'zzTEXTREPLvd[1]),');') :else :select gp' ' :case'[]' ? h/'[,]' :case'[,]' ? h/'[,,]' :endselect d/(Ρd)Ρ1c(�dr d)323�dr d/�d % coerce d to int :ifp'.'Lf ? z/zzCSE'ExecStmt'('Size',g,' ',f,' = new Size',g,'{};') ? :endif z/zzCSE'ExecStmt'('int',h,' ',f,'int = new int',h,'{};') z/zzCSE'SetValue'(f,'int')(zzTranspose d) z/zzCSE'ExecStmt'(f,' = zConverters.ToSize(',f,'int);') :endif :return

It may seem a little complicated, but once it is written, it will be used for years transparently and you will

even totally forget that a Converter is running in the background when you use your C# Size property.

Thanks to this Size converter, I can now create a matrix of 1000 by 100 Size objects as follows:

'zconv'�wi'*Create' 'zConverters' zconv 'zconv'�wi'SetSize' 'matSize[,]6' (1000 100 2ΡΙ100000)

This creates a matrix of 1000 by 100 Size objects in the current ⎕cse object.

You may ask yourself: ok, but is this fast?

]times 'zconv'�wi'SetSize' 'matSize[,]' (1000 100 2ΡΙ100000) 29

My ]times User Command indicates it takes 29 milliseconds which is pretty fast for converting a hundred

thousand Size objects!

We can check that the ⎕cse created variable is indeed a matrix of Size objects:

�cse'GetObjectType' 'matSize' System.Drawing.Size[,]

And we can retrieve the content of the ⎕cse matSize object as follows:

Ρ'zconv'�wi'GetSize' 'matSize' 1000 100 2

6 Note that you must append [] or [,] to the variable name with the Setxxxx methods to inform the system of the structure

of the variable you are creating, when you are not creating a scalar

Page 85: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 85

When you do so, the GetSize method is called and converts the Size objects back to an array of integers.

And I can use the same SetSize method to convert a single Size object or a vector of Size objects:

'zconv'�wi'SetSize' 'scalarSize' (30 20)

'zconv'�wi'GetSize' 'scalarSize' 30 20 'zconv'�wi'SetSize' 'vecSize[]' (10 2ΡΙ20) 'zconv'�wi'GetSize' 'vecSize' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

The zGenerate Code Generator makes a heavy use of zConverters methods to convert as many C# types

and structures as possible to APL (and vice versa).

And therefore all zObjects generated by zGenerate, inherit from zConverters to be able to use these

conversion methods.

The types which are currently supported by zObjects can be obtained by:

'zref'�wi'*Create' 'zReflection' zref c'zref'�wi'ConvertibleTypes' void bool byte char checkedindexcollection color datetime decimal double float geopoint int intptr long mappoint object objectcollection padding point rectangle sbyte selectedindex selectedindexcollection selecteditem selectedobjectcollection short

Page 86: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 86

size sizef string uint ulong uri ushort

Again, mostly all these converters supports scalars, vectors and matrices of those types.

Some other examples:

'zconv'�wi'SetDateTime' 'dates[]' (20140320+Ι8) 'zconv'�wi'GetDateTime' 'dates' 20140321 20140322 20140323 20140324 20140325 20140326 20140327 20140328 �cse'GetObjectType' 'dates' System.DateTime[] 'zconv'�wi'SetDateTime' 'matdates[,]' (4 4Ρ20140100+Ι16) �cse'GetObjectType' 'matdates' System.DateTime[,] 'zconv'�wi'GetDateTime' 'matdates' 20140101 20140102 20140103 20140104 20140105 20140106 20140107 20140108 20140109 20140110 20140111 20140112 20140113 20140114 20140115 20140116 'zconv'�wi'SetRectangle' 'rect' (10 20 30 40) 'zconv'�wi'GetRectangle' 'rect' 10 20 30 40 �cse'GetValue' 'rect.X' 20 �cse'GetValue' 'rect.Y' 10 �cse'GetValue' 'rect.Height' 30 �cse'GetValue' 'rect.Width' 40

'zconv'�wi'SetRectangle' 'rectvec[]' (10 4ΡΙ40) 'zconv'�wi'GetRectangle' 'rectvec' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

In future versions of zObjects, a lot of additional C# types could be supported for auto-conversion between

APL and C#.

Page 87: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 87

Using the zGenerate Class

Now that we have been able to develop a zGenerate class, let’s use it to convert .Net objects into APL

objects.

Converting .Net Forms or Dialog Boxes

Common Dialog Boxes

We have already seen how we can convert the .Net Framework FolderBrowserDialog into an APL

zFolderBrowserDialog object. We can use the following instructions to convert the other .Net Common

Dialogs:

'zgen'�wi'*Create' 'zGenerate' 'zgen'�wi'Generate' 'zColorDialog' '' 'ColorDialog' 4 'ms' 'zgen'�wi'Generate' 'zFontDialog' '' 'FontDialog' 4 'ms' 'zgen'�wi'Generate' 'zOpenFileDialog' '' 'OpenFileDialog' 4 'ms' 'zgen'�wi'Generate' 'zPageSetupDialog' '' 'PageSetupDialog' 4 'ms' 'zgen'�wi'Generate' 'zPrintDialog' '' 'PrintDialog' 4 'ms' 'zgen'�wi'Generate' 'zPrintPreviewDialog' '' 'PrintPreviewDialog' 4 'ms' 'zgen'�wi'Generate' 'zSaveFileDialog' '' 'SaveFileDialog' 4 'ms'

If you run these instructions, in way less than a minute you’ll have all the .Net Common Dialogs now

available and fully functional in APL.

A complete and fully functional Rich Text Editor

Let’s create a complete Text Editor with a ribbon, icons, etc.

1. Open Visual Studio

2. Create a new C# Project. Be sure to select the .Net Framework 4.5!

3. Right click the project in Solution Explorer, select Add and choose DevExpress 13.2 Template

Gallery7

4. Call the new form: zRichEditDXForm2

5. Click the Add button

6. In the DevExpress Template Gallery Wizard, choose Form

7. Enter zRichEditDXForm2 as the Item Name

8. Click the Add Item button

9. Then drag and drop a DevExpress 13.2 RichEditControl on to the Form

10. Click the Create Ribbon, then the Create All Tabs link

After seconds a Ribbon with a complete set of Tabs, Bars and Icons is created in the form

11. Click on the RIchEditControl to select it

7 For that you must have downloaded a free Trial version of the DevExpress WinForms Library or have acquired it

Page 88: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 88

12. In the Properties pane, change its Dock property to Fill

13. Finally, select the Form and change its Text property to Rich Text Editor

14. Compile the project

Page 89: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 89

Now let’s load APL+Win v14 and load the zObjects workspace.

Now, let’s generate a zRichEditDXForm2 APL object:

Page 90: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 90

'zgen'�wi'Generate' 'zRichEditDXForm' 'zRichEditDXForm' '' 3 ''

We can start using it right away:

'zrich'�wi'*Create' 'zRichEditDXForm' 'Show'

We have been able to build in less than 5 minutes a complete fully functional8 Rich Text Editor which would

have required several days (at least) of very difficult coding if we had had to do it with just APL+Win.

Additionally the User Interface is just great!

Converting Standard .Net Framework Controls

Getting the list of standard .Net Framework Controls

The Windows Forms .Net Framework includes a whole bunch of Controls and it would be nice to be able to

use some of them in our APL+Win Forms.

The zReflection GetControlTypes method allows us to get a list of those controls:

'zref'�wi'?GetControlTypes' Returns a list of all the types contained in the specified namespace which are controls Syntax: types/'obj'�wi'GetControlTypes'namespace namespace: character string (an existing .Net Framework namespace) types: a 6-column nested matrix with one type per line [;1]= type name [;2]= base type name [;3]= namespace [;4]= assembly name [;5]= reflected type (class used to get property info)

8 All the ribbon icons in this object are functional with appropriate dialog boxes to do their job!

Page 91: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 91

[;6]= declaring type (class that declares this property) Example: 'zref'�wi'GetControlTypes' 'System.Windows.Forms'

Let’s see which controls are contained in the System.Windows.Forms namespace (for lack of room, I am

displaying only the first 3 output columns below):

3C[2]'zref'�wi'GetControlTypes' 'System.Windows.Forms' AxHost Control System.Windows.Forms BindingNavigator ToolStrip System.Windows.Forms Button ButtonBase System.Windows.Forms ButtonBase Control System.Windows.Forms CheckBox ButtonBase System.Windows.Forms CheckedListBox ListBox System.Windows.Forms ComboBox ListControl System.Windows.Forms ContainerControl ScrollableControl System.Windows.Forms ContextMenuStrip ToolStripDropDownMenu System.Windows.Forms Control Component System.Windows.Forms DataGrid Control System.Windows.Forms DataGridTextBox TextBox System.Windows.Forms DataGridView Control System.Windows.Forms DataGridViewComboBoxEditingControl ComboBox System.Windows.Forms DataGridViewTextBoxEditingControl TextBox System.Windows.Forms DateTimePicker Control System.Windows.Forms DomainUpDown UpDownBase System.Windows.Forms FeedbackDropDown ToolStripDropDown System.Windows.Forms FlowLayoutPanel Panel System.Windows.Forms Form ContainerControl System.Windows.Forms GroupBox Control System.Windows.Forms HScrollBar ScrollBar System.Windows.Forms Label Control System.Windows.Forms LinkLabel Label System.Windows.Forms ListBox ListControl System.Windows.Forms ListControl Control System.Windows.Forms ListView Control System.Windows.Forms MarshalingControl Control System.Windows.Forms MaskedTextBox TextBoxBase System.Windows.Forms MdiClient Control System.Windows.Forms MdiControlStrip MenuStrip System.Windows.Forms MdiWindowDialog Form System.Windows.Forms MdiWindowListStrip MenuStrip System.Windows.Forms MenuStrip ToolStrip System.Windows.Forms MonthCalendar Control System.Windows.Forms NumericUpDown UpDownBase System.Windows.Forms Panel ScrollableControl System.Windows.Forms ParkingWindow ContainerControl System.Windows.Forms PictureBox Control System.Windows.Forms PrintPreviewControl Control System.Windows.Forms PrintPreviewDialog Form System.Windows.Forms ProgressBar Control System.Windows.Forms PropertyGrid ContainerControl System.Windows.Forms RadioButton ButtonBase System.Windows.Forms RichTextBox TextBoxBase System.Windows.Forms RightToLeftLayoutGrip Control System.Windows.Forms ScrollableControl Control System.Windows.Forms ScrollBar Control System.Windows.Forms SKWindow Control System.Windows.Forms SnappableControl Control System.Windows.Forms SplitContainer ContainerControl System.Windows.Forms Splitter Control System.Windows.Forms

Page 92: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 92

SplitterPanel Panel System.Windows.Forms StatusBar Control System.Windows.Forms StatusDialog Form System.Windows.Forms StatusStrip ToolStrip System.Windows.Forms StickyLabel Label System.Windows.Forms TabControl Control System.Windows.Forms TableLayoutPanel Panel System.Windows.Forms TabPage Panel System.Windows.Forms TextBox TextBoxBase System.Windows.Forms TextBoxBase Control System.Windows.Forms ThreadExceptionDialog Form System.Windows.Forms ToolBar Control System.Windows.Forms ToolStrip ScrollableControl System.Windows.Forms ToolStripComboBoxControl ComboBox System.Windows.Forms ToolStripContainer ContainerControl System.Windows.Forms ToolStripContentPanel Panel System.Windows.Forms ToolStripDropDown ToolStrip System.Windows.Forms ToolStripDropDownMenu ToolStripDropDown System.Windows.Forms ToolStripOverflow ToolStripDropDown System.Windows.Forms ToolStripPanel ContainerControl System.Windows.Forms ToolStripTextBoxControl TextBox System.Windows.Forms TrackBar Control System.Windows.Forms TreeView Control System.Windows.Forms UpDownBase ContainerControl System.Windows.Forms UpDownButtons Control System.Windows.Forms UpDownEdit TextBox System.Windows.Forms UserControl ContainerControl System.Windows.Forms VScrollBar ScrollBar System.Windows.Forms WebBrowser WebBrowserBase System.Windows.Forms WebBrowserBase Control System.Windows.Forms

The zLinkLabel and zWebBrowser Example

Let’s create a small APL application that uses a LinkLabel and a WebBrowser object.

Our first task is to generate a zLinkLabel APL object and a zWebBrowser APL object:

'zgen'�wi'Generate' 'zLinkLabel' '' 'LinkLabel' 1 'ms' zLinkLabel 'zgen'�wi'Generate' 'zWebBrowser' '' 'WebBrowser' 1 'ms' zWebBrowser

Let’s now create an APL Form that will host these objects:

'zf'�wi'*Create' 'zForm'('*caption' 'zLinkLabel and zWebBrowser Demo')'DemoShow' zf 'zf'�wi'*.ll.Create' 'zLinkLabel'('wherelc'h h h 200)('text' 'APL2000 Web Site') zf.ll 'zf'�wi'*.web.Create' 'zWebBrowser'('wherelc' '>' '=' '>' '>')('anchor'1 2 3 4) zf.web

Fine: see how we can resize the APL form and how the zWebBrowser object gets nicely resized.

Let’s see what events are available for the zLinkLabel:

100 TELPRINTc'zf.ll'�wi'events' onAutoSizeChanged onForeColorChanged onMouseMove onBackColorChanged onGiveFeedback onMouseUp onBackgroundImageChanged onGotFocus onMouseWheel

Page 93: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 93

onBackgroundImageLayoutChanged onHandleCreated onMove onBindingContextChanged onHandleDestroyed onPaddingChanged onCausesValidationChanged onHelpRequested onPaint onChangeUICues onImeModeChanged onParentChanged onClick onInvalidated onPreviewKeyDown onClientSizeChanged onKeyDown onQueryAccessibilityHelp onContextMenuChanged onKeyPress onQueryContinueDrag onContextMenuStripChanged onKeyUp onRegionChanged onControlAdded onLayout onResize onControlRemoved onLeave onRightToLeftChanged onCursorChanged onLinkClicked onSizeChanged onDisposed onLocationChanged onStyleChanged onDockChanged onLostFocus onSystemColorsChanged onDoubleClick onMarginChanged onTabIndexChanged onDragDrop onMouseCaptureChanged onTabStopChanged onDragEnter onMouseClick onTextAlignChanged onDragLeave onMouseDoubleClick onTextChanged onDragOver onMouseDown onValidated onEnabledChanged onMouseEnter onValidating onEnter onMouseHover onVisibleChanged onFontChanged onMouseLeave

We now need to handle a LinkClicked event (which is a C# event) on the zLinkLabel.

Using the AddHandler method (which is inherited from the zObject object), this is as easy as:

'zf'�wi'.ll.AddHandler' 'LinkClicked'

All objects generated with zGenerate are events ready! (i.e. code has been already generated to properly

handle all events).

So let’s click on the zLinkLabel.

Here is what we receive in the APL Session:

zcsedx ll LinkClicked cseEvt_1 Button 1048576 Link See _cseEvt for this object

If we click again a couple of times, we get:

zcsedx ll LinkClicked cseEvt_2 Button 1048576 Link See _cseEvt for this object zcsedx ll LinkClicked cseEvt_3 Button 1048576 Link See _cseEvt for this object

On the other hand, let’s see what methods are available for a zWebBrowser object:

90 TELPRINTc'zf.web'�wi'methods' GoBack New ShowPrintPreviewDialog GoForward Print ShowPropertiesDialog GoHome Refresh ShowSaveAsDialog GoSearch ShowPageSetupDialog Stop Navigate ShowPrintDialog

And let’s see what the documentation is for the Navigate method:

'zf.web'�wi'?Navigate'

Page 94: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 94

Loads the document at the location indicated by the specified System.Uri into the System.Windows.Forms.WebBrowser control, replacing the previous document Syntax: 'obj'�wi'Navigate'url url: (System.Uri)

So we now just have to change the zLinkLabel onLinkClicked event handler from:

%�------------------------------------------------onLinkClicked EonLinkClicked: %� (missing XML documentation) %� Syntax: 'obj'�wi'onLinkClicked'sender e %� sender: (System.Object) %� e: (System.Windows.Forms.LinkLabelLinkClickedEventArgs) �/Ewarg :return

to:

%�------------------------------------------------onLinkClicked EonLinkClicked: %� (missing XML documentation) %� Syntax: 'obj'�wi'onLinkClicked'sender e %� sender: (System.Object) %� e: (System.Windows.Forms.LinkLabelLinkClickedEventArgs) z/'zf.web'�wi'Navigate' 'http://www.apl2000.com' :return

It is time to click on our zLinkLabel object in our APL Form:

Page 95: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 95

So, to sum up, all we have had to do (except automatically generating the zLinkLabel and the zWebBrowser

objects) is summarized in the following function:

� zzlinklabel;z [1] z/'zf'�wi'*Create' 'zForm'('*caption' 'zLinkLabel and zWebBrowser Demo')'DemoShow' [2] z/'zf'�wi'*.ll.Create' 'zLinkLabel'('wherelc'h h h 200)('text' 'APL2000 Web Site') [3] z/'zf'�wi'*.web.Create' 'zWebBrowser'('wherelc' '>' '=' '>' '>')('anchor'1 2 3 4) [4] z/'zf'�wi'.ll.AddHandler' 'LinkClicked' [5] % Also we added the following line in the zLinkLabel onLinkClicked event handler: [6] % z/'zf.web'�wi'Navigate' 'http://www.apl2000.com' �

Mostly all .Net Framework Windows Forms controls can be almost instantly be converted into APL objects

and used in APL+Win Forms in the same manner we did it for zLinkLabel and zWebBrowser.

The zCheckedListBox Example

Here is another example.

Have you ever had a need for using a ListBox that would contain a CheckBox for each of its items? Maybe

not, but the .Net Framework has a CheckedListBox object.

Let’s make a zCheckedListBox APL object:

'zgen'�wi'Generate' 'zCheckedListBox' '' 'CheckedListBox' 1 'ms' zCheckedListBox

Let’s see what properties, methods and events this object has:

90 TELPRINTc'zf'�wi'.zclb.properties' backcolor forecolor selectedindex backgroundimage formatinfo selectedindices backgroundimagelayout formatstring selecteditem borderstyle formattingenabled selecteditems checkedindices help selectedvalue checkeditems horizontalextent selectionmode checkonclick horizontalscrollbar sorted class integralheight text columnwidth itemheight threedcheckboxes container items topindex customtaboffsets multicolumn usecompatibletextrendering datasource padding usecustomtaboffsets displaymember preferredheight usetabstops drawmode righttoleft valuemember font scrollalwaysvisible 90 TELPRINTc'zf'�wi'.zclb.methods' BeginUpdate GetItemCheckState InitializeLifetimeService ClearSelected GetItemChecked New CreateObjRef GetItemHeight Refresh Dispose GetItemRectangle ResetBackColor EndUpdate GetItemText ResetForeColor Equals GetLifetimeService SetItemCheckState FindString GetSelected SetItemChecked FindStringExact GetType SetSelected GetHashCode IndexFromPoint ToString

Page 96: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 96

100 TELPRINTc'zf'�wi'.zclb.events' onAutoSizeChanged onForeColorChanged onMouseHover onBackColorChanged onFormat onMouseLeave onBackgroundImageChanged onFormatInfoChanged onMouseMove onBackgroundImageLayoutChanged onFormatStringChanged onMouseUp onBindingContextChanged onFormattingEnabledChanged onMouseWheel onCausesValidationChanged onGiveFeedback onMove onChangeUICues onGotFocus onPaddingChanged onClick onHandleCreated onPaint onClientSizeChanged onHandleDestroyed onParentChanged onContextMenuChanged onHelpRequested onPreviewKeyDown onContextMenuStripChanged onImeModeChanged onQueryAccessibilityHelp onControlAdded onInvalidated onQueryContinueDrag onControlRemoved onItemCheck onRegionChanged onCursorChanged onKeyDown onResize onDataSourceChanged onKeyPress onRightToLeftChanged onDisplayMemberChanged onKeyUp onSelectedIndexChanged onDisposed onLayout onSelectedValueChanged onDockChanged onLeave onSizeChanged onDoubleClick onLocationChanged onStyleChanged onDragDrop onLostFocus onSystemColorsChanged onDragEnter onMarginChanged onTabIndexChanged onDragLeave onMeasureItem onTabStopChanged onDragOver onMouseCaptureChanged onTextChanged onDrawItem onMouseClick onValidated onEnabledChanged onMouseDoubleClick onValidating onEnter onMouseDown onValueMemberChanged onFontChanged onMouseEnter onVisibleChanged

As you can see a simple object like a CheckedListBox in C# has a lot of Properties, Methods and Events.

Let’s create a simple function to use our zCheckedListBox in an APL+Win Form:

� zzcheckedlistbox;z [1] z/'zf'�wi'*Create' 'zForm'('*caption' 'zCheckedListBox Example')('ontop'1)'*Hide' [2] z/'zf'�wi'*.zclb.Create' 'zCheckedListBox'('wherelc'h h 200 250)('anchor'1 2 3 4)('items'(zzDEB¨�split�nl 3)) [3] z/'zf'�wi'AutoFit' [4] z/'zf'�wi'DemoShow' [5] �wself/'zf.zclb' �

Page 97: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 97

And let’s run it:

zzcheckedlistbox

After checking a few items, we can query some properties:

�wi'checkedindices' 0 3 4 7 11 �wi'selectedindices' 0 �wi'selecteditems' AutoStart �wi'selecteditem' AutoStart �wi'selectedindex' 0 Ρ�wi'items' 210 10C�wi'items' AutoStart TELPRINT TEdit5 TForm5 TImagelist5 TMDIForm5 TObject5 TPage5 TResource5 Test

�wi'SetItemChecked'2 1 �wi'GetItemChecked'2 1 �wi'SetItemChecked'2 0 �wi'GetItemChecked'2

Page 98: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 98

The zNotifyIcon Example

Here is another example.

Let’s suppose you want to display a notification message in the tray icon. The .Net Framework has a

NotifyIcon object for that. Let’s convert it to an APL object:

'zgen'�wi'Generate' 'zNotifyIcon' 'NotifyIcon' 'NotifyIcon' 0'ms'

Now, let’s write a simple APL function that uses this object:

� zznotifyicon;z [1] �wself/'zni'�wi'*Create' 'zNotifyIcon'('visible'1) [2] z/�cse'ExecStmt' 'zni.Icon = SystemIcons.Exclamation;' [3] % z/�wi'icon'SystemIcons.Exclamation [4] :if 1 [5] z/�wi'balloontiptitle' 'Balloon Tip Title' [6] z/�wi'balloontiptext' 'Balloon Tip text' [7] z/�wi'balloontipicon'ToolTipIcon.Warning [8] z/�wi'ShowBalloonTip'1000 [9] :else [10] z/�wi'ShowBalloonTip2'1000'Balloon Tip Title' 'Balloon Tip text'ToolTipIcon.Warning [11] :endif �

Let’s use it:

zznotifyicon

As soon as you execute the above function the following notification balloon gets displayed in the tray icon:

The key to make the zNotifyIcon object work, is to set the Icon property.

Unfortunately, the zObjects system does not yet have a converter for the Icon type, so if you try to set the

icon property with ⎕wi, you’ll get an error:

'zni'�wi'?icon' Gets or sets the current icon Syntax: {value/}'obj'�wi'Icon'{value} value: (System.Drawing.Icon) Example: 'obj'�wi'Icon'value 'obj'�wi'Icon'

Page 99: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 99

�wi'icon' 1 Unsupported type or structure: Icon zNotifyIcon[145] zzError'Unsupported type or structure: Icon' n

But this is not a problem since you can always use ⎕cse directly when you can’t do something with

zObjects. So we can set the Icon property as follows:

�cse'ExecStmt' 'zni.Icon = SystemIcons.Exclamation;'

Other than that, the simple zznotifyicon function shows 2 ways to display the notification tooltip:

1. The first way is to set some properties and then call the ShowBalloonTip method with one

argument

2. The second is to call an overload of the ShowBalloonTip C# method which accepts 4 arguments.

However, the method used with ⎕wi is called ShowBalloonTip2: the reason is that C# supports

methods having the same name as long as they do not have the same arguments (these are called

“overloads”). The APL+Win ⎕wi system does not support overloads. So the zGenerate object

automatically renames the C# overloaded methods by appending a number. In other words, if the

C# NotifyIcon object had 4 ShowBalloonTip overloaded methods, they would appear in zNotifyIcon

as: ShowBalloonTip, ShowBalloonTip2, ShowBalloonTip3, ShowBalloonTip4

Page 100: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 100

Other Examples

The zObjects workspace includes a number of other .Net Framework controls that have been converted to

APL objects using zGenerate. These are:

• zDomainUpDown

• zGroupBox

• zMonthCalendar

• zPictureBox

• zNumericUpDown

• zSplitContainer

• zTabControl

You can use the zGenerate object to convert all the other .Net Framework controls to APL objects.

And you can then use these objects in your APL+Win Forms and applications!

Converting Third Party Controls

A whole bunch of companies have created significant libraries of controls to complement the .Net

Framework for Windows Forms as well as for WPF, for Silverlight and for ASP.Net.

The most famous of these libraries of Controls are:

• DevExpress (www.devexpress.com)

• Telerik (www.telerik.com)

• DevComponents (www.devcomponents.com)

• ComponentArt (www.componentart.com)

• SyncFusion (www.syncfusion.com)

• Infragistics (www.infragistics.com)

• Janus (www.janusys.com/controls)

I have bought and have personally been using DevExpress (extensively) but also Telerik and

DevComponents.

Among the 3, DevExpress stands out by the quality and beauty of its controls and the high quality of their

Web Site and support.

The zObjects contains a number of DevExpress controls which have been converted to APL objects using

the zObjects technology.

Page 101: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 101

Important Note

DevExpress is a commercial product.

The DevExpress License does not authorize a developer to create software that allows other developers

to use the DevExpress controls.

If you want to use the zObjects DevExpress controls examples, you must:

• Either download a free Trial of the DevExpress WinForms Library

• Or purchase the DevExpress WinForms Library ($899.99)

You can purchase DevExpress at: https://www.devexpress.com/Subscriptions/buy.xml

They have several products depending if you are using Windows Forms, WPF, Silverlight, ASP.Net and

you can also purchase combinations of those products (Universal Subscription or DXperience

Subscription).

Examples Shown Earlier

We have already shown a couple of examples using DevExpress controls in this paper:

• The zCalculatorDX example

• The zRichEditDXForm example

In these examples DX referred to DevExpress.

The zMapDXControl example

The DevExpress Library includes a powerful MapControl object allowing to display and manipulate maps.

I have added a zMapDXControl User Control to the zObjectsDX DLL and have added a few properties and

methods to this User Control.

It is out of the scope of this paper to describe in detail how to do that, but the basic steps I used were:

• Right click on the zObjectsDX C# project in Visual Studio

• Select Add

• Choose User Control…

• Then drag and drop a MapControl object from the Toolbox on to the User Control

• Set its Dock property to Fill

• Then write whatever C# properties, methods and events you want to add to the User Control

Once the C# zMapDXControl has been developed, let’s convert it to an APL zMapDXControl object:

'zgen'�wi'Generate' 'zMapDXControl' 'zMapDXControl' 'MapControl' 2 ''

Page 102: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 102

After a few seconds the zMapDXControl APL object is created and we can start using it. The following function

demonstrates how you can use the zMapDXControl:

� zzmapdxcontrol;c;s;z [1] z/'ff'�wi'*Create' 'zForm'('*caption' 'zMapDXControl Demo')('DemoShow'.5) [2] �wself/'ff'�wi'*.map.Create' 'zMapDXControl'('wherelc'h h '>' '>')('anchor'1 2 3 4)'ConnectToOpenStreetMap' [3] �wself/'ff.map' [4] [5] s/'' [6] s,/N"�wi'navpanelvisible'0" [7] s,/N"�wi'navpanelvisible'1" [8] s,/N"" [9] s,/N"�wi'showcoordinates'0" [10] s,/N"�wi'showcoordinates'1" [11] s,/N"" [12] s,/N"�wi'showmilesscale'0" [13] s,/N"�wi'showmilesscale'1" [14] s,/N"" [15] s,/N"�wi'showscrollbuttons'0" [16] s,/N"�wi'showscrollbuttons'1" [17] s,/N"" [18] s,/N"�wi'showzoomtrackbar'0" [19] s,/N"�wi'showzoomtrackbar'1" [20] s,/N"" [21] s,/N"�wi'GetCityLocation' 'FR,Paris'" [22] s,/N"�wi(N'centerpoint'),�wi'GetCityLocation' 'FR,Paris'" [23] s,/N"�wi'Zoom'8" [24] s,/N"" [25] s,/N"�wi'GetAllCities' 'US,San Francisco'" [26] s,/N"�wi'ShowCity' 'US,San Francisco'9" [27] s,/N"" [28] s,/N"�wi'ShowCity' 'US,Fort Lauderdale'12" [29] s,/N"�wi'ShowCity' 'US,Fort Lauderdale'14" [30] s,/N"" [31] s,/N"�wi'Zoom'1" [32] s,/N"�wi'centerpoint'0 0" [33] s,/N"c/(255 0 0)(192 0 0)(128 0 0)(64 0 0)(0 64 0)(0 128 0)(0 192 0)(0 255 0)(0 0 64)(0 0 128)" [34] s,/N"z/�wi'*.ColorizeMap' 'C:\Users\Public\Documents\DevExpress Demos 13.2\Components\Data\Countries.shp' 'GDP_MD_EST' (0 3000 10000 18000 28000 44000 82000 185000 1000000 2500000 15000000)c" [35] [36] �/cs �

Lines 5 to 35 just display APL instructions in the APL session, showing how to use some properties and

methods of the zMapDXControl object.

Let’s try it.

zzmapdxcontrol

Page 103: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 103

You can show or hide various elements of the User Interface. Try:

�wi'navpanelvisible'0 �wi'navpanelvisible'1 �wi'showcoordinates'0 �wi'showcoordinates'1 �wi'showmilesscale'0 �wi'showmilesscale'1 �wi'showscrollbuttons'0 �wi'showscrollbuttons'1 �wi'showzoomtrackbar'0 �wi'showzoomtrackbar'1

You can use some methods I have added to the zMapDXControl DLL such as GetCityLocation:

�wi'GetCityLocation' 'US,Fort Lauderdale' 26.1882 ¯80.1711

Knowing the latitude and longitude of a City, you can force the map to navigate to it and display it:

�wi(N'centerpoint'),�wi'GetCityLocation' ' US,Fort Lauderdale '

Page 104: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 104

This forces Fort Lauderdale to be at the center of the map.

We can then apply a zoom factor to reveal the city of Fort Lauderdale:

�wi'Zoom'12

Page 105: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 105

Or if it is not detailed enough:

�wi'Zoom'15

From there we can navigate in any direction with the GoNorth, GoEast, GoWest and GoSouth methods:

�wi'GoNorth' .01

Page 106: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 106

It is also possible to create thematic maps.

For example let’s display a map of the world countries:

�wi'centerpoint'0 0

�wi'Zoom'2

c/(255 0 0)(192 0 0)(128 0 0)(64 0 0)(0 64 0)(0 128 0)(0 192 0)(0 255 0)(0 0 64)(0

0 128)

z/�wi'.ColorizeMap' 'C:\Users\Public\Documents\DevExpress Demos

13.2\Components\Data\Countries.shp' 'GDP_MD_EST' (0 3000 10000 18000 28000 44000 82000

185000 1000000 2500000 15000000) c

This results in the following map being displayed:

Page 107: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 107

And since the zMapDXControl is a zObject, you can embed it in an APL+Win Form that has other

controls: also, just like all the other zObjects, the zMapDXControl supports the wherelc and anchor

properties.

Note that I have developed the additional methods (GetCityLocation, ShowCity, ColorizeMap, etc.) in

both the zMapDXControl object and in the C# zMapDXControl object. I did the APL version of them so

that you could see how to use ⎕cse to do the job.

When you want to add your own properties and methods to an object:

• First, be sure to place them at the bottom of your zObject, between the 2 lines marked as

Protected Code9

• You have the choice to add them in your C# User Control (the preferred way if you know C#) or

in your APL object (between the lines marked as Protected Code).

The zSpreadsheetDXControl example

The DevExpress library contains a control which is called SpreadsheetControl and is a spreadsheet highly

compatible with Excel.

Again I have developed a zSpreadsheetDXControl C# User Control which contains an instance of the

DevExpress SpreadsheetControl. I then just had to write a few methods in my C# User Control which

are cover methods for similar ones contained in the DevExpress SpreadsheetControl itself.

9 All methods, properties and events you develop and place in the Protected Code section will be preserved if you

regenerate your object with zGenerate

Page 108: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 108

Let’s convert the C# zSpreadsheetDXControl User Control into an APL+Win object:

'zgen'�wi'Generate' 'zSpreadsheetDXControl' 'zSpreadsheetDXControl' 'SpreadsheetControl' 2 ''

And now let’s develop a small APL application making use of this control to build a basic Invoice:

� a zexSpreadsheetDXControl b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;�io [1] %� a zexSpreadsheetDXControl b -- The zexSpreadsheetDXControl Object is a sample function showing how to use zSpreadsheetDXControl [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.83 [9] %� Copyright(c)2013-2014 Eric Lescasse [10] %� ELE29nov13 [11] [12] �io/1 [13] �cself/'zcsedx' [14] :if �monadic ? a/�wself ? :end [15] :if'Action'@Ewarg/b ? 0('?'=Cb/C�warg)ΡEEHelp ? :end [16] :if(�dr b)L326 807 ? :andif 6=Ρb ? b/'on',3cb ? :endif [17] 0(8G''Ρ�idloc'E',b)ΡEEInherit [18] :if'New'Pb ? a/(rn\raG'.')/a ? :endif [19] 0J'E',b [20] %�------------------------------------------------New [21] ENew: [22] %� Create a new instance of zexSpreadsheetDXControl [23] %� Example: [24] %� 'zt'�wi'*Create' 'zexSpreadsheetDXControl' [25] z/a�wi'*Create' 'zForm'('*caption' 'Sample Invoice using DevExpress Spreadsheet Control') [26] z/a�wi'*onAction'(L'zexSpreadsheetDXControl' 'zSpreadsheetDXControl' 'zForm' 'zObject',¨N'"Action"',�tcnl) [27] :if(c/a�wi'*name')Pd/a�wi'*self' ? z/'#'�wi'SetLinks'c d ? :endif [28] [29] % User Interface [30] z/a�wi'*.ss.Create' 'zSpreadsheetDXControl'('wherelc'h h '>' '>')('anchor'1 2 3 4) [31] z/a�wi'.ss.borderstyle'BorderStyle.FixedSingle [32] z/a�wi'*.bnOK.Create' 'zButton'('*caption' 'OK')('wherelc' '=' '>'h 120)('anchor'2 3) [33] z/a�wi'*.bnCancel.Create' 'zButton'('*caption' '&Cancel')('wherelc' '>' '=' '=' '=')('anchor'2 3) [34] z/a�wi'*.bnPopulate.Create' 'zButton'('*caption' '&Populate')('wherelc' '>' '=' '=' '=')('anchor'2 3) [35] z/a�wi'*.bnAddFormulae.Create' 'zButton'('*caption' '&Add Formulae')('wherelc' '>' '=' '=' '=')('anchor'2 3) [36] z/a�wi'*.bnClear.Create' 'zButton'('*caption' '&Clear')('wherelc' '>' '=' '=' '=')('anchor'2 3) [37] z/a�wi'*.bnSaveAs.Create' 'zButton'('*caption' '&Save As...')('wherelc' '>' '=' '=' '=')('anchor'2 3) [38] z/a�wi'*.ckBorder.Create' 'zCheck'('*caption' 'Border')('wherelc' '>' '=' '=' '=')('anchor'2 3)('*value'1) [39] z/a�wi'AutoSize' [40] [41] % Events

Page 109: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 109

[42] z/a�wi'.bnPopulate.AddHandler' 'onClick' 'zexSpreadsheetDXControl"bnPopulate_onClick"' [43] z/a�wi'.bnAddFormulae.AddHandler' 'onClick' 'zexSpreadsheetDXControl"bnAddFormulae_onClick"' [44] z/a�wi'.bnClear.AddHandler' 'onClick' 'zexSpreadsheetDXControl"bnClear_onClick"' [45] z/a�wi'.ckBorder.AddHandler' 'onClick' 'zexSpreadsheetDXControl"ckBorder_onClick"' [46] z/a�wi'.bnSaveAs.AddHandler' 'onClick' 'zexSpreadsheetDXControl"bnSaveAs_onClick"' [47] :return [48] %�------------------------------------------------class [49] Eclass: [50] �wres/'zexSpreadsheetDXControl' [51] :return [52] %�------------------------------------------------help [53] Ehelp: [54] %� 0 0Ρ'zt'�wi'*Create' 'zexSpreadsheetDXControl' [55] �wres/�wi'GetHelp' 'help' [56] :return [57] [58] %�------------------------------------------------bnAddFormulae_onClick [59] EbnAddFormulae_onClick: [60] z/�wi':ss.AddFormula'1'F10:F11' '=C10:C11*D10:D11*(1-E10:E11)' [61] z/�wi':ss.AddFormula'1'F13' '=SUM(F10:F11)' [62] :return [63] %�------------------------------------------------bnClear_onClick [64] EbnClear_onClick: [65] z/�wi':ss.ClearFormula'1 [66] z/�wi':ss.ClearSheet'1 [67] :return [68] %�------------------------------------------------bnPopulate_onClick [69] EbnPopulate_onClick: [70] % Create an invoice [71] z/�wi':ss.ClearFormula'1 [72] i/12 5ΡN'' [73] i[;1]/'BILL TO:' 'Alcorn Mickey' 'Mickeys World of Fun' '436 1st Ave.' 'Cleveland OH, 37288' 'Phone: (203)290-8902' '' 'Products' 'Chai' 'Chang' '' '' [74] i[;2]/(7ΡN''),'Quantity'3 6,2ΡN'' [75] i[;3]/(7ΡN''),'Price'100 120,2ΡN'' [76] i[;4]/(7ΡN''),'Discount'.1 .15'' 'Total:' [77] i[;5]/(7ΡN''),'Due' '=B9*C9*(1-D9)' '=B10*C10*(1-D10)' '' '=sum(e9:e10)' [78] z/�cse'ExecStmt' 'public DevExpress.Spreadsheet.Range rng;' [79] z/�wi':ss.Add'1(2 2)i [80] z/�wi':ss.BeginUpdate' [81] [82] z/�wi':ss.SetColWidths'1(Ι6)(2.5×20 200 100 100 100 200) [83] z/�wi':ss.BeginUpdateRange'1'B9' [84] z/�wi':ss.SetBottomBorderLineStyle'2 [85] z/�wi':ss.SetBottomBorderColor'(0 0 255) [86] z/�wi':ss.SetFontColor'(0 0 255) [87] z/�wi':ss.SetBackgroundColor'(255 212 224) [88] z/�wi':ss.SetFontSize'12 [89] z/�wi':ss.SetBold'1 [90] z/�wi':ss.EndUpdateRange'1'B9' [91] [92] z/�wi':ss.BeginUpdateRange'1'C9:F9' [93] z/�wi':ss.SetAlignment'3 [94] z/�wi':ss.SetBottomBorderLineStyle'2 [95] z/�wi':ss.SetBottomBorderColor'(0 0 255) [96] z/�wi':ss.SetFontColor'(0 0 255) [97] z/�wi':ss.SetFontSize'12

Page 110: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 110

[98] z/�wi':ss.SetBackgroundColor'(255 212 224) [99] z/�wi':ss.SetBold'1 [100] z/�wi':ss.EndUpdateRange'1'C9:F9' [101] [102] z/�wi':ss.BeginUpdateRange'1'E13:F13' [103] z/�wi':ss.SetFontSize'12 [104] z/�wi':ss.SetBold'1 [105] z/�wi':ss.EndUpdateRange'1'E13:F13' [106] z/�wi':ss.EndUpdate' [107] [108] :return [109] %�------------------------------------------------bnSaveAs_onClick [110] EbnSaveAs_onClick: [111] z/'zsfd'�wi'*Create' 'zSaveFileDialog' [112] z/'zsfd'�wi'filter' 'Excel files (*.xlsx)|*.xlsx' [113] z/'zsfd'�wi'ShowDialog' [114] :if [email protected] [115] f/'zsfd'�wi'filename' [116] z/�wi':ss.SaveDocument'f [117] :endif [118] :return [119] %�------------------------------------------------ckBorder_onClick [120] EckBorder_onClick: [121] z/�wi':ss.borderstyle'(�wi'*value') [122] :return [123] [124] %------------------------------------------------- [125] EEHelp: [126] �wres/�wi'GetHelp'(('?'=Cb)Xb) [127] :return [128] %------------------------------------------------- [129] EEInherit: [130] �wres/�wi'*' �

Note that this function is itself a zObject which inherits from zSpreadsheetDXControl.

Note lines 70 to 108 which use ⎕wi to call the various C# methods included in the

zSpreadsheetDXControl object.

Also note lines 111 to 117 which use our zSaveFileDialog (which is the C# SaveFileDialog) to save the

content of our spreadsheet to an .xlsx file and see how this is extremely simple and clean code.

Finally our application User Interface combine the zSpreadsheetDXControl which is a DevExpress C#

control and zButton and a zCheck object which are APL objects.

Let’s run this function:

�wself/'ff'�wi'*Create' 'zexSpreadsheetDXControl'('DemoWait'.5)

Page 111: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 111

See how all controls get automatically resized or repositioned when you resize the form.

Now click the Populate button:

Cells F10, F11 and F13 show the Formulae that will be installed in these cells if you click the Add

Formulae button. Just do it.

Page 112: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 112

Values in cells F10, F11 and F13 now are the results of the formulae and you can change Quantities or

Prices or Discounts and see the Due amounts getting automatically recalculated.

Click the Save As… button to save this Spreadsheet as an Excel .xlsx Spreadsheet:

Page 113: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 113

Now open Excel and load the saved spreadsheet into Excel:

Page 114: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 114

It is identical to what had been created in our APL application.

It is really great to be able to freely mix any C# control (whether .Net Framework ones or Third Party

ones) with APL controls and use them on APL forms.

Converting Non Visual Controls: the zRegex example

Finally, it is also possible to use the zGenerate object to convert non visual C# objects.

Let’s take the C# Regex object for example.

In this case, I again created a zRegex C# class in the zObjects DLL.

I could alternatively have written Converters for some of the types used by Regex, like the Matches

type.

Let’s take the example of the Regex.Matches type.

When you use Regular Expressions in C# to search for some text matching some conditions in a given

text, the result you get is a MatchCollection C# object. As its name indicates a MatchCollection object is

a collection of Match objects. Each Match object is a C# object representing one “match” found in the

searched text; each Match object includes quite a number of properties among which:

1. Index (the 0-origin Index of the match in the searched text)

2. Length (the length of the match)

3. Success (a Boolean 0 or 1 indicating match success or failure)

4. Value (the matched text)

There are quite a number of other properties, but let’s say we are interested in only those ones above.

We can very easily write a Matches method in your C# DLL that will convert the MatchCollection result

of the Regex.Matches method into a matrix of “object” with one row per match and 4 columns

(Success, Index, Length and Value).

To show how simple this is, let’s show the Matches C# method that does this: I guess that, even if you

do not know C#, you will understand what it does!

public object[,] Matches(string input, string pattern) { MatchCollection matches = Regex.Matches(input, pattern); object[,] result = new object[matches.Count, 4]; for (int i = 0; i < matches.Count; i++) { result[i, 0] = matches[i].Success; result[i, 1] = matches[i].Index; result[i, 2] = matches[i].Length; result[i, 3] = matches[i].Value; } return result; }

Our method has 2 arguments:

- input which is a string and is the text in which we want to search

Page 115: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 115

- pattern which is the regular expression which we want to use to find the searched text(s)

Note that:

• The first line calls the C# Regex.Matches static method which returns a MatchCollection object

called matches.

• The second line initializes a matrix of object variable called result with as many lines as elements

in the MatchCollection (matches.Count) and 4 columns

• The for loop just fills the result matrix with the various properties (Success, Index, Length and

Value) extracted from each Match object of the matches MatchCollection object.

• Finally we return the result variable

Basically, any APL developer not knowing C# should be able to write such a method after a week of

learning C#.

I have added a few more similar methods to the C# zRegex object (see Appendix 2).

Let’s now convert our zRegex C# object into a zRegex APL object:

'zgen'�wi'Generate' 'zRegex' 'zRegex' 'Regex' 0'ms'

And let’s start using our zRegex object right away, through an example.

Here is the text in which we want to make searches:

The brown fox received a fax that helped him fix a flexible problem.

- Fx! fx! shouted the Sphinx to make him run away.

I admit this text does not make any sense, but is ok for our example.

Let’s try to find all the words starting with f and ending with x in the above text which I have placed in an

APL variable called input.

'zreg'�wi'*Create' 'zRegex'

zreg 'zreg'�wi'Matches'input 'f.x'

1 10 3 fox 1 25 3 fax 1 45 3 fix

The f.x Regular Expression finds any string in the text that contains an f followed by exactly one

character (a . matches any character) followed by an x. We see that we have 3 hits, starting at character

11, 26 and 46 in origin 1.

That seems to work fine, but our Regular Expression would not have found a word starting with f and

having more than one character between f and x.

Page 116: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 116

Let’s try:

'zreg'�wi'Matches'input 'f.*x'

1 10 87 fox received a fax that helped him fix a flexible problem. - Fx! fx! shouted the Sphinx

The * character means: 0 or more, so .* means 0 or more characters between the f and the x. The way

Regular Expressions work by default is to match everything between the first occurrence of an f and the

last occurrence of an x.

To solve this problem we can add a ? after the * (the ? is called the Lazy Quantifier and means: match as

small a string as possible):

'zreg'�wi'Matches'input 'f.*?x'

1 10 3 fox 1 25 3 fax 1 45 3 fix 1 51 4 flex 1 75 2 fx

That’s better, but we found flex which is not a word ending with x!

To be sure to only match complete words, we must add the \b word boundaries to our Regular

Expression:

'zreg'�wi'Matches'input '\bf.*?x\b'

1 10 3 fox 1 25 3 fax 1 45 3 fix 1 51 22 flexible problem. - Fx 1 75 2 fx

Oops again! We find too many characters for the word flexible. We find too many characters because

after the x in flexible there is no other f before the x in Fx, so by default Regular Expressions finds the

furthest possible x that follows the f in flexible and which is before another f in the phrase. Let’s use the

Lazy Auantifier again:

'zreg'�wi'Matches'input '\bf.*?x?\b'

1 10 3 fox 1 25 3 fax 1 45 3 fix 1 51 8 flexible 1 75 2 fx

This time we got what we wanted because x? matches the x which is closest to the f that precedes it.

Regular Expressions are extremely powerful and sure require much less effort (when you start to master

them) than writing the APL code that would do the same work.

You can also use Regular Expressions to replace matches.

Page 117: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 117

Example:

'zreg'�wi'Replace'input '\bf.*?x?\b' 'XXXXX'

The brown XXXXX received a XXXXX that helped him XXXXX a XXXXX problem. - Fx! XXXXX! shouted the Sphinx to make him run away.

As we have seen above, finding the correct regular expression for the work you’ve got to do is often a

trial and failure approach, so to make this simpler, I have included a TestRegex method in the zRegex C#

object.

This method accepts an argument which is the input text and you can try various Egular Expressions by

typing them in the top TextBox.

'zreg'�wi'TestRegex'input

As you type characters in the top TextBox, the matches are highlighted in the bottom RichTextBox.

This way you can very easily try a lot of things to fine tune your Regular Expression.

The goal is not to teach Regular Expressions here but to see that we could create a method (TestRegex),

in a DLL, that dynamically builds a C# form and handle its events.

Page 118: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 118

For those who ask themselves how you can dynamically create a User Interface in C# (this is just as easy

as using ⎕wi to do the same thing in APL), refer to Appendix 2.

Conclusion

In this paper we have seen how it is possible to now directly use the .Net Framework as well as Third

Party Controls in APL+Win thanks to the new APL+Win ⎕cse System Function.

Moreover, we have seen how it is possible to create powerful Objects in APL+Win, allowing us to

develop applications in an Object Oriented manner.

The zObjects workspace, delivered to all Conference Attendees, contains a number of such objects.

It also contains a Code Generator that can convert any C# Object into an APL+Win Object that can be

used with ⎕wi instead of ⎕cse: this dramatically simplifies the use of C# objects in APL+Win

applications.

Page 119: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 119

Appendix 1: Sample C# .Net Framework Object converted to an APL+Win zObject

The APL Code below displays the complete code generated by the zGenerate object when converting the

C# MaskedTextBox object. 'zgen'�wi'Generate' 'zMaskedTextBox' '' 'MaskedTextBox' 0'ms'

Here is the code of the generated object. Note that some properties or methods have been

automatically commented by the zGenerate Code Generator as they are general properties or methods

of similar objects (TextBox) but do not apply to this specific object (this is sometimes the case in the

.Net Framework). As you can see C# objects have lots of properties, methods and events!

� a zMaskedTextBox b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y;z;Ewarg;�io [1] %� r/a zMaskedTextBox b -- The zMaskedTextBox Object is the zObjects implementation of a .Net Framework object [2] %� a /0 object name (may be omitted if �wself is set) [3] %� b /0 'property' [4] %� or 'property'value [5] %� or 'Method' [6] %� or 'Method'argument1 ... argumentN [7] %� Requires: (F) zObject [8] %� zObjects v1.0 [9] %� Copyright(c)2014 Eric Lescasse [10] %� ELE19feb14 [11] [12] �io/1 [13] �cself/'zcsedx' [14] :if �monadic ? a/�wself ? :end [15] :if'Action'@Ewarg/b ? 0('?'=Cb/C�warg)ΡEEHelp ? :end [16] :if(�dr b)L326 807 ? :andif 6=Ρb ? b/'on',3cb ? :endif [17] 0(8G''Ρ�idloc'E',b)ΡEEInherit [18] :if'New'Pb ? a/(rn\raG'.')/a ? :endif [19] 0J'E',b [20] %�------------------------------------------------New [21] ENew: [22] %� Create a new instance of zMaskedTextBox [23] %� Example: [24] %� 'ff'�wi'*Create' 'zMaskedTextBox' [25] z/a�wi'*Create' 'Menu' [26] z/a�wi'*onAction'(L'zMaskedTextBox' 'zConverters' 'zObject',¨N'"Action"',�tcnl) [27] c/rn\raG'.' [28] d/¯1X(pc)/a % parent name [29] e/c/a % top level name for C# object [30] :try * [31] z/zzCSE'ExecStmt'(e,'.Dispose();') [32] :catchall [33] :endtry [34] z/zzCSE'ExecStmt'('MaskedTextBox ',e,' = new MaskedTextBox();') [35] :try * [36] z/zzCSE'ExecStmt'(e,'.Name = "',e,'";') [37] :catchall [38] :endtry [39] % z/�wi'AddHandler' 'AcceptsTabChanged' [40] % z/�wi'AddHandler' 'AutoSizeChanged' [41] % z/�wi'AddHandler' 'BackColorChanged' [42] % z/�wi'AddHandler' 'BackgroundImageChanged' [43] % z/�wi'AddHandler' 'BackgroundImageLayoutChanged' [44] % z/�wi'AddHandler' 'BindingContextChanged'

Page 120: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 120

[45] % z/�wi'AddHandler' 'BorderStyleChanged' [46] % z/�wi'AddHandler' 'CausesValidationChanged' [47] % z/�wi'AddHandler' 'ChangeUICues' [48] % z/�wi'AddHandler' 'Click' [49] % z/�wi'AddHandler' 'ClientSizeChanged' [50] % z/�wi'AddHandler' 'ContextMenuChanged' [51] % z/�wi'AddHandler' 'ContextMenuStripChanged' [52] % z/�wi'AddHandler' 'ControlAdded' [53] % z/�wi'AddHandler' 'ControlRemoved' [54] % z/�wi'AddHandler' 'CursorChanged' [55] % z/�wi'AddHandler' 'Disposed' [56] % z/�wi'AddHandler' 'DockChanged' [57] % z/�wi'AddHandler' 'DoubleClick' [58] % z/�wi'AddHandler' 'DragDrop' [59] % z/�wi'AddHandler' 'DragEnter' [60] % z/�wi'AddHandler' 'DragLeave' [61] % z/�wi'AddHandler' 'DragOver' [62] % z/�wi'AddHandler' 'EnabledChanged' [63] % z/�wi'AddHandler' 'Enter' [64] % z/�wi'AddHandler' 'FontChanged' [65] % z/�wi'AddHandler' 'ForeColorChanged' [66] % z/�wi'AddHandler' 'GiveFeedback' [67] % z/�wi'AddHandler' 'GotFocus' [68] % z/�wi'AddHandler' 'HandleCreated' [69] % z/�wi'AddHandler' 'HandleDestroyed' [70] % z/�wi'AddHandler' 'HelpRequested' [71] % z/�wi'AddHandler' 'HideSelectionChanged' [72] % z/�wi'AddHandler' 'ImeModeChanged' [73] % z/�wi'AddHandler' 'Invalidated' [74] % z/�wi'AddHandler' 'IsOverwriteModeChanged' [75] % z/�wi'AddHandler' 'KeyDown' [76] % z/�wi'AddHandler' 'KeyPress' [77] % z/�wi'AddHandler' 'KeyUp' [78] % z/�wi'AddHandler' 'Layout' [79] % z/�wi'AddHandler' 'Leave' [80] % z/�wi'AddHandler' 'LocationChanged' [81] % z/�wi'AddHandler' 'LostFocus' [82] % z/�wi'AddHandler' 'MarginChanged' [83] % z/�wi'AddHandler' 'MaskChanged' [84] % z/�wi'AddHandler' 'MaskInputRejected' [85] % z/�wi'AddHandler' 'ModifiedChanged' [86] % z/�wi'AddHandler' 'MouseCaptureChanged' [87] % z/�wi'AddHandler' 'MouseClick' [88] % z/�wi'AddHandler' 'MouseDoubleClick' [89] % z/�wi'AddHandler' 'MouseDown' [90] % z/�wi'AddHandler' 'MouseEnter' [91] % z/�wi'AddHandler' 'MouseHover' [92] % z/�wi'AddHandler' 'MouseLeave' [93] % z/�wi'AddHandler' 'MouseMove' [94] % z/�wi'AddHandler' 'MouseUp' [95] % z/�wi'AddHandler' 'MouseWheel' [96] % z/�wi'AddHandler' 'Move' [97] % z/�wi'AddHandler' 'MultilineChanged' [98] % z/�wi'AddHandler' 'PaddingChanged' [99] % z/�wi'AddHandler' 'Paint' [100] % z/�wi'AddHandler' 'ParentChanged' [101] % z/�wi'AddHandler' 'PreviewKeyDown' [102] % z/�wi'AddHandler' 'QueryAccessibilityHelp' [103] % z/�wi'AddHandler' 'QueryContinueDrag' [104] % z/�wi'AddHandler' 'ReadOnlyChanged' [105] % z/�wi'AddHandler' 'RegionChanged' [106] % z/�wi'AddHandler' 'Resize'

Page 121: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 121

[107] % z/�wi'AddHandler' 'RightToLeftChanged' [108] % z/�wi'AddHandler' 'SizeChanged' [109] % z/�wi'AddHandler' 'StyleChanged' [110] % z/�wi'AddHandler' 'SystemColorsChanged' [111] % z/�wi'AddHandler' 'TabIndexChanged' [112] % z/�wi'AddHandler' 'TabStopChanged' [113] % z/�wi'AddHandler' 'TextAlignChanged' [114] % z/�wi'AddHandler' 'TextChanged' [115] % z/�wi'AddHandler' 'TypeValidationCompleted' [116] % z/�wi'AddHandler' 'Validated' [117] % z/�wi'AddHandler' 'Validating' [118] % z/�wi'AddHandler' 'VisibleChanged' [119] :return [120] %�------------------------------------------------class [121] Eclass: [122] �wres/'zMaskedTextBox' [123] :return [124] %�------------------------------------------------help [125] Ehelp: [126] %� 0 0Ρ'ff'�wi'*Create' 'zMaskedTextBox' [127] �wres/�wi'GetHelp' 'help' [128] :return [129] [130] %�================================================Generated Code [131] %%�------------------------------------------------acceptstab [132] %Eacceptstab: [133] % %� Gets or sets a value determining how TAB keys are handled for multiline configurations. This property is not supported by System.Windows.Forms.MaskedTextBox [134] % %� Syntax: {value/}'obj'�wi'AcceptsTab'{value} [135] % %� value: (System.Boolean) [136] % %� Example: [137] % %� 'obj'�wi'AcceptsTab'value [138] % %� 'obj'�wi'AcceptsTab' [139] % :if 1=Ρ�warg [140] % �wres/�wi'Getbool'(a,'.AcceptsTab') [141] % :else [142] % z/�wi'Setbool'(a,'.AcceptsTab')(''zzWarg�warg) [143] % :endif [144] % :return [145] %�------------------------------------------------allowpromptasinput [146] Eallowpromptasinput: [147] %� Gets or sets a value indicating whether System.Windows.Forms.MaskedTextBox.PromptChar can be entered as valid data by the user [148] %� Syntax: {value/}'obj'�wi'AllowPromptAsInput'{value} [149] %� value: (System.Boolean) [150] %� Example: [151] %� 'obj'�wi'AllowPromptAsInput'value [152] %� 'obj'�wi'AllowPromptAsInput' [153] :if 1=Ρ�warg [154] �wres/�wi'Getbool'(a,'.AllowPromptAsInput') [155] :else [156] z/�wi'Setbool'(a,'.AllowPromptAsInput')(''zzWarg�warg) [157] :endif [158] :return [159] %�------------------------------------------------asciionly [160] Easciionly: [161] %� Gets or sets a value indicating whether the System.Windows.Forms.MaskedTextBox control accepts characters outside of the ASCII character set [162] %� Syntax: {value/}'obj'�wi'AsciiOnly'{value} [163] %� value: (System.Boolean) [164] %� Example:

Page 122: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 122

[165] %� 'obj'�wi'AsciiOnly'value [166] %� 'obj'�wi'AsciiOnly' [167] :if 1=Ρ�warg [168] �wres/�wi'Getbool'(a,'.AsciiOnly') [169] :else [170] z/�wi'Setbool'(a,'.AsciiOnly')(''zzWarg�warg) [171] :endif [172] :return [173] %�------------------------------------------------autosize [174] Eautosize: [175] %� Gets or sets a value indicating whether the height of the control automatically adjusts when the font assigned to the control is changed [176] %� Syntax: {value/}'obj'�wi'AutoSize'{value} [177] %� value: (System.Boolean) [178] %� Example: [179] %� 'obj'�wi'AutoSize'value [180] %� 'obj'�wi'AutoSize' [181] :if 1=Ρ�warg [182] �wres/�wi'Getbool'(a,'.AutoSize') [183] :else [184] z/�wi'Setbool'(a,'.AutoSize')(''zzWarg�warg) [185] :endif [186] :return [187] %�------------------------------------------------backcolor [188] Ebackcolor: [189] %� Gets or sets the background color of the control [190] %� Syntax: {value/}'obj'�wi'BackColor'{value} [191] %� value: (System.Drawing.Color) [192] %� Example: [193] %� 'obj'�wi'BackColor'value [194] %� 'obj'�wi'BackColor' [195] :if 1=Ρ�warg [196] �wres/�wi'GetColor'(a,'.BackColor') [197] :else [198] z/�wi'SetColor'(a,'.BackColor')(''zzWarg�warg) [199] :endif [200] :return [201] %�------------------------------------------------backgroundimage [202] Ebackgroundimage: [203] %� This property is not relevant for this class [204] %� Syntax: {value/}'obj'�wi'BackgroundImage'{value} [205] %� value: (System.Drawing.Image) [206] %� Example: [207] %� 'obj'�wi'BackgroundImage'value [208] %� 'obj'�wi'BackgroundImage' [209] zzError'Unsupported type or structure: Image' [210] :return [211] %�------------------------------------------------backgroundimagelayout [212] Ebackgroundimagelayout: [213] %� This property is not relevant for this class [214] %� Syntax: {value/}'obj'�wi'BackgroundImageLayout'{value} [215] %� value: (System.Windows.Forms.ImageLayout) [216] %� 0= ImageLayout.None [217] %� 1= ImageLayout.Tile [218] %� 2= ImageLayout.Center [219] %� 3= ImageLayout.Stretch [220] %� 4= ImageLayout.Zoom [221] %� Example: [222] %� 'obj'�wi'BackgroundImageLayout'value [223] %� 'obj'�wi'BackgroundImageLayout' [224] :if 1=Ρ�warg [225] �wres/�wi'Getint'(a,'.BackgroundImageLayout')

Page 123: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 123

[226] :else [227] z/�wi'Setint'(a,'.BackgroundImageLayout')(''zzWarg�warg) [228] :endif [229] :return [230] %�------------------------------------------------beeponerror [231] Ebeeponerror: [232] %� Gets or sets a value indicating whether the masked text box control raises the system beep for each user key stroke that it rejects [233] %� Syntax: {value/}'obj'�wi'BeepOnError'{value} [234] %� value: (System.Boolean) [235] %� Example: [236] %� 'obj'�wi'BeepOnError'value [237] %� 'obj'�wi'BeepOnError' [238] :if 1=Ρ�warg [239] �wres/�wi'Getbool'(a,'.BeepOnError') [240] :else [241] z/�wi'Setbool'(a,'.BeepOnError')(''zzWarg�warg) [242] :endif [243] :return [244] %�------------------------------------------------borderstyle [245] Eborderstyle: [246] %� Gets or sets the border type of the text box control [247] %� Syntax: {value/}'obj'�wi'BorderStyle'{value} [248] %� value: (System.Windows.Forms.BorderStyle) [249] %� 0= BorderStyle.None [250] %� 1= BorderStyle.FixedSingle [251] %� 2= BorderStyle.Fixed3D [252] %� Example: [253] %� 'obj'�wi'BorderStyle'value [254] %� 'obj'�wi'BorderStyle' [255] :if 1=Ρ�warg [256] �wres/�wi'Getint'(a,'.BorderStyle') [257] :else [258] z/�wi'Setint'(a,'.BorderStyle')(''zzWarg�warg) [259] :endif [260] :return [261] %%�------------------------------------------------canundo [262] %Ecanundo: [263] % %� Gets a value indicating whether the user can undo the previous operation. This property is not supported by System.Windows.Forms.MaskedTextBox [264] % %� Syntax: value/'obj'�wi'CanUndo' [265] % %� value: (System.Boolean) [266] % %� Example: [267] % %� 'obj'�wi'CanUndo' [268] % :if 1=Ρ�warg [269] % �wres/�wi'Getbool'(a,'.CanUndo') [270] % :else [271] % zzError'Property <canundo> is read-only!' [272] % :endif [273] % :return [274] %�------------------------------------------------container [275] Econtainer: [276] %� (missing XML documentation) [277] %� Syntax: value/'obj'�wi'Container' [278] %� value: (System.ComponentModel.IContainer) [279] %� Example: [280] %� 'obj'�wi'Container' [281] zzError'Unsupported type or structure: IContainer' [282] :return [283] %�------------------------------------------------culture [284] Eculture: [285] %� Gets or sets the culture information associated with the masked text box

Page 124: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 124

[286] %� Syntax: {value/}'obj'�wi'Culture'{value} [287] %� value: (System.Globalization.CultureInfo) [288] %� Example: [289] %� 'obj'�wi'Culture'value [290] %� 'obj'�wi'Culture' [291] zzError'Unsupported type or structure: CultureInfo' [292] :return [293] %�------------------------------------------------cutcopymaskformat [294] Ecutcopymaskformat: [295] %� Gets or sets a value that determines whether literals and prompt characters are copied to the clipboard [296] %� Syntax: {value/}'obj'�wi'CutCopyMaskFormat'{value} [297] %� value: (System.Windows.Forms.MaskFormat) [298] %� 0= MaskFormat.ExcludePromptAndLiterals [299] %� 1= MaskFormat.IncludePrompt [300] %� 2= MaskFormat.IncludeLiterals [301] %� 3= MaskFormat.IncludePromptAndLiterals [302] %� Example: [303] %� 'obj'�wi'CutCopyMaskFormat'value [304] %� 'obj'�wi'CutCopyMaskFormat' [305] :if 1=Ρ�warg [306] �wres/�wi'Getint'(a,'.CutCopyMaskFormat') [307] :else [308] z/�wi'Setint'(a,'.CutCopyMaskFormat')(''zzWarg�warg) [309] :endif [310] :return [311] %�------------------------------------------------forecolor [312] Eforecolor: [313] %� Gets or sets the foreground color of the control [314] %� Syntax: {value/}'obj'�wi'ForeColor'{value} [315] %� value: (System.Drawing.Color) [316] %� Example: [317] %� 'obj'�wi'ForeColor'value [318] %� 'obj'�wi'ForeColor' [319] :if 1=Ρ�warg [320] �wres/�wi'GetColor'(a,'.ForeColor') [321] :else [322] z/�wi'SetColor'(a,'.ForeColor')(''zzWarg�warg) [323] :endif [324] :return [325] %�------------------------------------------------formatprovider [326] Eformatprovider: [327] %� Gets or sets the System.IFormatProvider to use when performing type validation [328] %� Syntax: {value/}'obj'�wi'FormatProvider'{value} [329] %� value: (System.IFormatProvider) [330] %� Example: [331] %� 'obj'�wi'FormatProvider'value [332] %� 'obj'�wi'FormatProvider' [333] zzError'Unsupported type or structure: IFormatProvider' [334] :return [335] %�------------------------------------------------hidepromptonleave [336] Ehidepromptonleave: [337] %� Gets or sets a value indicating whether the prompt characters in the input mask are hidden when the masked text box loses focus [338] %� Syntax: {value/}'obj'�wi'HidePromptOnLeave'{value} [339] %� value: (System.Boolean) [340] %� Example: [341] %� 'obj'�wi'HidePromptOnLeave'value [342] %� 'obj'�wi'HidePromptOnLeave' [343] :if 1=Ρ�warg [344] �wres/�wi'Getbool'(a,'.HidePromptOnLeave')

Page 125: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 125

[345] :else [346] z/�wi'Setbool'(a,'.HidePromptOnLeave')(''zzWarg�warg) [347] :endif [348] :return [349] %�------------------------------------------------hideselection [350] Ehideselection: [351] %� Gets or sets a value indicating whether the selected text in the text box control remains highlighted when the control loses focus [352] %� Syntax: {value/}'obj'�wi'HideSelection'{value} [353] %� value: (System.Boolean) [354] %� Example: [355] %� 'obj'�wi'HideSelection'value [356] %� 'obj'�wi'HideSelection' [357] :if 1=Ρ�warg [358] �wres/�wi'Getbool'(a,'.HideSelection') [359] :else [360] z/�wi'Setbool'(a,'.HideSelection')(''zzWarg�warg) [361] :endif [362] :return [363] %�------------------------------------------------insertkeymode [364] Einsertkeymode: [365] %� Gets or sets the text insertion mode of the masked text box control [366] %� Syntax: {value/}'obj'�wi'InsertKeyMode'{value} [367] %� value: (System.Windows.Forms.InsertKeyMode) [368] %� 0= InsertKeyMode.Default [369] %� 1= InsertKeyMode.Insert [370] %� 2= InsertKeyMode.Overwrite [371] %� Example: [372] %� 'obj'�wi'InsertKeyMode'value [373] %� 'obj'�wi'InsertKeyMode' [374] :if 1=Ρ�warg [375] �wres/�wi'Getint'(a,'.InsertKeyMode') [376] :else [377] z/�wi'Setint'(a,'.InsertKeyMode')(''zzWarg�warg) [378] :endif [379] :return [380] %�------------------------------------------------isoverwritemode [381] Eisoverwritemode: [382] %� Gets a value that specifies whether new user input overwrites existing input [383] %� Syntax: value/'obj'�wi'IsOverwriteMode' [384] %� value: (System.Boolean) [385] %� Example: [386] %� 'obj'�wi'IsOverwriteMode' [387] :if 1=Ρ�warg [388] �wres/�wi'Getbool'(a,'.IsOverwriteMode') [389] :else [390] zzError'Property <isoverwritemode> is read-only!' [391] :endif [392] :return [393] %%�------------------------------------------------lines [394] %Elines: [395] % %� Gets or sets the lines of text in multiline configurations. This property is not supported by System.Windows.Forms.MaskedTextBox [396] % %� Syntax: {value/}'obj'�wi'Lines'{value} [397] % %� value: (System.String[]) [398] % %� Example: [399] % %� 'obj'�wi'Lines'value [400] % %� 'obj'�wi'Lines' [401] % :if 1=Ρ�warg [402] % �wres/�wi'Getstring'(a,'.Lines') [403] % :else

Page 126: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 126

[404] % z/�wi'Setstring'(a,'.Lines[]')('[]'zzWarg�warg) [405] % :endif [406] % :return [407] %�------------------------------------------------mask [408] Emask: [409] %� Gets or sets the input mask to use at run time [410] %� Syntax: {value/}'obj'�wi'Mask'{value} [411] %� value: (System.String) [412] %� Example: [413] %� 'obj'�wi'Mask'value [414] %� 'obj'�wi'Mask' [415] :if 1=Ρ�warg [416] �wres/�wi'Getstring'(a,'.Mask') [417] :else [418] z/�wi'Setstring'(a,'.Mask')(''zzWarg�warg) [419] :endif [420] :return [421] %�------------------------------------------------maskcompleted [422] Emaskcompleted: [423] %� Gets a value indicating whether all required inputs have been entered into the input mask [424] %� Syntax: value/'obj'�wi'MaskCompleted' [425] %� value: (System.Boolean) [426] %� Example: [427] %� 'obj'�wi'MaskCompleted' [428] :if 1=Ρ�warg [429] �wres/�wi'Getbool'(a,'.MaskCompleted') [430] :else [431] zzError'Property <maskcompleted> is read-only!' [432] :endif [433] :return [434] %�------------------------------------------------maskfull [435] Emaskfull: [436] %� Gets a value indicating whether all required and optional inputs have been entered into the input mask [437] %� Syntax: value/'obj'�wi'MaskFull' [438] %� value: (System.Boolean) [439] %� Example: [440] %� 'obj'�wi'MaskFull' [441] :if 1=Ρ�warg [442] �wres/�wi'Getbool'(a,'.MaskFull') [443] :else [444] zzError'Property <maskfull> is read-only!' [445] :endif [446] :return [447] %�------------------------------------------------maskedtextprovider [448] Emaskedtextprovider: [449] %� Gets a clone of the mask provider associated with this instance of the masked text box control [450] %� Syntax: value/'obj'�wi'MaskedTextProvider' [451] %� value: (System.ComponentModel.MaskedTextProvider) [452] %� Example: [453] %� 'obj'�wi'MaskedTextProvider' [454] zzError'Unsupported type or structure: MaskedTextProvider' [455] :return [456] %%�------------------------------------------------maxlength [457] %Emaxlength: [458] % %� Gets or sets the maximum number of characters the user can type or paste into the text box control. This property is not supported by System.Windows.Forms.MaskedTextBox [459] % %� Syntax: {value/}'obj'�wi'MaxLength'{value} [460] % %� value: (System.Int32)

Page 127: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 127

[461] % %� Example: [462] % %� 'obj'�wi'MaxLength'value [463] % %� 'obj'�wi'MaxLength' [464] % :if 1=Ρ�warg [465] % �wres/�wi'Getint'(a,'.MaxLength') [466] % :else [467] % z/�wi'Setint'(a,'.MaxLength')(''zzWarg�warg) [468] % :endif [469] % :return [470] %�------------------------------------------------modified [471] Emodified: [472] %� Gets or sets a value that indicates that the text box control has been modified by the user since the control was created or its contents were last set [473] %� Syntax: {value/}'obj'�wi'Modified'{value} [474] %� value: (System.Boolean) [475] %� Example: [476] %� 'obj'�wi'Modified'value [477] %� 'obj'�wi'Modified' [478] :if 1=Ρ�warg [479] �wres/�wi'Getbool'(a,'.Modified') [480] :else [481] z/�wi'Setbool'(a,'.Modified')(''zzWarg�warg) [482] :endif [483] :return [484] %�------------------------------------------------multiline [485] Emultiline: [486] %� Gets or sets a value indicating whether this is a multiline text box control. This property is not fully supported by System.Windows.Forms.MaskedTextBox [487] %� Syntax: {value/}'obj'�wi'Multiline'{value} [488] %� value: (System.Boolean) [489] %� Example: [490] %� 'obj'�wi'Multiline'value [491] %� 'obj'�wi'Multiline' [492] :if 1=Ρ�warg [493] �wres/�wi'Getbool'(a,'.Multiline') [494] :else [495] z/�wi'Setbool'(a,'.Multiline')(''zzWarg�warg) [496] :endif [497] :return [498] %�------------------------------------------------padding [499] Epadding: [500] %� This property is not relevant for this class [501] %� Syntax: {value/}'obj'�wi'Padding'{value} [502] %� value: (System.Windows.Forms.Padding) [503] %� Example: [504] %� 'obj'�wi'Padding'value [505] %� 'obj'�wi'Padding' [506] :if 1=Ρ�warg [507] �wres/�wi'GetPadding'(a,'.Padding') [508] :else [509] z/�wi'SetPadding'(a,'.Padding')(''zzWarg�warg) [510] :endif [511] :return [512] %�------------------------------------------------passwordchar [513] Epasswordchar: [514] %� Gets or sets the character to be displayed in substitute for user input [515] %� Syntax: {value/}'obj'�wi'PasswordChar'{value} [516] %� value: (System.Char) [517] %� Example: [518] %� 'obj'�wi'PasswordChar'value [519] %� 'obj'�wi'PasswordChar' [520] :if 1=Ρ�warg

Page 128: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 128

[521] �wres/�wi'Getchar'(a,'.PasswordChar') [522] :else [523] z/�wi'Setchar'(a,'.PasswordChar')(''zzWarg�warg) [524] :endif [525] :return [526] %�------------------------------------------------preferredheight [527] Epreferredheight: [528] %� Gets the preferred height for a text box [529] %� Syntax: value/'obj'�wi'PreferredHeight' [530] %� value: (System.Int32) [531] %� Example: [532] %� 'obj'�wi'PreferredHeight' [533] :if 1=Ρ�warg [534] �wres/�wi'Getint'(a,'.PreferredHeight') [535] :else [536] zzError'Property <preferredheight> is read-only!' [537] :endif [538] :return [539] %�------------------------------------------------promptchar [540] Epromptchar: [541] %� Gets or sets the character used to represent the absence of user input in System.Windows.Forms.MaskedTextBox [542] %� Syntax: {value/}'obj'�wi'PromptChar'{value} [543] %� value: (System.Char) [544] %� Example: [545] %� 'obj'�wi'PromptChar'value [546] %� 'obj'�wi'PromptChar' [547] :if 1=Ρ�warg [548] �wres/�wi'Getchar'(a,'.PromptChar') [549] :else [550] z/�wi'Setchar'(a,'.PromptChar')(''zzWarg�warg) [551] :endif [552] :return [553] %�------------------------------------------------readonly [554] Ereadonly: [555] %� Gets or sets a value indicating whether text in the text box is read-only [556] %� Syntax: {value/}'obj'�wi'ReadOnly'{value} [557] %� value: (System.Boolean) [558] %� Example: [559] %� 'obj'�wi'ReadOnly'value [560] %� 'obj'�wi'ReadOnly' [561] :if 1=Ρ�warg [562] �wres/�wi'Getbool'(a,'.ReadOnly') [563] :else [564] z/�wi'Setbool'(a,'.ReadOnly')(''zzWarg�warg) [565] :endif [566] :return [567] %�------------------------------------------------rejectinputonfirstfailure [568] Erejectinputonfirstfailure: [569] %� Gets or sets a value indicating whether the parsing of user input should stop after the first invalid character is reached [570] %� Syntax: {value/}'obj'�wi'RejectInputOnFirstFailure'{value} [571] %� value: (System.Boolean) [572] %� Example: [573] %� 'obj'�wi'RejectInputOnFirstFailure'value [574] %� 'obj'�wi'RejectInputOnFirstFailure' [575] :if 1=Ρ�warg [576] �wres/�wi'Getbool'(a,'.RejectInputOnFirstFailure') [577] :else [578] z/�wi'Setbool'(a,'.RejectInputOnFirstFailure')(''zzWarg�warg) [579] :endif [580] :return

Page 129: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 129

[581] %�------------------------------------------------resetonprompt [582] Eresetonprompt: [583] %� Gets or sets a value that determines how an input character that matches the prompt character should be handled [584] %� Syntax: {value/}'obj'�wi'ResetOnPrompt'{value} [585] %� value: (System.Boolean) [586] %� Example: [587] %� 'obj'�wi'ResetOnPrompt'value [588] %� 'obj'�wi'ResetOnPrompt' [589] :if 1=Ρ�warg [590] �wres/�wi'Getbool'(a,'.ResetOnPrompt') [591] :else [592] z/�wi'Setbool'(a,'.ResetOnPrompt')(''zzWarg�warg) [593] :endif [594] :return [595] %�------------------------------------------------resetonspace [596] Eresetonspace: [597] %� Gets or sets a value that determines how a space input character should be handled [598] %� Syntax: {value/}'obj'�wi'ResetOnSpace'{value} [599] %� value: (System.Boolean) [600] %� Example: [601] %� 'obj'�wi'ResetOnSpace'value [602] %� 'obj'�wi'ResetOnSpace' [603] :if 1=Ρ�warg [604] �wres/�wi'Getbool'(a,'.ResetOnSpace') [605] :else [606] z/�wi'Setbool'(a,'.ResetOnSpace')(''zzWarg�warg) [607] :endif [608] :return [609] %�------------------------------------------------selectedtext [610] Eselectedtext: [611] %� Gets or sets the current selection in the System.Windows.Forms.MaskedTextBox control [612] %� Syntax: {value/}'obj'�wi'SelectedText'{value} [613] %� value: (System.String) [614] %� Example: [615] %� 'obj'�wi'SelectedText'value [616] %� 'obj'�wi'SelectedText' [617] :if 1=Ρ�warg [618] �wres/�wi'Getstring'(a,'.SelectedText') [619] :else [620] z/�wi'Setstring'(a,'.SelectedText')(''zzWarg�warg) [621] :endif [622] :return [623] %�------------------------------------------------selectionlength [624] Eselectionlength: [625] %� Gets or sets the number of characters selected in the text box [626] %� Syntax: {value/}'obj'�wi'SelectionLength'{value} [627] %� value: (System.Int32) [628] %� Example: [629] %� 'obj'�wi'SelectionLength'value [630] %� 'obj'�wi'SelectionLength' [631] :if 1=Ρ�warg [632] �wres/�wi'Getint'(a,'.SelectionLength') [633] :else [634] z/�wi'Setint'(a,'.SelectionLength')(''zzWarg�warg) [635] :endif [636] :return [637] %�------------------------------------------------selectionstart [638] Eselectionstart: [639] %� Gets or sets the starting point of text selected in the text box

Page 130: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 130

[640] %� Syntax: {value/}'obj'�wi'SelectionStart'{value} [641] %� value: (System.Int32) [642] %� Example: [643] %� 'obj'�wi'SelectionStart'value [644] %� 'obj'�wi'SelectionStart' [645] :if 1=Ρ�warg [646] �wres/�wi'Getint'(a,'.SelectionStart') [647] :else [648] z/�wi'Setint'(a,'.SelectionStart')(''zzWarg�warg) [649] :endif [650] :return [651] %�------------------------------------------------shortcutsenabled [652] Eshortcutsenabled: [653] %� Gets or sets a value indicating whether the defined shortcuts are enabled [654] %� Syntax: {value/}'obj'�wi'ShortcutsEnabled'{value} [655] %� value: (System.Boolean) [656] %� Example: [657] %� 'obj'�wi'ShortcutsEnabled'value [658] %� 'obj'�wi'ShortcutsEnabled' [659] :if 1=Ρ�warg [660] �wres/�wi'Getbool'(a,'.ShortcutsEnabled') [661] :else [662] z/�wi'Setbool'(a,'.ShortcutsEnabled')(''zzWarg�warg) [663] :endif [664] :return [665] %�------------------------------------------------skipliterals [666] Eskipliterals: [667] %� Gets or sets a value indicating whether the user is allowed to reenter literal values [668] %� Syntax: {value/}'obj'�wi'SkipLiterals'{value} [669] %� value: (System.Boolean) [670] %� Example: [671] %� 'obj'�wi'SkipLiterals'value [672] %� 'obj'�wi'SkipLiterals' [673] :if 1=Ρ�warg [674] �wres/�wi'Getbool'(a,'.SkipLiterals') [675] :else [676] z/�wi'Setbool'(a,'.SkipLiterals')(''zzWarg�warg) [677] :endif [678] :return [679] %�------------------------------------------------text [680] Etext: [681] %� Gets or sets the text as it is currently displayed to the user [682] %� Syntax: {value/}'obj'�wi'Text'{value} [683] %� value: (System.String) [684] %� Example: [685] %� 'obj'�wi'Text'value [686] %� 'obj'�wi'Text' [687] :if 1=Ρ�warg [688] �wres/�wi'Getstring'(a,'.Text') [689] :else [690] z/�wi'Setstring'(a,'.Text')(''zzWarg�warg) [691] :endif [692] :return [693] %�------------------------------------------------textalign [694] Etextalign: [695] %� Gets or sets how text is aligned in a masked text box control [696] %� Syntax: {value/}'obj'�wi'TextAlign'{value} [697] %� value: (System.Windows.Forms.HorizontalAlignment) [698] %� 0= HorizontalAlignment.Left [699] %� 1= HorizontalAlignment.Right [700] %� 2= HorizontalAlignment.Center

Page 131: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 131

[701] %� Example: [702] %� 'obj'�wi'TextAlign'value [703] %� 'obj'�wi'TextAlign' [704] :if 1=Ρ�warg [705] �wres/�wi'Getint'(a,'.TextAlign') [706] :else [707] z/�wi'Setint'(a,'.TextAlign')(''zzWarg�warg) [708] :endif [709] :return [710] %�------------------------------------------------textlength [711] Etextlength: [712] %� Gets the length of the displayed text [713] %� Syntax: value/'obj'�wi'TextLength' [714] %� value: (System.Int32) [715] %� Example: [716] %� 'obj'�wi'TextLength' [717] :if 1=Ρ�warg [718] �wres/�wi'Getint'(a,'.TextLength') [719] :else [720] zzError'Property <textlength> is read-only!' [721] :endif [722] :return [723] %�------------------------------------------------textmaskformat [724] Etextmaskformat: [725] %� Gets or sets a value that determines whether literals and prompt characters are included in the formatted string [726] %� Syntax: {value/}'obj'�wi'TextMaskFormat'{value} [727] %� value: (System.Windows.Forms.MaskFormat) [728] %� 0= MaskFormat.ExcludePromptAndLiterals [729] %� 1= MaskFormat.IncludePrompt [730] %� 2= MaskFormat.IncludeLiterals [731] %� 3= MaskFormat.IncludePromptAndLiterals [732] %� Example: [733] %� 'obj'�wi'TextMaskFormat'value [734] %� 'obj'�wi'TextMaskFormat' [735] :if 1=Ρ�warg [736] �wres/�wi'Getint'(a,'.TextMaskFormat') [737] :else [738] z/�wi'Setint'(a,'.TextMaskFormat')(''zzWarg�warg) [739] :endif [740] :return [741] %�------------------------------------------------usesystempasswordchar [742] Eusesystempasswordchar: [743] %� Gets or sets a value indicating whether the operating system-supplied password character should be used [744] %� Syntax: {value/}'obj'�wi'UseSystemPasswordChar'{value} [745] %� value: (System.Boolean) [746] %� Example: [747] %� 'obj'�wi'UseSystemPasswordChar'value [748] %� 'obj'�wi'UseSystemPasswordChar' [749] :if 1=Ρ�warg [750] �wres/�wi'Getbool'(a,'.UseSystemPasswordChar') [751] :else [752] z/�wi'Setbool'(a,'.UseSystemPasswordChar')(''zzWarg�warg) [753] :endif [754] :return [755] %�------------------------------------------------validatingtype [756] Evalidatingtype: [757] %� Gets or sets the data type used to verify the data input by the user [758] %� Syntax: {value/}'obj'�wi'ValidatingType'{value} [759] %� value: (System.Type) [760] %� Example:

Page 132: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 132

[761] %� 'obj'�wi'ValidatingType'value [762] %� 'obj'�wi'ValidatingType' [763] zzError'Unsupported type or structure: Type' [764] :return [765] %%�------------------------------------------------wordwrap [766] %Ewordwrap: [767] % %� Gets or sets a value indicating whether a multiline text box control automatically wraps words to the beginning of the next line when necessary. This property is not supported by System.Windows. Forms.MaskedTextBox [768] % %� Syntax: {value/}'obj'�wi'WordWrap'{value} [769] % %� value: (System.Boolean) [770] % %� Example: [771] % %� 'obj'�wi'WordWrap'value [772] % %� 'obj'�wi'WordWrap' [773] % :if 1=Ρ�warg [774] % �wres/�wi'Getbool'(a,'.WordWrap') [775] % :else [776] % z/�wi'Setbool'(a,'.WordWrap')(''zzWarg�warg) [777] % :endif [778] % :return [779] %�------------------------------------------------AppendText [780] EAppendText: [781] %� Appends text to the current text of a text box [782] %� Syntax: 'obj'�wi'AppendText'text [783] %� text: (System.String) [784] z/�wi'Setstring' 'text'(2c�warg) [785] z/zzCSE'ExecStmt'(a,'.AppendText(text);') [786] :return [787] %�------------------------------------------------Clear [788] EClear: [789] %� Clears all text from the text box control [790] %� Syntax: 'obj'�wi'Clear' [791] z/zzCSE'ExecStmt'(a,'.Clear();') [792] :return [793] %%�------------------------------------------------ClearUndo [794] %EClearUndo: [795] % %� Clears information about the most recent operation from the undo buffer of the text box. This method is not supported by System.Windows.Forms.MaskedTextBox [796] % %� Syntax: 'obj'�wi'ClearUndo' [797] % z/zzCSE'ExecStmt'(a,'.ClearUndo();') [798] % :return [799] %�------------------------------------------------Copy [800] ECopy: [801] %� Copies the current selection in the text box to the Clipboard [802] %� Syntax: 'obj'�wi'Copy' [803] z/zzCSE'ExecStmt'(a,'.Copy();') [804] :return [805] %�------------------------------------------------CreateObjRef [806] ECreateObjRef: [807] %� (missing XML documentation) [808] %� Syntax: result/'obj'�wi'CreateObjRef'requestedType [809] %� requestedType: (System.Type) [810] %� result: (System.Runtime.Remoting.ObjRef) [811] zzError'Non APL return type;Non APL argument type' [812] :return [813] %�------------------------------------------------Cut [814] ECut: [815] %� Moves the current selection in the text box to the Clipboard [816] %� Syntax: 'obj'�wi'Cut' [817] z/zzCSE'ExecStmt'(a,'.Cut();') [818] :return

Page 133: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 133

[819] %�------------------------------------------------DeselectAll [820] EDeselectAll: [821] %� Specifies that the value of the System.Windows.Forms.TextBoxBase.SelectionLength property is zero so that no characters are selected in the control [822] %� Syntax: 'obj'�wi'DeselectAll' [823] z/zzCSE'ExecStmt'(a,'.DeselectAll();') [824] :return [825] %�------------------------------------------------Dispose [826] EDispose: [827] %� (missing XML documentation) [828] %� Syntax: 'obj'�wi'Dispose' [829] z/zzCSE'ExecStmt'(a,'.Dispose();') [830] :return [831] %�------------------------------------------------Equals [832] EEquals: [833] %� (missing XML documentation) [834] %� Syntax: result/'obj'�wi'Equals'obj [835] %� obj: (System.Object) [836] %� result: (System.Boolean) [837] z/zzCSE'ExecStmt' 'bool result;' [838] z/�wi'Setobject' 'obj'(2c�warg) [839] z/zzCSE'ExecStmt'('result = ',a,'.Equals(obj);') [840] �wres/�wi'Getbool' 'result' [841] :return [842] %�------------------------------------------------GetCharFromPosition [843] EGetCharFromPosition: [844] %� pt: The location from which to seek the nearest character [845] %� Syntax: result/'obj'�wi'GetCharFromPosition' [846] %� notnamed: (System.Drawing.Point) [847] %� result: (System.Char) [848] z/zzCSE'ExecStmt' 'char result;' [849] z/zzCSE'ExecStmt'('result = ',a,'.GetCharFromPosition();') [850] �wres/�wi'Getchar' 'result' [851] :return [852] %�------------------------------------------------GetCharIndexFromPosition [853] EGetCharIndexFromPosition: [854] %� pt: The location to search [855] %� Syntax: result/'obj'�wi'GetCharIndexFromPosition' [856] %� notnamed: (System.Drawing.Point) [857] %� result: (System.Int32) [858] z/zzCSE'ExecStmt' 'int result;' [859] z/zzCSE'ExecStmt'('result = ',a,'.GetCharIndexFromPosition();') [860] �wres/�wi'Getint' 'result' [861] :return [862] %%�------------------------------------------------GetFirstCharIndexFromLine [863] %EGetFirstCharIndexFromLine: [864] % %� Retrieves the index of the first character of a given line. This method is not supported by System.Windows.Forms.MaskedTextBox [865] % %� Syntax: result/'obj'�wi'GetFirstCharIndexFromLine'lineNumber [866] % %� lineNumber: (System.Int32) [867] % %� result: (System.Int32) [868] % z/zzCSE'ExecStmt' 'int result;' [869] % z/�wi'Setint' 'lineNumber'(2c�warg) [870] % z/zzCSE'ExecStmt'('result = ',a,'.GetFirstCharIndexFromLine(lineNumber);') [871] % �wres/�wi'Getint' 'result' [872] % :return [873] %%�------------------------------------------------GetFirstCharIndexOfCurrentLine [874] %EGetFirstCharIndexOfCurrentLine: [875] % %� Retrieves the index of the first character of the current line. This method is not supported by System.Windows.Forms.MaskedTextBox [876] % %� Syntax: result/'obj'�wi'GetFirstCharIndexOfCurrentLine'

Page 134: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 134

[877] % %� result: (System.Int32) [878] % z/zzCSE'ExecStmt' 'int result;' [879] % z/zzCSE'ExecStmt'('result = ',a,'.GetFirstCharIndexOfCurrentLine();') [880] % �wres/�wi'Getint' 'result' [881] % :return [882] %�------------------------------------------------GetHashCode [883] EGetHashCode: [884] %� (missing XML documentation) [885] %� Syntax: result/'obj'�wi'GetHashCode' [886] %� result: (System.Int32) [887] z/zzCSE'ExecStmt' 'int result;' [888] z/zzCSE'ExecStmt'('result = ',a,'.GetHashCode();') [889] �wres/�wi'Getint' 'result' [890] :return [891] %�------------------------------------------------GetLifetimeService [892] EGetLifetimeService: [893] %� (missing XML documentation) [894] %� Syntax: result/'obj'�wi'GetLifetimeService' [895] %� result: (System.Object) [896] z/zzCSE'ExecStmt' 'object result;' [897] z/zzCSE'ExecStmt'('result = ',a,'.GetLifetimeService();') [898] �wres/�wi'Getobject' 'result' [899] :return [900] %%�------------------------------------------------GetLineFromCharIndex [901] %EGetLineFromCharIndex: [902] % %� Retrieves the line number from the specified character position within the text of the control. This method is not supported by System.Windows.Forms.MaskedTextBox [903] % %� Syntax: result/'obj'�wi'GetLineFromCharIndex'index [904] % %� index: (System.Int32) [905] % %� result: (System.Int32) [906] % z/zzCSE'ExecStmt' 'int result;' [907] % z/�wi'Setint' 'index'(2c�warg) [908] % z/zzCSE'ExecStmt'('result = ',a,'.GetLineFromCharIndex(index);') [909] % �wres/�wi'Getint' 'result' [910] % :return [911] %�------------------------------------------------GetPositionFromCharIndex [912] EGetPositionFromCharIndex: [913] %� index: The index of the character for which to retrieve the location [914] %� Syntax: result/'obj'�wi'GetPositionFromCharIndex' [915] %� notnamed: (System.Int32) [916] %� result: (System.Drawing.Point) [917] z/zzCSE'ExecStmt' 'Point result;' [918] z/zzCSE'ExecStmt'('result = ',a,'.GetPositionFromCharIndex();') [919] �wres/�wi'GetPoint' 'result' [920] :return [921] %�------------------------------------------------GetType [922] EGetType: [923] %� (missing XML documentation) [924] %� Syntax: result/'obj'�wi'GetType' [925] %� result: (System.Type) [926] zzError'Non APL return type' [927] :return [928] %�------------------------------------------------InitializeLifetimeService [929] EInitializeLifetimeService: [930] %� (missing XML documentation) [931] %� Syntax: result/'obj'�wi'InitializeLifetimeService' [932] %� result: (System.Object) [933] z/zzCSE'ExecStmt' 'object result;' [934] z/zzCSE'ExecStmt'('result = ',a,'.InitializeLifetimeService();') [935] �wres/�wi'Getobject' 'result' [936] :return [937] %�------------------------------------------------Paste

Page 135: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 135

[938] EPaste: [939] %� Replaces the current selection in the text box with the contents of the Clipboard [940] %� Syntax: 'obj'�wi'Paste' [941] z/zzCSE'ExecStmt'(a,'.Paste();') [942] :return [943] %%�------------------------------------------------ScrollToCaret [944] %EScrollToCaret: [945] % %� Scrolls the contents of the control to the current caret position. This method is not supported by System.Windows.Forms.MaskedTextBox [946] % %� Syntax: 'obj'�wi'ScrollToCaret' [947] % z/zzCSE'ExecStmt'(a,'.ScrollToCaret();') [948] % :return [949] %�------------------------------------------------Select [950] ESelect: [951] %� Selects a range of text in the text box [952] %� Syntax: 'obj'�wi'Select'start length [953] %� start: (System.Int32) [954] %� length: (System.Int32) [955] z/�wi'Setint' 'start'(2c�warg) [956] z/�wi'Setint' 'length'(3c�warg) [957] z/zzCSE'ExecStmt'(a,'.Select(start,length);') [958] :return [959] %�------------------------------------------------SelectAll [960] ESelectAll: [961] %� Selects all text in the text box [962] %� Syntax: 'obj'�wi'SelectAll' [963] z/zzCSE'ExecStmt'(a,'.SelectAll();') [964] :return [965] %�------------------------------------------------ToString [966] EToString: [967] %� Returns a string that represents the current masked text box. This method overrides <see cref="M:System.Windows.Forms.TextBoxBase.ToString [968] %� Syntax: result/'obj'�wi'ToString' [969] %� result: (System.String) [970] z/zzCSE'ExecStmt' 'string result;' [971] z/zzCSE'ExecStmt'('result = ',a,'.ToString();') [972] �wres/�wi'Getstring' 'result' [973] :return [974] %%�------------------------------------------------Undo [975] %EUndo: [976] % %� Undoes the last edit operation in the text box. This method is not supported by System.Windows.Forms.MaskedTextBox [977] % %� Syntax: 'obj'�wi'Undo' [978] % z/zzCSE'ExecStmt'(a,'.Undo();') [979] % :return [980] %�------------------------------------------------ValidateText [981] EValidateText: [982] %� Converts the user input string to an instance of the validating type [983] %� Syntax: result/'obj'�wi'ValidateText' [984] %� result: (System.Object) [985] z/zzCSE'ExecStmt' 'object result;' [986] z/zzCSE'ExecStmt'('result = ',a,'.ValidateText();') [987] �wres/�wi'Getobject' 'result' [988] :return [989] %�------------------------------------------------onAcceptsTabChanged [990] EonAcceptsTabChanged: [991] %� (missing XML documentation) [992] %� Syntax: 'obj'�wi'onAcceptsTabChanged'sender e [993] %� sender: (System.Object) [994] %� e: (System.EventArgs) [995] �/Ewarg

Page 136: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 136

[996] :return [997] %�------------------------------------------------onAutoSizeChanged [998] EonAutoSizeChanged: [999] %� (missing XML documentation) [1000] %� Syntax: 'obj'�wi'onAutoSizeChanged'sender e [1001] %� sender: (System.Object) [1002] %� e: (System.EventArgs) [1003] �/Ewarg [1004] :return [1005] %�------------------------------------------------onBackColorChanged [1006] EonBackColorChanged: [1007] %� (missing XML documentation) [1008] %� Syntax: 'obj'�wi'onBackColorChanged'sender e [1009] %� sender: (System.Object) [1010] %� e: (System.EventArgs) [1011] �/Ewarg [1012] :return [1013] %�------------------------------------------------onBackgroundImageChanged [1014] EonBackgroundImageChanged: [1015] %� (missing XML documentation) [1016] %� Syntax: 'obj'�wi'onBackgroundImageChanged'sender e [1017] %� sender: (System.Object) [1018] %� e: (System.EventArgs) [1019] �/Ewarg [1020] :return [1021] %�------------------------------------------------onBackgroundImageLayoutChanged [1022] EonBackgroundImageLayoutChanged: [1023] %� (missing XML documentation) [1024] %� Syntax: 'obj'�wi'onBackgroundImageLayoutChanged'sender e [1025] %� sender: (System.Object) [1026] %� e: (System.EventArgs) [1027] �/Ewarg [1028] :return [1029] %�------------------------------------------------onBindingContextChanged [1030] EonBindingContextChanged: [1031] %� (missing XML documentation) [1032] %� Syntax: 'obj'�wi'onBindingContextChanged'sender e [1033] %� sender: (System.Object) [1034] %� e: (System.EventArgs) [1035] �/Ewarg [1036] :return [1037] %�------------------------------------------------onBorderStyleChanged [1038] EonBorderStyleChanged: [1039] %� (missing XML documentation) [1040] %� Syntax: 'obj'�wi'onBorderStyleChanged'sender e [1041] %� sender: (System.Object) [1042] %� e: (System.EventArgs) [1043] �/Ewarg [1044] :return [1045] %�------------------------------------------------onCausesValidationChanged [1046] EonCausesValidationChanged: [1047] %� (missing XML documentation) [1048] %� Syntax: 'obj'�wi'onCausesValidationChanged'sender e [1049] %� sender: (System.Object) [1050] %� e: (System.EventArgs) [1051] �/Ewarg [1052] :return [1053] %�------------------------------------------------onChangeUICues [1054] EonChangeUICues: [1055] %� (missing XML documentation) [1056] %� Syntax: 'obj'�wi'onChangeUICues'sender e [1057] %� sender: (System.Object)

Page 137: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 137

[1058] %� e: (System.Windows.Forms.UICuesEventArgs) [1059] �/Ewarg [1060] :return [1061] %�------------------------------------------------onClick [1062] EonClick: [1063] %� (missing XML documentation) [1064] %� Syntax: 'obj'�wi'onClick'sender e [1065] %� sender: (System.Object) [1066] %� e: (System.EventArgs) [1067] �/Ewarg [1068] :return [1069] %�------------------------------------------------onClientSizeChanged [1070] EonClientSizeChanged: [1071] %� (missing XML documentation) [1072] %� Syntax: 'obj'�wi'onClientSizeChanged'sender e [1073] %� sender: (System.Object) [1074] %� e: (System.EventArgs) [1075] �/Ewarg [1076] :return [1077] %�------------------------------------------------onContextMenuChanged [1078] EonContextMenuChanged: [1079] %� (missing XML documentation) [1080] %� Syntax: 'obj'�wi'onContextMenuChanged'sender e [1081] %� sender: (System.Object) [1082] %� e: (System.EventArgs) [1083] �/Ewarg [1084] :return [1085] %�------------------------------------------------onContextMenuStripChanged [1086] EonContextMenuStripChanged: [1087] %� (missing XML documentation) [1088] %� Syntax: 'obj'�wi'onContextMenuStripChanged'sender e [1089] %� sender: (System.Object) [1090] %� e: (System.EventArgs) [1091] �/Ewarg [1092] :return [1093] %�------------------------------------------------onControlAdded [1094] EonControlAdded: [1095] %� (missing XML documentation) [1096] %� Syntax: 'obj'�wi'onControlAdded'sender e [1097] %� sender: (System.Object) [1098] %� e: (System.Windows.Forms.ControlEventArgs) [1099] �/Ewarg [1100] :return [1101] %�------------------------------------------------onControlRemoved [1102] EonControlRemoved: [1103] %� (missing XML documentation) [1104] %� Syntax: 'obj'�wi'onControlRemoved'sender e [1105] %� sender: (System.Object) [1106] %� e: (System.Windows.Forms.ControlEventArgs) [1107] �/Ewarg [1108] :return [1109] %�------------------------------------------------onCursorChanged [1110] EonCursorChanged: [1111] %� (missing XML documentation) [1112] %� Syntax: 'obj'�wi'onCursorChanged'sender e [1113] %� sender: (System.Object) [1114] %� e: (System.EventArgs) [1115] �/Ewarg [1116] :return [1117] %�------------------------------------------------onDisposed [1118] EonDisposed: [1119] %� (missing XML documentation)

Page 138: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 138

[1120] %� Syntax: 'obj'�wi'onDisposed'sender e [1121] %� sender: (System.Object) [1122] %� e: (System.EventArgs) [1123] �/Ewarg [1124] :return [1125] %�------------------------------------------------onDockChanged [1126] EonDockChanged: [1127] %� (missing XML documentation) [1128] %� Syntax: 'obj'�wi'onDockChanged'sender e [1129] %� sender: (System.Object) [1130] %� e: (System.EventArgs) [1131] �/Ewarg [1132] :return [1133] %�------------------------------------------------onDoubleClick [1134] EonDoubleClick: [1135] %� (missing XML documentation) [1136] %� Syntax: 'obj'�wi'onDoubleClick'sender e [1137] %� sender: (System.Object) [1138] %� e: (System.EventArgs) [1139] �/Ewarg [1140] :return [1141] %�------------------------------------------------onDragDrop [1142] EonDragDrop: [1143] %� (missing XML documentation) [1144] %� Syntax: 'obj'�wi'onDragDrop'sender e [1145] %� sender: (System.Object) [1146] %� e: (System.Windows.Forms.DragEventArgs) [1147] �/Ewarg [1148] :return [1149] %�------------------------------------------------onDragEnter [1150] EonDragEnter: [1151] %� (missing XML documentation) [1152] %� Syntax: 'obj'�wi'onDragEnter'sender e [1153] %� sender: (System.Object) [1154] %� e: (System.Windows.Forms.DragEventArgs) [1155] �/Ewarg [1156] :return [1157] %�------------------------------------------------onDragLeave [1158] EonDragLeave: [1159] %� (missing XML documentation) [1160] %� Syntax: 'obj'�wi'onDragLeave'sender e [1161] %� sender: (System.Object) [1162] %� e: (System.EventArgs) [1163] �/Ewarg [1164] :return [1165] %�------------------------------------------------onDragOver [1166] EonDragOver: [1167] %� (missing XML documentation) [1168] %� Syntax: 'obj'�wi'onDragOver'sender e [1169] %� sender: (System.Object) [1170] %� e: (System.Windows.Forms.DragEventArgs) [1171] �/Ewarg [1172] :return [1173] %�------------------------------------------------onEnabledChanged [1174] EonEnabledChanged: [1175] %� (missing XML documentation) [1176] %� Syntax: 'obj'�wi'onEnabledChanged'sender e [1177] %� sender: (System.Object) [1178] %� e: (System.EventArgs) [1179] �/Ewarg [1180] :return [1181] %�------------------------------------------------onEnter

Page 139: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 139

[1182] EonEnter: [1183] %� (missing XML documentation) [1184] %� Syntax: 'obj'�wi'onEnter'sender e [1185] %� sender: (System.Object) [1186] %� e: (System.EventArgs) [1187] �/Ewarg [1188] :return [1189] %�------------------------------------------------onFontChanged [1190] EonFontChanged: [1191] %� (missing XML documentation) [1192] %� Syntax: 'obj'�wi'onFontChanged'sender e [1193] %� sender: (System.Object) [1194] %� e: (System.EventArgs) [1195] �/Ewarg [1196] :return [1197] %�------------------------------------------------onForeColorChanged [1198] EonForeColorChanged: [1199] %� (missing XML documentation) [1200] %� Syntax: 'obj'�wi'onForeColorChanged'sender e [1201] %� sender: (System.Object) [1202] %� e: (System.EventArgs) [1203] �/Ewarg [1204] :return [1205] %�------------------------------------------------onGiveFeedback [1206] EonGiveFeedback: [1207] %� (missing XML documentation) [1208] %� Syntax: 'obj'�wi'onGiveFeedback'sender e [1209] %� sender: (System.Object) [1210] %� e: (System.Windows.Forms.GiveFeedbackEventArgs) [1211] �/Ewarg [1212] :return [1213] %�------------------------------------------------onGotFocus [1214] EonGotFocus: [1215] %� (missing XML documentation) [1216] %� Syntax: 'obj'�wi'onGotFocus'sender e [1217] %� sender: (System.Object) [1218] %� e: (System.EventArgs) [1219] �/Ewarg [1220] :return [1221] %�------------------------------------------------onHandleCreated [1222] EonHandleCreated: [1223] %� (missing XML documentation) [1224] %� Syntax: 'obj'�wi'onHandleCreated'sender e [1225] %� sender: (System.Object) [1226] %� e: (System.EventArgs) [1227] �/Ewarg [1228] :return [1229] %�------------------------------------------------onHandleDestroyed [1230] EonHandleDestroyed: [1231] %� (missing XML documentation) [1232] %� Syntax: 'obj'�wi'onHandleDestroyed'sender e [1233] %� sender: (System.Object) [1234] %� e: (System.EventArgs) [1235] �/Ewarg [1236] :return [1237] %�------------------------------------------------onHelpRequested [1238] EonHelpRequested: [1239] %� (missing XML documentation) [1240] %� Syntax: 'obj'�wi'onHelpRequested'sender hlpevent [1241] %� sender: (System.Object) [1242] %� hlpevent: (System.Windows.Forms.HelpEventArgs) [1243] �/Ewarg

Page 140: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 140

[1244] :return [1245] %�------------------------------------------------onHideSelectionChanged [1246] EonHideSelectionChanged: [1247] %� (missing XML documentation) [1248] %� Syntax: 'obj'�wi'onHideSelectionChanged'sender e [1249] %� sender: (System.Object) [1250] %� e: (System.EventArgs) [1251] �/Ewarg [1252] :return [1253] %�------------------------------------------------onImeModeChanged [1254] EonImeModeChanged: [1255] %� (missing XML documentation) [1256] %� Syntax: 'obj'�wi'onImeModeChanged'sender e [1257] %� sender: (System.Object) [1258] %� e: (System.EventArgs) [1259] �/Ewarg [1260] :return [1261] %�------------------------------------------------onInvalidated [1262] EonInvalidated: [1263] %� (missing XML documentation) [1264] %� Syntax: 'obj'�wi'onInvalidated'sender e [1265] %� sender: (System.Object) [1266] %� e: (System.Windows.Forms.InvalidateEventArgs) [1267] �/Ewarg [1268] :return [1269] %�------------------------------------------------onIsOverwriteModeChanged [1270] EonIsOverwriteModeChanged: [1271] %� (missing XML documentation) [1272] %� Syntax: 'obj'�wi'onIsOverwriteModeChanged'sender e [1273] %� sender: (System.Object) [1274] %� e: (System.EventArgs) [1275] �/Ewarg [1276] :return [1277] %�------------------------------------------------onKeyDown [1278] EonKeyDown: [1279] %� (missing XML documentation) [1280] %� Syntax: 'obj'�wi'onKeyDown'sender e [1281] %� sender: (System.Object) [1282] %� e: (System.Windows.Forms.KeyEventArgs) [1283] �/Ewarg [1284] :return [1285] %�------------------------------------------------onKeyPress [1286] EonKeyPress: [1287] %� (missing XML documentation) [1288] %� Syntax: 'obj'�wi'onKeyPress'sender e [1289] %� sender: (System.Object) [1290] %� e: (System.Windows.Forms.KeyPressEventArgs) [1291] �/Ewarg [1292] :return [1293] %�------------------------------------------------onKeyUp [1294] EonKeyUp: [1295] %� (missing XML documentation) [1296] %� Syntax: 'obj'�wi'onKeyUp'sender e [1297] %� sender: (System.Object) [1298] %� e: (System.Windows.Forms.KeyEventArgs) [1299] �/Ewarg [1300] :return [1301] %�------------------------------------------------onLayout [1302] EonLayout: [1303] %� (missing XML documentation) [1304] %� Syntax: 'obj'�wi'onLayout'sender e [1305] %� sender: (System.Object)

Page 141: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 141

[1306] %� e: (System.Windows.Forms.LayoutEventArgs) [1307] �/Ewarg [1308] :return [1309] %�------------------------------------------------onLeave [1310] EonLeave: [1311] %� (missing XML documentation) [1312] %� Syntax: 'obj'�wi'onLeave'sender e [1313] %� sender: (System.Object) [1314] %� e: (System.EventArgs) [1315] �/Ewarg [1316] :return [1317] %�------------------------------------------------onLocationChanged [1318] EonLocationChanged: [1319] %� (missing XML documentation) [1320] %� Syntax: 'obj'�wi'onLocationChanged'sender e [1321] %� sender: (System.Object) [1322] %� e: (System.EventArgs) [1323] �/Ewarg [1324] :return [1325] %�------------------------------------------------onLostFocus [1326] EonLostFocus: [1327] %� (missing XML documentation) [1328] %� Syntax: 'obj'�wi'onLostFocus'sender e [1329] %� sender: (System.Object) [1330] %� e: (System.EventArgs) [1331] �/Ewarg [1332] :return [1333] %�------------------------------------------------onMarginChanged [1334] EonMarginChanged: [1335] %� (missing XML documentation) [1336] %� Syntax: 'obj'�wi'onMarginChanged'sender e [1337] %� sender: (System.Object) [1338] %� e: (System.EventArgs) [1339] �/Ewarg [1340] :return [1341] %�------------------------------------------------onMaskChanged [1342] EonMaskChanged: [1343] %� (missing XML documentation) [1344] %� Syntax: 'obj'�wi'onMaskChanged'sender e [1345] %� sender: (System.Object) [1346] %� e: (System.EventArgs) [1347] �/Ewarg [1348] :return [1349] %�------------------------------------------------onMaskInputRejected [1350] EonMaskInputRejected: [1351] %� (missing XML documentation) [1352] %� Syntax: 'obj'�wi'onMaskInputRejected'sender e [1353] %� sender: (System.Object) [1354] %� e: (System.Windows.Forms.MaskInputRejectedEventArgs) [1355] �/Ewarg [1356] :return [1357] %�------------------------------------------------onModifiedChanged [1358] EonModifiedChanged: [1359] %� (missing XML documentation) [1360] %� Syntax: 'obj'�wi'onModifiedChanged'sender e [1361] %� sender: (System.Object) [1362] %� e: (System.EventArgs) [1363] �/Ewarg [1364] :return [1365] %�------------------------------------------------onMouseCaptureChanged [1366] EonMouseCaptureChanged: [1367] %� (missing XML documentation)

Page 142: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 142

[1368] %� Syntax: 'obj'�wi'onMouseCaptureChanged'sender e [1369] %� sender: (System.Object) [1370] %� e: (System.EventArgs) [1371] �/Ewarg [1372] :return [1373] %�------------------------------------------------onMouseClick [1374] EonMouseClick: [1375] %� (missing XML documentation) [1376] %� Syntax: 'obj'�wi'onMouseClick'sender e [1377] %� sender: (System.Object) [1378] %� e: (System.Windows.Forms.MouseEventArgs) [1379] �/Ewarg [1380] :return [1381] %�------------------------------------------------onMouseDoubleClick [1382] EonMouseDoubleClick: [1383] %� (missing XML documentation) [1384] %� Syntax: 'obj'�wi'onMouseDoubleClick'sender e [1385] %� sender: (System.Object) [1386] %� e: (System.Windows.Forms.MouseEventArgs) [1387] �/Ewarg [1388] :return [1389] %�------------------------------------------------onMouseDown [1390] EonMouseDown: [1391] %� (missing XML documentation) [1392] %� Syntax: 'obj'�wi'onMouseDown'sender e [1393] %� sender: (System.Object) [1394] %� e: (System.Windows.Forms.MouseEventArgs) [1395] �/Ewarg [1396] :return [1397] %�------------------------------------------------onMouseEnter [1398] EonMouseEnter: [1399] %� (missing XML documentation) [1400] %� Syntax: 'obj'�wi'onMouseEnter'sender e [1401] %� sender: (System.Object) [1402] %� e: (System.EventArgs) [1403] �/Ewarg [1404] :return [1405] %�------------------------------------------------onMouseHover [1406] EonMouseHover: [1407] %� (missing XML documentation) [1408] %� Syntax: 'obj'�wi'onMouseHover'sender e [1409] %� sender: (System.Object) [1410] %� e: (System.EventArgs) [1411] �/Ewarg [1412] :return [1413] %�------------------------------------------------onMouseLeave [1414] EonMouseLeave: [1415] %� (missing XML documentation) [1416] %� Syntax: 'obj'�wi'onMouseLeave'sender e [1417] %� sender: (System.Object) [1418] %� e: (System.EventArgs) [1419] �/Ewarg [1420] :return [1421] %�------------------------------------------------onMouseMove [1422] EonMouseMove: [1423] %� (missing XML documentation) [1424] %� Syntax: 'obj'�wi'onMouseMove'sender e [1425] %� sender: (System.Object) [1426] %� e: (System.Windows.Forms.MouseEventArgs) [1427] �/Ewarg [1428] :return [1429] %�------------------------------------------------onMouseUp

Page 143: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 143

[1430] EonMouseUp: [1431] %� (missing XML documentation) [1432] %� Syntax: 'obj'�wi'onMouseUp'sender e [1433] %� sender: (System.Object) [1434] %� e: (System.Windows.Forms.MouseEventArgs) [1435] �/Ewarg [1436] :return [1437] %�------------------------------------------------onMouseWheel [1438] EonMouseWheel: [1439] %� (missing XML documentation) [1440] %� Syntax: 'obj'�wi'onMouseWheel'sender e [1441] %� sender: (System.Object) [1442] %� e: (System.Windows.Forms.MouseEventArgs) [1443] �/Ewarg [1444] :return [1445] %�------------------------------------------------onMove [1446] EonMove: [1447] %� (missing XML documentation) [1448] %� Syntax: 'obj'�wi'onMove'sender e [1449] %� sender: (System.Object) [1450] %� e: (System.EventArgs) [1451] �/Ewarg [1452] :return [1453] %�------------------------------------------------onMultilineChanged [1454] EonMultilineChanged: [1455] %� (missing XML documentation) [1456] %� Syntax: 'obj'�wi'onMultilineChanged'sender e [1457] %� sender: (System.Object) [1458] %� e: (System.EventArgs) [1459] �/Ewarg [1460] :return [1461] %�------------------------------------------------onPaddingChanged [1462] EonPaddingChanged: [1463] %� (missing XML documentation) [1464] %� Syntax: 'obj'�wi'onPaddingChanged'sender e [1465] %� sender: (System.Object) [1466] %� e: (System.EventArgs) [1467] �/Ewarg [1468] :return [1469] %�------------------------------------------------onPaint [1470] EonPaint: [1471] %� (missing XML documentation) [1472] %� Syntax: 'obj'�wi'onPaint'sender e [1473] %� sender: (System.Object) [1474] %� e: (System.Windows.Forms.PaintEventArgs) [1475] �/Ewarg [1476] :return [1477] %�------------------------------------------------onParentChanged [1478] EonParentChanged: [1479] %� (missing XML documentation) [1480] %� Syntax: 'obj'�wi'onParentChanged'sender e [1481] %� sender: (System.Object) [1482] %� e: (System.EventArgs) [1483] �/Ewarg [1484] :return [1485] %�------------------------------------------------onPreviewKeyDown [1486] EonPreviewKeyDown: [1487] %� (missing XML documentation) [1488] %� Syntax: 'obj'�wi'onPreviewKeyDown'sender e [1489] %� sender: (System.Object) [1490] %� e: (System.Windows.Forms.PreviewKeyDownEventArgs) [1491] �/Ewarg

Page 144: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 144

[1492] :return [1493] %�------------------------------------------------onQueryAccessibilityHelp [1494] EonQueryAccessibilityHelp: [1495] %� (missing XML documentation) [1496] %� Syntax: 'obj'�wi'onQueryAccessibilityHelp'sender e [1497] %� sender: (System.Object) [1498] %� e: (System.Windows.Forms.QueryAccessibilityHelpEventArgs) [1499] �/Ewarg [1500] :return [1501] %�------------------------------------------------onQueryContinueDrag [1502] EonQueryContinueDrag: [1503] %� (missing XML documentation) [1504] %� Syntax: 'obj'�wi'onQueryContinueDrag'sender e [1505] %� sender: (System.Object) [1506] %� e: (System.Windows.Forms.QueryContinueDragEventArgs) [1507] �/Ewarg [1508] :return [1509] %�------------------------------------------------onReadOnlyChanged [1510] EonReadOnlyChanged: [1511] %� (missing XML documentation) [1512] %� Syntax: 'obj'�wi'onReadOnlyChanged'sender e [1513] %� sender: (System.Object) [1514] %� e: (System.EventArgs) [1515] �/Ewarg [1516] :return [1517] %�------------------------------------------------onRegionChanged [1518] EonRegionChanged: [1519] %� (missing XML documentation) [1520] %� Syntax: 'obj'�wi'onRegionChanged'sender e [1521] %� sender: (System.Object) [1522] %� e: (System.EventArgs) [1523] �/Ewarg [1524] :return [1525] %�------------------------------------------------onResize [1526] EonResize: [1527] %� (missing XML documentation) [1528] %� Syntax: 'obj'�wi'onResize'sender e [1529] %� sender: (System.Object) [1530] %� e: (System.EventArgs) [1531] �/Ewarg [1532] :return [1533] %�------------------------------------------------onRightToLeftChanged [1534] EonRightToLeftChanged: [1535] %� (missing XML documentation) [1536] %� Syntax: 'obj'�wi'onRightToLeftChanged'sender e [1537] %� sender: (System.Object) [1538] %� e: (System.EventArgs) [1539] �/Ewarg [1540] :return [1541] %�------------------------------------------------onSizeChanged [1542] EonSizeChanged: [1543] %� (missing XML documentation) [1544] %� Syntax: 'obj'�wi'onSizeChanged'sender e [1545] %� sender: (System.Object) [1546] %� e: (System.EventArgs) [1547] �/Ewarg [1548] :return [1549] %�------------------------------------------------onStyleChanged [1550] EonStyleChanged: [1551] %� (missing XML documentation) [1552] %� Syntax: 'obj'�wi'onStyleChanged'sender e [1553] %� sender: (System.Object)

Page 145: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 145

[1554] %� e: (System.EventArgs) [1555] �/Ewarg [1556] :return [1557] %�------------------------------------------------onSystemColorsChanged [1558] EonSystemColorsChanged: [1559] %� (missing XML documentation) [1560] %� Syntax: 'obj'�wi'onSystemColorsChanged'sender e [1561] %� sender: (System.Object) [1562] %� e: (System.EventArgs) [1563] �/Ewarg [1564] :return [1565] %�------------------------------------------------onTabIndexChanged [1566] EonTabIndexChanged: [1567] %� (missing XML documentation) [1568] %� Syntax: 'obj'�wi'onTabIndexChanged'sender e [1569] %� sender: (System.Object) [1570] %� e: (System.EventArgs) [1571] �/Ewarg [1572] :return [1573] %�------------------------------------------------onTabStopChanged [1574] EonTabStopChanged: [1575] %� (missing XML documentation) [1576] %� Syntax: 'obj'�wi'onTabStopChanged'sender e [1577] %� sender: (System.Object) [1578] %� e: (System.EventArgs) [1579] �/Ewarg [1580] :return [1581] %�------------------------------------------------onTextAlignChanged [1582] EonTextAlignChanged: [1583] %� (missing XML documentation) [1584] %� Syntax: 'obj'�wi'onTextAlignChanged'sender e [1585] %� sender: (System.Object) [1586] %� e: (System.EventArgs) [1587] �/Ewarg [1588] :return [1589] %�------------------------------------------------onTextChanged [1590] EonTextChanged: [1591] %� (missing XML documentation) [1592] %� Syntax: 'obj'�wi'onTextChanged'sender e [1593] %� sender: (System.Object) [1594] %� e: (System.EventArgs) [1595] �/Ewarg [1596] :return [1597] %�------------------------------------------------onTypeValidationCompleted [1598] EonTypeValidationCompleted: [1599] %� (missing XML documentation) [1600] %� Syntax: 'obj'�wi'onTypeValidationCompleted'sender e [1601] %� sender: (System.Object) [1602] %� e: (System.Windows.Forms.TypeValidationEventArgs) [1603] �/Ewarg [1604] :return [1605] %�------------------------------------------------onValidated [1606] EonValidated: [1607] %� (missing XML documentation) [1608] %� Syntax: 'obj'�wi'onValidated'sender e [1609] %� sender: (System.Object) [1610] %� e: (System.EventArgs) [1611] �/Ewarg [1612] :return [1613] %�------------------------------------------------onValidating [1614] EonValidating: [1615] %� (missing XML documentation)

Page 146: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 146

[1616] %� Syntax: 'obj'�wi'onValidating'sender e [1617] %� sender: (System.Object) [1618] %� e: (System.ComponentModel.CancelEventArgs) [1619] �/Ewarg [1620] :return [1621] %�------------------------------------------------onVisibleChanged [1622] EonVisibleChanged: [1623] %� (missing XML documentation) [1624] %� Syntax: 'obj'�wi'onVisibleChanged'sender e [1625] %� sender: (System.Object) [1626] %� e: (System.EventArgs) [1627] �/Ewarg [1628] :return [1629] %�================================================Generated Code [1630] [1631] %�================================================Protected Code [1632] %�================================================Protected Code [1633] [1634] %------------------------------------------------- [1635] EEHelp: [1636] �wres/�wi'GetHelp'(('?'=Cb)Xb) [1637] :return [1638] %------------------------------------------------- [1639] EEInherit: [1640] �wres/�wi'*' �

Page 147: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 147

Appendix 2: The C# zRegex Class

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Text.RegularExpressions; using System.Drawing; using System.Windows.Forms; namespace zObjects { public class zRegex { #region----------------------------------------------------------------Fields private TextBox txtRegex; private RichTextBox rtxtText; #endregion-------------------------------------------------------------Fields #region----------------------------------------------------------------EscapeChars public string EscapeChars { get { return @"\*+?|{[()n$.#"; } } #endregion-------------------------------------------------------------EscapeChars #region----------------------------------------------------------------IsMatch public bool IsMatch(string input, string pattern) { return Regex.IsMatch(input, pattern); } #endregion-------------------------------------------------------------IsMatch #region----------------------------------------------------------------Groups public object[,] Groups(string input, string pattern) { MatchCollection matches = Regex.Matches(input, pattern); if (matches.Count == 0) return new object[0, 4]; else { int count = matches[0].Groups.Count; object[,] result = new object[count * matches.Count, 4]; for (int i = 0; i < matches.Count; i++) { for (int j = 0; j < count; j++) { result[j + (i * count), 0] = matches[i].Groups[j].Success; result[j + (i * count), 1] = matches[i].Groups[j].Index; result[j + (i * count), 2] = matches[i].Groups[j].Length; result[j + (i * count), 3] = matches[i].Groups[j].Value; } }

Page 148: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 148

return result; } } #endregion-------------------------------------------------------------Groups #region----------------------------------------------------------------Matches public object[,] Matches(string input, string pattern) { MatchCollection matches = Regex.Matches(input, pattern); object[,] result = new object[matches.Count, 4]; for (int i = 0; i < matches.Count; i++) { result[i, 0] = matches[i].Success; result[i, 1] = matches[i].Index; result[i, 2] = matches[i].Length; result[i, 3] = matches[i].Value; } return result; } #endregion-------------------------------------------------------------Matches #region----------------------------------------------------------------Replace public string Replace(string input, string pattern, string replacement) { return Regex.Replace(input, pattern, replacement); } #endregion-------------------------------------------------------------Replace #region----------------------------------------------------------------TestRegex public void TestRegex(string input) { Form f = new Form(); f.Text = "Regular Expression Test Form"; f.Size = new Size(600, 400); f.StartPosition = FormStartPosition.CenterScreen; f.Load += f_Load; txtRegex = new TextBox(); txtRegex.Location = new Point(5, 5); txtRegex.Size = new Size(574, 20); txtRegex.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; txtRegex.TextChanged += txtRegex_TextChanged; txtRegex.Name = "txtRegex"; rtxtText = new RichTextBox(); rtxtText.Location = new Point(5, 30); rtxtText.Size = new Size(574, 328); rtxtText.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom; rtxtText.Name = "rtxtText"; rtxtText.Text = input; f.Controls.Add(txtRegex); f.Controls.Add(rtxtText); f.ShowDialog(); }

Page 149: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 149

void f_Load(object sender, EventArgs e) { txtRegex.Font = zAplFont.GetAplFont(10); rtxtText.Font = zAplFont.GetAplFont(10); } void txtRegex_TextChanged(object sender, EventArgs e) { string input = rtxtText.Text; string pattern = txtRegex.Text.Trim(); try { MatchCollection matches = Regex.Matches(input, pattern); HighlightText(rtxtText, matches, Color.Yellow); } catch { } } public static void HighlightText(RichTextBox rtxtText, MatchCollection matches, Color color) { int start = rtxtText.SelectionStart; int length = rtxtText.SelectionLength; rtxtText.SelectAll(); rtxtText.SelectionBackColor = Color.White; rtxtText.SelectionStart = start; rtxtText.SelectionLength = length; foreach (Match match in matches) { rtxtText.Select(match.Index, match.Length); rtxtText.SelectionBackColor = color; } rtxtText.SelectionStart = start; rtxtText.SelectionLength = 0; rtxtText.SelectionBackColor = Color.White; } #endregion-------------------------------------------------------------TestRegex } }

Page 150: Using .Net with []cse Made Easy - Lescasseold.lescasse.com/downloads/Using .Net with []cse Made Easy.pdfLescasse Consulting Using .Net with ⎕⎕⎕⎕cse Made Easy! March 25, 2014

Using .Net with ⎕cse Made Easy!

Copyright © 2014 Lescasse Consulting. All rights reserved. Page 150

Appendix 3: Installing the zObjects software

The Conference support material includes a file named zObjectsSetup.exe.

Just run zObjectsSetup.exe to install zObjects on your computer.

Requirements:

• You need APL+Win v14.0.04+ to run zObjects

• You need to have the .Net Framework v4.5+ properly installed on your computer

• You need a DevExpress WinForms Trial version (or Subscription) to use those objects and examples that

make use of DevExpress controls

You may choose to install the software to any folder on your computer. All installed files go to the same

folder.

In the current version, zObjects include an APL+Win workspace (zObjects.w3) and 2 C# DLLs which I

have developed:

• zObjects.dll

• zObjectsDX.dll

The first DLL (zObjects.dll) makes use of the Microsoft .Net Framework only. It does not use any third

party objects.

The second DLL (zObjectsDX.dll) uses quite a number of DLLs extracted from the DevExpress WinForms

Library.

The zObjects.w3 workspace includes a number of objects and examples which require those DevExpress

WinForms DLLs. In general, these objects or example functions include the letters DX or dx in their

names (example: zRichEditDXForm).

In order to be able to use these objects or run these examples you must:

• Either download a 30-day Trial version of the DevExpress WinForms library from:

https://www.devexpress.com/Products/NET/Controls/WinForms/demos.xml

• Or purchase a DevExpress WinForms10 Subscription ($899.99) at:

https://www.devexpress.com/Subscriptions/buy.xml

10 You may alternatively buy any larger Subscription (that includes the WinForms Subscription)

See: https://www.devexpress.com/Subscriptions/