ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
61.46k stars 10.34k forks source link

Separate window, can't be transparent, problem #8144

Closed 1540781622 closed 2 weeks ago

1540781622 commented 2 weeks ago

Version/Branch of Dear ImGui:

imgui 1.91.5 docking

Back-ends:

imgui_impl_dx11.cpp + imgui_impl_win32.cpp

Compiler, OS:

windows10 22H2

Full config/build information:

NOT

Details:

My Issue/Question:

XXX (please provide as much context as possible)

Screenshots/Video:

A0

Minimal, Complete and Verifiable Example code:

static ID3D11Device g_pd3dDevice = nullptr; static ID3D11DeviceContext g_pd3dDeviceContext = nullptr; static IDXGISwapChain g_pSwapChain = nullptr; static UINT g_ResizeWidth = 0, g_ResizeHeight = 0; static ID3D11RenderTargetView g_mainRenderTargetView = nullptr;

bool CreateDeviceD3D(HWND hWnd); void CleanupDeviceD3D(); void CreateRenderTarget(); void CleanupRenderTarget(); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

void EnableMouseTransparency() { HWND hWnd = (HWND)ImGui::GetCurrentWindow()->Viewport->PlatformHandle; LONG_PTR exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE); exStyle |= WS_EX_TRANSPARENT | WS_EX_LAYERED; SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle); }

void Overlay::DrawOverlayHandler() { ImGui::SetNextWindowSize(ImVec2(1920 / 2, 1080 / 2)); ImGui::SetNextWindowPos(ImVec2(Menu::Variable.绘制窗口X, Menu::Variable.绘制窗口Y));

ImGuiWindowClass WindowClass;
WindowClass.ClassId = ImHashStr("beging2");

ImGuiViewportFlags WindowClassFlags = 0;
WindowClassFlags |= ImGuiViewportFlags_NoDecoration;
WindowClassFlags |= ImGuiViewportFlags_NoInputs;
WindowClassFlags |= ImGuiViewportFlags_NoRendererClear;
WindowClassFlags |= ImGuiViewportFlags_NoAutoMerge;

ImGuiWindowFlags WindowFlags = 0;
WindowFlags |= ImGuiWindowFlags_NoTitleBar;
WindowFlags |= ImGuiWindowFlags_NoResize;
WindowFlags |= ImGuiWindowFlags_NoScrollbar;
WindowFlags |= ImGuiWindowFlags_NoCollapse;
WindowFlags |= ImGuiWindowFlags_NoInputs;
WindowFlags |= ImGuiWindowFlags_NoDecoration;
WindowFlags |= ImGuiWindowFlags_NoNav;

if (!Menu::Variable.串流模式)
{
    WindowFlags |= ImGuiWindowFlags_NoBackground;
    WindowClassFlags |= ImGuiViewportFlags_TopMost;
}

ImGuiStyle& style = ImGui::GetStyle();
float OriginalBorderSize = style.WindowBorderSize;
ImVec4 OriginalWindowBgColor = style.Colors[ImGuiCol_WindowBg];
ImVec2 OriginalWindowPadding = style.WindowPadding;

style.WindowBorderSize = 0.0f;
style.WindowPadding = { 0.f, 0.f };
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);

WindowClass.ViewportFlagsOverrideSet = WindowClassFlags;
ImGui::SetNextWindowClass(&WindowClass);
ImGui::GetStyle().Colors[ImGuiCol_WindowBg] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);

// 创建并绘制ESP Overlay窗口
ImGui::Begin("beging2", nullptr, WindowFlags);
{
    if (!Menu::Variable.串流模式) EnableMouseTransparency();

    ImGui::TextGradiented("66666666", 0x7ED4AD, 0xABBA7C, 66);

}
ImGui::End();

style.WindowBorderSize = OriginalBorderSize;
style.WindowPadding = OriginalWindowPadding;
style.Colors[ImGuiCol_WindowBg] = OriginalWindowBgColor;

}

int Overlay::Init() { WNDCLASSEXW wc = { sizeof(WNDCLASSEX),
CS_CLASSDC,
WndProc,
0L,
0L,
GetModuleHandle(NULL),
NULL,
NULL,
NULL,
NULL,
L"ImGui Example",
NULL
};

::RegisterClassExW(&wc);

HWND hwnd = ::CreateWindowW(
    wc.lpszClassName,       
    L"Menu --- ",       
    WS_OVERLAPPEDWINDOW,    
    0, 0,                   
    1280, 720,              
    nullptr,                
    nullptr,                
    wc.hInstance,           
    nullptr                 
);

if (!CreateDeviceD3D(hwnd))
{
    CleanupDeviceD3D();
    ::UnregisterClassW(wc.lpszClassName, wc.hInstance);
    return 1;
}

::ShowWindow(hwnd, SW_SHOWDEFAULT);
::UpdateWindow(hwnd);

IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; 

io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; 
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;  
io.ConfigViewportsNoDefaultParent = true;  
io.ConfigViewportsNoAutoMerge = true;      
io.ConfigViewportsNoTaskBarIcon = true;    

ImFontAtlas* FontAtlas = new ImFontAtlas();

ImFontConfig arialConfig;
arialConfig.FontDataOwnedByAtlas = false; 

ImFont* ArialFont = FontAtlas->AddFontFromFileTTF("c:\\Windows\\Fonts\\msyhbd.ttc", 19.0f, &arialConfig, io.Fonts->GetGlyphRangesChineseFull());

ImFontConfig fontAwesomeConfig;
fontAwesomeConfig.MergeMode = true; 
fontAwesomeConfig.FontDataOwnedByAtlas = false;

static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
ImFont* Fontawesome = FontAtlas->AddFontFromMemoryTTF(
    (void*)fontAwesome,
    sizeof(fontAwesome),
    23.0f,
    &fontAwesomeConfig,
    icon_ranges
);

io.Fonts = FontAtlas;

ImGui::StyleColorsLight();

ImGuiStyle& style = ImGui::GetStyle();
style.ScrollbarSize = 10.0f; 
style.ScrollbarRounding = 12.0f;
style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.f, 0.f, 0.f, 0.f);

if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
    style.WindowRounding = 1.0f;
    style.Colors[ImGuiCol_WindowBg].w = 1.0f; 
}

ImGui_ImplWin32_Init(hwnd); 
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);

bool show_demo_window = true; 
bool show_another_window = false;
ImVec4 clear_color = { 0, 0, 0, 0 }; 
const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };

bool done = false; 
bool Clear = false;

float TimeSeconds = 0.f; 

while (!done)
{
    MSG msg;

    while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE))
    {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
        if (msg.message == WM_QUIT)
            done = true;
    }

    if (done)
        break;

    if (g_ResizeWidth != 0 && g_ResizeHeight != 0)
    {
        CleanupRenderTarget();
        g_pSwapChain->ResizeBuffers(0, g_ResizeWidth, g_ResizeHeight, DXGI_FORMAT_UNKNOWN, 0);
        g_ResizeWidth = g_ResizeHeight = 0;
        CreateRenderTarget();
    }

    ImGui_ImplDX11_NewFrame(); 
    ImGui_ImplWin32_NewFrame();

    ImGui::NewFrame();

    if (true) {

        DrawOverlayHandler();
        Menu::DIY(FontAtlas);
    }

    ImGui::Render();

    g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);
    g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
    ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());

    ImGui::UpdatePlatformWindows();
    ImGui::RenderPlatformWindowsDefault();
    g_pSwapChain->Present(0, 0);
}

// Cleanup
ImGui_ImplDX11_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();

CleanupDeviceD3D();
::DestroyWindow(hwnd);
::UnregisterClassW(wc.lpszClassName, wc.hInstance);

return 0;

}

bool CreateDeviceD3D(HWND hWnd) { // Setup swap chain DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 2; sd.BufferDesc.Width = 0; sd.BufferDesc.Height = 0; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

UINT createDeviceFlags = 0;
//createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };
HRESULT res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
if (res == DXGI_ERROR_UNSUPPORTED) // Try high-performance WARP software driver if hardware is not available.
    res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
if (res != S_OK)
    return false;

CreateRenderTarget();
return true;

}

void CleanupDeviceD3D() { CleanupRenderTarget(); if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = nullptr; } if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = nullptr; } if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = nullptr; } }

void CreateRenderTarget() { ID3D11Texture2D* pBackBuffer; g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView); pBackBuffer->Release(); }

void CleanupRenderTarget() { if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = nullptr; } }

ifndef WM_DPICHANGED

define WM_DPICHANGED 0x02E0 // From Windows SDK 8.1+ headers

endif

extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true;

switch (msg)
{
case WM_SIZE:
    if (wParam == SIZE_MINIMIZED)
        return 0;
    g_ResizeWidth = (UINT)LOWORD(lParam); // Queue resize
    g_ResizeHeight = (UINT)HIWORD(lParam);
    return 0;
case WM_SYSCOMMAND:
    if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
        return 0;
    break;
case WM_DESTROY:
    ::PostQuitMessage(0);
    return 0;
case WM_DPICHANGED:
    if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports)
    {
        //const int dpi = HIWORD(wParam);
        //printf("WM_DPICHANGED to %d (%.0f%%)\n", dpi, (float)dpi / 96.0f * 100.0f);
        const RECT* suggested_rect = (RECT*)lParam;
        ::SetWindowPos(hWnd, nullptr, suggested_rect->left, suggested_rect->top, suggested_rect->right - suggested_rect->left, suggested_rect->bottom - suggested_rect->top, SWP_NOZORDER | SWP_NOACTIVATE);
    }
    break;
}
return ::DefWindowProcW(hWnd, msg, wParam, lParam);

}

ocornut commented 2 weeks ago

Sorry but #1586