📄 mt.cpp
字号:
m_iCurrentPoint++;
m_iCurrentAction = ACTION_CHAOSAREA2;
m_tMouseNewStart = m_tMouseEnd;
}
}
else
{
m_pt[m_iCurrentPoint].x = point.x;
m_pt[m_iCurrentPoint].y = point.y;
m_iCurrentPoint++;
m_iCurrentAction = ACTION_CHAOSAREA2;
m_tMouseNewStart = m_tMouseEnd;
if (m_iCurrentPoint >= 3)
{
m_fArea += CalcArea(m_pt[m_iCurrentPoint - 1], m_pt[m_iCurrentPoint - 2], m_pt[m_iCurrentPoint - 3]);
}
}
}
else if (ACTION_CHAOSAREA == m_iCurrentAction)
{
m_pt[m_iCurrentPoint] = point;
m_iCurrentPoint++;
m_tMouseNewStart = point;
m_iCurrentAction = ACTION_CHAOSAREA2;
}
else if (ACTION_CHAOSANGLE2 == m_iCurrentAction)
{
m_pt[m_iCurrentPoint++] = point;
BeginRecord(TYPE_CHAOSANGLE);
m_tTempItem.type = TYPE_LINE;
m_tTempItem.x0 = m_pt[0].x;
m_tTempItem.y0 = m_pt[0].y;
m_tTempItem.x1 = m_pt[1].x;
m_tTempItem.y1 = m_pt[1].y;
AppendNode(&m_tTempItem);
m_tTempItem.x0 = m_pt[2].x;
m_tTempItem.y0 = m_pt[2].y;
m_tTempItem.x1 = m_pt[3].x;
m_tTempItem.y1 = m_pt[3].y;
AppendNode(&m_tTempItem);
FLOAT angle = GetAngle(m_pt[0], m_pt[1], m_pt[3]);
CHAR buf[100];
INT cx = 0;
INT cy = 0;
cx += (m_pt[0].x + m_pt[1].x + m_pt[2].x + m_pt[3].x);
cy += (m_pt[0].y + m_pt[1].y + m_pt[2].y + m_pt[3].y);
m_pt[3].x -= (m_pt[2].x - m_pt[1].x);
m_pt[3].y -= (m_pt[2].y - m_pt[1].y);
sprintf(buf, "%5.2f゜", angle);
cx /= m_iCurrentPoint;
cy /= m_iCurrentPoint;
m_tTempItem.type = TYPE_TEXT;
m_tTempItem.x0 = cx;
m_tTempItem.y0 = cy;
strcpy(m_tTempItem.word, buf);
DoRecord(m_hDC, &m_tTempItem, R2_COPYPEN);
AppendNode(&m_tTempItem);
EndRecord();
if (NULL != pInfoWnd)
{
pInfoWnd->SetWindowText("");
}
m_iCurrentAction = (nFlags & MK_SHIFT)?ACTION_CHAOSANGLE:ACTION_NOTHING;
}
else if (ACTION_CHAOSANGLE == m_iCurrentAction)
{
m_tMouseEnd = point;
m_pt[m_iCurrentPoint++] = m_tMouseEnd;
m_iCurrentAction = ACTION_CHAOSANGLE2;
}
else if (ACTION_ANGLE2 == m_iCurrentAction)
{
m_tMouseEnd = point;
m_pt[m_iCurrentPoint++] = m_tMouseEnd;
DoRecord(m_hDC, &m_tTempItem, R2_COPYPEN);
// -> Record
BeginRecord(TYPE_ANGLE);
m_tTempItem.type = TYPE_LINE;
m_tTempItem.x0 = m_pt[0].x;
m_tTempItem.y0 = m_pt[0].y;
m_tTempItem.x1 = m_pt[1].x;
m_tTempItem.y1 = m_pt[1].y;
AppendNode(&m_tTempItem);
m_tTempItem.x0 = m_pt[1].x;
m_tTempItem.y0 = m_pt[1].y;
m_tTempItem.x1 = m_pt[2].x;
m_tTempItem.y1 = m_pt[2].y;
AppendNode(&m_tTempItem);
FLOAT angle = GetAngle(m_pt[0], m_pt[1], m_pt[2]);
CHAR buf[100];
// SIZE size;
INT cx = 0;
INT cy = 0;
sprintf(buf, "%5.2f゜", angle);
// ::GetTextExtentPoint32(m_hDC, buf, strlen(buf), &size);
cx += (m_pt[0].x + m_pt[1].x + m_pt[1].x + m_pt[2].x);
cy += (m_pt[0].y + m_pt[1].y + m_pt[1].y + m_pt[2].y);
cx /= 4;
cy /= 4;
// cx -= size.cx / 2;
// cy -= size.cy / 2;
m_tTempItem.type = TYPE_TEXT;
m_tTempItem.x0 = cx;
m_tTempItem.y0 = cy;
strcpy(m_tTempItem.word, buf);
DoRecord(m_hDC, &m_tTempItem, R2_COPYPEN);
AppendNode(&m_tTempItem);
EndRecord();
// <- Record
if (NULL != pInfoWnd)
{
pInfoWnd->SetWindowText("");
}
m_iCurrentAction = (nFlags & MK_SHIFT)?ACTION_ANGLE:ACTION_NOTHING;
}
else if (ACTION_ANGLE == m_iCurrentAction)
{
DoRecord(m_hDC, &m_tTempItem, R2_COPYPEN);
m_tMouseEnd = point;
m_pt[m_iCurrentPoint++] = m_tMouseEnd;
m_tMouseNewStart = m_tMouseEnd;
m_iCurrentAction = ACTION_ANGLE2;
}
else if (ACTION_LINEDIST == m_iCurrentAction ||
ACTION_LINEDIST2 == m_iCurrentAction)
{
INT dx = m_tMouseEnd.x - m_tMouseStart.x;
INT dy = m_tMouseEnd.y - m_tMouseStart.y;
m_iLength += float(sqrt(dx * dx + dy * dy) * m_InfoHeader.fD2 / m_InfoHeader.fD1);
m_pt[m_iCurrentPoint++] = point;
m_tMouseNewStart = m_tMouseEnd;
if (ACTION_LINEDIST == m_iCurrentAction)
m_iCurrentAction = ACTION_LINEDIST2;
if (FALSE != (nFlags & MK_CONTROL))
{
INT i;
INT cx = 0;
INT cy = 0;
BeginRecord(TYPE_LINEDIST);
for (i = 0; i < m_iCurrentPoint - 1; i++)
{
m_tTempItem.type = TYPE_LINE;
m_tTempItem.x0 = m_pt[i].x;
m_tTempItem.y0 = m_pt[i].y;
m_tTempItem.x1 = m_pt[i + 1].x;
m_tTempItem.y1 = m_pt[i + 1].y;
AppendNode(&m_tTempItem);
cx += m_pt[i].x;
cy += m_pt[i].y;
}
cx += m_pt[i].x;
cy += m_pt[i].y;
CHAR buf[200];
sprintf(buf, "%5.2f %s", m_iLength, m_InfoHeader.sUnit);
cx /= m_iCurrentPoint;
cy /= m_iCurrentPoint;
m_tTempItem.type = TYPE_TEXT;
m_tTempItem.x0 = cx;
m_tTempItem.y0 = cy;
strcpy(m_tTempItem.word, buf);
DoRecord(m_hDC, &m_tTempItem, R2_COPYPEN);
AppendNode(&m_tTempItem);
EndRecord();
if (NULL != pInfoWnd)
{
pInfoWnd->SetWindowText("");
}
m_iCurrentAction = (nFlags & MK_SHIFT)?ACTION_LINEDIST:ACTION_NOTHING;
}
}
else if (ACTION_RECTAREA == m_iCurrentAction)
{
CHAR sText[100];
FLOAT w1, h1, w2, h2, area;
INT x0, x1, y0, y1;
x0 = m_tMouseStart.x;
y0 = m_tMouseStart.y;
x1 = m_tMouseEnd.x;
y1 = m_tMouseEnd.y;
w1 = FLOAT(m_tMouseEnd.x - m_tMouseStart.x);
h1 = FLOAT(m_tMouseEnd.y - m_tMouseStart.y);
w2 = w1 * m_InfoHeader.fD2 / m_InfoHeader.fD1;
h2 = h1 * m_InfoHeader.fD2 / m_InfoHeader.fD1;
area = FLOAT(fabs(w2 * h2));
sprintf(sText, "%5.2f平方%s", area, m_InfoHeader.sUnit);
strcpy(m_tTempItem.word, sText);
DoRecord(m_hDC, &m_tTempItem, R2_COPYPEN);
BeginRecord(TYPE_RECTAREA);
AppendNode(&m_tTempItem);
EndRecord();
if (NULL != pInfoWnd)
{
pInfoWnd->SetWindowText("");
}
if (!(nFlags & MK_SHIFT)) m_iCurrentAction = ACTION_NOTHING;
}
else if (ACTION_SETSTANDARDLENGTH == m_iCurrentAction)
{
CStandardLength dlg;
DoRecord(m_hDC, &m_tTempItem, R2_COPYPEN);
if (IDOK == dlg.DoModal())
{
SetStandLength(m_tMouseStart, m_tMouseEnd, dlg.m_fLength, dlg.m_sUnit);
if (NULL != pInfoWnd)
{
pInfoWnd->SetWindowText("");
}
if (TRUE != (nFlags & MK_SHIFT)) m_iCurrentAction = ACTION_NOTHING;
}
else
{
m_iCurrentAction = ACTION_NOTHING;
}
CWnd *pWnd = CWnd::FromHandle(m_hContainWnd);
pWnd->RedrawWindow();
}
else if (ACTION_ARROW == m_iCurrentAction)
{
DoRecord(m_hDC, &m_tTempItem, R2_COPYPEN);
BeginRecord(TYPE_ARROW);
AppendNode(&m_tTempItem);
EndRecord();
if (FALSE == (nFlags & MK_SHIFT)) m_iCurrentAction = ACTION_NOTHING;
}
else if (m_iCurrentAction == ACTION_CROSS)
{
DoRecord(m_hDC, &m_tTempItem, R2_COPYPEN);
BeginRecord(TYPE_CROSS);
AppendNode(&m_tTempItem);
EndRecord();
if (FALSE == (nFlags & MK_SHIFT)) m_iCurrentAction = ACTION_NOTHING;
}
else if (ACTION_TEXT == m_iCurrentAction)
{
DoRecord(m_hDC, &m_tTempItem, R2_XORPEN);
strcpy(m_tTempItem.word, m_sText);
DoRecord(m_hDC, &m_tTempItem, R2_COPYPEN);
BeginRecord(TYPE_TEXT);
AppendNode(&m_tTempItem);
EndRecord();
if (FALSE == (nFlags & MK_SHIFT)) m_iCurrentAction = ACTION_NOTHING;
}
::SelectObject(m_hDC, m_hOldPen);
::DeleteObject(m_hCurrentPen);
::ReleaseDC(m_hWnd, m_hDC);
return TRUE;
}
BOOL
CMeta::SetAction(INT action, LPARAM lParam, HWND hInfoWnd)
{
#ifdef _DEBUG
// 获取当前节点信息
if (ACTION_GETINFO == action)
{
GetInfo();
return TRUE;
}
#endif
// 如果当前是不可改变的状态,则返回失败信息
if (ACTION_CHANGABLE < m_iCurrentAction) return (FALSE);
if (ACTION_NOTHING == action)
SelectNone();
else if (ACTION_DELETE == action)
{
// 如果需要设置的是删除状态,并且当前存在选择节点,则删除记录
if (ACTION_DELETE == m_iCurrentAction)
{
if (FALSE == HasSelected()) return (FALSE);
if (FALSE == EraseSel()) return (FALSE);
HWND hWnd = (HWND)(lParam);
::RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
return TRUE;
}
}
else
{
// 如果需要设置的不是删除状态,并且当前存在选择节点,则放弃选择
if (FALSE != HasSelected()) SelectNone();
// 文字状态获得文字信息
if (ACTION_TEXT == action)
{
CString sText;
HWND hTextWnd = (HWND)(lParam);
::GetWindowText(hTextWnd, m_sText, MAX_TEXT_LENGTH);
}
}
// 设置当前状态
m_iCurrentAction = action;
if (NULL != hInfoWnd)
{
CString sInfoText;
switch (m_iCurrentAction)
{
case ACTION_DELETE:
sInfoText = "删除标记...";
break;
case ACTION_ARROW:
sInfoText = "绘制箭头标记...";
break;
case ACTION_CROSS:
sInfoText = "绘制十字标记...";
break;
case ACTION_TEXT:
sInfoText = "绘制文字标记...";
break;
default:
sInfoText = "UNKNOW ACTION";
break;
}
::SetWindowText(hInfoWnd, sInfoText);
}
return TRUE;
}
/*
计算三角形面积(像素面积)
三点坐标由参数给出
返回三角形面积
*/
FLOAT
CMeta::CalcArea(POINT &pa, POINT &pb, POINT &pc)
{
DOUBLE d1_2, d2_2, d3_2, d1, d2, d3, sl, area;
// 计算三边长度的平方
d1_2 = (pa.x - pb.x) * (pa.x - pb.x) + (pa.y - pb.y) * (pa.y - pb.y);
d2_2 = (pb.x - pc.x) * (pb.x - pc.x) + (pb.y - pc.y) * (pb.y - pc.y);
d3_2 = (pc.x - pa.x) * (pc.x - pa.x) + (pc.y - pa.y) * (pc.y - pa.y);
// 计算三边长度
d1 = sqrt(d1_2);
d2 = sqrt(d2_2);
d3 = sqrt(d3_2);
// 三边长度之和的一半
sl = (d1 + d2 + d3) / 2;
// 海伦三角形面积公式
area = sqrt(sl * (sl - d1) * (sl - d2) * (sl - d3));
return FLOAT(area);
}
/*
计算直线夹角
参数:
pa -> pb: 第一边
pb -> pc: 第二边
pb: 顶点
返回值:
夹角角度值(单位为度)
*/
FLOAT
CMeta::GetAngle(POINT &pa, POINT &pb, POINT &pc)
{
DOUBLE dx, dy;
DOUBLE d1_2, d2_2, d3_2;
DOUBLE cosalpha;
DOUBLE alpha;
dx = pb.x - pa.x;
dy = pb.y - pa.y;
d1_2 = dx * dx + dy * dy;
dx = pc.x - pb.x;
dy = pc.y - pb.y;
d2_2 = dx * dx + dy * dy;
dx = pa.x - pc.x;
dy = pa.y - pc.y;
d3_2 = dx * dx + dy * dy;
cosalpha = 0.5 * (d1_2 + d2_2 - d3_2) / sqrt(d1_2 * d2_2);
alpha = acos(cosalpha);
return FLOAT(180 * alpha / PI);
}
/*
设置输出窗口
hContainWnd - 包容窗体句柄
hWnd - 显示窗体句柄
*/
BOOL
CMeta::SetOutputWindow(HWND hContainWnd, HWND hWnd)
{
m_hContainWnd = hContainWnd;
m_hWnd = hWnd;
return TRUE;
}
/*
删除一个节点
内部调用,不做合法性判定
*/
BOOL
CMeta::EraseNode(CMeta::ITEM *node)
{
node->prior->next = node->next;
if (NULL == node->next)
m_tItemHeader.prior = node->prior;
else
node->next->prior = node->prior;
delete node;
return TRUE;
}
/*
把选择的节点移到最后
*/
BOOL
CMeta::MoveSelToLast()
{
if (NULL == m_pSelItem || TYPE_START != m_pSelItem->type) return FALSE;
ITEM *pSelBegin = m_pSelItem;
ITEM *pPriorNode = m_pSelItem->prior;
ITEM *pSelEnd = NULL;
ITEM *pNextNode = NULL;
ITEM *p = NULL;
for (p = pSelBegin; NULL != p && TYPE_END != p->type; p = p->next);
if (NULL == p) return FALSE;
pSelEnd = p;
pNextNode = pSelEnd->next;
if (NULL != pNextNode)
{
pPriorNode->next = pNextNode;
pNextNode->prior = pPriorNode;
pSelBegin->prior = m_tItemHeader.prior;
m_tItemHeader.prior->next = pSelBegin;
pSelEnd->next = NULL;
m_tItemHeader.prior = pSelEnd;
}
return TRUE;
}
VOID
CMeta::GetInfo()
{
ITEM *p = NULL;
CString info = _T("");
CHAR buf[200];
for (p = &m_tItemHeader; NULL != p; p = p->next)
{
switch (p->type)
{
case TYPE_LINKHEADER:
sprintf(buf, "TYPE_LINKHEADER\r\n");
info += buf;
break;
case TYPE_NOTHING:
info += "TYPE_NOTHING\r\n";
break;
case TYPE_LINE:
sprintf(buf, "TYPE_LINE\t(%d,%d)-(%d,%d)\r\n", p->x0, p->y0, p->x1, p->y1);
info += buf;
break;
case TYPE_START:
switch (p->dwRecordType)
{
case TYPE_STANDARDLENGTH:
sprintf(buf, "TYPE_START\t- %s\r\n", "STANDARDLENGTH");
break;
case TYPE_ARROW:
sprintf(buf, "TYPE_START\t- %s\r\n", "ARROW");
break;
case TYPE_CROSS:
sprintf(buf, "TYPE_START\t- %s\r\n", "CROSS");
break;
case TYPE_CHAOSANGLE:
sprintf(buf, "TYPE_START\t- %s\r\n", "CHAOSANGLE");
break;
case TYPE_TEXT:
sprintf(buf, "TYPE_START\t- %s\r\n", "TEXT");
break;
case TYPE_CHAOSAREA:
sprintf(buf, "TYPE_START\t- %s\r\n", "CHAOSAREA");
break;
case TYPE_ANGLE:
sprintf(buf, "TYPE_START\t- %s\r\n", "ANGLE");
break;
case TYPE_LINEDIST:
sprintf(buf, "TYPE_START\t- %s\r\n", "LINEDIST");
break;
case TYPE_RECTAREA:
sprintf(buf, "TYPE_START\t- %s\r\n", "RECTAREA");
break;
default:
sprintf(buf, "TYPE_START\t- ??? [%i]\r\n", (INT)p->dwRecordType);
break;
}
info += buf;
break;
case TYPE_END:
sprintf(buf, "TYPE_END\r\n");
info += buf;
break;
case TYPE_ARC:
info += "TYPE_ARC\r\n";
break;
case TYPE_ARROW:
sprintf(buf, "TYPE_ARROW\t(%d,%d)-(%d,%d)\r\n", p->x0, p->y0, p->x1, p->y1);
info += buf;
break;
case TYPE_CROSS:
sprintf(buf, "TYPE_CROSS\t(%d,%d)\r\n", p->x0, p->y0);
info += buf;
break;
case TYPE_RECT:
sprintf(buf, "TYPE_RECT\t(%d,%d)-(%d,%d)\r\n", p->x0, p->y0, p->x1, p->y1);
info += buf;
break;
case TYPE_TEXT:
sprintf(buf, "TYPE_TEXT\t(%d,%d), [%s]\r\n", p->x0, p->y0, ('\0' != p->word[0]) ? (p->word) : ("NULL"));
info += buf;
break;
default:
sprintf(buf, "??? - (%d)\r\n", p->type);
info += buf;
break;
}
}
CShowInfo dlg(info);
dlg.DoModal();
return;
}
VOID
CMeta::ConvertRect(RECT &rect)
{
INT iSwap;
if (rect.left > rect.right)
{
iSwap = rect.left;
rect.left = rect.right;
rect.right = iSwap;
}
if (rect.top > rect.bottom)
{
iSwap = rect.top;
rect.top = rect.bottom;
rect.bottom = iSwap;
}
}
/*
设置标准长度
pa -> pb - 屏幕长度线段
fLen - 代表的真实长度
sUnit - 长度单位
Return Value - Always True
*/
BOOL
CMeta::SetStandLength(POINT &pa, POINT &pb, FLOAT fLen, CHAR *sUnit)
{
ITEM TextItem; // 文字
ITEM CrossItemA; // A 点交叉标记
ITEM CrossItemB; // B 点交叉标记
ITEM *p = NULL;
INT dx = pb.x - pa.x; // 屏幕横向距离
INT dy = pb.y - pa.y; // 屏幕纵向距离
INT cx = (pa.x + pb.x) / 2; // 中心点横坐标
INT cy = (pa.y + pb.y) / 2; // 中心点纵坐标
CHAR sText[100];
m_InfoHeader.fD1 = FLOAT(sqrt(dx * dx + dy * dy)); // 屏幕线段长度
m_InfoHeader.fD2 = fLen; // 对应真实长度
strcpy(m_InfoHeader.sUnit, sUnit); // 保存长度单位
// 删除以前的标准长度记录信息
while (NULL != (p = (ITEM *)FindRecord(TYPE_STANDARDLENGTH)))
{
EraseRecord(p);
}
// 线段节点
m_tTempItem.type = TYPE_LINE;
m_tTempItem.x0 = pa.x;
m_tTempItem.y0 = pa.y;
m_tTempItem.x1 = pb.x;
m_tTempItem.y1 = pb.y;
// A 点交叉节点
CrossItemA.type = TYPE_BIGPOINT;
CrossItemA.x0 = pa.x;
CrossItemA.y0 = pa.y;
// B 点交叉节点
CrossItemB.type = TYPE_BIGPOINT;
CrossItemB.x0 = pb.x;
CrossItemB.y0 = pb.y;
// 生成描述文字
sprintf(sText, "%5.2f %s", m_InfoHeader.fD2, m_InfoHeader.sUnit);
TextItem.type = TYPE_TEXT;
TextItem.x0 = cx;
TextItem.y0 = cy;
strcpy(TextItem.word, sText);
BeginRecord(TYPE_STANDARDLENGTH);
AppendNode(&m_tTempItem);
AppendNode(&CrossItemA);
AppendNode(&CrossItemB);
AppendNode(&TextItem);
EndRecord();
return TRUE;
}
BOOL
CMeta::InitMeta()
{
pFA = NULL;
::AfxBeginThread(MetaThread, NULL);
return (TRUE);
}
INT
CMeta::GetCurrentAction()
{
return (m_iCurrentAction);
}
/*
显示/隐藏标记
*/
BOOL
CMeta::ShowMark(BOOL bShow)
{
CWnd *pWnd = CWnd::FromHandle(m_hWnd);
m_bHideMark = !bShow;
pWnd->RedrawWindow();
return (TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -