软件工程结对编程第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

领航员:王海鹏

驾驶员评价

原文地址:https://www.cnblogs.com/linaria/p/8824579.html

时间: 2024-12-16 05:25:50

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

结对编程1 —— 基于GUI和Swing的四则运算题目生成器

结对编程1 -- 基于GUI和Swing的四则运算题目生成器 合作伙伴 201421123089 周迪 201421123069 黄睿 代码地址:https://git.coding.net/H1159650478/sizeyunsuanjiaqiang.git 题目描述 我们在个人作业1中,用各种语言实现了一个命令行的四则运算小程序.进一步,本次要求把这个程序做成GUI(可以是Windows PC 上的,也可以是Mac.Linux,web,手机上的),成为一个有基本功能.一定价值的程序.在下面

Jmeter:图形界面压力测试工具

Jmeter是一款强大的图形界面压力测试工具,完全用Java写成,关于Jmeter的介绍,网上其实有不少的文章,我原本是不想再重复写类似文章的,但我发现有些很关键性的,在我们测试中一定会用到的一些设置或操作很少见到有文章写清楚的,比如有这样的一个常见问题:如何对一个网站的多个链接进行压力测试?因为通常情况下,我们要测试的不是一个链接,假如我们测试的是某一网站的话,而这些链接我们通常都是写入到一个文本文件中,测试的过程中,会随机读取文件中的链接进行压力测试,我们所熟知的一些压力测试工具,例如Sie

关于在linux中使用图形界面的网络管理工具

有好几种自动设置的工具可以选择(既然说是自动设置的工具,那就说明有手动设置的工具,例如 使用 ip, iw, iwconfig 这些命令设置网络),例如:Connman, netctl, NetworkManager, Wicd, Wifi Radar 这几种工具如果同时使用的话可能会产生冲突,所以我们应该只选择其一.我们这里选择的是 NetworkManager,鉴于其功能强大又有图形界面的支持. 使用的linux是archlinux,桌面环境是 xfce4. 1. 安装 networkman

【转】Jmeter:图形界面压力测试工具

Jmeter是一款强大的图形界面压力测试工具,完全用Java写成,关于Jmeter的介绍,网上其实有不少的文章,我原本是不想再重复写类似文章的,但我发现有些很关键性的,在我们测试中一定会用到的一些设置或操作很少见到有文章写清楚的,比如有这样的一个常见问题:如何对一个网站的多个链接进行压力测试?因为通常情况下,我们要测试的不是一个链接,假如我们测试的是某一网站的话,而这些链接我们通常都是写入到一个文本文件中,测试的过程中,会随机读取文件中的链接进行压力测试,我们所熟知的一些压力测试工具,例如Sie

软件工程结对编程第一次作业

作业要求 (1). 首先在同学中找一个同伴,范围不限,可以在1~5班中随意组合,建议尽量不要找同组的成员,女同学尽量找男同学结对,但是不做强制要求: (2). 从以往个人完成的项目中选择一个作品,例如:以往的数据结构课程设计或者其它具有比较完整功能的小系统,代码至少要大于100行: (3). 将代码上传至个人GitHub或Coding.net系统中,并将代码地址交给对方: (4). 对同伴的作品进行代码复审,并参照C/C++代码审查表和 Java代码审查表 这两篇博文的内容自行设计代码审查表并填

软件工程结对编程博客

目录 结对编程博客 1.GitHub项目地址 2.PSP表格 3.看教科书和其它资料中关于Information Hiding, Interface Design, Loose Coupling的章节,说明你们在结对编程中是如何利用这些方法对接口进行设计的 4.计算模块接口的设计与实现过程 Input类 PreProcess类 DFS类 RingDFS类 Core类 Error类 5.画出UML图显示计算模块部分各个实体之间的关系 6.计算模块接口部分的性能改进.?记录在改进计算模块性能上所花费

软件工程------结对编程第二次

这一周我(1551426)还是继续和我们组的成员(1551419)两人一起结对编程,除此之外,我们还设计了数据库的,总共三个关系模式 room(roomtype,dailyprice,deposit) roominfo(roomnumber,roomtype,isfree) guest(id, startday,phonenumber,roomnumber,name,sex,stayday) 起初我们把room和guest 放在了一起,后来发现数据的冗余以后马上换成三个关系表. 这是我们的关系图

软件工程-------结对编程

这周我(1551426)和我们小组的成员(1551419)一起结对编程,写我们小组的项目.第一次尝试结对编程,感觉效率上比一个人编程高出许多,毕竟两个人肯定比一个人想得周全,出现了问题也能也不同的见解,以不同的思路去解决.因为我们组想做的是酒店管理系统,所以这周我们两个用java的GUI写了一个简单的登录系统. 登录的界面很简单. 一个用户名的输入框,一个密码框,一个登录按钮. 如果用户输入了错误的用户名 会弹出 如果用户的用户名没有输错,但是密码错误,会弹出 如果正确登录的话  页面会调用re

软件工程结对编程作业

代码复审---结对复查 一.题目要求: (1). 首先在同学中找一个同伴,范围不限,可以在1~5班中随意组合,建议尽量不要找同组的成员,女同学尽量找男同学结对,但是不做强制要求: (2). 从以往个人完成的项目中选择一个作品,例如:以往的数据结构课程设计或者其它具有比较完整功能的小系统,代码至少要大于100行: (3). 将代码上传至个人GitHub或Coding.net系统中,并将代码地址交给对方: (4). 对同伴的作品进行代码复审,并参照C/C++代码审查表和 Java代码审查表 这两篇博