📄 wizarddlg.cpp
字号:
// WizardDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "Wizard.h"
#include "WizardDlg.h"
#include "Author.h"
#include "valarray"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CWizardDlg 对话框
CWizardDlg::CWizardDlg(CWnd* pParent /*=NULL*/)
: CDialog(CWizardDlg::IDD, pParent)
, mPort(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CWizardDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CWizardDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON7, &CWizardDlg::OnBnClickedButton7)
ON_BN_CLICKED(IDC_BUTTON5, &CWizardDlg::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON6, &CWizardDlg::OnBnClickedButton6)
ON_BN_CLICKED(IDC_BUTTON4, &CWizardDlg::OnBnClickedButton4)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_BUTTON2, &CWizardDlg::OnBnClickedButton2)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON3, &CWizardDlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON1, &CWizardDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_RADIO3, &CWizardDlg::OnBnClickedRadio3)
ON_BN_CLICKED(IDC_RADIO4, &CWizardDlg::OnBnClickedRadio4)
ON_BN_CLICKED(IDC_RADIO5, &CWizardDlg::OnBnClickedRadio5)
ON_BN_CLICKED(IDC_RADIO6, &CWizardDlg::OnBnClickedRadio6)
ON_BN_CLICKED(IDC_BUTTON9, &CWizardDlg::OnBnClickedButton9)
ON_BN_CLICKED(IDC_BUTTON8, &CWizardDlg::OnBnClickedButton8)
ON_CBN_SELCHANGE(IDC_COMBO2, &CWizardDlg::OnCbnSelchangeCombo2)
ON_CBN_SELCHANGE(IDC_COMBO1, &CWizardDlg::OnCbnSelchangeCombo1)
ON_BN_CLICKED(IDC_RADIO1, &CWizardDlg::OnBnClickedRadio1)
ON_BN_CLICKED(IDC_RADIO2, &CWizardDlg::OnBnClickedRadio2)
ON_BN_CLICKED(IDC_BUTTON10, &CWizardDlg::OnBnClickedButton10)
ON_BN_CLICKED(IDC_CHECK2, &CWizardDlg::OnBnClickedCheck2)
ON_BN_CLICKED(IDC_CHECK3, &CWizardDlg::OnBnClickedCheck3)
ON_BN_CLICKED(IDC_CHECK4, &CWizardDlg::OnBnClickedCheck4)
ON_BN_CLICKED(IDC_CHECK5, &CWizardDlg::OnBnClickedCheck5)
ON_BN_CLICKED(IDC_CHECK6, &CWizardDlg::OnBnClickedCheck6)
ON_BN_CLICKED(IDC_CHECK7, &CWizardDlg::OnBnClickedCheck7)
ON_BN_CLICKED(IDC_CHECK8, &CWizardDlg::OnBnClickedCheck8)
ON_BN_CLICKED(IDC_CHECK9, &CWizardDlg::OnBnClickedCheck9)
ON_BN_CLICKED(IDC_BUTTON11, &CWizardDlg::OnBnClickedButton11)
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_BUTTON12, &CWizardDlg::OnBnClickedButton12)
END_MESSAGE_MAP()
// CWizardDlg 消息处理程序
BOOL CWizardDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
CButton* pButton=(CButton*)GetDlgItem(IDC_RADIO2);
pButton->SetCheck(BST_CHECKED);
pButton=(CButton*)GetDlgItem(IDC_RADIO6);
pButton->SetCheck(BST_CHECKED);//以上4句初始化单选按钮的位置,选择马达全停,虚拟串口4
CProgressCtrl* pCtrl=(CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);
pCtrl->SetStep(1);
pCtrl->SetRange(0,100);
pCtrl->SetPos(25);//以上几句设置温度计的进度条控件步进,范围。
CEdit* pEdit=(CEdit*)GetDlgItem(IDC_EDIT1);
CString Temperature("+0 ℃");
pEdit->SetWindowTextW(Temperature);
pEdit=(CEdit*)GetDlgItem(IDC_EDIT2);
CString Voltage("+0.00 V");
pEdit->SetWindowTextW(Voltage);
pEdit=(CEdit*)GetDlgItem(IDC_EDIT3);
CString Resistor("100 Ω");
pEdit->SetWindowTextW(Resistor);//以上几句初始化编辑框的数值,随便写。
mPort="COM4";
INITCOM();//初始化串口
CComboBox* pCombo=(CComboBox*)GetDlgItem(IDC_COMBO1);
int i=0;
char* straddr=new char [32];
CString strCombo("");
for(i=0;i<256;i++)
{
sprintf(straddr,"0x%02X",i);
strCombo=straddr;
pCombo->AddString(strCombo);
}
pCombo->SetCurSel(0);
pCombo=(CComboBox*)GetDlgItem(IDC_COMBO2);
for(i=0;i<256;i++)
{
sprintf(straddr,"0x%02X",i);
strCombo=straddr;
pCombo->AddString(strCombo);
}
pCombo->SetCurSel(0);//以上几句给I2C读写的地址和数据那两个组合框赋值
SetTimer(WARNING,500,NULL);//设置一个500ms定时器
led=0xFF;//LED初始全灭,注意我使用的是共阳极接法。
delete [] straddr;
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CWizardDlg::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 CWizardDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CWizardDlg::OnBnClickedButton7()
{
// TODO: 在此添加控件通知处理程序代码
int i=0;
CString Operation("open");
CString ProgramName("AcroRd32.exe");
CString FileName("授权许可协议宋培林.pdf");
HINSTANCE hInst=ShellExecute(NULL,Operation,ProgramName,FileName,NULL,SW_SHOW);
//ShellExecute是执行外部程序。
//其实可以不用CString,用_T("文字内容")就行
i=(int)hInst;
if(i<=32)
{
ProgramName="Acrobat.exe";
hInst=ShellExecute(NULL,Operation,ProgramName,FileName,NULL,SW_SHOW);
}
//Acrobat reader有两个版本,一个只能读文件,一个还能制作pdf文件。两个程序名不一样。
}
void CWizardDlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
CString Operation("open");
CString ProgramName("NOTEPAD.exe");
CString FileName("mcu.asm");
HINSTANCE hInst=ShellExecute(NULL,Operation,ProgramName,FileName,NULL,SW_SHOW);
//同上
}
void CWizardDlg::OnBnClickedButton6()
{
// TODO: 在此添加控件通知处理程序代码
int i=0;
CString Operation("open");
CString ProgramName("NOTEPAD.exe");
CString FileName("自定义协议.txt");
HINSTANCE hInst=ShellExecute(NULL,Operation,ProgramName,FileName,NULL,SW_SHOW);
//同上
}
void CWizardDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
//如果点击了串口选择的按钮,就会重新初始化串口。
//我关闭了物理串口1的按钮,仿真状态,不可能用的。谁需要自行打开。
CloseHandle(hCom);
CButton* pButton=(CButton*)GetDlgItem(IDC_RADIO1);
if( (pButton->GetCheck())==BST_CHECKED )
{
mPort="COM1";
INITCOM();
}
else
{
mPort="COM4";
INITCOM();
}
}
int CWizardDlg::INITCOM(void)
{
hCom=CreateFile(mPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//打开串口,串口是排外的,只能一个程序打开,而且必须存在。
GetCommState(hCom,&dcb);//获得串口参数默认值
//DCB这个结构老复杂了,因为串口不仅仅是51那种简单的,还得和Modem这些设备接,所以很多
//参数不懂
dcb.BaudRate=2400;//波特率
dcb.ByteSize=8;//数据位
dcb.StopBits=ONESTOPBIT;//停止位
dcb.Parity=NOPARITY;//校验
SetCommState(hCom,&dcb);//让新的参数生效
SetupComm(hCom,1024,1024);//输入输出缓冲区大小,不写这句,windows也会默认分配
COMMTIMEOUTS Timeouts;//超时设置,不懂,从msdn抄的。其实这里不用也行
memset(&Timeouts,0,sizeof(Timeouts));
Timeouts.ReadIntervalTimeout=50;
Timeouts.ReadTotalTimeoutConstant=500;
Timeouts.ReadTotalTimeoutMultiplier=50;
Timeouts.WriteTotalTimeoutConstant=500;
Timeouts.WriteTotalTimeoutMultiplier=50;
SetCommTimeouts(hCom,&Timeouts);
return 0;
//这是初始化串口,大家去网上找资料看吧,我对串口不是太懂,程序啰嗦,马马虎虎能行。
}
void CWizardDlg::OnClose()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CloseHandle(hCom);//程序退出一定要关闭串口,否则下次没法用了。
CDialog::OnClose();
}
void CWizardDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
//这是测电压,大家把这个搞懂了,剩下的都一样。
//程序比较啰嗦,一直没有时间精简。
char str[20];
unsigned char c=0x00;
memset(str,0,20);//初始化字符串,全部填0,不填也没事。
str[0]=(char)0xC1;//这是通过串口要传送的命令,参考自定义协议文件。
DWORD* length=new DWORD;//后面需要一个表明实际读写字节长度的指针参数。
WriteFile(hCom,str,1,length,NULL);//通过串口发送,就像写文件一样
//第一个参数是串口句柄,句柄就是一个标识符。
//第二个是要发送的数据,必须是字符串
//第三个是期待发送的数据长度
//第四个返回实际发送的长度,如果串口发生异常,那么不一定发送你
//期待的长度,读串口也一样,可以根据这个参数采取补救措施
DWORD dwEvtMask;
OVERLAPPED o;
o.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
o.Internal=0;
o.InternalHigh=0;
o.Offset=0;
o.OffsetHigh=0;//以上不懂,反正msdn告诉咱咋做咱就咋做
SetCommMask(hCom, EV_RXCHAR);//设置一个事件(实际上类似51的中端,我说类似,没说就是)
//等待串口接收事件,如果对方给本串口发来数据,这个事件就被触发。
WaitCommEvent(hCom, &dwEvtMask, &o);//等待设置的事件
//大家注意了,如果一直没有数据发来,那程序就一直等着,没有响应。
//好的做法,是使用类似中断的机制,有数据到来,触发一个回调函数,做进一步处理
//大家可以使用串口控件,此控件是微软做的。
if(dwEvtMask&EV_RXCHAR)
{
//这不数据来了
ReadFile(hCom,str,1,length,NULL);//读一个字节
//剩下的就是根据测什么推导结果,并且显示
CEdit* pEdit=(CEdit*)GetDlgItem(IDC_EDIT2);//找到标号为IDC_EDIT2的编辑框,
//在此显示结果
c=(unsigned char)str[0];
double Value=5.0*c/255;
//有了C,就不必愁数学运算了,当然也得是简单的,要是积分微分也不行
//可以调用matlab做,有机会再教你吧
sprintf(str,"%1.2lf V",Value);//格式化数据,跟printf差不多
//注意编译编译本程序,会有很多警告,不用管,主要是微软不停的发布
//新的运行库,导致老的调用VC2005视为邪教分子。
CString Voltage(str);
pEdit->SetWindowTextW(Voltage);//显示
}
delete length;
}
void CWizardDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//每次启动都会显示一些警告画面,就在这
//如果单独运行本程序,而不是让Proteus调用,就会显示作者信息,也在这里
CString Caption("Warning!");
CString Text("警告!如果您从外部运行本程序,请确保“51开发板典藏版”被打开且\
\n处于仿真状态!否则程序可能接收不到任何数据而处于“无响应状态”!");
if(nIDEvent==WARNING)
{
KillTimer(WARNING);//定时器只用一次,然后销毁
//windows的定时器不怎么好用,最好分辨1ms,还不能保证,因为它是分时操作系统
//精确定时,比如微秒级以下,必须直接调硬件,或者编写VXD和VDM驱动程序,俺
//不懂。因为处理器里定时器资源有限,而且操作系统绝对依赖定时,所以windows不会
//轻易让你操作硬件的。
if(theApp.IsOut==FALSE)
{
Text="\
请注意:1测量温度时程序反应慢(Proteus得仿真DS18B20的时序,所以慢)。如\
果在仿真状态改变DS18B20的温度,需要至少按两次测量温度按钮才能刷新温度值。\
(原因不知道,估计是Proteus的问题,当然了,也不能冤枉Proteus,也可能是程\
序有问题,但是在主动模式下没有过出现这个问题。)2不要像打游戏那样噼里啪啦\
地按按钮,通过串口把命令传给仿真状态的Proteus,速度过快是无法识别的,造成\
串口接收紊乱,容易引起复位。这里是仿真8051,不是操作双核CPU。等操作的结果\
稳定后,稍等一下,再按别的按钮。如果您温柔一点儿,应该不会出问题。";
MessageBox(Text,NULL,MB_OK);
return;
}
MessageBox(Text,Caption,MB_OK);
CAuthor m_Author;
m_Author.DoModal();
Text="\
请注意:1测量温度时程序反应慢(Proteus得仿真DS18B20的时序,所以慢)。如\
果在仿真状态改变DS18B20的温度,需要至少按两次测量温度按钮才能刷新温度值。\
(原因不知道,估计是Proteus的问题,当然了,也不能冤枉Proteus,也可能是程\
序有问题,但是在主动模式下没有过出现这个问题。)2不要像打游戏那样噼里啪啦\
地按按钮,通过串口把命令传给仿真状态的Proteus,速度过快是无法识别的,造成\
串口接收紊乱,容易引起复位。这里是仿真8051,不是操作双核CPU。等操作的结果\
稳定后,稍等一下,再按别的按钮。如果您温柔一点儿,应该不会出问题。";
MessageBox(Text,NULL,MB_OK);
}
CDialog::OnTimer(nIDEvent);
}
void CWizardDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
//这是测电阻,跟上面类似,以下类似的不解释了,不一样的解释
//注意看一下OnBnClickedButton8()这个函数
char str[20];
unsigned char c=0x00;
memset(str,0,20);
str[0]=(char)0xC2;
DWORD* length=new DWORD;
WriteFile(hCom,str,1,length,NULL);
DWORD dwEvtMask;
OVERLAPPED o;
o.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
o.Internal=0;
o.InternalHigh=0;
o.Offset=0;
o.OffsetHigh=0;
SetCommMask(hCom, EV_RXCHAR);
WaitCommEvent(hCom, &dwEvtMask, &o);
if(dwEvtMask&EV_RXCHAR)
{
ReadFile(hCom,str,1,length,NULL);
CEdit* pEdit=(CEdit*)GetDlgItem(IDC_EDIT3);
c=(unsigned char)str[0];
int Value=int(c*23500.0/3060.-910.0);
sprintf(str,"%-04dΩ",Value);
CString Resistor(str);
pEdit->SetWindowTextW(Resistor);
}
delete length;
}
void CWizardDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
char str[20];
char c=0x00;
memset(str,0,20);
str[0]=(char)0xC7;
DWORD* length=new DWORD;
WriteFile(hCom,str,1,length,NULL);
DWORD dwEvtMask;
OVERLAPPED o;
o.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
o.Internal=0;
o.InternalHigh=0;
o.Offset=0;
o.OffsetHigh=0;
SetCommMask(hCom, EV_RXCHAR);
WaitCommEvent(hCom, &dwEvtMask, &o);
if(dwEvtMask&EV_RXCHAR)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -