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

📄 simgui.cpp

📁 window下的多线程编程参考书。值得一读
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// FILE: SimGUI.cpp
//
// Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring
//
/////////////////////////////////////////////////////////////////////////
#include "SimGUI.h"
#include "resource.h"
#include <math.h>

// declare the single global application instance...
CDiningSim g_theApp;

// CDiningSim member functions...
BOOL CDiningSim::InitInstance(void) {
    m_pMainWnd = new CDiningSimWindow();
    m_pMainWnd->ShowWindow(m_nCmdShow);
    m_pMainWnd->UpdateWindow();
    return TRUE;
}

// CDiningSimWindow MFC message map...
BEGIN_MESSAGE_MAP(CDiningSimWindow, CFrameWnd)
    ON_WM_PAINT()
    ON_WM_ERASEBKGND()
    ON_WM_SIZE()
    ON_WM_VSCROLL()
    ON_WM_HSCROLL()
    ON_WM_GETMINMAXINFO()
    ON_WM_DESTROY()
    ON_COMMAND( ID_FILE_RUN, OnRun)
    ON_COMMAND( ID_FILE_STOP, OnStop)
    ON_COMMAND( ID_FILE_EXIT, OnExit)
    ON_UPDATE_COMMAND_UI( ID_FILE_RUN, OnUpdateRunUI)
    ON_UPDATE_COMMAND_UI( ID_FILE_STOP, OnUpdateStopUI)
    ON_MESSAGE( WM_DININGSIM_PHILOSOPHER_UPDATE, OnDiningSimPhilosopherUpdate)
    ON_MESSAGE( WM_DININGSIM_FORK_UPDATE, OnDiningSimForkUpdate)
END_MESSAGE_MAP()

// CDiningSimWindow constuctor...
CDiningSimWindow::CDiningSimWindow() {
    // not initially running...
    m_bRunning = FALSE;

    // no previous user message text rect...
    m_crLastTextRect = CRect(0,0,0,0);

    // no initial scroll...
    m_nHScrollPos = 0;
    m_nVScrollPos = 0;
    m_nHScrollPosMax = 0;
    m_nVScrollPosMax = 0;

    // default max window size is a big as the screen...
    CRect dr;
    GetDesktopWindow()->GetClientRect(dr);
    m_ptMaxWindowSize.x = dr.Width();
    m_ptMaxWindowSize.y = dr.Height();

    // table side will be 3/5 of the window width...
    m_nTableSide = 3*WINDOW_WIDTH/5;

    // initialize the philosopher and fork states...
    for (int i = 0; i < NUMBER_PHILOSOPHERS; i++) {
        m_nForkState[i] = FORK_STATE_AVAILABLE;
        m_nPhilosopherState[i] = PHILOSOPHER_STATE_THINKING;
    }

    // load the image of the spaghetti bowl...
    HBITMAP hBitmap;
    hBitmap = (HBITMAP) ::LoadImage( AfxGetApp()->m_hInstance, "bowl.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    if (hBitmap)
        m_cbmBowl.Attach(hBitmap);
    else
        ErrorExit("Unable to load image file 'bowl.bmp'!");

    // load the images of the philosophers...
    hBitmap = (HBITMAP) ::LoadImage( AfxGetApp()->m_hInstance, "philosophers.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    if (hBitmap)
        m_cbmPhilosophers.Attach(hBitmap);
    else 
        ErrorExit("Unable to load image file 'philosophers.bmp'!");

    // load the images of the forks...
    hBitmap = (HBITMAP) ::LoadImage( AfxGetApp()->m_hInstance, "forks.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    if (hBitmap)
        m_cbmForks.Attach(hBitmap);
    else 
        ErrorExit("Unable to load image file 'forks.bmp'!");

    // create the main window...
    Create( NULL, "Dining Philosophers Simulation", WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, rectDefault, NULL, MAKEINTRESOURCE(IDR_FILEMENU));

    // compute maximum size, resize, and center the main window...
    CRect wr, cr;
    GetClientRect(cr);
    GetWindowRect(wr);
    m_ptMaxWindowSize.x = WINDOW_WIDTH + wr.Width() - cr.Width();
    m_ptMaxWindowSize.y = WINDOW_HEIGHT + wr.Height() - cr.Height();
    int x = (m_ptMaxWindowSize.x > dr.Width()) ? dr.Width() : m_ptMaxWindowSize.x;
    int y = (m_ptMaxWindowSize.y > dr.Height()) ? dr.Height() : m_ptMaxWindowSize.y;
    SetWindowPos( NULL, 0, 0, x, y, SWP_NOMOVE | SWP_NOZORDER);
    CenterWindow();

    // set the simualation UI window...
    m_cSimulation.SetHwnd(m_hWnd);

    // show that we're ready...
    ShowUserMessage("Ready.");
}

// CDiningSimWindow standard message handler functions...
afx_msg void CDiningSimWindow::OnPaint() {
    // redraw the entire simulation...
    CPaintDC dc(this);

    // align the DC origin with the scroll position...
    dc.SetWindowOrg( m_nHScrollPos, m_nVScrollPos);

    // update the display...
    DrawSimulation(&dc);
}

afx_msg BOOL CDiningSimWindow::OnEraseBkgnd(CDC *pDC) {
    // fill the window with black...
    CRect cr;
    CBrush cb;
    GetClientRect(cr);
    cb.CreateStockObject(BLACK_BRUSH);
    pDC->FillRect( cr, &cb);
    return TRUE;
}

afx_msg void CDiningSimWindow::OnSize( UINT nType, int cx, int cy) {
    // adjust the horizontal scroll bar for the new window size...
    if (cx >= WINDOW_WIDTH) {
        // hide the scrollbar...
        SetScrollRange( SB_HORZ, 0, 0, TRUE);
        m_nHScrollPos = 0;
        m_nHScrollPosMax = 0;
    }
    else {
        // set the new scroll range...
        m_nHScrollPosMax = WINDOW_WIDTH - cx;
        SetScrollRange( SB_HORZ, 0, m_nHScrollPosMax, TRUE);

        // make the the current setting is not beyond the 
        // new upper bound...
        if (m_nHScrollPos > m_nHScrollPosMax) { 
            m_nHScrollPos = m_nHScrollPosMax;
            SetScrollPos( SB_HORZ, m_nHScrollPos, TRUE);
        }
    }

    // adjust the vertical scroll bar for the new window size...
    if (cy >= WINDOW_HEIGHT) {
        // hide the scrollbar...
        SetScrollRange( SB_VERT, 0, 0, TRUE);
        m_nVScrollPos = 0;
        m_nVScrollPosMax = 0;
    }
    else {
        // set the new scroll range...
        m_nVScrollPosMax = WINDOW_HEIGHT - cy;
        SetScrollRange( SB_VERT, 0, m_nVScrollPosMax, TRUE);

        // make the the current setting is not beyond the 
        // new upper bound...
        if (m_nVScrollPos > m_nVScrollPosMax) { 
            m_nVScrollPos = m_nVScrollPosMax;
            SetScrollPos( SB_VERT, m_nVScrollPos, TRUE);
        }
    }
}

afx_msg void CDiningSimWindow::OnVScroll( UINT nCode, UINT nPos, CScrollBar *pScrollBar) {
    // use this to store how far to move the window...
    int nDelta = 0;

    // simple scrolling...
    // a page equals a line equals one row of pixels...
    // dragging the thumb allows faster scrolling...
    switch (nCode) {
        case SB_PAGEUP:
        case SB_LINEUP:
            if (m_nVScrollPos <= 0)
                return;
            else
                nDelta = -1;
            break;
        case SB_PAGEDOWN:
        case SB_LINEDOWN:
            if (m_nVScrollPos >= m_nVScrollPosMax)
                return;
            else
                nDelta = 1;
            break;
        case SB_THUMBPOSITION:
            nDelta = (int) nPos - m_nVScrollPos;
            break;
    }

    // save the new scroll position...
    m_nVScrollPos += nDelta;

    // set the scroll bar to reflect the new position...
    SetScrollPos( SB_VERT, m_nVScrollPos, TRUE);

    // scroll the window and redraw the uncovered area...
    ScrollWindow( 0, -nDelta);
}

afx_msg void CDiningSimWindow::OnHScroll( UINT nCode, UINT nPos, CScrollBar *pScrollBar) {
    // use this to store how far to move the window...
    int nDelta = 0;

    // simple scrolling...
    // a page equals a line equals one column of pixels...
    // dragging the thumb allows faster scrolling...
    switch (nCode) {
        case SB_PAGEUP:
        case SB_LINEUP:
            if (m_nHScrollPos <= 0)
                return;
            else
                nDelta = -1;
            break;
        case SB_PAGEDOWN:
        case SB_LINEDOWN:
            if (m_nHScrollPos >= m_nHScrollPosMax)
                return;
            else
                nDelta = 1;
            break;
        case SB_THUMBPOSITION:
            nDelta = (int) nPos - m_nHScrollPos;
            break;
    }

    // save the new scroll position...
    m_nHScrollPos += nDelta;

    // set the scroll bar to reflect the new position...
    SetScrollPos( SB_HORZ, m_nHScrollPos, TRUE);

    // scroll the window and redraw the uncovered area...
    ScrollWindow( -nDelta, 0);
}

afx_msg void CDiningSimWindow::OnGetMinMaxInfo( MINMAXINFO FAR* lpMMI) {
    // tell Windows the application maximum window size...
    lpMMI->ptMaxSize = lpMMI->ptMaxTrackSize = m_ptMaxWindowSize;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -