先来一发软件截图~~~c++
因为对传统的对话框风格不太满意,因此此次做业的图形界面我使用了彻底重绘界面的方法来开发。本次图形界面基于MFC的对话框界面开发,可是去掉了对话框的边框,使用设备环境句柄自绘界面,虽然配色不太好,可是我对总体的效果仍是比较满意的。算法
MFC虽然默认的窗口不太好看,可是对各类消息的回调函数接口仍是比较完善的,基于此,我重载了onPaint函数来自绘界面,重载OnLButtonDown函数设置鼠标点击事件,重载OnMouseMove设置鼠标悬停事件来实现鼠标悬停在按钮上时变色。windows
预计的三个模块(生成题目、计算答案、历史记录)分别为三个非模态子窗口,鼠标左键点击不一样标题以后改变每一个窗口的SW_SHOW
和SW_HIDE
属性。函数
核心模块是使用c++ Console Application
编写,为了使它可以被MFC程序调用,咱们就须要将工程转为dll Project
。学习
#ifdef WIN32DLL_EXPORTS #define MY_TEST_API __declspec(dllexport) #else #define MY_TEST_API __declspec(dllimport) #endif #include "ProblemSet.h" class MY_TEST_API CCore { public: CCore(); ~CCore(); }; extern "C" { MY_TEST_API void gen(int a, int b, int c, int d, int e, int f, int g, char *s); MY_TEST_API void calc(char *s, char *ret); }
这是统一的函数声明方式,以前考虑直接在类中建立动态加载的函数,可是因为某种未知缘由,类中的函数老是不能加载,因此就采起了extern "C"
的方式。
在对应的.cpp文件中实现这两个函数即完成了dll工程的编写。编译以后的.dll文件便可被其余程序调用。测试
typedef void(*FUNC_GEN)(int a, int b,int c,int d, int e, int f,int g,char *ch); typedef void(*FUNC_CALC)(char* a, char *b);
HMODULE hDLL = ::LoadLibrary(L"ArchCore.dll"); if (!hDLL) { MessageBox(L"未找到ArchCore.dll文件!"); return; }
FUNC_GEN gen = (FUNC_GEN)::GetProcAddress(hDLL, "gen"); if (gen != NULL) { ... } FUNC_CALC calc = (FUNC_CALC)::GetProcAddress(hDLL, "calc"); if (calc != NULL) { ... }
在结对项目开始之初,我就与另外一个团队(pair16,学号后四位为1179)订好了公共的接口方案,在咱们各自完成了本身的部分以后,咱们交换了core部分的dll文件进行互测。设计
因为咱们采用的是在运行时动态加载dll的方法,所以交换dll并不须要对代码进行修改,仅仅须要把HMODULE hDLL = ::LoadLibrary(L"ArchCore.dll");
之中的dll文件名修改成另外一个同窗的文件名就好。指针
通过测试,咱们的dll在互相换事后也彻底可以运行,没有任何问题。只不过因为个人core文件采用了输入输出流的方式处理输入输出,所以运行起来会有一些慢。code
我万万没想到的是采用重载输入输出流的方式输出表达式竟然会对程序效率产生这么大的影响!!本来觉得只有在ACM竞赛这样对时间要求很严格的状况下流输入才会有影响,没想到在此次项目中也遇到了这个问题(对一样的题目进行计算标准答案并输出,使用个人Core须要大概20s才能出解, 而使用另外一个团队的core则仅需5s便可出解,咱们的算法设计没有什么区别,惟一的区别就是我采用了流输入输出,而他则是直接用一个toString函数处理的)。接口
此次的图形界面设计和core设计几乎是彻底独立的,仅须要经过dll进行链接,这在以前是从没有接触过的,感受很是神奇,不过我对dll的使用仍然存在许多不理解的地方,好比为何只有经过extern "C"
的方式生命的函数可以正确调用,而在CCore类中声明的函数则没法正确调用(在网上查资料说c++生成dll以后的函数名会发生变化,可是我也没法知道究竟是变成了什么)。这些都是之后须要学习的地方。
BTW,我仍是计划加入”历史记录“这个功能,另外,文件的选取但愿不是经过手动输入路径的方式进行,而是调用windows资源管理器进行选取。