📄 simgui.cpp
字号:
afx_msg void CDiningSimWindow::OnRun() {
// start the simulation running...
ShowUserMessage("Starting...");
StartSimulation();
ShowUserMessage("Running.");
}
afx_msg void CDiningSimWindow::OnStop() {
// tell the simulation to stop...
ShowUserMessage("Stopping...");
StopSimulation();
ShowUserMessage("Ready.");
}
afx_msg void CDiningSimWindow::OnUpdateRunUI( CCmdUI *pCmdUI) {
// set the state of the RUN menu option...
pCmdUI->Enable(!m_bRunning);
}
afx_msg void CDiningSimWindow::OnUpdateStopUI( CCmdUI *pCmdUI) {
// set the state of the STOP menu option...
pCmdUI->Enable(m_bRunning);
}
afx_msg void CDiningSimWindow::OnExit() {
// tell the application to terminate...
PostMessage( WM_CLOSE);
}
afx_msg void CDiningSimWindow::OnDestroy() {
// ensure the the simulation has stopped before
// we destroy the window...
ShowUserMessage("Shutting down...");
StopSimulation();
ShowUserMessage("Finished.");
}
// CDiningSimWindow user defined message handler functions...
afx_msg LONG CDiningSimWindow::OnDiningSimPhilosopherUpdate( UINT uPhilosopher, LONG lNewState) {
// change the philosopher state...
m_nPhilosopherState[uPhilosopher] = lNewState;
// get the window device context...
CDC *pDC = GetDC();
// align the DC origin with the scroll position...
pDC->SetWindowOrg( m_nHScrollPos, m_nVScrollPos);
// update the display...
DrawPhilosopher( pDC, uPhilosopher);
ReleaseDC(pDC);
return 0;
}
afx_msg LONG CDiningSimWindow::OnDiningSimForkUpdate( UINT uFork, LONG lNewState) {
// change the fork state...
m_nForkState[uFork] = lNewState;
// get the window device context...
CDC *pDC = GetDC();
// align the DC origin with the scroll position...
pDC->SetWindowOrg( m_nHScrollPos, m_nVScrollPos);
// update the display...
DrawFork( pDC, uFork);
ReleaseDC(pDC);
return 0;
}
// CDiningSimWindow simulation control functions...
void CDiningSimWindow::StartSimulation(void) {
// run the simulation if it is stopped...
if (!m_bRunning) {
m_cSimulation.Run();
m_bRunning = TRUE;
}
}
void CDiningSimWindow::StopSimulation(void) {
// stop the simulation if it is running...
if (m_bRunning) {
m_cSimulation.Stop();
m_bRunning = FALSE;
}
}
void CDiningSimWindow::ShowUserMessage( CString csMessage) {
// set the user message and update the display...
m_csUserMessage = csMessage;
// get the window device context...
CDC *pDC = GetDC();
// align the DC origin with the scroll position...
pDC->SetWindowOrg( m_nHScrollPos, m_nVScrollPos);
// update the display...
DrawUserMessage(pDC);
ReleaseDC(pDC);
}
// CDiningSimWindow drawing functions...
void CDiningSimWindow::DrawSimulation(CDC *pDC) {
// get the window client area...
CRect cr;
GetClientRect(cr);
// compute the center of the scrollable window...
CPoint cpt( WINDOW_WIDTH >> 1, WINDOW_HEIGHT >> 1);
// draw table in center of window...
CBrush cb;
cb.CreateStockObject(NULL_BRUSH);
CBrush *pOldBrush = pDC->SelectObject(&cb);
CPen cp;
cp.CreateStockObject(WHITE_PEN);
CPen *pOldPen = pDC->SelectObject(&cp);
pDC->Ellipse( cpt.x - m_nTableSide/2, cpt.y - m_nTableSide/2, cpt.x + m_nTableSide/2, cpt.y + m_nTableSide/2);
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
// create a DC to use for drawing bitmaps...
CDC mdc;
mdc.CreateCompatibleDC(pDC);
// used for computing drawing locations...
POINT pt;
// used to iterate over the seating positions...
int nSeat;
int iRadius;
// draw the bowls...
CBitmap *pOldBitmap = mdc.SelectObject(&m_cbmBowl);
iRadius = m_nTableSide/2 - BOWL_SPACING;
for (nSeat = 0; nSeat < NUMBER_PHILOSOPHERS; nSeat++) {
pt = ComputeSeatPosition( cpt, NUMBER_PHILOSOPHERS, nSeat, iRadius);
pt.x -= BITMAP_WIDTH >> 1;
pt.y -= BITMAP_HEIGHT >> 1;
pDC->BitBlt( pt.x, pt.y, BITMAP_WIDTH, BITMAP_HEIGHT, &mdc, 0, 0, SRCCOPY);
}
mdc.SelectObject(pOldBitmap);
// draw the philosophers...
for (nSeat = 0; nSeat < NUMBER_PHILOSOPHERS; nSeat++) {
DrawPhilosopher( pDC, nSeat);
}
// draw the forks...
for (nSeat = 0; nSeat < NUMBER_PHILOSOPHERS; nSeat++) {
DrawFork( pDC, nSeat);
}
// draw the current user message...
DrawUserMessage( pDC);
}
void CDiningSimWindow::DrawPhilosopher(CDC *pDC, UINT uPhilosopher) {
// get the window client area...
CRect cr;
GetClientRect(cr);
// compute the center of the scrollable window...
CPoint cpt( WINDOW_WIDTH >> 1, WINDOW_HEIGHT >> 1);
// create a DC to use for drawing bitmaps...
CDC mdc;
mdc.CreateCompatibleDC(pDC);
// compute philosopher distance from table center...
int iRadius = m_nTableSide/2 + PHILOSOPHER_SPACING;
// compute the upper-left corner of the blit rectangle...
POINT pt = ComputeSeatPosition( cpt, NUMBER_PHILOSOPHERS, uPhilosopher, iRadius);
pt.x -= BITMAP_WIDTH >> 1;
pt.y -= BITMAP_HEIGHT >> 1;
// blit the current philosopher image...
CBitmap *pOldBitmap = mdc.SelectObject(&m_cbmPhilosophers);
pDC->BitBlt( pt.x, pt.y, BITMAP_WIDTH, BITMAP_HEIGHT, &mdc, BITMAP_WIDTH*m_nPhilosopherState[uPhilosopher], 0, SRCCOPY);
mdc.SelectObject(pOldBitmap);
}
void CDiningSimWindow::DrawFork(CDC *pDC, UINT uFork) {
// get the window client area...
CRect cr;
GetClientRect(cr);
// compute the center of the scrollable window...
CPoint cpt( WINDOW_WIDTH >> 1, WINDOW_HEIGHT >> 1);
// create a DC to use for drawing bitmaps...
CDC mdc;
mdc.CreateCompatibleDC(pDC);
// compute philosopher distance from table center...
int iRadius = m_nTableSide/2 + PHILOSOPHER_SPACING;
// compute the upper-left corner of the blit rectangle...
POINT pt = ComputeForkPosition( cpt, NUMBER_PHILOSOPHERS, uFork, iRadius);
pt.x -= BITMAP_WIDTH >> 1;
pt.y -= BITMAP_HEIGHT >> 1;
// blit the current fork image...
CBitmap *pOldBitmap = mdc.SelectObject(&m_cbmForks);
pDC->BitBlt( pt.x, pt.y, BITMAP_WIDTH, BITMAP_HEIGHT, &mdc, BITMAP_WIDTH*m_nForkState[uFork], 0, SRCCOPY);
mdc.SelectObject(pOldBitmap);
}
void CDiningSimWindow::DrawUserMessage(CDC *pDC) {
// draw the current user message text string m_csUserMessage
// in the upper-left corner of the window...
COLORREF crOldTextColor = pDC->SetTextColor(RGB(0,255,0));
COLORREF crOldBkColor = pDC->SetBkColor(RGB(0,0,0));
// draw OPAQUE with the previous text rect to make sure that
// we erase the previous message...
pDC->ExtTextOut( 0, 0, ETO_OPAQUE, m_crLastTextRect, m_csUserMessage, NULL);
pDC->SetTextColor(crOldTextColor);
pDC->SetBkColor(crOldBkColor);
// save the text rect for later erasing...
CSize cz = pDC->GetTextExtent(m_csUserMessage);
m_crLastTextRect = CRect( 0, 0, cz.cx, cz.cy);
}
// CDiningSimWindow helper functions...
POINT CDiningSimWindow::ComputeSeatPosition( POINT ptCenter, int nPositions, int iPosition, int iRadius) {
POINT pt;
double rad = iPosition * (2 * 3.14159) / nPositions;
pt.x = (int)(ptCenter.x + sin(rad) * iRadius);
pt.y = (int)(ptCenter.y - cos(rad) * iRadius);
return pt;
}
POINT CDiningSimWindow::ComputeForkPosition( POINT ptCenter, int nPositions, int iPosition, int iRadius) {
POINT pt;
double rad = (iPosition - 0.50) * (2 * 3.14159) / nPositions;
pt.x = (int)(ptCenter.x + sin(rad) * iRadius);
pt.y = (int)(ptCenter.y - cos(rad) * iRadius);
return pt;
}
void CDiningSimWindow::ErrorExit( LPCTSTR lpMsg) {
::MessageBox( NULL, lpMsg, "DiningSim Fatal Error - Program will Exit", MB_ICONSTOP);
::ExitProcess(0xFFFFFFFF);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -