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 theview_instance
parameter in subsequent methods. Note thatparent
parameter might be0
. In that case, methodHostViewParent
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: Parameterevent_callback_data
is for internal use only and must be propagated whan callingevent_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\