imguiとは
まず読み方ですが、「イムギューアイ」 と読む人が多いです。
DirectX12 や OpenGL などのグラフィックスライブラリを使って GUI を描画するライブラリです。
GUI の制御をコードのみでできるので使いやすいのが特徴で、特にデバッグ時に重宝するようです。
対象のウィンドウ
CWndを継承したクラスに表示してみます。
ヘッダ
pch.h にヘッダを追加します。
#include "imgui.h" #include "imgui_impl_opengl3.h" #include "imgui_impl_win32.h"
MyWnd.h に ImGui_ImplWin32_WndProcHandler メソッドを定義します。
// Forward declare message handler from imgui_impl_win32.cpp extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
ソース
MyWnd::OnCreate() で OpenGL 初期化後に以下のように初期化します。
// DPI awareness(必要なら) ImGui_ImplWin32_EnableDpiAwareness(); float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor( MonitorFromPoint(POINT{ 0,0 }, MONITOR_DEFAULTTOPRIMARY) ); // ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Style ImGui::StyleColorsDark(); ImGuiStyle& style = ImGui::GetStyle(); style.ScaleAllSizes(main_scale); // ← OK(master でも使える) // master 版では FontScaleDpi が無いので、代わりにこれを使う io.FontGlobalScale = main_scale; // Backend init ImGui_ImplWin32_InitForOpenGL(m_hWnd); ImGui_ImplOpenGL3_Init("#version 130"); // GLAD ならこれでOK
SwapBuffer の前に以下のように書きます。
// Our state bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Start the Dear ImGui frame ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplWin32_NewFrame(); ImGui::NewFrame(); ImGui::Begin("Test Movable Window"); // ← フラグ完全に無し ImGui::Text("Move me!"); ImGui::End(); ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
imgui がイベントハンドリングできるように WindowProc を以下のように書きます。
LRESULT CGLLayer::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class if (ImGui_ImplWin32_WndProcHandler(m_hWnd, message, wParam, lParam)) return true; return CWnd::WindowProc(message, wParam, lParam); }
これで以下のように表示されるはずです。

imguiの再描画
imggi はグラフィックスライブラリで描画をするので、
GmeLoopがある場合はそこで、無い場合は Timer や Mousemove で再描画をする必要があります。
imgui のウィンドウを操作している時は、OnLButtonDownを処理しないようにする
そうしないと imgui のウィンドウを触るたびにイベントが発生して予期しない動作をしてしまいます。
私は、OnLButtonDown に以下のように書きました。
void MyWnd::OnLButtonDown(UINT nFlags, CPoint point) { // Add your message handler code here and/or call default ImGuiIO& io = ImGui::GetIO(); if (io.WantCaptureMouse) { // ImGui がマウスを使っている -> MFC の処理を無効化 return; } // 通常の処理 }
動かない場合は
本家のサンプル を参考にするとよいでしょう。
私もこれだけを見て動かしてみました。