【发布时间】:2015-07-16 18:41:59
【问题描述】:
我目前正在尝试创建一个 MFC 程序,它显示一种涉及对象的动画,这些对象的位置以图形方式转换为小板上的位置,如矩形、椭圆等。这是一个 32 位程序。
我的想法是,当用户按下按钮时,他会以特定的时间速率看到模拟。但是,我的代码使它只有在有人不断点击按钮以推进模拟时才会运行。
当我用另一个按钮做同样的事情时,图形通常会流畅地动画。但是,我的窗口屏幕上的(未响应)提示最终会出现在 Windows 7 中(在非特定时间),导致图形冻结,直到模拟完成。
如何防止图形窗口冻结?
相关代码:
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
}
}
【问题讨论】:
标签: c++ graphics windows-7 mfc