图形界面的四则运算生成工具
一个简单的图形界面四则运算生成工具 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-10-10 10:27:14