### Title Text Tweaker Configuration Example Source: https://context7.com/maplespe/dwmblurglass/llms.txt Provides an example configuration for TitleTextTweaker, specifying custom text colors for active/inactive states in both light and dark modes. This configuration is typically written to a data\config.ini file. ```cpp // Hooks installed in TitleTextTweaker::Attach(): // DrawTextW → MyDrawTextW (IAT in udwm.dll) // IWICImagingFactory2::CreateBitmapFromHBITMAP → MyCreateBitmapFromHBITMAP // CTopLevelWindow::UpdateWindowVisuals → CTopLevelWindow_UpdateWindowVisuals // CTopLevelWindow::UpdateText → CTopLevelWindow_UpdateText // CText::ValidateResources → CText_ValidateResources // Custom text color is sourced from ConfigData at render time: // Light mode active: cfg.activeTextColor (default 0xFF000000 = opaque black) // Light mode inactive: cfg.inactiveTextColor (default 0xFFB4B4B4 = light gray) // Dark mode active: cfg.activeTextColorDark (default 0xFFFFFFFF = white) // Dark mode inactive: cfg.inactiveTextColorDark (default 0xFFB4B4B4 = light gray) // Example config (written to data\config.ini): // [config] // ActiveTextColor=FF000000 // InactiveTextColor=FFB4B4B4 // ActiveTextColorDark=FFFFFFFF // InactiveTextColorDark=FFB4B4B4 ``` -------------------------------- ### Triggering Host Notifications Source: https://context7.com/maplespe/dwmblurglass/llms.txt Examples of triggering host notifications. A config file save can trigger a refresh notification, and the 'Uninstall' action can trigger a shutdown notification. ```cpp // Trigger a config reload from the host after saving settings: ConfigData::SaveToFile(L"data\config.ini", cfg); MHostNotify(MHostNotifyType::Refresh); // → Ext calls Refresh(true) in dwm.exe // Force shutdown (called when user clicks "Uninstall"): MHostNotify(MHostNotifyType::Shutdown); // → Ext calls Shutdown() in dwm.exe ``` -------------------------------- ### Host Notification for Accent Color Change Source: https://context7.com/maplespe/dwmblurglass/llms.txt Example of how the host process can trigger an accent color refresh. It registers for `WM_DWMCOLORIZATIONCOLORCHANGED` and calls `MHostNotify` to initiate the process. ```cpp // The host registers for WM_DWMCOLORIZATIONCOLORCHANGED and calls: // MHostNotify(MHostNotifyType::Refresh); // which triggers Refresh() → RefreshAccentColor(0) inside dwm.exe ``` -------------------------------- ### Create or Get Backdrop Brush Source: https://context7.com/maplespe/dwmblurglass/llms.txt Creates or retrieves a cached CompositionBrush for backdrop effects. Handles different effect types (Aero, Blur, Acrylic, Mica) and active/inactive window states. Uses a cache to avoid redundant brush creation. ```cpp wuc::CompositionBrush BackdropFactory::GetOrCreateBackdropBrush( const wuc::Compositor& compositor, DWORD color, // ABGR packed color (from ACCENT_POLICY or blend config) bool active, // true = window is active/focused DWM::ACCENT_POLICY* policy /*= nullptr*/) { // Aero has different active vs inactive appearances; others do not if (g_type != effectType::Aero) active = false; auto& map{ active ? g_backdropActiveBrushMap : g_backdropInactiveBrushMap }; auto it{ map.find(color) }; if (it != map.end() && it->second.Compositor() == compositor) return it->second; // Cache hit wuc::CompositionBrush brush{ nullptr }; auto winrtColor{ MakeWinrtColor(color) }; auto glassOpacity{ policy ? static_cast(policy->nColor >> 24 & 0xFF) / 255.f : 1.f }; switch (g_type) { case effectType::Blur: brush = BlurBackdrop::CreateBrush(compositor, winrtColor, glassOpacity, g_configData.customBlurAmount); break; case effectType::Aero: brush = AeroBackdrop::CreateBrush(compositor, MakeWinrtColor(color, true), MakeWinrtColor(color, true), active ? g_configData.aeroColorBalance : g_configData.aeroColorBalance * 0.4f, g_configData.aeroAfterglowBalance, active ? g_configData.aeroBlurBalance : 0.4f * g_configData.aeroBlurBalance + 0.6f, g_configData.customBlurAmount); break; case effectType::Acrylic: brush = AcrylicBackdrop::CreateBrush(compositor, g_materialTextureBrush, // Noise texture from Windows.UI.Xaml.Controls.dll AcrylicBackdrop::GetEffectiveTintColor(winrtColor, glassOpacity, std::nullopt), AcrylicBackdrop::GetEffectiveLuminosityColor(winrtColor, glassOpacity, std::nullopt), g_configData.customBlurAmount, 0.02f /*noise amount*/); break; case effectType::Mica: brush = MicaBackdrop::CreateBrush(compositor, AcrylicBackdrop::GetEffectiveTintColor(winrtColor, glassOpacity, std::nullopt), AcrylicBackdrop::GetEffectiveLuminosityColor(winrtColor, glassOpacity, std::nullopt), glassOpacity, g_configData.luminosityOpacity); break; default: brush = compositor.CreateColorBrush(MakeWinrtColor(color)); } if (!policy) map.insert_or_assign(color, brush); return brush; } ``` -------------------------------- ### DWMBlurGlass Extension DLL Startup and Shutdown Source: https://context7.com/maplespe/dwmblurglass/llms.txt The `Startup` function initializes hooks, loads symbols, and applies initial configuration. The `Shutdown` function cleans up hooks, restores original settings, and forces DWM to redraw windows. These are called by the DLL loader when the extension is injected into or removed from `dwm.exe`. ```cpp // Called from DllMain when the DLL is injected into dwm.exe namespace MDWMBlurGlassExt { bool Startup() try { // Idempotent guard if (g_startup) return true; g_startup = true; // Install crash dump handler g_oldExceptionFilter = SetUnhandledExceptionFilter(TopLevelExceptionFilter); // Load reversed symbol offsets from the host's offset table MHostLoadProcOffsetList(); // Retrieve live DWM singleton pointers by name CDesktopManager::s_pDesktopManagerInstance = *MHostGetProcAddress("CDesktopManager::s_pDesktopManagerInstance"); CDesktopManager::s_csDwmInstance = MHostGetProcAddress("CDesktopManager::s_csDwmInstance"); // Windows 10: patch HrgnFromRects for rounded border extension if (os::buildNumber < 22000) g_funHrgnFromRects.Attach(); // Enable the ValidateVisual dispatcher (hooks accent, button, backdrop, DWM API effects) g_CTopLevelWindow_ValidateVisual_HookDispatcher.enable_hook_routine<4, true>(); TitleTextTweaker::Attach(); // Windows 10: redirect CreateRoundRectRgn via IAT patch in udwm.dll if (os::buildNumber < 22000) { HMODULE hModule = GetModuleHandleW(L"gdi32.dll"); g_funCreateRoundRgn = (decltype(g_funCreateRoundRgn))GetProcAddress(hModule, "CreateRoundRectRgn"); WriteIAT(GetModuleHandleW(L"udwm.dll"), "gdi32.dll", { { "CreateRoundRectRgn", MyCreateRoundRectRgn } }); } // Load config and attach all sub-system hooks Refresh(); return true; } catch (...) { return false; } void Shutdown() { if (!g_startup) return; // Remove all hooks in reverse order CustomButton::Detach(); OcclusionCulling::Detach(); TitleTextTweaker::Detach(); BlurRadiusTweaker::Detach(); AccentBlur::Detach(); CustomBackdrop::Detach(); DwmAPIEffect::Detach(); ScaleOptimizer::Detach(); g_CTopLevelWindow_ValidateVisual_HookDispatcher.enable_hook_routine<4, false>(); // Restore IAT on Windows 10 if (os::buildNumber < 22000) WriteIAT(GetModuleHandleW(L"udwm.dll"), "gdi32.dll", { { "CreateRoundRectRgn", g_funCreateRoundRgn } }); // Force all visible windows to recalculate their non-client area EnumWindows([](HWND hwnd, LPARAM) -> BOOL { if (IsWindowVisible(hwnd) || IsIconic(hwnd)) SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE); return TRUE; }, 0); SetUnhandledExceptionFilter(g_oldExceptionFilter); g_startup = false; // Notify DWM to redraw with default appearance PostMessageW(FindWindowW(L"Dwm", nullptr), WM_THEMECHANGED, 0, 0); } } ``` -------------------------------- ### Host Process Management Functions Source: https://context7.com/maplespe/dwmblurglass/llms.txt Provides functions for managing the host process, including launching, stopping, checking symbol state, downloading symbols, and loading the DWM extension DLL. ```cpp // Host process management: MHostStartProcess(); // Launches DWMBlurGlass.exe with elevated privileges StopMHostProcess(); // Sends Shutdown notify then terminates the host process bool hasSymbols = MHostGetSymbolState(); // Returns true if symbol offsets are ready bool downloaded = MHostDownloadSymbol(); // Downloads PDB symbols for current DWM build bool loaded = LoadDWMExtensionBase(err, pid); // Injects DWMBlurGlassExt.dll into dwm.exe (pid) ``` -------------------------------- ### Create Mica Backdrop Brush Source: https://context7.com/maplespe/dwmblurglass/llms.txt Builds the Windows 11 Mica effect, which includes a blurred wallpaper backdrop with luminosity blend and tint overlay. Falls back to blur on Windows 10. Requires a compositor, tint color, luminosity color, and their respective opacities. ```cpp wuc::CompositionBrush MicaBackdrop::CreateBrush( const wuc::Compositor& compositor, const wu::Color& tintColor, // Blend tint (light/dark mode aware) const wu::Color& luminosityColor, // Derived from tint via HSV clamping float tintOpacity, // 0.0 – 1.0 float luminosityOpacity) // Typically 0.65 (from config) { if (static_cast(tintColor.A) * tintOpacity == 255.f) return compositor.CreateColorBrush(tintColor); // Tint layer with opacity auto tintColorEffect{ winrt::make_self() }; tintColorEffect->SetColor(tintColor); auto tintOpacityEffect{ winrt::make_self() }; tintOpacityEffect->SetOpacity(tintOpacity); tintOpacityEffect->SetInput(*tintColorEffect); // Luminosity layer with separate opacity auto luminosityColorEffect{ winrt::make_self() }; luminosityColorEffect->SetColor(luminosityColor); auto luminosityOpacityEffect{ winrt::make_self() }; luminosityOpacityEffect->SetOpacity(luminosityOpacity); luminosityOpacityEffect->SetInput(*luminosityColorEffect); // Luminosity blend over blurred wallpaper auto luminosityBlend{ winrt::make_self() }; luminosityBlend->SetBlendMode(D2D1_BLEND_MODE_COLOR); luminosityBlend->SetBackground( wuc::CompositionEffectSourceParameter{ L"BlurredWallpaperBackdrop" }); luminosityBlend->SetForeground(*luminosityOpacityEffect); // Color blend: tint over luminosity result auto colorBlend{ winrt::make_self() }; colorBlend->SetBlendMode(D2D1_BLEND_MODE_LUMINOSITY); colorBlend->SetBackground(*luminosityBlend); colorBlend->SetForeground(*tintOpacityEffect); auto effectBrush{ compositor.CreateEffectFactory(*colorBlend).CreateBrush() }; // TryCreateBlurredWallpaperBackdropBrush is a Win11-only API effectBrush.SetSourceParameter( L"BlurredWallpaperBackdrop", compositor.TryCreateBlurredWallpaperBackdropBrush()); return effectBrush; // Expected: title bar mirrors the desktop wallpaper with a tinted semi-transparent overlay } ``` -------------------------------- ### Get Tint Opacity Modifier Source: https://context7.com/maplespe/dwmblurglass/llms.txt Calculates an adaptive tint opacity modifier based on the input color's luminosity and saturation. This helps to ensure the Acrylic effect is visually balanced across different color schemes. ```cpp // Helper: compute adaptive tint opacity accounting for luminosity double AcrylicBackdrop::GetTintOpacityModifier(wu::Color tintColor) { // Maps luminosity to [0.45 (white), 0.90 (gray), 0.85 (black)] max opacity constexpr double whiteMaxOpacity { 0.45 }; constexpr double midPointMaxOpacity{ 0.90 }; constexpr double blackMaxOpacity { 0.85 }; const auto hsv{ RgbToHsv(RgbFromColor(tintColor)) }; // Returns modifier in [0.45, 0.90] that is further reduced by saturation // ... (luminosity/saturation calculation) ... return opacityModifier; // Applied as: effectiveAlpha = A * tintOpacity * modifier } ``` -------------------------------- ### Reload Configuration and Notify Subsystems Source: https://context7.com/maplespe/dwmblurglass/llms.txt Reloads the configuration file and notifies all rendering subsystems to reconfigure. Call with `reload = false` to propagate current in-memory settings without re-reading the file. Ensure `g_startup` is true before calling. ```cpp void Refresh(bool reload /*= true*/) { if (!g_startup) return; static std::mutex lock; std::lock_guard _lock(lock); if (reload) { // Config file is next to DWMBlurGlass.exe under data\config.ini auto path = Utils::GetCurrentDir() + L"\\data\\config.ini"; g_configData = ConfigData::LoadFromFile(path); } // Each sub-system reads g_configData directly DwmAPIEffect::Refresh(); // DwmEnableBlurBehindWindow interop CustomBackdrop::Refresh(); // Main title bar backdrop pipeline AccentBlur::Refresh(); // Accent API (ACCENT_POLICY) override BlurRadiusTweaker::Refresh();// Custom blur radius injection CustomButton::Refresh(); // Win7-style button height/glow ScaleOptimizer::Refresh(); // Pre-scale optimization for blur if (g_configData.useAccentColor) RefreshAccentColor(0); PostMessageW(FindWindowW(L"Dwm", nullptr), WM_THEMECHANGED, 0, 0); } ``` -------------------------------- ### Create Acrylic Backdrop Brush Source: https://context7.com/maplespe/dwmblurglass/llms.txt Constructs a CompositionBrush for the Acrylic effect. Handles an opaque fast-path for solid tints. Requires a compositor, noise brush, tint color, luminosity color, blur amount, and noise amount. ```cpp wuc::CompositionBrush AcrylicBackdrop::CreateBrush( const wuc::Compositor& compositor, const wuc::CompositionSurfaceBrush& noiseBrush, // 256×256 noise from Windows.UI.Xaml.Controls.dll const wu::Color& tintColor, // Pre-computed via GetEffectiveTintColor() const wu::Color& luminosityColor, // Pre-computed via GetEffectiveLuminosityColor() float blurAmount, // Gaussian sigma float noiseAmount) // Noise layer opacity (typically 0.02) { if (tintColor.A == 255) return compositor.CreateColorBrush(tintColor); // Opaque fast-path // Tint source auto tintColorEffect{ winrt::make_self() }; tintColorEffect->SetName(L"TintColor"); tintColorEffect->SetColor(tintColor); // Luminosity source auto luminosityColorEffect{ winrt::make_self() }; luminosityColorEffect->SetName(L"LuminosityColor"); luminosityColorEffect->SetColor(luminosityColor); // Step 1: Luminosity blend (note: D2D blend mode names are swapped — bug in Windows SDK) auto luminosityBlend{ winrt::make_self() }; luminosityBlend->SetBlendMode(D2D1_BLEND_MODE_COLOR); // Actually luminosity luminosityBlend->SetBackground(CreateBlurredBackdrop(blurAmount)); luminosityBlend->SetForeground(*luminosityColorEffect); // Step 2: Color blend auto colorBlend{ winrt::make_self() }; colorBlend->SetBlendMode(D2D1_BLEND_MODE_LUMINOSITY); // Actually color colorBlend->SetBackground(*luminosityBlend); colorBlend->SetForeground(*tintColorEffect); // Step 3: Noise texture with border wrap and opacity auto noiseBorder{ winrt::make_self() }; noiseBorder->SetExtendX(D2D1_BORDER_EDGE_MODE_WRAP); noiseBorder->SetExtendY(D2D1_BORDER_EDGE_MODE_WRAP); noiseBorder->SetInput(wuc::CompositionEffectSourceParameter{ L"Noise" }); auto noiseOpacity{ winrt::make_self() }; noiseOpacity->SetOpacity(noiseAmount); noiseOpacity->SetInput(*noiseBorder); // Step 4: Multiply noise over color-blended result auto finalBlend{ winrt::make_self() }; finalBlend->SetBlendMode(D2D1_BLEND_MODE_MULTIPLY); finalBlend->SetBackground(*colorBlend); finalBlend->SetForeground(*noiseOpacity); auto effectBrush{ compositor.CreateEffectFactory(*finalBlend).CreateBrush() }; effectBrush.SetSourceParameter(L"Noise", noiseBrush); effectBrush.SetSourceParameter(L"Backdrop", compositor.CreateBackdropBrush()); return effectBrush; // Expected: Fluent Acrylic — blurred, luminosity-tinted, noise-textured translucent surface } ``` -------------------------------- ### Create Gaussian Blurred Backdrop Brush Source: https://context7.com/maplespe/dwmblurglass/llms.txt Use this function to create a blurred backdrop with an optional tint. It handles pure blur or a composite of blur and tint. If the tint is fully opaque, it skips the blur effect for performance. ```cpp // Simple blur + optional tint — the most lightweight effect wuc::CompositionBrush BlurBackdrop::CreateBrush( const wuc::Compositor& compositor, const wu::Color& tintColor, // RGBA tint (use A=0 for pure blur) float tintOpacity, // 0.0 – 1.0 float blurAmount) // Gaussian sigma (e.g. 20.f) { // Fully opaque tint? Skip blur entirely if (static_cast(tintColor.A) * tintOpacity == 255.f) return compositor.CreateColorBrush(tintColor); auto gaussianBlurEffect{ winrt::make_self() }; gaussianBlurEffect->SetName(L"Blur"); gaussianBlurEffect->SetBorderMode(D2D1_BORDER_MODE_HARD); gaussianBlurEffect->SetBlurAmount(blurAmount); gaussianBlurEffect->SetOptimizationMode(D2D1_GAUSSIANBLUR_OPTIMIZATION_SPEED); gaussianBlurEffect->SetInput(wuc::CompositionEffectSourceParameter{ L"Backdrop" }); // No tint: return pure blur if (static_cast(tintColor.A) * tintOpacity == 0.f) { auto effectBrush{ compositor.CreateEffectFactory(*gaussianBlurEffect).CreateBrush() }; effectBrush.SetSourceParameter(L"Backdrop", compositor.CreateBackdropBrush()); return effectBrush; } // Composite: blur behind + tint color on top auto tintColorEffect{ winrt::make_self() }; tintColorEffect->SetColor(tintColor); auto tintOpacityEffect{ winrt::make_self() }; tintOpacityEffect->SetOpacity(tintOpacity); tintOpacityEffect->SetInput(*tintColorEffect); auto compositeStepEffect{ winrt::make_self() }; compositeStepEffect->SetDestination(*gaussianBlurEffect); // background compositeStepEffect->SetSource(*tintOpacityEffect); // foreground auto effectBrush{ compositor.CreateEffectFactory(*compositeStepEffect).CreateBrush() }; effectBrush.SetSourceParameter(L"Backdrop", compositor.CreateBackdropBrush()); return effectBrush; // Expected: title bar shows blurred content behind a semi-transparent tint } ``` -------------------------------- ### Save Configuration Data to File Source: https://context7.com/maplespe/dwmblurglass/llms.txt Saves the provided `ConfigData` structure to a specified file path. This is used to persist custom blur and effect settings. ```cpp // Example: ConfigData fields relevant to effect selection ConfigData cfg; cfg.effectType = effectType::Acrylic; // Blur | Aero | Acrylic | Mica cfg.blurmethod = blurMethod::CustomBlur; // CustomBlur | AccentBlur | DWMAPIBlur cfg.blurAmount = 20.f; // Global blur sigma cfg.customBlurAmount = 30.f; // Per-backdrop blur sigma cfg.luminosityOpacity = 0.65f; // Mica / Acrylic luminosity layer opacity cfg.activeBlendColor = 0x64FFFFFF; // ARGB blend color for active windows cfg.inactiveBlendColor = 0x64FFFFFF; // ARGB blend color for inactive windows cfg.extendBorder = true; // Extend effect to window borders cfg.reflection = true; // Enable Aero glass reflection cfg.crossFade = true; // Animated crossfade on effect change cfg.crossfadeTime = 160; // Crossfade duration in milliseconds ConfigData::SaveToFile(L"data\\config.ini", cfg); ``` -------------------------------- ### MicaBackdrop::CreateBrush Source: https://context7.com/maplespe/dwmblurglass/llms.txt Builds the Windows 11 Mica effect, which includes a blurred wallpaper backdrop with a luminosity blend and tint overlay. It falls back to a simple blur on Windows 10 builds. ```APIDOC ## Mica Backdrop — `MicaBackdrop::CreateBrush` Builds the Windows 11 Mica effect: blurred wallpaper backdrop with a luminosity blend and tint overlay; falls back to blur on Windows 10 builds. ```cpp wuc::CompositionBrush MicaBackdrop::CreateBrush( const wuc::Compositor& compositor, const wu::Color& tintColor, // Blend tint (light/dark mode aware) const wu::Color& luminosityColor, // Derived from tint via HSV clamping float tintOpacity, // 0.0 – 1.0 float luminosityOpacity) // Typically 0.65 (from config) { if (static_cast(tintColor.A) * tintOpacity == 255.f) return compositor.CreateColorBrush(tintColor); // Tint layer with opacity auto tintColorEffect{ winrt::make_self() }; tintColorEffect->SetColor(tintColor); auto tintOpacityEffect{ winrt::make_self() }; tintOpacityEffect->SetOpacity(tintOpacity); tintOpacityEffect->SetInput(*tintColorEffect); // Luminosity layer with separate opacity auto luminosityColorEffect{ winrt::make_self() }; luminosityColorEffect->SetColor(luminosityColor); auto luminosityOpacityEffect{ winrt::make_self() }; luminosityOpacityEffect->SetOpacity(luminosityOpacity); luminosityOpacityEffect->SetInput(*luminosityColorEffect); // Luminosity blend over blurred wallpaper auto luminosityBlend{ winrt::make_self() }; luminosityBlend->SetBlendMode(D2D1_BLEND_MODE_COLOR); luminosityBlend->SetBackground( wuc::CompositionEffectSourceParameter{ L"BlurredWallpaperBackdrop" }); luminosityBlend->SetForeground(*luminosityOpacityEffect); // Color blend: tint over luminosity result auto colorBlend{ winrt::make_self() }; colorBlend->SetBlendMode(D2D1_BLEND_MODE_LUMINOSITY); colorBlend->SetBackground(*luminosityBlend); colorBlend->SetForeground(*tintOpacityEffect); auto effectBrush{ compositor.CreateEffectFactory(*colorBlend).CreateBrush() }; // TryCreateBlurredWallpaperBackdropBrush is a Win11-only API effectBrush.SetSourceParameter( L"BlurredWallpaperBackdrop", compositor.TryCreateBlurredWallpaperBackdropBrush()); return effectBrush; // Expected: title bar mirrors the desktop wallpaper with a tinted semi-transparent overlay } ``` ``` -------------------------------- ### Host to DLL Notification Function Source: https://context7.com/maplespe/dwmblurglass/llms.txt Sends a notification from the host process to the injected DLL using `SendMessageW`. Finds the DLL's window by its class name and sends the specified `MHostNotifyType` command. ```cpp // Host → DLL (from DWMBlurGlass.exe): void MHostNotify(MHostNotifyType type, LPARAM param /*= 0*/) { HWND hwnd = FindWindowW(DWMBlurGlassNotifyClassName, nullptr); if (hwnd) SendMessageW(hwnd, WM_USER, static_cast(type), param); } ``` -------------------------------- ### AcrylicBackdrop::CreateBrush Source: https://context7.com/maplespe/dwmblurglass/llms.txt Creates a CompositionBrush that implements the full Windows Fluent Design Acrylic recipe. This includes background blur, luminosity blend, tint overlay, and a multiply-blended noise texture. ```APIDOC ## AcrylicBackdrop::CreateBrush ### Description Implements the full Windows Fluent Design Acrylic recipe: background blur → luminosity blend → tint overlay → multiply-blended noise texture. ### Method Signature ```cpp wuc::CompositionBrush AcrylicBackdrop::CreateBrush( const wuc::Compositor& compositor, const wuc::CompositionSurfaceBrush& noiseBrush, // 256×256 noise from Windows.UI.Xaml.Controls.dll const wu::Color& tintColor, // Pre-computed via GetEffectiveTintColor() const wu::Color& luminosityColor, // Pre-computed via GetEffectiveLuminosityColor() float blurAmount, // Gaussian sigma float noiseAmount) // Noise layer opacity (typically 0.02) ``` ### Parameters - **compositor** (const wuc::Compositor&): The compositor instance. - **noiseBrush** (const wuc::CompositionSurfaceBrush&): A 256x256 noise texture brush. - **tintColor** (const wu::Color&): The pre-computed tint color, typically obtained via `GetEffectiveTintColor()`. - **luminosityColor** (const wu::Color&): The pre-computed luminosity color, typically obtained via `GetEffectiveLuminosityColor()`. - **blurAmount** (float): The amount of Gaussian blur to apply (sigma value). - **noiseAmount** (float): The opacity of the noise layer (typically around 0.02). ### Returns - wuc::CompositionBrush: A brush representing the acrylic effect. ### Notes - If `tintColor.A` is 255 (opaque), a `ColorBrush` is returned as a fast path. - The function constructs a complex visual effect chain using `BlendEffect`, `ColorSourceEffect`, `BorderEffect`, and `OpacityEffect`. - `D2D1_BLEND_MODE_COLOR` is used for luminosity blending due to a known bug in the Windows SDK where blend mode names are swapped. - The `Noise` parameter is set using `SetSourceParameter` with `noiseBrush`. - The `Backdrop` parameter is set using `SetSourceParameter` with a `Compositor.CreateBackdropBrush()`. ### Example Usage (Conceptual) ```cpp // Assuming compositor, noiseBrush, tintColor, luminosityColor, blurAmount, noiseAmount are defined wuc::CompositionBrush acrylicBrush = AcrylicBackdrop::CreateBrush( compositor, noiseBrush, tintColor, luminosityColor, blurAmount, noiseAmount ); // Use acrylicBrush for UI elements ``` ``` -------------------------------- ### Create Aero Backdrop Brush Source: https://context7.com/maplespe/dwmblurglass/llms.txt Generates a composition brush for the Aero Glass effect. Handles optional Gaussian blur and applies color balance and afterglow tinting. Use when implementing custom window backgrounds with Aero-like transparency and effects. ```cpp wuc::CompositionBrush AeroBackdrop::CreateBrush( const wuc::Compositor& compositor, const wu::Color& color, // Main colorization color const wu::Color& afterglowColor, // Usually same as color float colorBalance, // Active: ~0.08, Inactive: ~0.032 float afterglowBalance, // ~0.43 float blurBalance, // Active: ~0.49, Inactive: ~0.80 float blurAmount) // Gaussian sigma { // 1. Create blurred backdrop (or raw backdrop if blurAmount == 0) wuc::CompositionBrush blurredBackdropBrush = [&]() -> wuc::CompositionBrush { if (!blurAmount) return compositor.CreateBackdropBrush(); auto gaussianBlurEffect{ winrt::make_self() }; gaussianBlurEffect->SetBlurAmount(blurAmount); gaussianBlurEffect->SetOptimizationMode(D2D1_GAUSSIANBLUR_OPTIMIZATION_SPEED); gaussianBlurEffect->SetInput(wuc::CompositionEffectSourceParameter{ L"Backdrop" }); auto brush{ compositor.CreateEffectFactory(*gaussianBlurEffect).CreateBrush() }; brush.SetSourceParameter(L"Backdrop", compositor.CreateBackdropBrush()); return brush; }(); // 2. Desaturate the blurred backdrop → grayscale base auto desaturated{ winrt::make_self() }; desaturated->SetSaturation(0.f); desaturated->SetInput(wuc::CompositionEffectSourceParameter{ L"BlurredBackdrop" }); // 3. Apply afterglow tint onto desaturated base auto tintEffect{ winrt::make_self() }; tintEffect->SetInput(/* backdropNotTransparentPromised */); tintEffect->SetColor(wu::Color{ static_cast(static_cast(afterglowColor.A) * afterglowBalance), afterglowColor.R, afterglowColor.G, afterglowColor.B }); // 4. Blend blurred backdrop with afterglow and main color // (multiple CompositeStepEffect layers with PLUS and SOURCE_OVER modes) auto colorEffect{ winrt::make_self() }; colorEffect->SetColor(color); auto colorOpacity{ winrt::make_self() }; colorOpacity->SetOpacity(colorBalance); colorOpacity->SetInput(*colorEffect); // Final brush exposes "BlurredBackdrop" source parameter auto effectBrush{ compositor.CreateEffectFactory(*compositeEffect).CreateBrush() }; effectBrush.SetSourceParameter(L"BlurredBackdrop", blurredBackdropBrush); return effectBrush; // Expected: classic frosted glass with saturation, color tint, and optional reflection } ``` -------------------------------- ### Configuration Reload - MDWMBlurGlassExt::Refresh Source: https://context7.com/maplespe/dwmblurglass/llms.txt Reloads the configuration file (`data\config.ini`) and notifies rendering sub-systems to reconfigure. Calling `Refresh(false)` uses current in-memory settings without re-reading the file. ```APIDOC ## MDWMBlurGlassExt::Refresh ### Description Reloads `data\config.ini` into `g_configData` and notifies every rendering sub-system to reconfigure itself. Calling `Refresh(false)` propagates current in-memory settings without re-reading the file. ### Method Signature ```cpp void Refresh(bool reload = true) ``` ### Parameters - **reload** (bool) - Optional - If true, re-reads the configuration file; otherwise, uses current in-memory settings. ### Usage Example (Configuration Fields) ```cpp // Example: ConfigData fields relevant to effect selection ConfigData cfg; cfg.effectType = effectType::Acrylic; // Blur | Aero | Acrylic | Mica cfg.blurmethod = blurMethod::CustomBlur; // CustomBlur | AccentBlur | DWMAPIBlur cfg.blurAmount = 20.f; // Global blur sigma cfg.customBlurAmount = 30.f; // Per-backdrop blur sigma cfg.luminosityOpacity = 0.65f; // Mica / Acrylic luminosity layer opacity cfg.activeBlendColor = 0x64FFFFFF; // ARGB blend color for active windows cfg.inactiveBlendColor = 0x64FFFFFF; // ARGB blend color for inactive windows cfg.extendBorder = true; // Extend effect to window borders cfg.reflection = true; // Enable Aero glass reflection cfg.crossFade = true; // Animated crossfade on effect change cfg.crossfadeTime = 160; // Crossfade duration in milliseconds ConfigData::SaveToFile(L"data\config.ini", cfg); ``` ``` -------------------------------- ### Declare Multi-Routine Hook Dispatcher with MinHook Source: https://context7.com/maplespe/dwmblurglass/llms.txt Use MiniHookDispatcher to manage multiple detour routines for a single API hook. Routines can be configured to run before or after the original function. Enable/disable routines by index at runtime. ```cpp // Declaring a multi-routine hook dispatcher (from HookDef.h pattern): inline MiniHookDispatcher g_CTopLevelWindow_ValidateVisual_HookDispatcher = { "CTopLevelWindow::ValidateVisual", // Symbol resolved via MHostGetProcAddress std::array { // Runs BEFORE the original function detour_info(AccentBlur::CTopLevelWindow_ValidateVisual, call_type::before), detour_info(CustomButton::CTopLevelWindow_ValidateVisual, call_type::before), detour_info(CustomBackdrop::CTopLevelWindow_ValidateVisual, call_type::before), // Runs AFTER the original function detour_info(DwmAPIEffect::CTopLevelWindow_ValidateVisual, call_type::after), detour_info(Common::CTopLevelWindow_ValidateVisual, call_type::after) } }; // Enable / disable individual routines by index at runtime: g_CTopLevelWindow_ValidateVisual_HookDispatcher.enable_hook_routine<4, true>(); // → installs the MinHook API hook when the first routine is enabled g_CTopLevelWindow_ValidateVisual_HookDispatcher.enable_hook_routine<4, false>(); // → removes the API hook when the last routine is disabled ``` -------------------------------- ### Single-Function Hook with MinHook Source: https://context7.com/maplespe/dwmblurglass/llms.txt Use MinHook for single-function hooks. Attach to enable the hook and detach to disable it. Call the original function using the `call_org` method. ```cpp // A single-function hook (used for HrgnFromRects): MinHook g_funHrgnFromRects{ "HrgnFromRects", HrgnFromRects }; g_funHrgnFromRects.Attach(); // MH_EnableHook g_funHrgnFromRects.Detach(); // MH_DisableHook // Call through to original: auto ret = g_funHrgnFromRects.call_org(Src, a2, a3); ``` -------------------------------- ### Glass Reflection Visual Class Source: https://context7.com/maplespe/dwmblurglass/llms.txt Defines the CGlassReflectionVisual class responsible for managing a DirectComposition SpriteVisual for Aero-style glass reflections. It includes static methods to update the reflection surface, intensity, and parallax, and a method to validate the visual's properties each frame. ```cpp // Instantiated per CTopLevelWindow when reflection is enabled in config class CGlassReflectionVisual { public: // reflection texture loaded from data\reflection.png (custom user file) static void UpdateReflectionSurface(std::wstring_view reflectionPath) { // Loads image via WIC, creates a CompositionDrawingSurface, // and draws the bitmap into it using ID2D1DeviceContext // Surface is shared across all windows (static) } static void UpdateIntensity(float intensity) { s_intensity = intensity; // 0.0 = hidden, 1.0 = fully visible } static void UpdateParallaxIntensity(float intensity) { s_parallaxIntensity = intensity; // Default: 0.1 (10% parallax shift) } // Called each frame by CCompositedBackdropVisual::ValidateVisual() void ValidateVisual() { // Recalculates brush offset based on: // windowRect relative to monitor → parallax effect // IsZoomed(hwnd) → maximized windows use zero offset winrt::Windows::Foundation::Numerics::float2 offset{ -static_cast((windowRect.left - mi.rcMonitor.left) + (!IsZoomed(hwnd) ? m_offsetToWindow.x : 0)) * (1.f - m_parallaxIntensity), -static_cast((windowRect.top - mi.rcMonitor.top) + (!IsZoomed(hwnd) ? m_offsetToWindow.y : 0)) }; m_brush.Offset(offset); } }; ``` -------------------------------- ### IPC Window Class Names for Host-Extension Communication Source: https://context7.com/maplespe/dwmblurglass/llms.txt Defines the window class names used for hidden Windows messages between the host process and the injected DLL. The host sends `MHostNotifyType` commands, and the DLL replies with `MClientNotifyType` status messages. ```cpp // Defined window class names for message passing (Common.h): auto constexpr DWMBlurGlassNotifyClassName = L"MDWMBlurGlassExtNotify"; // DLL side auto constexpr DWMBlurGlassHostNotifyClassName = L"MDWMBlurGlassHostNotify"; // Host side enum class MHostNotifyType { Refresh, Shutdown, EnableTransparency }; enum class MClientNotifyType { Shutdown = 1, QueryTransparency }; ``` -------------------------------- ### AeroBackdrop::CreateBrush Source: https://context7.com/maplespe/dwmblurglass/llms.txt Recreates the Windows Vista/7 Aero Glass effect with saturation, afterglow tinting, color balance layers, and an optional Gaussian blur; active and inactive windows receive different balance ratios. ```APIDOC ## Aero Backdrop — `AeroBackdrop::CreateBrush` ### Description Recreates the Windows Vista/7 Aero Glass effect with saturation, afterglow tinting, color balance layers, and an optional Gaussian blur; active and inactive windows receive different balance ratios. ### Signature ```cpp wuc::CompositionBrush AeroBackdrop::CreateBrush( const wuc::Compositor& compositor, const wu::Color& color, // Main colorization color const wu::Color& afterglowColor, // Usually same as color float colorBalance, // Active: ~0.08, Inactive: ~0.032 float afterglowBalance, // ~0.43 float blurBalance, // Active: ~0.49, Inactive: ~0.80 float blurAmount) // Gaussian sigma ``` ### Parameters * **compositor** (`wuc::Compositor&`): The compositor instance. * **color** (`wu::Color`): The main colorization color. * **afterglowColor** (`wu::Color`): The color for the afterglow effect, usually the same as the main color. * **colorBalance** (`float`): Controls the balance of the main color. Typically around 0.08 for active windows and 0.032 for inactive windows. * **afterglowBalance** (`float`): Controls the intensity of the afterglow effect. Typically around 0.43. * **blurBalance** (`float`): Controls the balance of the blur effect. Typically around 0.49 for active windows and 0.80 for inactive windows. * **blurAmount** (`float`): The sigma value for the Gaussian blur, determining the blur intensity. If 0, no blur is applied. ### Returns * `wuc::CompositionBrush`: A brush object that applies the Aero Glass effect. ``` -------------------------------- ### BackdropFactory::GetOrCreateBackdropBrush Source: https://context7.com/maplespe/dwmblurglass/llms.txt Creates and retrieves a cached `CompositionBrush` for a given color and active state. It selects the appropriate material pipeline based on the global effect type configuration. ```APIDOC ## BackdropFactory::GetOrCreateBackdropBrush ### Description Central brush cache that creates and memoizes `CompositionBrush` instances for each (color, active/inactive) pair, selecting the appropriate material pipeline based on `g_configData.effectType`. ### Signature ```cpp wuc::CompositionBrush BackdropFactory::GetOrCreateBackdropBrush( const wuc::Compositor& compositor, DWORD color, // ABGR packed color (from ACCENT_POLICY or blend config) bool active, // true = window is active/focused DWM::ACCENT_POLICY* policy /*= nullptr*/) ``` ### Parameters * **compositor** (`const wuc::Compositor&`): The compositor instance to use for creating brushes. * **color** (`DWORD`): ABGR packed color value. * **active** (`bool`): Indicates if the window associated with the brush is active or focused. * **policy** (`DWM::ACCENT_POLICY*`, optional): Pointer to DWM accent policy, used for determining glass opacity and other properties. ### Returns `wuc::CompositionBrush`: A `CompositionBrush` instance, either retrieved from cache or newly created. ``` -------------------------------- ### Refresh System Accent Color Source: https://context7.com/maplespe/dwmblurglass/llms.txt Reads the current system colorization color and caches it. If `color` is 0, it triggers a DWM repaint before sampling. The color is converted from BGRA to RGBA format. ```cpp void RefreshAccentColor(COLORREF color) { static COLORREF lastColor = 0; if (color == 0) { // Trigger a full DWM repaint before sampling PostMessageW(FindWindowW(L"Dwm", nullptr), WM_THEMECHANGED, 0, 0); BOOL blend = TRUE; // Returns the colorization color in BGRA byte order DwmGetColorizationColor(&color, &blend); } // DwmGetColorizationColor returns bytes as B, G, R — swap to R, G, B BYTE blue = GetRValue(color); BYTE green = GetGValue(color); BYTE red = GetBValue(color); color = RGB(red, green, blue); if (lastColor != color && g_configData.useAccentColor) { g_accentColor = color; // Consumed by backdrop brush creation lastColor = color; } } ``` -------------------------------- ### Accent Color Sync - MDWMBlurGlassExt::RefreshAccentColor Source: https://context7.com/maplespe/dwmblurglass/llms.txt Reads the current system colorization color and caches it for backdrop brushes to use, ensuring automatic accent tinting. ```APIDOC ## MDWMBlurGlassExt::RefreshAccentColor ### Description Reads the current system colorization color via `DwmGetColorizationColor` and caches it in `g_accentColor` so backdrop brushes can incorporate the Windows accent tint automatically. ### Method Signature ```cpp void RefreshAccentColor(COLORREF color = 0) ``` ### Parameters - **color** (COLORREF) - Optional - If 0, the function retrieves the current system colorization color. Otherwise, it uses the provided color. ### Host Integration Example // The host registers for WM_DWMCOLORIZATIONCOLORCHANGED and calls: // MHostNotify(MHostNotifyType::Refresh); // which triggers Refresh() → RefreshAccentColor(0) inside dwm.exe ``` -------------------------------- ### Detour Routine Flow Control with MinHook Source: https://context7.com/maplespe/dwmblurglass/llms.txt Detour routines can signal special flow control to the MinHook dispatcher. Use `handling_type::return_now` to stop the chain and return immediately, or `handling_type::skip` to skip the original function but continue the chain. ```cpp // A detour routine can signal special flow: // handling_type::return_now → stop chain, skip original, return immediately // handling_type::skip → skip original but continue chain // (set via HookDispatcherImpl::modify_handle_type_for_temporary) ``` -------------------------------- ### Override Blur Kernel Size in DWM Source: https://context7.com/maplespe/dwmblurglass/llms.txt Hooks into DWM's blur effect rendering to replace the default kernel size with a user-defined value. This allows for fine-grained control over the blur applied to the title bar region. The `blurAmount` configuration key controls this, with values above 30 potentially impacting GPU performance. ```cpp // Hooks attached in BlurRadiusTweaker::Attach(): // "CD2DContext::FillEffect" → BlurRadiusTweaker::CD2DContext_FillEffect (before) // "CRenderingTechnique::ExecuteBlur" → CRenderingTechnique_ExecuteBlur (before) // "CCustomBlur::BuildEffect" → CCustomBlur_BuildEffect (before) // "CCustomBlur::DetermineOutputScale" → CCustomBlur_DetermineOutputScale (before) // Key interception: overrides the kernel size parameter in the blur effect graph DWORD64 WINAPI BlurRadiusTweaker::CCustomBlur_BuildEffect( DWM::CCustomBlur* This, ID2D1Image* backdropImage, const D2D_RECT_F* srcRect, const D2D_SIZE_F* kSize, // Original kernel size from DWM D2D1_GAUSSIANBLUR_OPTIMIZATION a5, const D2D_VECTOR_2F* a6, D2D_VECTOR_2F* a7) { // Replace kernel size with user-configured blur amount D2D_SIZE_F newKSize { g_configData.blurAmount, g_configData.blurAmount }; return g_funCCustomBlur_BuildEffect.call_org( This, backdropImage, srcRect, &newKSize, a5, a6, a7); } // Config key: blurAmount (float, default 20.0) // Effects: applies when blurMethod == CustomBlur (the default) // Increasing blurAmount beyond 30 may have a visible GPU cost ```