📄 sounddlg.cpp
字号:
// soundDlg.cpp : implementation file
//本系统通过一个单片机然后与64个子机相连,系统的通讯主要是针对
//这个单片机,因为主机与64个子机间的通讯完全以单片机为中介。
//注意:该系统中老师端也是一个子机,故相当于共有65个子机。
//命令帧格式: 帧长度;命令类型;【子机1】;【子机2】;校验位
//接收帧格式:
//1、单片机响应: 帧长度(3);单片机响应命令(确认或要求重发);校验和
//2、子机呼叫: 帧长度(3);机号;校验和
//3、测验项数据: 帧长度(68);老师的子机号(0x60,作为命令的标志);对某题的所选答案(学生加老师,65项,其中最后记录老师的答案);校验和
#include "stdafx.h"
#include "sound.h"
#include "soundDlg.h"
#include "GradeDlg.h"
//为常量赋一个有意义的名字
#define comEvReceive 2
#define comInputModeBinary 1
unsigned char TxData[50]; //发送的数据,发送帧定义:第一项为发送的字节数;然后是命令帧(1~2个);最后是校验和。
//TxData[1],从1~7对应组合框的七种选择;8、9对应音量的控制;10表确认;1f表要求重发。
//补充:TxDate[1]为11(即0x0b)时表示组合框的第八种选择。
unsigned char RcvData[50]; //将所接收的数据写入该字符串,格式为接收帧格式
//RcvData[1]基本上对应TxData[1]的一些取值,另外,ff对应学生(即单片机处)要求重发;0f对应确认
//RcvData[1]对应单片机发来的数据帧中的命令类型
unsigned char Student[2]; //定义该变量的目的是点对点通讯时,指明学生接收对象。此处表明最多涉及两位学生。
static int PointStu=0; //使用此指针,防止重复选择学生
static int SavePoint=0;
static int Test=0; //此标志用于测试功能中的判断
static int n_Key=0;
static int Score[65][65]; //记录分数
static int Grade[64]; //记录成绩,用于计算Score[65][65]对应的累加和。
//CString szCall="";
CFont NewFont;
CFont* pOldFont;
CButton *pCallButton=NULL;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSoundDlg dialog
CSoundDlg::CSoundDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSoundDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSoundDlg)
m_Text = _T("");
m_Call = _T("");
m_Discrip = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSoundDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSoundDlg)
DDX_Control(pDX, IDC_H8, m_H8);
DDX_Control(pDX, IDC_H7, m_H7);
DDX_Control(pDX, IDC_H6, m_H6);
DDX_Control(pDX, IDC_H5, m_H5);
DDX_Control(pDX, IDC_H4, m_H4);
DDX_Control(pDX, IDC_H3, m_H3);
DDX_Control(pDX, IDC_H2, m_H2);
DDX_Control(pDX, IDC_H1, m_H1);
DDX_Control(pDX, IDC_G8, m_G8);
DDX_Control(pDX, IDC_G7, m_G7);
DDX_Control(pDX, IDC_G6, m_G6);
DDX_Control(pDX, IDC_G5, m_G5);
DDX_Control(pDX, IDC_G4, m_G4);
DDX_Control(pDX, IDC_G3, m_G3);
DDX_Control(pDX, IDC_G2, m_G2);
DDX_Control(pDX, IDC_G1, m_G1);
DDX_Control(pDX, IDC_F8, m_F8);
DDX_Control(pDX, IDC_F7, m_F7);
DDX_Control(pDX, IDC_F6, m_F6);
DDX_Control(pDX, IDC_F5, m_F5);
DDX_Control(pDX, IDC_F4, m_F4);
DDX_Control(pDX, IDC_F3, m_F3);
DDX_Control(pDX, IDC_F2, m_F2);
DDX_Control(pDX, IDC_F1, m_F1);
DDX_Control(pDX, IDC_E8, m_E8);
DDX_Control(pDX, IDC_E7, m_E7);
DDX_Control(pDX, IDC_E6, m_E6);
DDX_Control(pDX, IDC_E5, m_E5);
DDX_Control(pDX, IDC_E4, m_E4);
DDX_Control(pDX, IDC_E3, m_E3);
DDX_Control(pDX, IDC_E2, m_E2);
DDX_Control(pDX, IDC_E1, m_E1);
DDX_Control(pDX, IDC_D8, m_D8);
DDX_Control(pDX, IDC_D7, m_D7);
DDX_Control(pDX, IDC_D6, m_D6);
DDX_Control(pDX, IDC_D5, m_D5);
DDX_Control(pDX, IDC_D4, m_D4);
DDX_Control(pDX, IDC_D3, m_D3);
DDX_Control(pDX, IDC_D2, m_D2);
DDX_Control(pDX, IDC_D1, m_D1);
DDX_Control(pDX, IDC_C8, m_C8);
DDX_Control(pDX, IDC_C7, m_C7);
DDX_Control(pDX, IDC_C6, m_C6);
DDX_Control(pDX, IDC_C5, m_C5);
DDX_Control(pDX, IDC_C4, m_C4);
DDX_Control(pDX, IDC_C3, m_C3);
DDX_Control(pDX, IDC_C2, m_C2);
DDX_Control(pDX, IDC_C1, m_C1);
DDX_Control(pDX, IDC_B8, m_B8);
DDX_Control(pDX, IDC_B7, m_B7);
DDX_Control(pDX, IDC_B6, m_B6);
DDX_Control(pDX, IDC_B5, m_B5);
DDX_Control(pDX, IDC_B4, m_B4);
DDX_Control(pDX, IDC_B3, m_B3);
DDX_Control(pDX, IDC_B2, m_B2);
DDX_Control(pDX, IDC_B1, m_B1);
DDX_Control(pDX, IDC_A8, m_A8);
DDX_Control(pDX, IDC_A7, m_A7);
DDX_Control(pDX, IDC_A6, m_A6);
DDX_Control(pDX, IDC_A5, m_A5);
DDX_Control(pDX, IDC_A4, m_A4);
DDX_Control(pDX, IDC_A3, m_A3);
DDX_Control(pDX, IDC_A2, m_A2);
DDX_Control(pDX, IDC_A1, m_A1);
DDX_Control(pDX, IDC_COMBO1, m_Combo);
DDX_Text(pDX, IDC_TEXT, m_Text);
DDX_Control(pDX, IDC_MSCOMM, m_ComPort);
DDX_Text(pDX, IDC_CALL, m_Call);
DDX_Text(pDX, IDC_DISCRIP, m_Discrip);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSoundDlg, CDialog)
//{{AFX_MSG_MAP(CSoundDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_CBN_SELCHANGE(IDC_COMBO1, OnSelchangeCombo1)
ON_BN_CLICKED(IDC_SEND, OnSend)
ON_BN_CLICKED(IDC_A1, OnA1)
ON_BN_CLICKED(IDC_A2, OnA2)
ON_BN_CLICKED(IDC_A3, OnA3)
ON_BN_CLICKED(IDC_A4, OnA4)
ON_BN_CLICKED(IDC_A5, OnA5)
ON_BN_CLICKED(IDC_A6, OnA6)
ON_BN_CLICKED(IDC_A7, OnA7)
ON_BN_CLICKED(IDC_A8, OnA8)
ON_BN_CLICKED(IDC_B1, OnB1)
ON_BN_CLICKED(IDC_B2, OnB2)
ON_BN_CLICKED(IDC_B3, OnB3)
ON_BN_CLICKED(IDC_B4, OnB4)
ON_BN_CLICKED(IDC_B5, OnB5)
ON_BN_CLICKED(IDC_B6, OnB6)
ON_BN_CLICKED(IDC_B7, OnB7)
ON_BN_CLICKED(IDC_B8, OnB8)
ON_BN_CLICKED(IDC_C1, OnC1)
ON_BN_CLICKED(IDC_C2, OnC2)
ON_BN_CLICKED(IDC_C3, OnC3)
ON_BN_CLICKED(IDC_C4, OnC4)
ON_BN_CLICKED(IDC_C5, OnC5)
ON_BN_CLICKED(IDC_C6, OnC6)
ON_BN_CLICKED(IDC_C7, OnC7)
ON_BN_CLICKED(IDC_C8, OnC8)
ON_BN_CLICKED(IDC_D1, OnD1)
ON_BN_CLICKED(IDC_D2, OnD2)
ON_BN_CLICKED(IDC_D3, OnD3)
ON_BN_CLICKED(IDC_D4, OnD4)
ON_BN_CLICKED(IDC_D5, OnD5)
ON_BN_CLICKED(IDC_D6, OnD6)
ON_BN_CLICKED(IDC_D7, OnD7)
ON_BN_CLICKED(IDC_D8, OnD8)
ON_BN_CLICKED(IDC_E1, OnE1)
ON_BN_CLICKED(IDC_E2, OnE2)
ON_BN_CLICKED(IDC_E3, OnE3)
ON_BN_CLICKED(IDC_E4, OnE4)
ON_BN_CLICKED(IDC_E5, OnE5)
ON_BN_CLICKED(IDC_E6, OnE6)
ON_BN_CLICKED(IDC_E7, OnE7)
ON_BN_CLICKED(IDC_E8, OnE8)
ON_BN_CLICKED(IDC_F1, OnF1)
ON_BN_CLICKED(IDC_F2, OnF2)
ON_BN_CLICKED(IDC_F3, OnF3)
ON_BN_CLICKED(IDC_F4, OnF4)
ON_BN_CLICKED(IDC_F5, OnF5)
ON_BN_CLICKED(IDC_F6, OnF6)
ON_BN_CLICKED(IDC_F7, OnF7)
ON_BN_CLICKED(IDC_F8, OnF8)
ON_BN_CLICKED(IDC_G1, OnG1)
ON_BN_CLICKED(IDC_G2, OnG2)
ON_BN_CLICKED(IDC_G3, OnG3)
ON_BN_CLICKED(IDC_G4, OnG4)
ON_BN_CLICKED(IDC_G5, OnG5)
ON_BN_CLICKED(IDC_G6, OnG6)
ON_BN_CLICKED(IDC_G7, OnG7)
ON_BN_CLICKED(IDC_G8, OnG8)
ON_BN_CLICKED(IDC_H1, OnH1)
ON_BN_CLICKED(IDC_H2, OnH2)
ON_BN_CLICKED(IDC_H4, OnH4)
ON_BN_CLICKED(IDC_H3, OnH3)
ON_BN_CLICKED(IDC_H5, OnH5)
ON_BN_CLICKED(IDC_H6, OnH6)
ON_BN_CLICKED(IDC_H7, OnH7)
ON_BN_CLICKED(IDC_H8, OnH8)
ON_BN_CLICKED(IDC_ADD, OnAdd)
ON_BN_CLICKED(IDC_DEC, OnDec)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSoundDlg message handlers
BOOL CSoundDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
for(int iii=0;iii<2;iii++)
Student[iii]=0x00;//把Student的元素都赋初值为零
m_Combo.SetCurSel(0);
m_Combo.GetLBText(m_Combo.GetCurSel(),m_Text);
m_Discrip="老师讲课,所有同学都能听到。若要切换为此功能,只需按“确认执行”按键。此功能为默认功能。";
UpdateData(false);
m_ComPort.SetCommPort(2);
if(!m_ComPort.GetPortOpen())
m_ComPort.SetPortOpen(TRUE);
m_ComPort.SetInputMode(comInputModeBinary);
m_ComPort.SetSettings("9600,n,8,1");
m_ComPort.SetRThreshold(1);
m_ComPort.SetInputLen(0);
m_ComPort.GetInput();
pOldFont=m_A1.GetFont();//返回已存在的字体指针,以备后用
//创建新字体
NewFont.CreateFont(
20, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_BOLD, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
"Arial"); // lpszFacename
// OnSend();
return TRUE; // return TRUE unless you set the focus to a control
}
void CSoundDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CSoundDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
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;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CSoundDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CSoundDlg::OnSelchangeCombo1()
{
// TODO: Add your control notification handler code here
int nIndex=m_Combo.GetCurSel();
m_Combo.GetLBText(nIndex,m_Text);//把列表框中第nIndex项,写到m_Text中
switch(nIndex)
{
case 0:m_Discrip="老师讲课,所有同学都能听到。若要切换为此功能,只需按“确认执行”按键。此功能为默认功能。";break;
case 1:m_Discrip="老师与某一同学单独通话。若要切换为此功能,需点取同学按键(以最后一次为准),然后按“确认执行”按键。";break;
case 2:m_Discrip="放录音1,老师、同学均可听到。若要切换为此功能,只需按“确认执行”按键。";break;
case 3:m_Discrip="放录音2,老师、同学均可听到。若要切换为此功能,只需按“确认执行”按键。";break;
case 4:m_Discrip="某两位同学之间单独通话。若要切换为此功能,需点取同学按键(依次点取两位同学的按键,若点取第三人,则认为前两次作废,重新开始选取),然后按“确认执行”按键。";break;
case 5:m_Discrip="每一行的同学各自讨论。若要切换为此功能,只需按“确认执行”按键。";break;
case 6:m_Discrip="每一列的同学各自讨论。若要切换为此功能,只需按“确认执行”按键。";break;
case 7:m_Discrip="测验时,请注意及时输入选择。测验结束后,按“结束测验”进行判分。最大试题数请不要超过30";
}
ClearFont();
Student[0]=0x00;Student[1]=0x00;PointStu=0;
UpdateData(false);
}
void CSoundDlg::OnSend()
{
// TODO: Add your control notification handler code here
int nIndex;
nIndex=m_Combo.GetCurSel(); //返回列表当前所选项的索引
switch(nIndex)
{
case 0://case语句只起标号作用,程序将执行符合判断的语句
//下面的所有命令。故需用break跳出switch结构
{
//当nIndex==0
TxData[0]=0x03;//表发送帧的长度为3,此为十六进制表示
TxData[1]=0x01;//表发送帧的命令帧为1
Transmitt();
//发送命令后,禁止组合框再次使用,
//直至接到返回命令后在ProcessData()中复原。
m_Combo.EnableWindow (FALSE);
break;//使用break跳出switch结构,还可以跳出循环体。
}
case 1:
{
TxData[0]=0x04;
TxData[1]=0x02;
if(Student[0]==0x00)
{
MessageBox("操作有误!","提示");//第一项为提示内容,第二项为对话框标题。
break;
}
TxData[2]=Student[0];
Transmitt();
m_Combo.EnableWindow (FALSE);
break;
}
case 2:
{
TxData[0]=0x03;
TxData[1]=0x03;
Transmitt();
m_Combo.EnableWindow (FALSE);
break;
}
case 3:
{
TxData[0]=0x03;
TxData[1]=0x04;
Transmitt();
m_Combo.EnableWindow (FALSE);
break;
}
case 4:
{ //该情况为两学生间通话,帧长度为5,命令类型为5,
//然后是两个学生ID,发送时再设置校验和项。
//故,供5个字节。
TxData[0]=0x05;
TxData[1]=0x05;
if(Student[0]==0x00||Student[1]==0x00)
{
MessageBox("操作有误!","提示");
break;
}
TxData[2]=Student[0];
TxData[3]=Student[1];
Transmitt();
m_Combo.EnableWindow (FALSE);
break;
}
case 5:
{
TxData[0]=0x03;
TxData[1]=0x06;
Transmitt();
m_Combo.EnableWindow (FALSE);
break;
}
case 6:
{
TxData[0]=0x03;
TxData[1]=0x07;
Transmitt();
m_Combo.EnableWindow (FALSE);
break;
}
case 7:
{
TxData[0]=0x03;
TxData[1]=0x0b;
Transmitt();
//此操作中,用变量Test标记测验的开始与结束。
if(Test==0)//注意此时使用逻辑等于
{
m_Combo.EnableWindow (FALSE);
GetDlgItem(IDC_SEND)->SetWindowText(_T("结束测验"));
Test=1;
}
else//评分并显示成绩
{
GetDlgItem(IDC_SEND)->SetWindowText(_T("确认执行"));
m_Combo.EnableWindow (TRUE);
Test=0;
/////////////////////////////////////////////////////////////
//评分程序
//下面这5行程序是给Score赋值,从而检验评分功能
// for(int n_Person=0;n_Person<=63;n_Person++)
// {
// for(n_Key=0;n_Key<=30;n_Key++)//设试题数不超过30
// Score[n_Person][n_Key]=1;
// }
for(int n_Person=0;n_Person<=63;n_Person++)
{
for(n_Key=0;n_Key<=30;n_Key++)//设试题数不超过30
Grade[n_Person]+=Score[n_Person][n_Key];
}
//弹出对话框,显示成绩
GradeDlg NewDlg;
for(int h=0;h<=63;h++)
NewDlg.DataNew[h]=Grade[h];
int result=NewDlg.DoModal();
memset(Score,0,sizeof(Score));//将数组中所有元素置零
memset(Grade,0,sizeof(Grade));//该数组也必须及时清空,否则其和将不断累加。
n_Person=0;
n_Key=0;
}
break;
}
default: MessageBox("请您重新选择!");break;
}
Student[0]=0x00;
Student[1]=0x00;
PointStu=0;
}
void CSoundDlg::Transmitt()
{
int i;
CByteArray array;
// char sOutput[10];
unsigned char Sum=0,Count;
Count=TxData[0];
for(i=0;i<Count-1;i++)
Sum+=TxData[i];
TxData[Count-1]=Sum;
array.RemoveAll();
array.SetSize(Count);
for(i=0;i<Count;i++)
array.SetAt(i,TxData[i]);
if(!m_ComPort.GetPortOpen())
m_ComPort.SetPortOpen(TRUE);
m_ComPort.SetOutput(COleVariant(array));
// m_TxData="";
// for(i=0;i<Count+1;i++)
// {sprintf(sOutput,"%02X,",TxData[i]);
// m_TxData+=sOutput;
// }
UpdateData(FALSE);
}
void CSoundDlg::OnA1()
{
//OnA1()完成两个功能。1、处理学生呼叫;2、选学生进行通讯。
// TODO: Add your control notification handler code here
if(m_Call=="A1")//相应A1呼叫
{
//去除粗体,清除呼号
ClearFont();
// m_Call="";
// pCallButton->SetFont(pOldFont);
// ChangeFont(&m_A1,pOleFont);
PointStu=0;
Student[PointStu]=0x01;
m_Text="师生通话:A1";
UpdateData(FALSE);
OnSend();
}
else//选学生进行通讯
{
//判断两学生是否重复
if(Student[0]!=0x01)//表还没有选过A1时
{
int nIndex=m_Combo.GetCurSel();
if(nIndex==4)//在"两学生间通话"的情况
{
if(PointStu==0)
{
Student[PointStu]=0x01;
Student[1]=0x00;
PointStu=1;
m_Text="两学生之间通话:A1";
}
else
{
Student[PointStu]=0x01;
PointStu=0;
m_Text+=",A1";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -