"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "backends/imgui_impl_win32.cpp" between
imgui-1.86.tar.gz and imgui-1.87.tar.gz

About: Dear ImGui is a bloat-free Graphical User Interface for C++ with minimal dependencies.

imgui_impl_win32.cpp  (imgui-1.86):imgui_impl_win32.cpp  (imgui-1.87)
// dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications) // dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications)
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan. .) // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan. .)
// Implemented features: // Implemented features:
// [X] Platform: Clipboard support (for Win32 this is actually part of core dea r imgui) // [X] Platform: Clipboard support (for Win32 this is actually part of core dea r imgui)
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlag // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent()
s |= ImGuiConfigFlags_NoMouseCursorChange'. function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(Im
// [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImG GuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_O
ui::IsKeyPressed(VK_SPACE). BSOLETE_KEYIO is set]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFl ags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFl ags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlag s |= ImGuiConfigFlags_NoMouseCursorChange'.
// You can use unmodified imgui_impl_* files in your project. See examples/ fold er for examples of using this. // You can use unmodified imgui_impl_* files in your project. See examples/ fold er for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs // Read online: https://github.com/ocornut/imgui/tree/master/docs
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_win32.h" #include "imgui_impl_win32.h"
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
#include <windows.h> #include <windows.h>
#include <windowsx.h> // GET_X_LPARAM(), GET_Y_LPARAM()
#include <tchar.h> #include <tchar.h>
#include <dwmapi.h> #include <dwmapi.h>
// Configuration flags to add in your imconfig.h file: // Configuration flags to add in your imconfig.h file:
//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad suppo rt. This was meaningful before <1.81 but we now load XInput dynamically so the o ption is now less relevant. //#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad suppo rt. This was meaningful before <1.81 but we now load XInput dynamically so the o ption is now less relevant.
// Using XInput for gamepad (will load DLL dynamically) // Using XInput for gamepad (will load DLL dynamically)
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
#include <xinput.h> #include <xinput.h>
typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILIT IES*); typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILIT IES*);
typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
#endif #endif
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two wee
ks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusio
n.
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support,
instead of writing directly to io.NavInputs[].
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEven
t(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-17: Inputs: always update key mods next and before a key event (not
in NewFrame) to fix input queue with very low framerates.
// 2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + f
allback to provide it when focused but not hovered/captured. More standard and w
ill allow us to pass it to future input queue API.
// 2022-01-12: Inputs: Maintain our own copy of MouseButtonsDown mask instead o
f using ImGui::IsAnyMouseDown() which will be obsoleted.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.
SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMEN U/VK_RMENU for completeness. // 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMEN U/VK_RMENU for completeness.
// 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages. // 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
// 2021-08-02: Inputs: Fixed keyboard modifiers being reported when host window doesn't have focus. // 2021-08-02: Inputs: Fixed keyboard modifiers being reported when host window doesn't have focus.
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform wi ndow is hovered but not focused (using TrackMouseEvent() to receive WM_MOUSELEAV E events). // 2021-07-29: Inputs: MousePos is correctly reported when the host platform wi ndow is hovered but not focused (using TrackMouseEvent() to receive WM_MOUSELEAV E events).
// 2021-06-29: Reorganized backend to pull data from a single structure to faci litate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2021-06-29: Reorganized backend to pull data from a single structure to faci litate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-06-08: Fixed ImGui_ImplWin32_EnableDpiAwareness() and ImGui_ImplWin32_G etDpiScaleForMonitor() to handle Windows 8.1/10 features without a manifest (per -monitor DPI, and properly calls SetProcessDpiAwareness() on 8.1). // 2021-06-08: Fixed ImGui_ImplWin32_EnableDpiAwareness() and ImGui_ImplWin32_G etDpiScaleForMonitor() to handle Windows 8.1/10 features without a manifest (per -monitor DPI, and properly calls SetProcessDpiAwareness() on 8.1).
// 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLF OCUS). // 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLF OCUS).
// 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studi o users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi). // 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studi o users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi).
// 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get Set ProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1. // 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get Set ProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1.
// 2021-01-25: Inputs: Dynamically loading XInput DLL. // 2021-01-25: Inputs: Dynamically loading XInput DLL.
skipping to change at line 76 skipping to change at line 84
// 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag.
// 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the V K_MENU key can be read. // 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the V K_MENU key can be read.
// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mous e positions outside the client area when dragging. // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mous e positions outside the client area when dragging.
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCurso r is set. // 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCurso r is set.
struct ImGui_ImplWin32_Data struct ImGui_ImplWin32_Data
{ {
HWND hWnd; HWND hWnd;
HWND MouseHwnd; HWND MouseHwnd;
bool MouseTracked; bool MouseTracked;
int MouseButtonsDown;
INT64 Time; INT64 Time;
INT64 TicksPerSecond; INT64 TicksPerSecond;
ImGuiMouseCursor LastMouseCursor; ImGuiMouseCursor LastMouseCursor;
bool HasGamepad; bool HasGamepad;
bool WantUpdateHasGamepad; bool WantUpdateHasGamepad;
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
HMODULE XInputDLL; HMODULE XInputDLL;
PFN_XInputGetCapabilities XInputGetCapabilities; PFN_XInputGetCapabilities XInputGetCapabilities;
PFN_XInputGetState XInputGetState; PFN_XInputGetState XInputGetState;
skipping to change at line 125 skipping to change at line 134
io.BackendPlatformName = "imgui_impl_win32"; io.BackendPlatformName = "imgui_impl_win32";
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can hono r GetMouseCursor() values (optional) io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can hono r GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can hono r io.WantSetMousePos requests (optional, rarely used) io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can hono r io.WantSetMousePos requests (optional, rarely used)
bd->hWnd = (HWND)hwnd; bd->hWnd = (HWND)hwnd;
bd->WantUpdateHasGamepad = true; bd->WantUpdateHasGamepad = true;
bd->TicksPerSecond = perf_frequency; bd->TicksPerSecond = perf_frequency;
bd->Time = perf_counter; bd->Time = perf_counter;
bd->LastMouseCursor = ImGuiMouseCursor_COUNT; bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
io.ImeWindowHandle = hwnd; // Set platform dependent data in viewport
ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd;
// Keyboard mapping. Dear ImGui will use those indices to peek into the io.K
eysDown[] 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';
// Dynamically load XInput library // Dynamically load XInput library
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
const char* xinput_dll_names[] = const char* xinput_dll_names[] =
{ {
"xinput1_4.dll", // Windows 8+ "xinput1_4.dll", // Windows 8+
"xinput1_3.dll", // DirectX SDK "xinput1_3.dll", // DirectX SDK
"xinput9_1_0.dll", // Windows Vista, Windows 7 "xinput9_1_0.dll", // Windows Vista, Windows 7
"xinput1_2.dll", // DirectX SDK "xinput1_2.dll", // DirectX SDK
"xinput1_1.dll" // DirectX SDK "xinput1_1.dll" // DirectX SDK
skipping to change at line 224 skipping to change at line 210
case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break; case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break; case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
} }
::SetCursor(::LoadCursor(NULL, win32_cursor)); ::SetCursor(::LoadCursor(NULL, win32_cursor));
} }
return true; return true;
} }
static void ImGui_ImplWin32_UpdateMousePos() static bool IsVkDown(int vk)
{
return (::GetKeyState(vk) & 0x8000) != 0;
}
static void ImGui_ImplWin32_AddKeyEvent(ImGuiKey key, bool down, int native_keyc
ode, int native_scancode = -1)
{ {
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(bd->hWnd != 0); io.AddKeyEvent(key, down);
io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To suppor
t legacy indexing (<1.87 user code)
IM_UNUSED(native_scancode);
}
const ImVec2 mouse_pos_prev = io.MousePos; static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); {
// Left & right Shift keys: when both are pressed together, Windows tend to
not generate the WM_KEYUP event for the first released one.
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && !IsVkDown(VK_LSHIFT))
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, false, VK_LSHIFT);
if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT))
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, false, VK_RSHIFT);
// Sometimes WM_KEYUP for Win key is not passed down to the app (e.g. for Wi
n+V on some setups, according to GLFW).
if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN))
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftSuper, false, VK_LWIN);
if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN))
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightSuper, false, VK_RWIN);
}
// Obtain focused and hovered window. We forward mouse input when focused or static void ImGui_ImplWin32_UpdateKeyModifiers()
when hovered (and no other window is capturing) {
HWND focused_window = ::GetForegroundWindow(); ImGuiIO& io = ImGui::GetIO();
HWND hovered_window = bd->MouseHwnd; io.AddKeyEvent(ImGuiKey_ModCtrl, IsVkDown(VK_CONTROL));
HWND mouse_window = NULL; io.AddKeyEvent(ImGuiKey_ModShift, IsVkDown(VK_SHIFT));
if (hovered_window && (hovered_window == bd->hWnd || ::IsChild(hovered_windo io.AddKeyEvent(ImGuiKey_ModAlt, IsVkDown(VK_MENU));
w, bd->hWnd))) io.AddKeyEvent(ImGuiKey_ModSuper, IsVkDown(VK_APPS));
mouse_window = hovered_window; }
else if (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_
window, bd->hWnd))) static void ImGui_ImplWin32_UpdateMouseData()
mouse_window = focused_window; {
if (mouse_window == NULL) ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
return; ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(bd->hWnd != 0);
// Set OS mouse position from Dear ImGui if requested (rarely used, only whe const bool is_app_focused = (::GetForegroundWindow() == bd->hWnd);
n ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) if (is_app_focused)
if (io.WantSetMousePos)
{ {
POINT pos = { (int)mouse_pos_prev.x, (int)mouse_pos_prev.y }; // (Optional) Set OS mouse position from Dear ImGui if requested (rarely
if (::ClientToScreen(bd->hWnd, &pos)) used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
::SetCursorPos(pos.x, pos.y); if (io.WantSetMousePos)
} {
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
if (::ClientToScreen(bd->hWnd, &pos))
::SetCursorPos(pos.x, pos.y);
}
// Set Dear ImGui mouse position from OS position // (Optional) Fallback to provide mouse position when focused (WM_MOUSEM
POINT pos; OVE already provides this when hovered or captured)
if (::GetCursorPos(&pos) && ::ScreenToClient(mouse_window, &pos)) if (!io.WantSetMousePos && !bd->MouseTracked)
io.MousePos = ImVec2((float)pos.x, (float)pos.y); {
POINT pos;
if (::GetCursorPos(&pos) && ::ScreenToClient(bd->hWnd, &pos))
io.AddMousePosEvent((float)pos.x, (float)pos.y);
}
}
} }
// Gamepad navigation mapping // Gamepad navigation mapping
static void ImGui_ImplWin32_UpdateGamepads() static void ImGui_ImplWin32_UpdateGamepads()
{ {
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
memset(io.NavInputs, 0, sizeof(io.NavInputs));
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
return; return;
// Calling XInputGetState() every frame on disconnected gamepads is unfortun ately too slow. // Calling XInputGetState() every frame on disconnected gamepads is unfortun ately too slow.
// Instead we refresh gamepad availability by calling XInputGetCapabilities( ) _only_ after receiving WM_DEVICECHANGE. // Instead we refresh gamepad availability by calling XInputGetCapabilities( ) _only_ after receiving WM_DEVICECHANGE.
if (bd->WantUpdateHasGamepad) if (bd->WantUpdateHasGamepad)
{ {
XINPUT_CAPABILITIES caps; XINPUT_CAPABILITIES caps = {};
bd->HasGamepad = bd->XInputGetCapabilities ? (bd->XInputGetCapabilities( 0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false; bd->HasGamepad = bd->XInputGetCapabilities ? (bd->XInputGetCapabilities( 0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false;
bd->WantUpdateHasGamepad = false; bd->WantUpdateHasGamepad = false;
} }
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
XINPUT_STATE xinput_state; XINPUT_STATE xinput_state;
if (bd->HasGamepad && bd->XInputGetState && bd->XInputGetState(0, &xinput_st XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
ate) == ERROR_SUCCESS) if (!bd->HasGamepad || bd->XInputGetState == NULL || bd->XInputGetState(0, &
{ xinput_state) != ERROR_SUCCESS)
const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad; return;
io.BackendFlags |= ImGuiBackendFlags_HasGamepad; io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
#define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (ga #define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.
mepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; } 0f : V)
#define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - #define MAP_BUTTON(KEY_NO, BUTTON_ENUM) { io.AddKeyEvent(KEY_NO, (gamepa
V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs d.wButtons & BUTTON_ENUM) != 0); }
[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; } #define MAP_ANALOG(KEY_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0)
MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); / (float)(V1 - V0); io.AddKeyAnalogEvent(KEY_NO, vn > 0.10f, IM_SATURATE(vn));
// Cross / A }
MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); MAP_BUTTON(ImGuiKey_GamepadStart, XINPUT_GAMEPAD_START);
// Circle / B MAP_BUTTON(ImGuiKey_GamepadBack, XINPUT_GAMEPAD_BACK);
MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); MAP_BUTTON(ImGuiKey_GamepadFaceDown, XINPUT_GAMEPAD_A);
// Square / X MAP_BUTTON(ImGuiKey_GamepadFaceRight, XINPUT_GAMEPAD_B);
MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); MAP_BUTTON(ImGuiKey_GamepadFaceLeft, XINPUT_GAMEPAD_X);
// Triangle / Y MAP_BUTTON(ImGuiKey_GamepadFaceUp, XINPUT_GAMEPAD_Y);
MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); MAP_BUTTON(ImGuiKey_GamepadDpadLeft, XINPUT_GAMEPAD_DPAD_LEFT);
// D-Pad Left MAP_BUTTON(ImGuiKey_GamepadDpadRight, XINPUT_GAMEPAD_DPAD_RIGHT);
MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); MAP_BUTTON(ImGuiKey_GamepadDpadUp, XINPUT_GAMEPAD_DPAD_UP);
// D-Pad Right MAP_BUTTON(ImGuiKey_GamepadDpadDown, XINPUT_GAMEPAD_DPAD_DOWN);
MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); MAP_BUTTON(ImGuiKey_GamepadL1, XINPUT_GAMEPAD_LEFT_SHOULDER);
// D-Pad Up MAP_BUTTON(ImGuiKey_GamepadR1, XINPUT_GAMEPAD_RIGHT_SHOULDER);
MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); MAP_ANALOG(ImGuiKey_GamepadL2, gamepad.bLeftTrigger, XINPUT_GAM
// D-Pad Down EPAD_TRIGGER_THRESHOLD, 255);
MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); MAP_ANALOG(ImGuiKey_GamepadR2, gamepad.bRightTrigger, XINPUT_GA
// L1 / LB MEPAD_TRIGGER_THRESHOLD, 255);
MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); MAP_BUTTON(ImGuiKey_GamepadL3, XINPUT_GAMEPAD_LEFT_THUMB);
// R1 / RB MAP_BUTTON(ImGuiKey_GamepadR3, XINPUT_GAMEPAD_RIGHT_THUMB);
MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); MAP_ANALOG(ImGuiKey_GamepadLStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPA
// L1 / LB D_LEFT_THUMB_DEADZONE, -32768);
MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); MAP_ANALOG(ImGuiKey_GamepadLStickRight, gamepad.sThumbLX, +XINPUT_GAMEPA
// R1 / RB D_LEFT_THUMB_DEADZONE, +32767);
MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEP MAP_ANALOG(ImGuiKey_GamepadLStickUp, gamepad.sThumbLY, +XINPUT_GAMEPA
AD_LEFT_THUMB_DEADZONE, -32768); D_LEFT_THUMB_DEADZONE, +32767);
MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEP MAP_ANALOG(ImGuiKey_GamepadLStickDown, gamepad.sThumbLY, -XINPUT_GAMEPA
AD_LEFT_THUMB_DEADZONE, +32767); D_LEFT_THUMB_DEADZONE, -32768);
MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEP MAP_ANALOG(ImGuiKey_GamepadRStickLeft, gamepad.sThumbRX, -XINPUT_GAMEPA
AD_LEFT_THUMB_DEADZONE, +32767); D_LEFT_THUMB_DEADZONE, -32768);
MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEP MAP_ANALOG(ImGuiKey_GamepadRStickRight, gamepad.sThumbRX, +XINPUT_GAMEPA
AD_LEFT_THUMB_DEADZONE, -32767); D_LEFT_THUMB_DEADZONE, +32767);
#undef MAP_BUTTON MAP_ANALOG(ImGuiKey_GamepadRStickUp, gamepad.sThumbRY, +XINPUT_GAMEPA
#undef MAP_ANALOG D_LEFT_THUMB_DEADZONE, +32767);
} MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPA
D_LEFT_THUMB_DEADZONE, -32768);
#undef MAP_BUTTON
#undef MAP_ANALOG
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
} }
void ImGui_ImplWin32_NewFrame() void ImGui_ImplWin32_NewFrame()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
IM_ASSERT(bd != NULL && "Did you call ImGui_ImplWin32_Init()?"); IM_ASSERT(bd != NULL && "Did you call ImGui_ImplWin32_Init()?");
// Setup display size (every frame to accommodate for window resizing) // Setup display size (every frame to accommodate for window resizing)
skipping to change at line 326 skipping to change at line 349
::GetClientRect(bd->hWnd, &rect); ::GetClientRect(bd->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 // Setup time step
INT64 current_time = 0; INT64 current_time = 0;
::QueryPerformanceCounter((LARGE_INTEGER*)&current_time); ::QueryPerformanceCounter((LARGE_INTEGER*)&current_time);
io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond; io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond;
bd->Time = current_time; bd->Time = current_time;
// Update OS mouse position // Update OS mouse position
ImGui_ImplWin32_UpdateMousePos(); ImGui_ImplWin32_UpdateMouseData();
// Process workarounds for known Windows key handling issues
ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
// Update OS mouse cursor with the cursor requested by imgui // Update OS mouse cursor with the cursor requested by imgui
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
if (bd->LastMouseCursor != mouse_cursor) if (bd->LastMouseCursor != mouse_cursor)
{ {
bd->LastMouseCursor = mouse_cursor; bd->LastMouseCursor = mouse_cursor;
ImGui_ImplWin32_UpdateMouseCursor(); ImGui_ImplWin32_UpdateMouseCursor();
} }
// Update game controllers (if enabled and available) // Update game controllers (if enabled and available)
ImGui_ImplWin32_UpdateGamepads(); ImGui_ImplWin32_UpdateGamepads();
} }
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EX
TENDED, we assign it an arbitrary value to make code more readable (VK_ codes go
up to 255)
#define IM_VK_KEYPAD_ENTER (VK_RETURN + 256)
// Map VK_xxx to ImGuiKey_xxx.
static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
{
switch (wParam)
{
case VK_TAB: return ImGuiKey_Tab;
case VK_LEFT: return ImGuiKey_LeftArrow;
case VK_RIGHT: return ImGuiKey_RightArrow;
case VK_UP: return ImGuiKey_UpArrow;
case VK_DOWN: return ImGuiKey_DownArrow;
case VK_PRIOR: return ImGuiKey_PageUp;
case VK_NEXT: return ImGuiKey_PageDown;
case VK_HOME: return ImGuiKey_Home;
case VK_END: return ImGuiKey_End;
case VK_INSERT: return ImGuiKey_Insert;
case VK_DELETE: return ImGuiKey_Delete;
case VK_BACK: return ImGuiKey_Backspace;
case VK_SPACE: return ImGuiKey_Space;
case VK_RETURN: return ImGuiKey_Enter;
case VK_ESCAPE: return ImGuiKey_Escape;
case VK_OEM_7: return ImGuiKey_Apostrophe;
case VK_OEM_COMMA: return ImGuiKey_Comma;
case VK_OEM_MINUS: return ImGuiKey_Minus;
case VK_OEM_PERIOD: return ImGuiKey_Period;
case VK_OEM_2: return ImGuiKey_Slash;
case VK_OEM_1: return ImGuiKey_Semicolon;
case VK_OEM_PLUS: return ImGuiKey_Equal;
case VK_OEM_4: return ImGuiKey_LeftBracket;
case VK_OEM_5: return ImGuiKey_Backslash;
case VK_OEM_6: return ImGuiKey_RightBracket;
case VK_OEM_3: return ImGuiKey_GraveAccent;
case VK_CAPITAL: return ImGuiKey_CapsLock;
case VK_SCROLL: return ImGuiKey_ScrollLock;
case VK_NUMLOCK: return ImGuiKey_NumLock;
case VK_SNAPSHOT: return ImGuiKey_PrintScreen;
case VK_PAUSE: return ImGuiKey_Pause;
case VK_NUMPAD0: return ImGuiKey_Keypad0;
case VK_NUMPAD1: return ImGuiKey_Keypad1;
case VK_NUMPAD2: return ImGuiKey_Keypad2;
case VK_NUMPAD3: return ImGuiKey_Keypad3;
case VK_NUMPAD4: return ImGuiKey_Keypad4;
case VK_NUMPAD5: return ImGuiKey_Keypad5;
case VK_NUMPAD6: return ImGuiKey_Keypad6;
case VK_NUMPAD7: return ImGuiKey_Keypad7;
case VK_NUMPAD8: return ImGuiKey_Keypad8;
case VK_NUMPAD9: return ImGuiKey_Keypad9;
case VK_DECIMAL: return ImGuiKey_KeypadDecimal;
case VK_DIVIDE: return ImGuiKey_KeypadDivide;
case VK_MULTIPLY: return ImGuiKey_KeypadMultiply;
case VK_SUBTRACT: return ImGuiKey_KeypadSubtract;
case VK_ADD: return ImGuiKey_KeypadAdd;
case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter;
case VK_LSHIFT: return ImGuiKey_LeftShift;
case VK_LCONTROL: return ImGuiKey_LeftCtrl;
case VK_LMENU: return ImGuiKey_LeftAlt;
case VK_LWIN: return ImGuiKey_LeftSuper;
case VK_RSHIFT: return ImGuiKey_RightShift;
case VK_RCONTROL: return ImGuiKey_RightCtrl;
case VK_RMENU: return ImGuiKey_RightAlt;
case VK_RWIN: return ImGuiKey_RightSuper;
case VK_APPS: return ImGuiKey_Menu;
case '0': return ImGuiKey_0;
case '1': return ImGuiKey_1;
case '2': return ImGuiKey_2;
case '3': return ImGuiKey_3;
case '4': return ImGuiKey_4;
case '5': return ImGuiKey_5;
case '6': return ImGuiKey_6;
case '7': return ImGuiKey_7;
case '8': return ImGuiKey_8;
case '9': return ImGuiKey_9;
case 'A': return ImGuiKey_A;
case 'B': return ImGuiKey_B;
case 'C': return ImGuiKey_C;
case 'D': return ImGuiKey_D;
case 'E': return ImGuiKey_E;
case 'F': return ImGuiKey_F;
case 'G': return ImGuiKey_G;
case 'H': return ImGuiKey_H;
case 'I': return ImGuiKey_I;
case 'J': return ImGuiKey_J;
case 'K': return ImGuiKey_K;
case 'L': return ImGuiKey_L;
case 'M': return ImGuiKey_M;
case 'N': return ImGuiKey_N;
case 'O': return ImGuiKey_O;
case 'P': return ImGuiKey_P;
case 'Q': return ImGuiKey_Q;
case 'R': return ImGuiKey_R;
case 'S': return ImGuiKey_S;
case 'T': return ImGuiKey_T;
case 'U': return ImGuiKey_U;
case 'V': return ImGuiKey_V;
case 'W': return ImGuiKey_W;
case 'X': return ImGuiKey_X;
case 'Y': return ImGuiKey_Y;
case 'Z': return ImGuiKey_Z;
case VK_F1: return ImGuiKey_F1;
case VK_F2: return ImGuiKey_F2;
case VK_F3: return ImGuiKey_F3;
case VK_F4: return ImGuiKey_F4;
case VK_F5: return ImGuiKey_F5;
case VK_F6: return ImGuiKey_F6;
case VK_F7: return ImGuiKey_F7;
case VK_F8: return ImGuiKey_F8;
case VK_F9: return ImGuiKey_F9;
case VK_F10: return ImGuiKey_F10;
case VK_F11: return ImGuiKey_F11;
case VK_F12: return ImGuiKey_F12;
default: return ImGuiKey_None;
}
}
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WIN NT/WINVER versions. // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WIN NT/WINVER versions.
#ifndef WM_MOUSEHWHEEL #ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E #define WM_MOUSEHWHEEL 0x020E
#endif #endif
#ifndef DBT_DEVNODES_CHANGED #ifndef DBT_DEVNODES_CHANGED
#define DBT_DEVNODES_CHANGED 0x0007 #define DBT_DEVNODES_CHANGED 0x0007
#endif #endif
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.) // Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
// Call from your application's message handler. // Call from your application's message handler.
skipping to change at line 379 skipping to change at line 521
{ {
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE eve nts // We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE eve nts
bd->MouseHwnd = hwnd; bd->MouseHwnd = hwnd;
if (!bd->MouseTracked) if (!bd->MouseTracked)
{ {
TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hwnd, 0 }; TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hwnd, 0 };
::TrackMouseEvent(&tme); ::TrackMouseEvent(&tme);
bd->MouseTracked = true; bd->MouseTracked = true;
} }
io.AddMousePosEvent((float)GET_X_LPARAM(lParam), (float)GET_Y_LPARAM(lPa ram));
break; break;
case WM_MOUSELEAVE: case WM_MOUSELEAVE:
if (bd->MouseHwnd == hwnd) if (bd->MouseHwnd == hwnd)
bd->MouseHwnd = NULL; bd->MouseHwnd = NULL;
bd->MouseTracked = false; bd->MouseTracked = false;
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
break; break;
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
{ {
int button = 0; int button = 0;
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; } if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XB UTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XB UTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) if (bd->MouseButtonsDown == 0 && ::GetCapture() == NULL)
::SetCapture(hwnd); ::SetCapture(hwnd);
io.MouseDown[button] = true; bd->MouseButtonsDown |= 1 << button;
io.AddMouseButtonEvent(button, true);
return 0; return 0;
} }
case WM_LBUTTONUP: case WM_LBUTTONUP:
case WM_RBUTTONUP: case WM_RBUTTONUP:
case WM_MBUTTONUP: case WM_MBUTTONUP:
case WM_XBUTTONUP: case WM_XBUTTONUP:
{ {
int button = 0; int button = 0;
if (msg == WM_LBUTTONUP) { button = 0; } if (msg == WM_LBUTTONUP) { button = 0; }
if (msg == WM_RBUTTONUP) { button = 1; } if (msg == WM_RBUTTONUP) { button = 1; }
if (msg == WM_MBUTTONUP) { button = 2; } if (msg == WM_MBUTTONUP) { button = 2; }
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTT ON1) ? 3 : 4; } if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTT ON1) ? 3 : 4; }
io.MouseDown[button] = false; bd->MouseButtonsDown &= ~(1 << button);
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd)
::ReleaseCapture(); ::ReleaseCapture();
io.AddMouseButtonEvent(button, false);
return 0; return 0;
} }
case WM_MOUSEWHEEL: case WM_MOUSEWHEEL:
io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DE LTA; io.AddMouseWheelEvent(0.0f, (float)GET_WHEEL_DELTA_WPARAM(wParam) / (flo at)WHEEL_DELTA);
return 0; return 0;
case WM_MOUSEHWHEEL: case WM_MOUSEHWHEEL:
io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_D ELTA; io.AddMouseWheelEvent((float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHE EL_DELTA, 0.0f);
return 0; return 0;
case WM_KEYDOWN: case WM_KEYDOWN:
case WM_KEYUP: case WM_KEYUP:
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
case WM_SYSKEYUP: case WM_SYSKEYUP:
{ {
bool down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN); const bool is_key_down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
if (wParam < 256) if (wParam < 256)
io.KeysDown[wParam] = down;
if (wParam == VK_CONTROL)
{ {
io.KeysDown[VK_LCONTROL] = ((::GetKeyState(VK_LCONTROL) & 0x8000) != // Submit modifiers
0); ImGui_ImplWin32_UpdateKeyModifiers();
io.KeysDown[VK_RCONTROL] = ((::GetKeyState(VK_RCONTROL) & 0x8000) !=
0); // Obtain virtual key code
io.KeyCtrl = io.KeysDown[VK_LCONTROL] || io.KeysDown[VK_RCONTROL]; // (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED
} flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is ma
if (wParam == VK_SHIFT) pped to ImGuiKey_KeyPadEnter.)
{ int vk = (int)wParam;
io.KeysDown[VK_LSHIFT] = ((::GetKeyState(VK_LSHIFT) & 0x8000) != 0); if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
io.KeysDown[VK_RSHIFT] = ((::GetKeyState(VK_RSHIFT) & 0x8000) != 0); vk = IM_VK_KEYPAD_ENTER;
io.KeyShift = io.KeysDown[VK_LSHIFT] || io.KeysDown[VK_RS
HIFT]; // Submit key event
} const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
if (wParam == VK_MENU) const int scancode = (int)LOBYTE(HIWORD(lParam));
{ if (key != ImGuiKey_None)
io.KeysDown[VK_LMENU] = ((::GetKeyState(VK_LMENU) & 0x8000) != 0); ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);
io.KeysDown[VK_RMENU] = ((::GetKeyState(VK_RMENU) & 0x8000) != 0);
io.KeyAlt = io.KeysDown[VK_LMENU] || io.KeysDown[VK_RMEN // Submit individual left/right modifier events
U]; if (vk == VK_SHIFT)
{
// Important: Shift keys tend to get stuck when pressed together
, missing key-up events are corrected in ImGui_ImplWin32_ProcessKeyEventsWorkaro
unds()
if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKey
Event(ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); }
if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKey
Event(ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
}
else if (vk == VK_CONTROL)
{
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddK
eyEvent(ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddK
eyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
}
else if (vk == VK_MENU)
{
if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyE
vent(ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); }
if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyE
vent(ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
}
} }
return 0; return 0;
} }
case WM_SETFOCUS: case WM_SETFOCUS:
case WM_KILLFOCUS: case WM_KILLFOCUS:
io.AddFocusEvent(msg == WM_SETFOCUS); io.AddFocusEvent(msg == WM_SETFOCUS);
return 0; return 0;
case WM_CHAR: case WM_CHAR:
// You can also use ToAscii()+GetKeyboardState() to retrieve characters. // You can also use ToAscii()+GetKeyboardState() to retrieve characters.
if (wParam > 0 && wParam < 0x10000) if (wParam > 0 && wParam < 0x10000)
 End of changes. 31 change blocks. 
135 lines changed or deleted 310 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)