vurtun / nuklear

A single-header ANSI C gui library
13.69k stars 1.11k forks source link

nuklear problem in inputs in dll #771

Open exphck1337 opened 5 years ago

exphck1337 commented 5 years ago

Hello, I am trying to use nuklear in a dll, but I am having problems with input, doesn't work in any way, I believe that is related to the functions nk_input_begin/nk_input_end, where they should be called on an internal?

class nk_d3d9 : public make_instance< nk_d3d9 >
{
    using screen_size_t = std::pair< int, int >;
public:

    bool is_initialized( ) const noexcept
    {
        return this->_is_init;
    }

    nk_context* ctx( ) const noexcept
    {
        return this->_ctx;
    }

    void initialize( IDirect3DDevice9* device, const screen_size_t& scr_sz )
    {
        this->_ctx = nk_d3d9_init( device, scr_sz.first, scr_sz.second );

        struct nk_font_atlas* atlas;
        nk_d3d9_font_stash_begin( &atlas );
        nk_d3d9_font_stash_end( );

        this->_is_init = true;
    }

    void on_lost_device( )
    {
        if ( this->_ctx )
        {
            nk_free( this->_ctx );
            this->_ctx = nullptr;
        }

        nk_d3d9_release( );
    }

    void on_reset_device( IDirect3DDevice9* device, const screen_size_t& scr_sz )
    {
        this->initialize( device, scr_sz );
    }

    void on_endscene( )
    {
        constexpr auto main_window_flags = ( NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE | NK_WINDOW_MINIMIZABLE | NK_WINDOW_TITLE );

        if ( nk_begin( this->_ctx, "Testing", nk_rect( 0, 0, 400, 500 ), main_window_flags ) )
                {
                nk_label_colored( this->_ctx, "Hello", NK_TEXT_ALIGN_LEFT, { 255, 0, 0, 255 } );
                }

                nk_end( this->_ctx );

        nk_d3d9_render( NK_ANTI_ALIASING_ON );
                nk_input_begin( this->_ctx );
                nk_input_end( this->_ctx );
    }

    void on_wnd_proc_hook( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
    {
        nk_d3d9_handle_event( hWnd, msg, wParam, lParam );
    }

    void shutdown( )
    {
        nk_d3d9_shutdown( );
    }

private:
    nk_context*                                     _ctx;
    bool                        _is_init = false;
};

long __stdcall reset_hook( IDirect3DDevice9* device, D3DPRESENT_PARAMETERS* present_parameters )
{
    nk_d3d9::instance( )->on_lost_device( );

    auto result = reset_o( device, present_parameters );

        if ( SUCCEEDED( result ) )
        nk_d3d9::instance( )->on_reset_device( device, utils::instance( )->get_window_size( ) );

    return result;
}

long __stdcall endscene_hook( IDirect3DDevice9* device )
{
    if ( !nk_d3d9::instance( )->is_initialized( ) )
        nk_d3d9::instance( )->initialize( device, utils::instance( )->get_window_size( ) );

    nk_d3d9::instance( )->on_endscene( );

    return endscene_o( device );
}

LRESULT __stdcall wndproc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    nk_d3d9::instance( )->on_wnd_proc_hook( hWnd, msg, wParam, lParam );

    return CallWindowProcW( wndproc_o, hWnd, msg, wParam, lParam );
}

void install_wndproc_hook( HWND target_window )
{
    wndproc_o = SetWindowLongPtrW( target_window,  GWLP_WNDPROC, ( LONG_PTR ) wndproc );
}
yemeles commented 5 years ago

Try calling nk_d3d9_handle_event in your WndProc hook and nk_input_begin, nk_input_end at the end of your render function (after nk_d3d9_render).

exphck1337 commented 5 years ago

I tried, it did not work

yemeles commented 5 years ago

How are you creating your WndProc hook? I've done something similar and I have never had your issue. Update your original post with your new code or post it again. Thanks.

exphck1337 commented 5 years ago

I'm doing hook in WndProc with SetWindowLongPtrW(GWLP_WNDPROC), I updated the code

yemeles commented 5 years ago

Very strange. Make sure your on_wnd_proc_hook is actually being called. Some relevant code from my old project:

void render() {
        nk_begin(ctx_, "", nk_rect(50, 50, 400, 250), NK_WINDOW_MOVABLE | NK_WINDOW_TITLE);
        nk_end(ctx_);
        nk_d3d9_render(NK_ANTI_ALIASING_ON);

        nk_input_begin(ctx_);
        nk_input_end(ctx_);
}

LRESULT input(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
        return nk_d3d9_handle_event(hwnd, msg, wparam, lparam);
}

LRESULT hk_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
        if (menu->visible) {
                if (menu->input(hwnd, msg, wparam, lparam)) {
                        return 0;
                }
        }
        return CallWindowProcA(old_wndproc, hwnd, msg, wparam, lparam);
}