Skip to content
Tropby edited this page Jun 19, 2019 · 2 revisions

The Graphics Device Interface (GDI) is a component of the operating system Windows. If you are just starting with nuklear, GDI is the easiest way to get it running with Windows.

Compiling hints: You need to compile against the gdi32 library. For GCC (MinGW) you just need to add -lgdi32 to the compiler parameters.

Mode hints: Have a look to the demo demo/gdi/main.c.

Includes

The following headers are needed. In this example the GDI demo is used for the rendering.

#define COBJMACROS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define NK_IMPLEMENTATION
#define NK_ASSERT
#include "nuklear/nuklear.h"
#include "nuklear/demo/gdi/nuklear_gdi.h"

The Windows window

In windows your application must create a window to show something on the screen.

First of all the window parameters have to be defined.

ATOM atom;
RECT rect = { 0, 0, 500, 500};
DWORD style = WS_OVERLAPPEDWINDOW;
DWORD exstyle = WS_EX_APPWINDOW;

/* Win32 */
memset(&wc, 0, sizeof(wc));
wc.style = CS_DBLCLKS;
// Reserve space to store the instance pointer
wc.lpfnWndProc = WindowProc;
wc.hInstance = GetModuleHandleW(nullptr);
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.lpszClassName = L"NuklearWindowClass";
atom = RegisterClassW(&wc);

The window is created by calling CreateWindowExW with the properties we just setup.

AdjustWindowRectEx(&rect, style, FALSE, exstyle);
wnd = CreateWindowExW(exstyle, wc.lpszClassName, L"Nuklear Demo",
            style | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
            rect.right - rect.left, rect.bottom - rect.top,
            nullptr, nullptr, wc.hInstance, nullptr);

The next few lines will get the device context of the window, creates the font (Arial, 14) and creates the Nuklear context.

/* GUI */
dc = GetDC(wnd);
font = nk_gdifont_create("Arial", 14);        
ctx = nk_gdi_init(font, dc, 200, 200);

The message callback function

The window messages are handled by this function. By calling nk_gdi_handle_event the received events are commited to Nuklear.

static LRESULT CALLBACK WindowProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch (msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    if (nk_gdi_handle_event(wnd, msg, wparam, lparam))
        return 0;

    return DefWindowProcW(wnd, msg, wparam, lparam);
}

Nuklear Main Loop

The main loop of Nuklear have to tasks to do. Processing the inputs and rendering the GUI.

int running = 1;
int need_refresh = 0;
while (running)
{
    // HANDLE INPUTS

    // RENDER GUI
}

Processing the inputs

       /* Input */
        MSG msg;
        nk_input_begin(ctx);
        if (needs_refresh == 0) {
            if (GetMessageW(&msg, NULL, 0, 0) <= 0)
                running = 0;
            else {
                TranslateMessage(&msg);
                DispatchMessageW(&msg);
            }
            needs_refresh = 1;
        } else needs_refresh = 0;

        while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
            if (msg.message == WM_QUIT)
                running = 0;
            TranslateMessage(&msg);
            DispatchMessageW(&msg);
            needs_refresh = 1;
        }
        nk_input_end(ctx);

Render the GUI

       /* GUI */
        if (nk_begin(ctx, "Demo", nk_rect(50, 50, 200, 200),
            NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
            NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
        {
            enum {EASY, HARD};
            static int op = EASY;
            static int property = 20;

            nk_layout_row_static(ctx, 30, 80, 1);
            if (nk_button_label(ctx, "button"))
                fprintf(stdout, "button pressed\n");
            nk_layout_row_dynamic(ctx, 30, 2);
            if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
            if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
            nk_layout_row_dynamic(ctx, 22, 1);
            nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
        }
        nk_end(ctx);
 
        /* Draw */
        nk_gdi_render(nk_rgb(30,30,30));