VCMFC编写串口调试助手.docx

上传人:b****6 文档编号:5995373 上传时间:2023-01-02 格式:DOCX 页数:48 大小:735.66KB
下载 相关 举报
VCMFC编写串口调试助手.docx_第1页
第1页 / 共48页
VCMFC编写串口调试助手.docx_第2页
第2页 / 共48页
VCMFC编写串口调试助手.docx_第3页
第3页 / 共48页
VCMFC编写串口调试助手.docx_第4页
第4页 / 共48页
VCMFC编写串口调试助手.docx_第5页
第5页 / 共48页
点击查看更多>>
下载资源
资源描述

VCMFC编写串口调试助手.docx

《VCMFC编写串口调试助手.docx》由会员分享,可在线阅读,更多相关《VCMFC编写串口调试助手.docx(48页珍藏版)》请在冰豆网上搜索。

VCMFC编写串口调试助手.docx

VCMFC编写串口调试助手

VC(MFC)编写串口调试助手

1.序

确定基本功能:

1.自动寻找串口,并自动添加到下拉框中共选择;

2.有波特率、数据位、停止位、校验位的选择设置;

3.串口打开控制按钮;

4.发送、清除按钮;

5.接收是自动实现的;

6.有定时自动发送功能;

7.有传送文件功能;

8.有状态栏显示,指示串口状态,设置参数和发送接收显示。

下面就一步步实现,本人纯业余,只是记录下来这个学习过程,请勿拍砖。

开发平台VisualC++6.0英文版,电脑是i7-2670Q四核8G内存1G独显的笔记本,装的win764位旗舰版,因此VC6兼容不是太好,有些小毛病,不过不影响编写。

 

2.创建MFC项目

File->New->Projects选择MFCAppWizard(exe),项目名称commassist

选择OK

选中Dialogbased,点击Next>。

默认选项,点击Next>,

继续默认选项,点击Next>,如果选中Asastaticallylinkedlibrary,生产的EXE可直接在没装VC的机器上运行。

可以在项目中进行更改。

选择第二个CCommassistDlg,点击Finish

点击OK。

项目创建完毕,进入项目。

删除界面上确定和取消按钮以及静态文字。

3.创建界面

保存后便可以开始创建界面了。

参考界面

仿照设计的界面,具体添加按钮或编辑框等的布局步骤就不用细说了。

4.图标修改

在资源视图中选择Icon右键InsertIcon加入打开和关闭的Icon图标或自行绘制,如下图

IDR_MAINFRAME原为MFC提供的图标,这里我直接改成自己的,生成EXE后将会显示这个图标。

下面将帮助页面图标也改为自绘图标。

在打开按钮旁边加入自绘的打开和关闭图标:

先加入工具条中的Picture,然后选中右键看属性,并如图将Image选为默认的IDI_ICON_CLOSE。

如下图

5.基本设置

下面对各个按钮及编辑框设置进行描述

右键串口对应的ComboBox,ID设置为IDC_COMLIST,Type设置为DropList,Sort不选择(我系统是WIN764位,不选中反而自动排序,至于XP得试试看了,以下的选择相同)。

右键波特率对应的ComboBox,ID设置为IDC_BAUD,Type及Sort同上。

右键数据位对应的ComboBox,ID设置为IDC_BDATA,Type及Sort同上。

右键停止位对应的ComboBox,ID设置为IDC_BSTOP,Type及Sort同上。

右键校验位对应的ComboBox,ID设置为IDC_CAL,Type及Sort同上。

每个下拉框要点击右边的小箭头,然后将其拉长,不然显示不出内容。

接收EDIT框ID设置为IDC_EDIT_RX。

发送EDIT框ID设置为IDC_EDIT_TX。

自动发送时间间隔的EDIT框ID设置为IDC_EDIT_TIMER。

选择文件后面的EDIT框ID设置为IDC_EDIT_FILEPATH。

接收区的十六进制显示的CheckBox复选框ID设置为IDC_CHECK_HEXRX。

发送区的十六进制发送的CheckBox复选框ID设置为IDC_CHECK_HEXTX。

按钮“打开串口”ID设置为IDC_COMCONTROL。

按钮“清空显示区”ID设置为IDC_BTN_CLRRX。

按钮“手动发送”ID设置为IDC_BTN_HANDSEND。

按钮“清空发送区”ID设置为IDC_BTN_CLRTX。

按钮“自动发送”ID设置为IDC_BTN_AUTOSEND。

按钮“选择文件”ID设置为IDC_BTN_SELCTFILE。

按钮“发送文件”ID设置为IDC_BTN_SENDFILE。

6.开始写代码

6.1.基本思路:

因为串口通信部分代码我可能用在以后的单片机上位机上,因此考虑单独形成CPP和H文件,定义为comm.cpp和comm.h。

在comm.cpp中编写串口创建、打开、关闭以及串口监听线程(用于自动接收)的代码,同时加入进制转换或显示的函数,这些在comm.h文件中申明,在主对话框中包含comm.h即可。

想修改按钮样式,在网上搜了一圈,结果不轻松,最后确定创建新类来实现。

6.2.创建自定义按钮类:

View->ClassWizard选择AddClass->New,名字MyButton,基类选择CButton。

在头文件MyButton.h中加入以下变量和函数定义:

private:

intm_Style;//按钮形状(0-正常,1-当前,2-按下,3-锁定)

boolb_InRect;//鼠标进入标志

CStringm_strText;//按钮文字

COLORREFm_ForeColor;//文本颜色

COLORREFm_MouseInColor;//鼠标进入时文本颜色

COLORREFm_BackColor;//背景颜色

COLORREFm_LockForeColor;//锁定按钮的文字颜色

CRectm_ButRect;//按钮尺寸

CFont*p_Font;//字体

voidDrawButton(CDC*pDC);//画正常按钮

//接口函数

public:

MyButton();

voidSetText(CStringstr);//设置文字

voidSetForeColor(COLORREFcolor);//设置文本颜色

voidSetBkColor(COLORREFcolor);//设置背景颜色

voidSetTextFont(intFontHight,LPCTSTRFontName);//设置字体

在MyButton.cpp的构造函数中初始化变量:

m_Style=1;//m_Style=0;//按钮形状风格

b_InRect=false;//鼠标进入标志

m_strText=_T("");//按钮文字(使用默认文字)

m_ForeColor=RGB(0,0,0);//文字颜色(黑色)

m_MouseInColor=RGB(0,0,255);//鼠标进入时文字颜色(蓝色)

m_BackColor=RGB(230,230,230);//m_BackColor=RGB(243,243,243);//背景色(灰白色)

m_LockForeColor=GetSysColor(COLOR_GRAYTEXT);//锁定按钮的文字颜色

p_Font=NULL;//字体指针

用ClassWizard添加下列消息函数:

PreSubclassWindow();

DrawItem();

onMouseMove();

OnLButtonDown();

OnLButtonUp();

在各函数内加入代码:

voidMyButton:

:

PreSubclassWindow()

{

//TODO:

Addyourspecializedcodehereand/orcallthebaseclass

ModifyStyle(0,BS_OWNERDRAW);//设置按钮属性为自画式

//PreSubclassWindow()在按钮创建前自动执行,所以我们可以在其中做一些初始工作。

//这里只做了一项工作,就是为按钮设置属性为“自绘”式,这样,用户在添加按钮后,就不需设置“Ownerdraw”属性了。

CButton:

:

PreSubclassWindow();

}

voidMyButton:

:

DrawItem(LPDRAWITEMSTRUCTlpDrawItemStruct)

{

//TODO:

Addyourcodetodrawthespecifieditem

CDC*pDC=CDC:

:

FromHandle(lpDrawItemStruct->hDC);

m_ButRect=lpDrawItemStruct->rcItem;//获取按钮尺寸

if(m_strText.IsEmpty())

GetWindowText(m_strText);//获取按钮文本

intnSavedDC=pDC->SaveDC();

VERIFY(pDC);

DrawButton(pDC);//绘制按钮

pDC->RestoreDC(nSavedDC);

}

//DrawItem()函数是一个关键函数,按钮的绘制工作就在这里进行,它的作用相当于对话框中的OnPaint()函数和视图中的OnDraw()函数。

//这里我做了三项工作:

获取按钮尺寸、获取按钮文本、绘制按钮。

其中绘制工作在自定义函数DrawButton()中完成。

以下就是绘制过程:

voidMyButton:

:

DrawButton(CDC*pDC)

{

//调整状态

if(m_Style==3)m_Style=0;

if(GetStyle()&WS_DISABLED)

m_Style=3;//禁止状态

//根据状态调整边框颜色和文字颜色

COLORREFbColor,fColor;//bColor为边框颜色,fColor为文字颜色

switch(m_Style)

{

case0:

bColor=RGB(192,192,192);fColor=m_ForeColor;break;//正常按钮

case1:

bColor=RGB(255,255,255);fColor=m_ForeColor;break;//鼠标进入时按钮

case2:

bColor=RGB(192,192,192);fColor=m_MouseInColor;break;//按下的按钮

case3:

bColor=m_BackColor;fColor=m_LockForeColor;break;//锁定的按钮

}

//绘制按钮背景

CBrushBrush;

Brush.CreateSolidBrush(m_BackColor);//背景刷

pDC->SelectObject(&Brush);

CPenPen;

Pen.CreatePen(PS_SOLID,3,bColor);

pDC->SelectObject(&Pen);

pDC->RoundRect(&m_ButRect,CPoint(10,10));//画圆角矩形

//绘制按钮按下时的边框

if(m_Style!

=2)

{

CRectRect;

Rect.SetRect(m_ButRect.left+1,m_ButRect.top+1,m_ButRect.right,m_ButRect.bottom);

pDC->DrawEdge(&Rect,BDR_RAISEDINNER,BF_RECT);//画边框

}

//绘制按钮文字

pDC->SetTextColor(fColor);//画文字

pDC->SetBkMode(TRANSPARENT);

pDC->DrawText(m_strText,&m_ButRect,DT_SINGLELINE|DT_CENTER

|DT_VCENTER|DT_END_ELLIPSIS);

//绘制拥有焦点按钮的虚线框

if(GetFocus()==this)

{

CRectRect;

Rect.SetRect(m_ButRect.left+3,m_ButRect.top+2,m_ButRect.right-3,m_ButRect.bottom-2);

pDC->DrawFocusRect(&Rect);//画拥有焦点的虚线框

}

}

//变量m_Style表征当前按钮状态,它的取值为:

0-正常,1-当前,2-按下,3-锁定。

不同状态下按钮的边框颜色和文字颜色有所不同。

//m_Style的值在鼠标响应函数中进行修改。

//绘制工作主要利用CDC类的绘图函数完成,主要注意在m_Style不同取值下表现出来的差别。

voidMyButton:

:

OnLButtonDown(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

m_Style=2;

Invalidate();//重绘按钮

CButton:

:

OnLButtonDown(nFlags,point);

}

//OnLButtonDown()函数是单击鼠标左键时的消息函数。

这里只是重新绘制按钮,具体的单击响应应该在拥有按钮的对话框或视图中进行。

voidMyButton:

:

OnMouseMove(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

if(!

b_InRect||GetCapture()!

=this)//鼠标进入按钮

{

b_InRect=true;//设置进入标志

SetCapture();//捕获鼠标

m_Style=2;//m_Style=1;//设置按钮状态

Invalidate();//重绘按钮

}

else

{

if(!

m_ButRect.PtInRect(point))//鼠标离开按钮

{

b_InRect=false;//清除进入标志

ReleaseCapture();//释放捕获的鼠标

m_Style=1;//m_Style=0;//设置按钮状态

Invalidate();//重绘按钮

}

}

CButton:

:

OnMouseMove(nFlags,point);

}

//onMouseMove()函数是鼠标移动消息函数,用于判定当前鼠标指针是否在按钮上。

b_InRect是个标志,为true表示鼠标指针进入了按钮区域,

//此时要捕获鼠标,让鼠标命令传送给按钮。

当鼠标指针离开按钮时,要清除b_InRect标志,并且释放捕获的鼠标,让其它窗口可以接收鼠标命令。

//Invalidate()函数用于更新按钮,它会自动调用DrawItem()函数重新绘制按钮。

//设置条件的目的是仅在鼠标指针进入按钮和离开按钮时更新按钮,这样可以防止鼠标在按钮上移动时发生闪烁。

voidMyButton:

:

OnLButtonUp(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

m_Style=1;

Invalidate();//重绘按钮

CButton:

:

OnLButtonUp(nFlags,point);

}

//OnLButtonUp()函数是单击鼠标左键后弹起时的消息函数。

这里也只是重绘按钮,这样能使按钮在按下和弹起时有所不同,使按钮看上去有动态效果。

//接口函数是用CMyButton类定义的按钮修改颜色、字体和按钮文字的接口,由以下函数组成:

//设置按钮文本

voidMyButton:

:

SetText(CStringstr)

{

m_strText=_T("");

SetWindowText(str);

}

//设置文本颜色

voidMyButton:

:

SetForeColor(COLORREFcolor)

{

m_ForeColor=color;

Invalidate();

}

//设置背景颜色

voidMyButton:

:

SetBkColor(COLORREFcolor)

{

m_BackColor=color;

Invalidate();

}

//设置字体(字体高度、字体名)

voidMyButton:

:

SetTextFont(intFontHight,LPCTSTRFontName)

{

if(p_Font)deletep_Font;//删除旧字体

p_Font=newCFont;

p_Font->CreatePointFont(FontHight,FontName);//创建新字体

SetFont(p_Font);//设置字体

}

///由于新字体由new生成,必须显式回收,这项工作可以在CMyButton类的析构函数中进行:

/*CMyButton:

:

~CMyButton()

{

if(p_Font)deletep_Font;//删除字体

}

*/

//这样一个可设置颜色、字体的按钮类就做好了。

使用时,先在对话框中放置好按钮,再用ClassWizard为按钮添加控制变量,

//并且将变量的类型设置为CMyButton。

之后,可以用该变量调用接口函数设置按钮颜色和字体。

OK,自定义按钮完成。

6.3.实现过程及代码:

现在可以对按钮,EDIT框等控件添加变量,文字描述麻烦,上图。

comm.cpp编写内容如下

#include"stdafx.h"

#include"commassist.h"

#include"commassistDlg.h"

#include"comm.h"

charConvertHexChar(charch);

HANDLEhCom;//串口句柄

CStringstrcomname;//串口名,如"COM1"

boolComIsOK;//串口打开状态标识,为真表示已打开,否则未打开

//============自动寻找串口函数=================================

//函数功能:

通过扫描注册表来找出当前所有物理串口

//输入参数:

//返回类型:

//说明:

若搜索成功,则每搜到一个串口便发送消息通知主对话框,并将串口号以WPARAM传递

voidFindComm()

{

//枚举当前系统中的串口

LONGresult=0;

HKEYkey=NULL;

result=RegOpenKeyEx(HKEY_LOCAL_MACHINE,//需要打开的主键的名称

"HARDWARE\\DEVICEMAP\\SERIALCOMM",//需要打开的子键的名称,设备串口

0,//保留,必须设置为0

KEY_READ,//安全访问标记,也就是权限

&key);//得到的将要打开键的句柄,当不再需要句柄,

//必须调用RegCloseKey关闭它

if(result)

{

AfxMessageBox("无法获取串口,请确认是否安装并连接串口!

");

return;

}

TCHARportname[250];//串口名

TCHARdata[250];

DWORDportnamelen=0;//串口名长度

DWORDdatalen=0;

intindex=0;

while

(1)//找完COM后跳出

{

portnamelen=255;

datalen=255;

result=RegEnumValue(key,//Long,一个已打开项的句柄,或者指定一个标准项名

index++,//Long,欲获取值的索引。

注意第一个值的索引编号为零

portname,//String,用于装载位于指定索引处值名的一个缓冲区

&portnamelen,//Long,用于装载lpValueName缓冲区长度的一个变量。

//一旦返回,它会设为实际载入缓冲区的字符数量

NULL,//Long,未用;设为零

NULL,//Long,用于装载值的类型代码的变量

(LPBYTE)data,//Byte,用于装载值数据的一个缓冲区

&datalen);//Long,用于装载lpData缓冲区长度的一个变量。

//一旦返回,它会设为实际载入缓冲区的字符数量

if(result)break;

//发送消息,WM_USER+1为自定义消息,即找到串口的,并将串口号"COMx"通过WPARAM参数传送给主对话框窗口

//:

:

AfxGetMainWnd()->m_hWnd,获得主对话框句柄

//(WPARAM)(LPCTSTR)data,类型转换

:

:

SendMessage(:

:

AfxGetMainWnd()->m_hWnd,WM_FOUNDCOMM,(WPARAM)(LPCTSTR)data,0);

}

RegCloseKey(key);//调用RegCloseKey关闭打开键的句柄

}

//============自动寻找串口函数结束==================

//==========串口打开函数===========================

//功能:

打开串口,将已打开的串口句柄赋值给hCom,给出串口打开状态ComIsOK,完成串口状态设置

//输入参数:

波特率,数据位,停止位,校验位

//返回类型:

voidOpenComm(intnBaud,intnData,intnStop,intnCal)

{

hCom=CreateFile(strcomname,//串口号

GENERIC_READ|GENERIC_WRITE,//允许读或写

0,//独占方式

NULL,

OPEN_EXISTING,//打开而不是创建

FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//重叠方式,用于异步通信

NULL);

if(hCom==INVALID_HANDLE_VALUE)

{

AfxMessageBox("打开COM失败,串口不存在或已被占用!

");

ComIsOK=false;

return;

}

ComIsOK=true;

SetCommMask(hCom,EV_TXEMPTY|EV_RXC

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 节日庆典

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1