# HOOPS/Winforms Integration Guide

## Introduction

The HOOPS/Winforms integration consists a connection between HOOPS/3dGS and the Winforms ‘Panel’ and ‘Form’ GUI objects. This document describes how to use the HOOPS/Winforms integration to build a .NET Winforms application that incorporates the HOOPS/3DF components. Some familiarity with .NET Winforms, HOOPS/3dGS and HOOPS/MVO is assumed.

Developers should start by compiling and running the basic csharp_simple application as the starting point for their application. This is the primary example for .NET developers wishing to incorporate the HOOPS/3DF components into either existing or new .NET applications. The readable source code is located in your <hoops>/demo/dotnet/csharp_simple and <hoops>/demo/dotnet/vb_simple directories.

## Compilation and Runtime Information

The following steps are required to compile and run a HOOPS/Winforms based application:

- Compiling: Your application must reference the HOOPS/3DF C# wrapper classes.

  > - hoops_cs.dll
  > - hics_cs.dll
  > - hoops_mvo_cs.dll
  > - hoops_stream_cs.dll
  > - hoops_panel.dll

- Executing: Ensure that the following native .DLLs are in your application’s directory or in your PATH.

  > - hoops_vc.dll
  > - hcs.dll
  > - hics.dll
  > - hoops_mvo_mgk_vc.dll
  > - hcsmvo.dll
  > - hoops_stream_vc.dll
  > - hcsstream.dll
  > - hoops_panel.dll

The above files are located in your <VISUALIZE_INSTALL_DIR>/bin/nt_x64_v<version> directory.

## Component Object Relationships

This section discusses the relationship between .NET Winforms and HOOPS/3DF components. Building an application with both these toolkits minimally involves using the following objects from each component.

### Winforms

A .NET Winforms application typically has a master Form object, which contains child forms. Each child form may contain a Panel.

### HOOPS/Winforms

There should be at least one set of the `HNPanel` and `HNForm` objects, where the panel gets attached to the form. You usually create a custom panel and form derived from `HNPanel` and `HNForm`. The `HNPanel` and `HNForm` classes are found in <hoops>/Dev_Tools/hoops_winforms/source/.

### HOOPS/MVO

`HBaseModel`, `HBaseView`, and an operator class derived from `HBaseOperator`. Applications that want to implement selection of geometry will also need a `HSelectionSet` object. These objects are all connected by private data members which store pointers to other objects in the following manner:

## Steps to Building an Application with .NET Winforms and HOOPS

Programming with an object oriented GUI framework like .NET Winforms involves creating a set of objects and defining the ways in which they are connected, the manner in which they send and receive messages, and then launching the framework’s event loop. Building an application using .NET Winforms and HOOPS/3DF specifically requires creation and initialization of:

- NET Winforms application objects
- HOOPS/Winforms objects
- HOOPS/MVO objects

## Creating and Initializing the Application

A .NET Winforms application usually creates a master Form object which implements the function `Main()`. The csharp_simple application does this in it’s primary csharp_simple.cs source file as follows:

    public class SimpleAppForm : Form
    {
       ...

            /*! Entry point for the application*/
            static void Main()
            {
                    SimpleAppForm hoops = new SimpleAppForm();
                    Application.Run(hoops);
            }

            ...
    }

## Creating and Initializing HOOPS/Winforms Objects

The HOOPS/Winforms integration consists of a customized .NET Winforms ‘Form’ and ‘Panel’ called `HNForm` and `HNPanel`, as diagrammed up above. (Again, the Panel will get attached to the form.) As many pairs of these objects can be created as needed to implement the GUI’s design. Your application should define custom HNForm and HNPanel classes, as shown in csharp_simple source.

Custom `HNPanel` definition taken from the csharp_simple project’s SimpleHNPanel.cs source file:

    public class SimpleHNPanel : HNPanel
    {
            // Constructor which calls the Init() method of the class
            public SimpleHNPanel(): base()
            {
                    Init();
            }

            // This method will set up the default HOOPS/MVO view for the panel and attach a HOOPS/MVO default operator
            public new void Init()
            {
                    // contents reviewed later
            }

            ...
    }

Here is custom `HNForm` definition taken from the csharp_simple project’s SimpleHNForm.cs source file. Note that it creates the custom `HNPanel` object and initializes the form:

    public class SimpleHNForm : HNForm
    {
            ...

            // Sets up the panel and window
            public void Init(object sender, EventArgs e)
            {
                    // set up the panel that HOOPS will draw into
                    m_pHNPanel = new SimpleHNPanel();

                    Instance = (this.IsMdiChild) ? ((HForm)this.MdiParent).win_count : 0;

                    // first set up the window, then set the axis triad options
                    Init_Form();

                    m_pHNPanel.m_pHView.Update();
                    m_pHNPanel.m_pHView.SetAxisMode(AxisMode.AxisOn);
                    m_pHNPanel.m_pHView.AdjustAxisWindow();

                    ...
            }

            ...
    }

Finally, we can note that the `fileNew` and `fileOpen` methods of main app object (`SimpleAppForm`, again located in csharp_simple.cs) will create the custom `HNForm` object:

    public class SimpleAppForm : Form
    {
                    ...

                    private void fileNewMenu_Click(object sender, EventArgs e)
                    {
                            SimpleHNForm frmchild = new SimpleHNForm();
                            frmchild.MdiParent = this;
                            frmchild.Show();
                            win_count++;
                    }

                    private void fileOpenMenu_Click(object sender, EventArgs e)
                    {
                            OpenFileDialog dlg = new OpenFileDialog();
                            dlg.Title = "Open";
                            dlg.Filter = "HMF/HSF files (*.hmf, *.hsf)|*.hmf;*.hsf" +
                                                     "|All files (*.*)|*.*";

                            if (dlg.ShowDialog() == DialogResult.OK)
                            {
                                    SimpleHNForm frmchild = new SimpleHNForm();
                                    frmchild.MdiParent = this;
                                    frmchild.Show();

                                    frmchild.LoadFile(dlg);
                                    win_count++;
                            }
                            dlg.Dispose();
                    }

                    ...
    }

## Creating and Initializing HOOPS/MVO Objects

### HDB

One global pointer to a HOOPS/MVO HDB object should be declared and initialized in your application’s main class. The csharp_simple app does this in the main `SimpleAppForm` constructor (located in csharp_simple.cs):

    public class SimpleAppForm : Form
    {
            ...

            // Constructor which initializes hoops database and GUI features of the main window */
            public SimpleAppForm()
            {
                    win_count = 1;

                    m_pHDB = new HDB();
                    m_pHDB.Init();

                    ...
            }

            ...
    }

### HBaseModel

Multiple `HBaseModel` objects can be created as needed. The csharp_simple app creates one for every `SimpleHNPanel` object (i.e., there is a one-to-one mapping of `HBaseModel` to `SimpleHNPanel` objects) and does so in the `SimpleHNPanel::Init`:

    public class SimpleHNPanel : HNPanel
    {
      ...

      public new void Init()
      {
            ...

            m_pHModel = new HSimpleModel();
            m_pHModel.Init();

            ...
      }

    }

### HBaseView

Multiple `HBaseView` objects can be created as needed, with one object usually being created for each `HNPanel`. The `HBaseView` needs a valid native GUI window id passed to its constructor on object creation; this information is used to connect a HOOPS/3dGS output driver instance to a HNPanel. This requires that the `HNPanel`, to which the `HBaseView` will be attached, already exist prior to creating the `HBaseView` object.

Your app should create the `HBaseView` object in your overloaded `HNPanel::Init` method. Here is the csharp_simple example taken from csharp_simple.cs:

    public class SimpleHNPanel : HNPanel
    {
            ...

            public new void Init()
            {
                    ...

                    m_pHView = new HSimpleView(m_pHModel, "?picture" + SimpleHNForm.Instance, "opengl", "", winid);
                    m_pHView.Init();

                    ...
            }

    }

### HSelectionSet

The `HBaseView` class and `HNPanel` class contain pointers to a `HSelectionSet` object. A selection set class would typically be created and initialized during `HNPanel` initialization. After creation, it’s important to pass the `HSelectionSet` operator into `HBaseView` by calling `HBaseView::SetSelection`. The csharp_simple app does this in the overloaded method of `HNPanel::Init` method:

    public class SimpleHNPanel : HNPanel
    {
            ...

            public new void Init()
            {
                    ...

                    // view and model initialization goes here, and was discussed previously

                    // Set up the custom HSelectionSet object
                    m_pHSelection = new HSimpleSelectionSet(m_pHView);
                    m_pHView.SetSelection(m_pHSelection);
                    m_pHView.GetSelection().Init();

                    ...
            }

    }

### HBaseOperator

The `HBaseView` class and `HNPanel` class contains pointers to a `HBaseOperator` object. A default operator would typically be created and initialized during `HNPanel` initialization. After creating, you should set it to be the current operator by calling the utility method `HNPanel::SetCurrentOperator`. The csharp_simple app does this in the overloaded method of `HNPanel::Init` method:

    public class SimpleHNPanel : HNPanel
    {
            ...

            public new void Init()
            {
                    ...

                    // Set the default operator
                    m_pHOperator = new HOpCameraManipulate(m_pHView);
                    m_pHView.SetCurrentOperator((HBaseOperator)m_pHOperator);

                    ...
            }

    }

Conversation saved
HOOPSY BETA

### Hello! I'm HOOPSY

Your multilingual generative AI assistant for documentation. Ask me anything about HOOPS Visualize 3DF in your own language, or choose a sample question below to start a conversation:

What is HOOPS Visualize 3DF?
What are the latest release notes for HOOPS Visualize 3DF?
How do I start evaluating HOOPS Visualize 3DF?
How do I write my first sample application?
How can I get assistance?

HOOPSY may store conversations according to OpenAI's policy. Responses may not always be accurate.

HOOPSY is thinking...