Skip to content

Custom UI Controls Development

If the built-in UI components (controls) don't meet your requirements, you can expand the system by adding your own custom controls. For instance, if you need to archive and display X-ray scans, our existing viewers may not support this functionality. However, your X-ray scanner likely includes software with a viewing library (typically provided as a .dll). While you can't use this library directly, you can create a wrapper .dll by following the guidelines outlined below.

Library Wrapper

The first step is to create the wrapper dll. You can use any development environment that supports generating dlls and exporting methods using the __stdcall calling convention. We recommend using either Visual Studio (Community Edition is sufficient) or Embarcadero Delphi/C++ (Community Edition is also sufficient). Your library must export the following methods:

HANDLE  __stdcall HostViewCreate( 
    const wchar_t* name, 
    HWND           parent 
);

void    __stdcall HostViewDestroy( 
    HANDLE view_instance 
);

void   __stdcall HostViewParent( 
    HANDLE view_instance, 
    HWND   parent 
);

void    __stdcall HostViewResize(
    HANDLE view_instance, 
    int    width, 
    int    height 
);

VARIANT __stdcall HostViewCall( 
    HANDLE         view_instance, 
    const wchar_t* method, 
    const VARIANT* args, 
    const int      args_count 
);

typedef VARIANT(__stdcall* EventCallback)(  
    HANDLE         view_instance, 
    const wchar_t* event_name, 
    const void*    event_data, 
    VARIANT*       args, 
    int            args_count 
);

void   __stdcall HostViewEvent( 
    HANDLE              view_instance, 
    const wchar_t*      event_name, 
    const EventCallback event_callback, 
    const void*         event_data 
);
function HostViewCreate( 
    const name: PChar; 
    parent: HWND 
): THandle; stdcall;

procedure HostViewDestroy( 
    view_instance: THandle 
); stdcall;

procedure HostViewParent( 
    view_instance: THandle; 
    parent: HWND 
); stdcall;

procedure HostViewResize( 
    view_instance: THandle; 
    widht, height: Integer
); stdcall;

function HostViewCall( 
    view_instance: THandle; 
    const method_: PChar; 
    const args: array of Variant 
): Variant; stdcall;

type
TEventCallback = procedure( view_instance: THandle; 
                            const event_name: PChar; 
                            const event_callback_data: Pointer; 
                            const args: array of Variant ); stdcall;
procedure HostViewEvent( 
    view_instance: THandle; 
    const event_name: PChar; 
    const event_callback: TEventCallback; 
    const event_callback_data: Pointer 
); stdcall;
  • HostViewCreate: In this method, you need to create your control. Then, return the handle or pointer to your control. Keep in mind that the value you return in this method will be provided as the view_instance parameter in subsequent methods. Note that parent parameter might be 0. In that case, method HostViewParent will be called later.
  • HostViewDestroy: Use this method to destroy your wrapped control and clean up any library objects when the UI element is released.
  • HostViewParent: Sets your control's parent window handle.
  • HostViewResize: This method is called to resize the wrapped control.
  • HostViewCall: This serves as the entry point for all the methods provided by your control.
  • HostViewEvent: Implement this method if you need to register an event callback that can be triggered later from within your library.
    Important: Parameter event_callback_data is for internal use only and must be propagated whan calling event_callback.

HostView

Next, you need to create the JavaScript representation of your control. Start by creating a new control under UI→UI Controls. To do this, select UI→UI Controls in the application tree, right-click, and choose the New Application command from the context menu. Assign a Name/Label to your control (for example, MyCustomView) and click Make button. Place your .dll in your control's directory (in this case C:\Users\User\Documents\NodeActa-dev\Apps\UI\Controls\MyCustomView\). When uploading your new control in the Application Center, you will be prompted to add this dll to the archive, too. Remember, this approach ensures that your library is accessible to all users on all machines without requiring you to distribute the library yourself. Please ensure that your library's name includes a platform designation, such as mylib.x64.dll for 64-bit and mylib.x32.dll for 32-bit. It is recommended to provide both versions, as you may have client applications running in both 32-bit and 64-bit environments. The system will automatically load the appropriate library.
Finally, add a code similar to the example below to your control's script.

export class MyCustomView extends HostView {
    constructor(parent) {
        // You should not specify .dll file extension. 
        // The system will automatically search for mylib.x64.dll
        // (or mylib.x32.dll) depending on platform, and at the end 
        // it will try with mylib.dll 
        super('mylib', 'MyCustomView', parent);
    }

    someMethodInDll(argument1, argument2, argument3) {
        // this will call your dll's HostViewCall() method 
        // with the 'name' parameter set to `someMethodInDll`
        this.call('someMethodInDll', argument1, argument2, argument3); 
    }

    get wasClicked() {
        // this will call your dll's HostViewCall() method 
        // with the 'name' parameter set to `wasClicked`
        return this.call('wasClicked');
    }

    myClickEvent(handler) {
        // this will call your's dll HostViewEvent() method 
        // with the 'name' parameter set to `myClickEvent`.
        return this.event('myClickEvent', handler);
    }
}

C/C++ Example

A simplified example of a button control demonstrating click event callback is available, after installing the Application Center, in:
C:\Program Files\NodeActa\AppCenter\Examples\CustomUIView\

Delphi Example

A much more complex example used for displaying Charts is available, after installing the Application Center, in:
C:\Program Files\NodeActa\AppCenter\Examples\ChartView\