SDK Question Orbiter NG Plugin

infotechggs

New member
Joined
May 29, 2014
Messages
10
Reaction score
0
Points
1
Question in details:
By launching the Orbiter NG version without the D3D9 it is not possible to interface with the plugin launcher bar.
For example, typing the word 'gui' starts a very limited plugin.
Does anyone know if it is possible to create a plugin for the Orbiter NG (No graphics) version?
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,404
Reaction score
581
Points
153
Location
Vienna
Question in details:
By launching the Orbiter NG version without the D3D9 it is not possible to interface with the plugin launcher bar.
For example, typing the word 'gui' starts a very limited plugin.
Does anyone know if it is possible to create a plugin for the Orbiter NG (No graphics) version?

What do you mean with plugin launcher bar? There is a custom functions dialog that allows you to open dialogs of plugins, do you have that in mind?

Of course it is possible to create plugins for Orbiter NG that work without a graphics client. This is evident if you start it, because it shows you all the plugins that get loaded and initiated (Gbodies, vessels, MFDs, etc.).
 

infotechggs

New member
Joined
May 29, 2014
Messages
10
Reaction score
0
Points
1
Hi Face thanks for the quick response.
As launcher bar i mean the Orbiter Custom Function by pressing CTRL+F4 that doesn not work with Orbiter NG.
For example: i need to develop a plugin like SCNEditor that work with Orbiter NG.
Thanks
Enrico
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,404
Reaction score
581
Points
153
Location
Vienna
Hi Face thanks for the quick response.
As launcher bar i mean the Orbiter Custom Function by pressing CTRL+F4 that doesn not work with Orbiter NG.
For example: i need to develop a plugin like SCNEditor that work with Orbiter NG.

I see. In essence, your problem is that you don't have a way to open up your custom dialog, right? In this case, nothing stops you from developing a plugin that pops up its own dialog unconditionally on simulation start. I know that it works because I do this with OMP, and I have it running in a "headless" Orbiter NG session since 3 years now.
 

infotechggs

New member
Joined
May 29, 2014
Messages
10
Reaction score
0
Points
1
custom plug-in

I see. In essence, your problem is that you don't have a way to open up your custom dialog, right? In this case, nothing stops you from developing a plugin that pops up its own dialog unconditionally on simulation start. I know that it works because I do this with OMP, and I have it running in a "headless" Orbiter NG session since 3 years now.

Hy Face,
starting from the following code i tried without success to open a GUI at Orbiter Startup even with D3D9 enabled.
What do you think will be the solution to this problem?

#define ORBITER_MODULE
#define STRICT

#include "Orbitersdk.h"

// Global variables
int g_cmdID = NULL;
HINSTANCE g_hInstance = NULL;
HWND g_hWnd = NULL;
HWND g_hWndOrbiter = NULL;

// Global functions
void OpenWindow(void* context);
LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

DLLCLBK void InitModule(HINSTANCE hModule)
{
g_hInstance = hModule;

// Standard custom command registration.
g_cmdID = oapiRegisterCustomCmd("Win32 Test", "Win32 Test", &OpenWindow, NULL);

// Register the window class.
WNDCLASS wndClass;
wndClass.style = CS_HREDRAW|CS_VREDRAW;
wndClass.lpfnWndProc = &WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hModule;
wndClass.hIcon = NULL;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = "Test Window"; // Don't forget to match this class name when you create the window!
if(!RegisterClass (&wndClass))
MessageBox(NULL, "Cannot register window.", "Error", MB_ICONERROR);
}

DLLCLBK void ExitModule(HINSTANCE hModule)
{
// Just to clean everything when the user deselects your module.
if(g_cmdID)
oapiUnregisterCustomCmd(g_cmdID);
}

DLLCLBK void opcOpenRenderViewport(HWND hRenderWnd, DWORD width, DWORD height, BOOL fullscreen)
{
// =====================================================
// You'll need this pointer during the creation of the window
// =====================================================
g_hWndOrbiter = hRenderWnd;
}

DLLCLBK void opcCloseRenderViewport()
{
// To faciliate debugging.
g_hWndOrbiter = NULL;
}

void OpenWindow(void* context)
{
// Create window
g_hWnd = CreateWindowEx(
WS_EX_TOOLWINDOW, // tool window extend style. Looks better with the other windows.
// You can use WS_EX_OVERLAPPEDWINDOW which provides minimizing functionnality.
"Test Window", // class name
"Test", // window name
WS_OVERLAPPEDWINDOW|WS_VISIBLE, // visible overlapped window
CW_USEDEFAULT, // default horizontal position
CW_USEDEFAULT, // default vertical position
CW_USEDEFAULT, // default width
CW_USEDEFAULT, // default height
// ======================================================================================
// This is vital if you want your module to be available in fullscreen mode.
// We specify the Orbiter window as the parent, but we do not specify WS_CHILD.
// Therefore, Windows creates an owned window by Orbiter, and always keep it
// above Orbiter in the z-order.
(HWND) g_hWndOrbiter, // Orbiter window as parent, to create a owned window
//=======================================================================================
(HMENU) NULL, // No menu
g_hInstance, // DLL instance handle
NULL);

if(!g_hWnd)
{
MessageBox(NULL, "Cannot create window", "Error", MB_ICONERROR);
return;
}
// ==============================
// Register the window to Orbiter
// ==============================
if(!oapiRegisterWindow(g_hInstance, g_hWnd, NULL))
MessageBox(NULL, "Cannot register window to Orbiter.", "Error", MB_ICONERROR);
}

LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
// TODO: Add handled messages
// Don't forget to return 1!
}

// ====================================================================
// This function redraws Orbiter window when you move the child window.
// Help reducing the "big white area".
// Since this is not a dialog, you DO NOT RETURN ITS VALUE.
// Actually, I'm pretty sure it always returns 0.
// ====================================================================
oapiDefDialogProc (hWnd, uMsg, wParam, lParam);

// ==========================================================================
// This function is vital. Without this line, your window creation will FAIL.
// This is the returned value when you do not handle a message.
// ==========================================================================
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,404
Reaction score
581
Points
153
Location
Vienna
The solution is that you do this:

In this case, nothing stops you from developing a plugin that pops up its own dialog unconditionally on simulation start.

Your code is not doing much on simulation start (OpenRenderViewport). Why not call the window open function there to open the dialog unconditionally?
 

infotechggs

New member
Joined
May 29, 2014
Messages
10
Reaction score
0
Points
1
Open addictional windows with Orbiter_NG

Thank you Face.
I've posted the code in order to help also the other members of the forum just in case.
So, following your suggestion i've moved part of the initmodule code into opcOpenRenderViewport.


This code is fully functional and start a windows with D3D9 enabled and disabled.

#define ORBITER_MODULE
#define STRICT

#include "Orbitersdk.h"

// Global variables
int g_cmdID = NULL;
HINSTANCE g_hInstance = NULL;
HWND g_hWnd = NULL;
HWND g_hWndOrbiter = NULL;

// Global functions
void OpenWindow(void* context);
LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

DLLCLBK void InitModule(HINSTANCE hModule)
{
g_hInstance = hModule;

// Standard custom command registration.
//g_cmdID = oapiRegisterCustomCmd("Win32 Test", "Win32 Test", &OpenWindow, NULL);

//// Register the window class.
//WNDCLASS wndClass;
//wndClass.style = CS_HREDRAW|CS_VREDRAW;
//wndClass.lpfnWndProc = &WndProc;
//wndClass.cbClsExtra = 0;
//wndClass.cbWndExtra = 0;
//wndClass.hInstance = hModule;
//wndClass.hIcon = NULL;
//wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
//wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
//wndClass.lpszMenuName = NULL;
//wndClass.lpszClassName = "Test Window"; // Don't forget to match this class name when you create the window!
//if(!RegisterClass (&wndClass)) MessageBox(NULL, "Cannot register window.", "Error", MB_ICONERROR);
}

DLLCLBK void ExitModule(HINSTANCE hModule)
{
// Just to clean everything when the user deselects your module.
if(g_cmdID)
oapiUnregisterCustomCmd(g_cmdID);
}

DLLCLBK void opcOpenRenderViewport(HWND hRenderWnd, DWORD width, DWORD height, BOOL fullscreen)
{
// =====================================================
// You'll need this pointer during the creation of the window
// =====================================================
g_hWndOrbiter = hRenderWnd;
//g_cmdID = oapiRegisterCustomCmd("Win32 Test", "Win32 Test", &OpenWindow, NULL);

// // Register the window class.
WNDCLASS wndClass;
wndClass.style = CS_HREDRAW|CS_VREDRAW;
wndClass.lpfnWndProc = &WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = g_hInstance;
wndClass.hIcon = NULL;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = "Test Window"; // Don't forget to match this class name when you create the window!
if(!RegisterClass (&wndClass)) MessageBox(NULL, "Cannot register window.", "Error", MB_ICONERROR);



// Create window
g_hWnd = CreateWindowEx(
WS_EX_TOOLWINDOW, // tool window extend style. Looks better with the other windows.
// You can use WS_EX_OVERLAPPEDWINDOW which provides minimizing functionnality.
"Test Window", // class name
"Test", // window name
WS_OVERLAPPEDWINDOW|WS_VISIBLE, // visible overlapped window
CW_USEDEFAULT, // default horizontal position
CW_USEDEFAULT, // default vertical position
CW_USEDEFAULT, // default width
CW_USEDEFAULT, // default height
// ======================================================================================
// This is vital if you want your module to be available in fullscreen mode.
// We specify the Orbiter window as the parent, but we do not specify WS_CHILD.
// Therefore, Windows creates an owned window by Orbiter, and always keep it
// above Orbiter in the z-order.
(HWND) g_hWndOrbiter, // Orbiter window as parent, to create a owned window
//=======================================================================================
(HMENU) NULL, // No menu
g_hInstance, // DLL instance handle
NULL);

}

DLLCLBK void opcCloseRenderViewport()
{
// To faciliate debugging.
g_hWndOrbiter = NULL;
}

//void OpenWindow(void* context)
//{
// // Create window
// g_hWnd = CreateWindowEx(
// WS_EX_TOOLWINDOW, // tool window extend style. Looks better with the other windows.
// // You can use WS_EX_OVERLAPPEDWINDOW which provides minimizing functionnality.
// "Test Window", // class name
// "Test", // window name
// WS_OVERLAPPEDWINDOW|WS_VISIBLE, // visible overlapped window
// CW_USEDEFAULT, // default horizontal position
// CW_USEDEFAULT, // default vertical position
// CW_USEDEFAULT, // default width
// CW_USEDEFAULT, // default height
// // ======================================================================================
// // This is vital if you want your module to be available in fullscreen mode.
// // We specify the Orbiter window as the parent, but we do not specify WS_CHILD.
// // Therefore, Windows creates an owned window by Orbiter, and always keep it
// // above Orbiter in the z-order.
// (HWND) g_hWndOrbiter, // Orbiter window as parent, to create a owned window
// //=======================================================================================
// (HMENU) NULL, // No menu
// g_hInstance, // DLL instance handle
// NULL);
//
// if(!g_hWnd)
// {
// MessageBox(NULL, "Cannot create window", "Error", MB_ICONERROR);
// return;
// }
// // ==============================
// // Register the window to Orbiter
// // ==============================
// if(!oapiRegisterWindow(g_hInstance, g_hWnd, NULL))
// MessageBox(NULL, "Cannot register window to Orbiter.", "Error", MB_ICONERROR);
//}


LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
// TODO: Add handled messages
// Don't forget to return 1!
}

// ====================================================================
// This function redraws Orbiter window when you move the child window.
// Help reducing the "big white area".
// Since this is not a dialog, you DO NOT RETURN ITS VALUE.
// Actually, I'm pretty sure it always returns 0.
// ====================================================================
oapiDefDialogProc (hWnd, uMsg, wParam, lParam);

// ==========================================================================
// This function is vital. Without this line, your window creation will FAIL.
// This is the returned value when you do not handle a message.
// ==========================================================================
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

---------- Post added at 10:33 AM ---------- Previous post was at 06:52 AM ----------

Anyway now i'm trying to modify the DialogTemplate.sln to make it possible to launch a gui without D3D9.(This project use oapiOpenDialogEx instead of CreateWindowEx)

I moved the init code from InitModule to opcOpenRenderViewport and the plugin work well if D3D9 is enabled but does not work if D3D9 is disable(Orbiter NG).
Do any have an idea about that?



// ==============================================================
// ORBITER MODULE: DialogTemplate
// Part of the ORBITER SDK
// Copyright (C) 2003-2016 Martin Schweiger
// All rights reserved
//
// DialogTemplate.cpp
//
// This module demonstrates how to build an Orbiter plugin which
// opens a Windows dialog box. This is a good starting point for
// your own dialog-based addons.
// ==============================================================

#define STRICT
#define ORBITER_MODULE
#include "windows.h"
#include "orbitersdk.h"
#include "resource.h"
#include <stdio.h>

// ==============================================================
// Global variables
// ==============================================================

HINSTANCE g_hInst; // module instance handle
DWORD g_dwCmd; // custom function identifier
int myprm = 0;
HWND g_hWndOrbiter = NULL;
// ==============================================================
// Local prototypes
// ==============================================================

void OpenDlgClbk (void *context);
BOOL CALLBACK MsgProc (HWND, UINT, WPARAM, LPARAM);

// ==============================================================
// API interface
// ==============================================================

// ==============================================================
// This function is called when Orbiter starts or when the module
// is activated.

DLLCLBK void opcOpenRenderViewport(HWND hRenderWnd, DWORD width, DWORD height, BOOL fullscreen)
{
// =====================================================
// You'll need this pointer during the creation of the window
// =====================================================
g_hWndOrbiter = hRenderWnd;
g_dwCmd = oapiRegisterCustomCmd ("My dialog","Opens a test dialog box which doesn't do much.", OpenDlgClbk, NULL);
/////HWND hDlg = oapiOpenDialogEx (g_hInst, IDD_MYDIALOG, MsgProc);

}



DLLCLBK void InitModule (HINSTANCE hDLL)
{
g_hInst = hDLL; // remember the instance handle

// To allow the user to open our new dialog box, we create
// an entry in the "Custom Functions" list which is accessed
// in Orbiter via Ctrl-F4.
//g_dwCmd = oapiRegisterCustomCmd ("My dialog","Opens a test dialog box which doesn't do much.", OpenDlgClbk, NULL);
}



// ==============================================================
// This function is called when Orbiter shuts down or when the
// module is deactivated

DLLCLBK void ExitModule (HINSTANCE hDLL)
{
// Unregister the custom function in Orbiter
oapiUnregisterCustomCmd (g_dwCmd);
}


// ==============================================================
// Write some parameters to the scenario file

DLLCLBK void opcSaveState (FILEHANDLE scn)
{
oapiWriteScenario_int (scn, "Param", myprm);
}

// ==============================================================
// Read custom parameters from scenario

DLLCLBK void opcLoadState (FILEHANDLE scn)
{
char *line;
while (oapiReadScenario_nextline (scn, line)) {
if (!_strnicmp (line, "Param", 5)) {
sscanf (line+5, "%d", &myprm);
}
}
}

// ==============================================================
// Open the dialog window

void OpenDlgClbk (void *context)
{
//HWND hDlg = oapiOpenDialog (g_hInst, IDD_MYDIALOG, MsgProc);
// Don't use a standard Windows function like CreateWindow to
// open the dialog box, because it won't work in fullscreen mode
HWND hDlg = oapiOpenDialogEx (g_hInst, IDD_MYDIALOG, MsgProc);
}

// ==============================================================
// Close the dialog

void CloseDlg (HWND hDlg)
{
oapiCloseDialog (hDlg);
}

// ==============================================================
// Windows message handler for the dialog box

BOOL CALLBACK MsgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
char name[256];

switch (uMsg) {
case WM_INITDIALOG:
sprintf (name, "%d", myprm);
SetWindowText (GetDlgItem (hDlg, IDC_REMEMBER), name);
return TRUE;

case WM_DESTROY:
GetWindowText (GetDlgItem (hDlg, IDC_REMEMBER), name, 256);
sscanf (name, "%d", &myprm);
return TRUE;

case WM_COMMAND:
switch (LOWORD (wParam)) {

case IDC_WHOAMI: // user pressed dialog button
// display the focus vessel name
oapiGetObjectName (oapiGetFocusObject(), name, 256);
SetWindowText (GetDlgItem (hDlg, IDC_IAM), name);
return TRUE;

case IDCANCEL: // dialog closed by user
CloseDlg (hDlg);
return TRUE;
}
break;
}
return oapiDefDialogProc (hDlg, uMsg, wParam, lParam);
}
 
Top