You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

216 lines
8.3 KiB

using System.Reflection;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Housing;
using Housing.Login;
internal static class Program
{
private const int MainWidth = 1200;
private const int MainHeight = 800;
private const string ExampleBarcode = "A251001AM46110901T00001-01";
private const string ExampleIcSn = "025949A8492CFEAC";
[STAThread]
private static void Main()
{
var outputDirectory = Path.GetFullPath(
Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "manual-screens"));
Directory.CreateDirectory(outputDirectory);
var app = new App();
app.InitializeComponent();
CaptureLogin(Path.Combine(outputDirectory, "01-login.png"));
CaptureMainScreens(outputDirectory);
Console.WriteLine(outputDirectory);
}
private static void CaptureLogin(string path)
{
var window = new StartupLoginWindow
{
WindowState = WindowState.Normal,
Width = 760,
Height = 760
};
SelectFirst(window, "MakerComboBox");
SelectFirst(window, "ModelComboBox");
SelectFirst(window, "Variant1ComboBox");
SelectFirst(window, "Variant2ComboBox");
SelectFirst(window, "LineNoComboBox");
SelectFirst(window, "JigNoComboBox");
SetText(window, "OperatorTextBox", "OP1001");
SetPassword(window, "PasswordBox", "manual");
SetText(window, "LotNoTextBox", "LOT26001");
RenderWindowContent(window, path, 760, 760);
window.Close();
}
private static void CaptureMainScreens(string outputDirectory)
{
CaptureMain(Path.Combine(outputDirectory, "02-waiting-barcode.png"), window =>
{
PrepareMain(window);
SetText(window, "BarcodeTextBox", string.Empty);
SetText(window, "IcSnOutputTextBox", string.Empty);
Invoke(window, "SetProcessStatus", "WAITING BARCODE", "HmiAccentBrush");
Invoke(window, "ShowResultStatusMessage", "스캐너로 PCB_Barcode를 스캔해주세요.");
});
CaptureMain(Path.Combine(outputDirectory, "03-wait-start-signal.png"), window =>
{
PrepareMain(window);
SetText(window, "BarcodeTextBox", ExampleBarcode);
Invoke(window, "SetProcessStatus", "WAIT START SIGNAL", "HmiWarningBrush");
Invoke(
window,
"ShowResultStatusMessage",
"장비 시작 신호 대기\nNI-6501 Dev1/port0/line0\n시료를 넣고 Housing 장비 시작 버튼을 눌러주세요.");
});
CaptureMain(Path.Combine(outputDirectory, "04-board-test.png"), window =>
{
PrepareMain(window);
SetText(window, "BarcodeTextBox", ExampleBarcode);
SetText(window, "IcSnOutputTextBox", ExampleIcSn);
Invoke(window, "SetProcessStatus", "BOARD TEST", "HmiWarningBrush");
Invoke(
window,
"ShowResultStatusMessage",
"보드 테스트 시작\n1. 시료 연결 확인\n2. IC_SN 읽기\n3. CAL DEFAULT 조건 설정\n4. 시작 신호 기준 지연 후 계측 장비에서 V/A 읽기");
});
CaptureMain(Path.Combine(outputDirectory, "05-result-ok.png"), window =>
{
PrepareMain(window);
SetText(window, "BarcodeTextBox", ExampleBarcode);
SetText(window, "IcSnOutputTextBox", ExampleIcSn);
SetText(window, "VOutputTextBox", "5.02");
SetText(window, "AOutputTextBox", "118.40");
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "VOutputTextBox"), true);
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "AOutputTextBox"), true);
Invoke(window, "ShowInspectionResult", true);
Invoke(window, "SetProcessStatus", "COMPLETE OK", "HmiRunBrush");
});
CaptureMain(Path.Combine(outputDirectory, "06-result-ng.png"), window =>
{
PrepareMain(window);
SetText(window, "BarcodeTextBox", ExampleBarcode);
SetText(window, "IcSnOutputTextBox", ExampleIcSn);
SetText(window, "VOutputTextBox", "5.84");
SetText(window, "AOutputTextBox", "122.10");
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "VOutputTextBox"), false);
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "AOutputTextBox"), true);
Invoke(window, "ShowInspectionResult", false);
Invoke(window, "SetProcessStatus", "COMPLETE NG", "HmiDangerBrush");
});
CaptureMain(Path.Combine(outputDirectory, "07-db-save-error.png"), window =>
{
PrepareMain(window);
SetText(window, "BarcodeTextBox", ExampleBarcode);
SetText(window, "IcSnOutputTextBox", ExampleIcSn);
SetText(window, "VOutputTextBox", "5.01");
SetText(window, "AOutputTextBox", "117.80");
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "VOutputTextBox"), true);
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "AOutputTextBox"), true);
Invoke(window, "ShowInspectionResult", true);
Invoke(window, "SetProcessStatus", "DB SAVE ERROR", "HmiDangerBrush");
});
}
private static void CaptureMain(string path, Action<MainWindow> arrange)
{
var window = new MainWindow
{
WindowState = WindowState.Normal,
Width = MainWidth,
Height = MainHeight
};
arrange(window);
RenderWindowContent(window, path, MainWidth, MainHeight);
window.Close();
}
private static void PrepareMain(MainWindow window)
{
SetTextBlock(window, "OperatorTextBlock", "OP1001");
Find<Button>(window, "LogoutButton").Visibility = Visibility.Visible;
SetText(window, "VMinTextBox", "4.50");
SetText(window, "VMaxTextBox", "5.50");
SetText(window, "AMinTextBox", "80.00");
SetText(window, "AMaxTextBox", "150.00");
SetText(window, "VOutputTextBox", "0.00");
SetText(window, "AOutputTextBox", "0.00");
}
private static void RenderWindowContent(Window window, string path, int width, int height)
{
if (window.Content is not FrameworkElement content)
{
throw new InvalidOperationException("Window content was not a FrameworkElement.");
}
content.Width = width;
content.Height = height;
content.Measure(new Size(width, height));
content.Arrange(new Rect(0, 0, width, height));
content.UpdateLayout();
var bitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(content);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
using var stream = File.Create(path);
encoder.Save(stream);
}
private static T Find<T>(FrameworkElement owner, string name) where T : FrameworkElement
{
return owner.FindName(name) as T
?? throw new InvalidOperationException($"{name} was not found.");
}
private static void SetText(FrameworkElement owner, string name, string value)
{
Find<TextBox>(owner, name).Text = value;
}
private static void SetTextBlock(FrameworkElement owner, string name, string value)
{
Find<TextBlock>(owner, name).Text = value;
}
private static void SetPassword(FrameworkElement owner, string name, string value)
{
Find<PasswordBox>(owner, name).Password = value;
}
private static void SelectFirst(FrameworkElement owner, string name)
{
var comboBox = Find<ComboBox>(owner, name);
if (comboBox.Items.Count > 0)
{
comboBox.SelectedIndex = 0;
}
}
private static object? Invoke(object target, string methodName, params object?[] arguments)
{
var method = target.GetType().GetMethod(
methodName,
BindingFlags.Instance | BindingFlags.NonPublic)
?? throw new MissingMethodException(target.GetType().FullName, methodName);
return method.Invoke(target, arguments);
}
}