Resolved multiple issues with fix 2600

Device Contexts are no longer maintained for the application lifetime.
::GetDC() is now never called when using DirectX backend.
Removed lambda callback and brought WGL function loading into
conformance with XInput DLL loading.
diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp
index b603fff..877f25b 100644
--- a/backends/imgui_impl_opengl3.cpp
+++ b/backends/imgui_impl_opengl3.cpp
@@ -917,6 +917,11 @@
 
 static void ImGui_ImplOpenGL3_RenderWindow(ImGuiViewport* viewport, void*)
 {
+    ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
+
+    if (platform_io.Platform_PushOglContext)
+        platform_io.Platform_PushOglContext(viewport);
+
     if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
     {
         ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
@@ -924,6 +929,9 @@
         glClear(GL_COLOR_BUFFER_BIT);
     }
     ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData);
+    
+    if (platform_io.Platform_PopOglContext)
+        platform_io.Platform_PopOglContext(viewport);
 }
 
 static void ImGui_ImplOpenGL3_InitPlatformInterface()
diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp
index 0e452c2..bce3fa7 100644
--- a/backends/imgui_impl_win32.cpp
+++ b/backends/imgui_impl_win32.cpp
@@ -25,12 +25,12 @@
 #include <dwmapi.h>
 
 // Stuff for loading WGL functions explicitly
-#include <cstdlib> // atexit()
-static HMODULE libgl;
-HGLRC (WINAPI* _wglCreateContext)(HDC);
-BOOL  (WINAPI* _wglDeleteContext)(HGLRC);
-BOOL  (WINAPI* _wglMakeCurrent)(HDC, HGLRC);
-BOOL  (WINAPI* _wglShareLists)(HGLRC, HGLRC);
+static HGLRC (WINAPI* _wglCreateContext)(HDC);
+static BOOL  (WINAPI* _wglDeleteContext)(HGLRC);
+static BOOL  (WINAPI* _wglMakeCurrent)(HDC, HGLRC);
+static BOOL  (WINAPI* _wglShareLists)(HGLRC, HGLRC);
+static HGLRC (WINAPI* _wglGetCurrentContext)(VOID);
+static HDC   (WINAPI* _wglGetCurrentDC)(VOID);
 
 // Configuration flags to add in your imconfig.h file:
 //#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD              // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant.
@@ -103,8 +103,7 @@
 struct ImGui_ImplWin32_Data
 {
     HWND                        hWnd;
-    HDC                         Hdc;
-    HGLRC                       HgLrc;
+    HGLRC                       OpenGlContext;
     HWND                        MouseHwnd;
     int                         MouseTrackedArea;   // 0: not tracked, 1: client are, 2: non-client area
     int                         MouseButtonsDown;
@@ -113,6 +112,11 @@
     ImGuiMouseCursor            LastMouseCursor;
     bool                        WantUpdateMonitors;
 
+    // OpenGL
+    HMODULE                     OglDLL;
+    HDC                         stashedDeviceContext;
+    HGLRC                       stashedOpenGlContext;
+
 #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
     bool                        HasGamepad;
     bool                        WantUpdateHasGamepad;
@@ -134,7 +138,12 @@
 }
 
 // Functions
-bool    ImGui_ImplWin32_Init(void* hwnd, void* hglrc)
+bool    ImGui_ImplWin32_Init(void* hwnd)
+{
+    return ImGui_ImplWin32_InitForOpenGL(hwnd, NULL);
+}
+
+bool    ImGui_ImplWin32_InitForOpenGL(void* hwnd, void* hglrc)
 {
     ImGuiIO& io = ImGui::GetIO();
     IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
@@ -145,25 +154,6 @@
     if (!::QueryPerformanceCounter((LARGE_INTEGER*)&perf_counter))
         return false;
 
-    // Load WGL symbols explicitly
-    // This is needed to allow compilation if and when non-OpenGL APIs are used with Win32.
-    // The function pointer names are preceded with an underscore ("_") to prevent duplicate
-    // symbols in projects where OpenGL32.dll is linked implicitly.
-    if (hglrc)
-    {
-        libgl = LoadLibraryA("opengl32.dll");
-        IM_ASSERT(libgl);
-        _wglCreateContext = (HGLRC(WINAPI*)(HDC))GetProcAddress(libgl, "wglCreateContext");
-        _wglDeleteContext = (BOOL(WINAPI*)(HGLRC))GetProcAddress(libgl, "wglDeleteContext");
-        _wglMakeCurrent = (BOOL(WINAPI*)(HDC, HGLRC))GetProcAddress(libgl, "wglMakeCurrent");
-        _wglShareLists = (BOOL(WINAPI*)(HGLRC, HGLRC))GetProcAddress(libgl, "wglShareLists");
-        IM_ASSERT(_wglCreateContext);
-        IM_ASSERT(_wglDeleteContext);
-        IM_ASSERT(_wglMakeCurrent);
-        IM_ASSERT(_wglShareLists);
-        atexit([](){ FreeLibrary(libgl); });
-    }
-
     // Setup backend capabilities flags
     ImGui_ImplWin32_Data* bd = IM_NEW(ImGui_ImplWin32_Data)();
     io.BackendPlatformUserData = (void*)bd;
@@ -174,8 +164,7 @@
     io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
 
     bd->hWnd = (HWND)hwnd;
-    bd->Hdc = GetDC(bd->hWnd);
-    bd->HgLrc = (HGLRC)hglrc; // OpenGL
+    bd->OpenGlContext = (HGLRC)hglrc;
     bd->WantUpdateMonitors = true;
     bd->TicksPerSecond = perf_frequency;
     bd->Time = perf_counter;
@@ -187,6 +176,28 @@
     if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
         ImGui_ImplWin32_InitPlatformInterface();
 
+    // Dynamically load WGL symbols
+    // This is needed to allow compilation if and when non-OpenGL APIs are used with Win32.
+    // The function pointer names are preceded with an underscore ("_") to prevent duplicate
+    // symbols in projects where OpenGL32.dll is linked implicitly.
+    if (hglrc && !(bd->OglDLL))
+    {
+        bd->OglDLL = ::LoadLibraryA("opengl32.dll");
+        IM_ASSERT(bd->OglDLL);
+        _wglCreateContext = (HGLRC(WINAPI*)(HDC))GetProcAddress(bd->OglDLL, "wglCreateContext");
+        _wglDeleteContext = (BOOL(WINAPI*)(HGLRC))GetProcAddress(bd->OglDLL, "wglDeleteContext");
+        _wglMakeCurrent = (BOOL(WINAPI*)(HDC, HGLRC))GetProcAddress(bd->OglDLL, "wglMakeCurrent");
+        _wglShareLists = (BOOL(WINAPI*)(HGLRC, HGLRC))GetProcAddress(bd->OglDLL, "wglShareLists");
+        _wglGetCurrentContext = (HGLRC(WINAPI*)(VOID))GetProcAddress(bd->OglDLL, "wglGetCurrentContext");
+        _wglGetCurrentDC = (HDC(WINAPI*)(VOID))GetProcAddress(bd->OglDLL, "wglGetCurrentDC");
+        IM_ASSERT(_wglCreateContext);
+        IM_ASSERT(_wglDeleteContext);
+        IM_ASSERT(_wglMakeCurrent);
+        IM_ASSERT(_wglShareLists);
+        IM_ASSERT(_wglGetCurrentContext);
+        IM_ASSERT(_wglGetCurrentDC);
+    }
+
     // Dynamically load XInput library
 #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
     bd->WantUpdateHasGamepad = true;
@@ -219,6 +230,10 @@
 
     ImGui_ImplWin32_ShutdownPlatformInterface();
 
+    // Unload OpenGL library
+    if (bd->OglDLL)
+        ::FreeLibrary(bd->OglDLL);
+
     // Unload XInput library
 #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
     if (bd->XInputDLL)
@@ -930,8 +945,7 @@
 {
     HWND    Hwnd;
     bool    HwndOwned;
-    HDC     Hdc;
-    HGLRC   HgLrc;
+    HGLRC   OpenGlContext;
     DWORD   DwStyle;
     DWORD   DwExStyle;
 
@@ -939,8 +953,7 @@
     {
         Hwnd = nullptr;
         HwndOwned = false;
-        Hdc = nullptr;
-        HgLrc = nullptr;
+        OpenGlContext = nullptr;
         DwStyle = 0;
         DwExStyle = 0;
     }
@@ -983,27 +996,39 @@
         rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,    // Window area
         parent_window, nullptr, ::GetModuleHandle(nullptr), nullptr);           // Parent window, Menu, Instance, Param
     vd->HwndOwned = true;
-    vd->Hdc = GetDC(vd->Hwnd);
     viewport->PlatformRequestResize = false;
     viewport->PlatformHandle = viewport->PlatformHandleRaw = vd->Hwnd;
 
     ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
-    if (bd->HgLrc) // OpenGL
+    if (bd->OpenGlContext)
     {
+        HDC previousDC = _wglGetCurrentDC();
+        HGLRC previousRC = _wglGetCurrentContext();
+        HDC newDC = ::GetDC(vd->Hwnd);
+
         // Use the main window's pixel format
-        int pf = GetPixelFormat(bd->Hdc);
+        int pf;
         PIXELFORMATDESCRIPTOR pfd;
-        DescribePixelFormat(bd->Hdc, pf, sizeof(pfd), &pfd);
-        SetPixelFormat(vd->Hdc, pf, &pfd);
+        if (previousDC)
+        {
+            pf = ::GetPixelFormat(previousDC);
+            ::DescribePixelFormat(previousDC, pf, sizeof(pfd), &pfd);
+        }
+        else
+        {
+            HDC mainDC = ::GetDC(bd->hWnd);
+            pf = ::GetPixelFormat(mainDC);
+            ::DescribePixelFormat(mainDC, pf, sizeof(pfd), &pfd);
+            ::ReleaseDC(bd->hWnd, mainDC);
+        }
+        ::SetPixelFormat(newDC, pf, &pfd);
 
         // Create OpenGL context and share main context's lists with it
-        vd->HgLrc = _wglCreateContext(vd->Hdc);
-        _wglMakeCurrent(vd->Hdc, vd->HgLrc);
-        _wglShareLists(bd->HgLrc, vd->HgLrc);
-
-        // Present window
-        ImGui_ImplWin32_SetWindowFocus(viewport);
-        ImGui_ImplWin32_ShowWindow(viewport);
+        vd->OpenGlContext = _wglCreateContext(newDC);
+        _wglMakeCurrent(newDC, vd->OpenGlContext);
+        _wglShareLists(bd->OpenGlContext, vd->OpenGlContext);
+        _wglMakeCurrent(previousDC, previousRC);
+        ::ReleaseDC(vd->Hwnd, newDC);
     }
 }
 
@@ -1020,8 +1045,8 @@
         }
         if (vd->Hwnd && vd->HwndOwned)
         {
-            if (vd->HgLrc)
-                _wglDeleteContext(vd->HgLrc);
+            if (vd->OpenGlContext)
+                _wglDeleteContext(vd->OpenGlContext);
 
             ::DestroyWindow(vd->Hwnd);
         }
@@ -1184,19 +1209,37 @@
 #endif
 }
 
-static void ImGui_ImplWin32_OGL_RenderWindow(ImGuiViewport* viewport, void*)
+static void ImGui_ImplWin32_PushOglContext(ImGuiViewport* viewport)
 {
+    ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
     ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
-    IM_ASSERT(vd->HgLrc); // ImGui_ImplWin32_OGL_RenderWindow() is only registered if API is OpenGL
-    _wglMakeCurrent(vd->Hdc, vd->HgLrc);
+    IM_ASSERT(vd->OpenGlContext); // ImGui_ImplWin32_PushOglContext() is only registered if API is OpenGL
+
+    bd->stashedDeviceContext = _wglGetCurrentDC();
+    bd->stashedOpenGlContext = _wglGetCurrentContext();
+    _wglMakeCurrent(::GetDC(vd->Hwnd), vd->OpenGlContext);
+}
+
+static void ImGui_ImplWin32_PopOglContext(ImGuiViewport* viewport)
+{
+    ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
+    ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
+    IM_ASSERT(vd->OpenGlContext); // ImGui_ImplWin32_PopOglContext() is only registered if API is OpenGL
+
+    IM_ASSERT(_wglGetCurrentContext() == vd->OpenGlContext);
+    HDC vd_dc = _wglGetCurrentDC();
+    _wglMakeCurrent(bd->stashedDeviceContext, bd->stashedOpenGlContext);
+    ::ReleaseDC(vd->Hwnd, vd_dc);
 }
 
 static void ImGui_ImplWin32_OGL_SwapBuffers(ImGuiViewport* viewport, void*)
 {
     ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
-    IM_ASSERT(vd->HgLrc); // ImGui_ImplWin32_OGL_SwapBuffers() is only registered if API is OpenGL
-    _wglMakeCurrent(vd->Hdc, vd->HgLrc);
-    SwapBuffers(vd->Hdc);
+    IM_ASSERT(vd->OpenGlContext); // ImGui_ImplWin32_OGL_SwapBuffers() is only registered if API is OpenGL
+
+    ImGui_ImplWin32_PushOglContext(viewport);
+    ::SwapBuffers(_wglGetCurrentDC());
+    ImGui_ImplWin32_PopOglContext(viewport);
 }
 
 static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -1276,9 +1319,10 @@
     platform_io.Platform_OnChangedViewport = ImGui_ImplWin32_OnChangedViewport; // FIXME-DPI
 
     ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
-    if (bd->HgLrc) // OpenGL
+    if (bd->OpenGlContext) // OpenGL
     {
-        platform_io.Platform_RenderWindow = ImGui_ImplWin32_OGL_RenderWindow;
+        platform_io.Platform_PushOglContext = ImGui_ImplWin32_PushOglContext;
+        platform_io.Platform_PopOglContext = ImGui_ImplWin32_PopOglContext;
         platform_io.Platform_SwapBuffers = ImGui_ImplWin32_OGL_SwapBuffers;
     }
 
@@ -1288,8 +1332,7 @@
     ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)();
     vd->Hwnd = bd->hWnd;
     vd->HwndOwned = false;
-    vd->Hdc = bd->Hdc;
-    vd->HgLrc = bd->HgLrc; // OpenGL
+    vd->OpenGlContext = bd->OpenGlContext;
     main_viewport->PlatformUserData = vd;
     main_viewport->PlatformHandle = (void*)bd->hWnd;
 }
diff --git a/backends/imgui_impl_win32.h b/backends/imgui_impl_win32.h
index 8ca0cb7..b01f6e0 100644
--- a/backends/imgui_impl_win32.h
+++ b/backends/imgui_impl_win32.h
@@ -17,7 +17,8 @@
 #pragma once
 #include "imgui.h"      // IMGUI_IMPL_API
 
-IMGUI_IMPL_API bool     ImGui_ImplWin32_Init(void* hwnd, void* hglrc = NULL);
+IMGUI_IMPL_API bool     ImGui_ImplWin32_Init(void* hwnd);
+IMGUI_IMPL_API bool     ImGui_ImplWin32_InitForOpenGL(void* hwnd, void* hglrc);
 IMGUI_IMPL_API void     ImGui_ImplWin32_Shutdown();
 IMGUI_IMPL_API void     ImGui_ImplWin32_NewFrame();
 
diff --git a/imgui.h b/imgui.h
index 2910bd6..ab8fa5e 100644
--- a/imgui.h
+++ b/imgui.h
@@ -3220,6 +3220,8 @@
     float   (*Platform_GetWindowDpiScale)(ImGuiViewport* vp);               // N . . . .  // (Optional) [BETA] FIXME-DPI: DPI handling: Return DPI scale for this viewport. 1.0f = 96 DPI.
     void    (*Platform_OnChangedViewport)(ImGuiViewport* vp);               // . F . . .  // (Optional) [BETA] FIXME-DPI: DPI handling: Called during Begin() every time the viewport we are outputting into changes, so backend has a chance to swap fonts to adjust style.
     int     (*Platform_CreateVkSurface)(ImGuiViewport* vp, ImU64 vk_inst, const void* vk_allocators, ImU64* out_vk_surface); // (Optional) For a Vulkan Renderer to call into Platform code (since the surface creation needs to tie them both).
+    void    (*Platform_PushOglContext)(ImGuiViewport* vp);                  // . . . R .  // (Optional) For an OpenGL Renderer to make a platform window's rendering context current for rendering
+    void    (*Platform_PopOglContext)(ImGuiViewport* vp);                   // . . . R .  // (Optional) For an OpenGL Renderer to revert to the previous rendering context after rendering a platform window
 
     // (Optional) Renderer functions (e.g. DirectX, OpenGL, Vulkan)
     void    (*Renderer_CreateWindow)(ImGuiViewport* vp);                    // . . U . .  // Create swap chain, frame buffers etc. (called after Platform_CreateWindow)