⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simgui.cpp

📁 window下的多线程编程参考书。值得一读
💻 CPP
📖 第 1 页 / 共 2 页
字号:

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 + -