www.gusucode.com > VC++绘制样条曲线的源码实例源码程序 > VC++绘制样条曲线的源码实例源码程序\code\TestCurveDlg.cpp
// TestCurveDlg.cpp : implementation file // #include "stdafx.h" #include "TestCurve.h" #include "TestCurveDlg.h" #include <math.h> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // Download by http://www.NewXing.com typedef struct { COLORREF crColour; // color TCHAR *szName; // color name } ColourTableEntry; // colors static ColourTableEntry g_crColours[] = { { RGB(0xFF, 0x00, 0x00), _T("红色") }, { RGB(0x00, 0x93, 0x00), _T("绿色") }, { RGB(0x8B, 0x8B, 0x00), _T("深黄") }, { RGB(0x80, 0x00, 0x80), _T("紫色") }, { RGB(0xFF, 0x68, 0x20), _T("桔黄") }, { RGB(0x00, 0x00, 0x8B), _T("深蓝") }, { RGB(0x00, 0x40, 0x40), _T("橄榄绿") }, { RGB(0xA5, 0x2A, 0x00), _T("褐色") }, { RGB(0x38, 0x8E, 0x8E), _T("青色") }, { RGB(0x00, 0xFF, 0x00), _T("鲜绿") }, { RGB(0x4B, 0x00, 0x82), _T("靛蓝") }, { RGB(0xFF, 0xD7, 0x00), _T("金色") }, { RGB(0x40, 0xE0, 0xD0), _T("青绿") }, { RGB(0xD2, 0xB4, 0x8C), _T("棕黄") }, { RGB(0x68, 0x83, 0x8B), _T("淡蓝") }, // { RGB(0x00, 0x00, 0x5E), _T("深灰蓝") }, // { RGB(0x00, 0x00, 0xFF), _T("蓝色") }, // { RGB(0x48, 0x00, 0x48), _T("梅红") }, // { RGB(0x00, 0x55, 0x00), _T("深绿") }, // { RGB(0x7B, 0x7B, 0xC0), _T("蓝-灰") }, // { RGB(0x66, 0x66, 0x66), _T("灰-40%") }, // { RGB(0x7D, 0x9E, 0xC0), _T("浅蓝") }, // { RGB(0x32, 0xCD, 0x32), _T("酸橙色") }, // { RGB(0xFF, 0xAD, 0x5B), _T("浅桔黄") }, // { RGB(0x7F, 0x7F, 0x7F), _T("灰-50%") }, // { RGB(0x28, 0x28, 0x28), _T("灰-80%") }, // { RGB(0xFF, 0xC0, 0xCB), _T("粉红") }, // { RGB(0x8B, 0x00, 0x00), _T("深红") }, // { RGB(0x00, 0x00, 0x00), _T("黑色") }, // { RGB(0x7F, 0xFF, 0xD4), _T("宝石蓝") }, // { RGB(0x3C, 0xB3, 0x71), _T("海绿") }, // { RGB(0xFF, 0xFF, 0x00), _T("黄色") }, // { RGB(0xC0, 0xFF, 0xFF), _T("天蓝") }, // { RGB(0xC0, 0xC0, 0xC0), _T("灰-25%") }, // { RGB(0xFF, 0xFF, 0xE0), _T("浅黄") }, // { RGB(0xAF, 0xEE, 0xEE), _T("浅青绿") }, // { RGB(0xE6, 0xE6, 0xFA), _T("淡紫") }, // { RGB(0xFF, 0xE4, 0xE1), _T("玫瑰红") }, // { RGB(0x98, 0xFB, 0x98), _T("浅绿") }, // { RGB(0xFF, 0xFF, 0xFF), _T("白色") } }; const int g_nColourCount = sizeof(g_crColours) / sizeof(ColourTableEntry); #define ID_CURVE_CONTROL 0x9999 ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About // Download by http://www.NewXing.com class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTestCurveDlg dialog CTestCurveDlg::CTestCurveDlg(CWnd* pParent /*=NULL*/) : CDialog(CTestCurveDlg::IDD, pParent) { //{{AFX_DATA_INIT(CTestCurveDlg) m_iListIndex = -1; //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_pCurveCtrl = NULL; m_nCurveCount = 0; } CTestCurveDlg::~CTestCurveDlg() { delete m_pCurveCtrl; } void CTestCurveDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTestCurveDlg) DDX_Control(pDX, IDC_STATIC_CURVE, m_StcCurve); DDX_CBIndex(pDX, IDC_COMBO1, m_iListIndex); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CTestCurveDlg, CDialog) //{{AFX_MSG_MAP(CTestCurveDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(ID_BTN_ADD, OnBtnAdd) ON_WM_SIZE() ON_CBN_SELCHANGE(IDC_COMBO1, OnSelchangeCombo1) ON_BN_CLICKED(IDC_ADDDATA, OnAdddata) //}}AFX_MSG_MAP ON_NOTIFY(CVN_MVALUE_ADD, ID_CURVE_CONTROL, OnCurveMouseAdd) ON_NOTIFY(CVN_MVALUE_CHANG, ID_CURVE_CONTROL, OnCurveMouseModify) ON_NOTIFY(CVN_MVALUE_DELETE, ID_CURVE_CONTROL, OnCurveMouseDelete) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTestCurveDlg message handlers BOOL CTestCurveDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon CRect rect; m_StcCurve.GetWindowRect(rect); ScreenToClient(rect); if (NULL == m_pCurveCtrl) { m_pCurveCtrl = new CCurveCtrl; m_pCurveCtrl->Create(rect, this, ID_CURVE_CONTROL); m_pCurveCtrl->SetGridLineStyle(PS_DOT); m_pCurveCtrl->SetMargin(CRect(70, 50, 50, 50)); } return TRUE; // return TRUE unless you set the focus to a control } void CTestCurveDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CTestCurveDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CTestCurveDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CTestCurveDlg::OnBtnAdd() { m_nCurveCount++; float fX = 100; float fY = 0; CString strTitle; strTitle.Format("TestOneCurve%d", m_nCurveCount); int index = m_pCurveCtrl->AddCurve(strTitle, g_crColours[m_nCurveCount % g_nColourCount].crColour); m_pCurveCtrl->GetCurve(index)->ShowCurve(); for (float f = 0.0f; f < 6.28f; f += 0.1f) { fX = f; fY = 100.0 * m_nCurveCount * (sin(f)); m_pCurveCtrl->AddData(strTitle, (m_nCurveCount) * fX, fY); } fX = 6.28f; fY = 100 * m_nCurveCount * float(sin(6.28)); m_pCurveCtrl->AddData(strTitle, (m_nCurveCount) * fX, fY); m_pCurveCtrl->Invalidate(); } void CTestCurveDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); CRect rect; GetWindowRect(rect); ScreenToClient(rect); CRect ctrrect; CWnd* pWnd = GetDlgItem(ID_BTN_ADD); if (pWnd) { pWnd->GetWindowRect(ctrrect); ScreenToClient(ctrrect); CRect newrect(rect.right - ctrrect.Width() - 10, rect.bottom - ctrrect.Height() - 40, rect.right - 10, rect.bottom - 40); pWnd->MoveWindow(newrect); } pWnd = GetDlgItem(IDOK); if (pWnd) { pWnd->GetWindowRect(ctrrect); ScreenToClient(ctrrect); CRect newrect(rect.right - ctrrect.Width() - 10, rect.bottom - ctrrect.Height() - 15, rect.right - 10, rect.bottom - 15); pWnd->MoveWindow(newrect); } pWnd = GetDlgItem(IDC_ADDDATA); if (pWnd) { pWnd->GetWindowRect(ctrrect); ScreenToClient(ctrrect); CRect newrect(rect.right - ctrrect.Width() - 10, rect.bottom - ctrrect.Height() - 65, rect.right - 10, rect.bottom - 65); pWnd->MoveWindow(newrect); } pWnd = GetDlgItem(IDC_COMBO1); if (pWnd) { pWnd->GetWindowRect(ctrrect); ScreenToClient(ctrrect); CRect newrect(rect.right - ctrrect.Width() - 10, ctrrect.top, rect.right - 10, ctrrect.bottom); pWnd->MoveWindow(newrect); } if (m_pCurveCtrl) { m_pCurveCtrl->GetWindowRect(ctrrect); ScreenToClient(ctrrect); CRect newrect(ctrrect.left, ctrrect.top, rect.right - 95, rect.bottom - 15); m_pCurveCtrl->MoveWindow(newrect); } Invalidate(); } void CTestCurveDlg::OnSelchangeCombo1() { UpdateData(); /* MoveRight MoveLeft CurveRight CurveLeft Restore ShowMark ShowCross EditCurve MovePageRight MovePageLeft ZoomOut ZoomIn MirrorHori MirrorVert */ switch (m_iListIndex) { case 0: m_pCurveCtrl->Move(FALSE); break; case 1: m_pCurveCtrl->Move(TRUE); break; case 2: m_pCurveCtrl->CurveRight(m_pCurveCtrl->GetCurve(0), 0.5); break; case 3: m_pCurveCtrl->CurveLeft(m_pCurveCtrl->GetCurve(0), 0.5); break; case 4: m_pCurveCtrl->Restore(); break; case 5: { if (!m_pCurveCtrl->GetCurveCount()) return; CCurve* pCur = m_pCurveCtrl->GetCurve(0); pCur->Select(!pCur->IsSelected()); m_pCurveCtrl->Invalidate(); } break; case 6: m_pCurveCtrl->ShowCross(!m_pCurveCtrl->IsShowCross()); break; case 7: { m_pCurveCtrl->EnableEdit(!m_pCurveCtrl->CanEditCurve()); } break; case 8: m_pCurveCtrl->MovePage(FALSE); break; case 9: m_pCurveCtrl->MovePage(TRUE); break; case 10: m_pCurveCtrl->Zoom(TRUE); break; case 11: m_pCurveCtrl->Zoom(FALSE); break; case 12: m_pCurveCtrl->MirrorHori(m_pCurveCtrl->GetCurve(0), 2.0f); break; case 13: m_pCurveCtrl->MirrorVert(m_pCurveCtrl->GetCurve(0), 5.0f); default: break; } } void CTestCurveDlg::OnAdddata() { static int nAdd = 0; float fX = 6.28f + 0.1f * nAdd++; float fY = 100 * float(sin(fX)); m_pCurveCtrl->AddData("TestOne Curve1", fX, fY); m_pCurveCtrl->Invalidate(); } void CTestCurveDlg::OnCurveMouseAdd(NMHDR *pNotifyStruct, LRESULT* pResult) { NM_CURVECTRL* pItem = (NM_CURVECTRL*)pNotifyStruct; CCurve* pCurve = (CCurve*)pItem->pCurve; CString str; str.Format("%s: index: %d, %.1f, %.1f", pCurve->GetCurveName(), pItem->iIndex, pItem->fHori, pItem->fVert); TRACE(str); } void CTestCurveDlg::OnCurveMouseModify(NMHDR *pNotifyStruct, LRESULT* pResult) { NM_CURVECTRL* pItem = (NM_CURVECTRL*)pNotifyStruct; CCurve* pCurve = (CCurve*)pItem->pCurve; CString str; str.Format("%s: index: %d, %.1f, %.1f", pCurve->GetCurveName(), pItem->iIndex, pItem->fHori, pItem->fVert); TRACE(str); } void CTestCurveDlg::OnCurveMouseDelete(NMHDR *pNotifyStruct, LRESULT* pResult) { NM_CURVECTRL* pItem = (NM_CURVECTRL*)pNotifyStruct; CCurve* pCurve = (CCurve*)pItem->pCurve; CString str; str.Format("%s: index: %d, %.1f, %.1f", pCurve->GetCurveName(), pItem->iIndex, pItem->fHori, pItem->fVert); TRACE(str); }