先來一發軟件截圖~~~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資源管理器進行選取。