<<

SL-GMS® Developer for ® .NET User’s Guide

SL Corporation®

OBJECT-ORIENTED GRAPHICAL MODELING SYSTEM Version 3.3 --10 June 2010

Part Number DDUG-400610 The information in this document is subject to change without notice and should not be construed as a commitment by the Sherrill-Lubinski Corporation. The Sherrill-Lubinski Corporation assumes no responsibility for any errors that may appear in this document. The software described in this document is furnished under a license and may be used or copied only in accordance with the terms of such license. This software is based in part on the work of the Independent JPEG Group. SL-GMS® Developer for Microsoft® .NET User’s Guide This manual is for use only in connection with the described software and may not be used for any commercial purpose or copied, distributed, sold, displayed, modified, published, or posted in whole or in part without the prior written permission of Sherrill-Lubinski Corporation. SL-GMS, SL Corporation, the SL Logo, and all Sherrill-Lubinski product names referenced in this manual are trademarks or registered trademarks of the Sherrill-Lubinski Corporation; any unauthorized use of these marks is strictly prohibited. All trademarks and registered trademarks referenced in this document are property of their respective companies.

SL-GMS (3.3a) 10 June 2010 Configuration: D33a1_400610

Copyright (c) 1987-2010 Sherrill-Lubinski Corporation. All Rights Reserved.

LIMITATIONS ON USE

Use, duplication, or disclosure by the U.S. Government is subject to restrictions as set forth in the Technical Data - Commercial Items clause at DFARS 252.227-7015, the Rights in Data - General clause at FAR 52.227-14, and any other applicable provisions of the DFARS, FAR, or the NASA FAR supplement.

SL Corporation 240 Tamal Vista Blvd., Suite 110 Corte Madera, CA 94925

TECHNICAL SUPPORT Phone 800.548.6881 (inside U.S.) 415.927.8400 Fax 415.927.8401 E-mail [email protected]

6/17/10 Table of Contents

1. SL-GMS® Developer for Microsoft® .NET User’s Guide Introduction...... 1-1 Why Microsoft .NET? ...... 1-1 How does Visual Studio .NET help? ...... 1-2 How does SL-GMS Developer for Microsoft .NET fit in this environment?...... 1-3 SL-GMSDraw Dynamic Graphic Editor ...... 1-5 Dynamic Graphics ...... 1-7 Using the SL-GMS Microsoft .NET Viewer Control ...... 1-8 Example Scenario ...... 1-8 Summary ...... 1-9 2. Getting Started with SL-GMS® Developer for Microsoft® .NET Introduction...... 2-1 Installation from Download File ...... 2-1 License Types ...... 2-1 Learning to use SL-GMS Developer for Microsoft .NET...... 2-2 A Simple Exercise ...... 2-2 Using the GmsStreamComponent...... 2-12 3. Example Applications SimpleViewer ...... 3-3 SimpleViewer_VB ...... 3-7 SimpleViewer_Cache...... 3-11 Graphs...... 3-15 Interaction ...... 3-23 Browser ...... 3-32 SharePoint SL-GMS Viewer Web Part ...... 3-46 ZoomPan ...... 3-68 AutoZoomMode ...... 3-73 EmbeddedControls ...... 3-77 Dynamic Creation...... 3-86 User Methods ...... 3-89 Variable Binding...... 3-94

Version 3.3 - June 2010 SL-GMS Draw Users Guide page i Version 3.3 - June 2010 SL-GMS Draw Users Guide ii List of Figures

Number Title Page

Figure 1-1: Furnace Model in Visual Studio .NET...... 1-4 Figure 1-2: SL-GMSDraw Displaying Furnace Model...... 1-6 Figure 1-3: Custom Equipment Palette ...... 1-7 Figure 1-4: Symbol Factory Objects Included with SL-GMSDraw...... 1-7 Figure 3-1: SimpleViewer Example Displaying Valve 1 Model...... 3-3 Figure 3-2: SimpleViewer_VB Example Displaying Valve 2 Model ...... 3-7 Figure 3-3: SimpleViewer_Cache Example at startup...... 3-11 Figure 3-4: Graphs Example Displaying a Trend Graph ...... 3-15 Figure 3-5: Graphs Example Pull-Down Menu...... 3-18 Figure 3-6: Interaction Example Displaying Auxiliary Furnace Model...... 3-23 Figure 3-7: Cursor Change and Name Display ...... 3-29 Figure 3-8: Popup menu (2 Entries) ...... 3-30 Figure 3-9: Popup Menu for Named Object ...... 3-30 Figure 3-10: Object Property Dialog ...... 3-31 Figure 3-11: Browser Example Displaying Valve 1 Model ...... 3-32 Figure 3-12: ZoomPan Example ...... 3-68 Figure 3-13: Auto Zoom Mode Example ...... 3-73 Figure 3-14: Embedded Controls Example...... 3-79 Figure 3-15: Dynamic Creation Example...... 3-86 Figure 3-16: User Method Example ...... 3-89 Figure 3-17: Variable Binding Example ...... 3-94

Version 3.3 - June 2010 SL-GMS Draw Users Guide iii Version 3.3 - June 2010 SL-GMS Draw Users Guide iv SL-GMS® Developer for Microsoft® .NET User’s Guide Sherrill−Lubinski ®

Introduction

SL-GMS is known worldwide as the most complete, high performance dynamic graphics system available for real-time monitoring and control applications. SL-GMS is widely used in various industries such as process automation, network monitoring, power distribution and traffic control. Providing products since 1985, SL has maintained the goal of protecting its customers from shifting trends in user interface technologies. SL has helped its customer base retain its investment in user interface implementations, making the transition smooth between such varied technologies as proprietary graphics systems, XWindows, Motif, , MFC, Internet applications, ActiveX, Java, and Microsoft .NET. As technologies change, the SL customer doesn't have to think about entire re-writes of user interfaces. SL-GMS Developer for Microsoft .NET is a graphical development system specifically designed for use with Microsoft’s Visual Studio .NET development environment.

Why Microsoft .NET?

Software product architects in the past often focused on solving a particular focused business problem and created applications highly specified to addressing that point solution. This was effective in that it enabled developers to deliver applications that would be successful at providing needed functionality to a well-defined user. Recognizing that many of these point solutions use common building blocks gave rise to the concept of having common components that would promote re-use of software and reduction of development costs. Technologies such as Microsoft COM, CORBA, and Enterprise Java Beans were developed to address this need for component object brokering between applications. This has been a powerful architectural model for a number of years; however, it can create “application stovepipes” or “islands of information” that cause significant problems in architectural reuse when trying to integrate these applications to implement enterprise-wide business solutions.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 1-1 Today, complex enterprise solutions are being constructed that integrate existing application services that may reside on the local network or are accessible only on the Internet. Older common object model technologies are often not suited for this new type of solution because they are difficult to implement, not scalable, not suited for Internet communication across firewalls, and integrate only with common implementation technologies and platforms. Microsoft .NET resolves many of these issues with .NET server technologies, the facilities for creating Web services, and the ease of building distributed clients with Visual Studio .NET. The trend in enterprise solutions is to move from a strictly server-client paradigm to a distributed-computing paradigm composed of loosely coupled services that could reside on any smart device anywhere on a local network or on the Internet. The Microsoft .NET platform is clearly a competitive implementation technology option for new solutions in which either software services, Web services or clients can be restricted to the Microsoft .NET platform. ISV's who have already implemented legacy products using Microsoft technologies must struggle with the decision over which products must be migrated from strictly COM-based technologies to .NET, to be commercially viable in a world that seeks open standards and ease of integration in a distributed enterprise environment.

How does Visual Studio .NET help?

While Visual Studio .NET provides tools that assist in creating new Web services or exposing existing code as a Web service, we wish to focus on the features that make it optimal for creating distributed user interface clients. When building Web service clients, Visual Studio .NET provides classes to support writing, reading, and validation of XML, as well as the capability of recognizing existing Web services and automatically generating a proxy class that exposes the Web service interfaces as simple methods. Other ease-of-use features for data connectivity include classes to support TCP/UDP, HTTP, and sockets. Visual Studio .NET also has many features that make it easier to develop applications including: • Common language run-time that supports many languages with a consistent type system and class hierarchy • Assemblies that manage units of deployment and version control

Version 3.3 - June 2010 SL-GMS Draw Users Guide 1-2 • Easy form building features for both standard applications and web-based applications • Network deployment in a variety of service and client configurations • Security built into the run-time environment • Features that support wireless client development

How does SL-GMS Developer for Microsoft .NET fit in this environment?

SL-GMS Developer for Microsoft .NET contains the following: • SL-GMSDraw Dynamic Graphic Editor • SL-GMS Microsoft .NET Viewer control • Symbol libraries • Application examples • Documentation SL-GMS Developer for Microsoft .NET allows users to rapidly create dynamic graphic displays using the SL-GMSDraw Dynamic Graphic Editor. Non-programmers can configure displays with pre-defined components or design and animate their own components. These displays can be previewed with simulated data from within SL-GMSDraw. SL-GMS Developer for Microsoft .NET also provides a custom .NET control that can be used in Visual Studio .NET to create .NET applications that render these displays in a Windows Forms based application for use on the desktop or for browser-based Internet interfaces.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 1-3 Figure 1-1: Furnace Model in Visual Studio .NET SL-GMS Developer for Microsoft .NET takes advantage of the powerful development environment provided in Visual Studio .NET, that allow for rapid development of both standard applications and web-based applications. Because the custom .NET control can be easily used in this development environment, these applications can also take advantage of the rich support .NET provides for driving these displays from distributed data services. For example, a plant floor operations control application could be driving the display from an OPC server, an SQL database, or from proprietary SCADA or DCS data systems. Another web-based application could be using the same user interface, with data from an OPC-XML or other Web service. SL-GMS Developer for Microsoft .NET is a fully .NET compliant real-time graphics development system.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 1-4 • Enabled with classes, methods, properties, and events from within Microsoft Visual Studio .NET • Usable with any .NET supported language including C++, C#, or Visual Basic • Provides current SL-GMS users a supported migration path to .NET

SL-GMSDraw Dynamic Graphic Editor

SL-GMSDraw is a sophisticated graphic editor that facilitates the construction of dynamic graphic models. SL-GMSDraw provides tools that allow the user to specify an object’s dynamic behavior and the variables that drive that behavior. Dynamic behaviors can be tested within the editor to ensure proper operation before using them in an application. SL-GMSDraw is a Windows/MFC-based editor that provides advanced features, such as snap and point modes, alignment tools, object ordering tools, object reference point tools, and point editing. It also provides standard editing features, such as cut, copy, paste, undo, redo, toolbars, tooltips, and pop-up menus.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 1-5 Figure 1-2: SL-GMSDraw Displaying Furnace Model SL-GMSDraw is often used to develop libraries of dynamic symbols and graphic elements that are collected in palettes for easy use. Such symbols and graphic elements can be constructed from simple graphic primitives and shapes. There is no limit to the number of hierarchical levels that can be used to build a model. An object can be part of a group that is also a part of another group, and a model can be used as a part in another model. SL-GMSDraw can also import graphics from a number of different sources including AutoCAD and Windows metafiles such as Visio vector drawings, as well as JPEG and BMP image formats.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 1-6 LABEL 1 LABEL

LABEL LABEL

LABEL

Figure 1-3: Custom Equipment Palette

Figure 1-4: Symbol Factory Objects Included with SL-GMSDraw

Dynamic Graphics

SL-GMSDraw also provides the ability to define dynamic changes to graphic objects in response to changes in data variables. A robust library of basic functionality is provided for the management of dynamic graphics and the control of user interaction. Objects in the graphical model are automatically changed at runtime to reflect the state of application-specific

Version 3.3 - June 2010 SL-GMS Draw Users Guide 1-7 data variables. The dynamic behavior library uses proven, tested, and efficient techniques for storage of model files, object extent processing, execution of dynamic properties, redraw operations, and much more. Dozens of dynamic behaviors are available that are controlled through application variables and events including: • real-time movement, rotation, scaling, and path traversal • percent fill of irregular objects • visibility and detectability change • text label, formatting, and alignment change • fill color and style change • edge color, width, and style change Dynamic behaviors that change object properties are triggered by data thresholds that are defined using constants or variables.

Using the SL-GMS Microsoft .NET Viewer Control

The SL-GMS Microsoft .NET Viewer control can be instanced from the Visual Studio .NET control toolbar and inserted into Windows Forms based applications using any .NET supported language. The control is then sized and positioned in the Windows form and will be used to display the graphic models built with SL-GMSDraw and animate them with live data. Changing the value of the control's ModelName property changes the model displayed. Thus a single control can display many different models. The variables that drive a particular model's dynamic behaviors are obtained using the control's methods. These variables can then be driven by other .NET controls or data acquired by the container application.

Example Scenario

With the wide variety of servers and support for creating Web services and clients with the Microsoft .NET environment, there can be any number of architectural designs for creating a distributed system. One possible scenario for process control might unfold as follows:

Version 3.3 - June 2010 SL-GMS Draw Users Guide 1-8 • End-users build up displays with SL-GMSDraw, using palettes of common process symbols. Each symbol has one or more variables that drives its dynamic behavior. • In SL-GMSDraw, variables for each symbol are “re-named” to specific real data tagnames. The tagnames differentiate the symbols from each other and associate each symbol with a particular piece of real equipment. • As each display is loaded into the SL-GMS Microsoft .NET Viewer control using the Viewer.ModelName property, the variable tagnames are retrieved using Viewer.ModelManager.Model.Variables[].Name( ). • Using the tagnames as keys, the container application then queries the data source for the current values. • The application can create Gms variables of the appropriate type and associate them with this tag: Viewer.ModelManager.Model.Variables[“tag1”] = new GMSIntegerVariable(initial_value). • The application can then use the Value property of GMSIntegerVariables to update the value of each variable in the display. • The Viewer control automatically determines the necessary graphic updates based on the new values.

Summary

While Microsoft .NET and Visual Studio .NET resolve many enterprise development issues with their .NET server technologies, there are still challenges to developing commercially viable applications in a world that has come to expect open standards and ease of integration in a distributed enterprise environment.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 1-9 SL-GMS Developer for Microsoft .NET: • enables the creation of rich user interface displays by non-programmers • offers high performance • allows for the distribution of these displays with multiple data sources across the enterprise • Development of a system that meets these requirements would take many man-years of development effort with Visual Studio .NET alone. SL-GMS Developer for Microsoft .NET can reduce this effort to a matter of man-months rather than years, expediting time-to-market.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 1-10 Getting Started with SL-GMS® Developer for 2 Microsoft® .NET

Introduction

SL-GMS Developer for Microsoft .NET is available on CD-ROM media, and as a download file from the SL Corporation web site. Installation and setup procedures for the CD-ROM version are provided in the CD liner.

Installation from Download File

The download file is an executable file that is downloaded from SL Corporation’s web site. Save the file to a local directory, then execute the file and follow the instructions as they are presented on the screen. You will be prompted to run the registration program and contact SL Corporation for a software license.

License Types

SL-GMS Developer for Microsoft .NET is available with a development license or a run-time license. A development license allows three activities: 1. Use of the GmsViewer and GmsStreamComponent within Visual Studio 2. Use of the GMSDraw editor to build graphical models 3. Execution of applications using the controls and models The run-time license allows execution only of applications that use the controls with pre-built models. A separate software license is necessary to activate the GMSEditor control, which is used to create custom graphical editors. Web Licensing Web licensing is simple to implement. A program uses web licensing when it is run from a web server (via a web page in a browser) and the program sets the GmsSystem.ServerKeys property during the GmsSystem.Initializing event. A PIN and web key are needed for a web

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-1 Getting Started with SL-GMS® Developer for Microsoft® .NET

server to use web licensing with SL-GMS. The web server should be the server which will host web pages containing the SL-GMS .NET control(s). The Browswer Example contains details on implementing web licensing.

Learning to use SL-GMS Developer for Microsoft .NET

The following steps comprise a recommended course of action for becoming productive quickly with SL-GMS Developer for Microsoft NET. 1. Install SL-GMS Developer for Microsoft .NET 2. Run all of the example applications and study the documentation provided for each in Chapter 3 of this document. 3. Work all exercises in the SL-GMSDraw Tutorial. 4. Work through “A Simple Exercise” in this chapter. 5. Become familiar with all documentation provided with SL-GMS Developer for Microsoft .NET: • User’s Guide • SL-GMSDraw Tutorial • SL-GMSDraw User’s Guide • SL-GMSDraw Reference

A Simple Exercise

This exercise creates a very simple application that uses the viewer control provided with SL-GMS Developer for Microsoft .NET. Several assumptions are made in order to keep the exercise simple and focused. The application uses only one model whose name is known and set in the viewer’s ModelName property. The model uses only one variable to drive a simple dynamic, and its name is known and coded in the application. The steps provided show how to: • Add controls to the Visual Studio .NET Toolbox so they are ready to use when needed • Create a Visual C# project and customize its settings • Create an instance of the GmsViewer control and set its properties so that a model is loaded automatically at run-time

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-2 Getting Started with SL-GMS® Developer for Microsoft® .NET

• Create an instance of a timer that is used to manipulate the variable that drives the dynamic behavior of a simple SL-GMS model • Create a simple model using SL-GMSDraw that uses a fill percent dynamic driven by a variable to change the fill level of a rectangle • Build and run the application to observe the dynamic behavior Add Controls to the Visual Studio .NET Toolbox 1. Start Visual Studio .NET 2. Add the SL-GMS controls and components to the Visual Studio Toolbox: a. Click on the View > Toolbox menu item to open the Toolbox, then right click within the Toolbox and select Add/Remove Items. (You may wish first to “Add Tab” to create an SL-GMS-specif- ic Toolbox tab.) b. Click Browse and navigate to the SL-GMS installation direc- tory (normally %PROGRAMFILES%\SL Corporation\SL-GMS ). Navigate to the bin sub-directory. c. Double-click SL.GMS.Windows.Forms.dll to add GmsView- er to the Toolbox. d. Double-click SL.GMS.IO.dll to add GmsStreamComponent to the Toolbox. (Note: this will also add GmsWriteCompo- nent; however this component is not used by GmsViewer.) e. Click OK. Create a Project in Visual Studio .NET 1. Start Visual Studio .NET 2. Create a new project 3. In the New Project dialog Select Visual C# Projects in the left pane Select Windows Application in the right pane

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-3 Getting Started with SL-GMS® Developer for Microsoft® .NET

Set Name to MyProj1 Set Location to a suitable directory such as C:\ Click OK 4. Enlarge Form1 to make room for an instance of the viewer. A size of approximately 760x600 should be sufficient for this example. This is only a suggested size. Exact width and height values can be entered in the form’s Size property.

5. Add references to the solution for SL.GMS.dll, SL.GMS.Drawing.dll, SL.GMS.Internal.dll, SL.GMS.IO.dll, and SL.GMS.Windows.Forms.dll. a. In the Add Reference window (Project > Add Reference), click Browse and navigate to %GMS_HOME%\bin b. Select SL.GMS.dll SL.GMS.Drawing.dll

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-4 Getting Started with SL-GMS® Developer for Microsoft® .NET

SL.GMS.Internal.dll SL.GMS.IO.dll SL.Windows.Forms.dll c. Select Open, then OK. 6. Select GmsViewer from the General tab of the toolbox. 7. Create an instance of the GmsViewer in Form1 that is approximately 420x400 and centered on the form. This is only a suggested size. Exact width and height values can be entered in the viewer’s Size property.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-5 Getting Started with SL-GMS® Developer for Microsoft® .NET

8. Select the timer control in the Windows Forms tab of the toolbox. 9. Create one instance of the timer. 10. Set Enabled property for timer to True and the Interval property to 200. 11. Double-click on the control to bring up the file Form1.cs. 12. Add the following variable to the Form1 class variables after the components variable. private int ivalue = 0; private SL.GMS.Drawing.GmsIntegerVariable gmsVar = new SL.GMS.Drawing.GmsIntegerVariable(0);

13. In the constructor after the “TODO” comment, add the following line: gmsViewer1.ModelName = “model1”; gmsViewer1.ModelManager.Model.Variables[“var1”] = gmsVar;

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-6 Getting Started with SL-GMS® Developer for Microsoft® .NET

14. Double-click on the timer in design mode to create the timer1 callback. 15. Add the following code to timer1_Tick( ): ivalue = ivalue + 5; if (ivalue > 100) ivalue = 0; gmsVar.Value = ivalue; gmsViewer1.UpdateGraphics();

16. Add code to close the control when the form is closed.

Click on the form in design view to select it. Click on the Events button in the Properties window. Double-click on the Closed event to add an empty method, then add the following code to the Form1_Closed( ):

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-7 Getting Started with SL-GMS® Developer for Microsoft® .NET

// Explicitly dispose of gmsViewer when closing containing form gmsViewer1.Dispose(); gmsViewer1 = null;

17. Select Build Solution from the Build menu.

Build a Simple Model 1. Start gmsdraw_mfc from the program menu. 2. Select New with Background from the File menu to create a new model. 3. Select Properties from the Model menu. 4. Set the Background Color field in the Model Properties window to 14.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-8 Getting Started with SL-GMS® Developer for Microsoft® .NET

5. Create a filled rectangle in the middle of the model.

6. Click on the rectangle to select it if it is not already selected. 7. Select Object Dynamic Properties from the Dynamics menu to activate the Object Dynamic Properties window.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-9 Getting Started with SL-GMS® Developer for Microsoft® .NET

8. Click the Templates check box which expands the window to show a series of tabs. 9. Click the Fill tab.

10. Double-click the Fill Percent template, which will copy the template to the input field with its driving variable highlighted.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-10 Getting Started with SL-GMS® Developer for Microsoft® .NET

11. Replace the highlighted variable REAL with the variable var1. 12. Click the Apply button in the Object Dynamic Property window. 13. Save the model in the project directory with the name model1. Example E:\MyProj1\model1.m1 Test the Application in Visual Studio .NET 1. Switch to Visual Studio .NET. 2. Use File->Close Solution to close MyProj1 3. Use File->Open Solution to re-open MyProj1 Note: These steps insure that the correct directory is set properly in Visual Studio .NET. Otherwise a FileNotFoundException may occur if the GmsViewer fails to find the model.

4. In Visual Studio .NET press F5 or select Start from the Debug menu.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-11 Getting Started with SL-GMS® Developer for Microsoft® .NET

The rectangle should be seen dynamically changing its fill levels.

Using the GmsStreamComponent

The GmsStreamComponent allows you to locate and stream data from local and remote sources into an SL-GMS control. The stream component locates data via a path, and streams the data from the source into the SL-GMS control via the protocol specified in the path. The data can include SL-GMS Models and SubModels, as well as images, data files, and the like. Each GmsStreamComponent path is formatted as a URL (Universal Resource Locator) that specifies both a location and a protocol, such as: file://C:/SL-GMS/Models/ The path may contain either ‘/’ or ‘\’ as separator characters, and must end with a trailing separator. It may contain references to environment vari- ables, bracketed by ‘%’, such as:

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-12 Getting Started with SL-GMS® Developer for Microsoft® .NET

file://%GMS_HOME%/demo.net/SimpleViewer/

To use a GmsStreamComponent in a Windows.Forms application, drag it from the Visual Studio toolbox onto the Form and access its properties to set up its path list. This list can also be accessed at run time, as illustrated below. Paths An application can manipulate the list of paths in the stream component at run time. For example, an application presenting a file browser dialog to locate SL-GMS Model files should insure that the path to the chosen model file is included in the stream component at the time the model is opened by the control. Since the open file dialog sets the application’s current directory according to where the file was selected, upon return from the dialog the application might simply say:

string directory = Directory.GetCurrentDirectory(); string currentDirectoryPath = @"file://" + directory + Path.DirectorySeparatorChar; gmsStreamComponent.Paths.Insert(0, currentDirectoryPath );

Protocols Standard protocols such as file: and http: are supported, and applications may register custom protocols. For example, the SL-GMS control imple- ments and registers a protocol called relpath:, a modified file: protocol that allows the specification of paths relative to the application’s current directory. The relpath: protocol is implemented as follows:

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-13 Getting Started with SL-GMS® Developer for Microsoft® .NET

///

/// Factory class for RelPathWebRequest, specified as a /// URI relative to the application's Current Directory /// public class RelPathWebRequest: IWebRequestCreate { public RelPathWebRequest() { }F

public WebRequest Create(Uri uri) { string path = Directory.GetCurrentDirectory() + "\\" + uri.Host + uri.LocalPath; return WebRequest.Create( @"file://" + path ); } }

The protocol is registered with the system as follows:

WebRequest.RegisterPrefix( ”relpath”, new RelPathWebRequest() );

An application could use this protocol to specify that whenever a Model is opened in a given directory, the stream component will also look in the sub-directory submods: relpath://./submods/

Custom protocols could be used to meet a variety of application-specific needs, such as: • Working with a specific database or data transfer protocol • Interfacting with a Revision Control System. • Maintaining a local cache of remote files Compatibility In order to provide backward compatibility with previous versions of SL-GMS, the SL-GMS control will use a default GmsStreamComponent if the application does not provide one. This default stream component will

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-14 Getting Started with SL-GMS® Developer for Microsoft® .NET

read Model and SubModel files from the following locations using the file: protocol: 1. The current directory 2. The default SubModel subdirectories of the current directory

.\gismos\, .\graphs\, .\submods\

3. The default SubModel directories on the same level as the current directory

..\gismos\, ..\graphs\, ..\submods\

4. Standard SL-GMS model directories that are relative to the directory where SL-GMS Developer for Microsoft .NET has been installed.

lib, lib\SUBMODS, demo\gismos\GISMOS, demo\graphs\GRAPHS, demo\models\SUBMODS, work\gmsrun\GISMOS, work\gmsrun\BITMAPS, work\gmsrun\MODELS

NOTE: The above list does not include subdirectories where Visual Studio .NET executable files are commonly placed, such as bin\Debug and bin\Release. SL-GMS model files can be placed in the appropriate bin subdirectory, or the Visual Studio .NET project can be modified to change where the executable file is placed.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 2-15 3 Example Applications

SL-GMS Developer for Microsoft .NET is shipped with several examples that illustrate how to use the SL-GMS Microsoft .NET Viewer control and its features. • SimpleViewer This example shows how to display a model in the viewer control using C# and how to attach data that animates the model. • SimpleViewer_VB This example shows how to display a model in the viewer control using Visual Basic and how to attach data that animates the model. • SimpleViewer_Cache This example shows how to display a model in the viewer control using a memory cache of models for switching models. • Graphs This example shows how to use SL-GMS graphs and attach data to animate them. • Interaction This example shows how to enable interaction with objects in a model displayed by the viewer using C#. • Browser This example shows how to deploy an application that uses the SL-GMS Microsoft .NET Viewer control in a . • WebService1 This example is used with the Browser example and shows how to drive a web-based application with web services data. • SharePoint The SPViewer Web Part demo shows how the SL-GMS Viewer Control for .NET can be used to display and animate dynamic SL-GMS Models in web pages delivered using Microsoft Windows SharePoint Products and Technologies.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-1 Example Applications

• ZoomPan This example demonstrates different ways to use the ViewManager to implement various zooming and panning methods. • AutoZoomMode This example demonstrates the effect that AutoZoomMode has on zoom and pan functionality. • EmbeddedControls This example shows the use of EmbeddedControls, which are .NET controls existing as part of the GMS model. These controls may be the .NET controls provided in palettes in SL-GMSDraw for .NET or they may be third party .NET controls. • Dynamic Creation In most cases, objects are created and attributes are set from within SL-GMSDraw, a model is saved and that model is then loaded into a GMSViewer control. In some cases however it is desired to dynamically instantiate objects at run time based on data or some event. This example shows how to programmatically instance any GMS object and query and set their attributes. • UserMethods This example shows how to create user defined methods which are written in any .NET supported language and can be added to GMSObject dynamics. User defined methods are used when trying to describe built in behavior which may happen to user input on an object and it is also used when it is desired to change object attributes on an object as data changes via a written Visual Studio.net method rather than using the SL-GMS dynamic scripting language • VariableBinding The simplest way to define GMSVariables is demonstrated in the SimpleViewer examples. This example shows an advanced way to look at each object as it is being loaded, examine information about that object and its variables and use that information to determine how variables will be defined that animate that object. This technique is often used when it is desired to create a variety of hierarchical templates that can resolve variable binding by giving only one unique identifier to the top level template rather than describing the fully qualified tag name for the data on each dynamic object.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-2 Example Applications

SimpleViewer

The SimpleViewer example shows basic use of the SL-GMS Microsoft .NET Viewer control in a C# environment. Essential properties and methods are used to control the display of two valve models and animate them with data.

Figure 3-1: SimpleViewer Example Displaying Valve 1 Model Features Demonstrated • How to switch models using the ModelName property • How to use a timer to trigger data updates • Basic query/set data operations using the ModelManager.Model.Variables and GmsVariable properties and methods Form Contents Form1 contains two buttons, five labels, one scroll bar, and one instance of the SL-GMS Microsoft .NET Viewer control.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-3 Example Applications

• button1 - displays top_valve1 model when clicked • button2 - displays top_valve2 model when clicked • label1 - contains the text “Slow” • label2 - contains the text “Update Speed” • label3 - contains the text “Fast” • label4 - The text for this object is changed by hScrollBar1. The initial text is set to “250 ms”. • label5 - contains the text “Delay :” • hScrollBar1 - adjusts the Interval property for timer1 • timer1 - a timer with an initial Interval of 250 ms Models top_valve1 - contains a background rectangle and one instance of the valve1 model top_valve2 - contains a background rectangle and one instance of the valve2 model valve1 - graphic model for a plug valve valve2 - graphic model for a gate valve Viewer Properties Default properties are used. AntiAliasMode = none This can be set if it is desired to use Anti-aliasing to draw the graphics. This effect provides smoother drawing of graphical objects. This incurs a performance hit so it can be restricted to some types of objects or enabled for all objects. DataSimulatorFile = null If set to a file name, it would load a *.dat file whenever a model containing the standard GMS-simulated data syntax is loaded, which would be used to drive simulated data in the loaded model. DoubleBuffer = none Usually this is set to Redraw, which ensures proper redraw and no flicker

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-4 Example Applications

for updates, but if the dynamics of the model are optimized so that double buffering is unnecessary, this can be turned off. GmsRasterTextMode = SL.GMS.RasterTextMode.Rotatable (Fixed, Rotatable) ModelName = null Name = "gmsViewer1" Renderer = GDI GDI or GDI+ is used to render graphics. ResizeControls = false Native controls in the model will not resize if the size of the viewer is changed. ResizeStyle = SL.GMS.ResizeStyle.Fit The style used to fit a model in the control (Fit, Scale, Crop) ViewManager.AutoZoomMode = FitModel This places the viewer into the mode that automatically tries to fit the model into the viewing area when zooming. ViewManager.LoadAlignment = MiddleCenter Indicates how to align the model when loading. ViewManager.ResizeAlignment = MiddleCenter Indicates how to align the model when resizing a window. ViewManager.Zoom= 100 Default zoom level. ViewManager.ZoomLimits = 10 1000 Minimum and maximum zooms allowed. ViewManager.ZoomPanReverse = Alt Accelerator key which reverses a zoom or pan operation. Data The data source for ViewDemo1, defined in “Datasource.cs”, is a simple simulation data source that maintains a private table of data variables. The SetupVariables( ) method initializes the variables found in the model. The Datasource1 class Timer Update changes the values of all data variables.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-5 Example Applications

Timer The timer in Datasource.cs is configured to expire every 250 ms. Each time the timer expires it updates the variables contained in ModelManager.Model.Variables[] with simulated values and then calls UpdateGraphics( ) to update the display with the new data values. The timer interval, which is controlled by the slider, is changed by calling the datasource.TimerInterval method. Building SimpleViewer To build the SimpleViewer example, load the project solution file, “SimpleViewer.sln”, into Visual Studio .NET. Use the Build command to build the executable. Running SimpleViewer From Visual Studio .NET select Debug->Start Without Debugging or Ctrl+F5 to execute the example. From a properly configured Command Prompt window, cd to the SimpleViewer directory and execute one of the following batch files: run_rel (to run the release version) run_dbg (to run the debug version)

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-6 Example Applications

SimpleViewer_VB

The SimpleViewer_VB example shows basic use of the SL-GMS Microsoft .NET Viewer control in a VisualBasic environment. Essential properties and methods are used to control the display of two valve models and animate them with data.

Figure 3-2: SimpleViewer_VB Example Displaying Valve 2 Model Features Demonstrated • Switching models using the ModelName property • How to use a timer to trigger data updates • Basic query/set data operations using the ModelManager.Model.Variables and GmsVariable properties and methods Form Contents Form1 contains two buttons, five labels, one scroll bar, and one instance of the SL-GMS Microsoft .NET Viewer control.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-7 Example Applications

• button1 - displays top_valve1 model when clicked • button2 - displays top_valve2 model when clicked • label1 - contains the text “Slow” • label2 - contains the text “Update Speed” • label3 - contains the text “Fast” • label4 - text for this object is changed by hScrollBar1. The initial text is set to “250 ms”. • label5 - contains the text “Delay :” • hScrollBar1 - adjusts the Interval property for timer1 • timer1 - a timer with an initial Interval of 250 ms Models top_valve1 - contains a background rectangle and one instance of the valve1 model top_valve2 - contains a background rectangle and one instance of the valve2 model valve1 - graphic model for a plug valve valve2 - graphic model for a gate valve Viewer Properties Default properties are used. AntiAliasMode = none This can be set if it is desired to use Anti-aliasing to draw the graphics. This effect provides smoother drawing of graphical objects. This incurs a performance hit so it can be restricted to some types of objects or enabled for all objects. DataSimulatorFile = null If set to a file name, it would load a *.dat file whenever a model containing the standard GMS simulated data syntax is loaded, which would be used to drive simulated data in the loaded model. DoubleBuffer = none Usually this is set to Redraw, which ensures proper redraw and no flicker

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-8 Example Applications

for updates but if the dynamics of the model are optimized so that double buffering is unnecessary, this can be turned off. GmsRasterTextMode = SL.GMS.RasterTextMode.Rotatable (Fixed, Rotatable) ModelName = null Name = “gmsViewer1” Renderer = GDI GDI or GDI+ is used to render graphics. ResizeControls = false Native controls in the model will not resize if the size of the viewer is changed. ResizeStyle = SL.GMS.ResizeStyle.Fit The style used to fit a model in the control (Fit, Scale, Crop) ViewManager.AutoZoomMode = FitModel This places the viewer into the mode that automatically tries to fit the model into the viewing area when zooming. ViewManager.LoadAlignment = MiddleCenter ViewManager.ResizeAlignment = MiddleCenter ViewManager.Zoom = 100 Default zoom level. ViewManager.ZoomLimits = 10 1000 Minimum and maximum zooms allowed. ViewManager.ZoomPanReverse = Alt Accelerator key which reverses a zoom or pan operation. Data The data source for SimpleViewer_VB, defined in “Datasource.vb”, is a simple simulation data source that maintains a private table of data variables. The SetupVariables( ) function initializes the variables found in the model. The Datasource Timer Update changes the values of all data variables.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-9 Example Applications

Timer The timer in Datasource.vb is configured to expire every 250 ms. Each time the timer expires, it updates the variables contained in ModelManager.Model.Variables[] with simulated values and then calls UpdateGraphics( ) to update the display with the new data values. The timer interval, which is controlled by the slider, is changed by calling the datasource.TimerInterval function. Building SimpleViewer_VB To build the SimpleViewer_VB example, load the project solution file, “SimpleViewer_VB.sln”, into Visual Studio .NET. Use the Build command to build the executable. Running SimpleViewer_VB From Visual Studio .NET, select Debug->Start Without Debugging or Ctrl+F5 to execute the example. From a properly configured Command Prompt window, cd to the SimpleViewer_VB directory and execute one of the following batch files: run_rel (to run the release version) run_dbg (to run the debug version)

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-10 Example Applications

SimpleViewer_Cache

The SimpleViewer_cache example is a copy of the SimpleViewer example with some minor modifications. This example uses new events to set up a memory cache of the models and submodels used. Timing statistics are calculated for the length of time it takes to switch between models. From this, it can be determined whether or not the cache improves performance.

Figure 3-3: SimpleViewer_Cache Example at startup Features Demonstrated • How to use the InstanceModelFileFinding and InstanceModelFileFound events • How to create a memory cache of models for an application that does frequent model switching Form Contents Form1 contains two group boxes, one scroll bar, nine labels, one button, one combo box, one check box and one instance of the SL-GMS Microsoft .NET GmsViewer control.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-11 Example Applications

• groupBox1 - contains the model switching controls • groupBox2 - contains the data update period controls • button2 - switches between the top_valve1 and top_valve2 models a specified number of times • comboBox1 - specifies the number of times (repetitions) that the models will switch when button2 is pressed • label1 - contains the text "Slow" • label2 - contains the text "Elapsed Time (sec):" • label3 - contains the text "Fast" • label4 - contains the number of seconds elapsed. The initial text is set to "0". • label5 - contains the text "Delay:" • dataLabel - the text for this object is changed by dataScrollBar. The initial text is set to "250 ms". • dataScrollBar - adjusts the TimerInterval property of the datasource object • label6 - contains the text "Repetitions:" • label7 - contains the average elapsed time in seconds. The initial text is set to "0". • label8 - contains the text "Average Time (sec):" • checkBox1 - enables or disables the memory cache Models top_valve1 - contains a background rectangle and one instance of the valve1 model top_valve2 - contains a background rectangle and one instance of the valve2 model valve1 - graphic model for a plug valve valve2 - graphic model for a gate valve

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-12 Example Applications

Functional Differences The TimerEnabled property was added to Datasource.cs to allow the data update timer to be disabled while switching the models. ///

/// Gets or sets whether the datasource timer is enabled. /// public bool TimerEnabled { get { return this.dataUpdateTimer.Enabled; } set { this.dataUpdateTimer.Enabled = value; } }

Event handlers were added to handle the new InstanceModelFileFinding and InstanceModelFileFound events. The InstanceModelFileFinding event is used to return a cached model if it is found in the cache. The InstanceModelFileFound event is used to add a model to the cache if it isn't already there. void gmsViewer1_InstanceModelFileFinding( object sender, ModelFileFindEventArgs e ) { // Ignore built-in files, we aren't caching them or overriding them. if (!e.IsBuiltInFile) { if (fileCache.ContainsKey( e.FullFileName )) { // We found it in our cache. e.Stream = new MemoryStream( fileCache[e.FullFileName] ); e.IsFound = true; } } }

void gmsViewer1_InstanceModelFileFound( object sender, ModelFileFindEventArgs e ) { // The file has been found by GMS. Cache it in memory if it isn't // already AND it isn't a GMS built-in file. GMS built-in files are // already cached by GMS.

if (!e.IsBuiltInFile) { // If it doesn't already exist in cache, add it if (!fileCache.ContainsKey( e.FullFileName ))

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-13 Example Applications

{ fileCache[e.FullFileName] = e.Stream.ToArray(); } } } How it works The first time a model is opened, SL-GMS finds the file on disk and opens it. The InstanceModelFileFound event handler then adds a byte array containing the model to a memory cache. The next time SL-GMS searches for that model file, the InstanceModelFileFinding event handler sees that it is in the cache and returns it to SL-GMS through the ModelFileFindEventArgs.

The InstanceModelFileFinding and ModelFileFinding events are equivalent and the InstanceModelFileFound and ModelFileFound events are equivalent. The "Instance" events are for a specific GmsViewer or GmsEditor instance while the other events are for ALL GmsViewer and GmsEditor controls. This allows an application to handle these events at the desired granularity.

Building SimpleViewer_cache To build the SimpleViewer_cache example, load the project solution file, “SimpleViewer_cache.sln”, into Visual Studio .NET. Use the Build command to build the executable. Running SimpleViewer From Visual Studio .NET select Debug->Start Without Debugging or Ctrl+F5 to execute the example. From a properly configured Command Prompt window, cd to the SimpleViewer_cache directory and execute one of the following batch files: run_rel (to run the release version) run_dbg (to run the debug version)

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-14 Example Applications

Graphs

The Graph example shows how to use SL-GMS graphs in the model displayed by the SL-GMS Microsoft .NET Viewer.

Figure 3-4: Graphs Example Displaying a Trend Graph Features Demonstrated • Use of graph Models from the SL-GMS Graph Library • Use of data simulation files Form Contents Form1 contains two buttons, five labels, one scroll bar, and one instance of the SL-GMS Microsoft .NET Viewer control. • menuItemGraphs - first item in the pull-down menu • label1 - contains the text “Slow” • label2 - contains the text “Update Speed”

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-15 Example Applications

• label3 - contains the text “Fast” • label4 - text for this object is changed by hScrollBar1. The initial text is set to “250 ms”. • label5 - contains the text “Delay :” • hScrollBar1 - adjusts the Interval property for timer1 • timer1 - a timer with an initial Interval of 250 ms • mainMenu1 - the pull-down menu Models start - Initial model with instructions xclustbar - model with one cluster bar graph instance xcustom - model with a custom graph xdiffbar - model with a differential bar graph xhbarshift - model with horizontal bar trend graphs xhorizbar - model with horizontal bar graphs xhtrend - model with trend graphs xhtrendbar - model with horizontal trend bar graphs xlineplot - model with line plot graphs xlinlog - model with linear-logarithmic graphs xloglog - model with logarithmic graphs xmarkline - model with mark/line graphs xpie - model with pie graphs xradial - model with a radial/polar graph xscatter - model with a scatter graph xstackbar - model with a stacked bar graph xtimeplot - model with a time axis graphs xvtrend - model with vertical trend graphs xvtrendbar - model with vertical trend bar graphs

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-16 Example Applications

Viewer Properties Default properties are used. Data All models in the Graphs example use data simulation files (also known as “.dat” files) to drive the variables that animate the graphs. Further information about the format and use of “.dat” files is provided in the Dynamics chapter and the Dynamics Reference appendix of the SL-GMSDraw Reference. The viewer property UseDataSimulator turns the data simulator on and off. The model name is used as the default name for the data simulation file, but this can be overridden with the DataSimulationFile property. Timer The timer in form1 is initially configured to expire every 250 ms. Each time the timer expires it causes the data simulator and the datasource to update and then tells the viewer to update the model.

if (gmsViewer1.UseDataSimulator) { gmsViewer1.UpdateDataSimulator(); }

datasource1.Update();

if (datasourceMediator != null) { datasourceMediator.Update(); }

gmsViewer1.UpdateGraphics(); Warnings, Errors, and Control Disposal Warnings and errors generated by the control as well as disposing of the control when the form is closed is handled with the same code that is described in steps 15 - 17 of the Getting Started exercise.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-17 Example Applications

Building Graphs To build the Graphs example, load the project solution file, “Graphs.sln”, into Visual Studio .NET. Use the Build command to build the executable. Running Graphs From Visual Studio .NET, select Debug->Start Without Debugging or Ctrl+F5 to execute the example. From a properly configured Command Prompt window, cd to the Graphs directory and execute one of the following batch files: run_rel (to run the release version) run_dbg (to run the debug version)

Once Graphs is running, select the desired graph from the pull-down menu.

Figure 3-5: Graphs Example Pull-Down Menu

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-18 Example Applications

Graph Library The SL-GMS Graph Library includes examples of logarithmic, date/time GraphAxes, pie charts, radial Graphs, clustered bar Graphs, and stacked bar Graphs.The Graphs are provided as submodels which are instanced into top-level models and configured through their renamed variables. The SL-GMS Graph Library contains the following graphs: bundle - 10 bars: 2 bars: 2 traces clustbar - 4 traces: 4 offset bars diffbar - 4 traces: 2 differential bars, 1 bar, and 1 lineplot hbarshift - 1 trace: horizontal trending bar hltrendbar - 1 trace: horizontal left-trending line-bar horizbar - trace: horizontal bars hrtrendbar - 1 trace: horizontal right-trending line-bar htrend - 1 trace: horizontal trending line htrend2 - 2 traces: horizontal trending lines lineplot - 1 trace: line lineplot4 - 4 traces: lines linlog - 1 trace: line; linear x - logarithmic y axes linlog4 - 4 traces: lines; linear x - logarithmic y axes loglin - 1 trace: line; linear y - logarithmic x axis loglog - 1 trace: line; logarithmic x - logarithmic y axes loglog4 - 4 traces: lines; logarithmic x - logarithmic y axes markline - 1 trace: marker-line markline4 - 4 traces: marker-lines pie6 - 6 segments: pie chart with labeled segments radial - 1 trace: radial line radial4 - 4 traces: radial lines scatter - 1 trace: markers

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-19 Example Applications

scatter4 - 4 traces: markers stackbar - 4 traces: 4 stacked bars stock2vol1 - 3 traces: two hi-lo-close traces, 1 bar trace, date axis stockprice - 1 trace: line, arrow indicator, time axis timetrnd - 1 trace: line, time-based trend Graph with X axis labels in hh:mm:ss and 12 hour format tplt_hm12 - 1 trace: line, x axis displayed in hh:mm and 12 hour format tplt_hm24 - 1 trace: line, x axis displayed in hh:mm and 24 hour format tplt_hms12 - 1 trace: line, x axis displayed in hh:mm:ss and 12 hour format tplt_hms24 - 1 trace: line, displayed in hh:mm:ss in 24 hour format vbtrendbar - 1 trace: vertical up-trending line-bar vtrend - 1 trace: vertical trending line; auto-direction vtrend2 - 2 traces: vertical trending lines; auto-direction vttrendbar - 1 trace: vertical down-trending line-bar Variable names in SL standard Graphs The variables listed below are used in SL Standard Graphs as part of the dynamic descriptions for GraphAxes and GraphTraces. Most Graphs contain only a subset of the variables listed below. The "#" indicates an optional number for Graphs with multiple GraphAxes (more than one x and one y axis) or multiple GraphTraces.

Variable Names in SL-Standard Graphs

Variable Description represents the angular value of the next Point to be angle# plotted, in radial Graphs angle#_array used for arrays of angle values, in radial Graphs backgr_color controls the background color of the Graph c# controls the color of a section of a pie Graph grid_backgr_color controls the color of the Grid

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-20 Example Applications

Variable Names in SL-Standard Graphs (continued) Variable Description label# used to label sections of a pie Graph mag#_array used for arrays of magnitudes, in radial Graphs represents the magnitude of the next Point to be plotted, magnitude# in radial Graphs sets the number of Points (the trace length) for the num_points GraphTrace(s); same as trace#_length redraw_grid forces the Graph’s grid to be redrawn reset forces the background to be redrawn trace#__color controls the color of the GraphTrace(s) trace#__ecolor controls the edge color of the GraphTrace(s) trace#__fcolor controls the fill color of the (bar) GraphTrace(s) trace#__mcolor controls the Marker color of the GraphTrace(s) sets the number of Points for the GraphTrace(s); same trace#_length as num_points used as the horizontal (x) component of the next value trace#_x_value to be plotted trace#_y_value used as the vertical (y) component of the next value to be plotted trace#_x_array used as an array of x values trace#_y_array used as an array of y values v# used as the volume of a section of a pie Graph sets the lower limit of the range on the horizontal x#_min_value GraphAxis and the minimum x value for the GraphTrace(s) sets the upper limit of the range on the horizontal x#_max_value GraphAxis and the maximum x value for the GraphTrace(s) x#_tickmajor sets the major tick spacing on the horizontal GraphAxis sets the minor tick spacing on the horizontal GraphAxis; x#_tickminor sets to the same value as x#_tickmajor if minor tick marks are not desired controls the shift distance and direction in horizontal x_shift_val trend Graphs

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-21 Example Applications

Variable Names in SL-Standard Graphs (continued) Variable Description sets the horizontal position where Points are plotted in x_start trend Graphs sets the lower limit of the range on the vertical y#_min_value GraphAxis and the minimum y value for the GraphTrace(s) sets the upper limit of the range on the vertical y#_max_value GraphAxis and the maximum y value for the GraphTrace(s) y#_tickmajor sets the major tick spacing on the vertical GraphAxis sets the minor tick spacing on the vertical GraphAxis; y#_tickminor sets to the same value as y#_tickmajor if minor tick marks are not desired controls the shift distance and direction in vertical trend y_shift_val Graphs sets the vertical position where points are plotted in y_start trend Graphs

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-22 Example Applications

Interaction

The Interaction example shows how to interact with objects in the model displayed by the SL-GMS Microsoft .NET Viewer.

Figure 3-6: Interaction Example Displaying Auxiliary Furnace Model Features Demonstrated • Switching models using the ModelName property • Use of OnMouseMove event handler to change the cursor when the mouse is over a named object • Use of a OnMouseClick event handler to provide object selection and display of object data • Use of a OnMouseDoubleClick event handler to display a property dialog for the selected object • Use of a context menu popup event handler to create and display a popup menu when the right mouse button is clicked

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-23 Example Applications

Form Contents Form1 contains two buttons, five labels, one scroll bar and one instance of the SL-GMS Microsoft .NET Viewer control. • button1 - displays top_valve1 model when clicked • button2 - displays top_valve2 model when clicked • label1 - contains the text “Selected Object:” • label2 - used to display object name and data • label3 - contains usage text • label4 - set to the name of the object under the mouse cursor • label5 - contains the text “Name of Object Under Cursor:” • label6 - contains usage text Models auxfurnace - graphic model for a furnace auxsupply - graphic model for an auxiliary heating system SUBMODS - directory containing submodels used in building auxfurnace and auxsupply models Viewer Properties Default properties are used. Data The focus of the Interaction example is techniques for interacting with objects in a model, and therefore does not have a data source. Interaction Requirements The goal is to capture mouse events as the cursor moves over objects in the model displayed by the viewer, and perform certain actions. The desired behavior is described below. • If the cursor is over an object that has a Name property that is defined, change the mouse cursor to the “hand” cursor and display the object’s name in label4.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-24 Example Applications

• If a named object is clicked, display its name and data in label2. • If the right mouse button is clicked while the cursor is not over a named object, create a popup menu that contains the model names. The popup menu can be used to change the model displayed. If the cursor is over a named object, add an entry to the popup menu with the object’s name. Selecting the name entry will display a property dialog for the named object. • If the cursor is over a named object and the mouse is double-clicked, display a property dialog for that object. Implementation The first step is to declare variables needed for the interaction processing.

private GmsObject ObjectUnderMouse = null; private MouseEventArgs LastMouseDown = null;

private PropertyDialog Dialog; private GmsObject dialogObject;

private Cursor defaultCursor; private String hoverObjectName; private String selectedObjectName; private String selectedObjectUserData;

The next step is to establish event handlers for the viewer’s MouseMove, MouseDown, Click, and DoubleClick events.

gmsViewer1.MouseMove += new MouseEventHandler(OnMouseMove); gmsViewer1.MouseDown += new MouseEventHandler(OnMouseDown); gmsViewer1.Click += new EventHandler(OnMouseClick); gmsViewer1.DoubleClick += new EventHandler(OnMouseDoubleClick);

The OnMouseMove handler queries the viewer to find out if the cursor is over an object. It then determines if the cursor is entering or leaving an object and calls appropriate support functions.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-25 Example Applications

private void OnMouseMove( object sender, MouseEventArgs me ) { GmsObject obj = gmsViewer1.FindObject( me.X, me.Y ); if ( obj != ObjectUnderMouse ) { if ( ObjectUnderMouse != null ) MouseLeaveObject( ObjectUnderMouse );

if ( obj != null ) MouseEnterObject( obj, me );

ObjectUnderMouse = obj; } base.OnMouseMove(me); }

The OnMouseDown handler saves the mouse event data for use by the other event handlers.

private void OnMouseDown( object sender, MouseEventArgs me ) { lastMouseDown = me; }

The OnMouseClick handler displays the object’s name and data in label2.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-26 Example Applications

private void OnMouseClick( object sender, EventArgs e ) { // find the SL-GMS object that was clicked

GmsObject obj = gmsViewer1.FindObject( lastMouseDown.X, lastMouseDown.Y );

// update the selected object information on the form

if (obj == null || obj.Name == String.Empty) { resetSelectedObject(); } else { setSelectedObject(obj.Name, obj.UserData); }

The OnMouseDoubleClick handler is responsible for displaying the object property dialog. It queries the viewer for the object from which the data for the dialog is obtained.

private void OnMouseDoubleClick( object sender, EventArgs e ) { // Ignore event if no object under mouse

GmsObject obj = gmsViewer1.FindObject( lastMouseDown.X, lastMouseDown.Y ); if ( obj == null ) return;

showPropertiesDialog(obj); }

The popup menu event handler, popupMenuHandler, creates the context menu.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-27 Example Applications

private void popupMenuHandler(object sender, System.EventArgs e) { // Clear all previously added menu items

contextMenu1.MenuItems.Clear();

// Add the generic menu items -- these items are always available, regardless // of where on the form the user clicks.

MenuItem menuItem1 = new MenuItem("AuxFurnace System"); menuItem1.Click += new EventHandler(button1_Click); contextMenu1.MenuItems.Add(menuItem1);

MenuItem menuItem2 = new MenuItem("AuxSupply System"); menuItem2.Click += new EventHandler(button2_Click); contextMenu1.MenuItems.Add(menuItem2);

// If the menu is for a named SL-GMS object, add another menu item to // bring up the property dialog for the object.

GmsObject obj = gmsViewer1.FindObject( lastMouseDown.X, lastMouseDown.Y );

if (obj != null && obj.Name != String.Empty) { MenuItem props = new MenuItem(obj.Name + " Properties"); props.Click += new EventHandler(OnPropertiesItemClicked); contextMenu1.MenuItems.Add(props); } }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-28 Example Applications

Building Interaction To build the Interaction example, load the project solution file, “Interaction.sln”, into Visual Studio .NET. Use the Build command to build the executable. Running Interaction From Visual Studio .NET, select Debug->Start Without Debugging or Ctrl+F5 to execute the example. From a properly configured Command Prompt window, cd to the Interaction directory and execute one of the following batch files: run_rel (to run the release version) run_dbg (to run the debug version)

Once Interaction is running, moving the mouse cursor over some of the objects in the model results in the mouse cursor’s changing to a hand, as shown in Figure 3-7. When this occurs, the object’s name is displayed in label4.

Figure 3-7: Cursor Change and Name Display

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-29 Example Applications

Clicking the right mouse button results in the display of a popup menu, as shown Figure 3-8.

Figure 3-8: Popup menu (2 Entries) Clicking the right mouse button while the cursor is over a named object results in the display of a popup menu with an entry for the object’s name as shown Figure 3-9.

Figure 3-9: Popup Menu for Named Object Selecting the third entry in a popup menu, or double-clicking a named object in the model, causes a property dialog to appear that displays the object’s property values, as shown in Figure 3-10.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-30 Example Applications

Figure 3-10: Object Property Dialog

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-31 Example Applications

Browser

The Browser example shows how to deploy an application that uses the SL-GMS Microsoft .NET Viewer control in a web browser. Techniques consistent with browser deployment are also demonstrated, such as obtaining data from a web service and use of GmsStreamComponent to load SL-GMS model and data files from a web server.

Figure 3-11: Browser Example Displaying Valve 1 Model Features Demonstrated • Switching models using the ModelName property • Acquisition of data through a web service

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-32 Example Applications

• Transfer of SL-GMS models and data files from a remote web server using GmsStreamComponent Form Contents Form1 contains two buttons, five labels, one scroll bar, one timer, one GmsStreamComponent, and one instance of the SL-GMS Microsoft .NET Viewer control. • button1 - displays top_valve1 model when clicked • button2 - displays top_valve2 model when clicked • label1 - contains the text “Slow” • label2 - contains the text “Web Service Sample Rate” • label3 - contains the text “Fast” • label4 - The text for this object is changed by hScrollBar1. The initial text is set to “250 ms”. • label5 - contains the text “Delay :” • hScrollBar1 - adjusts the Interval property for timer1 • timer1 - a timer with an initial Interval of 250 ms • gmsStreamComponent1 - a component used for retrieval of SL-GMS files from a URL Models top_valve1 - contains a background rectangle and one instance of the valve1 model top_valve2 - contains a background rectangle and one instance of the valve2 model valve1 - graphic model for a plug valve valve2 - graphic model for a gate valve Viewer Properties Default properties are used.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-33 Example Applications

AntiAliasMode = none This can be set if it is desired to use Anti-aliasing to draw the graphics. This effect provides smoother drawing of graphical objects. This incurs a performance hit so it can be restricted to some types of objects or enabled for all objects. DataSimulatorFile = null If set to a file name, it would load a *.dat file whenever a model containing the standard GMS-simulated data syntax is loaded, which would be used to drive simulated data in the loaded model. DoubleBuffer = none Usually this is set to Redraw, which ensures proper redraw and no flicker for updates, but if the dynamics of the model are optimized so that double buffering is unnecessary, this can be turned off. GmsRasterTextMode = SL.GMS.RasterTextMode.Rotatable (Fixed, Rotatable) ModelName = null Name = "gmsViewer1" Renderer = GDI GDI or GDI+ is used to render graphics. ResizeControls = false Native controls in the model will not resize if the size of the viewer is changed. ResizeStyle = SL.GMS.ResizeStyle.Fit The style used to fit a model in the control (Fit, Scale, Crop) ViewManager.AutoZoomMode = FitModel This places the viewer into the mode that automatically tries to fit the model into the viewing area when zooming. ViewManager.LoadAlignment = MiddleCenter Indicates how to align the model when loading. ViewManager.ResizeAlignment = MiddleCenter Indicates how to align the model when resizing a window. ViewManager.Zoom= 100 Default zoom level.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-34 Example Applications

ViewManager.ZoomLimits = 10 1000 Minimum and maximum zooms allowed. ViewManager.ZoomPanReverse = Alt Accelerator key which reverses a zoom or pan operation. Data Acquisition The Browser example obtains its data from a web service through a proxy. The web service supports a number of operations that control the generation of data and its retrieval by applications. Each time timer1 expires, the following actions occur: • A list of variable names used in the current model is retrieved from the viewer. • A list containing values for each variable in the list is retrieved from the web service using its GetVariableValues operation.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-35 Example Applications

• The values are parsed and the variables in the model are updated.

for(int i = 0, length = NameValuePairs.Length ; i < length ; i++) { string name = NameValuePairs[i]; i++; string valuestr = NameValuePairs[i]; gmsViewer1.SetGmsVar( name, valuestr); }

• The model is updated with the new values using the viewer’s UpdateGraphics( ) method. Additional Browser Support When File->New->Window is selected from ’s pull-down menu, the new window that is created is a duplicate of the first, resulting in two viewer controls executing simultaneously. This situation requires coordination between the controls for them to operate properly. A static class, GmsMonitor, provides the locking functionality required. The constructor, Dispose( ), Unload( ), switchModel( ), timer1_Tick( ) and Browser_closed( ) are each broken into two parts. The first part contains the logic using GmsMonitor and the second part contains the original code.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-36 Example Applications

Constructor( )

private void BrowserConstructorCode() { // Required for Windows Form Designer support InitializeComponent(); // Setup SL-GMS error and warning handlers GmsViewer.GmsError += new GmsMessageEventHandler(this.gmsViewer1_GmsError); GmsViewer.GmsWarning += new GmsMessageEventHandler(this.gmsViewer1_GmsWarning); // set initial update rate for the Viewer based on initial // scrollbar values timer1.Interval = hScrollBar1.Value; label4.Text = Convert.ToString(hScrollBar1.Value) + " ms"; // create and initialize the datasource for this demo datasource = new Datasource(); // display the initial model Valve1(); } public Browser () { // we will require use of GmsMonitor.Lock be enabled since the // Browser control may run in a multi-threaded environment (i.e., // Internet Explorer) GmsMonitor.Enabled = true; if (GmsMonitor.Enabled) { lock (GmsMonitor.Lock) { BrowserConstructorCode(); } } else { BrowserConstructorCode(); } }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-37 Example Applications

Dispose( ) a private void BrowserDisposeCode (bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); }

///

/// Clean up any resources being used. /// protected override void Dispose (bool disposing) { if (GmsMonitor.Enabled) { lock (GmsMonitor.Lock) { BrowserDisposeCode(disposing); } } else { BrowserDisposeCode(disposing); } }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-38 Example Applications

Unload( )

private void BrowserUnloadCode() { timer1.Stop(); gmsViewer1.Dispose(); gmsViewer1 = null; timer1.Dispose(); timer1 = null; }

///

/// This method is invoked from the JScript in the HTML page /// when the HTML page is unloaded /// public void Unload() { if (GmsMonitor.Enabled) { lock (GmsMonitor.Lock) { BrowserUnloadCode(); } } else { BrowserUnloadCode(); } }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-39 Example Applications

switchModel( )

private void BrowserSwitchModelCode (string modelName) { // set model name in viewer -- this loads the new Model gmsViewer1.ModelName = modelName;

// tell datasource that a new model has been loaded-- // the datasource will create new GmsVariables to control // the animation of the Model GmsModel model = gmsViewer1.Model; datasource.SetupVariables(model); }

private void switchModel(string modelName) { if (GmsMonitor.Enabled) { lock (GmsMonitor.Lock) { BrowserSwitchModelCode(modelName); } } else { BrowserSwitchModelCode(modelName); } }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-40 Example Applications

timer1_Tick( )

private void BrowserTimer1_TickCode (object sender, System.EventArgs e) { if (datasource != null) { datasource.UpdateVariables(gmsViewer1.Model); gmsViewer1.UpdateGraphics(); } }

private void timer1_Tick (object sender, System.EventArgs e) { if (GmsMonitor.Enabled) { lock (GmsMonitor.Lock) { BrowserTimer1_TickCode(sender, e); } } else { BrowserTimer1_TickCode(sender, e); } }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-41 Example Applications

Browser_Closed( )

private void Browser_ClosedCode (object sender, System.EventArgs e) { this.gmsViewer1.Dispose(); this.gmsViewer1 = null; }

private void Browser_Closed (object sender, System.EventArgs e) { if (GmsMonitor.Enabled) { lock (GmsMonitor.Lock) { Browser_ClosedCode(sender, e); } } else { Browser_ClosedCode(sender, e); } }

Getting Files from the Web Server The Browser example uses the GmsStreamComponent to retrieve SL-GMS model and data files from a web server. The data files transferred include colordef.dat, fontdef.dat, font files, and other files required for proper operation of the viewer control. The Paths property of the GmsStreamComponent is set to the URL of the virtual directory containing the files needed by the application. Building Browser To build the Browser example, load the project solution file, “Browser.sln”, into Visual Studio .NET. Set the project’s output path to the location of the SLGMS.NET virtual directory (e.g., C:\SLGMS.NET\). Use the Build command to build the DLL. The Visual Studio .NET post-build event will automatically copy the models, color and font definition files, and the HTML file for the demo to the virtual directory.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-42 Example Applications

Running Browser Prerequisites The Browser example requires the availability of several services for proper function: • A web server with Microsoft Internet Information Services configured so that GmsStreamComponent can transfer files from it. • A web service configured to supply data to the Browser example The configuration and testing of these services is described in the document Installation and Configuration of Services for the Browser Example. Verify that the required services and files are available and functioning properly, as described in the above document. Start Internet Explorer and enter the following URL in the address field: http://localhost/SLGMS.NET/Browser.htm

If the web server is not on the same machine that is running the Browser example, replace localhost in the above URL with the appropriate host name. The Valve1 and Valve2 buttons change the model displayed in the viewer. The Browser example HTML page also has two Java Script buttons that change the model displayed in the viewer. The slider changes how often the application retrieves data values from the web service. Moving the slider will not change how fast the valve moves. The web service has its own update rate (default 500ms), which is the rate at which the web service generates new values. To make the valve move faster, both rates (the application sample rate and web service data generation rate) must be increased. To increase the web service data generation rate, start Internet Explorer and set the address field to: http://localhost/WebService1/Service1.asmx

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-43 Example Applications

Select the “SetUpdateRate” operation. A second web page will appear. Enter the value 50 into the text box and select “Invoke.” A new window will appear, confirming that the update rate has been changed to 50 milliseconds. Web Licensing Web Licensing is a variation on SL-GMS licensing that allows clients to use applications hosted by a web server without requiring an individual license key for each client machine, only for the host server. Implementing web licensing is simple. The SL-GMS application hosted by the web server via a web page must set the GmsSystem.ServerKeys property during the GmsSystem.Initializing event. The PIN for web licensing is different from the NIC or dongle PIN used for standard licensing. To determine the PIN for your server, copy the files gmsjregster.jar and gmsregister. from the %GMS_HOME%demo.net/browser directory into the document root directory of your web server. Open the gmsregister.html web page on your browser via its URL and note the PIN that is displayed. You will need to contact SL Corporation with that PIN in order to request a web server key. The key you receive for your web server should be stored in a file named “gms.txt” in the document root directory. Below is a sample of how to modify the Browser demo to implement web licensing. There are three functional changes. First, an event handler is registered for the GmsSystem.Initializing event. Second, the event handler opens a file on the web server called "gms.txt" and creates an array of key strings from the data in the file. Lastly, the event handler assigns the key string array to GmsSystem.ServerKeys. The string array assigned to GmsSystem.ServerKeys must contain zero or more strings containing 16 digit hex keys. Any string that isn't a 16 digit hex number will be ignored. The modified Browser demo is run by opening the web page with a URI that uses the proper server, e.g. http://www.mycompany.com/SLGMS.NET/Browser.htm instead of http://localhost/SLGMS.NET/Browser.htm

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-44 Example Applications

Be sure to create the gms.txt file with the proper key(s) before running the demo.

using System.Collections; using System.IO; using System.Net; using System.Text; . . . private void BrowserConstructorCode () { GmsSystem.Initializing += new EventHandler(GmsSystem_Initializing);

// Required for Windows Form Designer support

InitializeComponent(); . . . } . . . private void GmsSystem_Initializing(object sender, EventArgs e) { WebRequest webReq = WebRequest.Create( "http://www.mycompany.com/SLGMS.NET/gms.txt" ); WebResponse webResp = webReq.GetResponse(); Stream stream = webResp.GetResponseStream(); StreamReader sr = new StreamReader( stream, new ASCIIEncoding() );

string str; ArrayList keys = new ArrayList(); while ( null != (str = sr.ReadLine())) { keys.Add( str ); }

sr.Close(); stream.Close(); webResp.Close();

GmsSystem.ServerKeys = (string[])keys.ToArray( typeof(string) ); }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-45 Example Applications

SharePoint SL-GMS Viewer Web Part Introduction The SPViewer Web Part demo shows how the SL-GMS Viewer Control for .NET can be used to display and animate dynamic SL-GMS Models in web pages delivered using Microsoft Windows SharePoint Products and Technologies. This document begins by describing the steps necessary to configure the SharePoint server, the development platform, and the client. These sections include to a number of useful resources and tools that can help to simplify the configuration process. The following sections describe the SPViewer Control and the SPViewer Web Part. The SPViewer Control is a Microsoft Windows Forms Smart Client written in C#, which uses the SL-GMS Viewer Control to load, display, and animate a SL-GMS Model. The document shows how the SPViewer Control can be configured for No-Touch Deployment from the SharePoint Server. The SPViewer Web Part is a SharePoint Web Part Library that generates the HTML required to display the SPViewer Control in a SharePoint Web Part Page. The document describes how to build a Web Part Package for simple deployment into the SharePoint Virtual Server Gallery on the server. The final section of the document contains a discussion of several useful techniques for resolving problems during the development and deployment of a Web Part that uses the SL-GMS Viewer Control. Links to several excellent system utilities and web resources are provided. System Configuration This section describes the steps required to configure the Client, Server, and Development environments for the SL-GMS SPViewer Web Part demo. The configuration process is critical to the successful development and deployment of the project, addressing areas including SharePoint Server administration, Internet Information Services (IIS) administration, Microsoft .NET Code Access Security, and Internet Explorer zone settings.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-46 Example Applications

Configuring the SharePoint Server

The SharePoint server should be running the Windows Server 2003 operating system with Windows SharePoint Services (WSS) installed. WSS is a free add-on to Windows Server 2003 and can be downloaded from: http://www.microsoft.com/WindowsServer2003/technologies/SharePoint Note that to install WSS you will first have to configure the server as an Application Server and enable IIS 6.0 and ASP.NET 1.1, both of which are required by WSS. For a more complete discussion of the WSS architecture, please refer to the following MSDN article: http://msdn.microsoft.com/msdnmag/issues/04/07/WindowsSharePointServi ces/default.aspx To deploy the SPViewer Control on the SharePoint Server you will need to create two directories under the wpresources directory named SPViewer and SPModels. These directories will contain the DLLs and the Models for the SPViewer Control, respectively. The directories are created under the wpresources directory because Windows SharePoint Services does not intercept HTTP requests for files in the wpresources directory or its subdirectories. If you would like to create the SPViewer and SPModels directories in another location on the server, you will need to configure the SharePoint Managed Paths to mark these directories as Excluded Paths. More details can be found at: http://www.microsoft.com/resources/documentation/wss/2/all/adminguide/en -us/stsf05.mspx After the directories have been created, we can adjust the IIS properties and permissions of the virtual directories to allow files to be downloaded to the client machine. Start the IIS Manager by choosing Start / Administrative Tools / Internet Information Services (IIS) Manager. In the left pane, expand Local Computer / Web Sites / Default Web Site / wpresources. Right-click on the SPViewer folder and choose Properties. In the Directory tab of the SPViewer Properties window, verify that the Read, Write, and Log Visits boxes are checked, and that the Execute Permissions are set to Scripts Only. The Read permission is required to download files, the Write permission is required to upload files during

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-47 Example Applications

application development, and the Log Visits permission is useful for debugging IIS problems. More information about debugging is provided in the section "Troubleshooting", below. Setting the Execute Permissions to Scripts Only allows the application DLLs to be downloaded rather than executed when they are requested from the server. In the Directory Security tab of the SPViewer Properties window, select the Edit... button from the Authentication and Access Control section. In the Authentication Methods dialog, verify that the Enable Anonymous Access box is checked. Make a note of the User Name that is displayed, then click OK to close the dialog. We will verify that this user account has sufficient permissions to access the files in the virtual directory when we configure the IIS permissions for the virtual directory below. In the HTTP Headers tab of the SPViewer Properties window, select the Mime Types... button near the bottom of the dialog. In the Mime Types dialog, select the New... button. In the dialog that appears, enter .dat into the Extension textbox and text/plain into the MIME type textbox, then click OK. The new MIME type will appear in the list of Registered MIME types (file extensions). Repeat this process to add a new MIME type for SL-GMS Model files, which have a .m1 extension and a MIME type of application/octet-stream. Click OK to close the MIME Types dialog. The IIS directory properties are now set. Click OK to close the SPViewer Properties dialog. To adjust the directory access permissions, right-click the SPViewer folder in the IIS Manager window and choose Permissions. In the list box at the top of the Security tab, click on the name of the user that you noted when setting the Directory Security for anonymous access, above. On most systems, this user will be listed as the Internet Guest Account. When you select this user, the Permissions list box at the bottom of the Security tab will update to show the effective permissions for this user account. Verify that this account is able to read files from this directory by ensuring that the Read checkbox in the Allow column is checked. Click OK to close the dialog. The SPViewer directory properties and permissions have now been configured. Repeat this process for the SPModels directory to configure its properties and permissions. The settings should be identical to the SPViewer directory.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-48 Example Applications

Configuring the Development Platform Development of SharePoint Web Parts may be done locally on a server running Windows Server 2003 with Windows SharePoint Services (WSS) installed or remotely on a separate PC. If you're developing remotely, you'll need to copy the file Microsoft SharePoint DLL from the server to your development machine. This DLL can be found at the following location on your server: C:\Program Files\Common Files\Microsoft Shared\Web server extensions\60\ISAPI\Microsoft.SharePoint.dll Whether you're developing locally or remotely, you'll want to download and install Microsoft's Web Part Templates for Visual Studio .NET. These templates simplify the creation of custom web parts, and can be downloaded from: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odc_sp2003 _ta/html/sharepoint_webparttemplates.asp If you're developing remotely, when you install the templates be sure to indicate the location of the Microsoft.Sharepoint.dll file that you copied from the server to your development machine. This will allow Visual Studio .NET to automatically add a reference to the Sharepoint DLL whenever you create a Web Part project. At this point you're ready to begin creating Web Parts. The following MSDN article gives an overview of the Web Part development process: http://msdn.microsoft.com/msdnmag/issues/04/08/WebParts/ The SL-GMS Viewer web part that we'll be discussing shortly can be found in the following directory: %GMS_HOME%\demo.net\SharePointViewer There are five subdirectories under this directory. The SPViewer subdirectory contains the Visual Studio .NET solution, application code, and supporting files for the SPViewer Control, a Windows Forms UserControl that loads, displays, and animates SL-GMS Models. The SPViewerCab and SPModelsCab subdirectories contain CAB projects for packaging the DLLs, Models, and data files for deployment on the SharePoint server. These three projects are discussed in the section "The SPViewer Control" below.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-49 Example Applications

The SPViewerWebPart subdirectory contains the Visual Studio .NET solution and application code for the SPViewer Web Part, a custom SharePoint Web Part that generates the HTML to render the SPViewer Control. The SPViewerWebPartCab subdirectory contains a CAB project for packaging the DLL and supporting files needed to deploy the SPViewer Web Part on the SharePoint server. These two projects are discussed in the section "The SPViewer Web Part" below. Configuring the Client The client machine must have the .NET Framework runtime installed in order to display a web page that includes the SPViewer Web Part. This is necessary because the SPViewer Control is a Windows Forms Smart Client, which requires the services of the .NET Framework runtime. The .NET Framework runtime can be freely downloaded from the Microsoft MSDN Download Center at the following location: http://www.microsoft.com/downloads/details.aspx?FamilyID=262D25E3-F58 9-4842-8157-034D1E7CF3A3&displaylang=en Note that it is also possible to create a Setup Project for the SPViewer Control which will automatically install the .NET Framework runtime on the client machine if the runtime has not already been installed. This deployment option makes use of a freely redistributable Microsoft Setup.exe bootstrapper sample that can be included in a Windows Installer Setup project. More details can be found at: http://www.microsoft.com/downloads/details.aspx?familyid=BF253CFD-1EF C-4FC5-BA7E-6A6F21403495&displaylang=en Because the SPViewer Control is a SL-GMS application, a valid SL-GMS Product License Key must be available in order to use the Web Part. As distributed, the SPViewer Control assumes per-client licensing, so this key should be placed in the KEYS file, which is located in the %GMS_HOME%\lib directory on the client machine. For web-based licensing, the SPViewer Control should be modified to set the GmsSystem.ServerKeys property during initialization, as described on page 3-44 of this manual. The Web Part Page must be displayed in a browser based on the .01 engine or higher. The security settings of both the browser and the .NET Framework must be configured to allow pages downloaded from the SharePoint server to execute with increased permissions. There

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-50 Example Applications

are several ways to do this, including creating Custom Code Groups and Code Access Permission Sets, but for simplicity we will add the SharePoint Server to the list of Trusted Sites and increase the .NET permissions granted to the Trusted Sites Zone. For a more complete discussion of .NET Code Groups, Code Access Security, and Internet Explorer, please see the following articles: http://support.microsoft.com/default.aspx?scid=kb;en-us;311301 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/htm l/winforms11122002.asp For this demo, there are two steps required to adjust the security levels on the client machine. First, in Internet Explorer, the SharePoint server should be added to the list of Trusted Sites. Run Internet Explorer and select Tools / Internet Options... On the Security tab of the options dialog, select the Trusted Sites icon in the top panel and press the Sites... button. Enter the URL of the SharePoint server, for example http://mywebserver. Uncheck the button to require : from sites in the zone, and click OK. At the bottom of the Security tab, adjust the slider so that the security level for the Trusted Sites zone is set to Low. Click OK to close the Internet Options dialog. Second, the .NET security level of the Trusted Sites Zone must also be adjusted. Open the .NET framework configuration utility by selecting Start / Programs / Administrative Tools / Microsoft .NET Framework 1.1 Configuration. In the main window, choose Adjust Zone Security to display the Security Adjustment Wizard. Check the radio button labeled "Make changes to this computer" and click Next. Select the Trusted Sites icon from the listbox at the top of the page and adjust the slider all the way upwards to Full Trust. Click Next and Finish to apply the changes and close the wizard. The SPViewer Control This section describes the SPViewer Control, a Windows Forms User Control that includes a SL-GMS Viewer for displaying and animating Models. The SPViewer Control is instanced by the SPViewer Web Part for use in SharePoint Web Part Pages.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-51 Example Applications

Overview The SPViewer Control is a Windows Control Library (DLL) that displays and animates a SL-GMS Model. This control can be referenced from within a SharePoint Web Part, as described in the section "The SPViewer Web Part", later in this document. The SPViewer Control consists of a top-level Form containing a SL-GMS Viewer Control, a SL-GMS Stream Component, and a Windows Forms TextBox. When the user enters the name of a Model into the text box and presses , the Model is downloaded from the web server and displayed in the SL-GMS Viewer control. If the Model is not found, a substitute model is displayed in the SL-GMS Viewer control. Data to animate the Model is read from the associated SL-GMS .dat file, also downloaded from the web server when the Model is loaded. If the .dat file for the Model is not found, the Model will not animate. All Models and .dat files are downloaded from the wpresources\SPModels directory on the web server, as specified in the Paths collection of the SL-GMS Stream Component. Two sample Models, "testmodel" and "testmodel2" are provided with the demo. Any number of additional Models can be added by copying these Models and the associated .dat files to the wpresources\SPModels directory on the web server. It is not necessary to stop, reload, or refresh the Web Part Page to display new Models. The new Models are immediately accessible as soon as they are copied to the web server. Project Structure The Visual Studio .NET solution for the SPViewer Control is found in the following directory: %GMS_HOME%\demo.net\SharePointViewer\SPViewer This solution contains three projects, SPViewer, SPViewerCab, and SPModelsCab. The SPViewer project contains the application code for the UserControl. The application processes text entered into the TextBox, downloads Models from the web server and displays them in the SL-GMS Viewer Control, and configues the SL-GMS Data Simulator to animate the Models.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-52 Example Applications

The search path for the Models loaded by the SL-GMS Viewer Control is set in the Paths collection of the SL-GMS Stream Component. Initially, this path is set to http://localhost/wpresources/SPModels. In the constructor for the UserControl, additional paths are added using the CODEBASE of the SPViewer assembly, to allow Models to be automatically downloaded from the web server. The SPViewerCab project is a Setup and Deployment project that bundles the SPViewer DLL and the necessary SL-GMS runtime DLLs into a CAB file for deployment on the web server. The contents of the SPViewerCab.CAB file should be extracted to the wpresources\SPViewer directory on the web server. The SPModelsCab project is a Setup and Deployment project that bundles the SL-GMS Models and .dat files for the SPViewer Control into a CAB file for deployment on the web server. This project contains two example Models, testmodel.m1 and testmodel2.m1, along with definitions for simulated data in the files testmodel.dat and testmodel2.dat. In addition to these files, a third .dat file, testmodel_edit.dat, is provided for use with the SPEditor Control described in the section "The SPEditor Control", later in this document. The contents of the SPModelsCab.CAB file should be extracted to the wpresources\SPModels directory on the web server.

Building and Deploying the SPViewer Control This section describes how to build the SPViewer Control and how to deploy the SPViewer DLLs and the SL-GMS Model and .dat files on the web server. From Visual Studio .NET, open the SPViewer solution and choose Build / Build Solution. In the Output window, verify that all three projects have built successfully. After you build the solution, locate the file SPViewerCab.CAB, which contains the output DLLs for the project. This file will be in either the Debug or Release subdirectory under the SPViewerCab directory, depending upon your build configuration. Use the Windows File Expansion Utility to extract the files from the CAB file and deploy them to the web server. Note that the OSD (Open Software Description) file is not needed on the web server and may be removed. For example,

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-53 Example Applications

expand SPViewerCab.CAB -F:* \\mywebserver\c_root\InetPub\wwwroot\wpresources\SPViewer\ delete \\mywebserver\c_root\InetPub\wwwroot\wpresources\SPViewer\*.OSD Alternatively, you could double-click on the SPViewerCab.CAB file to open it and drag the DLL files to the appropriate directory on the web server. You should end up with the following DLL files in the wpresources\SPViewer directory on the web server: SL.GMS.dll SL.GMS.Drawing.dll SL.GMS.IO.dll SL.GMS.Windows.Forms.dll SPViewer.dll Finally, locate the file SPModelsCab.CAB in either the Debug or Release subdirectory under the SPModelsCab directory, depending again upon your build configuration. Use the Windows File Expansion Utility to extract the files from the CAB file and deploy them to the web server, as described above. For example, expand SPModelsCab.CAB -F:* \\mywebserver\c_root\InetPub\wwwroot\wpresources\SPModels\ delete \\mywebserver\c_root\InetPub\wwwroot\wpresources\SPModels\*.OSD Alternatively, you could double-click on the SPModelsCab.CAB file to open it and drag the .m1 and .dat files to the appropriate directory on the web server. You should end up with the following DLL files in the wpresources\SPModels directory on the web server: testmodel.dat testmodel.m1 testmodel2.dat testmodel2.m1 testmodel_edit.dat

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-54 Example Applications

Congratulations! The SPViewer Control is now ready for use. Next we'll build a SharePoint Web Part that will wrap this control and make it available in the SharePoint Web Parts Gallery. The SPViewer Web Part This section describes the SPViewer Web Part, a SharePoint Web Part that can display and animate a SL-GMS Model. This web part uses the SPViewer Control described above. Overview To use the SPViewer Control from within SharePoint we must wrap the control in a web part. The SPViewer Web Part is a simple Web Part Library that generates the HTML required to display the SPViewer Control in a SharePoint Web Part Page. The SPViewer Web Part identifies the location of the SPViewer Control on the web server and specifies the width and height of the region allocated to display the control. In this demo, we have set the width and height to exactly match the size of the main Form in the SPViewer Control. Project Structure The Visual Studio .NET solution for the SPViewer Web Part is found in the following directory: %GMS_HOME%\demo.net\SharePointViewer\SPViewerWebPart This solution contains two projects, SPViewerWebPart and SPViewerWebPartCab. The SPViewerWebPart project contains the application code for the Web Part. In the file WebPart1.cs, the RenderWebPart method contains all of the custom code for generating the proper HTML to display the SPViewer Control. The Web Part Description file, WebPart1.dwp, contains the metadata that describes the Web Part, its Assembly, and Type. Finally, the file Manifest.xml describes the assemblies, controls, and supporting files that make up the Web Part Package. The SPViewerWebPartCab project is a Setup and Deployment project that bundles the Manifest, the Web Part Description, and the Web Part Library to create a Web Part Package for deployment on the web server. The Windows SharePoint Services Administration Tool, stsadm.exe, will be used to install the Web Part on the server.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-55 Example Applications

Building and Deploying the SPViewer Web Part This section describes how to build the SPViewer Web Part and how to deploy and install the Web Part on the server. From Visual Studio .NET, open the SPViewerWebPart solution and choose Build / Build Solution. In the Output window, verify that both projects have built successfully. After you build the solution, locate the file SPViewerWebPartCab.CAB, which is the Web Part Package that was generated during the build. This file will be in either the Debug or Release subdirectory under the SPViewerWebPartCab directory, depending upon your build configuration. Copy this file to your SharePoint Server. For example, copy SPViewerWebPartCab.CAB \\mywebserver\c_root\CabFiles\ On the SharePoint Server, use the Stsadm.exe tool to install the Web Part. The "addwppack" command installs the Web Part Package by extracting the Web Part DLL to the server's bin directory, extracting the Web Part Description to the server's wpcatalog directory, and modifying the server's web.config file to identify the web part as a Safe Control. For example, cd c:\CabFiles stsadm.exe -o addwppack -filename SPViewerWebPartCab.CAB -force You should see the messages:

spviewerwebpartcab.cab: Deploying to http://mywebserver/. Operation completed successfully.

After you install or update a Web Part assembly or Web Part Description file (.dwp), or after making a change to the system configuration file, you may need to stop and restart the Internet Information Services (IIS) server before the changes are recognized. To restart IIS, bring up the IIS Manager by choosing Start / Administrative Tools / Internet Information Services (IIS) Manager. In the left pane, right-click on the Local Computer and choose All Tasks / Restart IIS... In the dialog that appears, select Reset Internet Services on and hit OK. When the operation completes, verify that IIS services are running by looking at the Web Sites icon in the right pane of the IIS Manager window. The status should say "Service is running".

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-56 Example Applications

Note that you can also restart IIS from the command-line by issuing the following command: iisreset /restart After installation, the Web Part should appear in the SharePoint Virtual Server Gallery. To verify this, navigate to a page on your SharePoint web site and select Modify Shared Page / Add Web Parts / Browse. Select the Virtual Server Gallery and look for the SL-GMS Viewer web part. Using the SPViewer Web Part If you've followed the instructions to this point, the SPViewer Web Part should now be ready for use in a SharePoint Web Part Page. Before continuing, be certain that you have configured the server and client as described in the sections "Configuring the Sharepoint Server" and "Configuring the Client". In particular, the client must have installed the .NET Framework Runtime and have configured Internet Explorer 5.01 or higher for trusted access to pages served from the SharePoint server. A valid SL-GMS Product License Key must also be available. Note that it is not necessary to install SL-GMS on each client machine, although it is fine if SL-GMS has already been installed on the client. The SPViewer Control only requires that a valid Product License Key is available on the client under the %GMS_HOME% directory. Begin by opening an existing Web Part Page, or by creating a new Web Part Page in your browser. Display the list of available web parts by selecting Modify Shared Page / Add Web Parts / Browse, and then selecting the Virtual Server Gallery. Drag the SL-GMS Viewer web part from the gallery and drop it into a Web Part Zone on the page. The SPViewer Web Part DLL, the SPViewer Control DLL, and the supporting SL-GMS DLLs will be downloaded from the web cerver to the client and stored in the Assembly Download Cache. Note that these DLLs will not need to be downloaded again unless newer versions are placed on the web server. The .NET Framework will automatically either use the locally cached version or download the newer version from the server whenever the Web Part Page is displayed. After a few seconds the web part should appear. The SL-GMS Model "testmodel" should display and begin to animate. To change the Model,

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-57 Example Applications

type "testmodel2" into the TextBox and hit . The second example Model should display and begin to animate. To display other SL-GMS Models, copy them to the wpresources\SPModels directory on the web server, along with a .dat file to control the animation. Once a Model has been copied to the web server, you can view it by typing its name into the TextBox. If you have provided a .dat file, the Model should begin to animate. Updating the SPViewer Web Part or the SPViewer Control To update either the SPViewer Web Part or the SPViewer Control, repeat the procedure described in the sections "Building and Deploying the SPViewer Web Part" or "Building and Deploying the SPViewer Control", above. The deployment procedures described in those sections will overwrite the existing web part, control DLLs, and Model files with new versions. Because we have configured the SPViewer Control for No Touch Deployment, the newest version of the Control will automatically be downloaded and displayed in new and existing SharePoint Web Part Pages on client machines. Removing the SPViewer Web Part On the SharePoint Server, use the Stsadm.exe tool to remove the Web Part. The "deletewppack" command removes the Web Part Package. For example, stsadm.exe -o deletewppack -name SPViewerWebPartCab.CAB To remove the SPViewer Control from the SharePoint Server, use IIS Manager to delete the virtual directories wpresources\SPViewer and wpresources\SPModels. For example, • Start / Administrative Tools / Internet Information Services (IIS) Manager • In the left pane, expand Local Computer / Web Sites / Default Web Site / wpresources • Right click on SPViewer and choose Delete • Right click on SPModels and choose Delete

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-58 Example Applications

Although the SPViewer web part does not install any files on client machines, you can "clean" a client machine by clearing the files downloaded from the web server and cached on the client, namely the files in the .NET Assembly Download Cache and the Internet Explorer Cache, and by removing the SL-GMS home directory and environment variable that were added to the client for SL-GMS product licensing. To clear the .NET Assembly Download Cache, issue the command gacutil /cdl To clear the browser cache, Start Internet Explorer and choose Tools / Internet Options... On the General tab, in the Temporary Internet Files box, click the Delete Files... button Click OK Finally, if SL-GMS has been installed on the client machine and is no longer needed, use Add / Remove Programs to uninstall the product. If SL-GMS has not been installed on the client and you have used per-client SL-GMS Product Licensing, you can also delete the %GMS_HOME% root directory and remove the environment variable definition for %GMS_HOME% from the System Control Panel. Troubleshooting This section describes techniques for troubleshooting problems with the SPViewer Web Part. The most common problems are related to assembly downloading and security permissions. The .NET Assembly Download Cache The SPViewer Control is a Windows Forms Smart Client application hosted in Internet Explorer. When the control is displayed, the assemblies that it references are downloaded from the web server and execute on the client. Note that this is different than an ASP.NET control, which executes on the server. The application assembly SPViewer.dll and the dependent SL-GMS assemblies are downloaded into the .NET Assembly Download Cache on the client. The Assembly Management utility Gacutil.exe can be used to examine the contents of this cache. Gacutil.exe can be found in the following location on the client machine:

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-59 Example Applications

%WINDIR%\Microsoft.NET\Framework\v1.1.4322\Gacutil.exe The Visual Studio .NET SDK also includes the Gacutil.exe utility, in the following location: C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\bin\Gacutil.exe To list the contents of the Assembly Download Cache, issue the command gacutil /ldl You should see output similar to the following:

Microsoft (R) .NET Global Assembly Cache Utility. Version 1.1.4322.573 Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

The cache of downloaded files contains the following entries: SPViewer, Version=1.0.2018.17915, Culture=neutral, PublicKeyToken=null, Custom=null

If SL-GMS has been installed on the client machine, you will not see any of the SL.GMS DLLs listed in the Assembly Download Cache. This is because .NET will examine the Global Assembly Cache (GAC) on the client before downloading these DLLs from the web server. Typically, SL-GMS will not be installed on the client machine. In this case the SL.GMS DLLs will also appear in the Assembly Download Cache. The command gacutil /ldl will show a display similar to the following:

Microsoft (R) .NET Global Assembly Cache Utility. Version 1.1.4322.573 Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

The cache of downloaded files contains the following entries: SPViewer, Version=1.0.2018.17915, Culture=neutral, PublicKeyToken=null, Custom=null SL.GMS, Version=2.0.2018.17806, Culture=neutral, PublicKeyToken=c83b600fe4fd8e53, Custom=null SL.GMS.Drawing, Version=2.0.2018.17814, Culture=neutral, PublicKeyToken=c83b600fe4fd8e53, Custom=null SL.GMS.IO, Version=2.0.2018.17830, Culture=neutral, PublicKeyToken=c83b600fe4fd8e53, Custom=null SL.GMS.Windows.Forms, Version=2.0.2018.17836, Culture=neutral, PublicKeyToken=c83b600fe4fd8e53, Custom=null

As you develop and deploy additional versions of the SPViewer Control or your own Windows Forms UserControls, the Assembly Download Cache

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-60 Example Applications

will grow to include the new versions. You can clear the contents of the Assembly Download Cache by issuing the following command: gacutil /cdl While you are developing your web parts, is a good idea to periodically clear the Assembly Download Cache to ensure that your SharePoint Web Part Pages are using the most current versions of the application DLLs. The Internet Explorer Cache Files that are downloaded from the web server to the client are also cached by Internet Explorer. Like the Assembly Download Cache, the Internet Explorer Cache should be periodically cleared to ensure that the latest versions of the DLLs are downloaded from the web server. You can clear the contents of the cache from the Internet Options dialog. Run Internet Explorer and choose Tools / Internet Options... On the General Tab, in the Temporary Internet Files section, choose Delete Files... In the Delete Files dialog, check the box labeled "Delete all offline content" and click OK. You can also configure Internet Explorer to automatically clear the cache whenever you exit the browser. SL recommends setting this option while you are developing and testing your SharePoint Web Part, to avoid confusion about which DLLs are being loaded when you view a Web Part Page. From IE, choose Tools / Internet Options... and select the Advanced tab. Scroll down to the Security section, check the box labeled "Empty Temporary Internet Files folder when browser is closed", and click OK. Note that if multiple IE windows are open, the cache is only cleared when the last window is closed. The IIS Log File If the program DLLs are not being downloaded to the Assembly Download Cache or the IE Cache, there may be a problem with the IIS virtual directory on the SharePoint server. One useful tool for debugging these kinds of problems is the IIS Log File. The IIS Log file settings are controlled through the IIS Manager snap-in for MMC. On the web server, start IIS Manager by selecting Start /

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-61 Example Applications

Administrative Tools / Internet Information Services (IIS) Manager. In the left pane, navigate to Local Computer / Web Sites, right-click on Default Web Site and choose Properties. The Default Web Site Properties dialog will appear. In the Web Site tab, check the box labeled "Enable logging". In the Active log format dropdown, choose "W3C Extended Log File Format" and hit the Properties... button. The Logging Properties dialog will appear. In the General tab, the "Log file directory" textbox shows the location of the root directory used for logging. On most systems this will be %SYSDIR%\system32\LogFiles. The IIS Log can be found in a subdirectory, which is identified by the template pattern shown in the "Log file name:" label at the bottom of the dialog. On most systems this is the directory W3SVC1. This directory will contain several log files; a new log file will be created periodically, according to the value selected in the "New log schedule" section of the dialog. Next, click the Advanced tab to display the "Extended logging options", the list of properties that will be logged. You can choose any of these properties, but a useful set for debugging might include Date, Time, Client IP Address, User Name, Service Name, Server IP Address, Server Port, Method, URI Stem, URI Query Protocol Status Protocol Substatus, Win32 Status, and User Agent. Check the fields you want to have logged, click OK to close the Logging Properties dialog, and click OK to close the Default Web Site Properties dialog. To examine the IIS Log File, use Explorer to navigate to the logfile directory (e.g. %SYSDIR%\system32\LogFiles\W3SVC1) and double-click on the most recent logfile. The newest entries will be at the bottom of the file. For example,

#Software: Microsoft Internet Information Services 6.0 #Version: 1.0 #Date: 2005-07-19 05:04:59 #Fields: date time s-sitename s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status

2005-07-19 05:06:06 W3SVC1 192.168.200.4 GET /wpresources/SPViewer/SPViewer.dll - 80 - 200.204.3.140 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.0;+;+.NET+CLR+1.1.4322) 200 0 0

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-62 Example Applications

This log entry shows a HTTP GET request for the file /wpresources/SPViewer/SPViewer.dll. The status 200 0 0 indicates that the file was found and successfully downloaded.

2005-07-19 05:06:06 W3SVC1 192.168.200.4 GET /_vti_bin/owssvr.dll - 80 MYSPSERVER\m 200.204.3.140 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.0;+Maxthon;+.NET+CLR+1.1.4322) 415 0 0

2005-07-19 05:06:06 W3SVC1 192.168.200.4 GET /_vti_bin/owssvr.dll - 80 MYSPSERVER\m 200.204.3.140 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.0;+Maxthon;+.NET+CLR+1.1.4322) 415 0 0

The two log entries above show HTTP GET requests for /_vti_bin/owssvr.dll. You will find many requests like this in the IIS Log Files. These are requests that have been intercepted by the SharePoint ISAPI Filter and have been passed to the SharePoint HandlerFactory for processing.

2005-07-19 05:06:06 W3SVC1 192.168.200.4 GET /wpresources/SPModels/testmodel.m1 - 80 - 200.204.3.140 - 200 0 0

2005-07-19 05:07:01 W3SVC1 192.168.200.4 GET /wpresources/SPModels/testmodel_xxx.m1 - 80 - 200.204.3.140 - 404 0 2

These final two entries are HTTP GET requests for SL-GMS Model files. The first request, for /wpresources/SPModels/testmodel.m1, is successful. The second request, for /wpresources/SPModels/testmodel_xxx.m1, fails with HTTP status code 404, File Not Found. By examining the IIS Log in this way, you can identify problems related to directory security and deployment. For more information about correcting these problems, please refer to the sections "Configuring the SharePoint Server" and "Building and Deploying the SPViewer Control", above. The Assembly Binding Log Another useful tool for debugging assembly load problems is the Assembly Binding Log Viewer, Fuslogvw.exe, which is distributed as part of the Microsoft .NET Framework SDK. This utility can be found at C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\bin\Fuslogvw.exe Begin by verifying that assembly load failures are being logged. Examine the registry key MyComputer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion\LogFailures

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-63 Example Applications

and check that its value is non-zero. If this key is missing, add this key (a DWORD) to the registry and set its value to 1. You can now run Fuslogvw.exe and view the log entries for each failed assembly binding. Note that Fuslogvw.exe does not update in real-time, so you will need to hit Refresh to update the list of logged entries after starting the application. By default, only failed attempts to load assemblies are logged. You can change this behavior so that all assembly load attempts are logged by adding a DWORD key to the registry at MyComputer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion\ForceLog and setting its value to 1. Setting this value is useful to determine exactly where each assembly was found (e.g. GAC, download cache, local disk, etc.). Fuslogvw.exe also does not, by default, log information about satellite assemblies. You can enable logging for satellite assemblies by adding a DWORD key to the registry at MyComputer\HKEY_LOCAL_MACHINE\ SOFTWARE\Microsoft\Fusion\LogResourceBinds and setting its value to 1. Setting this value is useful when trying to debug problems with localized resource assemblies. More information about the Assembly Binding Log Viewer can be found at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/ cpgrffusionlogviewerfuslogvwexe.asp The IEHost Extended Error Log In a browser-based .NET application, after an assembly loads it begins execution in IEHost.dll, the managed CLR host that runs inside Internet Explorer. Errors in code access security or object initialization typically fail silently. To debug these problems, you can activate the IEHost Debug Log File. You will need to add two entries to the registry. The first, a DWORD, is MyComputer\HKEY_LOCAL_MACHINE\ SOFTWARE\Microsoft\.NETFramework\DebugIEHost. Set the value of this key to 1.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-64 Example Applications

The second key identifies the path and filename of the log file. This string key is MyComputer\HKEY_LOCAL_MACHINE\ SOFTWARE\Microsoft\.NETFramework\IEHostLogFile. Set the value of this key to the full path and filename where you want the log to be stored (e.g. C:\LogFiles\IEHost.log). The log file will contain information about the application, security permissions, and if the application fails to initialize properly, a stack trace showing where the exception occurred. You will also see log entries for successful object initialization, like these entries following the successful download and activation of the SPViewer Control:

Microsoft.IE.SecureFactory: Trying to create instance of type http://mywebserver.com/wpresources/SPViewer/SPViewer.dll#SPViewer.UserControl1

Microsoft.IE.SecureFactory: Created instance of type http://mywebserver.com/wpresources/SPViewer/SPViewer.dll::SPViewer.UserControl1

More information about the IEHost Debug Log File can be found at: http://support.microsoft.com/default.aspx?scid=kb;en-us;313892 Code Access Security The IEHost Error Log may include entries related to .NET Code Access Security violations, which must be addressed before the SPViewer Control can execute. Begin by verifying that the security levels on the client machine have been adjusted according to the instructions in the section "Configuring the Client", above. The topic of .NET Code Access Security is beyond the scope of this document, but a more complete discussion of the role of Code Access Security in Windows SharePoint Services can be found at: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odc_SP2003 _ta/html/sharepoint_wsscodeaccesssecurity.asp SL-GMS Licensing Like any SL-GMS application, the SPViewer Control requires a valid SL-GMS Product License Key. As distributed, the SPViewer Control assumes per-client licensing, so this key should be placed in the file %GMS_HOME%\lib\KEYS on the client machine. Verify that the

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-65 Example Applications

GMS_HOME environment variable has been set and that a valid key is available in the KEYS file, as described in the section "Configuring the Client", above. If you have modified the SPViewer Control to use web-based licensing, verify that a valid key is specified in the GmsSystem.ServerKeys property during initialization, as described on page 3-44of this manual. Web Part Debugging Although the SPViewer Web Part is a relatively simple web part, acting only to generate the HTML to instance the SPViewer Control, it still may be necessary to debug. Web Part debugging involves attaching to the ASP.NET process W3wp.exe, and is discussed in the following MSDN article: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odc_SP2003 _ta/html/sharepoint_debugwebparts.asp Debugging the SPViewer Control To debug the SPViewer Control, it is useful to first convert the application from a User Control Library to a Windows Forms Application. This is simple to do. Begin by opening the SPViewer solution, right-clicking on the SPViewer project and selecting Properties. In the Common Properties / General tab, change the Output Type to Windows Application and hit OK. Unlike a WIndows Control Library, a Windows Forms application must define a Main method as an entry point, and the class must derive from System.Windows.Forms.Form. In the file UserControl1.cs, change the class to derive from System.Windows.Forms.Form instead of from System.Windows.Forms.UserControl. For example, public class UserControl1 : System.Windows.Forms.Form

Also in the file UserControl1.cs, add an entry point for the application: ///

/// The main entry point for the application. ///

[STAThread]

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-66 Example Applications

static void Main() { Application.Run(new UserControl1()); } Now the application can be built, run, and debugged from Visual Studio .NET like any other SL-GMS application. Remember to configure the Paths property of the GmsStreamComponent to identify the location of the Models for the application. Restarting IIS If the Web Part does not appear in the Virtual Server Gallery, or if changes you have made to the Web Part are not appearing, the problem may be with the Internet Information Services (IIS) server. After you install or update a Web Part assembly or Web Part Description file (.dwp), or after making a change to the system configuration file web.config, you may need to stop and restart the IIS server. Bring up the IIS Manager by choosing Start / Administrative Tools / Internet Information Services (IIS) Manager. In the left pane, right-click on the Local Computer and choose All Tasks / Restart IIS... In the dialog that appears, select Reset Internet Services on and hit OK. You can also restart IIS from the command-line by issuing the following command: iisreset /restart When the operation completes, verify that IIS services are running by looking at the Web Sites icon in the right pane of the IIS Manager window. The status should say "Service is running".

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-67 Example Applications

ZoomPan

The ZoomPan example shows various properties and methods that are part of the ViewManager class, and that manage portions of the loaded model currently visible in the control.

Figure 3-12: ZoomPan Example Features Demonstrated • How properties of the ViewManager affect the way a model is viewed when loaded

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-68 Example Applications

• Using the ViewManager methods to programmatically change how the model is viewed • Using ViewManager methods to set a mode which allows user interaction with the control to change how the model is viewed Form Contents Form1 contains two buttons on the left top corner that allow selection of the model to view; a set of radio buttons and a check box that set different properties which affect what happens when a model is loaded; five buttons that invoke various zoom/pan commands; six buttons that invoke zoom and pan interactive modes; a grid of buttons that perform model alignment; and top drop down boxes that set zoom percentage and zoom key accelerators. Model Switching Buttons • solidButton - displays tm_frect_solid model when clicked • opaqueButton - displays tm_frect_opaque model when clicked • transparentButton - displays tm_frect_transparent model when clicked • gradientButton - displays tm_frect_gradient model when clicked • complexButton - displays tm_frect_complex model when clicked • truetypeButton - displays tm_frect_raster model when clicked • hersheyButton - displays tm_frect_vector model when clicked • embeddedControlsButton - displays tm_ec_button model when clicked When Model Changes Buttons • fitModelRadioButton - Causes the next loaded model to perform the best fit into the control by setting ViewManager.FitModelInView(ContentAlignment.MiddleCenter) in the ModelLoaded event. • zoom100PercentRadioButton - Causes the next model to be loaded at 100% zoom by setting ViewManager.Zoom = 100.0 in the ModelLoaded event. • preserveviewRadioButton - Causes the next model to be loaded, keeping the current view by extent by setting

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-69 Example Applications

ViewManager.ViewExtent = savedViewExtent in the Model Loaded event. • preservezoompanmodeCheckBox - Causes the next model to be loaded, keeping the current interactive zoom/pan mode by setting ViewManager.ZoomPanMode = savedZoomPanMode in the ModelLoaded event. Zoom/Pan Commands Buttons • zoominonce - Calls ViewManager.ZoomInOnce( ) to zoom in the model in one step. • zoomoutonce - Calls ViewManager.ZoomoutOnce( ) to zoom out of the model in one step. • fitWidthButton - Zooms so that the full model width is visible and the model’s top edge is aligned with the view’s top edge by using ModelManager.Model.Extent to determine how to set the ViewManager.ViewExtent. • fitHeightButton - Zooms so that the model’s full height is visible and the model’s left edge is aligned with the view’s left edge by using ModelManager.Model.Extent and ViewManager.ViewExtent. • restoreview - Zooms so that the model’s full height is visible and the model’s left edge is aligned with the view’s left edge using ModelManager.Model.Extent and ViewManager.ViewExtent. Zoom/Pan Modes Button • zoomincontinuous - Puts the control in a mode where the user can zoom-in continuously when holding down the mouse by setting ViewManager.ZoomPanMode = ZoomPanMode.ContinuousZoomIn. • zoomoutcontinuous - Puts the control in a mode where the user can zoom-out continuously when holding down the mouse by setting ViewManager.ZoomPanMode = ZoomPanMode.ContinuousZoomOut. • zoomrectangle - Puts the control in a mode where the user can zoom to an area designated by drawing a rectangle by setting ViewManager.ZoomPanMode = ZoomPanMode.ZoomRectangle.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-70 Example Applications

• pancontinuous - Puts the control in a mode where the user can continuously pan when clicking and holding the mouse in a direction offset from center by setting ViewManager.ZoomPanMode = ZoomPanMode.ContinuousPan. • dragpan - Puts the control in a mode in which the user can perform discrete pans when clicking and dragging the mouse by setting ViewManager.ZoomPanMode = ZoomPanMode.DragPan. • None - Puts the control in default mode, where no user interaction is defined for zooming or panning by setting ViewManager.ZoomPanMode = ZoomPanMode.None. Align Model in View Buttons These buttons determine how to position the model in the view, for example, by moving the model to the top center by setting ViewManager.AlignModelInView(System.Drawing.ContentAlignment. TopCenter. Other Zoom Controls • zoompercentComboBox - This combo box allows entry of a zoom level by setting ViewManager.Zoom. • reversalComboBox - Determines the key which will reverse a zoom pan operation while the mouse is being held down by setting ViewManager.ZoomPanReversalKey = ZoomPanReversalKey.Alt. Models tm_frect_solid - contains solid filled rectangles which change color tm_frect_opaque - contains opaque filled rectangles which change color tm_frect_transparent - contains transparent filled rectangles which change color tm_frect_gradient model - contains gradient filled rectangles which change color tm_spline_complex model - contains complex filled polygons which change color tm_text_raster model when clicked - contains true type font text which changes color

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-71 Example Applications

tm_text_vector model when clicked - contains vector text which changes color tm_ec_button model when clicked - contains embedded control buttons which change color Cursors The cursors are changed programmatically when the zoom/pan mode is set by creating a dotnet cursor and setting the control cursor zoominActiveCursor = new Cursor(GetType(), “cursors.zoomin_active.cur”); viewer.Cursor = zoominActiveCursor; This cursor is set whenever the mode has been selected but it is also set when someone uses the zoompan reversal key. Notification that the zoompan mode has changed in order to update the cursor is implemented by registering for the ZoomPanChanged event. Viewer Properties Default properties are used. Data The data source for ZoomPan, defined in “Datasource.cs”, is the same as demonstrated in the SimpleViewer exercise. Building ZoomPan To build the ZoomPan example, load the project solution file, “ZoomPan.sln”, into Visual Studio .NET. Use the Build command to build the executable. Running ZoomPan From Visual Studio .NET, select Debug->Start Without Debugging or Ctrl+F5 to execute the example. From a properly configured Command Prompt window, cd to the ZoomPan directory and execute one of the following batch files: run_rel (to run the release version) run_dbg (to run the debug version)

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-72 Example Applications

AutoZoomMode

The AutoZoomMode example shows the effect the various AutoZoomMode options have when loading a new model and when resizing a window.

Figure 3-13: Auto Zoom Mode Example Features Demonstrated • Autozoom mode with Interactive Zoom/Pan modes • Autozoom mode with Model Loading alignment • Autozoom mode with Window Resize alignment • Setting control background color

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-73 Example Applications

Form Contents Form1 contains two buttons on the left top corner that allow selection of the model to view; a group of buttons below that allow selection of the control’s background color; two combo boxes that set the zoom percentage and AutoZoomMode properties; two groups of buttons that set the load and resize alignment properties; and a row of buttons on the right side of the form that set the interactive zoom/pan modes and reset the view. Model Switching Buttons • valve1ModelButton - displays top_valve1model when clicked • valve2ModelButton - displays top_valve2 model when clicked Control Background Color buttons • bgButton1-6 - Selects the control background by setting the viewer control background color to the background color of the selected button: gmsViewer1.BackColor = sender.BackColor ZoomPercent and AutoZoomMode Combo Boxes • zoomComboBox - Sets ViewManager.Zoom() to zoom the model • autoZoomModeComboBox - Sets ViewManager.AutoZoomMode() to None or FitModel Load and Resize Alignment Buttons Boxes • LoadTopLeftButton, etc. - Sets ViewManager.LoadAlignment to the selected alignment • resizeTopLeftButton, etc. - Sets ViewManager.ResizeAlignment to the selected alignment Zoom/Pan Modes Buttons • zoomInButton - Puts the control in a model where the user can zoom-in continuously when holding down the mouse by setting ViewManager.ZoomPanMode = ZoomPanMode.ContinuousZoomIn • zoomOutButton - Puts the control in a mode where the user can zoom-out continuously when holding down the mouse by setting ViewManager.ZoomPanMode = ZoomPanMode.ConintuousZoomOut

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-74 Example Applications

• zoomRectangleButton - Puts the control in a mode where the user can zoom to an area designated by drawing a rectangle by setting ViewManager.ZoomPanMode = ZoomPanMode.ZoomRectangle • panButton - Puts the control in a mode where the user can continuously pan when clicking and holding the mouse in a direction offset from center by setting ViewManager.ZoomPanMode = ZoomPanMode.ContinuousPan • dragPanButton - Puts the control in a mode where the user can perform discrete pans when clicking and dragging the mouse by setting ViewManager.ZoomPanMode = ZoomPanMode.DragPan • doneButton - Puts the control in the default mode where no user interactions are defined for zooming or panning by setting ViewManager.ZoomPanMode = ZoomPanMode.None • restoreViewButton - Restores the view to the zoom and pan coordinates when the model was first loaded by calling ViewManager.RestoreView() Models • top_valve1 - contains valve model • top_valve2 - contains alternative valve model Viewer Properties Default properties are used. Data The data source for AutoZoomMode, defined in “Datasource.cs”, is the same as demonstrated in the SimpleViewer exercise. Building AutoZoomMode To build the AutoZoomMode example, load the project solution file, “AutoZoomMode.sln”, into Visual Studio .NET. Use the Build command to build the executable.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-75 Example Applications

Running AutoZoomMode From Visual Studio .NET, select Debug->Start Without Debugging or Ctrl+F5 to execute the example. From a properly configured Command Prompt window, cd to the AutoZoomMode directory and execute one of the following batch files: run_rel (to run the release version) run_dbg (to run the debug version)

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-76 Example Applications

EmbeddedControls What are Embedded Controls? Embedded controls are .NET controls that can be instanced the same as any other GMS submodel as part of the GMS model. These controls are implemented by defining them as a GMS submodel, which retrieves attributes about the control such as assembly name and control class name to define which control will be rendered when the model is loaded into the GMSViewer control. Any .NET control can be implemented in this manner and several of the most common controls, such as Buttons, CheckBoxes, TrackBars, and TextBoxes from the Microsoft .NET assemblies have been pre-defined. WPF Controls used in this demo are only available in versions of SL-GMS for Visual Studio 2008 and .Net Framework 3.0 and above. Why use Embedded Controls? Though it is possible to simply instance controls in a Windows Form directly in Visual Studio .NET-- which may exist alongside or even on top of a GMSViewer control-- it is sometimes not desirable to implement it in that manner. Oftentimes, developers like to create generic applications that can load and animate any model developed using a GMS Editor, without having to make modifications to the Visual Studio application. In this way it is then possible for end users to create displays which contain graphics and controls without having knowledge of Visual Studio .NET or the developed application which will load and display them. A preference for placing control objects in spatial reference to other graphical objects in one editing environment is also common. For example, a user may wish to place a textbox, used for entering data relevant to a specific piece of equipment, next to the graphical representation of that equipment in the model. Using SL-GMSDraw for .NET to create Embedded Controls in a model Models may be loaded into SL-GMSDraw for .NET and the palette of pre-defined controls can be accessed by selecting “Palettes” from the Palettes pull-down menu and then selecting “Controls” or “WPF_Controls” from the Palette browser to open the Controls palette. These palettes

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-77 Example Applications

contain a variety of Windows Forms and WPF controls which can be dragged and dropped into the edit area. Pre-defined Controls The pre-defined Embedded Controls can be found in the GMS_HOME/symbols/Controls directory and include the following controls.

.NET Control *g file name Description Name Button Button.g Push button CheckBox ChecBox.g Check box HScrollBar HScrollBar.g Horizontal Scroll Bar Label Label.g Text label NumericUpDown NumericUpDown.g Spinbox ProgressBar ProgressBar.g Progress Bar RichTextBox RichTextbox.g Rich Text Entry Box TextBox TextBox.g One line Text entry box TrackBar TrackBar.g Scrolling Track Bar VScrollBar VScrollBar.g Vertical ScrollBar Button WPF_Button.g WPF Push Button CheckBox WPF_Checkbox.g WPF Check Box Label WPF_Label.g WPF Text Label ProgressBar WPF_ProgressBar.g WPF Progress Bar ScrollBar WPF_ScrollBar.g WPF Scroll Bar Slider WPF_Slider.g WPF Slider TextBox WPF_TextBox.g WPF Text Entry Box

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-78 Example Applications

Figure 3-14: Embedded Controls Example Application interaction with Embedded Controls Static properties can be set on an Embedded Control from the SL-GMSDraw for .NET editor, however the application can also interact with these controls in three ways: • Upon Model Load the application can get the handle to the control and set/get attributes • If the control has exposed properties as GMSVariables, those properties can be set/get by using a GMSVariable

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-79 Example Applications

• If the control has exposed events, those named events will be called in the application code How Embedded Controls are created A GmsEmbeddedControl SubModel contains a control instance, which determines the control's assembly and class, and a dynprop which specifies the exposed properties and events. For examples of embedded control submodels, look in the demo.net/GmsDraw/Controls directory. The following example will be using the submodel button.g to embed a Windows Forms button control. Step One: Create a Submodel Create a submodel *.g file with a text editor which will be used to embed the desired control: Button: model inst c1net 0 0 renamedvars \ assembly_load_mode :: 0 \ assembly_name :: "System.Windows.Forms" \ control_class_name :: "System.Windows.Forms.Button" \ control_name :: "Button" endm

This defines a submodel named “Button” which has an instance of the c1net submodel that is required for all embedded controls. The following renamed variables are used to uniquely define the .NET control. assembly_load_mode The assembly_load_mode specifies how the string specified in assembly_name will be used to locate and load the desired assembly. Three methods from the .NET Framework Assembly class are used: Assembly.Load Loads an assembly from the global assembly cache given its fully qualified name. A "fully qualified" assembly name includes its name, culture, public key, and version number, for example:

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-80 Example Applications

SL.GMS, Version=2.0.1896.16394, Culture=neutral, PublicKeyToken=c83b600fe4fd8e53 Assembly.LoadFrom Loads an assembly from a file given the file name or path. Assembly.LoadWithPartialName Loads an assembly from the application directory or from the global assembly cache using a partial name. The assembly_load_mode takes the values 0, 1, or 2, which use the above methods as follows: Value 0 Tries to load the assembly from the global cache. It will first try Assembly.Load, and if that fails it will try Assembly.LoadWithPartialName. Value 1 Tries to load the assembly from a file or pathname using Assembly.LoadFrom. It will first substitute environment variable values for environment variable names bracketed with '%' in the string. So for example to load the assembly MyAssembly from the bin sub-directory of the GMS_HOME directory, you would use the assembly_name string "%GMS_HOME%\bin\MyAssembly.dll". Value 2 Tries to load the assembly from the global cache using Assembly.Load. If that fails it will not try alternate methods. Note that Value 0 is the most flexible and may be used when you do not need to specify a specific version of the assembly, whereas value 2 may be used when you want only a specific version of the assembly to be used. Finally, Value 1 is useful if the assembly is not in the global assembly cache. assembly_name is the name of the assembly which contains the control control_class_name is the full name of the control contol_name is an arbitrary string which is user defined.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-81 Example Applications

Step Two: Implement any needed dynamics When embedded controls are instanced in SL-GMSDraw for .NET, it is possible to set all standard .NET properties exposed on the control to static values. In some cases it is desired to expose these properties so they can be controlled dynamically with GMSVariables. The following shows how to add a GMSVariable which would control the background color of this button: Button: model inst c1net 0 0 renamedvars \ assembly_load_mode :: 0 \ assembly_name :: "System.Windows.Forms" \ control_class_name :: "System.Windows.Forms.Button" \ control_name :: "Button" dynprop \ ( B G C o l o r \ ( = * \ (call GmsECSetIntegerProperty( "BackColor", BGColor)))) endm

In this example, the BackColor property of the control is exposed as a GMS renamed variable “BGColor” . This is accomplished with the dynamic user function “GmsECSetIntegerProperty”. Built-in User Functions GmsECSetIntegerProperty, GmsECSetDoubleProperty, and GmsECSetStringProperty are available for setting each type of data variable. The arguments to these functions, are the name of the .NET property as a string and an SL-GMS variable of the corresponding type: integer, double, or string. Step Three: Implement any needed events .NET controls interact with applications by raising events. For example, the .NET Button, when clicked, raises the event "Click.” In a Windows Forms application you would subscribe to this event and provide an event handler in your application code. In a GmsViewer application you also provide an event handler in your application code, but the process of subscribing to the event is different.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-82 Example Applications

Control events are exposed as renamed variables in a process similar to that used for properties. First, a User Method call is added to the dynprop; in this case the User Method is GmsECSetEventHandler, and it takes the event name as a string and an SL-GMS variable which is a string indicating the name of the embedded control event handler. Button: model inst c1net 0 0 renamedvars \ assembly_load_mode :: 0 \ assembly_name :: "System.Windows.Forms" \ control_class_name :: "System.Windows.Forms.Button" \ control_name :: "Button" dynprop \ (BGColor \ ( = * \ (call GmsECSetIntegerProperty( "BackColor", BGColor)))) ClickHandlerName \ ( = * \ (call GmsECSetEventHandler( "Click", ClickHandlerName)))) \ endm

Step Four: Convert from *.g to a *.m1 submodel From the start menu, open a GMS command prompt and change directory to where the *.g file exists. Type in gm1 button. This will convert the submodel and make it available for instancing in SL-GMSDraw for .NET. Step Five: Instance the submodel from SL-GMSDraw for .NET The new control submodel can be placed in the GmsDraw/controls directory and when SL-GMSDraw for .NET is started the new button submodel can be instanced with the Palette/Submodels menu and the static properties set. The renamed variables might be set as described below: BGColor: buttonColor ClickHandlerName :: "Button_Click"

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-83 Example Applications

This would indicate that the background color could be controlled by the current state of a GMSVariable called “buttonColor.” The event handler name "Button_Click" is associated with an actual event handler in the application code. This is done with a method on the GmsViewer class, AddEmbeddedControlEventHandler, which takes as its argument an object of class EmbeddedControlNamedEventHandler. Objects of this class are constructed with two arguments: the name of the event handler, as used in the renamed variable above, and a delegate to the actual event handler method: gmsViewer.AddEmbeddedControlEventHandler( new EmbeddedControlNamedEventHandler( "Button_Click", new System.EventHandler(Button_Click))); Finally, the application code would include the event handler method referenced above: private void Button_Click(object sender, System.EventArgs e) { . . . Any event raised by a control that might be of interest to an application, such as "MouseEnter" or "KeyPress", can be exposed, renamed, and handled as above. Differences between Windows Forms and WPF Embedded Controls The use of Windows Forms and WPF Embedded Controls in a model is basically the same. However, there are a few differences that are important. There are three areas of difference. First, the base submodel for building a custom WPF Embedded Control submodel is different. A WPF Embedded Control submodel instances a WPF_c1net submodel instead of a c1net submodel. Second, WPF Embedded Controls use different User Methods. The last difference exists because WPF controls are contained in an ElementHost control so they can be used in a Windows Forms application. There are new User Methods which allow access to this ElementHost control. The new User Methods for the WPF controls and ElementHost are explained below.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-84 Example Applications

The User Methods for setting properties directly on a WPF control are GmsECSetWPFIntegerProperty, GmsECSetWPFDoubleProperty and GmsECSetWPFStringProperty. Event handlers for WPF controls may be set with GmsECSetWPFEventHandler. These work the same way as the Windows Forms Embedded Control User Methods.

When a WPF control is created, SL-GMS automatically inserts it into an ElementHost control so that it can be used in a GmsUserControl (GmsEditor, GmsViewer). The new User Methods which set ElementHost properties are GmsECSetHostIntegerProperty, GmsECSetHostDoubleProperty and GmsECSetHostStringProperty. Event handlers for the ElementHost may be set with GmsECSetHostEventHandler. These methods work the same way as the other Embedded Control User Methods. The WPF *.g Embedded Control submodel below shows the use of the new WPF_c1net submodel as well as the Host (ElementHost) and WPF User Methods. WPF_TextBox: model inst WPF_c1net 0 0 . scale 0 0 1.5625 1.25 . dynprop \ (BackColor \ ( = * \ (call GmsECSetHostIntegerProperty("BackColor", BackColor)))) \ ( T a g \ ( = * \ (call GmsECSetHostStringProperty("Tag", Tag)))) \ ( T e x t \ ( = * \ (call GmsECSetWPFStringProperty("Text", Text)))) \ (TextChangedEventHandlerName \ ( = * \ (call GmsECSetWPFEventHandler("TextChanged", TextChangedEventHandlerName)))) renamedvars \ assembly_load_mode :: 0 \ assembly_name :: "PresentationFramework" \ control_class_name :: "System.Windows.Controls.TextBox" endm

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-85 Example Applications

New Features A feature available to WPF controls hosted in a Windows Forms application is the ability to map ElementHost control properties to WPF control properties. This may be done with the new User Methods GmsECAddHostPropertyMap and GmsECExtendHostPropertyMap. Below is the WPF Label Embedded Control submodel modified to allow the ElementHost Text property to be mapped to a property of the Label. This is done through a PropertyTranslator delegate. The relevant parts of the model and application which implement this are listed below.

WPF_Label Embedded Control submodel WPF_Label: model inst WPF_c1net 0 0 . scale 0 0 1.171875 1.4375 . dynprop \ (TextPropertyTranslatorName \ ( = * \ (call GmsECAddHostPropertyMap("Text", TextPropertyTranslatorName)))) \ (BackColor \ ( = * \ (call GmsECSetHostIntegerProperty("BackColor", BackColor)))) \ ( T a g \ ( = * \ (call GmsECSetHostStringProperty("Tag", Tag)))) \ ( T e x t \ ( = * \ (call GmsECSetHostStringProperty("Text", Text)))) renamedvars \ assembly_load_mode :: 0 \ assembly_name :: "PresentationFramework" \ control_class_name :: "System.Windows.Controls.Label" endm

Model that sets up a property translator for the WPF_Label instance . . . inst WPF_Label renamedvars \ TextPropertyTranslatorName :: "WPFContentControl_TextTranslator" .

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-86 Example Applications

. .

Application code that registers and implements a property translator . . . . gmsViewer.AddEmbeddedControlWPFPropertyTranslator( new PropertyTranslator( WPFContentControl_TextTranslator ) ); . . . private void WPFContentControl_TextTranslator( object host, string propertyName, object value ) { ElementHost elemHost =3D (ElementHost)host; ContentControl wpfContentControl =3D (ContentControl)elemHost.Child; wpfContentControl.Content =3D elemHost.Text; }

The following property mappings are provided by the .NET Framework by default. • BackColor -> Background • BackgroundImage -> Background • BackgroundImageLayout -> Background • Cursor -> Cursor • Font -> FontFamily, FontSize, FontStretch, FontStyle, FontWeight • Bold -> FontWeight • Italic -> FontStyle

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-87 Example Applications

• Strikeout -> TextDecorations • Underline -> TextDecorations • ForeColor -> Foreground • RightToLeft -> FlowDirection • Visible -> Visibility For more information on property mapping and extending property maps, see the .NET Framework documentation. There are two new methods that have been added to the GmsUserControl (GmsViewer, GmsEditor) for WPF Embedded Control support. The first is an overload to the AddEmbeddedControlEventHandler method. The new overload takes an EventHandler Delegate as the argument. The name that SL-GMS registers for the EventHandler is the method name (retrieved by reflection). This method is more convenient than its overload if the method name is the same name as is being registered with SL-GMS. The AddEmbeddedControlEventHandler methods are used for both Windows Forms and WPF Embedded Control EventHandlers. The second new method is AddEmbeddedControlWPFPropertyTranslator. This registers a PropertyTranslator which can then be used. This method is only for WPF Embedded Controls. Registration of EventHandlers and PropertyTranslators must be done BEFORE a model is opened. To allow custom User Methods to be used as property setters for Embedded Controls, a naming convention has been created. This makes it so that SL-GMS's variable binding can recognize the GmsVariable type that should be associated with the GmsVariable that triggers the User Method call. The User Method naming convention is: GmsECSet...Property(...)

where is "" (empty) or "WPF" is "Integer", "Double" or "String"

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-88 Example Applications

Below is an example of a custom User Method for setting a Uri property on a WPF control from a string GmsVariable. For more information about writing GmsUserMethods, see the User Methods example..

[GmsUserMethod] private static void GmsECSetWPFUriStringProperty( UserMethodArgs a, string propertyName, string propertyValue ) { const string NOT_GMS_EMBEDDED_CONTROL =3D "Not a GmsEmbeddedControl."; const string ERROR =3D "Error";

if (null == a.GmsObject) return null; // no GmsObject, something wrong

// Get the GmsEmbeddedControl

GmsModelInstance modinst =3D a.GmsObject.Owner.Owner as GmsModelInstance; if (null =3D=3D modinst) { MessageBox.Show( NOT_GMS_EMBEDDED_CONTROL, ERROR, MessageBoxButtons.OK ); return; }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-89 Example Applications

GmsEmbeddedControl embeddedControl =3D GmsUserControl.GetEmbeddedControlByModinst( modinst.Handle ); if (null =3D=3D embeddedControl) { MessageBox.Show( NOT_GMS_EMBEDDED_CONTROL, ERROR, MessageBoxButtons.OK ); return; }

// Make sure this is a WPF control

object control =3D embeddedControl.ControlObject; if (!(control is ElementHost)) { // not a WPF GmsEmbeddedControl MessageBox.Show( "Not a WPF GmsEmbeddedControl.", ERROR, MessageBoxButtons.OK ); return; }

// Set the Uri on the WPF control

// get the WPF control control =3D embeddedControl.UnderlyingControl; Type controlType =3D control.GetType(); try=20 { Uri url =3D (0 =3D=3D propertyValue.Length) ? null : new Uri( propertyValue ); PropertyInfo propertyInfo =3D controlType.GetProperty( propertyName ); propertyInfo.SetValue( control, url, null ); } catch (Exception ex) { MessageBox.Show( ex.ToString(), ERROR, MessageBoxButtons.OK ); } } Note that for WPF custom Embedded Controls, the WPF control must have FrameworkElement in its inheritance chain. FrameworkElement provides the Name property which is used by SL-GMSDraw for .NET.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-90 Example Applications

Transparency through the ElementHost container is not a feature that is supported at this time.

Features Demonstrated The Embedded Controls example shows five models which have an instance of every pre-defined control. The first two models, “Interaction” and "WPFInteraction", show how how these control submodels can be instanced and the renamed variables describing their event handlers are added to the object properties. The application then can handle the control’s events. These two models are the same except one uses Windows Forms Embedded Controls and the other uses WPF Embedded Controls. Currently there is no WPF NumericUpDown control, so a similar interaction is shown with a vertical Slider control. The third model, “Automation”, contains the same controls but shows how properties of the controls can be controlled via GmsVariables. The last two models, "OtherControls" and "WPFOtherControls" show how to create Embedded Control submodels for custom Windows Forms and WPF controls. You can interact with the Calendar and Pie chart on the "Other Controls" tab or turn on automation for them. The 3D Bar Chart on the "WPF Other Controls" tab can be rotated by clicking and dragging on the chart. The values for the 3D Bar Chart can be changed by changing the values shown in the text controls. The original 3D Bar Chart may be found under the "Interactive 3D Bar chart custom control in WPF (C# .Net) with rotation, touch-sense display and Databinding support" article on The Code Project web site. It has been modified for the EmbeddedControls example so it will work in an ElementHost control. It is licensed under the The Code Project Open License. The article URL is http://www.codeproject.com/KB/WPF/WPF_3D_Bar_chart_control.aspx Form Contents The example form contains five tabControls which switch between the “Interaction”, "WPFInteraction", “Automation”, "OtherControls" and "WPFOtherControls" models.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-91 Example Applications

Models • Automation • Interaction • OtherControls • WPFInteraction • WPFOtherControls Viewer Properties Default properties are used. Data Data simulation is used to update the GMSVariables which are driving the control properties in the Automation model. Building the EmbeddedControls Example To build the EmbeddedControls example, load the project solution file, “EmbeddedControls.sln”, into Visual Studio .NET. Use the Build command to build the executable. Running the EmbeddedControls Example From Visual Studio .NET, select Debug->Start Without Debugging or Ctrl+F5 to execute the example. From a properly configured Command Prompt window, cd to the EmbeddedControls directory and execute one of the following batch files: run_rel (to run the release version) run_dbg (to run the debug version)

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-92 Example Applications

Dynamic Creation

The Dynamic creation example shows how to programmatically create instances of the GMS objects GmsPolyLine, GmsText, GmsCircle, GmsRectangle, GmsSector, GmsPie, GmsSpline, GmsTextRectangle, GmsModelInstance, GmsImage, GmsGroup, and GmsFillGroup. It also shows how to set attributes on these objects using the GMS Attributes managers. And finally it demonstrates how to create a Property Grid dialog on mouse click over an object which will allow getting/setting of object properties.

Figure 3-15: Dynamic Creation Example

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-93 Example Applications

Features Demonstrated • How to instance and set properties of GMS Objects • How to use property grid dialogs Form Contents Form1 contains only one instance of the SL-GMS Microsoft .NET Viewer control. Models EmptyModel - An empty model loaded into the viewer control which will contain the instanced objects. Viewer Properties Default viewer properties are used. Object Instancing See the source in DynamicCreation.cs for examples of creating each type of GMS object, how to set their properties and how to use the Attribute managers when necessary. Property Grid Dialogs See PropertiesDialog.cs for examples on how to create property grid dialogs which get and set GMS object properties. Building Dynamic Creation To build the Dynamic Creation example, load the project solution file, “DynamicCreation.sln”, into Visual Studio .NET. Use the Build command to build the executable. Running Dynamic Creation From Visual Studio .NET select Debug->Start Without Debugging or Ctrl+F5 to execute the example. From a properly configured Command Prompt window, cd to the DynamicCreation directory and execute one of the following batch files: run_rel (to run the release version)

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-94 Example Applications

run_dbg (to run the debug version) Select the various objects with the left mouse button to bring up the property grid dialog and view the properties of each object and set them from this dialog.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-95 Example Applications

User Methods

User Methods are methods written in any Visual Studio-supported language which can be called from the SL-GMS dynamic scripting language. User methods are used in two general cases. The first is when it is desired to encapsulate the event behavior of a particular object from within the object itself. The second is when it is desirable to define how an object will change its appearance when data changes using Visual Studio as the scripting language, instead of the SL-GMS dynamic scripting language.

Figure 3-16: User Method Example Features Demonstrated • How to call a user-defined input method from SL-GMS dynamics • How to create a user defined input method for defining object input behavior

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-96 Example Applications

• How to call a user-defined output method from SL-GMS dynamics • How to create a user-defined output method for defining how object graphic behaviors change when data is changed. Form Contents Form1 contains only one instance of the SL-GMS Microsoft .NET Viewer control. Models animation - The model which contains objects that call user defined methods from their dynamics. Four objects in this model are acted on by user methods including: Object Information - Top text rectangle which will call the user method “SetDisplayObjectText()” when selected with the left mouse which displays the object class and object name selected in this text box. Mouse Event Information - The second text rectangle which calls two user methods on mouse selection. One displays the objects class and name in the object information text box (“SetDisplayObjectText”) and the other displays information about the mouse event in this text box (SetMouseInputText()). Color swatch - The third rectangle in the display which calls SetDisplayObjectText() on mouse selection and calls gmsNextColor() which continually changes the rectangle fill color. Ball - The moving ball at the bottom of the model which contains calls to the user function SetDisplayObjectText() on mouse selection and calls the output dynamic user method SetLocation(x,y) whenever the value of the variables x or y change which updates the location of the ball in the model. Viewer Properties Default viewer properties are used. Calling User Defined Input Methods from Dynamics To describe the different types of user methods we will look in detail at how these user methods are implemented on the ball. If the animation model is

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-97 Example Applications

loaded into SL-GMSDraw and the dynamic properties are displayed on the ball, the following input dynamics can be seen: # call SetDisplayObjectText()

The “#” symbol indicates that input methods to be called are listed on subsequent lines. On any event such as mouse clicks and mouse entry, this user function will be called. Defining the User Defined Input Methods in source code Static methods of type GmsUserMethod are automatically added to the globally available user methods, which may be activated from any object dynamics. User-defined input methods are activated by the “#” dynamics and passed in the EventUserMethodArgs, which describe the type of event which activated the method and the object that received the event. This, as well as other information passed in, can be used to filter for the event of interest and perform the desired action. In this example, if the event was a mouse down event, the object class name and the object instance named is retrieved from the object which received the event, and this information is presented in a text rectangle. If a mouse up event is received, the text is cleared. . // Set the text on the object saved by SaveDisplayObject(). // // This user method is used in input dynamics to set the text of // displayObject whenever a MouseDown occurs. When the corresponding // MouseUp occurs, the text is cleared. [GmsUserMethod] static void SetDisplayObjectText( EventUserMethodArgs ea ) {

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-98 Example Applications

if ( null == displayObject) return;

if (UserMethodEventType.Mouse == ea.EventType) if (UserMethodEventAction.Down == ea.EventAction) { // Only need to set the text once, so do it on MouseDown. displayObject.Text = ea.GmsObject.ClassName + ":" + ea.GmsObject.Name; } else if (UserMethodEventAction.Up == ea.EventAction) { // Clear the text on MouseUp. displayObject.Text = ""; } }

Calling User-Defined Output Methods from dynamics Output methods are those that are called when a GMSVariable has changed. In the ball object these dynamics are defined as: * call SetLocation(x, y)

The “*” symbol indicates unconditional dynamics and will cause any following user defined methods to be called if any of the GmsVariables included as parameters have been updated with new data. Defining the User-Defined Output Methods in source code The following code for SetLocation() takes two double values as new coordinates for the ball. The ball object is provided via the UserMethodArgs and the location of that object is updated with the new x and y values. [GmsUserMethod] static void SetLocation( UserMethodArgs a, double x, double y ) { // Ignore the y coordinate, just use the current y. a.GmsObject.Location = new SL.GMS.PointD( x, a.GmsObject.Location.Y ); }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-99 Example Applications

Building User Methods To build the User Methods example, load the project solution file, “UserMethods.sln”, into Visual Studio .NET. Use the Build command to build the executable. Running User Methods From Visual Studio .NET select Debug->Start Without Debugging or Ctrl+F5 to execute the example. From a properly-configured Command Prompt window, cd to the UserMethods directory and execute one of the following batch files: run_rel (to run the release version) run_dbg (to run the debug version) Select on the various objects with the left mouse button to display the object class and name in the green text rectangle. Click in the blue text rectangle to see mouse event information.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-100 Example Applications

Variable Binding

The Variable Binding example shows an advanced way to determine tag information necessary for determining the real-time data that drives dynamic behavior which allows for templating of hierarchical models. To describe this method, we will first look at an example template and how it might be constructed.

Figure 3-17: Variable Binding Example The above figure is first constructed by creating a “meter” submodel that only has one variable “value” which controls the fill percent of a rectangle.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-101 Example Applications

The second template submodel “unit” contains two instances of “meter” and the userdata on one is set to “meter1” and the other is set to “meter 2” The third template submodel is called “machine” and it includes two instances of the “unit” submodel with the userdata on one set to “unitA” and the other is set to “unitB”. The goal of this type of variable binding is to allow end users to make an instance of the object “machine” and only give a unique identifier indicating which machine is indicated instead of having to directly connect all four changing meter values to specific tags. The user could instance the machine submodel template and set the user data to be “machine123”. When this model is then loaded into the GmsViewer the necessary variables that would be needed to drive the dynamic graphics could then be automatically determined as: machine123.unitA.meter1.value machine123.unitA.meter2.value machine123.unitB.meter1.value machine123.unitB.meter2.value This sort of variable binding can be implemented with events which are available on the GmsViewer which are activated at model loading. The GmsVariableBinding event allows an application to specify how GmsVariables will be bound to data. The application can subscribe to this event by creating an event handler for this event. The event handler code has access to various items including • The names of the variables to be bound to data • User data on the model instance object containing this object • A binding context variable, that is, a GmsObject • User data for ancestors through the Owner property on GmsObject • A user-supplied “tag” object which will be returned to the application in the arguments of subsequent events. The GmsModelInstanceBinding and GmsModelInstanceBound events inform the application that the GmsViewer control has begun binding the variables in a GmsModelInstance, and has bound them, respectively. The

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-102 Example Applications

event handler code has access to the GmsModelInstance and the user-supplied “tag” object, as above. Note concerning GmsVariableBindingEventArgs Tag property The Tag property is shared among the three events described above. Thus if a Tag value is set in a GmsVariableBindingEventArgs object that same value will be returned in the GmsVariableBindingEventArgs object of a subsequent GmsVariableBinding event, as well as being returned in subsequent GmsModelInstanceBinding and GmsModelInstanceBound events. GmsVariableBinding event description The GmsViewer control has the GmsVariableBinding event for which clients may add event handlers. This event is raised before a GMS variable is bound to a variable reference if an event handler exists.

///

Occurs before a GmsVariable is bound to an SL-GMS variable reference. /// [Category("SL-GMS")] [Description("Occurs before a GmsVariable is bound to an SL-GMS variable reference")] public event GmsVariableBindingEventHandler GmsVariableBinding;

Client event handlers are methods with the same parameters as the GmsVariableBindingEventHandler delegate.

///

/// Represents a method that will handle a GmsModelInstanceBinding, /// GmsVariableBinding or GmsModelInstanceBound event of a /// GmsViewer control. /// public delegate void GmsVariableBindingEventHandler(object sender, GmsVariableBindingEventArgs args);

The GmsVariableBindingEventArgs class contains the following information:

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-103 Example Applications

. ///

/// Provides data for the GmsModelInstanceBinding, GmsModelInstanceBound /// and GmsVariableBinding events. /// public class GmsVariableBindingEventArgs : EventArgs { … /// /// Gets the GmsObject which contains the SL-GMS variable reference. /// For the GmsModelInstanceBinding and GmsModelInstanceBound events this /// object is the GmsModelInstance for which the event was raised. /// public GmsObject Object { get { … } }

///

/// Gets or sets an object that represents custom information about the event. /// This object will be the value of the Tag property in the /// GmsVariableBindingEventArgs of subsequent GmsModelInstanceBinding, /// GmsVariableBinding, and GmsModelInstanceBound events. /// public Object Tag { get { … } set { … } }

///

/// Gets or sets a GmsVariable object to be bound to the SL-GMS variable reference. /// public GmsVariable Variable { get { … } set { … } }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-104 Example Applications

///

/// Gets the SL-GMS variable reference name. /// public string VariableReferenceName { get { … } }

///

/// Gets the probable type of the GmsVariable. /// public GmsVariableType VariableType { get { … } }}

The GmsViewer control also has the GmsModelInstanceBinding and GmsModelInstanceBound events for which clients may add event handlers. These events are raised when a GmsModelInstance is encountered during variable binding if a corresponding event handler exists.

///

/// Occurs before binding GmsVariables in a GmsModelInstance. /// [Category("SL-GMS")] [Description("Occurs before binding GmsVariables in a GmsModelInstance")] public event GmsVariableBindingEventHandler ModelInstanceBinding {…}

///

/// Occurs after binding GmsVariables in a GmsModelInstance. /// [Category("SL-GMS")] [Description("Occurs after binding GmsVariables in a GmsModelInstance")] public event GmsVariableBindingEventHandler ModelInstanceBound {…}

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-105 Example Applications

Usage Event handlers may be added in the designer or in code: this.gmsViewer1.GmsVariableBinding += new GmsVariableBindingEventHandler(this.gmsViewer1_GmsVa riableBinding); this.gmsViewer1.GmsModelInstanceBinding += new GmsVariableBindingEventHandler(this.gmsViewer1_GmsMo delInstanceBinding); this.gmsViewer1.GmsModelInstanceBound += new GmsVariableBindingEventHandler(this.gmsViewer1_GmsMo delInstanceBound);

The GmsVariableBindingEventHandler method is expected to return a GmsVariable object via the event args. It has access to the GmsObject associated with the GMS variable reference to be defined. Using this information the event handler can identify the specific context of the GMS variable in the Model. This context might be used to construct a key to a database of application variables. This database could then be queried for information such as the variable’s type and initial value. Alternatively the GmsModelInstance objects in the GmsModel could determine the context for the GmsVariable references on objects within their GmsSubModels. In this case the application could subscribe to the GmsModelInstanceBinding and GmsModelInstanceBound events and use information on each GmsModelInstance encountered to construct a context for the GmsVariable references on the objects in the GmsSubModels. This context can be saved in the GmsVariableBindingEventArgs Tag property, where it will be passed on to subsequent GmsModelInstanceBinding, GmsModelInstanceBound and GmsVariableBinding events as well. In the following example a context is constructed as each GmsModelInstanceBinding event is received by adding its UserData to a list. The UserData is then removed from the list when the GmsModelInstanceBound event is received. When a GmsVariableBinding event is received, the list of UserData strings is used to construct a unique key for the variable. The key is used to obtain information about the variable in the form of a BindingObject, a hypothetical application-defined class that keeps track of

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-106 Example Applications

the relationship, or “binding,” between GMS variables and application variables. If the BindingObject indicates there is already a GmsVariable for this binding, the event handler just returns that GmsVariable. If not, it creates a new GmsVariable object using the information in the BindingObject, inserts it in the BindingObject, and returns it.

///

/// Handle a GmsModelInstanceBinding event ///

private void gmsViewer1_GmsModelInstanceBinding( object sender, GmsVariableBindingEventArgs args) { StringCollection sc;

Console.WriteLine("gmsViewer1_ GmsModelInstanceBinding called"); Console.WriteLine("\tSubModel Name = " + (args.Object as GmsModelInstance).SubModel.Name);

// If there is not yet a context object initialize one. if ( args.Tag == null ) { sc = new StringCollection(); args.Tag = sc;

// Add the top model’s UserData to the context object. sc.Add( args.Object.TopModel.UserData ); } else { sc = args.Tag as StringCollection; }

// Add the GmsModelInstance’s UserData to the context object. sc.Add( args.Object.UserData ); }

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-107 Example Applications

///

/// Handle a GmsModelInstanceBound event ///

private void gmsViewer1_GmsModelInstanceBound( object sender, GmsVariableBindingEventArgs args) { Console.WriteLine("gmsViewer1_ GmsModelInstanceBound called"); Console.WriteLine("\tSubModel Name = " + (args.Object as GmsModelInstance).SubModel.Name);

// Remove the last GmsModelInstance’s UserData from the context object. StringCollection sc = args.Tag as StringCollection; sc.RemoveAt( sc.Count-1 ); } ///

/// Return a GmsVariable from a GmsVariableBinding event ///

private void gmsViewer1_GmsVariableBinding(object sender, GmsVariableBindingEventArgs args) { Console.WriteLine("gmsViewer1_GmsVariableBinding called"); Console.WriteLine("\targs.VariableName = " + args.VariableReferenceName); Console.WriteLine("\targs.VariableType = " + args.VariableType); Console.WriteLine("\targs.Object.ClassName = " + args.Object.ClassName); // Construct unique key from the context supplied via the EventArgs StringCollection context = args.Tag as StringCollection; StringBuilder buildKey = new StringBuilder(); for (int i = 0; i < context.Count-1; i++) { buildKey.Append(context[i] + “.”); } string uniqueKey = buildKey.ToString() + context[i]; Console.WriteLine("\tUnique variable key = “ + uniqueKey); // Obtain a BindingObject using the unique key BindingObject bo = BindingObject.GetBinding(uniqueKey);

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-108 Example Applications

// If the BindingObject doesn't already contain a GmsVariable then create a new one if (bo.GmsVariable == null) { bo.GmsVariable = GmsVariableFactory.Create(bo.Type);

// Set the initial value of the GmsVariable bo.GmsVariable.Value = bo.Value; } // Return the GmsVariable that was found or created args.Variable = bo.GmsVariable; }

Features Demonstrated • How to create submodel templates described by userdata • How use variable binding events to determine the hierarchical tag data from these submodel templates Form Contents Form1 contains only one instance of GMSViewer Models meter - contains the filled rectangle which is animated by the variable “value” unit - contains two instances of the meter submodel which are differentiated by adding “meter1” and “meter2” to their respective userdata machine - contains two instances of unit which are differentiated by adding “unitA” and “unitB” to their respective userdata Viewer Properties Default Viewer properties are used Building VariableBinding To build the VariableBinding example, load the project solution file, “VariableBinding.sln”, into Visual Studio .NET. Use the Build command to build the executable.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-109 Example Applications

Running Variable Binding From Visual Studio .NET select Debug->Start Without Debugging or Ctrl+F5 to execute the example. This example is meant to be run from Visual Studio .NET only because the formation of the variable binding tags built from the events are displayed in the output console.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-110 Example Applications

Variable Binding Renamed Vars

The Variable Binding Renamed Vars example binds a seperate GmsVariable to each object's variables except when those variables are renamed for a model instance. The renamed variables are bound so they will be unique to the model instance. Userdata from the objects in the model are used to create unique variable names.

Figure 3-18: Variable Binding Renamed VariablesExample The model in the figure above is constructed by creating a "meter" submodel that has two variables, "d_value" and "i_fillColor" which control the fill percent and fill color of a rectangle. It also has a third variable, "s_meter_label" which controls the meter's name label.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-111 Example Applications

The second submodel, "unit", contains two instances of "meter" with the userdata on one is set to "meter1" and the other is set to "meter 2". "Unit" has one variable which controls its name label. The third submodel is called "machine" and it includes two instances of the "unit" submodel with the userdata on one set to "unitA" and the other is set to "unitB". The "unitB" variables "s_unit_label", "s_meter_label", and "i_fillColor" are renamed while the variables for "unitA" are left alone. The goal of this variable binding example is to show how the variable binding used in the original VariableBinding example can be mixed with a different variable binding for renamed variables. The unrenamed variables are bound the same way as in the VariableBinding example. Each unique renamed variable is bound to only one GmsVariable. The variables for "unitA" are created as follows. Unrenamed Variables machine1.unitA.meter1.d_value machine1.unitA.meter2.d_value machine1.unitA.meter3.d_value machine1.unitA.meter1.i_fillColor machine1.unitA.meter2.i_fillColor machine1.unitA.meter3.i_fillColor machine1.unitA.meter1.s_meter_label machine1.unitA.meter2.s_meter_label machine1.unitA.meter3.s_meter_label

The variables for "unitB" are created as follows. Unrenamed Variables machine1.unitB.meter1.d_value machine1.unitB.meter2.d_value machine1.unitB.meter3.d_value

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-112 Example Applications

Renamed Variables machine1.unitB.i_fillColor_changed machine1.unitB.s_meter_label_changed The names show that "i_fillColor_changed" and "s_meter_label_changed" are bound for "unitB" only one time while all the other variables are bound for each meter they are in (three times). Because of this each individual meter parameter is individually controllable in "unitA". The "unitB" meter values are individually controlled, but the fill color and meter labels for "unitB" are the same for all its meters. Usage The changes necessary to treat renamed variable differently aren't difficult. In the GmsModelInstanceBinding event, a dictionary and model instance prefix are pushed on top of a model instance stack. The model instance's renamed variables are added to the dictionary with a flag indicating whether a GmsVariable has been created for the renamed variable yet. By doing this, the stack entries will contain the model instance context for all the renamed variables currently active for binding.

private void gmsViewer_GmsModelInstanceBinding( o b j e c t s e n d e r , GmsVariableBindingEventArgs args ) { . . . // make context prefix string for this model instance string prefix = string.Empty; foreach (string s in sc) prefix =3D prefix + s + "."; prefix =3D prefix.TrimEnd( new char[] { '.' } );

// push renvar table & prefix on the stack for this modinst Dictionary dict = new Dictionary(); this.modinstContextStack.Push( new KeyValuePair, string>( dict, prefix ) =

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-113 Example Applications

// make hash table of rename variables decimal decVal; GmsRenamedPair[] varArray =

((GmsModelInstance)args.Object).Rename dVariables.GetRenamedPairs(); foreach (GmsRenamedPair pair in varArray) { // Skip variables that haven't been renamed

// Make sure // 1 - the variable is renamed // 2 - it isn't renamed to a string constant // 3 - it isn't renamed to a numeric constant if ((0 != pair.Value.Length) && !pair.Value.StartsWith( "\"" ) && !Decimal.TryParse( pair.Value, out decVal )) { // make entry of renamed variable name and flag // (flag indicates no GmsVariable created for this variable yet) dict.Add( pair.Value, false ); Console.WriteLine( "{0}\tVariable \"{1}\" renamed to \"{2}\"", tabs, pair.Name, pair.Value ); } } }

.In the GmsVariableBinding event, the getRenVarContext() method searches the model instance context stack to see if it finds a renamed variable matching the variable name passed in. The GmsVariableBinding event can then handle naming and GmsVariable creation differently for for a renamed variables than it does for other variables.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-114 Example Applications

private void gmsViewer_GmsVariableBinding( o b j e c t s e n d e r , GmsVariableBindingEventArgs args ) { . . . string uniqueKey = ""; KeyValuePair, string>? contextPair = this.getRenVarContext( args.VariableReferenceName ); if (contextPair.HasValue) { // This is a renamed variable ...... } else { // Not a renamed variable ...... }

When the GmsModelInstanceBound event is raised, all the variables for that instance are bound so the top entry is popped off of the model instance context stack. The result of all this is shown by two things. First, the meter labels in "unitA" are all "PSI". The other thing is that each checkbox under "unitA" controls a single meter's fill color. The checkbox under "unitB" controls the fill color for all the meters in "unitB". Features Demonstrated • How to create submodel templates described by userdata • How use variable binding events to determine the hierarchical tag data from these submodel templates

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-115 Example Applications

• How renamed variable information can be used in variable binding events Form Contents Form1 contains only one instance of GMSViewer Models meter - contains the filled rectangle which is animated by the variable “d_value” unit - contains three instances of the meter submodel which are differentiated by adding “meter1”, “meter2” and "meter3" to their respective userdata machine - contains two instances of unit which are differentiated by adding “unitA” and “unitB” to their respective userdata Viewer Properties Default Viewer properties are used Building VariableBinding To build the VariableBinding example, load the project solution file, “VariableBinding.sln”, into Visual Studio .NET. Use the Build command to build the executable. Running Variable Binding From Visual Studio .NET select Debug->Start Without Debugging (Ctrl+F5) to execute the example. This example is meant to be run from Visual Studio .NET only because the formation of the variable binding tags built from the events are displayed in the output console.

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-116 Example Applications

Version 3.3 - June 2010 SL-GMS Draw Users Guide 3-117 NOTES NOTES