@ -56,9 +56,6 @@
static HWND g_hWnd = NULL ;
static HWND g_hWnd = NULL ;
static INT64 g_Time = 0 ;
static INT64 g_Time = 0 ;
static INT64 g_TicksPerSecond = 0 ;
static INT64 g_TicksPerSecond = 0 ;
static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT ;
static bool g_HasGamepad = false ;
static bool g_WantUpdateHasGamepad = true ;
// Functions
// Functions
bool ImGui_ImplWin32_Init ( void * hwnd )
bool ImGui_ImplWin32_Init ( void * hwnd )
@ -71,146 +68,13 @@ bool ImGui_ImplWin32_Init(void* hwnd)
// Setup back-end capabilities flags
// Setup back-end capabilities flags
g_hWnd = ( HWND ) hwnd ;
g_hWnd = ( HWND ) hwnd ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
io . BackendFlags | = ImGuiBackendFlags_HasMouseCursors ; // We can honor GetMouseCursor() values (optional)
io . BackendFlags | = ImGuiBackendFlags_HasSetMousePos ; // We can honor io.WantSetMousePos requests (optional, rarely used)
io . BackendPlatformName = " imgui_impl_win32 " ;
io . BackendPlatformName = " imgui_impl_win32 " ;
io . ImeWindowHandle = hwnd ;
io . ImeWindowHandle = hwnd ;
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
io . KeyMap [ ImGuiKey_Tab ] = VK_TAB ;
io . KeyMap [ ImGuiKey_LeftArrow ] = VK_LEFT ;
io . KeyMap [ ImGuiKey_RightArrow ] = VK_RIGHT ;
io . KeyMap [ ImGuiKey_UpArrow ] = VK_UP ;
io . KeyMap [ ImGuiKey_DownArrow ] = VK_DOWN ;
io . KeyMap [ ImGuiKey_PageUp ] = VK_PRIOR ;
io . KeyMap [ ImGuiKey_PageDown ] = VK_NEXT ;
io . KeyMap [ ImGuiKey_Home ] = VK_HOME ;
io . KeyMap [ ImGuiKey_End ] = VK_END ;
io . KeyMap [ ImGuiKey_Insert ] = VK_INSERT ;
io . KeyMap [ ImGuiKey_Delete ] = VK_DELETE ;
io . KeyMap [ ImGuiKey_Backspace ] = VK_BACK ;
io . KeyMap [ ImGuiKey_Space ] = VK_SPACE ;
io . KeyMap [ ImGuiKey_Enter ] = VK_RETURN ;
io . KeyMap [ ImGuiKey_Escape ] = VK_ESCAPE ;
io . KeyMap [ ImGuiKey_KeyPadEnter ] = VK_RETURN ;
io . KeyMap [ ImGuiKey_A ] = ' A ' ;
io . KeyMap [ ImGuiKey_C ] = ' C ' ;
io . KeyMap [ ImGuiKey_V ] = ' V ' ;
io . KeyMap [ ImGuiKey_X ] = ' X ' ;
io . KeyMap [ ImGuiKey_Y ] = ' Y ' ;
io . KeyMap [ ImGuiKey_Z ] = ' Z ' ;
return true ;
return true ;
}
}
void ImGui_ImplWin32_Shutdown ( )
{
g_hWnd = ( HWND ) 0 ;
}
static bool ImGui_ImplWin32_UpdateMouseCursor ( )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
if ( io . ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange )
return false ;
ImGuiMouseCursor imgui_cursor = ImGui : : GetMouseCursor ( ) ;
if ( imgui_cursor = = ImGuiMouseCursor_None | | io . MouseDrawCursor )
{
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
: : SetCursor ( NULL ) ;
}
else
{
// Show OS mouse cursor
LPTSTR win32_cursor = IDC_ARROW ;
switch ( imgui_cursor )
{
case ImGuiMouseCursor_Arrow : win32_cursor = IDC_ARROW ; break ;
case ImGuiMouseCursor_TextInput : win32_cursor = IDC_IBEAM ; break ;
case ImGuiMouseCursor_ResizeAll : win32_cursor = IDC_SIZEALL ; break ;
case ImGuiMouseCursor_ResizeEW : win32_cursor = IDC_SIZEWE ; break ;
case ImGuiMouseCursor_ResizeNS : win32_cursor = IDC_SIZENS ; break ;
case ImGuiMouseCursor_ResizeNESW : win32_cursor = IDC_SIZENESW ; break ;
case ImGuiMouseCursor_ResizeNWSE : win32_cursor = IDC_SIZENWSE ; break ;
case ImGuiMouseCursor_Hand : win32_cursor = IDC_HAND ; break ;
case ImGuiMouseCursor_NotAllowed : win32_cursor = IDC_NO ; break ;
}
: : SetCursor ( : : LoadCursor ( NULL , win32_cursor ) ) ;
}
return true ;
}
static void ImGui_ImplWin32_UpdateMousePos ( )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
if ( io . WantSetMousePos )
{
POINT pos = { ( int ) io . MousePos . x , ( int ) io . MousePos . y } ;
: : ClientToScreen ( g_hWnd , & pos ) ;
: : SetCursorPos ( pos . x , pos . y ) ;
}
// Set mouse position
io . MousePos = ImVec2 ( - FLT_MAX , - FLT_MAX ) ;
POINT pos ;
if ( HWND active_window = : : GetForegroundWindow ( ) )
if ( active_window = = g_hWnd | | : : IsChild ( active_window , g_hWnd ) )
if ( : : GetCursorPos ( & pos ) & & : : ScreenToClient ( g_hWnd , & pos ) )
io . MousePos = ImVec2 ( ( float ) pos . x , ( float ) pos . y ) ;
}
// Gamepad navigation mapping
static void ImGui_ImplWin32_UpdateGamepads ( )
{
# ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
ImGuiIO & io = ImGui : : GetIO ( ) ;
memset ( io . NavInputs , 0 , sizeof ( io . NavInputs ) ) ;
if ( ( io . ConfigFlags & ImGuiConfigFlags_NavEnableGamepad ) = = 0 )
return ;
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
if ( g_WantUpdateHasGamepad )
{
XINPUT_CAPABILITIES caps ;
g_HasGamepad = ( XInputGetCapabilities ( 0 , XINPUT_FLAG_GAMEPAD , & caps ) = = ERROR_SUCCESS ) ;
g_WantUpdateHasGamepad = false ;
}
XINPUT_STATE xinput_state ;
io . BackendFlags & = ~ ImGuiBackendFlags_HasGamepad ;
if ( g_HasGamepad & & XInputGetState ( 0 , & xinput_state ) = = ERROR_SUCCESS )
{
const XINPUT_GAMEPAD & gamepad = xinput_state . Gamepad ;
io . BackendFlags | = ImGuiBackendFlags_HasGamepad ;
# define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
# define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
MAP_BUTTON ( ImGuiNavInput_Activate , XINPUT_GAMEPAD_A ) ; // Cross / A
MAP_BUTTON ( ImGuiNavInput_Cancel , XINPUT_GAMEPAD_B ) ; // Circle / B
MAP_BUTTON ( ImGuiNavInput_Menu , XINPUT_GAMEPAD_X ) ; // Square / X
MAP_BUTTON ( ImGuiNavInput_Input , XINPUT_GAMEPAD_Y ) ; // Triangle / Y
MAP_BUTTON ( ImGuiNavInput_DpadLeft , XINPUT_GAMEPAD_DPAD_LEFT ) ; // D-Pad Left
MAP_BUTTON ( ImGuiNavInput_DpadRight , XINPUT_GAMEPAD_DPAD_RIGHT ) ; // D-Pad Right
MAP_BUTTON ( ImGuiNavInput_DpadUp , XINPUT_GAMEPAD_DPAD_UP ) ; // D-Pad Up
MAP_BUTTON ( ImGuiNavInput_DpadDown , XINPUT_GAMEPAD_DPAD_DOWN ) ; // D-Pad Down
MAP_BUTTON ( ImGuiNavInput_FocusPrev , XINPUT_GAMEPAD_LEFT_SHOULDER ) ; // L1 / LB
MAP_BUTTON ( ImGuiNavInput_FocusNext , XINPUT_GAMEPAD_RIGHT_SHOULDER ) ; // R1 / RB
MAP_BUTTON ( ImGuiNavInput_TweakSlow , XINPUT_GAMEPAD_LEFT_SHOULDER ) ; // L1 / LB
MAP_BUTTON ( ImGuiNavInput_TweakFast , XINPUT_GAMEPAD_RIGHT_SHOULDER ) ; // R1 / RB
MAP_ANALOG ( ImGuiNavInput_LStickLeft , gamepad . sThumbLX , - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , - 32768 ) ;
MAP_ANALOG ( ImGuiNavInput_LStickRight , gamepad . sThumbLX , + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , + 32767 ) ;
MAP_ANALOG ( ImGuiNavInput_LStickUp , gamepad . sThumbLY , + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , + 32767 ) ;
MAP_ANALOG ( ImGuiNavInput_LStickDown , gamepad . sThumbLY , - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE , - 32767 ) ;
# undef MAP_BUTTON
# undef MAP_ANALOG
}
# endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
}
void ImGui_ImplWin32_NewFrame ( )
void ImGui_ImplWin32_NewFrame ( )
{
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
@ -221,125 +85,8 @@ void ImGui_ImplWin32_NewFrame()
: : GetClientRect ( g_hWnd , & rect ) ;
: : GetClientRect ( g_hWnd , & rect ) ;
io . DisplaySize = ImVec2 ( ( float ) ( rect . right - rect . left ) , ( float ) ( rect . bottom - rect . top ) ) ;
io . DisplaySize = ImVec2 ( ( float ) ( rect . right - rect . left ) , ( float ) ( rect . bottom - rect . top ) ) ;
// Setup time step
INT64 current_time ;
: : QueryPerformanceCounter ( ( LARGE_INTEGER * ) & current_time ) ;
io . DeltaTime = ( float ) ( current_time - g_Time ) / g_TicksPerSecond ;
g_Time = current_time ;
// Read keyboard modifiers inputs
io . KeyCtrl = ( : : GetKeyState ( VK_CONTROL ) & 0x8000 ) ! = 0 ;
io . KeyShift = ( : : GetKeyState ( VK_SHIFT ) & 0x8000 ) ! = 0 ;
io . KeyAlt = ( : : GetKeyState ( VK_MENU ) & 0x8000 ) ! = 0 ;
io . KeySuper = false ;
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
// Update OS mouse position
ImGui_ImplWin32_UpdateMousePos ( ) ;
// Update OS mouse cursor with the cursor requested by imgui
ImGuiMouseCursor mouse_cursor = io . MouseDrawCursor ? ImGuiMouseCursor_None : ImGui : : GetMouseCursor ( ) ;
if ( g_LastMouseCursor ! = mouse_cursor )
{
g_LastMouseCursor = mouse_cursor ;
ImGui_ImplWin32_UpdateMouseCursor ( ) ;
}
// Update game controllers (if enabled and available)
ImGui_ImplWin32_UpdateGamepads ( ) ;
}
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
# ifndef WM_MOUSEHWHEEL
# define WM_MOUSEHWHEEL 0x020E
# endif
# ifndef DBT_DEVNODES_CHANGED
# define DBT_DEVNODES_CHANGED 0x0007
# endif
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
// Call from your application's message handler.
// When implementing your own back-end, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
#if 0
// Copy this line into your .cpp file to forward declare the function.
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler ( HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam ) ;
# endif
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler ( HWND hwnd , UINT msg , WPARAM wParam , LPARAM lParam )
{
if ( ImGui : : GetCurrentContext ( ) = = NULL )
return 0 ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
switch ( msg )
{
case WM_LBUTTONDOWN : case WM_LBUTTONDBLCLK :
case WM_RBUTTONDOWN : case WM_RBUTTONDBLCLK :
case WM_MBUTTONDOWN : case WM_MBUTTONDBLCLK :
case WM_XBUTTONDOWN : case WM_XBUTTONDBLCLK :
{
int button = 0 ;
if ( msg = = WM_LBUTTONDOWN | | msg = = WM_LBUTTONDBLCLK ) { button = 0 ; }
if ( msg = = WM_RBUTTONDOWN | | msg = = WM_RBUTTONDBLCLK ) { button = 1 ; }
if ( msg = = WM_MBUTTONDOWN | | msg = = WM_MBUTTONDBLCLK ) { button = 2 ; }
if ( msg = = WM_XBUTTONDOWN | | msg = = WM_XBUTTONDBLCLK ) { button = ( GET_XBUTTON_WPARAM ( wParam ) = = XBUTTON1 ) ? 3 : 4 ; }
if ( ! ImGui : : IsAnyMouseDown ( ) & & : : GetCapture ( ) = = NULL )
: : SetCapture ( hwnd ) ;
io . MouseDown [ button ] = true ;
return 0 ;
}
case WM_LBUTTONUP :
case WM_RBUTTONUP :
case WM_MBUTTONUP :
case WM_XBUTTONUP :
{
int button = 0 ;
if ( msg = = WM_LBUTTONUP ) { button = 0 ; }
if ( msg = = WM_RBUTTONUP ) { button = 1 ; }
if ( msg = = WM_MBUTTONUP ) { button = 2 ; }
if ( msg = = WM_XBUTTONUP ) { button = ( GET_XBUTTON_WPARAM ( wParam ) = = XBUTTON1 ) ? 3 : 4 ; }
io . MouseDown [ button ] = false ;
if ( ! ImGui : : IsAnyMouseDown ( ) & & : : GetCapture ( ) = = hwnd )
: : ReleaseCapture ( ) ;
return 0 ;
}
}
case WM_MOUSEWHEEL :
io . MouseWheel + = ( float ) GET_WHEEL_DELTA_WPARAM ( wParam ) / ( float ) WHEEL_DELTA ;
return 0 ;
case WM_MOUSEHWHEEL :
io . MouseWheelH + = ( float ) GET_WHEEL_DELTA_WPARAM ( wParam ) / ( float ) WHEEL_DELTA ;
return 0 ;
case WM_KEYDOWN :
case WM_SYSKEYDOWN :
if ( wParam < 256 )
io . KeysDown [ wParam ] = 1 ;
return 0 ;
case WM_KEYUP :
case WM_SYSKEYUP :
if ( wParam < 256 )
io . KeysDown [ wParam ] = 0 ;
return 0 ;
case WM_CHAR :
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
if ( wParam > 0 & & wParam < 0x10000 )
io . AddInputCharacterUTF16 ( ( unsigned short ) wParam ) ;
return 0 ;
case WM_SETCURSOR :
if ( LOWORD ( lParam ) = = HTCLIENT & & ImGui_ImplWin32_UpdateMouseCursor ( ) )
return 1 ;
return 0 ;
case WM_DEVICECHANGE :
if ( ( UINT ) wParam = = DBT_DEVNODES_CHANGED )
g_WantUpdateHasGamepad = true ;
return 0 ;
}
return 0 ;
}
//--------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------
// DPI-related helpers (optional)
// DPI-related helpers (optional)