Initial commit: ノーコード画像検査アプリ (MVP + 追加機能一式)

検査レシピ=処理/検査ステップの縦リスト(配線なし)。yfoxlib(yfoximg/yfoxbase)使用。

- ビジュアル・パイプライン(カード+適用後サムネイル+緑/赤 合否)
- テンプレート/対話式ウィザードでレシピ生成(CTaskDialog)
- パラメータのスライダー・ライブ調整
- レシピ保存/読込(*.itr) + 最近使ったファイル(MRU)
- 検査範囲(ROI)を複数マウス指定(ドラッグ追加/右クリック削除)
- カードのドラッグ並べ替え
- 判定結果画像の保存 + 検査ログCSV(項目拡張)
- 処理6種+検査3種(明るさ/白画素率/塊の数)
- /selftest(実行+レシピ往復+結果画像+複数ROI塊カウント検証)、/demo

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 09:26:10 +09:00
co-authored by Claude Opus 4.8
commit e4eca6b303
24 changed files with 3120 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
#pragma once
#include "stdafx.h"
#include "core/Recipe.h"
#include "core/InspectEngine.h"
// 親へ「カード選択が変わった」を通知(wParam = 選択index)。
#define WM_PV_SELCHANGED (WM_APP + 11)
// 親へ「カードを移動した」を通知(wParam = 元index, lParam = 挿入スロット 0..n)。
#define WM_PV_MOVESTEP (WM_APP + 12)
// ビジュアル・パイプライン表示: 各ステップをカード化し、適用後サムネイル + 合否を縦に並べる。
class CPipelineView : public CWnd
{
public:
CPipelineView();
BOOL Create(CWnd* parent, UINT id);
void SetData(core::Recipe* recipe, core::InspectEngine* engine);
void RefreshView(); // スクロール範囲再計算 + 再描画
void SetSel(int idx);
int GetSel() const { return m_sel; }
protected:
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnLButtonDown(UINT nFlags, CPoint pt);
afx_msg void OnMouseMove(UINT nFlags, CPoint pt);
afx_msg void OnLButtonUp(UINT nFlags, CPoint pt);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pBar);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP()
private:
int CardHeight() const { return 104; }
int ContentHeight() const;
CRect CardRect(int i) const; // クライアント座標(スクロール込み)
void UpdateScroll();
void DrawCard(CDC* dc, int i, const CRect& rc);
core::Recipe* m_recipe = nullptr;
core::InspectEngine* m_engine = nullptr;
int m_sel = -1;
int m_scrollY = 0;
// ドラッグ並べ替え
int m_dragFrom = -1; // 押下したカード(まだ移動と確定していない)
bool m_dragging = false; // しきい値を超えて移動中
CPoint m_dragStart;
int m_dragY = 0; // 現在のマウスY(挿入位置インジケータ用)
int InsertSlotAt(int y) const; // クライアントYから挿入スロット 0..n
CFont m_fTitle, m_fHint, m_fBadge, m_fNum;
};