// MainFrm.cpp: CMainFrame 类的实现 // #include #include #include #include #include #include "pch.h" #include "framework.h" #include "MCA.h" #include "Matrix.h" #include "MainFrm.h" #include "TotalView.h" #include "DetailView.h" #include "ControlView.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CMainFrame IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_CREATE() ON_WM_TIMER() ON_WM_CLOSE() ON_COMMAND(ID_OPT_OPEN, &CMainFrame::OnOptOpen) ON_COMMAND(ID_OPT_SAVE, &CMainFrame::OnOptSave) ON_COMMAND(ID_STA_START, &CMainFrame::OnStaStart) ON_COMMAND(ID_STA_STOP, &CMainFrame::OnStaStop) ON_COMMAND(ID_STA_CLEAR, &CMainFrame::OnStaClear) ON_COMMAND(ID_SIMU_CO, &CMainFrame::OnSimuCo) ON_COMMAND(ID_SIMU_CS, &CMainFrame::OnSimuCs) ON_COMMAND(ID_SIMU_NA, &CMainFrame::OnSimuNa) ON_COMMAND(ID_AXIS_LINEAR, &CMainFrame::OnAxisLinear) ON_COMMAND(ID_AXIS_LOG, &CMainFrame::OnAxisLog) ON_COMMAND(ID_RANGE_AUTO, &CMainFrame::OnRangeAuto) ON_COMMAND(ID_RANGE_D4, &CMainFrame::OnRangeD4) ON_COMMAND(ID_RANGE_D2, &CMainFrame::OnRangeD2) ON_COMMAND(ID_RANGE_M2, &CMainFrame::OnRangeM2) ON_COMMAND(ID_RANGE_M4, &CMainFrame::OnRangeM4) ON_COMMAND(ID_DATA_ORIGIN, &CMainFrame::OnDataOrigin) ON_COMMAND(ID_DATA_3, &CMainFrame::OnData3) ON_COMMAND(ID_DATA_5, &CMainFrame::OnData5) ON_COMMAND(ID_DATA_PEAK, &CMainFrame::OnDataPeak) ON_UPDATE_COMMAND_UI(ID_STA_START, &CMainFrame::OnUpdateStaStart) ON_UPDATE_COMMAND_UI(ID_STA_STOP, &CMainFrame::OnUpdateStaStop) ON_UPDATE_COMMAND_UI(ID_STA_CLEAR, &CMainFrame::OnUpdateStaClear) ON_UPDATE_COMMAND_UI(ID_SIMU_CO, &CMainFrame::OnUpdateSimuCo) ON_UPDATE_COMMAND_UI(ID_SIMU_CS, &CMainFrame::OnUpdateSimuCs) ON_UPDATE_COMMAND_UI(ID_SIMU_NA, &CMainFrame::OnUpdateSimuNa) ON_UPDATE_COMMAND_UI(ID_AXIS_LINEAR, &CMainFrame::OnUpdateAxisLinear) ON_UPDATE_COMMAND_UI(ID_AXIS_LOG, &CMainFrame::OnUpdateAxisLog) ON_UPDATE_COMMAND_UI(ID_RANGE_AUTO, &CMainFrame::OnUpdateRangeAuto) ON_UPDATE_COMMAND_UI(ID_DATA_ORIGIN, &CMainFrame::OnUpdateDataOrigin) ON_UPDATE_COMMAND_UI(ID_DATA_3, &CMainFrame::OnUpdateData3) ON_UPDATE_COMMAND_UI(ID_DATA_5, &CMainFrame::OnUpdateData5) END_MESSAGE_MAP() static UINT indicators[] = { ID_SEPARATOR, // 状态行指示器 ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; // CMainFrame 构造/析构 CMainFrame::CMainFrame() noexcept { // TODO: 在此添加成员初始化代码 } CMainFrame::~CMainFrame() { } int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("未能创建工具栏\n"); return -1; // 未能创建 } if (!m_wndStatusBar.Create(this)) { TRACE0("未能创建状态栏\n"); return -1; // 未能创建 } m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)); // TODO: 如果不需要可停靠工具栏,则删除这三行 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); MoveWindow(0, 0, 2386, 1200); CenterWindow(); OnLoadToolBarIcon(); return 0; } BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) { // 左右拆分窗口,1行2列 VERIFY(m_wndSplitter.CreateStatic(this, 1, 2, WS_CHILD | WS_VISIBLE, AFX_IDW_PANE_FIRST)); // 左侧窗口创建视图,第0行第0列 VERIFY(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CControlView), CSize(300, 0), pContext)); // 右侧窗口上下拆分,2行1列 VERIFY(m_wndSplitter2.CreateStatic(&m_wndSplitter, 2, 1, WS_CHILD | WS_VISIBLE, m_wndSplitter.IdFromRowCol(0, 1))); // 右上窗口创建视图,第0行第0列 VERIFY(m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(CTotalView), CSize(2086, 400), pContext)); // 右下窗口创建视图,第1行第0列 VERIFY(m_wndSplitter2.CreateView(1, 0, RUNTIME_CLASS(CDetailView), CSize(2086, 0), pContext)); return TRUE; } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; cs.style &= ~WS_THICKFRAME; cs.style &= ~WS_MAXIMIZEBOX; return TRUE; } void CMainFrame::OnLoadToolBarIcon() { HICON icon; m_imgList.Create(50, 50, TRUE | ILC_COLOR32, 10, 0); icon = AfxGetApp()->LoadIconW(IDI_START); m_imgList.Add(icon); icon = AfxGetApp()->LoadIconW(IDI_STOP); m_imgList.Add(icon); icon = AfxGetApp()->LoadIconW(IDI_CLEAR); m_imgList.Add(icon); icon = AfxGetApp()->LoadIconW(IDI_FOLDER); m_imgList.Add(icon); icon = AfxGetApp()->LoadIconW(IDI_SAVE); m_imgList.Add(icon); icon = AfxGetApp()->LoadIconW(IDI_UP); m_imgList.Add(icon); icon = AfxGetApp()->LoadIconW(IDI_DOWN); m_imgList.Add(icon); icon = AfxGetApp()->LoadIconW(IDI_AUTO); m_imgList.Add(icon); icon = AfxGetApp()->LoadIconW(IDI_CLOSE); m_imgList.Add(icon); m_wndToolBar.GetToolBarCtrl().SetImageList(&m_imgList); } // CMainFrame 诊断 #ifdef _DEBUG void CMainFrame::AssertValid() const { CFrameWnd::AssertValid(); } void CMainFrame::Dump(CDumpContext& dc) const { CFrameWnd::Dump(dc); } #endif //_DEBUG int CMainFrame::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 CMainFrame::GetMilliTime() { std::chrono::milliseconds ms = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch() ); return ms.count() / 1000.; } void CMainFrame::UpdateValue() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); // 更新显示曲线 for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = pDoc->m_nChannelCount[i]; if (pView->m_sSmoothType == "S3") SmoothThree(); else if (pView->m_sSmoothType == "S5") SmoothFive(); // 更新信息 pView->m_nTotalCount = pDoc->GetTotal(0, 1023); pView->m_nMaxCount = pDoc->GetMax(0, 1023); pView->m_nPartCount = pDoc->GetTotal(pView->m_nCursor1, pView->m_nCursor2); pView->m_nCursorROICount = pDoc->m_nChannelCount[pView->m_nCursorROI]; pView->m_nTime += GetMilliTime() - pView->m_nT0; pView->m_nTimeStr.Format(_T("%.1f"), pView->m_nTime); pView->m_nT0 = GetMilliTime(); // 更新量程 if (pView->m_sRangeMode == "Auto") pView->m_nLC = RoundupPowerof2(pView->m_nMaxCount); // 更新屏幕信息 pView->UpdateData(FALSE); } void CMainFrame::SaveFirst() { int res = MessageBox(TEXT("打开前是否保存?"), TEXT("保存文件"), MB_YESNO | MB_ICONQUESTION); if (res == IDYES) OnOptSave(); } void CMainFrame::SmoothThree() { pDoc->m_nChannelSmooth[0] = (5 * pDoc->m_nChannelCount[0] + 2 * pDoc->m_nChannelCount[1] - pDoc->m_nChannelCount[2]) / 6; 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; pDoc->m_nChannelSmooth[1023] = (5 * pDoc->m_nChannelCount[1023] + 2 * pDoc->m_nChannelCount[1022] - pDoc->m_nChannelCount[1021]) / 6; for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = max(0, pDoc->m_nChannelSmooth[i]); } void CMainFrame::SmoothFive() { pDoc->m_nChannelSmooth[0] = (3 * pDoc->m_nChannelCount[0] + 2 * pDoc->m_nChannelCount[1] + pDoc->m_nChannelCount[2] - pDoc->m_nChannelCount[4]) / 5; pDoc->m_nChannelSmooth[1] = (4 * pDoc->m_nChannelCount[0] + 3 * pDoc->m_nChannelCount[1] + 2 * pDoc->m_nChannelCount[2] + pDoc->m_nChannelCount[3]) / 10; 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; pDoc->m_nChannelSmooth[1022] = (4 * pDoc->m_nChannelCount[1023] + 3 * pDoc->m_nChannelCount[1022] + 2 * pDoc->m_nChannelCount[1021] + pDoc->m_nChannelCount[1020]) / 10; pDoc->m_nChannelSmooth[1023] = (3 * pDoc->m_nChannelCount[1023] + 2 * pDoc->m_nChannelCount[1022] + pDoc->m_nChannelCount[1021] - pDoc->m_nChannelCount[1019]) / 5; for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = max(0, pDoc->m_nChannelSmooth[i]); } // CMainFrame 消息处理程序 void CMainFrame::OnTimer(UINT_PTR nIDEvent) { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pDoc->SetModifiedFlag(TRUE); // 生成随机信号 int n = rand() % 50 + 25; pDoc->RandomPeak(pView->m_sSource, n); // 更新 UpdateValue(); // 判断终止 CString tmp; pView->m_ComboMode.GetWindowText(tmp); if (tmp == "时间" && pView->m_nTime >= pView->m_nCond) OnStaStop(); if (tmp == "计数" && pView->m_nTotalCount >= pView->m_nCond) OnStaStop(); // 修改坐标轴 pView->m_ComboAxis.GetWindowText(tmp); if (tmp == "对数") { m_bAutoFlag = FALSE; pView->m_sAxisMode = "Log"; pView->m_sRangeMode = "Auto"; m_bLinearFlag = TRUE; m_bLogFlag = FALSE; } else { pView->m_sAxisMode = "Linear"; m_bLinearFlag = FALSE; m_bLogFlag = TRUE; } pDoc->UpdateAllViews(NULL); CFrameWnd::OnTimer(nIDEvent); } void CMainFrame::OnClose() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pDoc->IsModified()) { int res = MessageBox(TEXT("退出前是否保存?"), TEXT("保存文件"), MB_YESNO | MB_ICONQUESTION); if (res == IDYES) OnOptSave(); pDoc->SetModifiedFlag(FALSE); } CFrameWnd::OnClose(); } BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); if (pMsg->message == WM_KEYDOWN && pMsg->wParam >= 0x25 && pMsg->wParam <= 0x28) { 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) OnRangeM2(); if (pMsg->wParam == VK_DOWN) OnRangeD2(); pView->m_nWidth = pView->m_nCursor2 - pView->m_nCursor1 + 1; pView->m_nCursorROICount = pDoc->m_nChannelCount[pView->m_nCursorROI]; pView->UpdateData(FALSE); pDoc->UpdateAllViews(NULL); return TRUE; } return CFrameWnd::PreTranslateMessage(pMsg); } void CMainFrame::OnStaStart() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); // 重置结束条件 pView->m_nT0 = GetMilliTime(); // 设置状态 m_bStartFlag = FALSE; m_bStopFlag = TRUE; m_bClearFlag = FALSE; pView->SetCond(FALSE); // 获取屏幕值至变量 pView->UpdateData(TRUE); // 设置更新 SetTimer(1, 100, NULL); } void CMainFrame::OnUpdateStaStart(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bStartFlag); } void CMainFrame::OnOptOpen() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); if (pDoc->IsModified()) SaveFirst(); CString szFilter = (CString)"文本文件(*.txt)|*.txt|"; CFileDialog fileDlg(TRUE, (CString)"*.txt", NULL, OFN_OVERWRITEPROMPT, szFilter); if (IDCANCEL == fileDlg.DoModal()) return; CString szfile = fileDlg.GetPathName(); int k, cnt = 0; int count[1024] = { 0 }; std::string line, tmp; std::ifstream ifs(szfile); try { std::getline(ifs, line); pView->m_nTime = 0; pView->m_nT0 = GetMilliTime() - std::stof(line); std::getline(ifs, line); pView->m_sSource = line.c_str(); while (std::getline(ifs, line)) { std::stringstream ss(line); std::getline(ss, tmp, ','); k = std::stoi(tmp); std::getline(ss, tmp, ','); count[k] = std::stoi(tmp); cnt += 1; } for (int i = 1; i < 1024; i++) pDoc->m_nChannelCount[i] = count[i]; m_bClearFlag = TRUE; pView->m_sRangeMode = "Auto"; UpdateValue(); pDoc->UpdateAllViews(NULL); } catch (const std::exception&) { AfxMessageBox((CString)"文件格式错误"); } } void CMainFrame::OnOptSave() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); CString szFilter = (CString)"文本文件(*.txt)|*.txt|"; CFileDialog fileDlg(FALSE, (CString)"*.txt", NULL, OFN_OVERWRITEPROMPT, szFilter); if (IDCANCEL == fileDlg.DoModal()) return; CString szfile = fileDlg.GetPathName(); std::ofstream ofs(szfile); ofs << pView->m_nTime << std::endl; ofs << pView->m_sSource << std::endl; for (int i = 0; i < 1024; i++) ofs << i << ", " << pDoc->m_nChannelCount[i] << std::endl; AfxMessageBox((CString)"保存成功"); pDoc->SetModifiedFlag(FALSE); } void CMainFrame::OnStaStop() { // 设置状态 m_bStartFlag = TRUE; m_bStopFlag = FALSE; m_bClearFlag = TRUE; pView->SetCond(TRUE); // 停止更新 KillTimer(1); } void CMainFrame::OnUpdateStaStop(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bStopFlag); } void CMainFrame::OnStaClear() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); // 重置 pView->m_nLC = 4; pView->m_nTime = 0; pView->m_nMaxCount = 0; pView->m_nPartCount = 0; pView->m_nTotalCount = 0; pView->m_nCursorROICount = 0; pView->m_nTimeStr = (CString)"0.0"; // 更新屏幕信息 pView->UpdateData(FALSE); // 设置曲线 for (int i = 0; i < 1024; i++) pDoc->m_nChannelCount[i] = 0; for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = 0; pDoc->UpdateAllViews(NULL); pDoc->SetModifiedFlag(FALSE); } void CMainFrame::OnUpdateStaClear(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bClearFlag); } void CMainFrame::OnSimuCo() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sSource = (CString)"Co60"; m_bCoFlag = FALSE; m_bCsFlag = TRUE; m_bNaFlag = TRUE; OnStaStop(); OnStaClear(); } void CMainFrame::OnUpdateSimuCo(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bCoFlag); } void CMainFrame::OnSimuCs() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sSource = (CString)"Cs137"; m_bCoFlag = TRUE; m_bCsFlag = FALSE; m_bNaFlag = TRUE; OnStaStop(); OnStaClear(); } void CMainFrame::OnUpdateSimuCs(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bCsFlag); } void CMainFrame::OnSimuNa() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sSource = (CString)"Na22"; m_bCoFlag = TRUE; m_bCsFlag = TRUE; m_bNaFlag = FALSE; OnStaStop(); OnStaClear(); } void CMainFrame::OnUpdateSimuNa(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bNaFlag); } void CMainFrame::OnAxisLinear() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sAxisMode = (CString)"Linear"; m_bLinearFlag = FALSE; m_bLogFlag = TRUE; } void CMainFrame::OnUpdateAxisLinear(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bLinearFlag); } void CMainFrame::OnAxisLog() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sAxisMode = (CString)"Log"; m_bLinearFlag = TRUE; m_bLogFlag = FALSE; } void CMainFrame::OnUpdateAxisLog(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bLogFlag); } void CMainFrame::OnRangeAuto() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sRangeMode = (CString)"Auto"; m_bAutoFlag = FALSE; pView->m_nLC = max(1, RoundupPowerof2(pView->m_nMaxCount)); pDoc->UpdateAllViews(NULL); } void CMainFrame::OnUpdateRangeAuto(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bAutoFlag); } void CMainFrame::OnRangeD4() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sRangeMode = (CString)"Manual"; pView->m_nLC /= 4; m_bAutoFlag = TRUE; pView->UpdateData(FALSE); pDoc->UpdateAllViews(NULL); } void CMainFrame::OnRangeD2() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sRangeMode = (CString)"Manual"; pView->m_nLC /= 2; m_bAutoFlag = TRUE; pView->UpdateData(FALSE); pDoc->UpdateAllViews(NULL); } void CMainFrame::OnRangeM2() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sRangeMode = (CString)"Manual"; pView->m_nLC *= 2; m_bAutoFlag = TRUE; pView->UpdateData(FALSE); pDoc->UpdateAllViews(NULL); } void CMainFrame::OnRangeM4() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sRangeMode = (CString)"Manual"; pView->m_nLC *= 4; m_bAutoFlag = TRUE; pView->UpdateData(FALSE); pDoc->UpdateAllViews(NULL); } void CMainFrame::OnDataOrigin() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sSmoothType = (CString)"Origin"; m_bOriginFlag = FALSE; m_bTSmoothFlag = TRUE; m_bFSmoothFlag = TRUE; for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = pDoc->m_nChannelCount[i]; pDoc->UpdateAllViews(NULL); } void CMainFrame::OnUpdateDataOrigin(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bOriginFlag); } void CMainFrame::OnData3() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sSmoothType = (CString)"S3"; m_bOriginFlag = TRUE; m_bTSmoothFlag = FALSE; m_bFSmoothFlag = TRUE; SmoothThree(); pDoc->UpdateAllViews(NULL); } void CMainFrame::OnUpdateData3(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bTSmoothFlag); } void CMainFrame::OnData5() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); pView->m_sSmoothType = (CString)"S5"; m_bOriginFlag = TRUE; m_bTSmoothFlag = TRUE; m_bFSmoothFlag = FALSE; SmoothFive(); pDoc->UpdateAllViews(NULL); } void CMainFrame::OnUpdateData5(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bFSmoothFlag); } void CMainFrame::OnDataPeak() { if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument(); if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView)); int L = pView->m_nCursor1; int R = pView->m_nCursor2; if (pView->m_nWidth > 256) { AfxMessageBox((CString)"ROI区域太大(需≤256)"); return ; } int cnt = 0; double amplitude, mean, sigma, b0, b1, b2; for (int i = L; i <= R; i++) if (pDoc->m_nChannelSmooth[i] != 0) cnt++; matrix mZ(cnt, 1); matrix mX(cnt, 3); matrix mB(3, 1); cnt = 0; for (int i = L; i <= R; i++) { if (pDoc->m_nChannelSmooth[i] == 0) continue; vX[cnt] = i, vY[cnt] = pDoc->m_nChannelSmooth[i]; mZ(cnt, 0) = log(pDoc->m_nChannelSmooth[i]); mX(cnt, 0) = 1, mX(cnt, 1) = i, mX(cnt, 2) = i * i; cnt++; } mB = (mX.T() * mX).I() * mX.T() * mZ; b0 = mB(0, 0), b1 = mB(1, 0), b2 = mB(2, 0); sigma = -1 / b2; mean = b1 * sigma / 2; amplitude = exp(b0 + mean * mean / sigma); sigma = sqrt(sigma); matrix mJ(cnt, 3); matrix mH(3, 3); matrix mF(cnt, 1); matrix mG(3, 1); matrix mS(3, 1); matrix mL(3, 3); matrix mU(3, 3); double maxV; int* P = new int[3](); double* b = new double[3](); for (int i = 0; i < 10; i++) { mJ = Jacobian(cnt, &vX[0], amplitude, mean, sigma); mH = mJ.T() * mJ; for (int j = 0; j < cnt; j++) mF(j, 0) = vY[j] - Gaussian(vX[j], amplitude, mean, sigma); mG = mJ.T() * mF; for (int j = 0; j < 3; j++) b[j] = -mG(j, 0); if (!LUPDescomposition(mH, mL, mU, P)) return; mS = LUPSolve(mL, mU, P, b); amplitude += mS(0, 0), mean += mS(1, 0), sigma += mS(2, 0); maxV = 0; for (int j = 0; j < 3; j++) maxV = max(maxV, abs(mS(j, 0))); if (maxV < 1e-5) break; } if (amplitude < 0 || mean < 0 || sigma < 0) { AfxMessageBox((CString)"拟合失败"); return ; } CString strText; strText.Format(_T("幅值%.3f\n均值%.3f\n标准差%.3f"), amplitude, mean, sigma); AfxMessageBox(strText); }