Initial commit: OtozaiPrinter (AveryDennisonUtil) ラベル/レシート レイアウト設計・印刷 MFC アプリ
- 用紙設計キャンバス(1/100mm 基準)・テキスト/画像/矩形/直線アイテム - コピー/複製/Zオーダー/整列/グリッドスナップ、原紙(下絵)読込と印刷可否 - GDI 直接印刷、.otz 保存/再読込(版数つき) - MFC/CRT 静的リンクで VS2022 IDE から F5 デバッグ可
This commit is contained in:
+109
@@ -0,0 +1,109 @@
|
||||
// PrintItem.cpp
|
||||
#include "pch.h"
|
||||
#include "PrintItem.h"
|
||||
|
||||
IMPLEMENT_DYNAMIC(CPrintItem, CObject)
|
||||
|
||||
// 選択ハンドルの一辺(デバイスピクセル)
|
||||
static const int kHandleSize = 7;
|
||||
|
||||
// コンストラクタ。矩形を空(0,0,0,0)で初期化。
|
||||
CPrintItem::CPrintItem()
|
||||
: m_rect(0, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
CPrintItem::~CPrintItem()
|
||||
{
|
||||
}
|
||||
|
||||
// 当たり判定。指定座標(1/100mm)がこのアイテムの矩形内なら TRUE。
|
||||
// 既定は矩形の内側判定。直線など特殊な形状は派生側で上書きできる。
|
||||
BOOL CPrintItem::HitTest(const CPoint& huPt) const
|
||||
{
|
||||
return m_rect.PtInRect(huPt);
|
||||
}
|
||||
|
||||
// 共通の永続化処理。矩形(left/top/right/bottom)だけを保存/復元する。
|
||||
// 派生クラスは自分の Serialize で本関数を呼んでから固有データを読み書きする。
|
||||
void CPrintItem::Serialize(CArchive& ar)
|
||||
{
|
||||
CObject::Serialize(ar);
|
||||
if (ar.IsStoring())
|
||||
{
|
||||
ar << (int)m_rect.left << (int)m_rect.top
|
||||
<< (int)m_rect.right << (int)m_rect.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
int l, t, r, b;
|
||||
ar >> l >> t >> r >> b;
|
||||
m_rect.SetRect(l, t, r, b);
|
||||
}
|
||||
}
|
||||
|
||||
// 8 個のハンドル(四隅 + 各辺中央)の中心座標
|
||||
static CPoint HandleCenter(const CRect& dr, int i)
|
||||
{
|
||||
int mx = (dr.left + dr.right) / 2;
|
||||
int my = (dr.top + dr.bottom) / 2;
|
||||
switch (i)
|
||||
{
|
||||
case 0: return CPoint(dr.left, dr.top); // 左上
|
||||
case 1: return CPoint(mx, dr.top); // 上中央
|
||||
case 2: return CPoint(dr.right, dr.top); // 右上
|
||||
case 3: return CPoint(dr.right, my); // 右中央
|
||||
case 4: return CPoint(dr.right, dr.bottom); // 右下
|
||||
case 5: return CPoint(mx, dr.bottom); // 下中央
|
||||
case 6: return CPoint(dr.left, dr.bottom); // 左下
|
||||
case 7: return CPoint(dr.left, my); // 左中央
|
||||
}
|
||||
return CPoint(0, 0);
|
||||
}
|
||||
|
||||
// index 番目(0..7)のハンドルが占める小矩形(デバイス座標)を返す。
|
||||
CRect CPrintItem::HandleRectAt(const CRect& devRect, int index)
|
||||
{
|
||||
CPoint c = HandleCenter(devRect, index);
|
||||
int h = kHandleSize / 2;
|
||||
return CRect(c.x - h, c.y - h, c.x + h + 1, c.y + h + 1);
|
||||
}
|
||||
|
||||
// 選択中アイテムの装飾(破線枠 + 8個のサイズ変更ハンドル)を描画する。
|
||||
// devRect はアイテム矩形をデバイス座標へ変換したもの。
|
||||
void CPrintItem::DrawSelection(CDC& dc, const CRect& devRect)
|
||||
{
|
||||
// 破線の選択枠
|
||||
CPen pen(PS_DOT, 1, RGB(0, 0, 255));
|
||||
CPen* pOld = dc.SelectObject(&pen);
|
||||
int oldBk = dc.SetBkMode(TRANSPARENT);
|
||||
CBrush* pOldBrush = (CBrush*)dc.SelectStockObject(NULL_BRUSH);
|
||||
dc.Rectangle(devRect);
|
||||
dc.SelectObject(pOldBrush);
|
||||
dc.SetBkMode(oldBk);
|
||||
dc.SelectObject(pOld);
|
||||
|
||||
// ハンドル(白塗り+黒枠)
|
||||
CBrush white(RGB(255, 255, 255));
|
||||
CPen black(PS_SOLID, 1, RGB(0, 0, 0));
|
||||
CPen* pOld2 = dc.SelectObject(&black);
|
||||
CBrush* pOld3 = dc.SelectObject(&white);
|
||||
for (int i = 0; i < 8; ++i)
|
||||
dc.Rectangle(HandleRectAt(devRect, i));
|
||||
dc.SelectObject(pOld3);
|
||||
dc.SelectObject(pOld2);
|
||||
}
|
||||
|
||||
// devPt(デバイス座標)がどのハンドル上にあるかを返す。0..7、無ければ -1。
|
||||
// 判定矩形を少し広げて掴みやすくしている。
|
||||
int CPrintItem::HitHandle(const CRect& devRect, const CPoint& devPt)
|
||||
{
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
CRect hr = HandleRectAt(devRect, i);
|
||||
hr.InflateRect(2, 2); // 掴みやすく
|
||||
if (hr.PtInRect(devPt))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
Reference in New Issue
Block a user