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

📄 elevatorthread.cpp

📁 电梯调度模拟,有mfc界面展现5部电梯的相互调度
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ElevatorThread.cpp : 实现文件
//

#include "stdafx.h"
#include "074099_EleAttemper.h"
#include "ElevatorThread.h"
#include "stdafx.h"
#include "074099_EleAttemper.h"
#include "ElevatorThread.h"
#include "MyVariousState.h"
#include "MyWaitQueue.h"




//电梯类模拟单线程


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框



CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CMyElevatorThread 对话框

CMyElevatorThread::CMyElevatorThread(CWnd* pParent /*=NULL*/)
: CDialog(CMyElevatorThread::IDD, pParent)

{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_TCB.m_iElevatorNo=1;
	m_TCB.m_iCurPassengerNum = 0;
	m_TCB.m_iCurFloor = 1;
	m_TCB.m_iNextDestFloor = -1;
	m_TCB.m_eCurState = Ele_IDLE;

	m_mycUpInnerWaitQueue =new CUpInnerWaitQueue();
	m_mycDownInnerWaitQueue =new CDownInnerWaitQueue();



}


CMyElevatorThread::CMyElevatorThread(int iElevatorNo, CWnd* pParent/*=NULL*/)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_TCB.m_iElevatorNo = iElevatorNo;
	m_TCB.m_iCurPassengerNum = 0;
	m_TCB.m_iCurFloor = 1;//电梯开始时所在楼层
	m_TCB.m_iNextDestFloor = -1;
	m_TCB.m_eCurState = Ele_IDLE;	
	m_TCB.m_eBackupDirection = BAD_DIRE;
	m_TCB.m_bCanSchedule = TRUE;

	m_pParent=pParent;
	m_mycUpInnerWaitQueue =new CUpInnerWaitQueue();
	m_mycDownInnerWaitQueue =new CDownInnerWaitQueue();

	stateDespArr[0] = "空闲";
	stateDespArr[1] = "下行";
	stateDespArr[2] = "上行";
	stateDespArr[3] = "下行暂停";
	stateDespArr[4] = "上行暂停";
	stateDespArr[5] = "开门";
	stateDespArr[6] = "故障!";	
	stateDespArr[7] = "";

	str_arrElevatorName[0]='1';
	str_arrElevatorName[1]='2';
	str_arrElevatorName[2]='3';
	str_arrElevatorName[3]='4';
	str_arrElevatorName[4]='5';





}

void CMyElevatorThread::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_STATIC_MyELEVATORItem, m_ElevatorBox);
	DDX_Control(pDX, IDC_STATIC_AIM, m_Elevatordestination);
	DDX_Control(pDX, IDC_STATIC_PERSONNUM, m_conPsgNum);
}

BEGIN_MESSAGE_MAP(CMyElevatorThread, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BUTTON_OPENDOOR, openDoor)
	ON_BN_CLICKED(IDC_BUTTON_CLOSEDOOR, closeDoor)
	ON_BN_CLICKED(IDC_BUTTON_TROUBLE, OnBtnCreateFault)
	ON_BN_CLICKED(IDC_BUTTON_CORRECT, OnBtnCorrectFault)
	ON_BN_CLICKED(IDC_BUTTON_ENTER, OnBtnPsgEnter)
	ON_BN_CLICKED(IDC_BUTTON_LEAVE, OnBtnPsgLeave)
	ON_COMMAND_RANGE(IDC_MYBUTTONS,IDC_MYBUTTONS+20,OnInnerBtnClk) 
END_MESSAGE_MAP()


// CMyElevatorThread 消息处理程序

BOOL CMyElevatorThread::OnInitDialog()
{
	CDialog::OnInitDialog();

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	//m_btnarlarm.SubclassDlgItem(IDC_BUTTON_ARLARM,this);
	m_btnenter.SubclassDlgItem(IDC_BUTTON_ENTER,this);
	m_btnleave.SubclassDlgItem(IDC_BUTTON_LEAVE,this);
	m_btnopendoor.SubclassDlgItem(IDC_BUTTON_OPENDOOR,this);
	m_btnclosedoor.SubclassDlgItem(IDC_BUTTON_CLOSEDOOR,this);
	m_btntrouble.SubclassDlgItem(IDC_BUTTON_TROUBLE,this);
	m_btncorrect.SubclassDlgItem(IDC_BUTTON_CORRECT,this);
	///////////创建电梯内部按钮/////////////////////////////////////////////////////////////////
	CString strCaption;
	int iInnerBtnLeft = 20;
	int iInnerBtnTop = 220;
	int iRowHeight = 35;
	int iColWidth = 36;

	int iInnerBtnWidth = 35;
	int iInnerBtnHeight = 30;
	int i;

	try{

		for(i=20;i>0;i--)
		{
			strCaption.Format(_T("%d"),i);
			m_pButton[i-1]=new MyButton;

			if(i%2==0)
			{
				m_pButton[i-1]->Create(strCaption,BS_PUSHBUTTON|WS_CHILD|WS_VISIBLE,\
					CRect(iInnerBtnLeft,iInnerBtnTop+(10-i)*iRowHeight/2,iInnerBtnLeft+iInnerBtnWidth,iInnerBtnTop+(10-i)*iRowHeight/2+iInnerBtnHeight),\
					this,IDC_MYBUTTONS+i-1);

			}
			else
			{
				m_pButton[i-1]->Create(strCaption,BS_PUSHBUTTON|WS_CHILD|WS_VISIBLE,\
					CRect(iInnerBtnLeft+iColWidth,iInnerBtnTop+(10-i-1)*iRowHeight/2,iInnerBtnLeft+iColWidth+iInnerBtnWidth,iInnerBtnTop+(10-i-1)*iRowHeight/2+iInnerBtnHeight),\
					this,IDC_MYBUTTONS+i-1);
			}

		}

	}
	catch(CException* e)
	{
		AfxMessageBox(_T("无法创建电梯按钮,程序不能正常运行。"));
		e->ReportError();
		e->Delete();
		return FALSE;//退出!
	}
	GetDlgItem(IDC_BUTTON_OPENDOOR)->EnableWindow(FALSE);
	GetDlgItem(IDC_BUTTON_CLOSEDOOR)->EnableWindow(FALSE);
	GetDlgItem(IDC_BUTTON_ENTER)->EnableWindow(FALSE);
	GetDlgItem(IDC_BUTTON_LEAVE)->EnableWindow(FALSE);
	GetDlgItem(IDC_BUTTON_CORRECT)->EnableWindow(FALSE);
	//GetDlgItem(IDC_BUTTON_ARLARM)->EnableWindow(FALSE);
	GetDlgItem(IDC_STATIC_AIM)->ShowWindow(SW_HIDE);


	///////////////////创建电梯内部楼层号///////////////////////////////////////////////////
	CString TempString;
	iInnerBtnLeft = 173;
	int iLabelWidth = 25;
	int iLabelHeight = ELEVATOR_HEIGHT;
	iInnerBtnTop = 345;

	try{

		for(i=MAX_FLOOR_NUM;i>0;i--)
		{
			TempString.Format(_T("%d"),i);
			m_pLabel[i-1] = new CStatic;
			m_pLabel[i-1]->Create(TempString+"#",WS_CHILD|WS_VISIBLE|SS_CENTER,\
				CRect(iInnerBtnLeft,iInnerBtnTop+(10-i)*iLabelHeight,iInnerBtnLeft+iLabelWidth,iInnerBtnTop+(11-i)*iLabelHeight),\
				this,IDC_MYLABELS+i-1);


		}

	}
	catch(CException* e)
	{
		AfxMessageBox(_T("无法创建楼层标号,程序不能正常运行。"));
		e->ReportError();
		e->Delete();
		return FALSE;//退出!
	}
	//////////////////////////////////////////////////////////////////////////////////////
	CFont cFont;
	cFont.CreateFont(12, 10, 0, 0, FW_BOLD, FALSE, TRUE,0,0,0,0,0,0, _T("宋体"));
	TempString.Format(_T("%c"),str_arrElevatorName[m_TCB.m_iElevatorNo-1]);
	((CButton* )GetDlgItem(IDC_STATIC_ELEVATOR))->SetFont(&cFont);	
	((CButton* )GetDlgItem(IDC_STATIC_ELEVATOR))->SetWindowText(_T("电梯")+TempString);
	cFont.DeleteObject();

	m_ElevatorBox.SetWindowText(_T(" 空闲 "));
	m_ElevatorBox.SetBkColor(RGB(0,0,255));

	//===========电梯箱体
	m_ElevatorBox.MoveWindow(iInnerBtnLeft-60,iInnerBtnTop+(10-m_TCB.m_iCurFloor)*iLabelHeight,70,20);	
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CMyElevatorThread::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

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

		// 使图标在工作区矩形中居中
		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;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMyElevatorThread::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CMyElevatorThread::OnTimer(UINT nIDEvent) 
{
	switch(nIDEvent)
	{
	case 1://电梯运行控制时钟
		if(m_TCB.m_eCurState==Ele_UP_RUN)
		{
			if(m_TCB.m_iCurFloor < m_TCB.m_iNextDestFloor)
			{
				m_TCB.m_iCurFloor++;
				m_ElevatorBox.MoveWindow(110,67+(19-m_TCB.m_iCurFloor)*ELEVATOR_HEIGHT,65,20);
				GetDlgItem(IDC_STATIC_AIM)->ShowWindow(SW_SHOW);
				m_Elevatordestination.SetBkColor(RGB(0,255,255));
				m_Elevatordestination.SetWindowText(_T("下一目的地"));
				m_Elevatordestination.MoveWindow(110,67+(19-m_TCB.m_iNextDestFloor)*ELEVATOR_HEIGHT,65,20);

			}
			else //到达目的楼层
			{
				//delete m_ElevatorBox;
				KillTimer(1);
				MessageBeep(MB_ICONASTERISK);

				openDoor();

			}
		}
		else if(m_TCB.m_eCurState==Ele_DOWN_RUN)
		{
			if(m_TCB.m_iCurFloor > m_TCB.m_iNextDestFloor)
			{
				m_TCB.m_iCurFloor--;
				m_ElevatorBox.MoveWindow(110,67+(19-m_TCB.m_iCurFloor)*ELEVATOR_HEIGHT,65,20);	

				m_Elevatordestination.SetBkColor(RGB(0,255,255));
				m_Elevatordestination.SetWindowText(_T("下一目的地"));
				m_Elevatordestination.MoveWindow(110,67+(19-m_TCB.m_iNextDestFloor)*ELEVATOR_HEIGHT,65,20);


			}
			else //到达目的楼层
			{
				//delete m_ElevatorBox;
				KillTimer(1);
				MessageBeep(MB_ICONASTERISK);

				openDoor();
			}
		}
		break;

	case 2://电梯开门超时控制时钟
		KillTimer(2);
		closeDoor();
		break;

	}

	CDialog::OnTimer(nIDEvent);
}

//接受外部主控中心的请求

void CMyElevatorThread::acceptReq(sOuterRequest& tmpOuterRequest)
{
	enum direction eReqDirection = tmpOuterRequest.eMyReqDirection;
	int iReqFloor = tmpOuterRequest.iMyReqFloor;
	//如果刚好电梯所停楼层有请求,则直接开门
	if((m_TCB.m_eCurState==Ele_IDLE || m_TCB.m_eCurState==Ele_UP_PAUSE || m_TCB.m_eCurState==Ele_DOWN_PAUSE) && iReqFloor == m_TCB.m_iCurFloor)
	{
		if(eReqDirection==UP) {m_TCB.m_eCurState = Ele_UP_RUN;}
		else {m_TCB.m_eCurState = Ele_DOWN_RUN;}

		MessageBeep(MB_ICONASTERISK);

		openDoor();
		return;
	}

	enum direction realDire = (iReqFloor>m_TCB.m_iCurFloor) ? UP : DOWN; 

	switch(m_TCB.m_eCurState)
	{
	case Ele_IDLE:
		//记录用户请求方向与电梯应该运行方向不一致的情况,以便电梯到达后调整方向
		if(eReqDirection==UP && realDire==DOWN){
			m_TCB.m_eBackupDirection = UP;
			m_TCB.m_bCanSchedule = FALSE;//电梯在到达本请求楼层前不允许再被调度
		}
		else if(eReqDirection==DOWN && realDire==UP){
			m_TCB.m_eBackupDirection = DOWN;
			m_TCB.m_bCanSchedule = FALSE;//电梯在到达本请求楼层前不允许再被调度
		}

		if(realDire==UP)
		{
			m_TCB.m_eCurState =Ele_UP_RUN;
			m_mycUpInnerWaitQueue->addElement(iReqFloor);
		}else{
			m_TCB.m_eCurState =Ele_DOWN_RUN;
			m_mycDownInnerWaitQueue->addElement(iReqFloor);
		}

		m_ElevatorBox.SetWindowText(stateDespArr[m_TCB.m_eCurState]);//改变电梯状态显示

⌨️ 快捷键说明

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