#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);
}