软件工程结对编程第2次作业 - 图形界面四则运算生成工具

Posted linaria

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件工程结对编程第2次作业 - 图形界面四则运算生成工具相关的知识,希望对你有一定的参考价值。

图形界面的四则运算生成工具

一个简单的图形界面四则运算生成工具 by Linaria with ??

环境

  • 操作系统:Windows 10
  • 语言:C++ / XML
  • 集成开发环境:Visual studio 2017

界面

主界面

技术分享图片

关于页面

技术分享图片

界面设计基于开源UI库 duilib

代码实现

全部代码托管在Coding

题目生成

int PrintQuestions(int amount, int symbolCount, int maxNumber, bool haveBrackets, bool haveFloat, char* outPath) {
    int a, b;
    float c, d;
    std::ofstream questionFile;
    questionFile.open(outPath);

    if (questionFile.fail()) {
        return -1;
    }

    if (!haveBrackets) {
        if (!haveFloat) {
            for (int i = 0; i < amount; i++) {
                if (100 == maxNumber) {
                    a = rand() % 100 + 1;
                    b = rand() % 100 + 1;
                }

                if (10 == maxNumber) {
                    a = rand() % 10 + 1;
                    b = rand() % 10 + 1;
                }

                questionFile << a << GetSymbols(symbolCount) << b << "=\\n";
            }
        } else {
            for (int i = 0; i < amount; i++) {
                if (100 == maxNumber) {
                    c = rand() * 0.001 + 1;
                    d = rand() * 0.001 + 1;
                } else {
                    c = rand() * 0.0001 + 1;
                    d = rand() * 0.0001 + 1;
                }

                questionFile << c << GetSymbols(symbolCount) << d << "=\\n";
            }
        }
    } else {
        int r = 0, e;

        if (!haveFloat) {
            for (int i = 0; i < amount; i++) {
                r = 0;
                e = rand() % 2 + 1;

                if (e == 1) {
                    questionFile << "(";
                    r++;
                }

                if (100 == maxNumber) {
                    a = rand() % 100 + 1;
                    b = rand() % 100 + 1;
                } else {
                    a = rand() % 10 + 1;
                    b = rand() % 10 + 1;
                }

                questionFile << a << GetSymbols(symbolCount);
                e = rand() % 2 + 1;

                if (1 == e) {
                    questionFile << "(";
                    r++;
                }

                questionFile << b << GetSymbols(symbolCount);

                if (100 == maxNumber) {
                    a = rand() % 100 + 1;
                    b = rand() % 100 + 1;
                } else {
                    a = rand() % 10 + 1;
                    b = rand() % 10 + 1;
                }

                questionFile << a;
                e = rand() % 2 + 1;

                if (e == 1 && r != 0) {
                    questionFile << ")";
                    r--;
                }

                if (r == 2) {
                    questionFile << ")" << GetSymbols(symbolCount) << b;
                    r--;
                }

                if (r != 0) {
                    questionFile << ")=";
                } else {
                    questionFile << "=";
                }

                questionFile << "\\n";
            }
        } else {
            for (int i = 0; i < amount; i++) {
                r = 0;
                e = rand() % 2 + 1;

                if (e == 1) {
                    questionFile << "(";
                    r++;
                }

                if (100 == maxNumber) {
                    c = rand() * 0.001 + 1;
                    d = rand() * 0.001 + 1;
                } else {
                    c = rand() * 0.0001 + 1;
                    d = rand() * 0.0001 + 1;
                }

                questionFile << c << GetSymbols(symbolCount);
                e = rand() % 2 + 1;

                if (e == 1) {
                    questionFile << "(";
                    r++;
                }

                questionFile << d << GetSymbols(symbolCount);

                if (100 == maxNumber) {
                    c = rand() * 0.001 + 1;
                    d = rand() * 0.001 + 1;
                } else {
                    c = rand() * 0.0001 + 1;
                    d = rand() * 0.0001 + 1;
                }

                questionFile << c;
                e = rand() % 2 + 1;

                if (e == 1 && r != 0) {
                    questionFile << ")";
                    r--;
                }

                if (r == 2) {
                    questionFile << ")";
                    r--;
                }

                questionFile << GetSymbols(symbolCount) << d;

                if (r != 0) {
                    questionFile << ")=";
                } else {
                    questionFile << "=";
                }

                questionFile << "\\n";
            }
        }
    }

    questionFile.close();
    return 0;
}

界面绘制及事件响应

class ToolsFrameWnd : public CWindowWnd, public INotifyUI {
  public:
    LPCTSTR GetWindowClassName() const {
        return _T("UIMainFrame");
    };
    UINT GetClassStyle() const {
        return CS_DBLCLKS;
    };
    void OnFinalMessage(HWND /*hWnd*/) {
        delete this;
    };

    void Init() {
        m_pCloseBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("closebtn")));
        m_pMaxBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("maxbtn")));
        m_pRestoreBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("restorebtn")));
        m_pMinBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("minbtn")));
        m_qAmount = static_cast<CTextUI*>(m_pm.FindControl(_T("Amount")));
        m_logPrint = static_cast<CTextUI*>(m_pm.FindControl(_T("logprint")));
        m_symbol = static_cast<CComboUI*>(m_pm.FindControl(_T("Symbol")));
        m_maxnumber = static_cast<CComboUI*>(m_pm.FindControl(_T("MaxNumber")));
        m_HaveBrackets = static_cast<CComboUI*>(m_pm.FindControl(_T("HaveBrackets")));
        m_HaveFloat = static_cast<CComboUI*>(m_pm.FindControl(_T("HaveFloat")));
        m_OutputMode = static_cast<CComboUI*>(m_pm.FindControl(_T("OutputMode")));
        m_OutputPath = static_cast<CComboUI*>(m_pm.FindControl(_T("OutputPath")));
    }

    void OnPrepare() {
    }

    void Notify(TNotifyUI& msg) {
        if (msg.sType == _T("windowinit")) OnPrepare();
        else if (msg.sType == _T("click")) {
            if (msg.pSender == m_pCloseBtn) {
                PostQuitMessage(0);
                return;
            } else if (msg.pSender->GetName() == _T("GButton")) {
                wstring amount(m_qAmount->GetText()); // lpcwstr to int
                int symbolCount = 0;
                wstring symbolName(m_symbol->GetText());
                wstring maxNumberText(m_maxnumber->GetText());
                int maxNumber = 10;
                wstring haveBracketsText(m_HaveBrackets->GetText());
                bool haveBrackets = false;
                wstring haveFloatText(m_HaveBrackets->GetText());
                bool haveFloat = false;
                wstring OutputPathText(m_OutputPath->GetText());
                char OutputPath[MAX_PATH];
                std::wcstombs(OutputPath, OutputPathText.c_str(), MAX_PATH);

                if (L"+ 和 -" == symbolName) {
                    symbolCount = 1;
                } else if (L"/ 和 *" == symbolName) {
                    symbolCount = 2;
                } else {
                    symbolCount = 3;
                }

                if (L"10" == maxNumberText) {
                    maxNumber = 10;
                } else {
                    maxNumber = 100;
                }

                if (L"是" == haveBracketsText) {
                    haveBrackets = true;
                } else {
                    haveBrackets = false;
                }

                if (L"是" == haveFloatText) {
                    haveFloat = true;
                } else {
                    haveFloat = false;
                }

                //int value = _wtoi(tempstr.c_str());
                if (!PrintQuestions(_wtoi(amount.c_str()), symbolCount, maxNumber, haveBrackets, haveFloat, OutputPath)) {
                    str.Format(_T("输出到: %s 成功!"), m_OutputPath->GetText());
                } else {
                    str.Format(_T("输出到: %s 失败!"), m_OutputPath->GetText());
                }

                m_logPrint->SetText(str);
            } else if (msg.pSender == m_pMinBtn) {
                SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
                return;
            } else if (msg.pSender == m_pMaxBtn) {
                SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
                return;
            } else if (msg.pSender == m_pRestoreBtn) {
                SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
                return;
            }
        } else if (msg.sType == _T("selectchanged")) {
            CDuiString name = msg.pSender->GetName();
            CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(m_pm.FindControl(_T("main_option_switch")));

            if (name == _T("main_option_main"))
                pControl->SelectItem(0);
            else if (name == _T("main_option_about"))
                pControl->SelectItem(1);
        }
    }

    LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
        styleValue &= ~WS_CAPTION;
        ::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
        m_pm.Init(m_hWnd);
        CDialogBuilder builder;
        CDialogBuilderCallbackEx cb;
        CControlUI* pRoot = builder.Create(_T("skin.xml"), (UINT)0, &cb, &m_pm);
        ASSERT(pRoot && "Failed to parse XML");
        m_pm.AttachDialog(pRoot);
        m_pm.AddNotifier(this);
        Init();
        return 0;
    }

    LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        ::PostQuitMessage(0L);
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        if (::IsIconic(*this)) bHandled = FALSE;

        return (wParam == 0) ? TRUE : FALSE;
    }

    LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        return 0;
    }

    LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        return 0;
    }

    LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        POINT pt;
        pt.x = GET_X_LPARAM(lParam);
        pt.y = GET_Y_LPARAM(lParam);
        ::ScreenToClient(*this, &pt);
        RECT rcClient;
        ::GetClientRect(*this, &rcClient);
        RECT rcCaption = m_pm.GetCaptionRect();

        if (pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right                 && pt.y >= rcCaption.top && pt.y < rcCaption.bottom) {
            CControlUI* pControl = static_cast<CControlUI*>(m_pm.FindControl(pt));

            if (pControl && _tcscmp(pControl->GetClass(), DUI_CTR_BUTTON) != 0 &&
                    _tcscmp(pControl->GetClass(), DUI_CTR_OPTION) != 0 &&
                    _tcscmp(pControl->GetClass(), DUI_CTR_TEXT) != 0)
                return HTCAPTION;
        }

        return HTCLIENT;
    }

    LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        SIZE szRoundCorner = m_pm.GetRoundCorner();

        if (!::IsIconic(*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0)) {
            CDuiRect rcWnd;
            ::GetWindowRect(*this, &rcWnd);
            rcWnd.Offset(-rcWnd.left, -rcWnd.top);
            rcWnd.right++;
            rcWnd.bottom++;
            HRGN hRgn = ::CreateRoundRectRgn(rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom, szRoundCorner.cx, szRoundCorner.cy);
            ::SetWindowRgn(*this, hRgn, TRUE);
            ::DeleteObject(hRgn);
        }

        bHandled = FALSE;
        return 0;
    }

    LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        MONITORINFO oMonitor = {};
        oMonitor.cbSize = sizeof(oMonitor);
        ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
        CDuiRect rcWork = oMonitor.rcWork;
        rcWork.Offset(-oMonitor.rcMonitor.left, -oMonitor.rcMonitor.top);
        LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam;
        lpMMI->ptMaxPosition.x = rcWork.left;
        lpMMI->ptMaxPosition.y = rcWork.top;
        lpMMI->ptMaxSize.x = rcWork.right;
        lpMMI->ptMaxSize.y = rcWork.bottom;
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
        if (wParam == SC_CLOSE) {
            ::PostQuitMessage(0L);
            bHandled = TRUE;
            return 0;
        }

        BOOL bZoomed = ::IsZoomed(*this);
        LRESULT lRes = CWindowWnd::HandleMessage(uMsg, wParam, lParam);

        if (::IsZoomed(*this) != bZoomed) {
            if (!bZoomed) {
                CControlUI* pControl = static_cast<CControlUI*>(m_pm.FindControl(_T("maxbtn")));

                if (pControl) pControl->SetVisible(false);

                pControl = static_cast<CControlUI*>(m_pm.FindControl(_T("restorebtn")));

                if (pControl) pControl->SetVisible(true);
            } else {
                CControlUI* pControl = static_cast<CControlUI*>(m_pm.FindControl(_T("maxbtn")));

                if (pControl) pControl->SetVisible(true);

                pControl = static_cast<CControlUI*>(m_pm.FindControl(_T("restorebtn")));

                if (pControl) pControl->SetVisible(false);
            }
        }

        return lRes;
    }

    virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) {
        LRESULT lRes = 0;
        BOOL bHandled = TRUE;

        switch (uMsg) {
            case WM_CREATE:
                lRes = OnCreate(uMsg, wParam, lParam, bHandled);
                break;

            case WM_CLOSE:
                lRes = OnClose(uMsg, wParam, lParam, bHandled);
                break;

            case WM_DESTROY:
                lRes = OnDestroy(uMsg, wParam, lParam, bHandled);
                break;

            case WM_NCACTIVATE:
                lRes = OnNcActivate(uMsg, wParam, lParam, bHandled);
                break;

            case WM_NCCALCSIZE:
                lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled);
                break;

            case WM_NCPAINT:
                lRes = OnNcPaint(uMsg, wParam, lParam, bHandled);
                break;

            case WM_NCHITTEST:
                lRes = OnNcHitTest(uMsg, wParam, lParam, bHandled);
                break;

            case WM_SIZE:
                lRes = OnSize(uMsg, wParam, lParam, bHandled);
                break;

            case WM_GETMINMAXINFO:
                lRes = OnGetMinMaxInfo(uMsg, wParam, lParam, bHandled);
                break;

            case WM_SYSCOMMAND:
                lRes = OnSysCommand(uMsg, wParam, lParam, bHandled);
                break;

            default:
                bHandled = FALSE;
        }

        if (bHandled) return lRes;

        if (m_pm.MessageHandler(uMsg, wParam, lParam, lRes)) return lRes;

        return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
    }

  protected:
    CPaintManagerUI m_pm;

  private:
    CButtonUI* m_pCloseBtn;
    CButtonUI* m_pMaxBtn;
    CButtonUI* m_pRestoreBtn;
    CButtonUI* m_pMinBtn;
    CTextUI* m_qAmount;
    CTextUI* m_logPrint;
    CComboUI* m_symbol;
    CComboUI* m_maxnumber;
    CComboUI* m_HaveBrackets;
    CComboUI* m_HaveFloat;
    CComboUI* m_OutputMode;
    CComboUI* m_OutputPath;
    CDuiString str;
};

题目输出

技术分享图片

如上图所示,选择了:题目数量:10,包括全部运算符,最大数:10,包含括号,包含小数,输出到文件,结果如下:

(1.6359-(3.7624/3.7595)*1.4041)=
4.0836+(1.9374-3.7348)+3.3199=
1.4734/(1.0053*1.69/1.3788)=
(2.4893/3.4648-2.431*1.6617)=
1.7616/(2.8935-2.6519)/4.1556=
(2.1008-1.5844*1.3195/3.0485)=
1.1587/(3.9314+2.3458)+1.6618=
(2.5281*2.9589-3.0472)+3.3622=
(3.4179-(2.819/2.9815)/3.2888)=
(1.2634/(3.4272*3.6362)-1.4886)=

驾驶员:linaria

领航员:王海鹏

驾驶员评价

以上是关于软件工程结对编程第2次作业 - 图形界面四则运算生成工具的主要内容,如果未能解决你的问题,请参考以下文章

结对第二次作业

结对作业2(软件工程第五次作业)

结对编程第二次作业

软件工程第二次结对作业

结对编程第二次作业

软件工程第五次作业(结对作业)