├── .gitattributes ├── .gitignore ├── CDataFuncDlg.cpp ├── CDataFuncDlg.h ├── CDelFuncDlg.cpp ├── CDelFuncDlg.h ├── CFuncDlg.cpp ├── CFuncDlg.h ├── CNormalFuncDlg.cpp ├── CNormalFuncDlg.h ├── CPolarFuncDlg.cpp ├── CPolarFuncDlg.h ├── CSetXYrangeDlg.cpp ├── CSetXYrangeDlg.h ├── CTwoFuncDlg.cpp ├── CTwoFuncDlg.h ├── CalculatorFunc.cpp ├── CalculatorFunc.h ├── FuncData.cpp ├── FuncData.h ├── LICENSE ├── MainFrm.cpp ├── MainFrm.h ├── README.md ├── Resource.h ├── framework.h ├── mfcplot.cpp ├── mfcplot.h ├── mfcplot.rc ├── mfcplot.sln ├── mfcplot.vcxproj ├── mfcplot.vcxproj.filters ├── mfcplotDoc.cpp ├── mfcplotDoc.h ├── mfcplotView.cpp ├── mfcplotView.h ├── pch.cpp ├── pch.h ├── res ├── Toolbar.bmp ├── icon1.ico ├── mfcplot.ico ├── mfcplot.rc2 └── mfcplotDoc.ico └── targetver.h /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | [Aa][Rr][Mm]/ 24 | [Aa][Rr][Mm]64/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015/2017 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # Visual Studio 2017 auto generated files 36 | Generated\ Files/ 37 | 38 | # MSTest test Results 39 | [Tt]est[Rr]esult*/ 40 | [Bb]uild[Ll]og.* 41 | 42 | # NUNIT 43 | *.VisualState.xml 44 | TestResult.xml 45 | 46 | # Build Results of an ATL Project 47 | [Dd]ebugPS/ 48 | [Rr]eleasePS/ 49 | dlldata.c 50 | 51 | # Benchmark Results 52 | BenchmarkDotNet.Artifacts/ 53 | 54 | # .NET Core 55 | project.lock.json 56 | project.fragment.lock.json 57 | artifacts/ 58 | 59 | # StyleCop 60 | StyleCopReport.xml 61 | 62 | # Files built by Visual Studio 63 | *_i.c 64 | *_p.c 65 | *_h.h 66 | *.ilk 67 | *.meta 68 | *.obj 69 | *.iobj 70 | *.pch 71 | *.pdb 72 | *.ipdb 73 | *.pgc 74 | *.pgd 75 | *.rsp 76 | *.sbr 77 | *.tlb 78 | *.tli 79 | *.tlh 80 | *.tmp 81 | *.tmp_proj 82 | *_wpftmp.csproj 83 | *.log 84 | *.vspscc 85 | *.vssscc 86 | .builds 87 | *.pidb 88 | *.svclog 89 | *.scc 90 | 91 | # Chutzpah Test files 92 | _Chutzpah* 93 | 94 | # Visual C++ cache files 95 | ipch/ 96 | *.aps 97 | *.ncb 98 | *.opendb 99 | *.opensdf 100 | *.sdf 101 | *.cachefile 102 | *.VC.db 103 | *.VC.VC.opendb 104 | 105 | # Visual Studio profiler 106 | *.psess 107 | *.vsp 108 | *.vspx 109 | *.sap 110 | 111 | # Visual Studio Trace Files 112 | *.e2e 113 | 114 | # TFS 2012 Local Workspace 115 | $tf/ 116 | 117 | # Guidance Automation Toolkit 118 | *.gpState 119 | 120 | # ReSharper is a .NET coding add-in 121 | _ReSharper*/ 122 | *.[Rr]e[Ss]harper 123 | *.DotSettings.user 124 | 125 | # JustCode is a .NET coding add-in 126 | .JustCode 127 | 128 | # TeamCity is a build add-in 129 | _TeamCity* 130 | 131 | # DotCover is a Code Coverage Tool 132 | *.dotCover 133 | 134 | # AxoCover is a Code Coverage Tool 135 | .axoCover/* 136 | !.axoCover/settings.json 137 | 138 | # Visual Studio code coverage results 139 | *.coverage 140 | *.coveragexml 141 | 142 | # NCrunch 143 | _NCrunch_* 144 | .*crunch*.local.xml 145 | nCrunchTemp_* 146 | 147 | # MightyMoose 148 | *.mm.* 149 | AutoTest.Net/ 150 | 151 | # Web workbench (sass) 152 | .sass-cache/ 153 | 154 | # Installshield output folder 155 | [Ee]xpress/ 156 | 157 | # DocProject is a documentation generator add-in 158 | DocProject/buildhelp/ 159 | DocProject/Help/*.HxT 160 | DocProject/Help/*.HxC 161 | DocProject/Help/*.hhc 162 | DocProject/Help/*.hhk 163 | DocProject/Help/*.hhp 164 | DocProject/Help/Html2 165 | DocProject/Help/html 166 | 167 | # Click-Once directory 168 | publish/ 169 | 170 | # Publish Web Output 171 | *.[Pp]ublish.xml 172 | *.azurePubxml 173 | # Note: Comment the next line if you want to checkin your web deploy settings, 174 | # but database connection strings (with potential passwords) will be unencrypted 175 | *.pubxml 176 | *.publishproj 177 | 178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 179 | # checkin your Azure Web App publish settings, but sensitive information contained 180 | # in these scripts will be unencrypted 181 | PublishScripts/ 182 | 183 | # NuGet Packages 184 | *.nupkg 185 | # The packages folder can be ignored because of Package Restore 186 | **/[Pp]ackages/* 187 | # except build/, which is used as an MSBuild target. 188 | !**/[Pp]ackages/build/ 189 | # Uncomment if necessary however generally it will be regenerated when needed 190 | #!**/[Pp]ackages/repositories.config 191 | # NuGet v3's project.json files produces more ignorable files 192 | *.nuget.props 193 | *.nuget.targets 194 | 195 | # Microsoft Azure Build Output 196 | csx/ 197 | *.build.csdef 198 | 199 | # Microsoft Azure Emulator 200 | ecf/ 201 | rcf/ 202 | 203 | # Windows Store app package directories and files 204 | AppPackages/ 205 | BundleArtifacts/ 206 | Package.StoreAssociation.xml 207 | _pkginfo.txt 208 | *.appx 209 | 210 | # Visual Studio cache files 211 | # files ending in .cache can be ignored 212 | *.[Cc]ache 213 | # but keep track of directories ending in .cache 214 | !?*.[Cc]ache/ 215 | 216 | # Others 217 | ClientBin/ 218 | ~$* 219 | *~ 220 | *.dbmdl 221 | *.dbproj.schemaview 222 | *.jfm 223 | *.pfx 224 | *.publishsettings 225 | orleans.codegen.cs 226 | 227 | # Including strong name files can present a security risk 228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 229 | #*.snk 230 | 231 | # Since there are multiple workflows, uncomment next line to ignore bower_components 232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 233 | #bower_components/ 234 | 235 | # RIA/Silverlight projects 236 | Generated_Code/ 237 | 238 | # Backup & report files from converting an old project file 239 | # to a newer Visual Studio version. Backup files are not needed, 240 | # because we have git ;-) 241 | _UpgradeReport_Files/ 242 | Backup*/ 243 | UpgradeLog*.XML 244 | UpgradeLog*.htm 245 | ServiceFabricBackup/ 246 | *.rptproj.bak 247 | 248 | # SQL Server files 249 | *.mdf 250 | *.ldf 251 | *.ndf 252 | 253 | # Business Intelligence projects 254 | *.rdl.data 255 | *.bim.layout 256 | *.bim_*.settings 257 | *.rptproj.rsuser 258 | *- Backup*.rdl 259 | 260 | # Microsoft Fakes 261 | FakesAssemblies/ 262 | 263 | # GhostDoc plugin setting file 264 | *.GhostDoc.xml 265 | 266 | # Node.js Tools for Visual Studio 267 | .ntvs_analysis.dat 268 | node_modules/ 269 | 270 | # Visual Studio 6 build log 271 | *.plg 272 | 273 | # Visual Studio 6 workspace options file 274 | *.opt 275 | 276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 277 | *.vbw 278 | 279 | # Visual Studio LightSwitch build output 280 | **/*.HTMLClient/GeneratedArtifacts 281 | **/*.DesktopClient/GeneratedArtifacts 282 | **/*.DesktopClient/ModelManifest.xml 283 | **/*.Server/GeneratedArtifacts 284 | **/*.Server/ModelManifest.xml 285 | _Pvt_Extensions 286 | 287 | # Paket dependency manager 288 | .paket/paket.exe 289 | paket-files/ 290 | 291 | # FAKE - F# Make 292 | .fake/ 293 | 294 | # JetBrains Rider 295 | .idea/ 296 | *.sln.iml 297 | 298 | # CodeRush personal settings 299 | .cr/personal 300 | 301 | # Python Tools for Visual Studio (PTVS) 302 | __pycache__/ 303 | *.pyc 304 | 305 | # Cake - Uncomment if you are using it 306 | # tools/** 307 | # !tools/packages.config 308 | 309 | # Tabs Studio 310 | *.tss 311 | 312 | # Telerik's JustMock configuration file 313 | *.jmconfig 314 | 315 | # BizTalk build output 316 | *.btp.cs 317 | *.btm.cs 318 | *.odx.cs 319 | *.xsd.cs 320 | 321 | # OpenCover UI analysis results 322 | OpenCover/ 323 | 324 | # Azure Stream Analytics local run output 325 | ASALocalRun/ 326 | 327 | # MSBuild Binary and Structured Log 328 | *.binlog 329 | 330 | # NVidia Nsight GPU debugger configuration file 331 | *.nvuser 332 | 333 | # MFractors (Xamarin productivity tool) working folder 334 | .mfractor/ 335 | 336 | # Local History for Visual Studio 337 | .localhistory/ 338 | 339 | # BeatPulse healthcheck temp database 340 | healthchecksdb -------------------------------------------------------------------------------- /CDataFuncDlg.cpp: -------------------------------------------------------------------------------- 1 | // CDataFuncDlg.cpp: 实现文件 2 | // 3 | 4 | #include "pch.h" 5 | #include "mfcplot.h" 6 | #include "CDataFuncDlg.h" 7 | #include "afxdialogex.h" 8 | 9 | 10 | // CDataFuncDlg 对话框 11 | 12 | IMPLEMENT_DYNAMIC(CDataFuncDlg, CDialogEx) 13 | 14 | CDataFuncDlg::CDataFuncDlg(CWnd* pParent /*=nullptr*/) 15 | : CDialogEx(IDD_DIALOG_DATAFUNC, pParent) 16 | , m_penWidth(1) 17 | , m_penType(0) 18 | { 19 | m_color = RGB(0, 0, 0); 20 | } 21 | 22 | CDataFuncDlg::~CDataFuncDlg() 23 | { 24 | } 25 | 26 | void CDataFuncDlg::DoDataExchange(CDataExchange* pDX) 27 | { 28 | CDialogEx::DoDataExchange(pDX); 29 | DDX_Text(pDX, IDC_EDIT1, m_penWidth); 30 | DDX_CBIndex(pDX, IDC_COMBO_LINETYPE, m_penType); 31 | } 32 | 33 | 34 | BEGIN_MESSAGE_MAP(CDataFuncDlg, CDialogEx) 35 | ON_BN_CLICKED(IDC_BUTTON_COLOR, &CDataFuncDlg::OnBnClickedButtonColor) 36 | ON_BN_CLICKED(IDC_BUTTON_READDATA, &CDataFuncDlg::OnBnClickedButtonReaddata) 37 | END_MESSAGE_MAP() 38 | 39 | 40 | // CDataFuncDlg 消息处理程序 41 | 42 | 43 | void CDataFuncDlg::OnBnClickedButtonColor() 44 | { 45 | // TODO: 在此添加控件通知处理程序代码 46 | CColorDialog dlg; 47 | if (dlg.DoModal() == IDOK) { 48 | m_color = dlg.GetColor(); 49 | } 50 | } 51 | 52 | 53 | void CDataFuncDlg::OnBnClickedButtonReaddata() 54 | { 55 | // TODO: 在此添加控件通知处理程序代码 56 | CString filter; 57 | filter = "文本文档(*.txt)|*.txt||"; 58 | CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter); 59 | if (dlg.DoModal() == IDOK) 60 | { 61 | CStdioFile file; 62 | file.Open(dlg.GetPathName(), CFile::modeRead); 63 | CString tmp; 64 | file.ReadString(tmp); 65 | int cnt = _ttoi(tmp); 66 | for (int i = 0; i < cnt; i++) { 67 | file.ReadString(tmp); 68 | int tmpx = _ttoi(tmp); 69 | vetX.emplace_back(tmpx); 70 | file.ReadString(tmp); 71 | int tmpy = _ttoi(tmp); 72 | vetY.emplace_back(tmpy); 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /CDataFuncDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | using std::vector; 4 | 5 | // CDataFuncDlg 对话框 6 | 7 | class CDataFuncDlg : public CDialogEx 8 | { 9 | DECLARE_DYNAMIC(CDataFuncDlg) 10 | 11 | public: 12 | CDataFuncDlg(CWnd* pParent = nullptr); // 标准构造函数 13 | virtual ~CDataFuncDlg(); 14 | 15 | // 对话框数据 16 | #ifdef AFX_DESIGN_TIME 17 | enum { IDD = IDD_DIALOG_DATAFUNC }; 18 | #endif 19 | 20 | protected: 21 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 22 | 23 | DECLARE_MESSAGE_MAP() 24 | public: 25 | int m_penWidth; 26 | int m_penType; 27 | COLORREF m_color; 28 | vector vetX, vetY; 29 | afx_msg void OnBnClickedButtonColor(); 30 | afx_msg void OnBnClickedButtonReaddata(); 31 | }; 32 | -------------------------------------------------------------------------------- /CDelFuncDlg.cpp: -------------------------------------------------------------------------------- 1 | // CDelFuncDlg.cpp: 实现文件 2 | // 3 | 4 | #include "pch.h" 5 | #include "mfcplot.h" 6 | #include "CDelFuncDlg.h" 7 | #include "afxdialogex.h" 8 | 9 | 10 | // CDelFuncDlg 对话框 11 | 12 | IMPLEMENT_DYNAMIC(CDelFuncDlg, CDialogEx) 13 | 14 | CDelFuncDlg::CDelFuncDlg(CWnd* pParent /*=nullptr*/) 15 | : CDialogEx(IDD_DIALOG_DEL, pParent) 16 | , m_id(0) 17 | { 18 | 19 | } 20 | 21 | CDelFuncDlg::~CDelFuncDlg() 22 | { 23 | } 24 | 25 | void CDelFuncDlg::DoDataExchange(CDataExchange* pDX) 26 | { 27 | CDialogEx::DoDataExchange(pDX); 28 | DDX_Text(pDX, IDC_EDIT1, m_id); 29 | } 30 | 31 | 32 | BEGIN_MESSAGE_MAP(CDelFuncDlg, CDialogEx) 33 | END_MESSAGE_MAP() 34 | 35 | 36 | // CDelFuncDlg 消息处理程序 37 | -------------------------------------------------------------------------------- /CDelFuncDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | // CDelFuncDlg 对话框 5 | 6 | class CDelFuncDlg : public CDialogEx 7 | { 8 | DECLARE_DYNAMIC(CDelFuncDlg) 9 | 10 | public: 11 | CDelFuncDlg(CWnd* pParent = nullptr); // 标准构造函数 12 | virtual ~CDelFuncDlg(); 13 | 14 | // 对话框数据 15 | #ifdef AFX_DESIGN_TIME 16 | enum { IDD = IDD_DIALOG_DEL }; 17 | #endif 18 | 19 | protected: 20 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 21 | 22 | DECLARE_MESSAGE_MAP() 23 | public: 24 | int m_id; 25 | }; 26 | -------------------------------------------------------------------------------- /CFuncDlg.cpp: -------------------------------------------------------------------------------- 1 | // CFuncDlg.cpp: 实现文件 2 | // 3 | 4 | #include "pch.h" 5 | #include "mfcplot.h" 6 | #include "CFuncDlg.h" 7 | #include "afxdialogex.h" 8 | 9 | 10 | // CFuncDlg 对话框 11 | 12 | IMPLEMENT_DYNAMIC(CFuncDlg, CDialogEx) 13 | 14 | CFuncDlg::CFuncDlg(int cas, CWnd* pParent /*=nullptr*/) 15 | : CDialogEx(IDD_NORMALFUNC_DIALOG, pParent) 16 | , m_strEquation(_T("")) 17 | { 18 | m_cas = cas; 19 | } 20 | 21 | CFuncDlg::~CFuncDlg() 22 | { 23 | } 24 | 25 | void CFuncDlg::DoDataExchange(CDataExchange* pDX) 26 | { 27 | CDialogEx::DoDataExchange(pDX); 28 | DDX_Text(pDX, IDC_EQUATION_EDIT, m_strEquation); 29 | } 30 | 31 | 32 | BEGIN_MESSAGE_MAP(CFuncDlg, CDialogEx) 33 | ON_BN_CLICKED(IDC_BUTTON_1, &CFuncDlg::OnBnClickedButton1) 34 | ON_BN_CLICKED(IDC_BUTTON_2, &CFuncDlg::OnBnClickedButton2) 35 | ON_BN_CLICKED(IDC_BUTTON_3, &CFuncDlg::OnBnClickedButton3) 36 | ON_BN_CLICKED(IDC_BUTTON_4, &CFuncDlg::OnBnClickedButton4) 37 | ON_BN_CLICKED(IDC_BUTTON_5, &CFuncDlg::OnBnClickedButton5) 38 | ON_BN_CLICKED(IDC_BUTTON_6, &CFuncDlg::OnBnClickedButton6) 39 | ON_BN_CLICKED(IDC_BUTTON_7, &CFuncDlg::OnBnClickedButton7) 40 | ON_BN_CLICKED(IDC_BUTTON_8, &CFuncDlg::OnBnClickedButton8) 41 | ON_BN_CLICKED(IDC_BUTTON_9, &CFuncDlg::OnBnClickedButton9) 42 | ON_BN_CLICKED(IDC_BUTTON_PI, &CFuncDlg::OnBnClickedButtonPi) 43 | ON_BN_CLICKED(IDC_BUTTON_10, &CFuncDlg::OnBnClickedButton10) 44 | ON_BN_CLICKED(IDC_BUTTON_E, &CFuncDlg::OnBnClickedButtonE) 45 | ON_BN_CLICKED(IDC_BUTTON_ADD, &CFuncDlg::OnBnClickedButtonAdd) 46 | ON_BN_CLICKED(IDC_BUTTON_DOT, &CFuncDlg::OnBnClickedButtonDot) 47 | ON_BN_CLICKED(IDC_BUTTON_DEC, &CFuncDlg::OnBnClickedButtonDec) 48 | ON_BN_CLICKED(IDC_BUTTON_MUL, &CFuncDlg::OnBnClickedButtonMul) 49 | ON_BN_CLICKED(IDC_BUTTON_DIV, &CFuncDlg::OnBnClickedButtonDiv) 50 | ON_BN_CLICKED(IDC_BUTTON_SIN, &CFuncDlg::OnBnClickedButtonSin) 51 | ON_BN_CLICKED(IDC_BUTTON_COS, &CFuncDlg::OnBnClickedButtonCos) 52 | ON_BN_CLICKED(IDC_BUTTON_TAN, &CFuncDlg::OnBnClickedButtonTan) 53 | ON_BN_CLICKED(IDC_BUTTON_LOG, &CFuncDlg::OnBnClickedButtonLog) 54 | ON_BN_CLICKED(IDC_BUTTON_POW, &CFuncDlg::OnBnClickedButtonPow) 55 | ON_BN_CLICKED(IDC_BUTTON_2POW, &CFuncDlg::OnBnClickedButton2pow) 56 | ON_BN_CLICKED(IDC_BUTTON_SQRT, &CFuncDlg::OnBnClickedButtonSqrt) 57 | ON_BN_CLICKED(IDC_BUTTON_LN, &CFuncDlg::OnBnClickedButtonLn) 58 | ON_BN_CLICKED(IDC_BUTTON_ABS, &CFuncDlg::OnBnClickedButtonAbs) 59 | ON_BN_CLICKED(IDC_BUTTON_X, &CFuncDlg::OnBnClickedButtonX) 60 | ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CFuncDlg::OnBnClickedButtonClear) 61 | ON_BN_CLICKED(IDC_BUTTON_DEL, &CFuncDlg::OnBnClickedButtonDel) 62 | ON_BN_CLICKED(IDC_BUTTON_LEFT, &CFuncDlg::OnBnClickedButtonLeft) 63 | ON_BN_CLICKED(IDC_BUTTON_RIGHT, &CFuncDlg::OnBnClickedButtonRight) 64 | ON_BN_CLICKED(IDC_BUTTON_FLOOR, &CFuncDlg::OnBnClickedButtonFloor) 65 | ON_BN_CLICKED(IDC_BUTTON_CEILING, &CFuncDlg::OnBnClickedButtonCeiling) 66 | ON_BN_CLICKED(IDC_BUTTON_ROUND, &CFuncDlg::OnBnClickedButtonRound) 67 | ON_BN_CLICKED(IDC_BUTTON_CUBIC, &CFuncDlg::OnBnClickedButtonCubic) 68 | END_MESSAGE_MAP() 69 | 70 | 71 | // CFuncDlg 消息处理程序 72 | 73 | 74 | void CFuncDlg::OnBnClickedButton1() 75 | { 76 | // TODO: 在此添加控件通知处理程序代码 77 | UpdateData(); 78 | m_strEquation += "1"; 79 | UpdateData(false); 80 | } 81 | 82 | 83 | void CFuncDlg::OnBnClickedButton2() 84 | { 85 | // TODO: 在此添加控件通知处理程序代码 86 | UpdateData(); 87 | m_strEquation += "2"; 88 | UpdateData(false); 89 | } 90 | 91 | 92 | void CFuncDlg::OnBnClickedButton3() 93 | { 94 | // TODO: 在此添加控件通知处理程序代码 95 | UpdateData(); 96 | m_strEquation += "3"; 97 | UpdateData(false); 98 | } 99 | 100 | 101 | 102 | void CFuncDlg::OnBnClickedButton4() 103 | { 104 | // TODO: 在此添加控件通知处理程序代码 105 | UpdateData(); 106 | m_strEquation += "4"; 107 | UpdateData(false); 108 | } 109 | 110 | 111 | 112 | void CFuncDlg::OnBnClickedButton5() 113 | { 114 | // TODO: 在此添加控件通知处理程序代码 115 | UpdateData(); 116 | m_strEquation += "5"; 117 | UpdateData(false); 118 | } 119 | 120 | 121 | void CFuncDlg::OnBnClickedButton6() 122 | { 123 | // TODO: 在此添加控件通知处理程序代码 124 | UpdateData(); 125 | m_strEquation += "6"; 126 | UpdateData(false); 127 | } 128 | 129 | 130 | void CFuncDlg::OnBnClickedButton7() 131 | { 132 | // TODO: 在此添加控件通知处理程序代码 133 | UpdateData(); 134 | m_strEquation += "7"; 135 | UpdateData(false); 136 | } 137 | 138 | 139 | 140 | void CFuncDlg::OnBnClickedButton8() 141 | { 142 | // TODO: 在此添加控件通知处理程序代码 143 | UpdateData(); 144 | m_strEquation += "8"; 145 | UpdateData(false); 146 | } 147 | 148 | 149 | void CFuncDlg::OnBnClickedButton9() 150 | { 151 | // TODO: 在此添加控件通知处理程序代码 152 | UpdateData(); 153 | m_strEquation += "9"; 154 | UpdateData(false); 155 | } 156 | 157 | 158 | void CFuncDlg::OnBnClickedButtonPi() 159 | { 160 | // TODO: 在此添加控件通知处理程序代码 161 | UpdateData(); 162 | m_strEquation += "p"; 163 | UpdateData(false); 164 | } 165 | 166 | 167 | 168 | 169 | void CFuncDlg::OnBnClickedButton10() 170 | { 171 | // TODO: 在此添加控件通知处理程序代码 172 | UpdateData(); 173 | m_strEquation += "0"; 174 | UpdateData(false); 175 | } 176 | 177 | 178 | void CFuncDlg::OnBnClickedButtonE() 179 | { 180 | // TODO: 在此添加控件通知处理程序代码 181 | UpdateData(); 182 | m_strEquation += "e"; 183 | UpdateData(false); 184 | } 185 | 186 | 187 | void CFuncDlg::OnBnClickedButtonAdd() 188 | { 189 | // TODO: 在此添加控件通知处理程序代码 190 | UpdateData(); 191 | m_strEquation += "+"; 192 | UpdateData(false); 193 | } 194 | 195 | 196 | 197 | 198 | void CFuncDlg::OnBnClickedButtonDot() 199 | { 200 | // TODO: 在此添加控件通知处理程序代码 201 | UpdateData(); 202 | m_strEquation += "."; 203 | UpdateData(false); 204 | } 205 | 206 | 207 | void CFuncDlg::OnBnClickedButtonDec() 208 | { 209 | // TODO: 在此添加控件通知处理程序代码 210 | UpdateData(); 211 | m_strEquation += "-"; 212 | UpdateData(false); 213 | } 214 | 215 | 216 | void CFuncDlg::OnBnClickedButtonMul() 217 | { 218 | // TODO: 在此添加控件通知处理程序代码 219 | UpdateData(); 220 | m_strEquation += "*"; 221 | UpdateData(false); 222 | } 223 | 224 | 225 | 226 | 227 | 228 | void CFuncDlg::OnBnClickedButtonDiv() 229 | { 230 | // TODO: 在此添加控件通知处理程序代码 231 | UpdateData(); 232 | m_strEquation += "/"; 233 | UpdateData(false); 234 | } 235 | 236 | 237 | 238 | void CFuncDlg::OnBnClickedButtonSin() 239 | { 240 | // TODO: 在此添加控件通知处理程序代码 241 | UpdateData(); 242 | m_strEquation += "sin("; 243 | UpdateData(false); 244 | } 245 | 246 | 247 | 248 | void CFuncDlg::OnBnClickedButtonCos() 249 | { 250 | // TODO: 在此添加控件通知处理程序代码 251 | UpdateData(); 252 | m_strEquation += "cos("; 253 | UpdateData(false); 254 | } 255 | 256 | 257 | void CFuncDlg::OnBnClickedButtonTan() 258 | { 259 | // TODO: 在此添加控件通知处理程序代码 260 | UpdateData(); 261 | m_strEquation += "tan("; 262 | UpdateData(false); 263 | } 264 | 265 | 266 | 267 | 268 | void CFuncDlg::OnBnClickedButtonLog() //以10为底 269 | { 270 | // TODO: 在此添加控件通知处理程序代码 271 | UpdateData(); 272 | m_strEquation += "lg("; 273 | UpdateData(false); 274 | } 275 | 276 | 277 | void CFuncDlg::OnBnClickedButtonPow() 278 | { 279 | // TODO: 在此添加控件通知处理程序代码 280 | UpdateData(); 281 | m_strEquation += "^"; 282 | UpdateData(false); 283 | } 284 | 285 | 286 | void CFuncDlg::OnBnClickedButton2pow() 287 | { 288 | // TODO: 在此添加控件通知处理程序代码 289 | UpdateData(); 290 | m_strEquation += "^2"; 291 | UpdateData(false); 292 | } 293 | 294 | 295 | 296 | 297 | void CFuncDlg::OnBnClickedButtonSqrt() 298 | { 299 | // TODO: 在此添加控件通知处理程序代码 300 | UpdateData(); 301 | m_strEquation += "sqrt("; 302 | UpdateData(false); 303 | } 304 | 305 | 306 | 307 | 308 | void CFuncDlg::OnBnClickedButtonLn() 309 | { 310 | // TODO: 在此添加控件通知处理程序代码 311 | UpdateData(); 312 | m_strEquation += "ln("; 313 | UpdateData(false); 314 | } 315 | 316 | 317 | 318 | void CFuncDlg::OnBnClickedButtonAbs() 319 | { 320 | // TODO: 在此添加控件通知处理程序代码 321 | UpdateData(); 322 | m_strEquation += "abs("; 323 | UpdateData(false); 324 | } 325 | 326 | 327 | void CFuncDlg::OnBnClickedButtonX() 328 | { 329 | // TODO: 在此添加控件通知处理程序代码 330 | UpdateData(); 331 | if (m_cas == 0) m_strEquation += "x"; 332 | else m_strEquation += 't'; 333 | UpdateData(false); 334 | } 335 | 336 | 337 | void CFuncDlg::OnBnClickedButtonClear() 338 | { 339 | // TODO: 在此添加控件通知处理程序代码 340 | UpdateData(); 341 | m_strEquation = ""; 342 | UpdateData(false); 343 | } 344 | 345 | 346 | void CFuncDlg::OnBnClickedButtonDel() 347 | { 348 | // TODO: 在此添加控件通知处理程序代码 349 | UpdateData(); 350 | int T = m_strEquation.GetLength(); 351 | if (T > 0) 352 | m_strEquation = m_strEquation.Left(T - 1); 353 | UpdateData(false); 354 | } 355 | 356 | 357 | 358 | void CFuncDlg::OnBnClickedButtonLeft() 359 | { 360 | // TODO: 在此添加控件通知处理程序代码 361 | UpdateData(); 362 | m_strEquation += "("; 363 | UpdateData(false); 364 | } 365 | 366 | 367 | 368 | 369 | void CFuncDlg::OnBnClickedButtonRight() 370 | { 371 | // TODO: 在此添加控件通知处理程序代码 372 | UpdateData(); 373 | m_strEquation += ")"; 374 | UpdateData(false); 375 | } 376 | 377 | 378 | 379 | void CFuncDlg::OnBnClickedButtonFloor() 380 | { 381 | // TODO: 在此添加控件通知处理程序代码 382 | UpdateData(); 383 | m_strEquation += "floor("; 384 | UpdateData(false); 385 | } 386 | 387 | 388 | void CFuncDlg::OnBnClickedButtonCeiling() 389 | { 390 | // TODO: 在此添加控件通知处理程序代码 391 | UpdateData(); 392 | m_strEquation += "ceil("; 393 | UpdateData(false); 394 | } 395 | 396 | 397 | void CFuncDlg::OnBnClickedButtonRound() 398 | { 399 | // TODO: 在此添加控件通知处理程序代码 400 | UpdateData(); 401 | m_strEquation += "round("; 402 | UpdateData(false); 403 | } 404 | 405 | 406 | void CFuncDlg::OnBnClickedButtonCubic() 407 | { 408 | // TODO: 在此添加控件通知处理程序代码 409 | UpdateData(); 410 | m_strEquation += "^3"; 411 | UpdateData(false); 412 | } 413 | -------------------------------------------------------------------------------- /CFuncDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | // CFuncDlg 对话框 5 | 6 | class CFuncDlg : public CDialogEx 7 | { 8 | DECLARE_DYNAMIC(CFuncDlg) 9 | 10 | public: 11 | CFuncDlg(int cas = 0,CWnd* pParent = nullptr); // 标准构造函数 12 | virtual ~CFuncDlg(); 13 | int m_cas; 14 | // 对话框数据 15 | #ifdef AFX_DESIGN_TIME 16 | enum { IDD = IDD_NORMALFUNC_DIALOG }; 17 | #endif 18 | 19 | protected: 20 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 21 | 22 | DECLARE_MESSAGE_MAP() 23 | public: 24 | CString m_strEquation; 25 | afx_msg void OnBnClickedButton1(); 26 | afx_msg void OnBnClickedButton2(); 27 | afx_msg void OnBnClickedButton3(); 28 | afx_msg void OnBnClickedButton4(); 29 | afx_msg void OnBnClickedButton5(); 30 | afx_msg void OnBnClickedButton6(); 31 | afx_msg void OnBnClickedButton7(); 32 | afx_msg void OnBnClickedButton8(); 33 | afx_msg void OnBnClickedButton9(); 34 | afx_msg void OnBnClickedButtonPi(); 35 | afx_msg void OnBnClickedButton10(); 36 | afx_msg void OnBnClickedButtonE(); 37 | afx_msg void OnBnClickedButtonAdd(); 38 | afx_msg void OnBnClickedButtonDot(); 39 | afx_msg void OnBnClickedButtonDec(); 40 | afx_msg void OnBnClickedButtonMul(); 41 | afx_msg void OnBnClickedButtonDiv(); 42 | afx_msg void OnBnClickedButtonSin(); 43 | afx_msg void OnBnClickedButtonCos(); 44 | afx_msg void OnBnClickedButtonTan(); 45 | afx_msg void OnBnClickedButtonLog(); 46 | afx_msg void OnBnClickedButtonPow(); 47 | afx_msg void OnBnClickedButton2pow(); 48 | afx_msg void OnBnClickedButtonSqrt(); 49 | afx_msg void OnBnClickedButtonLn(); 50 | afx_msg void OnBnClickedButtonAbs(); 51 | afx_msg void OnBnClickedButtonX(); 52 | afx_msg void OnBnClickedButtonClear(); 53 | afx_msg void OnBnClickedButtonDel(); 54 | afx_msg void OnBnClickedButtonLeft(); 55 | afx_msg void OnBnClickedButtonRight(); 56 | afx_msg void OnBnClickedButtonFloor(); 57 | afx_msg void OnBnClickedButtonCeiling(); 58 | afx_msg void OnBnClickedButtonRound(); 59 | afx_msg void OnBnClickedButtonCubic(); 60 | }; 61 | -------------------------------------------------------------------------------- /CNormalFuncDlg.cpp: -------------------------------------------------------------------------------- 1 | // CNormalFuncDlg.cpp: 实现文件 2 | // 3 | 4 | #include "pch.h" 5 | #include "mfcplot.h" 6 | #include "CNormalFuncDlg.h" 7 | #include "afxdialogex.h" 8 | #include "CFuncDlg.h" 9 | 10 | 11 | // CNormalFuncDlg 对话框 12 | 13 | IMPLEMENT_DYNAMIC(CNormalFuncDlg, CDialogEx) 14 | 15 | CNormalFuncDlg::CNormalFuncDlg(int Xmin, int Xmax, CWnd* pParent /*=nullptr*/) 16 | : CDialogEx(IDD_DIALOG_NORMALFUNC, pParent) 17 | , m_sEquation(_T("")) 18 | , m_Xmin(Xmin) 19 | , m_Xmax(Xmax) 20 | , m_stepX(1000) 21 | , m_penWidth(1) 22 | , m_penType(0) 23 | { 24 | m_color = RGB(0, 0, 0); 25 | m_penType = PS_SOLID; 26 | } 27 | 28 | CNormalFuncDlg::~CNormalFuncDlg() 29 | { 30 | } 31 | 32 | void CNormalFuncDlg::DoDataExchange(CDataExchange* pDX) 33 | { 34 | CDialogEx::DoDataExchange(pDX); 35 | DDX_Text(pDX, IDC_EDIT_FUNC, m_sEquation); 36 | DDX_Text(pDX, IDC_EDIT2, m_Xmin); 37 | DDX_Text(pDX, IDC_EDIT3, m_Xmax); 38 | DDX_Text(pDX, IDC_EDIT4, m_stepX); 39 | DDX_Text(pDX, IDC_EDIT1, m_penWidth); 40 | DDX_CBIndex(pDX, IDC_COMBO_LINETYPE, m_penType); 41 | } 42 | 43 | 44 | BEGIN_MESSAGE_MAP(CNormalFuncDlg, CDialogEx) 45 | ON_BN_CLICKED(IDC_BUTTON_SETFUNC, &CNormalFuncDlg::OnBnClickedButtonSetfunc) 46 | ON_BN_CLICKED(IDC_BUTTON_COLOR, &CNormalFuncDlg::OnBnClickedButtonColor) 47 | END_MESSAGE_MAP() 48 | 49 | 50 | // CNormalFuncDlg 消息处理程序 51 | 52 | 53 | void CNormalFuncDlg::OnBnClickedButtonSetfunc() 54 | { 55 | // TODO: 在此添加控件通知处理程序代码 56 | UpdateData(); 57 | CFuncDlg dlg; 58 | if (dlg.DoModal() == IDOK) { 59 | m_sEquation = dlg.m_strEquation; 60 | } 61 | UpdateData(false); 62 | } 63 | 64 | 65 | void CNormalFuncDlg::OnBnClickedButtonColor() 66 | { 67 | // TODO: 在此添加控件通知处理程序代码 68 | CColorDialog dlg; 69 | if (dlg.DoModal() == IDOK) { 70 | m_color = dlg.GetColor(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /CNormalFuncDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | // CNormalFuncDlg 对话框 5 | 6 | class CNormalFuncDlg : public CDialogEx 7 | { 8 | DECLARE_DYNAMIC(CNormalFuncDlg) 9 | 10 | public: 11 | CNormalFuncDlg(int Xmin,int Xmax, CWnd* pParent = nullptr); // 标准构造函数 12 | virtual ~CNormalFuncDlg(); 13 | 14 | // 对话框数据 15 | #ifdef AFX_DESIGN_TIME 16 | enum { IDD = IDD_DIALOG_NORMALFUNC }; 17 | #endif 18 | 19 | protected: 20 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 21 | 22 | DECLARE_MESSAGE_MAP() 23 | public: 24 | CString m_sEquation; 25 | double m_Xmin; 26 | double m_Xmax; 27 | int m_stepX; 28 | COLORREF m_color; 29 | afx_msg void OnBnClickedButtonSetfunc(); 30 | afx_msg void OnBnClickedButtonColor(); 31 | int m_penWidth; 32 | int m_penType; 33 | }; 34 | -------------------------------------------------------------------------------- /CPolarFuncDlg.cpp: -------------------------------------------------------------------------------- 1 | // CPolarFuncDlg.cpp: 实现文件 2 | // 3 | 4 | #include "pch.h" 5 | #include "mfcplot.h" 6 | #include "CPolarFuncDlg.h" 7 | #include "afxdialogex.h" 8 | #include "CFuncDlg.h" 9 | 10 | 11 | // CPolarFuncDlg 对话框 12 | 13 | IMPLEMENT_DYNAMIC(CPolarFuncDlg, CDialogEx) 14 | 15 | CPolarFuncDlg::CPolarFuncDlg(CWnd* pParent /*=nullptr*/) 16 | : CDialogEx(IDD_DIALOG_POLARFUNC, pParent) 17 | , m_sEquation(_T("")) 18 | , m_Thetamin(-3.14) 19 | , m_Thetamax(3.14) 20 | , m_StepTheta(1000) 21 | , m_penWidth(1) 22 | , m_penType(0) 23 | { 24 | m_color = RGB(0, 0, 0); 25 | } 26 | 27 | CPolarFuncDlg::~CPolarFuncDlg() 28 | { 29 | } 30 | 31 | void CPolarFuncDlg::DoDataExchange(CDataExchange* pDX) 32 | { 33 | CDialogEx::DoDataExchange(pDX); 34 | DDX_Text(pDX, IDC_EDIT_FUNC, m_sEquation); 35 | DDX_Text(pDX, IDC_EDIT2, m_Thetamin); 36 | DDX_Text(pDX, IDC_EDIT3, m_Thetamax); 37 | DDX_Text(pDX, IDC_EDIT4, m_StepTheta); 38 | DDX_Text(pDX, IDC_EDIT1, m_penWidth); 39 | DDX_CBIndex(pDX, IDC_COMBO_LINETYPE, m_penType); 40 | } 41 | 42 | 43 | BEGIN_MESSAGE_MAP(CPolarFuncDlg, CDialogEx) 44 | ON_BN_CLICKED(IDC_BUTTON_COLOR, &CPolarFuncDlg::OnBnClickedButtonColor) 45 | ON_BN_CLICKED(IDC_BUTTON_SETFUNC, &CPolarFuncDlg::OnBnClickedButtonSetfunc) 46 | END_MESSAGE_MAP() 47 | 48 | 49 | // CPolarFuncDlg 消息处理程序 50 | 51 | 52 | void CPolarFuncDlg::OnBnClickedButtonColor() 53 | { 54 | // TODO: 在此添加控件通知处理程序代码 55 | CColorDialog dlg; 56 | if (dlg.DoModal() == IDOK) { 57 | m_color = dlg.GetColor(); 58 | } 59 | } 60 | 61 | 62 | void CPolarFuncDlg::OnBnClickedButtonSetfunc() 63 | { 64 | // TODO: 在此添加控件通知处理程序代码 65 | UpdateData(); 66 | CFuncDlg dlg(1); 67 | if (dlg.DoModal()) { 68 | m_sEquation = dlg.m_strEquation; 69 | } 70 | UpdateData(false); 71 | } 72 | -------------------------------------------------------------------------------- /CPolarFuncDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | // CPolarFuncDlg 对话框 5 | 6 | class CPolarFuncDlg : public CDialogEx 7 | { 8 | DECLARE_DYNAMIC(CPolarFuncDlg) 9 | 10 | public: 11 | CPolarFuncDlg(CWnd* pParent = nullptr); // 标准构造函数 12 | virtual ~CPolarFuncDlg(); 13 | 14 | // 对话框数据 15 | #ifdef AFX_DESIGN_TIME 16 | enum { IDD = IDD_DIALOG_POLARFUNC }; 17 | #endif 18 | 19 | protected: 20 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 21 | 22 | DECLARE_MESSAGE_MAP() 23 | public: 24 | CString m_sEquation; 25 | double m_Thetamin; 26 | double m_Thetamax; 27 | int m_StepTheta; 28 | int m_penWidth; 29 | COLORREF m_color; 30 | int m_penType; 31 | afx_msg void OnBnClickedButtonColor(); 32 | afx_msg void OnBnClickedButtonSetfunc(); 33 | }; 34 | -------------------------------------------------------------------------------- /CSetXYrangeDlg.cpp: -------------------------------------------------------------------------------- 1 | // CSetXYrangeDlg.cpp: 实现文件 2 | // 3 | 4 | #include "pch.h" 5 | #include "mfcplot.h" 6 | #include "CSetXYrangeDlg.h" 7 | #include "afxdialogex.h" 8 | 9 | 10 | // CSetXYrangeDlg 对话框 11 | 12 | IMPLEMENT_DYNAMIC(CSetXYrangeDlg, CDialogEx) 13 | 14 | CSetXYrangeDlg::CSetXYrangeDlg(double Xmin, double Xmax, double Ymin, double Ymax, CWnd* pParent /*=nullptr*/) 15 | : CDialogEx(IDD_DIALOG_SET_RANGE, pParent) 16 | , m_Xmin(Xmin) 17 | , m_Xmax(Xmax) 18 | , m_Ymin(Ymin) 19 | , m_Ymax(Ymax) 20 | { 21 | 22 | } 23 | 24 | CSetXYrangeDlg::~CSetXYrangeDlg() 25 | { 26 | } 27 | 28 | void CSetXYrangeDlg::DoDataExchange(CDataExchange* pDX) 29 | { 30 | CDialogEx::DoDataExchange(pDX); 31 | DDX_Text(pDX, IDC_EDIT5, m_Xmin); 32 | DDX_Text(pDX, IDC_EDIT1, m_Xmax); 33 | DDX_Text(pDX, IDC_EDIT6, m_Ymin); 34 | DDX_Text(pDX, IDC_EDIT7, m_Ymax); 35 | } 36 | 37 | 38 | BEGIN_MESSAGE_MAP(CSetXYrangeDlg, CDialogEx) 39 | END_MESSAGE_MAP() 40 | 41 | 42 | // CSetXYrangeDlg 消息处理程序 43 | -------------------------------------------------------------------------------- /CSetXYrangeDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | // CSetXYrangeDlg 对话框 5 | 6 | class CSetXYrangeDlg : public CDialogEx 7 | { 8 | DECLARE_DYNAMIC(CSetXYrangeDlg) 9 | 10 | public: 11 | CSetXYrangeDlg(double Xmin, double Xmax, double Ymin, double Ymax, CWnd* pParent = nullptr); // 标准构造函数 12 | virtual ~CSetXYrangeDlg(); 13 | 14 | // 对话框数据 15 | #ifdef AFX_DESIGN_TIME 16 | enum { IDD = IDD_DIALOG_SET_RANGE }; 17 | #endif 18 | 19 | protected: 20 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 21 | 22 | DECLARE_MESSAGE_MAP() 23 | public: 24 | double m_Xmin; 25 | double m_Xmax; 26 | double m_Ymin; 27 | double m_Ymax; 28 | }; 29 | -------------------------------------------------------------------------------- /CTwoFuncDlg.cpp: -------------------------------------------------------------------------------- 1 | // CTwoFuncDlg.cpp: 实现文件 2 | // 3 | 4 | #include "pch.h" 5 | #include "mfcplot.h" 6 | #include "CTwoFuncDlg.h" 7 | #include "afxdialogex.h" 8 | #include "CFuncDlg.h" 9 | 10 | 11 | // CTwoFuncDlg 对话框 12 | 13 | IMPLEMENT_DYNAMIC(CTwoFuncDlg, CDialogEx) 14 | 15 | CTwoFuncDlg::CTwoFuncDlg(CWnd* pParent /*=nullptr*/) 16 | : CDialogEx(IDD_DIALOG_TWOFUNC, pParent) 17 | , m_sEquationX(_T("")) 18 | , m_sEquationY(_T("")) 19 | , m_Tmin(0) 20 | , m_Tmax(10) 21 | , m_stepT(1000) 22 | , m_penWidth(1) 23 | { 24 | m_color = RGB(0, 0, 0); 25 | } 26 | 27 | CTwoFuncDlg::~CTwoFuncDlg() 28 | { 29 | } 30 | 31 | void CTwoFuncDlg::DoDataExchange(CDataExchange* pDX) 32 | { 33 | CDialogEx::DoDataExchange(pDX); 34 | DDX_Text(pDX, IDC_EDIT_FUNC, m_sEquationX); 35 | DDX_Text(pDX, IDC_EDIT_FUNC2, m_sEquationY); 36 | DDX_Text(pDX, IDC_EDIT2, m_Tmin); 37 | DDX_Text(pDX, IDC_EDIT3, m_Tmax); 38 | DDX_Text(pDX, IDC_EDIT4, m_stepT); 39 | DDX_CBIndex(pDX, IDC_COMBO_LINETYPE, m_penType); 40 | DDX_Text(pDX, IDC_EDIT1, m_penWidth); 41 | } 42 | 43 | 44 | BEGIN_MESSAGE_MAP(CTwoFuncDlg, CDialogEx) 45 | ON_BN_CLICKED(IDC_BUTTON_SETFUNC, &CTwoFuncDlg::OnBnClickedButtonSetfunc) 46 | ON_BN_CLICKED(IDC_BUTTON_SETFUNC2, &CTwoFuncDlg::OnBnClickedButtonSetfunc2) 47 | ON_BN_CLICKED(IDC_BUTTON_COLOR, &CTwoFuncDlg::OnBnClickedButtonColor) 48 | END_MESSAGE_MAP() 49 | 50 | 51 | // CTwoFuncDlg 消息处理程序 52 | 53 | 54 | void CTwoFuncDlg::OnBnClickedButtonSetfunc() 55 | { 56 | // TODO: 在此添加控件通知处理程序代码 57 | UpdateData(); 58 | CFuncDlg dlg(1); 59 | if (dlg.DoModal() == IDOK) { 60 | m_sEquationX = dlg.m_strEquation; 61 | } 62 | UpdateData(false); 63 | 64 | } 65 | 66 | 67 | void CTwoFuncDlg::OnBnClickedButtonSetfunc2() 68 | { 69 | // TODO: 在此添加控件通知处理程序代码 70 | UpdateData(); 71 | CFuncDlg dlg(1); 72 | if (dlg.DoModal() == IDOK) { 73 | m_sEquationY = dlg.m_strEquation; 74 | } 75 | UpdateData(false); 76 | } 77 | 78 | 79 | 80 | void CTwoFuncDlg::OnBnClickedButtonColor() 81 | { 82 | // TODO: 在此添加控件通知处理程序代码 83 | CColorDialog dlg; 84 | if (dlg.DoModal() == IDOK) { 85 | m_color = dlg.GetColor(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /CTwoFuncDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | // CTwoFuncDlg 对话框 5 | 6 | class CTwoFuncDlg : public CDialogEx 7 | { 8 | DECLARE_DYNAMIC(CTwoFuncDlg) 9 | 10 | public: 11 | CTwoFuncDlg(CWnd* pParent = nullptr); // 标准构造函数 12 | virtual ~CTwoFuncDlg(); 13 | 14 | // 对话框数据 15 | #ifdef AFX_DESIGN_TIME 16 | enum { IDD = IDD_DIALOG_TWOFUNC }; 17 | #endif 18 | 19 | protected: 20 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 21 | 22 | DECLARE_MESSAGE_MAP() 23 | public: 24 | CString m_sEquationX; 25 | CString m_sEquationY; 26 | double m_Tmin; 27 | double m_Tmax; 28 | int m_stepT; 29 | int m_penType; 30 | int m_penWidth; 31 | COLORREF m_color; 32 | afx_msg void OnBnClickedButtonSetfunc(); 33 | afx_msg void OnBnClickedButtonSetfunc2(); 34 | afx_msg void OnBnClickedButtonColor(); 35 | }; 36 | -------------------------------------------------------------------------------- /CalculatorFunc.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wineee/mfcplot/4f081ca7d0121d4e1011eda4178e99c4f8d24794/CalculatorFunc.cpp -------------------------------------------------------------------------------- /CalculatorFunc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | bool IsNum(char c); 4 | bool IsOpt(char c); 5 | int cPriority(char c); 6 | double Calc(double num1, char opt, double num2); 7 | double GetNum(CString& Eq, int& i, char xKey = 'x', double xVal = 0); 8 | double CalcEquation(CString m_sEquation, bool& succ, char xKey = 'x', double xVal = 0); 9 | double Get_Equation_Num(CString& Eq, int& i, bool& succ, char xKey = 'x', double xVal = 0); 10 | 11 | -------------------------------------------------------------------------------- /FuncData.cpp: -------------------------------------------------------------------------------- 1 | // FuncData.cpp: 实现文件 2 | // 3 | 4 | #include "pch.h" 5 | #include "mfcplot.h" 6 | #include "FuncData.h" 7 | #include "CalculatorFunc.h" 8 | 9 | const double inf = 1e14; 10 | inline double Pow2(double x) { return x * x; } 11 | 12 | FuncData::FuncData() 13 | { 14 | minX = maxX = stepX = 0; 15 | maxY = minY = 0; 16 | m_penType = PS_SOLID; 17 | m_penWidth = 1; 18 | m_color = RGB(0, 0, 0); 19 | } 20 | 21 | FuncData::~FuncData() 22 | { 23 | } 24 | 25 | FuncData::FuncData(CString Equation, double min_X, double max_X, int step_X, COLORREF color, int penWidth, int penType) : 26 | m_Equation(Equation), minX(min_X), maxX(max_X), stepX(step_X), m_color(color), m_penWidth(penWidth),m_penType(penType) 27 | { 28 | maxY = minY = 0; 29 | } 30 | 31 | // FuncData 成员函数 32 | 33 | bool FuncData::GetNearest(pair NowPoint, pair &CmpPoint) { 34 | if (NowPoint.first < minX || NowPoint.second > maxX) return false; 35 | double detx = (maxX - minX) / stepX; 36 | bool ok = false; 37 | for (auto dot : vetPoint) 38 | if (abs(dot.first - NowPoint.first) <= detx+0.1) 39 | if (Pow2(dot.first - NowPoint.first) + Pow2(dot.second - NowPoint.second) < \ 40 | Pow2(NowPoint.first - CmpPoint.first) + Pow2(NowPoint.second - CmpPoint.second)) { 41 | CmpPoint = dot; 42 | ok = true; 43 | } 44 | return ok; 45 | } 46 | 47 | CString FuncData::GetEquation2() { 48 | return _T("NULL"); 49 | } 50 | 51 | 52 | 53 | IMPLEMENT_SERIAL(NormalFD, FuncData, 0) 54 | IMPLEMENT_SERIAL(PolarFD, FuncData, 0) 55 | IMPLEMENT_SERIAL(TwoFD, FuncData, 0) 56 | IMPLEMENT_SERIAL(DataFD, FuncData, 0) 57 | 58 | NormalFD::NormalFD() 59 | { 60 | FuncCas = CAS_NORMAL; 61 | } 62 | 63 | NormalFD::NormalFD(CString Equation, double min_X, double max_X, int step_X, COLORREF color, int penWidth, int penType) : 64 | FuncData(Equation, min_X, max_X, step_X, color, penWidth, penType) 65 | { 66 | FuncCas = CAS_NORMAL; 67 | } 68 | 69 | double NormalFD::GetY(double xVal, bool& succ) 70 | { 71 | return CalcEquation(m_Equation, succ, 'x', xVal); 72 | } 73 | 74 | bool NormalFD::CalcList() 75 | { 76 | vetPoint.clear(); 77 | double detx = (maxX - minX) / stepX; 78 | bool succ = true; 79 | minY = inf; maxY = -inf; 80 | for (double tmp_x = minX; tmp_x <= maxX; tmp_x += detx) { 81 | double tmp_y = this->GetY(tmp_x, succ); 82 | if (tmp_y > maxY) maxY = tmp_y; 83 | if (tmp_y < minY) minY = tmp_y; 84 | vetPoint.emplace_back(std::make_pair(tmp_x, tmp_y)); 85 | if (!succ) return false; 86 | } 87 | return true; 88 | } 89 | 90 | bool NormalFD::GetNearest(pair NowPoint, pair &CmpPoint) 91 | { 92 | if (NowPoint.first < minX || NowPoint.second > maxX) return false; 93 | bool succ; 94 | double nY = GetY(NowPoint.first,succ); 95 | if (Pow2(nY - NowPoint.second) < Pow2(NowPoint.first - CmpPoint.first) + Pow2(NowPoint.second - CmpPoint.second)) { 96 | CmpPoint = std::make_pair(NowPoint.first, nY); 97 | return true; 98 | } 99 | return false; 100 | } 101 | 102 | void NormalFD::Serialize(CArchive& ar) { 103 | if (ar.IsStoring()) { 104 | ar << FuncCas << m_Equation << minX << maxX << maxY << minY << stepX << m_penWidth << m_penType << m_color; 105 | } 106 | else { 107 | ar >> FuncCas >> m_Equation >> minX >> maxX >> maxY >> minY >> stepX >> m_penWidth >> m_penType >> m_color; 108 | this->CalcList(); 109 | } 110 | } 111 | 112 | 113 | PolarFD::PolarFD() 114 | { 115 | FuncCas = CAS_POLAR; 116 | } 117 | 118 | PolarFD::PolarFD(CString Equation, double min_T, double max_T, int step_T, COLORREF color, int penWidth, int penType) : 119 | FuncData(Equation, inf, -inf, step_T, color, penWidth, penType) 120 | { 121 | FuncCas = CAS_POLAR; 122 | maxth = max_T; 123 | minth = min_T; 124 | } 125 | 126 | 127 | double PolarFD::GetY(double thVal, bool& succ) 128 | { 129 | return CalcEquation(m_Equation, succ, 't', thVal); 130 | } 131 | 132 | bool PolarFD::CalcList() 133 | { 134 | vetPoint.clear(); 135 | double detth = (maxth - minth) / stepX; 136 | bool succ = true; 137 | minY = inf; maxY = -inf; 138 | for (double tmp_th = minth; tmp_th <= maxth; tmp_th += detth) { 139 | double tmp_r = this->GetY(tmp_th, succ); 140 | double tmp_x = tmp_r * cos(tmp_th); 141 | double tmp_y = tmp_r * sin(tmp_th); 142 | if (tmp_x > maxX) maxX = tmp_x; 143 | if (tmp_x < minX) minX = tmp_x; 144 | if (tmp_y > maxY) maxY = tmp_y; 145 | if (tmp_y < minY) minY = tmp_y; 146 | vetPoint.emplace_back(std::make_pair(tmp_x, tmp_y)); 147 | if (!succ) return false; 148 | } 149 | return true; 150 | } 151 | 152 | 153 | void PolarFD::Serialize(CArchive& ar) { 154 | if (ar.IsStoring()) { 155 | ar << FuncCas << m_Equation << minX << maxX << maxY << minY << stepX << m_penWidth << m_penType << m_color\ 156 | << minth << maxth; 157 | } 158 | else { 159 | ar >> FuncCas >> m_Equation >> minX >> maxX >> maxY >> minY >> stepX >> m_penWidth >> m_penType >> m_color\ 160 | >> minth >> maxth; 161 | this->CalcList(); 162 | } 163 | } 164 | 165 | TwoFD::TwoFD() 166 | { 167 | FuncCas = CAS_TWO; 168 | 169 | } 170 | 171 | TwoFD::TwoFD(CString Equation_X, CString Equation_Y, double min_T, double max_T, int step_T, COLORREF color, int penWidth, int penType) : 172 | FuncData(Equation_X, inf, -inf, step_T, color, penWidth, penType) 173 | { 174 | m_EquationY = Equation_Y; 175 | maxT = max_T; 176 | minT = min_T; 177 | FuncCas = CAS_TWO; 178 | } 179 | 180 | double TwoFD::GetX(double tVal, bool& succ) 181 | { 182 | return CalcEquation(m_Equation, succ, 't', tVal); 183 | } 184 | 185 | 186 | double TwoFD::GetY(double tVal, bool& succ) 187 | { 188 | return CalcEquation(m_EquationY, succ, 't', tVal); 189 | } 190 | 191 | bool TwoFD::CalcList() 192 | { 193 | vetPoint.clear(); 194 | double detT = (maxT - minT) / stepX; 195 | bool succ = true; 196 | minY = inf; maxY = -inf; 197 | for (double tmp_T = minT; tmp_T <= maxT; tmp_T += detT) { 198 | double tmp_x = this->GetX(tmp_T, succ); 199 | double tmp_y = this->GetY(tmp_T, succ); 200 | if (tmp_y > maxY) maxY = tmp_y; 201 | if (tmp_y < minY) minY = tmp_y; 202 | if (tmp_x > maxX) maxX = tmp_x; 203 | if (tmp_x < minX) minX = tmp_x; 204 | vetPoint.emplace_back(std::make_pair(tmp_x, tmp_y)); 205 | if (!succ) return false; 206 | } 207 | return true; 208 | } 209 | 210 | CString TwoFD::GetEquation2() { 211 | return m_EquationY; 212 | } 213 | 214 | void TwoFD::Serialize(CArchive& ar) { 215 | if (ar.IsStoring()) { 216 | ar << FuncCas << m_Equation << minX << maxX << maxY << minY << stepX << m_penWidth << m_penType << m_color \ 217 | << minT << maxT << m_EquationY; 218 | } 219 | else { 220 | ar >> FuncCas >> m_Equation >> minX >> maxX >> maxY >> minY >> stepX >> m_penWidth >> m_penType >> m_color\ 221 | >> minT >> maxT >> m_EquationY; 222 | this->CalcList(); 223 | } 224 | } 225 | 226 | int DataFD::DataFD_Cnt = 0; 227 | 228 | DataFD::DataFD() 229 | { 230 | FuncCas = CAS_DATA; 231 | } 232 | 233 | DataFD::DataFD(vector &vetX, vector &vetY, COLORREF color, int penWidth, int penType) 234 | { 235 | minY = inf; maxY = -inf; 236 | minX = inf; maxY = -inf; 237 | for (int i = 0; i < vetX.size(); i++) { 238 | if (vetY[i] > maxY) maxY = vetY[i]; 239 | if (vetY[i] < minY) minY = vetY[i]; 240 | if (vetX[i] > maxX) maxX = vetX[i]; 241 | if (vetX[i] < minX) minX = vetX[i]; 242 | vetPoint.emplace_back(std::make_pair(vetX[i], vetY[i])); 243 | } 244 | stepX = -1; 245 | m_color = color; 246 | m_penType = penType; 247 | m_penWidth = penWidth; 248 | DataFD_Cnt++; 249 | FuncCas = CAS_DATA; 250 | m_Equation = _T("DataFunc"); 251 | for (int i = 0; i < DataFD_Cnt; i++) 252 | m_Equation += _T("I"); 253 | } 254 | 255 | bool DataFD::CalcList() { 256 | return true; 257 | } 258 | 259 | double DataFD::GetY(double xVal, bool& succ) { 260 | for (auto dot : vetPoint) 261 | if (dot.first == xVal) 262 | return dot.second; 263 | return inf; 264 | } 265 | 266 | void DataFD::Serialize(CArchive& ar) { 267 | if (ar.IsStoring()) { 268 | ar << FuncCas << m_Equation << minX << maxX << maxY << minY << m_penWidth << m_penType << m_color; 269 | int n = vetPoint.size(); 270 | ar << n; 271 | for (int i = 0; i < n; i++) 272 | ar << vetPoint[i].first << vetPoint[i].second; 273 | } 274 | else { 275 | ar >> FuncCas >> m_Equation >> minX >> maxX >> maxY >> minY >> m_penWidth >> m_penType >> m_color; 276 | int n; 277 | ar >> n; 278 | for (int i = 0; i < n; i++) { 279 | double tmpX, tmpY; 280 | ar >> tmpX >> tmpY; 281 | vetPoint.push_back(std::make_pair(tmpX, tmpY)); 282 | } 283 | } 284 | } -------------------------------------------------------------------------------- /FuncData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | using std::pair; 5 | using std::vector; 6 | // FuncData 命令目标 7 | 8 | #define CAS_NORMAL 1 9 | #define CAS_POLAR 2 10 | #define CAS_TWO 3 11 | #define CAS_DATA 4 12 | 13 | class FuncData : public CObject 14 | { 15 | // DECLARE_SERIAL(FuncData) 16 | public: 17 | int FuncCas; //函数类型 18 | CString m_Equation; //函数表达式 19 | double minX, maxX; //x极值 20 | double maxY, minY; //y极值 21 | int stepX; //可以理解为样本点的数量 22 | int m_penWidth; //画笔宽度 23 | int m_penType; //画笔类型 24 | COLORREF m_color; //画笔颜色 25 | vector > vetPoint; //储存所有样本点 26 | virtual double GetY(double xVal, bool& succ) = 0;//得到未知数为xVal时函数值,succ表示计算是否成功 27 | virtual bool CalcList() = 0; //计算vetPoint 28 | virtual bool GetNearest(pair NowPoint, pair &CmpPoint);//获取本函数与NowPoint最近的点 29 | virtual CString GetEquation2(); //为了得到参数方程第二个函数式 30 | FuncData(); 31 | FuncData(CString Equation,double minX,double maxX,int stepX,COLORREF color, int penWidth,int penType);//构造函数 32 | virtual ~FuncData(); 33 | }; 34 | 35 | 36 | class NormalFD : public FuncData 37 | { 38 | DECLARE_SERIAL(NormalFD) 39 | public: 40 | virtual double GetY(double xVal, bool& succ); 41 | virtual bool CalcList(); 42 | virtual bool GetNearest(pair NowPoint, pair &CmpPoint); 43 | virtual void Serialize(CArchive& ar); 44 | NormalFD(); 45 | NormalFD(CString Equation, double minX, double maxX, int stepX, COLORREF color, int penWidth,int penType); 46 | 47 | }; 48 | 49 | class PolarFD : public FuncData 50 | { 51 | DECLARE_SERIAL(PolarFD) 52 | public: 53 | virtual double GetY(double sVal, bool& succ); 54 | virtual bool CalcList(); 55 | virtual void Serialize(CArchive& ar); 56 | double maxth, minth; //自变量θ取值范围 57 | PolarFD(); 58 | PolarFD(CString Equation, double minTh, double maxTh, int stepTh, COLORREF color, int penWidth, int penType); 59 | }; 60 | 61 | class TwoFD : public FuncData 62 | { 63 | DECLARE_SERIAL(TwoFD) 64 | public: 65 | CString m_EquationY; 66 | double maxT, minT; 67 | double GetX(double tVal, bool& succ); 68 | virtual double GetY(double tVal, bool& succ); 69 | virtual bool CalcList(); 70 | virtual CString GetEquation2(); 71 | virtual void Serialize(CArchive& ar); 72 | TwoFD(); 73 | TwoFD(CString Equation_X, CString Equation_Y,double minX, double maxX, int stepX, COLORREF color, int penWidth, int penType); 74 | }; 75 | 76 | class DataFD : public FuncData 77 | { 78 | DECLARE_SERIAL(DataFD) 79 | public: 80 | static int DataFD_Cnt; //记录数据点类型函数数量 81 | virtual double GetY(double tVal, bool& succ); 82 | virtual bool CalcList(); 83 | virtual void Serialize(CArchive& ar); 84 | DataFD(); 85 | DataFD(vector &vetX, vector &vetY, COLORREF color, int penWidth, int penType); 86 | }; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 wineee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MainFrm.cpp: -------------------------------------------------------------------------------- 1 |  2 | // MainFrm.cpp: CMainFrame 类的实现 3 | // 4 | 5 | #include "pch.h" 6 | #include "framework.h" 7 | #include "mfcplot.h" 8 | 9 | #include "MainFrm.h" 10 | 11 | #ifdef _DEBUG 12 | #define new DEBUG_NEW 13 | #endif 14 | 15 | // CMainFrame 16 | 17 | IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) 18 | 19 | BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) 20 | ON_WM_CREATE() 21 | END_MESSAGE_MAP() 22 | 23 | static UINT indicators[] = 24 | { 25 | ID_SEPARATOR, // 状态行指示器 26 | ID_INDICATOR_MOUSE_POS, 27 | ID_INDICATOR_CAPS, 28 | ID_INDICATOR_NUM, 29 | ID_INDICATOR_SCRL, 30 | }; 31 | 32 | // CMainFrame 构造/析构 33 | 34 | CMainFrame::CMainFrame() noexcept 35 | { 36 | // TODO: 在此添加成员初始化代码 37 | } 38 | 39 | CMainFrame::~CMainFrame() 40 | { 41 | } 42 | 43 | int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 44 | { 45 | if (CFrameWnd::OnCreate(lpCreateStruct) == -1) 46 | return -1; 47 | 48 | if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || 49 | !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) 50 | { 51 | TRACE0("未能创建工具栏\n"); 52 | return -1; // 未能创建 53 | } 54 | 55 | if (!m_wndStatusBar.Create(this)) 56 | { 57 | TRACE0("未能创建状态栏\n"); 58 | return -1; // 未能创建 59 | } 60 | m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)); 61 | 62 | // TODO: 如果不需要可停靠工具栏,则删除这三行 63 | m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); 64 | EnableDocking(CBRS_ALIGN_ANY); 65 | DockControlBar(&m_wndToolBar); 66 | 67 | 68 | return 0; 69 | } 70 | 71 | BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) 72 | { 73 | if( !CFrameWnd::PreCreateWindow(cs) ) 74 | return FALSE; 75 | // TODO: 在此处通过修改 76 | // CREATESTRUCT cs 来修改窗口类或样式 77 | 78 | return TRUE; 79 | } 80 | 81 | // CMainFrame 诊断 82 | 83 | #ifdef _DEBUG 84 | void CMainFrame::AssertValid() const 85 | { 86 | CFrameWnd::AssertValid(); 87 | } 88 | 89 | void CMainFrame::Dump(CDumpContext& dc) const 90 | { 91 | CFrameWnd::Dump(dc); 92 | } 93 | #endif //_DEBUG 94 | 95 | 96 | // CMainFrame 消息处理程序 97 | 98 | -------------------------------------------------------------------------------- /MainFrm.h: -------------------------------------------------------------------------------- 1 |  2 | // MainFrm.h: CMainFrame 类的接口 3 | // 4 | 5 | #pragma once 6 | 7 | class CMainFrame : public CFrameWnd 8 | { 9 | 10 | protected: // 仅从序列化创建 11 | CMainFrame() noexcept; 12 | DECLARE_DYNCREATE(CMainFrame) 13 | 14 | // 特性 15 | public: 16 | 17 | // 操作 18 | public: 19 | 20 | // 重写 21 | public: 22 | virtual BOOL PreCreateWindow(CREATESTRUCT& cs); 23 | 24 | // 实现 25 | public: 26 | virtual ~CMainFrame(); 27 | #ifdef _DEBUG 28 | virtual void AssertValid() const; 29 | virtual void Dump(CDumpContext& dc) const; 30 | #endif 31 | 32 | protected: // 控件条嵌入成员 33 | CToolBar m_wndToolBar; 34 | CStatusBar m_wndStatusBar; 35 | 36 | // 生成的消息映射函数 37 | protected: 38 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); 39 | DECLARE_MESSAGE_MAP() 40 | 41 | }; 42 | 43 | 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mfcplot 2 | mfc数学函数曲线绘制程序 3 | [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fwineee%2Fmfcplot.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fwineee%2Fmfcplot?ref=badge_shield) 4 | ### 实验环境 5 | - window 10 版本19041 6 | - Microsoft Visual Studio Community 2019 版本 16.6.4 7 | 8 | ### 实现功能 9 | - [x] 绘制常见一元函数的图像 10 | - [x] 支持普通函数,极坐标函数,参数方程,直接输入数据点 11 | - [x] 可以删除指定函数图像 12 | - [x] 可以在一个坐标系中绘制多条数学曲线 13 | - [x] 显示坐标轴,网格,刻度值,图例 14 | - [x] 可以选择不同颜色线型来绘制不同的曲线 15 | - [x] 当鼠标移动到曲线上某点时,可以显示该点的坐标 16 | - [x] 可以用鼠标拖动图像 17 | - [x] 可以进行图形的放大,缩小,定量设置显示范围,自动缩放 18 | - [x] 普通函数x取值范围可设置为跟随显示范围变化 19 | - [x] 状态栏实时显示鼠标位置,双击显示鼠标精确位置 20 | - [x] 重要数据的序列化和反序列化 21 | - [ ] 突变函数(如floor(x))和部分y值接近无穷的函数(如tan(x))无法完美显示 22 | 23 | 24 | 25 | ### 界面展示 26 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720012121800.png) 27 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020072001273763.png) 28 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720014118171.png) 29 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720014136668.png) 30 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720014609420.png) 31 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020072001464030.png) 32 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720014714925.png) 33 | 34 | ### 设计结构 35 | ##### 程序流程及设计 36 |   用户输入函数信息,显示函数图像。还可以通过菜单和工具栏更改设置。 37 | 38 |   通过计算样本点,相邻样本点用直线连接,当样本点数量足够大时,可近似看成曲线。 39 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720162214892.png) 40 | 41 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720161921318.png) 42 | ##### 程序所有源文件 43 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720162844144.png) 44 | ##### CalculatorFunc.cpp介绍 45 | >double CalcEquation(CString m_sEquation, bool& succ, char xKey, double xVal) 46 | >m_sEquation:表达式 47 | >succ:计算是否成功 48 | >xKey:未知数是"x"还是"t" 49 | >xVal:未知数的值 50 | 51 | >此文件可以单独拿出来(把CString换成string就行)使用 52 | >bool succ = true; 53 | >double ans = CalcEquation("sin(x)+e^x",succ,'x',1.1); 54 | 55 |  对方程,分为数(常数,未知数x),双目运算符(+ , - ,* , / , ^ ) ,单目运算符(sin,cos等等),单目运算符后面是一个完整的子式,如2+cos(x+1)中,x+1就是一个完整的式子,通过递归调用可以求子式的值,如果已知子式值,这个[单目运算符+子式]就是一个已知数了,那剩下的就等效于只有+ , - , * , / , ^ 的公式,用表达式栈法就可以解决。 56 | ##### FuncData.cpp介绍 57 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720161950216.png) 58 | ```cpp 59 | FuncData类 60 | 成员变量: 61 | int FuncCas; //函数类型 62 | CString m_Equation; //函数表达式 63 | double minX, maxX; //x极值 64 | double maxY, minY; //y极值 65 | int stepX; //可以理解为样本点的数量 66 | int m_penWidth; //画笔宽度 67 | int m_penType; //画笔类型 68 | COLORREF m_color; //画笔颜色 69 | vector > vetPoint; //储存所有样本点 70 | 成员函数: 71 | virtual double GetY(double xVal, bool& succ) = 0;//得到未知数为xVal时函数值,succ表示计算是否成功 72 | virtual bool CalcList() = 0; //计算vetPoint 73 | virtual bool GetNearest(pair NowPoint, pair &CmpPoint);//获取本函数与NowPoint最近的点 74 | virtual CString GetEquation2(); //为了得到参数方程第二个函数式 75 | FuncData(); 76 | FuncData(CString Equation,double minX,double maxX,int stepX,COLORREF color, int penWidth,int penType);//构造函数 77 | 78 | 注意:此处派生类只记录特有的成员 79 | NormalFD类 80 | 无 81 | 82 | PolarFD 类 83 | 成员变量 84 | double maxth, minth; //自变量θ取值范围 85 | 86 | TwoFD类 87 | 成员变量 88 | CString m_EquationY; 89 | double maxT, minT; 90 | 成员函数 91 | double GetX(double tVal, bool& succ);//参数方程X也需要求值 92 | virtual double GetY(double tVal, bool& succ); 93 | 94 | DataFD类 95 | 成员函数 96 | static int DataFD_Cnt; //记录数据点类型函数数量 97 | ``` 98 | 99 | 100 | ##### mfcplotDoc.cpp介绍 101 |  mfcplotDoc中记录着设置信息和函数数据,主要内容如下 102 | ```cpp 103 | public: 104 | bool m_WillShowGrid; //是否显示网格 105 | bool m_WillShowAxis; //是否显示坐标轴 106 | bool m_WillShowEdge; //是否显示边框 107 | bool m_SingelMode; //单函数模式添加函数自动删除上一个函数 108 | bool m_ForceXrange; //普通函数x范围是否固定,不固定的话随显示范围变化 109 | bool m_ShowNearPoint;//鼠标接近函数线时是否显示其坐标 110 | double m_Xmin, m_Xmax, m_Ymin, m_Ymax;//显示范围 111 | FuncData *m_FD;//临时变量 112 | CObList m_List;//记录所有函数信息 113 | public: 114 | afx_msg void OnAxisMenu();//坐标轴 115 | afx_msg void OnGridMenu();//网格 116 | afx_msg void OnEdgeMenu();//边框 117 | afx_msg void OnSmallerMenu();//显示范围缩小 0.8 118 | afx_msg void OnBiggerMenu();//显示范围放大 1.25 119 | afx_msg void OnNormalFuncMenu();//增加普通函数 120 | afx_msg void OnMenuSetXyrange();//设置显示范围 121 | afx_msg void OnFuncMode();//单/多函数模式 122 | afx_msg void OnPolarFuncMenu();//增加极坐标函数 123 | afx_msg void OnTwoFuncMenu();//增加参数方程函数 124 | afx_msg void OnDataFuncMenu();//增加数据点型函数 125 | afx_msg void OnFroceXrang();//普通函数x范围是否固定 126 | afx_msg void OnNearpointMenu();//是否显示最近点 127 | afx_msg void OnAutorangeMenu();//自动调整显示范围,正好显示完整函数图像 128 | afx_msg void OnDelfunconeMenu();//删除一个函数 129 | afx_msg void OnDelallMenu();//删除所有函数 130 | ``` 131 | ##### mfcplotView.cpp介绍 132 |  绘图逻辑是在这里实现的,主要内容如下 133 | ```cpp 134 | public: 135 | double m_Xmin, m_Xmax, m_Ymin, m_Ymax;//函数显示范围 136 | int nTop, nButton, nLeft, nRight;//对应的逻辑坐标范围 137 | int isMoving;//拖动状态 0不拖动 1拖动模式 2正在拖动 138 | double tmp_Xmin, tmp_Xmax, tmp_Ymin, tmp_Ymax; 139 | //拖动模式下,单击鼠标左键,记录起点的显示范围 140 | CPoint m_posStart; 141 | //拖动模式下,单击鼠标左键,记录起点的鼠标坐标 142 | //根据鼠标坐标偏移量可以计算显示范围变化量 143 | ``` 144 | 145 |  函数中LPxtoFPx表示把函数坐标x变成pDC可以用的逻辑坐标_x,原理函数坐标范围m_Xmin,m_Xmax到逻辑坐标范围nLeft,nRight(下面函数会给出)等比例的映射。 146 | 147 | ```cpp 148 | double CmfcplotView::LPxtoFPx(int x) { 149 | return m_Xmin + (1.0 * x - nLeft) * (m_Xmax - m_Xmin) / (1.0 * nRight - nLeft); 150 | } 151 | ``` 152 |  实现坐标转换后就可以进行绘图工作了。 153 | 154 | ```cpp 155 | void CmfcplotView::OnDraw(CDC* pDC) 156 | { 157 | CmfcplotDoc* pDoc = GetDocument(); 158 | ASSERT_VALID(pDoc); 159 | if (!pDoc) 160 | return; 161 | m_Xmin = pDoc->m_Xmin;//极值保存在Doc中 162 | m_Xmax = pDoc->m_Xmax; 163 | m_Ymin = pDoc->m_Ymin; 164 | m_Ymax = pDoc->m_Ymax; 165 | 166 | CRect rect; 167 | GetClientRect(&rect);//获得视图区 168 | 169 | nTop = (int)round(rect.bottom * 0.1); //函数图像不会占据整个视图区 170 | nButton = (int)round(rect.bottom * 0.9); 171 | nLeft = (int)round(rect.right * 0.1); 172 | nRight = (int)round(rect.right * 0.9); 173 | 174 | if (pDoc->m_WillShowEdge) {//画边框 175 | pDC->MoveTo(nLeft, nTop); 176 | pDC->LineTo(nLeft, nButton); 177 | pDC->LineTo(nRight, nButton); 178 | pDC->LineTo(nRight, nTop); 179 | pDC->LineTo(nLeft, nTop); 180 | } 181 | 182 | //画x坐标信息 183 | int nX,nY; 184 | bool BIGX = abs(m_Xmin) > 100 || abs(m_Xmax) > 100;//x坐标值比较大时,标注更稀 185 | for (nX = nLeft; nX < nRight; nX += (BIGX ? 100 : 50)) { //每隔100/50像素一个标注 186 | CRect textRect(nX - (BIGX ? 50 : 25), nButton + 1, nX + (BIGX ? 50 : 25), nButton + 20);//显示区域 187 | CString xInfo; 188 | xInfo.Format(_T("%.2f"),LPxtoFPx(nX)); 189 | pDC->DrawText(xInfo, &textRect, DT_SINGLELINE | DT_CENTER); 190 | //单行,上下左右居中显示 191 | } 192 | if (nX - nRight <= (BIGX ? 50 : 25)) {//最后一个x坐标,与前一个标注距离太近则不显示 193 | CRect textRect(nRight, nButton + 1, nRight + 50, nButton + 20); 194 | CString xInfo; 195 | xInfo.Format(_T("%.2f"),m_Xmax); 196 | pDC->DrawText(xInfo, &textRect, DT_SINGLELINE | DT_LEFT | DT_TOP); 197 | } 198 | 199 | //y坐标 200 | for (nY = nButton - 50; nY > nTop; nY -= 50) { 201 | CRect textRect(nLeft - 200, nY-10, nLeft - 3, nY + 10); 202 | CString yInfo; 203 | yInfo.Format(_T("%.2f"), LPytoFPy(nY)); 204 | pDC->DrawText(yInfo, &textRect, DT_SINGLELINE | DT_RIGHT); 205 | } 206 | if (nTop - nY <= 25) { 207 | CRect textRect(nLeft - 200, nTop - 10, nLeft - 3, nTop + 10); 208 | CString yInfo; 209 | yInfo.Format(_T("%.2f"),m_Ymax); 210 | pDC->DrawText(yInfo, &textRect, DT_SINGLELINE | DT_BOTTOM | DT_RIGHT); 211 | } 212 | 213 | 214 | // 显示网格 215 | if (pDoc->m_WillShowGrid) { 216 | CPen pen(PS_DOT, 1, RGB(100, 100, 100)); //创建笔,虚线,并调整坐标颜色灰色 217 | CPen *pOldPen = (CPen *)pDC->SelectObject(&pen); 218 | for (nX = nLeft+50; nX < nRight; nX += 50) { 219 | pDC->MoveTo(nX, nTop); 220 | pDC->LineTo(nX, nButton); 221 | } 222 | for (nY = nButton - 50; nY > nTop; nY -= 50) { 223 | pDC->MoveTo(nLeft, nY); 224 | pDC->LineTo(nRight, nY); 225 | } 226 | pDC->SelectObject(pOldPen); 227 | } 228 | 229 | // 显示坐标轴 230 | if (pDoc->m_WillShowAxis) { 231 | CPen pen(PS_SOLID, 2, RGB(0, 0, 0)); 232 | CPen* pOldPen = (CPen*)pDC->SelectObject(&pen); 233 | int oX = FPxtoLPx(0); 234 | int oY = FPytoLPy(0); 235 | bool showY = oX >= nLeft && oX <= nRight; 236 | bool showX = oY >= nTop && oY <= nButton;//判断x,y轴是否在范围内 237 | if (showX) { 238 | pDC->MoveTo(nLeft - 10, oY); 239 | pDC->LineTo(nRight + 10, oY); 240 | } 241 | if (showY) { 242 | pDC->MoveTo(oX, nButton + 10); 243 | pDC->LineTo(oX, nTop - 10); 244 | } 245 | if (showX && showY) { 246 | pDC->TextOutW(oX + 1, oY + 1, _T("O")); 247 | } 248 | if (showX) { 249 | pDC->MoveTo(nRight + 10, oY); 250 | pDC->LineTo(nRight + 5, oY + 5); 251 | pDC->MoveTo(nRight + 10, oY); 252 | pDC->LineTo(nRight + 5, oY - 5); 253 | pDC->TextOutW(nRight + 10, oY, _T("X轴")); 254 | } 255 | if (showY) { 256 | pDC->MoveTo(oX, nTop - 10); 257 | pDC->LineTo(oX - 5, nTop - 5); 258 | pDC->MoveTo(oX, nTop - 10); 259 | pDC->LineTo(oX + 5, nTop - 5); 260 | pDC->TextOutW(oX + 5, nTop - 10, _T("Y轴")); 261 | } 262 | pDC->SelectObject(pOldPen); 263 | } 264 | 265 | 266 | POSITION p = pDoc->m_List.GetHeadPosition(); 267 | 268 | int showTop = nTop; 269 | while (p != nullptr) { 270 | bool shouldMov = true;//一段曲线第一个点MoveTo,其他都是LineTo 271 | FuncData* tmpFD = (FuncData*)pDoc->m_List.GetNext(p); 272 | CPen pen(tmpFD->m_penType, tmpFD->m_penWidth, tmpFD->m_color); 273 | CPen* pOldPen = (CPen*)pDC->SelectObject(&pen); 274 | 275 | if (tmpFD->FuncCas == CAS_NORMAL) {//动态X坐标模式下,普通函数x范围与视图不同时自动同步 276 | if (pDoc->m_ForceXrange && isMoving!=2) 277 | if (tmpFD->minX != m_Xmin || tmpFD->maxX != m_Xmax) { 278 | tmpFD->minX = m_Xmin; 279 | tmpFD->maxX = m_Xmax; 280 | tmpFD->CalcList(); 281 | } 282 | } 283 | 284 | for (auto dot : tmpFD->vetPoint) { 285 | if (dot.first < m_Xmin || dot.first > m_Xmax || dot.second < m_Ymin || dot.second > m_Ymax || dot.second != dot.second) { 286 | shouldMov = true; 287 | continue; 288 | } 289 | if (shouldMov) { 290 | pDC->MoveTo(FPxtoLPx(dot.first), FPytoLPy(dot.second)); 291 | shouldMov = false; 292 | } 293 | else 294 | pDC->LineTo(FPxtoLPx(dot.first), FPytoLPy(dot.second)); 295 | } 296 | 297 | pDC->MoveTo(nRight+5, showTop);//显示图例 298 | pDC->LineTo(rect.right, showTop); 299 | showTop += 5; 300 | if (tmpFD->FuncCas == CAS_NORMAL) 301 | pDC->TextOutW(nRight + 5, showTop, _T("f(x)=")+tmpFD->m_Equation); 302 | else if (tmpFD->FuncCas == CAS_POLAR) 303 | pDC->TextOutW(nRight + 5, showTop, _T("r(t)=") + tmpFD->m_Equation); 304 | else if (tmpFD->FuncCas == CAS_TWO) { 305 | pDC->TextOutW(nRight + 5, showTop, _T("x(t)=") + tmpFD->m_Equation); 306 | showTop += 20; 307 | pDC->TextOutW(nRight + 5, showTop, _T("y(t)=") + tmpFD->GetEquation2()); 308 | } else if (tmpFD->FuncCas == CAS_DATA) 309 | pDC->TextOutW(nRight + 5, showTop, _T("y(t)=") + tmpFD->m_Equation); 310 | showTop += 25; 311 | pDC->SelectObject(pOldPen); 312 | } 313 | } 314 | ``` 315 |  值得一提的是OnMouseMove的代码,拖动模式下,起点信息已经在OnLButtonDown更新,拖动过程使用了双缓冲绘图防止闪烁。具体原理可参看文末参考资料。 316 | ```cpp 317 | void CmfcplotView::OnMouseMove(UINT nFlags, CPoint point) 318 | { 319 | // TODO: 在此添加消息处理程序代码和/或调用默认值 320 | 更新状态栏,此处省略 321 | if (isMoving==2) { 322 | ::SetCursor(LoadCursor(NULL, IDC_SIZEALL)); 323 | CmfcplotDoc* pDoc = GetDocument(); 324 | double detx = LPxtoFPx(point.x) - LPxtoFPx(m_posStart.x); 325 | pDoc->m_Xmin = tmp_Xmin - detx; 326 | pDoc->m_Xmax = tmp_Xmax - detx; 327 | double dety = LPytoFPy(point.y) - LPytoFPy(m_posStart.y); 328 | pDoc->m_Ymin = tmp_Ymin - dety; 329 | pDoc->m_Ymax = tmp_Ymax - dety; 330 | CDC* pDC = GetDC(); 331 | //创建一个内存中的显示设备 332 | CDC MemDC; 333 | MemDC.CreateCompatibleDC(NULL); 334 | //创建一个内存中的图像 335 | CBitmap MemBitmap; 336 | CRect rect; 337 | GetClientRect(&rect); 338 | MemBitmap.CreateCompatibleBitmap(pDC, rect.right, rect.bottom); 339 | //指定内存显示设备在内存中的图像上画图 340 | MemDC.SelectObject(&MemBitmap); 341 | //先用一种颜色作为内存显示设备的背景色 342 | MemDC.FillSolidRect(rect.left, rect.top, rect.right, rect.bottom, RGB(144, 144, 144)); 343 | this->OnDraw(&MemDC); 344 | //将内存中画好的图像直接拷贝到屏幕指定区域上 345 | pDC->BitBlt(rect.left, rect.top, rect.right, rect.bottom, &MemDC, 0, 0, SRCCOPY); 346 | //释放相关资源 347 | ReleaseDC(pDC); 348 | } 349 | else if (isMoving == 1) { 350 | ::SetCursor(LoadCursor(NULL, IDC_HAND)); 351 | } 352 | 显示函数最近点部分,此处省略 353 | CView::OnMouseMove(nFlags, point); 354 | } 355 | 356 | ``` 357 | 358 | 359 | ### 完整代码 360 | [github](https://github.com/wineee/mfcplot) 361 | [gitee](https://gitee.com/rewine/mfcplot) 362 | [csdn下载](https://download.csdn.net/download/qq_33831360/12636165) 363 | ### 参考资料 364 | - [DrawText函数的讲解](https://blog.csdn.net/by_mxy/article/details/9932967) 365 | - [VC双缓冲绘图技术介绍](https://blog.csdn.net/oceanlucy/article/details/46827809?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.nonecase) 366 | - 阎光伟,彭文,徐琳茜. 基于案例的Visual C++程序设计教程[M].北京:清华大学出版社,2012 367 | - 张晓民. VC++2010应用开发技术[M].北京:机械工业出版社,2013 368 | 369 | 370 | ## License 371 | [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fwineee%2Fmfcplot.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fwineee%2Fmfcplot?ref=badge_large) 372 | -------------------------------------------------------------------------------- /Resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ 生成的包含文件。 3 | // 供 mfcplot.rc 使用 4 | // 5 | #define IDD_ABOUTBOX 100 6 | #define IDP_OLE_INIT_FAILED 100 7 | #define ID_INDICATOR_MOUSE_POS 101 8 | #define IDR_MAINFRAME 128 9 | #define IDR_mfcplotTYPE 130 10 | #define IDD_NORMALFUNC_DIALOG 310 11 | #define IDD_DIALOG_NORMALFUNC 315 12 | #define IDD_DIALOG_SET_RANGE 318 13 | #define IDD_DIALOG_POLARFUNC 319 14 | #define IDD_DIALOG_TWOFUNC 320 15 | #define IDD_DIALOG_DATAFUNC 324 16 | #define IDD_DIALOG_DEL 327 17 | #define IDC_EDIT 1000 18 | #define IDC_EQUATION_EDIT 1000 19 | #define IDC_BUTTON_1 1001 20 | #define IDC_BUTTON_2 1002 21 | #define IDC_BUTTON_3 1003 22 | #define IDC_BUTTON_4 1004 23 | #define IDC_BUTTON_5 1005 24 | #define IDC_BUTTON_6 1006 25 | #define IDC_EDIT_FUNC 1006 26 | #define IDC_BUTTON_7 1007 27 | #define IDC_BUTTON_SETFUNC 1007 28 | #define IDC_BUTTON_8 1008 29 | #define IDC_BUTTON_9 1009 30 | #define IDC_BUTTON_LINETYPE 1009 31 | #define IDC_BUTTON_10 1010 32 | #define IDC_BUTTON_COLOR 1010 33 | #define IDC_BUTTON_PI 1011 34 | #define IDC_EDIT2 1011 35 | #define IDC_BUTTON_E 1012 36 | #define IDC_EDIT3 1012 37 | #define IDC_BUTTON_ADD 1013 38 | #define IDC_EDIT4 1013 39 | #define IDC_BUTTON_DEC 1014 40 | #define IDC_EDIT1 1014 41 | #define IDC_BUTTON_MUL 1015 42 | #define IDC_EDIT5 1015 43 | #define IDC_EDIT_FUNC2 1015 44 | #define IDC_BUTTON_DIV 1016 45 | #define IDC_COMBO_LINETYPE 1016 46 | #define IDC_EDIT6 1016 47 | #define IDC_BUTTON_DOT 1017 48 | #define IDC_EDIT7 1017 49 | #define IDC_BUTTON_SETFUNC2 1017 50 | #define IDC_BUTTON_READDATA 1017 51 | #define IDC_BUTTON_ABS 1018 52 | #define IDC_BUTTON_SIN 1020 53 | #define IDC_BUTTON_COS 1021 54 | #define IDC_BUTTON_LN 1022 55 | #define IDC_BUTTON_LOG 1023 56 | #define IDC_BUTTON_POW 1024 57 | #define IDC_BUTTON_X 1025 58 | #define IDC_BUTTON_TAN 1026 59 | #define IDC_BUTTON_SQRT 1027 60 | #define IDC_BUTTON_2POW 1028 61 | #define IDC_BUTTON_CLEAR 1029 62 | #define IDC_BUTTON_DEL 1030 63 | #define IDC_BUTTON_LEFT 1031 64 | #define IDC_BUTTON_RIGHT 1032 65 | #define IDC_BUTTON_FLOOR 1033 66 | #define IDC_BUTTON_CEILING 1034 67 | #define IDC_BUTTON_ROUND 1035 68 | #define IDC_BUTTON_CUBIC 1036 69 | #define ID_32771 32771 70 | #define ID_Menu 32772 71 | #define ID_32773 32773 72 | #define ID_32774 32774 73 | #define ID_32775 32775 74 | #define ID_POLAR_MENU 32776 75 | #define ID_POLAR_FUNC_MENU 32777 76 | #define ID_NORMAL_FUNC_MENU 32778 77 | #define ID_TWO_FUNC_MENU 32779 78 | #define ID_DATA 32780 79 | #define ID_DATA_FUNC_MENU 32781 80 | #define ID_32782 32782 81 | #define ID_32783 32783 82 | #define ID_AXIS_MENU 32784 83 | #define ID_ 32785 84 | #define ID_GRID_MENU 32786 85 | #define ID_32787 32787 86 | #define ID_32788 32788 87 | #define ID_32789 32789 88 | #define ID_32790 32790 89 | #define ID_BIGGER_MENU 32791 90 | #define ID_SMALLER_MENU 32792 91 | #define ID_MOVE_MENU 32793 92 | #define ID_BI 32794 93 | #define ID_BUTTON32797 32797 94 | #define ID_32800 32800 95 | #define ID_FUNC_MODE 32801 96 | #define ID_32802 32802 97 | #define ID_EDGE_MENU 32803 98 | #define ID_Menu32806 32806 99 | #define ID_Menu_SET_XYRANGE 32807 100 | #define ID_32808 32808 101 | #define ID_FROCE_XRANG 32809 102 | #define ID_32810 32810 103 | #define ID_DELALL_MENU 32811 104 | #define ID_32812 32812 105 | #define ID_NEARPOINT_MENU 32813 106 | #define ID_32814 32814 107 | #define ID_AUTORANGE_MENU 32815 108 | #define ID_32816 32816 109 | #define ID_DELFUNCONE_MENU 32817 110 | 111 | // Next default values for new objects 112 | // 113 | #ifdef APSTUDIO_INVOKED 114 | #ifndef APSTUDIO_READONLY_SYMBOLS 115 | #define _APS_NEXT_RESOURCE_VALUE 329 116 | #define _APS_NEXT_COMMAND_VALUE 32818 117 | #define _APS_NEXT_CONTROL_VALUE 1019 118 | #define _APS_NEXT_SYMED_VALUE 310 119 | #endif 120 | #endif 121 | -------------------------------------------------------------------------------- /framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef VC_EXTRALEAN 4 | #define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料 5 | #endif 6 | 7 | #include "targetver.h" 8 | 9 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的 10 | 11 | // 关闭 MFC 的一些常见且经常可放心忽略的隐藏警告消息 12 | #define _AFX_ALL_WARNINGS 13 | 14 | #include // MFC 核心组件和标准组件 15 | #include // MFC 扩展 16 | 17 | 18 | #include // MFC 自动化类 19 | 20 | #ifndef _AFX_NO_OLE_SUPPORT 21 | #include // MFC 对 Internet Explorer 4 公共控件的支持 22 | #endif 23 | #ifndef _AFX_NO_AFXCMN_SUPPORT 24 | #include // MFC 对 Windows 公共控件的支持 25 | #endif // _AFX_NO_AFXCMN_SUPPORT 26 | 27 | #include // MFC 支持功能区和控制条 28 | 29 | 30 | #ifdef _UNICODE 31 | #if defined _M_IX86 32 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") 33 | #elif defined _M_X64 34 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") 35 | #else 36 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 37 | #endif 38 | #endif 39 | 40 | 41 | -------------------------------------------------------------------------------- /mfcplot.cpp: -------------------------------------------------------------------------------- 1 |  2 | // mfcplot.cpp: 定义应用程序的类行为。 3 | // 4 | 5 | #include "pch.h" 6 | #include "framework.h" 7 | #include "afxwinappex.h" 8 | #include "afxdialogex.h" 9 | #include "mfcplot.h" 10 | #include "MainFrm.h" 11 | 12 | #include "mfcplotDoc.h" 13 | #include "mfcplotView.h" 14 | 15 | #ifdef _DEBUG 16 | #define new DEBUG_NEW 17 | #endif 18 | 19 | 20 | // CmfcplotApp 21 | 22 | BEGIN_MESSAGE_MAP(CmfcplotApp, CWinApp) 23 | ON_COMMAND(ID_APP_ABOUT, &CmfcplotApp::OnAppAbout) 24 | // 基于文件的标准文档命令 25 | ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew) 26 | ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen) 27 | // 标准打印设置命令 28 | ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup) 29 | END_MESSAGE_MAP() 30 | 31 | 32 | // CmfcplotApp 构造 33 | 34 | CmfcplotApp::CmfcplotApp() noexcept 35 | { 36 | // 支持重新启动管理器 37 | m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS; 38 | #ifdef _MANAGED 39 | // 如果应用程序是利用公共语言运行时支持(/clr)构建的,则: 40 | // 1) 必须有此附加设置,“重新启动管理器”支持才能正常工作。 41 | // 2) 在您的项目中,您必须按照生成顺序向 System.Windows.Forms 添加引用。 42 | System::Windows::Forms::Application::SetUnhandledExceptionMode(System::Windows::Forms::UnhandledExceptionMode::ThrowException); 43 | #endif 44 | 45 | // TODO: 将以下应用程序 ID 字符串替换为唯一的 ID 字符串;建议的字符串格式 46 | //为 CompanyName.ProductName.SubProduct.VersionInformation 47 | SetAppID(_T("mfcplot.AppID.NoVersion")); 48 | 49 | // TODO: 在此处添加构造代码, 50 | // 将所有重要的初始化放置在 InitInstance 中 51 | } 52 | 53 | // 唯一的 CmfcplotApp 对象 54 | 55 | CmfcplotApp theApp; 56 | 57 | 58 | // CmfcplotApp 初始化 59 | 60 | BOOL CmfcplotApp::InitInstance() 61 | { 62 | // 如果一个运行在 Windows XP 上的应用程序清单指定要 63 | // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, 64 | //则需要 InitCommonControlsEx()。 否则,将无法创建窗口。 65 | INITCOMMONCONTROLSEX InitCtrls; 66 | InitCtrls.dwSize = sizeof(InitCtrls); 67 | // 将它设置为包括所有要在应用程序中使用的 68 | // 公共控件类。 69 | InitCtrls.dwICC = ICC_WIN95_CLASSES; 70 | InitCommonControlsEx(&InitCtrls); 71 | 72 | CWinApp::InitInstance(); 73 | 74 | 75 | // 初始化 OLE 库 76 | if (!AfxOleInit()) 77 | { 78 | AfxMessageBox(IDP_OLE_INIT_FAILED); 79 | return FALSE; 80 | } 81 | 82 | AfxEnableControlContainer(); 83 | 84 | EnableTaskbarInteraction(FALSE); 85 | 86 | // 使用 RichEdit 控件需要 AfxInitRichEdit2() 87 | // AfxInitRichEdit2(); 88 | 89 | // 标准初始化 90 | // 如果未使用这些功能并希望减小 91 | // 最终可执行文件的大小,则应移除下列 92 | // 不需要的特定初始化例程 93 | // 更改用于存储设置的注册表项 94 | // TODO: 应适当修改该字符串, 95 | // 例如修改为公司或组织名 96 | SetRegistryKey(_T("应用程序向导生成的本地应用程序")); 97 | LoadStdProfileSettings(4); // 加载标准 INI 文件选项(包括 MRU) 98 | 99 | 100 | // 注册应用程序的文档模板。 文档模板 101 | // 将用作文档、框架窗口和视图之间的连接 102 | CSingleDocTemplate* pDocTemplate; 103 | pDocTemplate = new CSingleDocTemplate( 104 | IDR_MAINFRAME, 105 | RUNTIME_CLASS(CmfcplotDoc), 106 | RUNTIME_CLASS(CMainFrame), // 主 SDI 框架窗口 107 | RUNTIME_CLASS(CmfcplotView)); 108 | if (!pDocTemplate) 109 | return FALSE; 110 | AddDocTemplate(pDocTemplate); 111 | 112 | 113 | // 分析标准 shell 命令、DDE、打开文件操作的命令行 114 | CCommandLineInfo cmdInfo; 115 | ParseCommandLine(cmdInfo); 116 | 117 | 118 | 119 | // 调度在命令行中指定的命令。 如果 120 | // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。 121 | if (!ProcessShellCommand(cmdInfo)) 122 | return FALSE; 123 | 124 | // 唯一的一个窗口已初始化,因此显示它并对其进行更新 125 | m_pMainWnd->SetWindowTextW(_T("mfcplot")); 126 | m_pMainWnd->ShowWindow(SW_SHOW); 127 | m_pMainWnd->UpdateWindow(); 128 | return TRUE; 129 | } 130 | 131 | int CmfcplotApp::ExitInstance() 132 | { 133 | //TODO: 处理可能已添加的附加资源 134 | AfxOleTerm(FALSE); 135 | 136 | return CWinApp::ExitInstance(); 137 | } 138 | 139 | // CmfcplotApp 消息处理程序 140 | 141 | 142 | // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 143 | 144 | class CAboutDlg : public CDialogEx 145 | { 146 | public: 147 | CAboutDlg() noexcept; 148 | 149 | // 对话框数据 150 | #ifdef AFX_DESIGN_TIME 151 | enum { IDD = IDD_ABOUTBOX }; 152 | #endif 153 | 154 | protected: 155 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 156 | 157 | // 实现 158 | protected: 159 | DECLARE_MESSAGE_MAP() 160 | public: 161 | }; 162 | 163 | CAboutDlg::CAboutDlg() noexcept : CDialogEx(IDD_ABOUTBOX) 164 | { 165 | } 166 | 167 | void CAboutDlg::DoDataExchange(CDataExchange* pDX) 168 | { 169 | CDialogEx::DoDataExchange(pDX); 170 | } 171 | 172 | BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) 173 | END_MESSAGE_MAP() 174 | 175 | // 用于运行对话框的应用程序命令 176 | void CmfcplotApp::OnAppAbout() 177 | { 178 | CAboutDlg aboutDlg; 179 | aboutDlg.DoModal(); 180 | } 181 | 182 | // CmfcplotApp 消息处理程序 183 | -------------------------------------------------------------------------------- /mfcplot.h: -------------------------------------------------------------------------------- 1 |  2 | // mfcplot.h: mfcplot 应用程序的主头文件 3 | // 4 | #pragma once 5 | 6 | #ifndef __AFXWIN_H__ 7 | #error "在包含此文件之前包含 'pch.h' 以生成 PCH" 8 | #endif 9 | 10 | #include "resource.h" // 主符号 11 | 12 | 13 | // CmfcplotApp: 14 | // 有关此类的实现,请参阅 mfcplot.cpp 15 | // 16 | 17 | class CmfcplotApp : public CWinApp 18 | { 19 | public: 20 | CmfcplotApp() noexcept; 21 | 22 | 23 | // 重写 24 | public: 25 | virtual BOOL InitInstance(); 26 | virtual int ExitInstance(); 27 | 28 | // 实现 29 | afx_msg void OnAppAbout(); 30 | DECLARE_MESSAGE_MAP() 31 | }; 32 | 33 | extern CmfcplotApp theApp; 34 | -------------------------------------------------------------------------------- /mfcplot.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wineee/mfcplot/4f081ca7d0121d4e1011eda4178e99c4f8d24794/mfcplot.rc -------------------------------------------------------------------------------- /mfcplot.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30204.135 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mfcplot", "mfcplot.vcxproj", "{BA524D4B-FB5E-42FA-B64F-B9B90E0C5FF4}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {BA524D4B-FB5E-42FA-B64F-B9B90E0C5FF4}.Debug|x64.ActiveCfg = Debug|x64 17 | {BA524D4B-FB5E-42FA-B64F-B9B90E0C5FF4}.Debug|x64.Build.0 = Debug|x64 18 | {BA524D4B-FB5E-42FA-B64F-B9B90E0C5FF4}.Debug|x86.ActiveCfg = Debug|Win32 19 | {BA524D4B-FB5E-42FA-B64F-B9B90E0C5FF4}.Debug|x86.Build.0 = Debug|Win32 20 | {BA524D4B-FB5E-42FA-B64F-B9B90E0C5FF4}.Release|x64.ActiveCfg = Release|x64 21 | {BA524D4B-FB5E-42FA-B64F-B9B90E0C5FF4}.Release|x64.Build.0 = Release|x64 22 | {BA524D4B-FB5E-42FA-B64F-B9B90E0C5FF4}.Release|x86.ActiveCfg = Release|Win32 23 | {BA524D4B-FB5E-42FA-B64F-B9B90E0C5FF4}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {09076C19-F9A9-40D0-818A-B0BC7AE5044D} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /mfcplot.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {BA524D4B-FB5E-42FA-B64F-B9B90E0C5FF4} 24 | MFCProj 25 | mfcplot 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | Dynamic 35 | 36 | 37 | Application 38 | false 39 | v142 40 | true 41 | Unicode 42 | Dynamic 43 | 44 | 45 | Application 46 | true 47 | v142 48 | Unicode 49 | Dynamic 50 | 51 | 52 | Application 53 | false 54 | v142 55 | true 56 | Unicode 57 | Dynamic 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | true 79 | 80 | 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | false 88 | 89 | 90 | 91 | Use 92 | Level3 93 | true 94 | WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) 95 | pch.h 96 | 97 | 98 | Windows 99 | 100 | 101 | false 102 | true 103 | _DEBUG;%(PreprocessorDefinitions) 104 | 105 | 106 | 0x0804 107 | _DEBUG;%(PreprocessorDefinitions) 108 | $(IntDir);%(AdditionalIncludeDirectories) 109 | 110 | 111 | 112 | 113 | Use 114 | Level3 115 | true 116 | _WINDOWS;_DEBUG;%(PreprocessorDefinitions) 117 | pch.h 118 | 119 | 120 | Windows 121 | 122 | 123 | false 124 | true 125 | _DEBUG;%(PreprocessorDefinitions) 126 | 127 | 128 | 0x0804 129 | _DEBUG;%(PreprocessorDefinitions) 130 | $(IntDir);%(AdditionalIncludeDirectories) 131 | 132 | 133 | 134 | 135 | Use 136 | Level3 137 | true 138 | true 139 | true 140 | WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) 141 | pch.h 142 | 143 | 144 | Windows 145 | true 146 | true 147 | 148 | 149 | false 150 | true 151 | NDEBUG;%(PreprocessorDefinitions) 152 | 153 | 154 | 0x0804 155 | NDEBUG;%(PreprocessorDefinitions) 156 | $(IntDir);%(AdditionalIncludeDirectories) 157 | 158 | 159 | 160 | 161 | Use 162 | Level3 163 | true 164 | true 165 | true 166 | _WINDOWS;NDEBUG;%(PreprocessorDefinitions) 167 | pch.h 168 | 169 | 170 | Windows 171 | true 172 | true 173 | 174 | 175 | false 176 | true 177 | NDEBUG;%(PreprocessorDefinitions) 178 | 179 | 180 | 0x0804 181 | NDEBUG;%(PreprocessorDefinitions) 182 | $(IntDir);%(AdditionalIncludeDirectories) 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | Create 220 | Create 221 | Create 222 | Create 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /mfcplot.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 头文件 26 | 27 | 28 | 头文件 29 | 30 | 31 | 头文件 32 | 33 | 34 | 头文件 35 | 36 | 37 | 头文件 38 | 39 | 40 | 头文件 41 | 42 | 43 | 头文件 44 | 45 | 46 | 头文件 47 | 48 | 49 | 头文件 50 | 51 | 52 | 头文件 53 | 54 | 55 | 头文件 56 | 57 | 58 | 头文件 59 | 60 | 61 | 头文件 62 | 63 | 64 | 头文件 65 | 66 | 67 | 头文件 68 | 69 | 70 | 71 | 72 | 源文件 73 | 74 | 75 | 源文件 76 | 77 | 78 | 源文件 79 | 80 | 81 | 源文件 82 | 83 | 84 | 源文件 85 | 86 | 87 | 源文件 88 | 89 | 90 | 源文件 91 | 92 | 93 | 源文件 94 | 95 | 96 | 源文件 97 | 98 | 99 | 源文件 100 | 101 | 102 | 源文件 103 | 104 | 105 | 源文件 106 | 107 | 108 | 源文件 109 | 110 | 111 | 源文件 112 | 113 | 114 | 115 | 116 | 资源文件 117 | 118 | 119 | 120 | 121 | 资源文件 122 | 123 | 124 | 125 | 126 | 资源文件 127 | 128 | 129 | 资源文件 130 | 131 | 132 | 资源文件 133 | 134 | 135 | 资源文件 136 | 137 | 138 | -------------------------------------------------------------------------------- /mfcplotDoc.cpp: -------------------------------------------------------------------------------- 1 |  2 | // mfcplotDoc.cpp: CmfcplotDoc 类的实现 3 | // 4 | 5 | #include "pch.h" 6 | #include "framework.h" 7 | // SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的 8 | // ATL 项目中进行定义,并允许与该项目共享文档代码。 9 | #ifndef SHARED_HANDLERS 10 | #include "mfcplot.h" 11 | #endif 12 | 13 | #include "mfcplotDoc.h" 14 | #include 15 | #include 16 | #include "CFuncDlg.h" 17 | #include "CNormalFuncDlg.h" 18 | #include "CPolarFuncDlg.h" 19 | #include "CSetXYrangeDlg.h" 20 | #include "CTwoFuncDlg.h" 21 | #include "CDataFuncDlg.h" 22 | #include "CDelFuncDlg.h" 23 | 24 | #ifdef _DEBUG 25 | #define new DEBUG_NEW 26 | #endif 27 | 28 | // CmfcplotDoc 29 | 30 | IMPLEMENT_DYNCREATE(CmfcplotDoc, CDocument) 31 | 32 | BEGIN_MESSAGE_MAP(CmfcplotDoc, CDocument) 33 | ON_COMMAND(ID_AXIS_MENU, &CmfcplotDoc::OnAxisMenu) 34 | ON_COMMAND(ID_GRID_MENU, &CmfcplotDoc::OnGridMenu) 35 | ON_COMMAND(ID_SMALLER_MENU, &CmfcplotDoc::OnSmallerMenu) 36 | ON_COMMAND(ID_BIGGER_MENU, &CmfcplotDoc::OnBiggerMenu) 37 | ON_COMMAND(ID_NORMAL_FUNC_MENU, &CmfcplotDoc::OnNormalFuncMenu) 38 | ON_UPDATE_COMMAND_UI(ID_EDGE_MENU, &CmfcplotDoc::OnUpdateEdgeMenu) 39 | ON_COMMAND(ID_EDGE_MENU, &CmfcplotDoc::OnEdgeMenu) 40 | ON_COMMAND(ID_Menu_SET_XYRANGE, &CmfcplotDoc::OnMenuSetXyrange) 41 | ON_COMMAND(ID_FUNC_MODE, &CmfcplotDoc::OnFuncMode) 42 | ON_UPDATE_COMMAND_UI(ID_FUNC_MODE, &CmfcplotDoc::OnUpdateFuncMode) 43 | ON_UPDATE_COMMAND_UI(ID_AXIS_MENU, &CmfcplotDoc::OnUpdateAxisMenu) 44 | ON_UPDATE_COMMAND_UI(ID_GRID_MENU, &CmfcplotDoc::OnUpdateGridMenu) 45 | ON_COMMAND(ID_POLAR_FUNC_MENU, &CmfcplotDoc::OnPolarFuncMenu) 46 | ON_COMMAND(ID_TWO_FUNC_MENU, &CmfcplotDoc::OnTwoFuncMenu) 47 | ON_COMMAND(ID_DATA_FUNC_MENU, &CmfcplotDoc::OnDataFuncMenu) 48 | ON_COMMAND(ID_FROCE_XRANG, &CmfcplotDoc::OnFroceXrang) 49 | ON_UPDATE_COMMAND_UI(ID_FROCE_XRANG, &CmfcplotDoc::OnUpdateFroceXrang) 50 | ON_COMMAND(ID_DELALL_MENU, &CmfcplotDoc::OnDelallMenu) 51 | ON_COMMAND(ID_NEARPOINT_MENU, &CmfcplotDoc::OnNearpointMenu) 52 | ON_UPDATE_COMMAND_UI(ID_NEARPOINT_MENU, &CmfcplotDoc::OnUpdateNearpointMenu) 53 | ON_COMMAND(ID_AUTORANGE_MENU, &CmfcplotDoc::OnAutorangeMenu) 54 | ON_COMMAND(ID_DELFUNCONE_MENU, &CmfcplotDoc::OnDelfunconeMenu) 55 | END_MESSAGE_MAP() 56 | 57 | 58 | // CmfcplotDoc 构造/析构 59 | 60 | CmfcplotDoc::CmfcplotDoc() noexcept 61 | { 62 | // TODO: 在此添加一次性构造代码 63 | m_WillShowGrid = true; 64 | m_WillShowAxis = true; 65 | m_WillShowEdge = true; 66 | m_SingelMode = true; 67 | m_ForceXrange = false; 68 | m_ShowNearPoint = false; 69 | m_Xmin = -10; 70 | m_Xmax = 10; 71 | m_Ymin = -1; 72 | m_Ymax = 1; 73 | m_FD = nullptr; 74 | } 75 | 76 | CmfcplotDoc::~CmfcplotDoc() 77 | { 78 | } 79 | 80 | BOOL CmfcplotDoc::OnNewDocument() 81 | { 82 | if (!CDocument::OnNewDocument()) 83 | return FALSE; 84 | 85 | // TODO: 在此添加重新初始化代码 86 | // (SDI 文档将重用该文档) 87 | 88 | return TRUE; 89 | } 90 | 91 | 92 | // CmfcplotDoc 序列化 93 | 94 | void CmfcplotDoc::Serialize(CArchive& ar) 95 | { 96 | m_List.Serialize(ar); 97 | if (ar.IsStoring()) 98 | { 99 | // TODO: 在此添加存储代码 100 | ar << m_WillShowGrid << m_WillShowAxis << m_WillShowEdge << m_SingelMode << m_ForceXrange << m_ShowNearPoint \ 101 | << m_Xmin << m_Xmax << m_Ymin << m_Ymax; 102 | } 103 | else 104 | { 105 | // TODO: 在此添加加载代码 106 | ar >> m_WillShowGrid >> m_WillShowAxis >> m_WillShowEdge >> m_SingelMode >> m_ForceXrange >> m_ShowNearPoint \ 107 | >> m_Xmin >> m_Xmax >> m_Ymin >> m_Ymax; 108 | } 109 | } 110 | 111 | #ifdef SHARED_HANDLERS 112 | 113 | // 缩略图的支持 114 | void CmfcplotDoc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds) 115 | { 116 | // 修改此代码以绘制文档数据 117 | dc.FillSolidRect(lprcBounds, RGB(255, 255, 255)); 118 | 119 | CString strText = _T("TODO: implement thumbnail drawing here"); 120 | LOGFONT lf; 121 | 122 | CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)); 123 | pDefaultGUIFont->GetLogFont(&lf); 124 | lf.lfHeight = 36; 125 | 126 | CFont fontDraw; 127 | fontDraw.CreateFontIndirect(&lf); 128 | 129 | CFont* pOldFont = dc.SelectObject(&fontDraw); 130 | dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK); 131 | dc.SelectObject(pOldFont); 132 | } 133 | 134 | // 搜索处理程序的支持 135 | void CmfcplotDoc::InitializeSearchContent() 136 | { 137 | CString strSearchContent; 138 | // 从文档数据设置搜索内容。 139 | // 内容部分应由“;”分隔 140 | 141 | // 例如: strSearchContent = _T("point;rectangle;circle;ole object;"); 142 | SetSearchContent(strSearchContent); 143 | } 144 | 145 | void CmfcplotDoc::SetSearchContent(const CString& value) 146 | { 147 | if (value.IsEmpty()) 148 | { 149 | RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid); 150 | } 151 | else 152 | { 153 | CMFCFilterChunkValueImpl *pChunk = nullptr; 154 | ATLTRY(pChunk = new CMFCFilterChunkValueImpl); 155 | if (pChunk != nullptr) 156 | { 157 | pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT); 158 | SetChunkValue(pChunk); 159 | } 160 | } 161 | } 162 | 163 | #endif // SHARED_HANDLERS 164 | 165 | // CmfcplotDoc 诊断 166 | 167 | #ifdef _DEBUG 168 | void CmfcplotDoc::AssertValid() const 169 | { 170 | CDocument::AssertValid(); 171 | } 172 | 173 | void CmfcplotDoc::Dump(CDumpContext& dc) const 174 | { 175 | CDocument::Dump(dc); 176 | } 177 | #endif //_DEBUG 178 | 179 | 180 | // CmfcplotDoc 命令 181 | 182 | 183 | void CmfcplotDoc::OnAxisMenu() 184 | { 185 | // TODO: 在此添加命令处理程序代码 186 | m_WillShowAxis = !m_WillShowAxis; 187 | 188 | this->UpdateAllViews(NULL); 189 | } 190 | 191 | void CmfcplotDoc::OnGridMenu() 192 | { 193 | // TODO: 在此添加命令处理程序代码 194 | m_WillShowGrid = !m_WillShowGrid; 195 | this->UpdateAllViews(NULL); 196 | } 197 | 198 | 199 | 200 | void CmfcplotDoc::OnSmallerMenu() 201 | { 202 | // TODO: 在此添加命令处理程序代码 203 | double detx = (m_Xmax - m_Xmin) * 0.125; 204 | m_Xmax += detx; 205 | m_Xmin -= detx; 206 | double dety = (m_Ymax - m_Ymin) * 0.125; 207 | m_Ymax += dety; 208 | m_Ymin -= dety; 209 | UpdateAllViews(NULL); 210 | } 211 | 212 | 213 | void CmfcplotDoc::OnBiggerMenu() 214 | { 215 | // TODO: 在此添加命令处理程序代码 216 | double detx = (m_Xmax - m_Xmin) * 0.1; 217 | m_Xmax -= detx; 218 | m_Xmin += detx; 219 | double dety = (m_Ymax - m_Ymin) * 0.1; 220 | m_Ymax -= dety; 221 | m_Ymin += dety; 222 | UpdateAllViews(NULL); 223 | } 224 | 225 | 226 | 227 | void CmfcplotDoc::OnUpdateEdgeMenu(CCmdUI* pCmdUI) 228 | { 229 | // TODO: 在此添加命令更新用户界面处理程序代码 230 | pCmdUI->SetCheck(m_WillShowEdge); 231 | 232 | } 233 | 234 | 235 | void CmfcplotDoc::OnEdgeMenu() 236 | { 237 | // TODO: 在此添加命令处理程序代码 238 | m_WillShowEdge = !m_WillShowEdge; 239 | UpdateAllViews(NULL); 240 | } 241 | 242 | 243 | void CmfcplotDoc::OnMenuSetXyrange() 244 | { 245 | // TODO: 在此添加命令处理程序代码 246 | CSetXYrangeDlg dlg(m_Xmin, m_Xmax, m_Ymin, m_Ymax, nullptr); 247 | if (dlg.DoModal()) { 248 | if (dlg.m_Xmin >= dlg.m_Xmax || dlg.m_Ymin >= dlg.m_Ymax) 249 | AfxMessageBox(_T("输入不合法!")); 250 | else { 251 | m_Xmin = dlg.m_Xmin; 252 | m_Xmax = dlg.m_Xmax; 253 | m_Ymin = dlg.m_Ymin; 254 | m_Ymax = dlg.m_Ymax; 255 | UpdateAllViews(NULL); 256 | } 257 | } 258 | } 259 | 260 | 261 | void CmfcplotDoc::OnFuncMode() 262 | { 263 | // TODO: 在此添加命令处理程序代码 264 | m_SingelMode = !m_SingelMode; 265 | if (m_SingelMode == true) { 266 | this->OnDelallMenu(); 267 | } 268 | } 269 | 270 | 271 | void CmfcplotDoc::OnUpdateFuncMode(CCmdUI* pCmdUI) 272 | { 273 | // TODO: 在此添加命令更新用户界面处理程序代码 274 | pCmdUI->SetCheck(m_SingelMode); 275 | } 276 | 277 | 278 | void CmfcplotDoc::OnUpdateAxisMenu(CCmdUI* pCmdUI) 279 | { 280 | // TODO: 在此添加命令更新用户界面处理程序代码 281 | pCmdUI->SetCheck(m_WillShowAxis); 282 | } 283 | 284 | 285 | void CmfcplotDoc::OnUpdateGridMenu(CCmdUI* pCmdUI) 286 | { 287 | // TODO: 在此添加命令更新用户界面处理程序代码 288 | pCmdUI->SetCheck(m_WillShowGrid); 289 | } 290 | 291 | void CmfcplotDoc::OnNormalFuncMenu() 292 | { 293 | // TODO: 在此添加命令处理程序代码 294 | //CFuncDlg dlg; 295 | CNormalFuncDlg dlg(m_Xmin, m_Xmax, nullptr); 296 | // 297 | if (dlg.DoModal() == IDOK) 298 | { 299 | if (m_SingelMode) { 300 | if (m_FD) delete m_FD; 301 | m_List.RemoveAll(); 302 | } 303 | m_FD = new NormalFD(dlg.m_sEquation, dlg.m_Xmin, dlg.m_Xmax, dlg.m_stepX, dlg.m_color, dlg.m_penWidth, dlg.m_penType); 304 | if (m_FD->CalcList() == false) { 305 | AfxMessageBox(_T("请检查方程是否完整!")); 306 | } 307 | else { 308 | if (m_FD->minY < m_Ymin) m_Ymin = m_FD->minY; 309 | if (m_FD->maxY > m_Ymax) m_Ymax = m_FD->maxY; 310 | m_List.AddTail(m_FD); 311 | } 312 | 313 | } 314 | UpdateAllViews(NULL); 315 | } 316 | 317 | 318 | void CmfcplotDoc::OnPolarFuncMenu() 319 | { 320 | // TODO: 在此添加命令处理程序代码 321 | CPolarFuncDlg dlg; 322 | // 323 | if (dlg.DoModal() == IDOK) 324 | { 325 | if (m_SingelMode) { 326 | if (m_FD) delete m_FD; 327 | m_List.RemoveAll(); 328 | } 329 | m_FD = new PolarFD(dlg.m_sEquation, dlg.m_Thetamin, dlg.m_Thetamax, dlg.m_StepTheta, dlg.m_color, dlg.m_penWidth, dlg.m_penType); 330 | if (m_FD->CalcList() == false) { 331 | AfxMessageBox(_T("请检查方程是否完整!")); 332 | } 333 | else { 334 | if (m_FD->minY < m_Ymin) m_Ymin = m_FD->minY; 335 | if (m_FD->maxY > m_Ymax) m_Ymax = m_FD->maxY; 336 | if (m_FD->minX < m_Xmin) m_Xmin = m_FD->minX; 337 | if (m_FD->maxX > m_Xmax) m_Xmax = m_FD->maxX; 338 | m_List.AddTail(m_FD); 339 | } 340 | 341 | } 342 | UpdateAllViews(NULL); 343 | 344 | } 345 | 346 | 347 | void CmfcplotDoc::OnTwoFuncMenu() 348 | { 349 | // TODO: 在此添加命令处理程序代码 350 | CTwoFuncDlg dlg; 351 | if (dlg.DoModal() == IDOK) 352 | { 353 | if (m_SingelMode) { 354 | if (m_FD) delete m_FD; 355 | m_List.RemoveAll(); 356 | } 357 | m_FD = new TwoFD(dlg.m_sEquationX, dlg.m_sEquationY, dlg.m_Tmin, dlg.m_Tmax, dlg.m_stepT, dlg.m_color, dlg.m_penWidth, dlg.m_penType); 358 | if (m_FD->CalcList() == false) { 359 | AfxMessageBox(_T("请检查方程是否完整!")); 360 | } 361 | else { 362 | if (m_FD->minY < m_Ymin) m_Ymin = m_FD->minY; 363 | if (m_FD->maxY > m_Ymax) m_Ymax = m_FD->maxY; 364 | if (m_FD->minX < m_Xmin) m_Xmin = m_FD->minX; 365 | if (m_FD->maxX > m_Xmax) m_Xmax = m_FD->maxX; 366 | m_List.AddTail(m_FD); 367 | } 368 | 369 | } 370 | UpdateAllViews(NULL); 371 | } 372 | 373 | 374 | void CmfcplotDoc::OnDataFuncMenu() 375 | { 376 | // TODO: 在此添加命令处理程序代码 377 | CDataFuncDlg dlg; 378 | if (dlg.DoModal()) { 379 | if (m_SingelMode) { 380 | if (m_FD) delete m_FD; 381 | m_List.RemoveAll(); 382 | } 383 | m_FD = new DataFD(dlg.vetX, dlg.vetY, dlg.m_color, dlg.m_penWidth, dlg.m_penType); 384 | CString str; 385 | if (m_FD->minY < m_Ymin) m_Ymin = m_FD->minY; 386 | if (m_FD->maxY > m_Ymax) m_Ymax = m_FD->maxY; 387 | if (m_FD->minX < m_Xmin) m_Xmin = m_FD->minX; 388 | if (m_FD->maxX > m_Xmax) m_Xmax = m_FD->maxX; 389 | m_List.AddTail(m_FD); 390 | } 391 | 392 | UpdateAllViews(NULL); 393 | } 394 | 395 | 396 | void CmfcplotDoc::OnFroceXrang() 397 | { 398 | // TODO: 在此添加命令处理程序代码 399 | m_ForceXrange = !m_ForceXrange; 400 | UpdateAllViews(NULL); 401 | } 402 | 403 | 404 | void CmfcplotDoc::OnUpdateFroceXrang(CCmdUI* pCmdUI) 405 | { 406 | // TODO: 在此添加命令更新用户界面处理程序代码 407 | pCmdUI->SetCheck(m_ForceXrange); 408 | } 409 | 410 | 411 | void CmfcplotDoc::OnNearpointMenu() 412 | { 413 | // TODO: 在此添加命令处理程序代码 414 | m_ShowNearPoint = !m_ShowNearPoint; 415 | } 416 | 417 | 418 | void CmfcplotDoc::OnUpdateNearpointMenu(CCmdUI* pCmdUI) 419 | { 420 | // TODO: 在此添加命令更新用户界面处理程序代码 421 | pCmdUI->SetCheck(m_ShowNearPoint); 422 | } 423 | 424 | void CmfcplotDoc::OnDelallMenu() 425 | { 426 | // TODO: 在此添加命令处理程序代码 427 | POSITION p = m_List.GetHeadPosition(); 428 | while (p != nullptr) { 429 | FuncData* tmpFD = (FuncData*)m_List.GetNext(p); 430 | delete tmpFD; 431 | } 432 | m_List.RemoveAll(); 433 | UpdateAllViews(NULL); 434 | } 435 | 436 | 437 | void CmfcplotDoc::OnAutorangeMenu() 438 | { 439 | // TODO: 在此添加命令处理程序代码 440 | double miX = -10, maX = 10, miY = -1, maY = 1; 441 | POSITION p = m_List.GetHeadPosition(); 442 | bool flag = true; 443 | while (p) { 444 | FuncData* tmpFD = (FuncData*)m_List.GetNext(p); 445 | if (flag) { 446 | miY = tmpFD->minY; 447 | maY = tmpFD->maxY; 448 | miX = tmpFD->minX; 449 | maX = tmpFD->maxX; 450 | flag = false; 451 | } 452 | else { 453 | if (tmpFD->minY < miY) miY = tmpFD->minY; 454 | if (tmpFD->maxY > maY) maY = tmpFD->maxY; 455 | if (tmpFD->minX < miX) miX = tmpFD->minX; 456 | if (tmpFD->maxX > maX) maX = tmpFD->maxX; 457 | } 458 | } 459 | if (miX == maX) { 460 | miX -= 0.5; 461 | maX += 0.5; 462 | } 463 | if (miY == maY) { 464 | miY += 0.5; 465 | maY -= 0.5; 466 | } 467 | m_Xmin = miX; 468 | m_Xmax = maX; 469 | m_Ymin = miY; 470 | m_Ymax = maY; 471 | UpdateAllViews(NULL); 472 | } 473 | 474 | 475 | void CmfcplotDoc::OnDelfunconeMenu() 476 | { 477 | // TODO: 在此添加命令处理程序代码 478 | int cnt = 0, id = 0; 479 | CDelFuncDlg dlg; 480 | if (dlg.DoModal()) { 481 | id = dlg.m_id; 482 | } 483 | POSITION p = m_List.GetHeadPosition(),tmpp; 484 | while (p) { 485 | tmpp = p; 486 | FuncData* tmpFD = (FuncData*)m_List.GetNext(p); 487 | cnt++; 488 | if (cnt == id) { 489 | delete tmpFD; 490 | m_List.RemoveAt(tmpp); 491 | } 492 | } 493 | UpdateAllViews(NULL); 494 | } 495 | -------------------------------------------------------------------------------- /mfcplotDoc.h: -------------------------------------------------------------------------------- 1 |  2 | // mfcplotDoc.h: CmfcplotDoc 类的接口 3 | // 4 | 5 | #include "FuncData.h" 6 | #pragma once 7 | 8 | 9 | class CmfcplotDoc : public CDocument 10 | { 11 | protected: // 仅从序列化创建 12 | CmfcplotDoc() noexcept; 13 | DECLARE_DYNCREATE(CmfcplotDoc) 14 | 15 | // 特性 16 | public: 17 | bool m_WillShowGrid; //是否显示网格 18 | bool m_WillShowAxis; //是否显示坐标轴 19 | bool m_WillShowEdge; //是否显示边框 20 | bool m_SingelMode; //单函数模式添加函数自动删除上一个函数 21 | bool m_ForceXrange; //普通函数x范围是否固定,不固定的话随显示范围变化 22 | bool m_ShowNearPoint;//鼠标接近函数线时是否显示其坐标 23 | double m_Xmin, m_Xmax, m_Ymin, m_Ymax;//显示范围 24 | FuncData* m_FD;//临时变量 25 | CObList m_List;//记录所有函数信息 26 | // 操作 27 | public: 28 | 29 | // 重写 30 | public: 31 | virtual BOOL OnNewDocument(); 32 | virtual void Serialize(CArchive& ar); 33 | #ifdef SHARED_HANDLERS 34 | virtual void InitializeSearchContent(); 35 | virtual void OnDrawThumbnail(CDC& dc, LPRECT lprcBounds); 36 | #endif // SHARED_HANDLERS 37 | 38 | // 实现 39 | public: 40 | virtual ~CmfcplotDoc(); 41 | #ifdef _DEBUG 42 | virtual void AssertValid() const; 43 | virtual void Dump(CDumpContext& dc) const; 44 | #endif 45 | 46 | protected: 47 | 48 | // 生成的消息映射函数 49 | protected: 50 | DECLARE_MESSAGE_MAP() 51 | 52 | #ifdef SHARED_HANDLERS 53 | // 用于为搜索处理程序设置搜索内容的 Helper 函数 54 | void SetSearchContent(const CString& value); 55 | #endif // SHARED_HANDLERS 56 | public: 57 | afx_msg void OnAxisMenu();//坐标轴 58 | afx_msg void OnGridMenu();//网格 59 | afx_msg void OnEdgeMenu();//边框 60 | afx_msg void OnSmallerMenu();//显示范围缩小 0.8 61 | afx_msg void OnBiggerMenu();//显示范围放大 1.25 62 | afx_msg void OnNormalFuncMenu();//增加普通函数 63 | afx_msg void OnMenuSetXyrange();//设置显示范围 64 | afx_msg void OnFuncMode();//单/多函数模式 65 | afx_msg void OnPolarFuncMenu();//增加极坐标函数 66 | afx_msg void OnTwoFuncMenu();//增加参数方程函数 67 | afx_msg void OnDataFuncMenu();//增加数据点型函数 68 | afx_msg void OnFroceXrang();//普通函数x范围是否固定 69 | afx_msg void OnNearpointMenu();//是否显示最近点 70 | afx_msg void OnAutorangeMenu();//自动调整显示范围,正好显示完整函数图像 71 | afx_msg void OnDelfunconeMenu();//删除一个函数 72 | afx_msg void OnDelallMenu();//删除所有函数 73 | afx_msg void OnUpdateEdgeMenu(CCmdUI* pCmdUI); 74 | afx_msg void OnUpdateFuncMode(CCmdUI* pCmdUI); 75 | afx_msg void OnUpdateAxisMenu(CCmdUI* pCmdUI); 76 | afx_msg void OnUpdateGridMenu(CCmdUI* pCmdUI); 77 | afx_msg void OnUpdateFroceXrang(CCmdUI* pCmdUI); 78 | afx_msg void OnUpdateNearpointMenu(CCmdUI* pCmdUI); 79 | }; 80 | -------------------------------------------------------------------------------- /mfcplotView.cpp: -------------------------------------------------------------------------------- 1 |  2 | // mfcplotView.cpp: CmfcplotView 类的实现 3 | // 4 | 5 | #include "pch.h" 6 | #include "framework.h" 7 | // SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的 8 | // ATL 项目中进行定义,并允许与该项目共享文档代码。 9 | #ifndef SHARED_HANDLERS 10 | #include "mfcplot.h" 11 | #endif 12 | 13 | #include "mfcplotDoc.h" 14 | #include "mfcplotView.h" 15 | #include 16 | using std::vector; 17 | 18 | #ifdef _DEBUG 19 | #define new DEBUG_NEW 20 | #endif 21 | 22 | 23 | // CmfcplotView 24 | 25 | IMPLEMENT_DYNCREATE(CmfcplotView, CView) 26 | 27 | BEGIN_MESSAGE_MAP(CmfcplotView, CView) 28 | // 标准打印命令 29 | ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint) 30 | ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint) 31 | ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview) 32 | ON_WM_MOUSEMOVE() 33 | ON_WM_SETCURSOR() 34 | ON_COMMAND(ID_MOVE_MENU, &CmfcplotView::OnMoveMenu) 35 | ON_WM_LBUTTONDOWN() 36 | ON_WM_LBUTTONUP() 37 | ON_UPDATE_COMMAND_UI(ID_MOVE_MENU, &CmfcplotView::OnUpdateMoveMenu) 38 | ON_WM_LBUTTONDBLCLK() 39 | END_MESSAGE_MAP() 40 | 41 | // CmfcplotView 构造/析构 42 | 43 | CmfcplotView::CmfcplotView() noexcept 44 | { 45 | // TODO: 在此处添加构造代码 46 | isMoving = false; 47 | //下面这个没什么用,防止编译警告 48 | tmp_Xmin = m_Xmin = -10; 49 | tmp_Xmax = m_Xmax = 10; 50 | tmp_Ymin = m_Ymin = -1; 51 | tmp_Ymax = m_Ymax = 1; 52 | } 53 | 54 | CmfcplotView::~CmfcplotView() 55 | { 56 | } 57 | 58 | BOOL CmfcplotView::PreCreateWindow(CREATESTRUCT& cs) 59 | { 60 | // TODO: 在此处通过修改 61 | // CREATESTRUCT cs 来修改窗口类或样式 62 | 63 | return CView::PreCreateWindow(cs); 64 | } 65 | 66 | 67 | double CmfcplotView::LPxtoFPx(int x) { 68 | return m_Xmin + (1.0 * x - nLeft) * (m_Xmax - m_Xmin) / (1.0 * nRight - nLeft); 69 | } 70 | 71 | int CmfcplotView::FPxtoLPx(double x) { 72 | return nLeft + (int)round((x - m_Xmin) * (1.0 * nRight - nLeft) / (m_Xmax - m_Xmin)); 73 | } 74 | 75 | double CmfcplotView::LPytoFPy(int y) { 76 | return m_Ymin + (1.0 * nButton - y) * (m_Ymax - m_Ymin) / (1.0 * nButton - nTop); 77 | } 78 | 79 | int CmfcplotView::FPytoLPy(double y) { 80 | return nButton - (int)round((y - m_Ymin) * (1.0 * nButton - nTop) / (m_Ymax - m_Ymin)); 81 | } 82 | 83 | // CmfcplotView 绘图 84 | 85 | void CmfcplotView::OnDraw(CDC* pDC) 86 | { 87 | CmfcplotDoc* pDoc = GetDocument(); 88 | ASSERT_VALID(pDoc); 89 | if (!pDoc) 90 | return; 91 | m_Xmin = pDoc->m_Xmin;//极值保存在Doc中 92 | m_Xmax = pDoc->m_Xmax; 93 | m_Ymin = pDoc->m_Ymin; 94 | m_Ymax = pDoc->m_Ymax; 95 | 96 | CRect rect; 97 | GetClientRect(&rect);//获得视图区 98 | 99 | nTop = (int)round(rect.bottom * 0.1); //函数图像不会占据整个视图区 100 | nButton = (int)round(rect.bottom * 0.9); 101 | nLeft = (int)round(rect.right * 0.1); 102 | nRight = (int)round(rect.right * 0.9); 103 | 104 | if (pDoc->m_WillShowEdge) {//画边框 105 | pDC->MoveTo(nLeft, nTop); 106 | pDC->LineTo(nLeft, nButton); 107 | pDC->LineTo(nRight, nButton); 108 | pDC->LineTo(nRight, nTop); 109 | pDC->LineTo(nLeft, nTop); 110 | } 111 | 112 | //画x坐标信息 113 | int nX,nY; 114 | bool BIGX = abs(m_Xmin) > 100 || abs(m_Xmax) > 100;//x坐标值比较大时,标注更稀 115 | for (nX = nLeft; nX < nRight; nX += (BIGX ? 100 : 50)) { //每隔100/50像素一个标注 116 | CRect textRect(nX - (BIGX ? 50 : 25), nButton + 1, nX + (BIGX ? 50 : 25), nButton + 20);//显示区域 117 | CString xInfo; 118 | xInfo.Format(_T("%.2f"),LPxtoFPx(nX)); 119 | pDC->DrawText(xInfo, &textRect, DT_SINGLELINE | DT_CENTER); 120 | //单行,上下左右居中显示 121 | } 122 | if (nX - nRight <= (BIGX ? 50 : 25)) {//最后一个x坐标,与前一个标注距离太近则不显示 123 | CRect textRect(nRight, nButton + 1, nRight + 50, nButton + 20); 124 | CString xInfo; 125 | xInfo.Format(_T("%.2f"),m_Xmax); 126 | pDC->DrawText(xInfo, &textRect, DT_SINGLELINE | DT_LEFT | DT_TOP); 127 | } 128 | 129 | //y坐标 130 | for (nY = nButton - 50; nY > nTop; nY -= 50) { 131 | CRect textRect(nLeft - 200, nY-10, nLeft - 3, nY + 10); 132 | CString yInfo; 133 | yInfo.Format(_T("%.2f"), LPytoFPy(nY)); 134 | pDC->DrawText(yInfo, &textRect, DT_SINGLELINE | DT_RIGHT); 135 | } 136 | if (nTop - nY <= 25) { 137 | CRect textRect(nLeft - 200, nTop - 10, nLeft - 3, nTop + 10); 138 | CString yInfo; 139 | yInfo.Format(_T("%.2f"),m_Ymax); 140 | pDC->DrawText(yInfo, &textRect, DT_SINGLELINE | DT_BOTTOM | DT_RIGHT); 141 | } 142 | 143 | 144 | // 显示网格 145 | if (pDoc->m_WillShowGrid) { 146 | CPen pen(PS_DOT, 1, RGB(100, 100, 100)); //创建笔,虚线,并调整坐标颜色灰色 147 | CPen *pOldPen = (CPen *)pDC->SelectObject(&pen); 148 | for (nX = nLeft+50; nX < nRight; nX += 50) { 149 | pDC->MoveTo(nX, nTop); 150 | pDC->LineTo(nX, nButton); 151 | } 152 | for (nY = nButton - 50; nY > nTop; nY -= 50) { 153 | pDC->MoveTo(nLeft, nY); 154 | pDC->LineTo(nRight, nY); 155 | } 156 | pDC->SelectObject(pOldPen); 157 | } 158 | 159 | // 显示坐标轴 160 | if (pDoc->m_WillShowAxis) { 161 | CPen pen(PS_SOLID, 2, RGB(0, 0, 0)); 162 | CPen* pOldPen = (CPen*)pDC->SelectObject(&pen); 163 | int oX = FPxtoLPx(0); 164 | int oY = FPytoLPy(0); 165 | bool showY = oX >= nLeft && oX <= nRight; 166 | bool showX = oY >= nTop && oY <= nButton;//判断x,y轴是否在范围内 167 | if (showX) { 168 | pDC->MoveTo(nLeft - 10, oY); 169 | pDC->LineTo(nRight + 10, oY); 170 | } 171 | if (showY) { 172 | pDC->MoveTo(oX, nButton + 10); 173 | pDC->LineTo(oX, nTop - 10); 174 | } 175 | if (showX && showY) { 176 | pDC->TextOutW(oX + 1, oY + 1, _T("O")); 177 | } 178 | if (showX) { 179 | pDC->MoveTo(nRight + 10, oY); 180 | pDC->LineTo(nRight + 5, oY + 5); 181 | pDC->MoveTo(nRight + 10, oY); 182 | pDC->LineTo(nRight + 5, oY - 5); 183 | pDC->TextOutW(nRight + 10, oY, _T("X轴")); 184 | } 185 | if (showY) { 186 | pDC->MoveTo(oX, nTop - 10); 187 | pDC->LineTo(oX - 5, nTop - 5); 188 | pDC->MoveTo(oX, nTop - 10); 189 | pDC->LineTo(oX + 5, nTop - 5); 190 | pDC->TextOutW(oX + 5, nTop - 10, _T("Y轴")); 191 | } 192 | pDC->SelectObject(pOldPen); 193 | } 194 | 195 | 196 | POSITION p = pDoc->m_List.GetHeadPosition(); 197 | 198 | int showTop = nTop; 199 | while (p != nullptr) { 200 | bool shouldMov = true;//一段曲线第一个点MoveTo,其他都是LineTo 201 | FuncData* tmpFD = (FuncData*)pDoc->m_List.GetNext(p); 202 | CPen pen(tmpFD->m_penType, tmpFD->m_penWidth, tmpFD->m_color); 203 | CPen* pOldPen = (CPen*)pDC->SelectObject(&pen); 204 | 205 | if (tmpFD->FuncCas == CAS_NORMAL) {//动态X坐标模式下,普通函数x范围与视图不同时自动同步 206 | if (pDoc->m_ForceXrange && isMoving!=2) 207 | if (tmpFD->minX != m_Xmin || tmpFD->maxX != m_Xmax) { 208 | tmpFD->minX = m_Xmin; 209 | tmpFD->maxX = m_Xmax; 210 | tmpFD->CalcList(); 211 | } 212 | } 213 | 214 | for (auto dot : tmpFD->vetPoint) { 215 | if (dot.first < m_Xmin || dot.first > m_Xmax || dot.second < m_Ymin || dot.second > m_Ymax || dot.second != dot.second) { 216 | shouldMov = true; 217 | continue; 218 | } 219 | if (shouldMov) { 220 | pDC->MoveTo(FPxtoLPx(dot.first), FPytoLPy(dot.second)); 221 | shouldMov = false; 222 | } 223 | else 224 | pDC->LineTo(FPxtoLPx(dot.first), FPytoLPy(dot.second)); 225 | } 226 | 227 | pDC->MoveTo(nRight+5, showTop);//显示图例 228 | pDC->LineTo(rect.right, showTop); 229 | showTop += 5; 230 | if (tmpFD->FuncCas == CAS_NORMAL) 231 | pDC->TextOutW(nRight + 5, showTop, _T("f(x)=")+tmpFD->m_Equation); 232 | else if (tmpFD->FuncCas == CAS_POLAR) 233 | pDC->TextOutW(nRight + 5, showTop, _T("r(t)=") + tmpFD->m_Equation); 234 | else if (tmpFD->FuncCas == CAS_TWO) { 235 | pDC->TextOutW(nRight + 5, showTop, _T("x(t)=") + tmpFD->m_Equation); 236 | showTop += 20; 237 | pDC->TextOutW(nRight + 5, showTop, _T("y(t)=") + tmpFD->GetEquation2()); 238 | } else if (tmpFD->FuncCas == CAS_DATA) 239 | pDC->TextOutW(nRight + 5, showTop, _T("y(t)=") + tmpFD->m_Equation); 240 | showTop += 25; 241 | pDC->SelectObject(pOldPen); 242 | } 243 | } 244 | 245 | 246 | // CmfcplotView 打印 247 | 248 | BOOL CmfcplotView::OnPreparePrinting(CPrintInfo* pInfo) 249 | { 250 | // 默认准备 251 | return DoPreparePrinting(pInfo); 252 | } 253 | 254 | void CmfcplotView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 255 | { 256 | // TODO: 添加额外的打印前进行的初始化过程 257 | } 258 | 259 | void CmfcplotView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 260 | { 261 | // TODO: 添加打印后进行的清理过程 262 | } 263 | 264 | 265 | // CmfcplotView 诊断 266 | 267 | #ifdef _DEBUG 268 | void CmfcplotView::AssertValid() const 269 | { 270 | CView::AssertValid(); 271 | } 272 | 273 | void CmfcplotView::Dump(CDumpContext& dc) const 274 | { 275 | CView::Dump(dc); 276 | } 277 | 278 | CmfcplotDoc* CmfcplotView::GetDocument() const // 非调试版本是内联的 279 | { 280 | ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CmfcplotDoc))); 281 | return (CmfcplotDoc*)m_pDocument; 282 | } 283 | #endif //_DEBUG 284 | 285 | 286 | // CmfcplotView 消息处理程序 287 | bool tmp_redraw = false; 288 | 289 | void CmfcplotView::OnMouseMove(UINT nFlags, CPoint point) 290 | { 291 | // TODO: 在此添加消息处理程序代码和/或调用默认值 292 | 293 | CStatusBar* pBar = (CStatusBar*)AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR); 294 | if (pBar) { 295 | CString msg; 296 | if (point.x >= nLeft && point.x <= nRight && point.y >= nTop && point.y <= nButton) 297 | msg.Format(_T("(%.1f,%.1f)"), LPxtoFPx(point.x), LPytoFPy(point.y)); 298 | else 299 | msg = _T("(NaN,NaN)"); 300 | pBar->SetPaneText(1, msg); 301 | } 302 | 303 | if (isMoving==2) { 304 | ::SetCursor(LoadCursor(NULL, IDC_SIZEALL)); 305 | CmfcplotDoc* pDoc = GetDocument(); 306 | double detx = LPxtoFPx(point.x) - LPxtoFPx(m_posStart.x); 307 | pDoc->m_Xmin = tmp_Xmin - detx; 308 | pDoc->m_Xmax = tmp_Xmax - detx; 309 | double dety = LPytoFPy(point.y) - LPytoFPy(m_posStart.y); 310 | pDoc->m_Ymin = tmp_Ymin - dety; 311 | pDoc->m_Ymax = tmp_Ymax - dety; 312 | //RedrawWindow(); 313 | CDC* pDC = GetDC(); 314 | //创建一个内存中的显示设备 315 | CDC MemDC; 316 | MemDC.CreateCompatibleDC(NULL); 317 | //创建一个内存中的图像 318 | CBitmap MemBitmap; 319 | CRect rect; 320 | GetClientRect(&rect); 321 | MemBitmap.CreateCompatibleBitmap(pDC, rect.right, rect.bottom); 322 | //指定内存显示设备在内存中的图像上画图 323 | MemDC.SelectObject(&MemBitmap); 324 | //先用一种颜色作为内存显示设备的背景色 325 | MemDC.FillSolidRect(rect.left, rect.top, rect.right, rect.bottom, RGB(144, 144, 144)); 326 | this->OnDraw(&MemDC); 327 | //将内存中画好的图像直接拷贝到屏幕指定区域上 328 | pDC->BitBlt(rect.left, rect.top, rect.right, rect.bottom, &MemDC, 0, 0, SRCCOPY); 329 | 330 | //释放相关资源 331 | ReleaseDC(pDC); 332 | 333 | } 334 | else if (isMoving == 1) { 335 | ::SetCursor(LoadCursor(NULL, IDC_HAND)); 336 | } 337 | 338 | CmfcplotDoc* pDoc = GetDocument(); 339 | if (GetDocument()->m_ShowNearPoint && isMoving != 2) { 340 | 341 | pair nearDot(1e14, 1e14); 342 | pair nowDot = std::make_pair(LPxtoFPx(point.x), LPytoFPy(point.y));//当前函数坐标 343 | POSITION p = pDoc->m_List.GetHeadPosition(); 344 | COLORREF tmpcolor = RGB(0, 0, 0); 345 | while (p != nullptr) { 346 | FuncData* tmpFD = (FuncData*)pDoc->m_List.GetNext(p); 347 | if (tmpFD->GetNearest(nowDot, nearDot)) { 348 | tmpcolor = tmpFD->m_color;//枚举函数,找最近的 349 | } 350 | } 351 | int nX = FPxtoLPx(nearDot.first); 352 | int nY = FPytoLPy(nearDot.second); 353 | 354 | CDC* pDC = GetDC(); 355 | if (tmp_redraw) {//标记有输出,刷新 356 | CDC MemDC; 357 | MemDC.CreateCompatibleDC(NULL); 358 | CBitmap MemBitmap; 359 | CRect rect; 360 | GetClientRect(&rect); 361 | MemBitmap.CreateCompatibleBitmap(pDC, rect.right, rect.bottom); 362 | MemDC.SelectObject(&MemBitmap); 363 | MemDC.FillSolidRect(rect.left, rect.top, rect.right, rect.bottom, RGB(255, 255, 255)); 364 | this->OnDraw(&MemDC); 365 | pDC->BitBlt(rect.left, rect.top, rect.right, rect.bottom, &MemDC, 0, 0, SRCCOPY); 366 | } 367 | if (abs(nX - point.x) < 5 && abs(nY - point.y) < 5) { 368 | tmp_redraw = true;//输出了,标记一下 369 | CString msg; 370 | msg.Format(_T("(%.2f,%.2f)"), nearDot.first, nearDot.second); 371 | CRect textrect(nX, nY - 10, nX + 100, nY + 10); 372 | COLORREF oldcolor = pDC->SetTextColor(tmpcolor); 373 | pDC->DrawText(msg, &textrect, DT_SINGLELINE | DT_CENTER); 374 | pDC->SetTextColor(oldcolor); 375 | } 376 | 377 | ReleaseDC(pDC); 378 | } 379 | 380 | CView::OnMouseMove(nFlags, point); 381 | } 382 | 383 | BOOL CmfcplotView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 384 | { 385 | // TODO: 在此添加消息处理程序代码和/或调用默认值 386 | if (isMoving) { 387 | return TRUE; 388 | } 389 | return CView::OnSetCursor(pWnd, nHitTest, message); 390 | } 391 | 392 | 393 | void CmfcplotView::OnMoveMenu() 394 | { 395 | // TODO: 在此添加命令处理程序代码 396 | if (isMoving) { 397 | isMoving = 0; 398 | } 399 | else { 400 | isMoving = 1; 401 | ::SetCursor(LoadCursor(NULL, IDC_HAND)); 402 | } 403 | } 404 | 405 | 406 | 407 | void CmfcplotView::OnLButtonDown(UINT nFlags, CPoint point) 408 | { 409 | // TODO: 在此添加消息处理程序代码和/或调用默认值 410 | SetCapture(); 411 | if (isMoving == 1) { 412 | isMoving = 2; 413 | m_posStart = point; 414 | CmfcplotDoc* pDoc = GetDocument(); 415 | tmp_Xmin = pDoc->m_Xmin; 416 | tmp_Xmax = pDoc->m_Xmax; 417 | tmp_Ymin = pDoc->m_Ymin; 418 | tmp_Ymax = pDoc->m_Ymax; 419 | ::SetCursor(LoadCursor(NULL, IDC_SIZEALL)); 420 | } 421 | CView::OnLButtonDown(nFlags, point); 422 | } 423 | 424 | 425 | void CmfcplotView::OnLButtonUp(UINT nFlags, CPoint point) 426 | { 427 | // TODO: 在此添加消息处理程序代码和/或调用默认值 428 | if (isMoving == 2) { 429 | isMoving = 1; 430 | ::SetCursor(LoadCursor(NULL, IDC_HAND)); 431 | CmfcplotDoc* pDoc = GetDocument(); 432 | double detx = LPxtoFPx(point.x) - LPxtoFPx(m_posStart.x); 433 | pDoc->m_Xmin = tmp_Xmin - detx; 434 | pDoc->m_Xmax = tmp_Xmax - detx; 435 | double dety = LPytoFPy(point.y) - LPytoFPy(m_posStart.y); 436 | pDoc->m_Ymin = tmp_Ymin - dety; 437 | pDoc->m_Ymax = tmp_Ymax - dety; 438 | RedrawWindow(); 439 | } 440 | ReleaseCapture(); 441 | CView::OnLButtonUp(nFlags, point); 442 | } 443 | 444 | 445 | void CmfcplotView::OnUpdateMoveMenu(CCmdUI* pCmdUI) 446 | { 447 | // TODO: 在此添加命令更新用户界面处理程序代码 448 | pCmdUI->SetCheck(isMoving!=0); 449 | } 450 | 451 | 452 | void CmfcplotView::OnLButtonDblClk(UINT nFlags, CPoint point) 453 | { 454 | // TODO: 在此添加消息处理程序代码和/或调用默认值 455 | CString msg; 456 | msg.Format(_T("(%.4f,%.4f)"), LPxtoFPx(point.x), LPytoFPy(point.y)); 457 | AfxMessageBox(msg); 458 | CView::OnLButtonDblClk(nFlags, point); 459 | } 460 | -------------------------------------------------------------------------------- /mfcplotView.h: -------------------------------------------------------------------------------- 1 |  2 | // mfcplotView.h: CmfcplotView 类的接口 3 | // 4 | 5 | #pragma once 6 | 7 | 8 | class CmfcplotView : public CView 9 | { 10 | protected: // 仅从序列化创建 11 | CmfcplotView() noexcept; 12 | DECLARE_DYNCREATE(CmfcplotView) 13 | 14 | // 特性 15 | public: 16 | CmfcplotDoc* GetDocument() const; 17 | 18 | // 操作 19 | public: 20 | double m_Xmin, m_Xmax, m_Ymin, m_Ymax;//函数显示范围 21 | int nTop, nButton, nLeft, nRight;//对应的逻辑坐标范围 22 | int isMoving;//拖动状态 0不拖动 1拖动模式 2正在拖动 23 | double tmp_Xmin, tmp_Xmax, tmp_Ymin, tmp_Ymax; 24 | //拖动模式下,单击鼠标左键,记录起点的显示范围 25 | CPoint m_posStart; 26 | //拖动模式下,单击鼠标左键,记录起点的鼠标坐标 27 | //根据鼠标坐标偏移量可以计算显示范围变化量 28 | 29 | double LPxtoFPx(int x); 30 | int FPxtoLPx(double x); 31 | double LPytoFPy(int y); 32 | int FPytoLPy(double y); 33 | 34 | // 重写 35 | public: 36 | virtual void OnDraw(CDC* pDC); // 重写以绘制该视图 37 | virtual BOOL PreCreateWindow(CREATESTRUCT& cs); 38 | protected: 39 | virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); 40 | virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); 41 | virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); 42 | 43 | // 实现 44 | public: 45 | virtual ~CmfcplotView(); 46 | #ifdef _DEBUG 47 | virtual void AssertValid() const; 48 | virtual void Dump(CDumpContext& dc) const; 49 | #endif 50 | 51 | protected: 52 | 53 | // 生成的消息映射函数 54 | protected: 55 | DECLARE_MESSAGE_MAP() 56 | public: 57 | afx_msg void OnMouseMove(UINT nFlags, CPoint point); 58 | afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); 59 | afx_msg void OnMoveMenu(); 60 | afx_msg void OnLButtonDown(UINT nFlags, CPoint point); 61 | afx_msg void OnLButtonUp(UINT nFlags, CPoint point); 62 | afx_msg void OnUpdateMoveMenu(CCmdUI* pCmdUI); 63 | afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); 64 | }; 65 | 66 | #ifndef _DEBUG // mfcplotView.cpp 中的调试版本 67 | inline CmfcplotDoc* CmfcplotView::GetDocument() const 68 | { return reinterpret_cast(m_pDocument); } 69 | #endif 70 | 71 | -------------------------------------------------------------------------------- /pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: 与预编译标头对应的源文件 2 | 3 | #include "pch.h" 4 | 5 | // 当使用预编译的头时,需要使用此源文件,编译才能成功。 6 | -------------------------------------------------------------------------------- /pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: 这是预编译标头文件。 2 | // 下方列出的文件仅编译一次,提高了将来生成的生成性能。 3 | // 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 4 | // 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 5 | // 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // 添加要在此处预编译的标头 11 | #include "framework.h" 12 | 13 | #endif //PCH_H 14 | -------------------------------------------------------------------------------- /res/Toolbar.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wineee/mfcplot/4f081ca7d0121d4e1011eda4178e99c4f8d24794/res/Toolbar.bmp -------------------------------------------------------------------------------- /res/icon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wineee/mfcplot/4f081ca7d0121d4e1011eda4178e99c4f8d24794/res/icon1.ico -------------------------------------------------------------------------------- /res/mfcplot.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wineee/mfcplot/4f081ca7d0121d4e1011eda4178e99c4f8d24794/res/mfcplot.ico -------------------------------------------------------------------------------- /res/mfcplot.rc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wineee/mfcplot/4f081ca7d0121d4e1011eda4178e99c4f8d24794/res/mfcplot.rc2 -------------------------------------------------------------------------------- /res/mfcplotDoc.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wineee/mfcplot/4f081ca7d0121d4e1011eda4178e99c4f8d24794/res/mfcplotDoc.ico -------------------------------------------------------------------------------- /targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。 4 | 5 | // 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将 6 | // 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。 7 | 8 | #include 9 | --------------------------------------------------------------------------------