5.14 시작전
This commit is contained in:
@@ -274,6 +274,7 @@ internal static class CutFileAudit
|
||||
payload.CounterNumberKeys,
|
||||
Array.Empty<KarismaChartCellUpdate>(),
|
||||
Array.Empty<KarismaPositionUpdate>(),
|
||||
Array.Empty<KarismaCropKeyUpdate>(),
|
||||
payload.StyleColorUpdates,
|
||||
payload.VisibilityUpdates,
|
||||
CancellationToken.None)
|
||||
@@ -524,6 +525,10 @@ internal static class CutFileAudit
|
||||
string scenario,
|
||||
string frameLabel)
|
||||
{
|
||||
_ = ShowWindow(pgmWindow.Handle, ShowWindowRestore);
|
||||
_ = SetForegroundWindow(pgmWindow.Handle);
|
||||
Thread.Sleep(80);
|
||||
|
||||
var fileName = $"{result.Index:000}_{SanitizeFileName(result.FolderName)}_{SanitizeFileName(result.BaseName)}_{scenario.ToLowerInvariant()}_{frameLabel}.png";
|
||||
var outputPath = Path.Combine(options.CapturePath, fileName);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
|
||||
@@ -961,6 +966,12 @@ internal static class CutFileAudit
|
||||
{
|
||||
var normalizedBaseName = NormalizeVariantName(result.BaseName);
|
||||
var explicitBaseName = TryResolveExplicitRgbSpec(result.FolderName, normalizedBaseName);
|
||||
if (explicitBaseName is not null && string.IsNullOrWhiteSpace(explicitBaseName))
|
||||
{
|
||||
mappingKind = "explicit-none";
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(explicitBaseName) &&
|
||||
rgbCatalog.TryGetValue(BuildRgbCatalogKey(result.FolderName, explicitBaseName), out var explicitSpec))
|
||||
{
|
||||
@@ -1027,11 +1038,12 @@ internal static class CutFileAudit
|
||||
Add("Elect2026_Normal_민방", "모든후보_교육감", "모든후보_교육감");
|
||||
Add("Elect2026_Normal_민방", "사전_역대당선", "사전_역대당선자", "사전_역대당선자_기초단체장");
|
||||
Add("Elect2026_Normal_민방", "사전_역대당선_교육감", "사전_역대당선자_교육감");
|
||||
Add("Elect2026_Normal_민방", "이시각1위_광역단체장", "이시각1위_광역단체장");
|
||||
Add("Elect2026_Normal_민방", "이시각1위_광역단체장_5760", "이시각1위_광역단체장_5760");
|
||||
Add("Elect2026_Normal_민방", "이시각1위_기초단체장(5760동일)", "이시각1위_기초단체장");
|
||||
Add("Elect2026_Normal_민방", string.Empty, "사전_역대투표율");
|
||||
Add("Elect2026_Normal_민방", "이시각1위_광역단체장", "이시각1위_광역단체장", "이시각1위_광역단체장_HD");
|
||||
Add("Elect2026_Normal_민방", "이시각1위_광역단체장_5760", "이시각1위_광역단체장_5760", "이시각1위_광역단체장_L");
|
||||
Add("Elect2026_Normal_민방", "이시각1위_기초단체장(5760동일)", "이시각1위_기초단체장", "이시각1위_기초단체장_HD", "이시각1위_기초단체장_L");
|
||||
Add("Elect2026_Normal_민방", "접전,초접전", "접전_광역단체장", "접전_기초단체장", "초접전_광역단체장", "초접전_기초단체장");
|
||||
Add("Elect2026_Normal_민방", "판세_광역단체장", "판세_광역단체장", "판세_기초단체장");
|
||||
Add("Elect2026_Normal_민방", "판세_광역단체장", "판세_광역단체장", "판세_기초단체장", "역대시도판세_광역단체장", "역대시도판세_기초단체장");
|
||||
Add("Elect2026_Bottom_민방", "1-2위, 1-3위, 이시각1위", "1-2위_광역단체장", "1-2위_기초단체장", "1-3위_광역단체장", "1-3위_기초단체장", "1위_광역단체장", "1위_기초단체장");
|
||||
Add("Elect2026_Bottom_민방", "당선", "당선_광역단체장", "당선_광역의원", "당선_기초단체장", "당선_기초의원");
|
||||
Add("Elect2026_Bottom_민방", "모든후보", "전후보_광역단체장", "전후보_기초단체장");
|
||||
@@ -1296,29 +1308,62 @@ internal static class CutFileAudit
|
||||
|
||||
private static PgmWindow? TryFindPgmWindow()
|
||||
{
|
||||
var process = Process.GetProcessesByName("Tornado3")
|
||||
.FirstOrDefault(candidate => string.Equals(candidate.MainWindowTitle, "PGM", StringComparison.Ordinal));
|
||||
if (process is null || process.MainWindowHandle == IntPtr.Zero)
|
||||
var handle = IntPtr.Zero;
|
||||
var tornadoProcessIds = Process.GetProcessesByName("Tornado3")
|
||||
.Select(process => process.Id)
|
||||
.ToHashSet();
|
||||
|
||||
EnumWindows((candidateHandle, lParam) =>
|
||||
{
|
||||
if (handle != IntPtr.Zero)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_ = GetWindowThreadProcessId(candidateHandle, out var processId);
|
||||
if (!tornadoProcessIds.Contains((int)processId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var titleLength = GetWindowTextLength(candidateHandle);
|
||||
if (titleLength <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var title = new StringBuilder(titleLength + 1);
|
||||
_ = GetWindowText(candidateHandle, title, title.Capacity);
|
||||
if (string.Equals(title.ToString(), "PGM", StringComparison.Ordinal))
|
||||
{
|
||||
handle = candidateHandle;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}, IntPtr.Zero);
|
||||
|
||||
if (handle == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (TryGetDwmExtendedFrameBounds(process.MainWindowHandle, out var dwmBounds))
|
||||
if (TryGetDwmExtendedFrameBounds(handle, out var dwmBounds))
|
||||
{
|
||||
return new PgmWindow(process.MainWindowHandle, dwmBounds);
|
||||
return new PgmWindow(handle, dwmBounds);
|
||||
}
|
||||
|
||||
if (TryGetClientBounds(process.MainWindowHandle, out var clientBounds))
|
||||
if (TryGetClientBounds(handle, out var clientBounds))
|
||||
{
|
||||
return new PgmWindow(process.MainWindowHandle, clientBounds);
|
||||
return new PgmWindow(handle, clientBounds);
|
||||
}
|
||||
|
||||
if (!GetWindowRect(process.MainWindowHandle, out var rect))
|
||||
if (!GetWindowRect(handle, out var rect))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new PgmWindow(process.MainWindowHandle, new Rect(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top));
|
||||
return new PgmWindow(handle, new Rect(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top));
|
||||
}
|
||||
|
||||
private static bool TryGetDwmExtendedFrameBounds(IntPtr handle, out Rect bounds)
|
||||
@@ -1544,6 +1589,27 @@ internal static class CutFileAudit
|
||||
return value.Replace("|", "\\|", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetWindowTextLength(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GetWindowRect(IntPtr hWnd, out NativeRect lpRect);
|
||||
@@ -1560,6 +1626,8 @@ internal static class CutFileAudit
|
||||
private static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out NativeRect pvAttribute, int cbAttribute);
|
||||
|
||||
private const int DwmwaExtendedFrameBounds = 9;
|
||||
private const int ShowWindowRestore = 9;
|
||||
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
|
||||
|
||||
private readonly record struct AuditScene(string ScenePath, string RelativePath, string FolderName, string BaseName, BroadcastChannel Channel);
|
||||
private readonly record struct AuditChannelBinding(int OutputChannelIndex, int LayerNo);
|
||||
|
||||
Reference in New Issue
Block a user