mfc 使用MsComm自制USB助手

来源:互联网 发布:真月谭月姬 漫画软件 编辑:程序博客网 时间:2024/04/29 10:07

1.添加MsComm控件
右键点击添加ActiveX控件
选择Microsoft Communications Control, version 6.0
会出现像电话一样的图标,这个图标在程序运行时不会显示。
2.添加接收数据相应事件
这里写图片描述
3.添加其它控件
其它控件
4.运行结果
运行结果截图

5.MsComm编程基本步骤
6.工程文件
代码:

// UseMsCommDlg.cpp : 实现文件//#include "stdafx.h"#include "UseMsComm.h"#include "UseMsCommDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialog{public:    CAboutDlg();// 对话框数据    enum { IDD = IDD_ABOUTBOX };    protected:    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现protected:    DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){    CDialog::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)END_MESSAGE_MAP()// CUseMsCommDlg 对话框CUseMsCommDlg::CUseMsCommDlg(CWnd* pParent /*=NULL*/)    : CDialog(CUseMsCommDlg::IDD, pParent)    , m_strBord(_T(""))    , m_strChkbit(_T(""))    , m_strDatabit(_T(""))    , m_strStopbit(_T(""))    , m_strSendCnt(_T(""))    , m_bShowAsHex(FALSE)    , m_strSavePath(_T(""))    , m_bAutoSend(FALSE)    , m_strAutoSendCyc(_T("1000"))    , m_strSendFilePath(_T(""))    , m_strTx(_T("Tx:0"))    , m_strRx(_T("Rx:0"))    , m_bSendAsHex(FALSE){    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);    m_nRx = m_nTx = 0;}// 析构函数CUseMsCommDlg::~CUseMsCommDlg(){    POSITION pos = m_portList.GetHeadPosition();    for(int i=0;i<m_portList.GetCount();i++)    {        tPortInfo *inf = &m_portList.GetNext(pos);        if(inf->lpName) delete[] inf->lpName;        if(inf->lpPath) delete[] inf->lpPath;    }}void CUseMsCommDlg::DoDataExchange(CDataExchange* pDX){    CDialog::DoDataExchange(pDX);    DDX_Control(pDX, IDC_MSCOMM, m_mscom);    DDX_Control(pDX, IDC_RICHEDIT2, m_rceditRecv);    DDX_Control(pDX, IDC_COM_PORT, m_combPort);    DDX_Control(pDX, IDC_BUT_OPENPORT, m_butOpenPort);    DDX_CBString(pDX, IDC_COM_BORD, m_strBord);    DDX_CBString(pDX, IDC_COMB_CHECKBIT, m_strChkbit);    DDX_CBString(pDX, IDC_COM_DATABIT, m_strDatabit);    DDX_CBString(pDX, IDC_COM_STOPBIT, m_strStopbit);    DDX_Control(pDX, IDC_COM_BORD, m_combBord);    DDX_Control(pDX, IDC_COMB_CHECKBIT, m_combChkbit);    DDX_Control(pDX, IDC_COM_DATABIT, m_combDatabit);    DDX_Control(pDX, IDC_COM_STOPBIT, m_combStopbit);    DDX_Text(pDX, IDC_EDIT_SEND, m_strSendCnt);    DDX_Control(pDX, IDC_EDIT_SEND, m_editSend);    DDX_Control(pDX, IDC_BUTTON1, m_butSend);    DDX_Control(pDX, IDC_BUT_STOPSHOW, m_butStopShow);    DDX_Check(pDX, IDC_CHECK_16SYS, m_bShowAsHex);    DDX_Text(pDX, IDC_EDIT_SAVEPATH, m_strSavePath);    DDX_Check(pDX, IDC_CHECK_AUTOSEND, m_bAutoSend);    DDX_Text(pDX, IDC_EDIT_SENDCYCLE, m_strAutoSendCyc);    DDX_Control(pDX, IDC_EDIT_SENDCYCLE, m_editAutoSendCyc);    DDX_Text(pDX, IDC_EDIT_SENDFILE_PATH, m_strSendFilePath);    DDX_Text(pDX, IDC_EDIT_RXNUM, m_strTx);    DDX_Text(pDX, IDC_EDIT_TXNUM, m_strRx);    DDX_Check(pDX, IDC_CHECK_16SYSSEND, m_bSendAsHex);}BEGIN_MESSAGE_MAP(CUseMsCommDlg, CDialog)    ON_WM_SYSCOMMAND()    ON_WM_PAINT()    ON_WM_QUERYDRAGICON()    //}}AFX_MSG_MAP    ON_CBN_DROPDOWN(IDC_COM_PORT, &CUseMsCommDlg::OnCbnDropdownComPort)    ON_BN_CLICKED(IDC_BUT_OPENPORT, &CUseMsCommDlg::OnBnClickedButOpenport)    ON_BN_CLICKED(IDC_BUTTON1, &CUseMsCommDlg::OnBnClickedSend)    ON_WM_CLOSE()    ON_BN_CLICKED(IDC_BUT_CLEARRECV, &CUseMsCommDlg::OnBnClickedButClearrecv)    ON_BN_CLICKED(IDC_BUT_STOPSHOW, &CUseMsCommDlg::OnBnClickedButStopShow)    ON_BN_CLICKED(IDC_BUT_BROWSE_FILE, &CUseMsCommDlg::OnBnClickedButBrowseFile)    ON_BN_CLICKED(IDC_CHECK_AUTOSEND, &CUseMsCommDlg::OnBnClickedCheckAutosend)    ON_WM_TIMER()    ON_BN_CLICKED(IDC_BUT_CLEAR, &CUseMsCommDlg::OnBnClickedButClear)    ON_BN_CLICKED(IDC_BUT_BROW_SENDFILE, &CUseMsCommDlg::OnBnClickedButBrowSendfile)    ON_BN_CLICKED(IDC_BUT_CACLCLREAR, &CUseMsCommDlg::OnBnClickedButCaclclrear)    ON_BN_CLICKED(IDC_BUT_SAVEDATA, &CUseMsCommDlg::OnBnClickedButSavedata)    ON_BN_CLICKED(IDC_BUT_SENDFILE, &CUseMsCommDlg::OnBnClickedButSendfile)    ON_BN_CLICKED(IDC_CHECK_16SYS, &CUseMsCommDlg::OnBnClickedCheck16sys)    ON_BN_CLICKED(IDC_CHECK_16SYSSEND, &CUseMsCommDlg::OnBnClickedCheck16syssend)END_MESSAGE_MAP()// CUseMsCommDlg 消息处理程序BOOL CUseMsCommDlg::OnInitDialog(){    CDialog::OnInitDialog();    // 将“关于...”菜单项添加到系统菜单中。    // IDM_ABOUTBOX 必须在系统命令范围内。    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);    ASSERT(IDM_ABOUTBOX < 0xF000);    CMenu* pSysMenu = GetSystemMenu(FALSE);    if (pSysMenu != NULL)    {        BOOL bNameValid;        CString strAboutMenu;        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);        ASSERT(bNameValid);        if (!strAboutMenu.IsEmpty())        {            pSysMenu->AppendMenu(MF_SEPARATOR);            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);        }    }    // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动    //  执行此操作    SetIcon(m_hIcon, TRUE);         // 设置大图标    SetIcon(m_hIcon, FALSE);        // 设置小图标    m_butOpenPort.EnableWindow(FALSE);    m_butSend.EnableWindow(FALSE);    m_combBord.SetCurSel(0);    m_combChkbit.SetCurSel(0);    m_combDatabit.SetCurSel(0);    m_combStopbit.SetCurSel(0);    m_strAppDir = GetAppDir();         // 获取应用程序路径    m_strSavePath = m_strAppDir + _T("\\") + g_lpDefFileName;    m_bStopShow = FALSE;    m_bShowAsHex = FALSE;    UpdateData(FALSE);    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}void CUseMsCommDlg::OnSysCommand(UINT nID, LPARAM lParam){    if ((nID & 0xFFF0) == IDM_ABOUTBOX)    {        CAboutDlg dlgAbout;        dlgAbout.DoModal();    }    else    {        CDialog::OnSysCommand(nID, lParam);    }}// 如果向对话框添加最小化按钮,则需要下面的代码//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,//  这将由框架自动完成。void CUseMsCommDlg::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 CUseMsCommDlg::OnQueryDragIcon(){    return static_cast<HCURSOR>(m_hIcon);}// 鼠标点击串口复选框void CUseMsCommDlg::OnCbnDropdownComPort(){    ScanPort();}// 扫描串口void CUseMsCommDlg::ScanPort(void){    BOOL bRet = FALSE;    SP_DEVICE_INTERFACE_DATA DevInterfaceData;    DWORD dwRequiredSize = 0;    PSP_INTERFACE_DEVICE_DETAIL_DATA pDevDetialData = NULL;    GUID InterfaceGuid = { 0x4d36e978, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 };    HDEVINFO hDevInfo;    DevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);    int i = 0;    hDevInfo = SetupDiGetClassDevs(        &InterfaceGuid,        NULL,        NULL,        DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);    if(hDevInfo == INVALID_HANDLE_VALUE)    {        return;    }    m_butOpenPort.EnableWindow(FALSE);    m_portList.RemoveAll();    while(m_combPort.GetCount())         m_combPort.DeleteString(0);    while(1)    {        bRet = SetupDiEnumDeviceInterfaces(hDevInfo,NULL,&InterfaceGuid,i++,&DevInterfaceData);        if(!bRet)        {            break;        }        // 得到Interface的详细信息        bRet = SetupDiGetDeviceInterfaceDetail(hDevInfo,&DevInterfaceData,NULL,0,&dwRequiredSize,NULL);        if(bRet)        {            break;        }        // 为详细信息分配内存        if(pDevDetialData)        {            free(pDevDetialData);            pDevDetialData = NULL;        }        pDevDetialData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(dwRequiredSize);        if(pDevDetialData == NULL)            break;        // 得到interface的纤细信息        pDevDetialData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);        SP_DEVINFO_DATA DeviceInfoData;        DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);        bRet = SetupDiGetDeviceInterfaceDetail(            hDevInfo,            &DevInterfaceData,            pDevDetialData,            dwRequiredSize,            &dwRequiredSize,            &DeviceInfoData);        if(!bRet)        {            break;        }        tPortInfo pinf;        int len = wcslen(pDevDetialData->DevicePath);        pinf.lpName = new WCHAR[256];        pinf.lpPath = new WCHAR[len+1];        wcscpy(pinf.lpPath,pDevDetialData->DevicePath);        bRet = SetupDiGetDeviceRegistryProperty(hDevInfo,&DeviceInfoData,SPDRP_FRIENDLYNAME,NULL,(PBYTE)pinf.lpName,256,NULL);        pinf.dwIndex = GetPortNumFromName(pinf.lpName);        if(pinf.dwIndex <= 0) continue;        m_portList.AddTail(pinf);    }    if(pDevDetialData)    {        free(pDevDetialData);        pDevDetialData = NULL;    }    SetupDiDestroyDeviceInfoList(hDevInfo);    CString strMsg;    POSITION pos = m_portList.GetHeadPosition();    for(int i=0;i<m_portList.GetCount();i++)    {        tPortInfo inf = m_portList.GetNext(pos);        m_combPort.AddString(TrimBrackets(inf.lpName));        m_combPort.SetItemData(i,inf.dwIndex);    }    if(m_combPort.GetCount() > 0)    {        m_combPort.SetCurSel(0);        m_butOpenPort.EnableWindow(TRUE);    }}// 通过串口完整名字获取串口号int CUseMsCommDlg::GetPortNumFromName(LPWSTR lpPortName){    CString strName(lpPortName);    int idxS = strName.Find(_T("COM"));    if(idxS == -1) return -1;    idxS += 3;    int idxE = strName.Find(_T(')'),idxS);    if(idxE == -1) return -1;    CString strNum = strName.Mid(idxS,idxE-idxS);    int n = _wtoi(strNum);    return n;}// 取得括号中的内容CString CUseMsCommDlg::TrimBrackets(CString strPortName){    int idxS = strPortName.Find(_T('('));    idxS++;    int idxE = strPortName.Find(_T(')'),idxS);    CString strName = strPortName.Mid(idxS,idxE - idxS);    return strName;}// 打开串口按钮响应事件void CUseMsCommDlg::OnBnClickedButOpenport(){    UpdateData();    int iSel = m_combPort.GetCurSel();    int nPort = m_combPort.GetItemData(iSel);    if(nPort > 0)    {        if(m_mscom.get_PortOpen())       // 如果串口已经打开,则关闭        {            m_mscom.put_PortOpen(FALSE);            m_butOpenPort.SetWindowText(_T("打开串口"));            m_butSend.EnableWindow(FALSE);            return;        }        m_mscom.put__CommPort(nPort);    // 选择COM        m_mscom.put_InBufferSize(1024);  // 接收缓冲区        m_mscom.put_OutBufferSize(1024); // 发送缓冲区        m_mscom.put_InputLen(0);         // 设置当前接收区长度为0,表示全部读取        m_mscom.put_InputMode(1);        // 以二进制方式读写数据        m_mscom.put_RThreshold(1);       // 接收缓冲区有1个及以上字符时,将响应接收数据事件        CString strSetting;        strSetting.Format(_T("%s,%s,%s,%s"),m_strBord,TrimBrackets(m_strChkbit),m_strDatabit,m_strStopbit);        m_mscom.put_Settings(strSetting);        try        {            m_mscom.put_PortOpen(TRUE);            m_butOpenPort.SetWindowText(_T("关闭串口"));            m_butSend.EnableWindow(TRUE);        }        catch (CException* )        {            m_mscom.put_OutBufferCount(0);            CString strErr;            strErr.Format(_T("打开串口COM%d失败, 请检查串口是否被占用."),nPort);            MessageBox(strErr,_T("无法打开串口"),MB_OK | MB_ICONQUESTION);        }    }}// 发送数据按钮void CUseMsCommDlg::OnBnClickedSend(){    UpdateData();    OnSend(m_strSendCnt);    UpdateData(FALSE);}// 主窗口关闭事件void CUseMsCommDlg::OnClose(){    if(m_mscom.get_PortOpen()) // 如果串口已经打开,则关闭    {        m_mscom.put_PortOpen(FALSE);    }    CDialog::OnClose();}BEGIN_EVENTSINK_MAP(CUseMsCommDlg, CDialog)    ON_EVENT(CUseMsCommDlg, IDC_MSCOMM, 1, CUseMsCommDlg::OnCommMscomm, VTS_NONE)END_EVENTSINK_MAP()// 接收数据响应函数void CUseMsCommDlg::OnCommMscomm(){    static unsigned int nsCnt = 0;    VARIANT variant_inp;    COleSafeArray safeArray_inp;    long len, k;    unsigned int data[1024] = { 0 };    BYTE rxdata[1024] = { 0 };    if(2 == m_mscom.get_CommEvent()) // 接收缓冲区内有字符    {        nsCnt ++;        variant_inp = m_mscom.get_Input();    // 读缓冲区消息        safeArray_inp = variant_inp;          // 变量转换        len = safeArray_inp.GetOneDimSize();  // 得到有效的数组长度        for(k = 0; k < len; k++)        {            safeArray_inp.GetElement(&k,rxdata+k);        }        m_nRx += k;                           // 接收的总字节数        WCHAR lpwstr[1024] = { 0 };        for(k = 0; k < len; k++)        {            if(!m_bShowAsHex)                wsprintf(lpwstr,_T("%s%c"),lpwstr,*(rxdata+k));            else                wsprintf(lpwstr,_T("%s %x"),lpwstr,*(rxdata+k));        }        CString strMsg;        strMsg.Format(_T("接收数据:%s\r\n"),lpwstr);        m_strRx.Format(_T("Rx:%d"),m_nRx);        if(!m_bStopShow) //停止显示标志位        {            m_rceditRecv.SetSel(-1,-1);            m_rceditRecv.ReplaceSel(strMsg);        }    }    UpdateData(FALSE); }// 清空接收区void CUseMsCommDlg::OnBnClickedButClearrecv(){    m_rceditRecv.SetSel(0,-1);    m_rceditRecv.ReplaceSel(_T(""));}void CUseMsCommDlg::OnBnClickedButStopShow(){    if(!m_bStopShow)        {        m_bStopShow = FALSE;        m_butStopShow.SetWindowText(_T("继续显示"));    }    else    {        m_bStopShow = TRUE;        m_butStopShow.SetWindowText(_T("停止显示"));    }}// 获取应用程序的路径CString CUseMsCommDlg::GetAppDir(){    LPWSTR lpFileName = new WCHAR[MAX_PATH];    GetModuleFileName(NULL,lpFileName,MAX_PATH);    CString strFileName(lpFileName);    int nPos = strFileName.ReverseFind(_T('\\'));    CString strAppDir = strFileName.Mid(0,nPos);    if(lpFileName)        delete[] lpFileName;    return strAppDir;}// 浏览文件,保存数据void CUseMsCommDlg::OnBnClickedButBrowseFile(){    LPWSTR lpfilter = _T("文本文件(*.txt)|*.txt||");    CFileDialog cf(FALSE,_T(".txt"),m_strSavePath,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, lpfilter);    if(cf.DoModal() == IDOK)    {        m_strSavePath = cf.GetPathName();        UpdateData(FALSE);    }}// 自动发送复选框void CUseMsCommDlg::OnBnClickedCheckAutosend(){    UpdateData();    if(m_bAutoSend) // 自动发送    {        int nEscTime = _wtoi(m_strAutoSendCyc);        SetTimer(2000,nEscTime,NULL);        m_butSend.EnableWindow(FALSE);        m_editAutoSendCyc.EnableWindow(FALSE);    }    else    {        KillTimer(2000);        m_butSend.EnableWindow(TRUE);        m_editAutoSendCyc.EnableWindow(TRUE);    }}// 定时器响应函数void CUseMsCommDlg::OnTimer(UINT_PTR nIDEvent){    UpdateData();    OnSend(m_strSendCnt);    UpdateData(FALSE);    CDialog::OnTimer(nIDEvent);}// 发送数据函数void CUseMsCommDlg::OnSend(CString strData){    if(strData.IsEmpty())        return;    if(!m_bSendAsHex)        m_mscom.put_Output(COleVariant(strData));    else    {        int len = strData.GetLength();        LPWSTR lpwstr = new WCHAR[len*6];        memset(lpwstr,0,sizeof(lpwstr));        for(int i=0;i<len;i++)        {            wsprintf(lpwstr,_T("%s %x"),lpwstr,(int)strData.GetAt(i));        }        CString strHexData(lpwstr);        m_mscom.put_Output(COleVariant(strHexData));    }    if(!m_bStopShow) // 停止显示标志位    {        CString strShow;        if(m_bShowAsHex) // 是否以16进制显示        {            int len = strData.GetLength();            LPWSTR lpwstr = new WCHAR[len*6];            memset(lpwstr,0,sizeof(lpwstr));            for(int i=0;i<len;i++)            {                wsprintf(lpwstr,_T("%s %x"),lpwstr,(int)strData.GetAt(i));            }            strShow.Format(_T("发送数据:%s\r\n"),lpwstr);            if(lpwstr)                delete[] lpwstr;        }        else            strShow.Format(_T("发送数据:%s\r\n"),strData);          m_nTx += CStringA(strData).GetLength();                     // 获取字符串字节数        m_strTx.Format(_T("Tx:%d"),m_nTx);        m_rceditRecv.SetSel(-1,-1);        m_rceditRecv.ReplaceSel(strShow);    }}// 清空重填按钮void CUseMsCommDlg::OnBnClickedButClear(){    m_strSendCnt = _T("");    m_editSend.SetFocus();    UpdateData(FALSE);}// 浏览文件,发送文件void CUseMsCommDlg::OnBnClickedButBrowSendfile(){    CString strFilter = _T("文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||");    CFileDialog cf(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,strFilter);    if(cf.DoModal() == IDOK)    {        m_strSendFilePath = cf.GetPathName();        UpdateData(FALSE);    }}// 计数清零按钮void CUseMsCommDlg::OnBnClickedButCaclclrear(){    m_strTx = _T("Tx:0");    m_strRx = _T("Rx:0");    m_nRx = m_nTx = 0;    UpdateData(FALSE);}// 保存数据按钮事件处理函数void CUseMsCommDlg::OnBnClickedButSavedata(){    UpdateData();    CFile file;    if(!file.Open(m_strSavePath,CFile::modeCreate | CFile::modeWrite))    {        CString strMsg;        strMsg.Format(_T("创建文件%s失败 . %d"),m_strSavePath,GetLastError());        MessageBox(strMsg,_T("tip"),MB_OK | MB_ICONINFORMATION);        return;    }    CString strCnt;    m_rceditRecv.GetWindowText(strCnt);    char* lpstrCnt = UnicodeToAnsic(strCnt);    file.Write(lpstrCnt,strlen(lpstrCnt));    delete[] lpstrCnt;    file.Close();}// 发送文件按钮事件处理函数void CUseMsCommDlg::OnBnClickedButSendfile(){       UpdateData();    CFile file;    if(!file.Open(m_strSendFilePath,CFile::modeRead))    {        CString strMsg;        strMsg.Format(_T("打开文件%s失败 . %d"),m_strSendFilePath,GetLastError());        MessageBox(strMsg,_T("Tip"),MB_OK | MB_ICONINFORMATION);        return;    }    char strbuf[1024] = { 0 };    while(file.Read(strbuf,1024))    {        LPWSTR lpwstr = AnsicToUnicode(strbuf);        OnSend(lpwstr);        memset(strbuf,0,sizeof(strbuf));        if(lpwstr)            delete[] lpwstr;    }    file.Close();}// 宽字符转化为窄字符char* CUseMsCommDlg::UnicodeToAnsic(CString lpwstr){    int nLen = WideCharToMultiByte(CP_ACP,0,lpwstr,-1,NULL,0,NULL,NULL);    if(0 == nLen)        return NULL;    char* pchstr = new char[nLen];    WideCharToMultiByte(CP_ACP,0,lpwstr,-1,pchstr,nLen,NULL,NULL);    return pchstr;}// 窄字符转化为宽字符wchar_t* CUseMsCommDlg::AnsicToUnicode(char* pchstr){    int nLen = MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,pchstr,-1,NULL,0);    if(0 == nLen)    {        return NULL;    }    wchar_t *pwchstr = new wchar_t[nLen];    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pchstr, -1, pwchstr, nLen);    return pwchstr;}// 点击16进制显示复选框void CUseMsCommDlg::OnBnClickedCheck16sys(){    m_bShowAsHex = ~m_bShowAsHex;}// 16进制发送复选框void CUseMsCommDlg::OnBnClickedCheck16syssend(){    m_bSendAsHex = ~m_bSendAsHex;}

// UseMsCommDlg.cpp : 实现文件
//

include “stdafx.h”

include “UseMsComm.h”

include “UseMsCommDlg.h”

ifdef _DEBUG

define new DEBUG_NEW

endif

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

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// 对话框数据
enum { IDD = IDD_ABOUTBOX };

protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
DECLARE_MESSAGE_MAP()
};

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

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

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()

// CUseMsCommDlg 对话框

CUseMsCommDlg::CUseMsCommDlg(CWnd* pParent /=NULL/)
: CDialog(CUseMsCommDlg::IDD, pParent)
, m_strBord(_T(“”))
, m_strChkbit(_T(“”))
, m_strDatabit(_T(“”))
, m_strStopbit(_T(“”))
, m_strSendCnt(_T(“”))
, m_bShowAsHex(FALSE)
, m_strSavePath(_T(“”))
, m_bAutoSend(FALSE)
, m_strAutoSendCyc(_T(“1000”))
, m_strSendFilePath(_T(“”))
, m_strTx(_T(“Tx:0”))
, m_strRx(_T(“Rx:0”))
, m_bSendAsHex(FALSE)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_nRx = m_nTx = 0;
}

// 析构函数
CUseMsCommDlg::~CUseMsCommDlg()
{
POSITION pos = m_portList.GetHeadPosition();
for(int i=0;i

在InitInstance函数中添加AfxInitRichEdit2()函数。
“`