📄 elevatorthread.cpp
字号:
// 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 + -