gpt4 book ai didi

c++ - MFC 应用程序 : animating graphics cause program to not respond

转载 作者:行者123 更新时间:2023-11-28 00:14:03 25 4
gpt4 key购买 nike

我目前正在尝试创建一个 MFC 程序,该程序显示一种涉及对象的动画,对象的位置以图形方式转换为小板上的矩形、椭圆等位置。这是一个 32 位程序。

我的想法是,当用户按下按钮时,他会以特定的时间速率看到模拟。但是,我的代码使其仅在有人不断点击按钮以推进模拟时运行。

当我用另一个按钮做同样的事情时,图形动画通常很流畅。但是,我的窗口屏幕上最终出现了一个 (Not Responding) 提示(在非特定时间),导致图形卡住,直到模拟完成。

如何防止图形窗口卡住?

相关代码:

void Csmart_parking_guiDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
DrawGrid();
}


void Csmart_parking_guiDlg::DrawGrid() {
CRect gridBase;
gridDrawSurface->GetWindowRect(&gridBase);
this->ScreenToClient(&gridBase);
CPoint bottomRight = gridBase.TopLeft();
int rectSize = 400;
bottomRight += CPoint(rectSize, rectSize);
gridBase.BottomRight() = bottomRight;
gridBase.NormalizeRect();
gridDraw->Rectangle(gridBase);
int baseRectWidth = gridBase.Width();
int baseRectHeight = gridBase.Height();
double proportion = (baseRectWidth / world->getGridSize());
// Draw destinations. Set boolean to check if all are drawn yet
CBrush brushDest(RGB(165, 42, 42));
gridBrush = gridDraw->SelectObject(&brushDest);
CPen penBlack;
penBlack.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
gridPen = gridDraw->SelectObject(&penBlack);
vector <Location> destLoc = world->getDestLocations();
int xCenter;
int yCenter;
for (size_t ii = 0; ii < destLoc.size(); ii++) { // draw brown circle
xCenter = (int)round(gridBase.TopLeft().x + destLoc[ii].x*proportion);
yCenter = (int)round(gridBase.TopLeft().y + destLoc[ii].y*proportion);
gridDraw->Rectangle(xCenter - 4, yCenter-4, xCenter+4, yCenter+4);
}
gridDraw->SelectObject(gridBrush);
destDrawn = true;
// Draw lots.
CBrush brushLot(RGB(35, 62, 148));
gridDraw->SetTextColor(RGB(35, 62, 148));
// gridDraw->SetBkMode(TRANSPARENT);
gridBrush = gridDraw->SelectObject(&brushLot);
vector<Location> lotLoc = world->getLotLocations();
vector<int> lotSpots;
vector<Lot *> allLots = world->getAllLots();
for (size_t ii = 0; ii < allLots.size(); ii++) {
lotSpots.push_back(allLots[ii]->getOpenSpots());
}
for (size_t ii = 0; ii < lotLoc.size(); ii++) { // draw blue circle and number
xCenter = (int)round(gridBase.TopLeft().x + lotLoc[ii].x*proportion);
yCenter = (int)round(gridBase.TopLeft().y + lotLoc[ii].y*proportion);
gridDraw->Ellipse(xCenter-3, yCenter-3, xCenter+3, yCenter+3);
CString echoNum;
echoNum.Format(_T("%d"), lotSpots[ii]);
gridDraw->TextOutW(xCenter + 4, yCenter + 1, echoNum);
}
lotDrawn = true;
gridDraw->SelectObject(gridBrush);
gridDraw->SelectObject(gridPen);
// Draw drivers
vector<Location> driverLoc = world->getDriverLocations(); // get all drivers currently visible on screen
for (size_t ii = 0; ii < driverLoc.size(); ii++) { // draw red dot
xCenter = (int)round(gridBase.TopLeft().x + driverLoc[ii].x*proportion);
yCenter = (int)round(gridBase.TopLeft().y + driverLoc[ii].y*proportion);
gridDraw->Rectangle(xCenter - 1, yCenter - 1, xCenter + 1, yCenter + 1);
}
}

void Csmart_parking_guiDlg::OnBnClickedBSimend() // On clicking, simulation jumps to the very end.
{
while (!world->simulationOver[world->getCurrentIteration()]) {
run_simulation(*world);
m_TimeDisplay = world->getTime(); // double
m_EchoTime.Format(_T("Time: %g"), m_TimeDisplay);
if (!world->simulationOver[world->getCurrentIteration()]) oss << world->getCurrentEvent();
CString c_status(oss.str().c_str());
m_EchoStatus = c_status;
UpdateData(FALSE);
OnPaint();
GetDlgItem(IDC_ST_STATUS)->RedrawWindow();
pEdit->LineScroll(pEdit->GetLineCount());
// theApp.PumpMessage(); // this works but it makes it way too slow
// Sleep(50); // program stops responding at times with a sleep message
}
}

最佳答案

您可以(并且应该)摆脱 while 循环,只需调用 SetTimer 即可开始模拟。然后在每次调用 WM_TIMER 消息处理程序时执行模拟的一个步骤。你永远不应该自己调用 OnPaint。您的计时器可以调用 Invalidate 使 Windows 调用 OnPaint。

关于c++ - MFC 应用程序 : animating graphics cause program to not respond,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31462079/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com