add: cursor, range select, log axis, curve smooth;

This commit is contained in:
liuyihui 2022-06-02 10:08:38 +08:00
parent fd8d749eb9
commit 06b5c82686
12 changed files with 453 additions and 119 deletions

View File

@ -1,13 +1,15 @@
## Change Log ## Change Log
### 3.21-3.27 ### 3.21-3.27
* `Visio`的`UML`类图初步制作 * `Visio`的`UML`类图初步制作
* 随机信号的生成[^1]
### 5.24 ### 5.28
* 随机信号的完善 * 模拟信号的生成
### 5.29
* 模拟信号的完善
### 5.30 ### 5.30
* control view * 侧边信息栏
### 5.31 ### 5.31
* 全谱区 * 全谱区
@ -16,4 +18,14 @@
* 模拟信号 * 模拟信号
* 开始、结束、暂停 * 开始、结束、暂停
[^1]: Xiao M, Hu R, Ge L Q, et al. Study of a full-digital multi-waveform nuclear pulse signal generator[J]. Applied Radiation and Isotopes, 2022, 179: 110028. ### 6.1
* 光标显示
* 量程
* 对数量程
### 6.2
* 曲线平滑
## Bugs
1. 点击其他视图时工具栏ToolBar和菜单栏Menu无法使用失去焦点
2. 最开始无法通过方向键左右移动或调整量程

View File

@ -1,10 +1,10 @@
// ControlView.cpp: 实现文件 // ControlView.cpp: 实现文件
// //
#include <math.h>
#include <chrono> #include <chrono>
#include "pch.h" #include "pch.h"
#include "math.h"
#include "MCA.h" #include "MCA.h"
#include "MCADoc.h" #include "MCADoc.h"
@ -24,7 +24,7 @@ CControlView::CControlView()
, m_nTotalCount(0) , m_nTotalCount(0)
, m_nPartCount(0) , m_nPartCount(0)
, m_nMaxCount(0) , m_nMaxCount(0)
, m_nRange(4) , m_nLC(4)
, m_nCursor1(0) , m_nCursor1(0)
, m_nCursor2(1023) , m_nCursor2(1023)
, m_nCursorROI(0) , m_nCursorROI(0)
@ -46,7 +46,7 @@ void CControlView::DoDataExchange(CDataExchange* pDX)
DDX_Text(pDX, IDC_MCOUNT, m_nMaxCount); DDX_Text(pDX, IDC_MCOUNT, m_nMaxCount);
DDX_Control(pDX, IDC_MODE, m_ComboMode); DDX_Control(pDX, IDC_MODE, m_ComboMode);
DDX_Control(pDX, IDC_AXIS, m_ComboAxis); DDX_Control(pDX, IDC_AXIS, m_ComboAxis);
DDX_Text(pDX, IDC_RANGE, m_nRange); DDX_Text(pDX, IDC_RANGE, m_nLC);
DDX_Text(pDX, IDC_CURSOR1, m_nCursor1); DDX_Text(pDX, IDC_CURSOR1, m_nCursor1);
DDX_Text(pDX, IDC_CURSOR2, m_nCursor2); DDX_Text(pDX, IDC_CURSOR2, m_nCursor2);
DDX_Text(pDX, IDC_CURSORROI, m_nCursorROI); DDX_Text(pDX, IDC_CURSORROI, m_nCursorROI);
@ -55,18 +55,36 @@ void CControlView::DoDataExchange(CDataExchange* pDX)
BEGIN_MESSAGE_MAP(CControlView, CFormView) BEGIN_MESSAGE_MAP(CControlView, CFormView)
ON_WM_SIZE() ON_WM_SIZE()
ON_WM_TIMER()
ON_COMMAND(ID_STA_START, &CControlView::OnStaStart) ON_COMMAND(ID_STA_START, &CControlView::OnStaStart)
ON_COMMAND(ID_STA_STOP, &CControlView::OnStaStop) ON_COMMAND(ID_STA_STOP, &CControlView::OnStaStop)
ON_UPDATE_COMMAND_UI(ID_STA_START, &CControlView::OnUpdateStaStart)
ON_UPDATE_COMMAND_UI(ID_STA_STOP, &CControlView::OnUpdateStaStop)
ON_COMMAND(ID_STA_CLEAR, &CControlView::OnStaClear) ON_COMMAND(ID_STA_CLEAR, &CControlView::OnStaClear)
ON_UPDATE_COMMAND_UI(ID_STA_CLEAR, &CControlView::OnUpdateStaClear)
ON_WM_TIMER()
ON_COMMAND(ID_SIMU_CO, &CControlView::OnSimuCo) ON_COMMAND(ID_SIMU_CO, &CControlView::OnSimuCo)
ON_COMMAND(ID_SIMU_CS, &CControlView::OnSimuCs) ON_COMMAND(ID_SIMU_CS, &CControlView::OnSimuCs)
ON_COMMAND(ID_SIMU_NA, &CControlView::OnSimuNa) ON_COMMAND(ID_SIMU_NA, &CControlView::OnSimuNa)
END_MESSAGE_MAP() ON_COMMAND(ID_AXIS_LINEAR, &CControlView::OnAxisLinear)
ON_COMMAND(ID_AXIS_LOG, &CControlView::OnAxisLog)
ON_COMMAND(ID_RANGE_AUTO, &CControlView::OnRangeAuto)
ON_COMMAND(ID_RANGE_D4, &CControlView::OnRangeD4)
ON_COMMAND(ID_RANGE_D2, &CControlView::OnRangeD2)
ON_COMMAND(ID_RANGE_M2, &CControlView::OnRangeM2)
ON_COMMAND(ID_RANGE_M4, &CControlView::OnRangeM4)
ON_COMMAND(ID_DATA_ORIGIN, &CControlView::OnDataOrigin)
ON_COMMAND(ID_DATA_3, &CControlView::OnData3)
ON_COMMAND(ID_DATA_5, &CControlView::OnData5)
ON_UPDATE_COMMAND_UI(ID_STA_START, &CControlView::OnUpdateStaStart)
ON_UPDATE_COMMAND_UI(ID_STA_STOP, &CControlView::OnUpdateStaStop)
ON_UPDATE_COMMAND_UI(ID_STA_CLEAR, &CControlView::OnUpdateStaClear)
ON_UPDATE_COMMAND_UI(ID_SIMU_CO, &CControlView::OnUpdateSimuCo)
ON_UPDATE_COMMAND_UI(ID_SIMU_CS, &CControlView::OnUpdateSimuCs)
ON_UPDATE_COMMAND_UI(ID_SIMU_NA, &CControlView::OnUpdateSimuNa)
ON_UPDATE_COMMAND_UI(ID_RANGE_AUTO, &CControlView::OnUpdateRangeAuto)
ON_UPDATE_COMMAND_UI(ID_DATA_ORIGIN, &CControlView::OnUpdateDataOrigin)
ON_UPDATE_COMMAND_UI(ID_DATA_3, &CControlView::OnUpdateData3)
ON_UPDATE_COMMAND_UI(ID_DATA_5, &CControlView::OnUpdateData5)
END_MESSAGE_MAP()
// CControlView 诊断 // CControlView 诊断
@ -84,6 +102,37 @@ void CControlView::Dump(CDumpContext& dc) const
#endif #endif
#endif //_DEBUG #endif //_DEBUG
int CControlView::roundupPowerof2(int val)
{
if ((val & (val - 1)) == 0) return val;
int andv = 1 << 30;
while ((andv & val) == 0) andv = andv >> 1;
return andv << 1;
}
double CControlView::GetMilliTime()
{
std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()
);
return ms.count() / 1000.;
}
void CControlView::UpdateValue()
{
// 更新信息
m_nTotalCount = pDoc->GetTotal(0, 1023);
m_nMaxCount = pDoc->GetMax(0, 1023);
m_nPartCount = pDoc->GetTotal(m_nCursor1, m_nCursor2);
m_nCursorROICount = pDoc->m_nChannelCount[m_nCursorROI];
m_nTime += GetMilliTime() - m_nT0;
m_nTimeStr.Format(_T("%.1f"), m_nTime);
m_nT0 = GetMilliTime();
// 更新屏幕信息
UpdateData(FALSE);
}
// CControlView 消息处理程序 // CControlView 消息处理程序
void CControlView::OnSize(UINT nType, int cx, int cy) void CControlView::OnSize(UINT nType, int cx, int cy)
@ -120,12 +169,76 @@ void CControlView::OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHi
{ {
} }
double CControlView::GetMilliTime() void CControlView::OnTimer(UINT_PTR nIDEvent)
{ {
std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>( if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument();
std::chrono::system_clock::now().time_since_epoch()
); // 生成随机信号
return ms.count() / 1000.; int n = rand() % 50 + 25;
pDoc->RandomPeak(m_sSource, n);
// 平滑数据
for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = pDoc->m_nChannelCount[i];
OutputDebugString(m_sSmoothType);
if (m_sSmoothType == "S3") {
pDoc->m_nChannelSmooth[0] = (5.0 * pDoc->m_nChannelCount[0] + 2.0 * pDoc->m_nChannelCount[1] - pDoc->m_nChannelCount[2]) / 6.0;
for (int i = 1; i < 1023; i++)
pDoc->m_nChannelSmooth[i] = (pDoc->m_nChannelCount[i - 1] + pDoc->m_nChannelCount[i] + pDoc->m_nChannelCount[i + 1]) / 3.0;
pDoc->m_nChannelSmooth[1023] = (5.0 * pDoc->m_nChannelCount[1023] + 2.0 * pDoc->m_nChannelCount[1022] - pDoc->m_nChannelCount[1021]) / 6.0;
}
else if (m_sSmoothType == "S5") {
pDoc->m_nChannelSmooth[0] = (3.0 * pDoc->m_nChannelCount[0] + 2.0 * pDoc->m_nChannelCount[1] + pDoc->m_nChannelCount[2] - pDoc->m_nChannelCount[4]) / 5.0;
pDoc->m_nChannelSmooth[1] = (4.0 * pDoc->m_nChannelCount[0] + 3.0 * pDoc->m_nChannelCount[1] + 2 * pDoc->m_nChannelCount[2] + pDoc->m_nChannelCount[3]) / 10.0;
for (int i = 2; i < 1022; i++)
pDoc->m_nChannelSmooth[i] = (pDoc->m_nChannelCount[i - 2] + pDoc->m_nChannelCount[i - 1] + pDoc->m_nChannelCount[i] + pDoc->m_nChannelCount[i + 1] + pDoc->m_nChannelCount[i + 2]) / 5.0;
pDoc->m_nChannelSmooth[1022] = (4.0 * pDoc->m_nChannelCount[1023] + 3.0 * pDoc->m_nChannelCount[1022] + 2 * pDoc->m_nChannelCount[1021] + pDoc->m_nChannelCount[1020]) / 10.0;
pDoc->m_nChannelSmooth[1023] = (3.0 * pDoc->m_nChannelCount[1023] + 2.0 * pDoc->m_nChannelCount[1022] + pDoc->m_nChannelCount[1021] - pDoc->m_nChannelCount[1019]) / 5.0;
}
for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = max(0, pDoc->m_nChannelSmooth[i]);
// 更新信息
UpdateValue();
// 判断终止
CString tmp;
m_ComboMode.GetWindowText(tmp);
if (tmp == "时间" && m_nTime >= m_nCond) OnStaStop();
if (tmp == "计数" && m_nTotalCount >= m_nCond) OnStaStop();
// 修改坐标轴
m_ComboAxis.GetWindowText(tmp);
if (tmp == "对数") {
m_bAutoFlag = FALSE;
m_sAxisMode = "Log";
m_sRangeMode = "Auto";
}
else m_sAxisMode = "Linear";
// 判断量程
if (m_sRangeMode == "Auto" && m_nMaxCount >= m_nLC) m_nLC *= 2;
pDoc->UpdateAllViews(NULL);
CFormView::OnTimer(nIDEvent);
}
BOOL CControlView::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam >= 0x25 && pMsg->wParam <= 0x28) {
if (pMsg->wParam == VK_LEFT) m_nCursorROI = max(m_nCursor1, m_nCursorROI - 1);
if (pMsg->wParam == VK_RIGHT) m_nCursorROI = min(m_nCursor2, m_nCursorROI + 1);
if (pMsg->wParam == VK_UP) {
m_nLC *= 2;
m_bAutoFlag = TRUE;
m_sRangeMode = (CString)"Manual";
}
if (pMsg->wParam == VK_DOWN) {
m_nLC = m_nLC > 1 ? m_nLC / 2 : 1;
m_bAutoFlag = TRUE;
m_sRangeMode = (CString)"Manual";
}
return TRUE;
}
return CFormView::PreTranslateMessage(pMsg);
} }
void CControlView::OnStaStart() void CControlView::OnStaStart()
@ -133,9 +246,9 @@ void CControlView::OnStaStart()
// 重置结束条件 // 重置结束条件
m_nT0 = GetMilliTime(); m_nT0 = GetMilliTime();
// 设置状态 // 设置状态
startFlag = FALSE; m_bStartFlag = FALSE;
stopFlag = TRUE; m_bStopFlag = TRUE;
clearFlag = FALSE; m_bClearFlag = FALSE;
((CEdit*)GetDlgItem(IDC_COND))->EnableWindow(FALSE); ((CEdit*)GetDlgItem(IDC_COND))->EnableWindow(FALSE);
// 获取屏幕值至变量 // 获取屏幕值至变量
UpdateData(TRUE); UpdateData(TRUE);
@ -145,15 +258,15 @@ void CControlView::OnStaStart()
void CControlView::OnUpdateStaStart(CCmdUI* pCmdUI) void CControlView::OnUpdateStaStart(CCmdUI* pCmdUI)
{ {
pCmdUI->Enable(startFlag); pCmdUI->Enable(m_bStartFlag);
} }
void CControlView::OnStaStop() void CControlView::OnStaStop()
{ {
// 设置状态 // 设置状态
startFlag = TRUE; m_bStartFlag = TRUE;
stopFlag = FALSE; m_bStopFlag = FALSE;
clearFlag = TRUE; m_bClearFlag = TRUE;
((CEdit*)GetDlgItem(IDC_COND))->EnableWindow(TRUE); ((CEdit*)GetDlgItem(IDC_COND))->EnableWindow(TRUE);
// 停止更新 // 停止更新
KillTimer(1); KillTimer(1);
@ -161,66 +274,162 @@ void CControlView::OnStaStop()
void CControlView::OnUpdateStaStop(CCmdUI* pCmdUI) void CControlView::OnUpdateStaStop(CCmdUI* pCmdUI)
{ {
pCmdUI->Enable(stopFlag); pCmdUI->Enable(m_bStopFlag);
} }
void CControlView::OnStaClear() void CControlView::OnStaClear()
{ {
CMCADoc* pDoc = (CMCADoc*)GetDocument(); if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument();
// 重置 // 重置
m_nLC = 4;
m_nTime = 0; m_nTime = 0;
m_nMaxCount = 0; m_nMaxCount = 0;
m_nPartCount = 0; m_nPartCount = 0;
m_nTotalCount = 0; m_nTotalCount = 0;
m_nTimeStr = (CString)"0.0"; m_nTimeStr = (CString)"0.0";
// 获取屏幕值至变量 // 更新屏幕信息
UpdateData(FALSE); UpdateData(FALSE);
// 设置曲线 // 设置曲线
for (int i = 0; i < pDoc->m_nChannelNum; i++) for (int i = 0; i < 1024; i++) pDoc->m_nChannelCount[i] = 0;
pDoc->m_nChannelCount[i] = 0; for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = 0;
pDoc->UpdateAllViews(NULL); pDoc->UpdateAllViews(NULL);
} }
void CControlView::OnUpdateStaClear(CCmdUI* pCmdUI) void CControlView::OnUpdateStaClear(CCmdUI* pCmdUI)
{ {
pCmdUI->Enable(clearFlag); pCmdUI->Enable(m_bClearFlag);
}
void CControlView::OnTimer(UINT_PTR nIDEvent)
{
CString tmp;
CMCADoc* pDoc = (CMCADoc*)GetDocument();
m_nTotalCount = pDoc->GetTotal(0, 1023);
m_nMaxCount = pDoc->GetMax(0, 1023);
m_nPartCount = pDoc->GetTotal(m_nCursor1, m_nCursor2);
m_nTime += GetMilliTime() - m_nT0;
m_nTimeStr.Format(_T("%.1f"), m_nTime);
m_nT0 = GetMilliTime();
m_ComboMode.GetWindowText(tmp);
if (tmp == "时间" && m_nTime >= m_nCond) OnStaStop();
if (tmp == "计数" && m_nTotalCount >= m_nCond) OnStaStop();
UpdateData(FALSE);
int n = rand() % 50 + 25;
((CMCADoc*)GetDocument())->RandomPeak(source, n);
((CMCADoc*)GetDocument())->UpdateAllViews(NULL);
CFormView::OnTimer(nIDEvent);
} }
void CControlView::OnSimuCo() void CControlView::OnSimuCo()
{ {
source = (CString)"Co60"; m_sSource = (CString)"Co60";
m_bCoFlag = FALSE;
m_bCsFlag = TRUE;
m_bNaFlag = TRUE;
OnStaClear();
OnStaStart();
}
void CControlView::OnUpdateSimuCo(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bCoFlag);
} }
void CControlView::OnSimuCs() void CControlView::OnSimuCs()
{ {
source = (CString)"Cs137"; m_sSource = (CString)"Cs137";
m_bCoFlag = TRUE;
m_bCsFlag = FALSE;
m_bNaFlag = TRUE;
OnStaClear();
OnStaStart();
}
void CControlView::OnUpdateSimuCs(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bCsFlag);
} }
void CControlView::OnSimuNa() void CControlView::OnSimuNa()
{ {
source = (CString)"Na22"; m_sSource = (CString)"Na22";
m_bCoFlag = TRUE;
m_bCsFlag = TRUE;
m_bNaFlag = FALSE;
OnStaClear();
OnStaStart();
}
void CControlView::OnUpdateSimuNa(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bNaFlag);
}
void CControlView::OnAxisLinear()
{
m_sAxisMode = (CString)"Linear";
}
void CControlView::OnAxisLog()
{
m_sAxisMode = (CString)"Log";
}
void CControlView::OnRangeAuto()
{
m_sRangeMode = (CString)"Auto";
m_bAutoFlag = FALSE;
m_nLC = roundupPowerof2(m_nMaxCount);
}
void CControlView::OnUpdateRangeAuto(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bAutoFlag);
}
void CControlView::OnRangeD4()
{
m_sRangeMode = (CString)"Manual";
m_nLC /= 4;
m_bAutoFlag = TRUE;
}
void CControlView::OnRangeD2()
{
m_sRangeMode = (CString)"Manual";
m_nLC /= 2;
m_bAutoFlag = TRUE;
}
void CControlView::OnRangeM2()
{
m_sRangeMode = (CString)"Manual";
m_nLC *= 2;
m_bAutoFlag = TRUE;
}
void CControlView::OnRangeM4()
{
m_sRangeMode = (CString)"Manual";
m_nLC *= 4;
m_bAutoFlag = TRUE;
}
void CControlView::OnDataOrigin()
{
m_sSmoothType = (CString)"Origin";
m_bOriginFlag = FALSE;
m_bTSmoothFlag = TRUE;
m_bFSmoothFlag = TRUE;
}
void CControlView::OnUpdateDataOrigin(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bOriginFlag);
}
void CControlView::OnData3()
{
m_sSmoothType = (CString)"S3";
m_bOriginFlag = TRUE;
m_bTSmoothFlag = FALSE;
m_bFSmoothFlag = TRUE;
}
void CControlView::OnUpdateData3(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bTSmoothFlag);
}
void CControlView::OnData5()
{
m_sSmoothType = (CString)"S5";
m_bOriginFlag = TRUE;
m_bTSmoothFlag = TRUE;
m_bFSmoothFlag = FALSE;
}
void CControlView::OnUpdateData5(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bFSmoothFlag);
} }

View File

@ -2,6 +2,8 @@
#include <chrono> #include <chrono>
#include "MCADoc.h"
// CControlView 窗体视图 // CControlView 窗体视图
class CControlView : public CFormView class CControlView : public CFormView
@ -28,12 +30,26 @@ protected:
DECLARE_MESSAGE_MAP() DECLARE_MESSAGE_MAP()
public: public:
afx_msg void OnSize(UINT nType, int cx, int cy); CMCADoc* pDoc = nullptr;
virtual void OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/); int roundupPowerof2(int val);
double GetMilliTime(); double GetMilliTime();
void UpdateValue();
// 消息处理
afx_msg void OnSize(UINT nType, int cx, int cy);
virtual void OnInitialUpdate();
virtual void OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/);
afx_msg void OnTimer(UINT_PTR nIDEvent);
virtual BOOL PreTranslateMessage(MSG* pMsg);
// 选择信息 // 选择信息
CString source = (CString)"Cs137"; CString m_sSource = (CString)"Cs137";
CString m_sAxisMode = (CString)"Linear";
CString m_sRangeMode = (CString)"Auto";
CString m_sSmoothType = (CString)"Origin";
// 量程
int m_nLC;
// 光标信息 // 光标信息
int m_nCursor1; int m_nCursor1;
@ -49,25 +65,49 @@ public:
int m_nTotalCount; int m_nTotalCount;
int m_nPartCount; int m_nPartCount;
int m_nMaxCount; int m_nMaxCount;
int m_nRange;
CComboBox m_ComboMode; CComboBox m_ComboMode;
CComboBox m_ComboAxis; CComboBox m_ComboAxis;
virtual void OnInitialUpdate();
// 菜单与工具栏响应 // 菜单与工具栏响应
CMenu m_Menu; CMenu m_Menu;
CToolBar m_wndToolBar; CToolBar m_wndToolBar;
BOOL startFlag = TRUE;
BOOL stopFlag = FALSE;
BOOL clearFlag = FALSE;
afx_msg void OnStaStart(); afx_msg void OnStaStart();
afx_msg void OnUpdateStaStart(CCmdUI* pCmdUI);
afx_msg void OnStaStop(); afx_msg void OnStaStop();
afx_msg void OnUpdateStaStop(CCmdUI* pCmdUI);
afx_msg void OnStaClear(); afx_msg void OnStaClear();
afx_msg void OnUpdateStaClear(CCmdUI* pCmdUI);
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnSimuCo(); afx_msg void OnSimuCo();
afx_msg void OnSimuCs(); afx_msg void OnSimuCs();
afx_msg void OnSimuNa(); afx_msg void OnSimuNa();
afx_msg void OnAxisLinear();
afx_msg void OnAxisLog();
afx_msg void OnRangeAuto();
afx_msg void OnRangeD4();
afx_msg void OnRangeD2();
afx_msg void OnRangeM2();
afx_msg void OnRangeM4();
afx_msg void OnDataOrigin();
afx_msg void OnData3();
afx_msg void OnData5();
// 点击状态
BOOL m_bStartFlag = TRUE;
BOOL m_bStopFlag = FALSE;
BOOL m_bClearFlag = FALSE;
BOOL m_bCoFlag = TRUE;
BOOL m_bCsFlag = FALSE;
BOOL m_bNaFlag = TRUE;
BOOL m_bAutoFlag = FALSE;
BOOL m_bOriginFlag = FALSE;
BOOL m_bTSmoothFlag = TRUE;
BOOL m_bFSmoothFlag = TRUE;
afx_msg void OnUpdateStaStart(CCmdUI* pCmdUI);
afx_msg void OnUpdateStaStop(CCmdUI* pCmdUI);
afx_msg void OnUpdateStaClear(CCmdUI* pCmdUI);
afx_msg void OnUpdateSimuCo(CCmdUI* pCmdUI);
afx_msg void OnUpdateSimuCs(CCmdUI* pCmdUI);
afx_msg void OnUpdateSimuNa(CCmdUI* pCmdUI);
afx_msg void OnUpdateRangeAuto(CCmdUI* pCmdUI);
afx_msg void OnUpdateDataOrigin(CCmdUI* pCmdUI);
afx_msg void OnUpdateData3(CCmdUI* pCmdUI);
afx_msg void OnUpdateData5(CCmdUI* pCmdUI);
}; };

View File

@ -39,6 +39,7 @@ void CDetailView::OnDraw(CDC* pDc)
if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
L = pView->m_nCursor1; L = pView->m_nCursor1;
R = pView->m_nCursor2; R = pView->m_nCursor2;
// 缩放 // 缩放
CRect rect; CRect rect;
GetClientRect(&rect); GetClientRect(&rect);
@ -46,20 +47,34 @@ void CDetailView::OnDraw(CDC* pDc)
// 背景颜色、笔颜色等设置 // 背景颜色、笔颜色等设置
CDC MemDC; CDC MemDC;
MemDC.CreateCompatibleDC(pDc);
CBitmap Bitmap, * OldBitmap; CBitmap Bitmap, * OldBitmap;
CPen pen(PS_SOLID, 2, RGB(255, 255, 255)); CPen pen(PS_SOLID, 3, RGB(255, 255, 255));
CPen* oldpen = MemDC.SelectObject(&pen); CPen* oldpen = MemDC.SelectObject(&pen);
GetClientRect(&rect);
MemDC.CreateCompatibleDC(pDc);
Bitmap.CreateCompatibleBitmap(pDc, rect.Width(), rect.Height()); Bitmap.CreateCompatibleBitmap(pDc, rect.Width(), rect.Height());
OldBitmap = MemDC.SelectObject(&Bitmap); OldBitmap = MemDC.SelectObject(&Bitmap);
MemDC.FillSolidRect(0, 0, rect.Width(), rect.Height(), RGB(119, 7, 243)); MemDC.FillSolidRect(0, 0, rect.Width(), rect.Height(), RGB(119, 7, 243));
// 绘图 // 绘图
MemDC.MoveTo(1, rect.Height() - pDoc->m_nChannelCount[L]); int nMaxCount = pDoc->GetMax(L, R) ? pDoc->GetMax(L, R) * 5 / 4 : 1;
int nX = (pView->m_nCursorROI - pView->m_nCursor1) * ZF;
if (pView->m_sAxisMode == "Linear") {
MemDC.MoveTo(1, rect.Height() - pDoc->m_nChannelSmooth[L] * rect.Height() / nMaxCount);
for (int i = L; i <= R; i++) for (int i = L; i <= R; i++)
MemDC.LineTo((i - L) * ZF, rect.Height() - pDoc->m_nChannelCount[i]); MemDC.LineTo((i - L) * ZF, rect.Height() - pDoc->m_nChannelSmooth[i] * rect.Height() / nMaxCount);
}
else {
MemDC.MoveTo(1, rect.Height() - log10(max(pDoc->m_nChannelSmooth[L], 1)) * rect.Height() / log10(nMaxCount));
for (int i = L; i <= R; i++)
MemDC.LineTo((i - L) * ZF, rect.Height() - log10(max(pDoc->m_nChannelSmooth[i], 1)) * rect.Height() / log10(nMaxCount));
}
// »æÖƹâ±êÊúÏß
pen.CreatePen(PS_SOLID, 5, RGB(0, 255, 0));
MemDC.SelectObject(&pen);
MemDC.MoveTo(nX, 0);
MemDC.LineTo(nX, rect.Height());
//释放资源 //释放资源
pDc->BitBlt(0, 0, rect.Width(), rect.Width(), &MemDC, 0, 0, SRCCOPY); pDc->BitBlt(0, 0, rect.Width(), rect.Width(), &MemDC, 0, 0, SRCCOPY);
@ -90,10 +105,10 @@ void CDetailView::Dump(CDumpContext& dc) const
// CDetailView 消息处理程序 // CDetailView 消息处理程序
void CDetailView::OnPaint() void CDetailView::OnPaint()
{ {
if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument(); if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument();
if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
CPaintDC dc(this); // device context for painting CPaintDC dc(this); // device context for painting
OnPrepareDC(&dc); OnPrepareDC(&dc);
OnDraw(&dc); OnDraw(&dc);
@ -110,30 +125,39 @@ void CDetailView::OnLButtonDown(UINT nFlags, CPoint point)
if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
int nX = point.x / ZF + pView->m_nCursor1; int nX = point.x / ZF + pView->m_nCursor1;
pView->m_nCursorROI = nX; pView->m_nCursorROI = nX;
pView->m_nCursorROICount = pDoc->m_nChannelCount[nX]; pDoc->UpdateAllViews(NULL);
CPen pen;
CDC* pDC = GetDC();
pen.CreatePen(PS_SOLID, 5, RGB(255, 180, 20));
CPen* oldpen = pDC->SelectObject(&pen);
CRect rect;
GetClientRect(&rect);
pDC->SetROP2(R2_XORPEN); //²Á³ý
pDC->MoveTo(point.x, 0); //»æÖƹâ±ê
pDC->LineTo(point.x, rect.Height());
pDC->SelectObject(oldpen);
pen.DeleteObject();
CView::OnLButtonDown(nFlags, point); CView::OnLButtonDown(nFlags, point);
} }
void CDetailView::OnRButtonDown(UINT nFlags, CPoint point) void CDetailView::OnRButtonDown(UINT nFlags, CPoint point)
{ {
if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument(); if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument();
if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_nCursor1 = 0; pView->m_nCursor1 = 0;
pView->m_nCursor2 = 1023; pView->m_nCursor2 = 1023;
pDoc->UpdateAllViews(NULL);
CView::OnRButtonDown(nFlags, point); CView::OnRButtonDown(nFlags, point);
} }
BOOL CDetailView::PreTranslateMessage(MSG* pMsg)
{
if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument();
if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
if (pMsg->message == WM_KEYDOWN) {
if (pMsg->wParam == VK_LEFT) pView->m_nCursorROI = max(pView->m_nCursor1, pView->m_nCursorROI - 1);
if (pMsg->wParam == VK_RIGHT) pView->m_nCursorROI = min(pView->m_nCursor2, pView->m_nCursorROI + 1);
if (pMsg->wParam == VK_UP) {
pView->m_nLC *= 2;
pView->m_bAutoFlag = TRUE;
pView->m_sRangeMode = (CString)"Manual";
}
if (pMsg->wParam == VK_DOWN) {
pView->m_nLC = pView->m_nLC > 1 ? pView->m_nLC / 2 : 1;
pView->m_bAutoFlag = TRUE;
pView->m_sRangeMode = (CString)"Manual";
}
pDoc->UpdateAllViews(NULL);
return TRUE;
}
return CView::PreTranslateMessage(pMsg);
}

View File

@ -36,4 +36,5 @@ public:
afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
virtual BOOL PreTranslateMessage(MSG* pMsg);
}; };

Binary file not shown.

View File

@ -39,8 +39,8 @@ CMCADoc::CMCADoc() noexcept
srand((unsigned)time(0)); srand((unsigned)time(0));
m_nChannelCount = new int[m_nChannelNum]; for (int i = 0; i < 1024; i++) m_nChannelCount[i] = 0;
for (int i = 0; i < m_nChannelNum; i++) m_nChannelCount[i] = 0; for (int i = 0; i < 1024; i++) m_nChannelSmooth[i] = 0;
freopen_s(&stream_tmp, "data/Co60.txt", "r", stdin); freopen_s(&stream_tmp, "data/Co60.txt", "r", stdin);
for (int i = 0; i < 1024; i++) for (int i = 0; i < 1024; i++)
@ -196,14 +196,14 @@ void CMCADoc::RandomPeak(CString name, int n)
int CMCADoc::GetTotal(int L, int R) int CMCADoc::GetTotal(int L, int R)
{ {
int cSum = 0; int cSum = 0;
for (int i = L; i <= min(m_nChannelNum-1, R); i++) cSum += m_nChannelCount[i]; for (int i = L; i <= min(1023, R); i++) cSum += m_nChannelCount[i];
return cSum; return cSum;
} }
int CMCADoc::GetMax(int L, int R) int CMCADoc::GetMax(int L, int R)
{ {
int cMax = 0; int cMax = 0;
for (int i = L; i <= min(m_nChannelNum - 1, R); i++) for (int i = L; i <= min(1023, R); i++)
if (m_nChannelCount[i] > cMax) if (m_nChannelCount[i] > cMax)
cMax = m_nChannelCount[i]; cMax = m_nChannelCount[i];
return cMax; return cMax;

View File

@ -15,8 +15,8 @@ protected: // 仅从序列化创建
// 特性 // 特性
public: public:
int m_nChannelNum = 1024; int m_nChannelCount[1024];
int *m_nChannelCount; int m_nChannelSmooth[1024];
private: private:
// reference spectrum // reference spectrum

View File

@ -7,10 +7,9 @@
#include "MCA.h" #include "MCA.h"
#include "MainFrm.h" #include "MainFrm.h"
#include "ControlView.h"
#include "DetailView.h"
#include "TotalView.h" #include "TotalView.h"
#include "DetailView.h"
#include "ControlView.h"
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@ -121,9 +120,6 @@ void CMainFrame::Dump(CDumpContext& dc) const
// CMainFrame 消息处理程序 // CMainFrame 消息处理程序
void CMainFrame::OnLoadToolBarIcon() void CMainFrame::OnLoadToolBarIcon()
{ {
HICON icon; HICON icon;

View File

@ -1,5 +1,6 @@
// TotalView.cpp : 实现文件 // TotalView.cpp : 实现文件
// //
#include <math.h>
#include "pch.h" #include "pch.h"
@ -35,27 +36,45 @@ void CTotalView::OnDraw(CDC* pDc)
{ {
// 背景颜色、笔颜色等设置 // 背景颜色、笔颜色等设置
CDC MemDC; CDC MemDC;
MemDC.CreateCompatibleDC(pDc);
CRect rect; CRect rect;
CBitmap Bitmap, * OldBitmap; CBitmap Bitmap, * OldBitmap;
CPen pen(PS_SOLID, 2, RGB(0, 0, 0)); CPen pen(PS_SOLID, 3, RGB(0, 0, 0));
CPen* oldpen = MemDC.SelectObject(&pen); CPen* oldpen = MemDC.SelectObject(&pen);
GetClientRect(&rect); GetClientRect(&rect);
MemDC.CreateCompatibleDC(pDc);
Bitmap.CreateCompatibleBitmap(pDc, rect.Width(), rect.Height()); Bitmap.CreateCompatibleBitmap(pDc, rect.Width(), rect.Height());
OldBitmap = MemDC.SelectObject(&Bitmap); OldBitmap = MemDC.SelectObject(&Bitmap);
MemDC.FillSolidRect(0, 0, rect.Width(), rect.Height(), RGB(36, 217, 163)); MemDC.FillSolidRect(0, 0, rect.Width(), rect.Height(), RGB(36, 217, 163));
// 绘图 // 绘图
MemDC.MoveTo(1, rect.Height() - pDoc->m_nChannelCount[0]); if (pView->m_sAxisMode == "Linear") {
for (int i = 0; i < pDoc->m_nChannelNum; i++) MemDC.MoveTo(1, rect.Height() - pDoc->m_nChannelSmooth[0] * rect.Height() / pView->m_nLC);
MemDC.LineTo(2 * i + 1, rect.Height() - pDoc->m_nChannelCount[i]); for (int i = 0; i < 1024; i++)
MemDC.LineTo(2 * i + 1, rect.Height() - pDoc->m_nChannelSmooth[i] * rect.Height() / pView->m_nLC);
}
else {
MemDC.MoveTo(1, rect.Height() - log10(max(pDoc->m_nChannelSmooth[0], 1)) * rect.Height() / log10(pView->m_nLC));
for (int i = 0; i < 1024; i++)
MemDC.LineTo(2 * i + 1, rect.Height() - log10(max(pDoc->m_nChannelSmooth[i], 1)) * rect.Height() / log10(pView->m_nLC));
}
// 绘制光标竖线
pen.CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
MemDC.SelectObject(&pen);
MemDC.MoveTo(2 * pView->m_nCursor1 + 1, 0);
MemDC.LineTo(2 * pView->m_nCursor1 + 1, rect.Height());
pen.CreatePen(PS_SOLID, 5, RGB(0, 255, 0));
MemDC.SelectObject(&pen);
MemDC.MoveTo(2 * pView->m_nCursor2 + 1, 0);
MemDC.LineTo(2 * pView->m_nCursor2 + 1, rect.Height());
//释放资源    //释放资源
pDc->BitBlt(0, 0, rect.Width(), rect.Height(), &MemDC, 0, 0, SRCCOPY);
MemDC.SelectObject(oldpen); MemDC.SelectObject(oldpen);
MemDC.SelectObject(OldBitmap);
pen.DeleteObject(); pen.DeleteObject();
pDc->BitBlt(0, 0, rect.Width(), rect.Height(), &MemDC, 0, 0, SRCCOPY);
MemDC.SelectObject(OldBitmap);
Bitmap.DeleteObject(); Bitmap.DeleteObject();
MemDC.DeleteDC(); MemDC.DeleteDC();
} }
@ -84,6 +103,7 @@ void CTotalView::Dump(CDumpContext& dc) const
void CTotalView::OnPaint() void CTotalView::OnPaint()
{ {
if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument(); if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument();
if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
CPaintDC dc(this); // device context for painting CPaintDC dc(this); // device context for painting
OnPrepareDC(&dc); OnPrepareDC(&dc);
OnDraw(&dc); OnDraw(&dc);
@ -100,7 +120,11 @@ void CTotalView::OnLButtonDown(UINT nFlags, CPoint point)
if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument(); if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument();
if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
int nX = (point.x - 1) / 2; int nX = (point.x - 1) / 2;
if (nX < pView->m_nCursor2) pView->m_nCursor1 = nX; if (nX < pView->m_nCursor2) {
pView->m_nCursor1 = nX;
pView->m_nCursorROI = max(pView->m_nCursor1, pView->m_nCursorROI);
}
pDoc->UpdateAllViews(NULL);
CView::OnLButtonDown(nFlags, point); CView::OnLButtonDown(nFlags, point);
} }
@ -109,6 +133,33 @@ void CTotalView::OnRButtonDown(UINT nFlags, CPoint point)
if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument(); if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument();
if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
int nX = (point.x - 1) / 2; int nX = (point.x - 1) / 2;
if (nX > pView->m_nCursor1) pView->m_nCursor2 = nX; if (nX > pView->m_nCursor1) {
pView->m_nCursor2 = nX;
pView->m_nCursorROI = min(pView->m_nCursor2, pView->m_nCursorROI);
}
pDoc->UpdateAllViews(NULL);
CView::OnRButtonDown(nFlags, point); CView::OnRButtonDown(nFlags, point);
} }
BOOL CTotalView::PreTranslateMessage(MSG* pMsg)
{
if (pDoc == NULL) pDoc = (CMCADoc*)GetDocument();
if (pView == NULL) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
if (pMsg->message == WM_KEYDOWN) {
if (pMsg->wParam == VK_LEFT) pView->m_nCursorROI = max(pView->m_nCursor1, pView->m_nCursorROI - 1);
if (pMsg->wParam == VK_RIGHT) pView->m_nCursorROI = min(pView->m_nCursor2, pView->m_nCursorROI + 1);
if (pMsg->wParam == VK_UP) {
pView->m_nLC *= 2;
pView->m_bAutoFlag = TRUE;
pView->m_sRangeMode = (CString)"Manual";
}
if (pMsg->wParam == VK_DOWN) {
pView->m_nLC = pView->m_nLC > 1 ? pView->m_nLC / 2 : 1;
pView->m_bAutoFlag = TRUE;
pView->m_sRangeMode = (CString)"Manual";
}
pDoc->UpdateAllViews(NULL);
return TRUE;
}
return CView::PreTranslateMessage(pMsg);
}

View File

@ -35,4 +35,5 @@ public:
afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
virtual BOOL PreTranslateMessage(MSG* pMsg);
}; };