diff --git a/src/SheetMe.Designer/App.xaml.cs b/src/SheetMe.Designer/App.xaml.cs
index f0f8c44..b46d635 100644
--- a/src/SheetMe.Designer/App.xaml.cs
+++ b/src/SheetMe.Designer/App.xaml.cs
@@ -171,6 +171,11 @@ public partial class App : Application
return Diagnostics.DbSmoke.RunTableSearch(args[1], args[2]);
}
+ if (args.Length >= 2 && args[0] == "--dialog-shots")
+ {
+ return Diagnostics.DialogShots.Run(args[1]);
+ }
+
MessageBox.Show($"알 수 없는 진단 옵션입니다: {args[0]}", "서식생성기",
MessageBoxButton.OK, MessageBoxImage.Warning);
return 2;
diff --git a/src/SheetMe.Designer/Diagnostics/DialogShots.cs b/src/SheetMe.Designer/Diagnostics/DialogShots.cs
new file mode 100644
index 0000000..6e9d3d0
--- /dev/null
+++ b/src/SheetMe.Designer/Diagnostics/DialogShots.cs
@@ -0,0 +1,189 @@
+using System.IO;
+using System.Windows;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using SheetMe.Core.Models;
+using SheetMe.Data.Stores;
+using SheetMe.Designer.Services;
+using SheetMe.Designer.ViewModels;
+
+namespace SheetMe.Designer.Diagnostics;
+
+///
+/// 별도 창(대화상자) 오프스크린 스냅샷 — --dialog-shots <출력폴더>.
+///
+/// 창 10종을 다크·라이트 양 테마로 열어 PNG 로 남긴다. 목적은 하나다:
+/// 테마 대비 결함을 사람 손 없이 재현 가능하게 확인한다.
+/// 실입력(마우스·키보드) 주입은 화면 잠금·세션 격리 상태에서 OS 가 거부하지만
+/// 이 경로는 창을 화면 밖에 띄워 RenderTargetBitmap 으로 찍으므로 그 제약을 받지 않는다.
+///
+/// 창은 화면 밖(-10000)에 Show() 로 띄운다 — 레이아웃이 실제로 돌아야 템플릿·트리거가
+/// 적용된 상태로 찍힌다(Measure/Arrange 만으로는 Window 크롬이 구성되지 않는다).
+/// 모든 창은 찍은 뒤 즉시 닫는다.
+///
+public static class DialogShots
+{
+ #region Methods
+ public static int Run(string outputDirectory)
+ {
+ try
+ {
+ Directory.CreateDirectory(outputDirectory);
+ // 기본 ShutdownMode 는 OnLastWindowClose 라, 찍고 닫는 순간 마지막 창이 사라져 앱이 종료된다
+ // (그 뒤 Application.Current 가 null 이 되어 테마 교체에서 NRE). 명시 종료로 바꾼다.
+ Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
+ var lines = new List();
+
+ foreach (var light in new[] { false, true })
+ {
+ ThemeManager.Apply(light);
+ var suffix = light ? "light" : "dark";
+ foreach (var (name, factory) in Factories())
+ {
+ try
+ {
+ var window = factory();
+ Capture(window, Path.Combine(outputDirectory, $"{name}-{suffix}.png"));
+ // 창 배경이 실제로 무엇으로 해석됐는지 함께 남긴다 — 픽셀만 보면 원인을 못 가린다.
+ // WPF 는 암시 스타일을 요소의 '정확한 타입'으로만 찾으므로, Window 를 상속한
+ // 대화상자에는
+
+
+
diff --git a/src/SheetMe.Designer/Views/ColorPickerWindow.cs b/src/SheetMe.Designer/Views/ColorPickerWindow.cs
index 1b92bbc..d6354e7 100644
--- a/src/SheetMe.Designer/Views/ColorPickerWindow.cs
+++ b/src/SheetMe.Designer/Views/ColorPickerWindow.cs
@@ -54,6 +54,11 @@ public sealed class ColorPickerWindow : Window
private ColorPickerWindow(string? initialHex)
{
Title = "색상 선택";
+ // 암시 Window 스타일은 파생 클래스에 적용되지 않는다 — 직접 걸지 않으면 다크에서 흰 창이 된다
+ if (Application.Current?.TryFindResource("ThemedWindow") is Style themed)
+ {
+ Style = themed;
+ }
Width = 300;
SizeToContent = SizeToContent.Height;
WindowStartupLocation = WindowStartupLocation.CenterOwner;
diff --git a/src/SheetMe.Designer/Views/FontManagerDialogView.xaml b/src/SheetMe.Designer/Views/FontManagerDialogView.xaml
index 5bda3bc..ef22180 100644
--- a/src/SheetMe.Designer/Views/FontManagerDialogView.xaml
+++ b/src/SheetMe.Designer/Views/FontManagerDialogView.xaml
@@ -2,7 +2,8 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="폰트 일괄 변경" Width="620" Height="560" MinWidth="520" MinHeight="420"
- WindowStartupLocation="CenterOwner" ShowInTaskbar="False">
+ WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
+ Style="{StaticResource ThemedWindow}">
diff --git a/src/SheetMe.Designer/Views/MainView.xaml b/src/SheetMe.Designer/Views/MainView.xaml
index 20b1c8d..f3af249 100644
--- a/src/SheetMe.Designer/Views/MainView.xaml
+++ b/src/SheetMe.Designer/Views/MainView.xaml
@@ -16,7 +16,8 @@
Width="1440" Height="920" MinWidth="940" MinHeight="640"
WindowStyle="None" WindowStartupLocation="CenterScreen"
Background="{DynamicResource B.AppBg}" FontFamily="Malgun Gothic" FontSize="13"
- Loaded="OnWindowLoaded" StateChanged="OnWindowStateChanged" Closing="OnWindowClosing">
+ Loaded="OnWindowLoaded" StateChanged="OnWindowStateChanged" Closing="OnWindowClosing"
+ Style="{StaticResource ThemedWindow}">