﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-C++历程</title><link>http://www.cppblog.com/jianxin0558/</link><description>生活中的点点滴滴在此积累。</description><language>zh-cn</language><lastBuildDate>Mon, 13 Apr 2026 09:42:39 GMT</lastBuildDate><pubDate>Mon, 13 Apr 2026 09:42:39 GMT</pubDate><ttl>60</ttl><item><title>CFileDialog的用法简介</title><link>http://www.cppblog.com/jianxin0558/archive/2009/03/09/76051.html</link><dc:creator>李建新</dc:creator><author>李建新</author><pubDate>Mon, 09 Mar 2009 15:41:00 GMT</pubDate><guid>http://www.cppblog.com/jianxin0558/archive/2009/03/09/76051.html</guid><wfw:comment>http://www.cppblog.com/jianxin0558/comments/76051.html</wfw:comment><comments>http://www.cppblog.com/jianxin0558/archive/2009/03/09/76051.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jianxin0558/comments/commentRss/76051.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jianxin0558/services/trackbacks/76051.html</trackback:ping><description><![CDATA[楚秦(37187453) 23:35:06<br>CFileDialog的用法简介！！<br>CFileDialog文件选择对话框的使用：首先构造一个对象并提供<br>相应的参数，构造函数原型如下：<br>CFileDialog::CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );参数意义如下：<br><br>bOpenFileDialog 为TRUE则显示打开对话框，为FALSE则显示保存对话文件对话框。<br>lpszDefExt 指定默认的文件扩展名。<br>lpszFileName 指定默认的文件名。<br>dwFlags 指明一些特定风格。<br>lpszFilter 是最重要的一个参数，它指明可供选择的文件类型和相应的扩展名。参数格式如：<br>"Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|*.xlc; *.xls|All Files (*.*)|*.*||";文件类型说明和扩展名间用 | 分隔，同种类型文件的扩展名间可以用 ; 分割，每种文件类型间用 | 分隔，末尾用 || 指明。<br>pParentWnd 为父窗口指针。<br>创建文件对话框可以使用DoModal()，在返回后可以利用下面的函数得到用户选择：<br>CString CFileDialog::GetPathName( ) 得到完整的文件名，包括目录名和扩展名如：c:\test\test1.txt<br>CString CFileDialog::GetFileName( ) 得到完整的文件名，包括扩展名如：test1.txt<br>CString CFileDialog::GetExtName( ) 得到完整的文件扩展名，如：txt<br>CString CFileDialog::GetFileTitle ( ) 得到完整的文件名，不包括目录名和扩展名如：test1<br>POSITION CFileDialog::GetStartPosition( ) 对于选择了多个文件的情况得到第一个文件位置。<br>CString CFileDialog::GetNextPathName( POSITION&amp; pos ) 对于选择了多个文件的情况得到下一个文件位置，并同时返回当前文件名。但必须已经调用过POSITION CFileDialog::GetStartPosition( )来得到最初的POSITION变量。 <br>楚秦(37187453) 23:35:53<br>CFileDialog dlg(TRUE,<br>&nbsp;&nbsp;&nbsp; "DEM Files (*DEM)",<br>&nbsp;&nbsp;&nbsp; NULL,<br>&nbsp;&nbsp;&nbsp; OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |OFN_ALLOWMULTISELECT|OFN_ENABLESIZING,<br>&nbsp;&nbsp;&nbsp; _T("Layer Files (*.DEM;*.TIFF;*.BMP;*.JPG)|*.DEM;*.TIFF;*.BMP;*.JPG;)||"),<br>&nbsp;&nbsp;&nbsp; NULL);<br><img src ="http://www.cppblog.com/jianxin0558/aggbug/76051.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jianxin0558/" target="_blank">李建新</a> 2009-03-09 23:41 <a href="http://www.cppblog.com/jianxin0558/archive/2009/03/09/76051.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC++串口编程之基于Win32</title><link>http://www.cppblog.com/jianxin0558/archive/2008/12/11/69208.html</link><dc:creator>李建新</dc:creator><author>李建新</author><pubDate>Thu, 11 Dec 2008 11:49:00 GMT</pubDate><guid>http://www.cppblog.com/jianxin0558/archive/2008/12/11/69208.html</guid><wfw:comment>http://www.cppblog.com/jianxin0558/comments/69208.html</wfw:comment><comments>http://www.cppblog.com/jianxin0558/archive/2008/12/11/69208.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/jianxin0558/comments/commentRss/69208.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jianxin0558/services/trackbacks/69208.html</trackback:ping><description><![CDATA[<h1 id="artibodyTitle">VC++串口编程之基于Win32 API</h1>
1、API描述<br><br>　　在WIN32 API中，串口使用文件方式进行访问，其操作的API基本上与文件操作的API一致。<br><br>　　打开串口<br><br>　　Win32 中用于打开串口的API 函数为CreateFile，其原型为：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>HANDLE CreateFile (<br>　LPCTSTR lpFileName, //将要打开的串口逻辑名，如COM1 或COM2<br>　DWORD dwAccess, //指定串口访问的类型，可以是读取、写入或两者并列<br>　DWORD dwShareMode, //指定共享属性，由于串口不能共享,该参数必须置为0<br>　LPSECURITY_ATTRIBUTES lpsa, //引用安全性属性结构，缺省值为NULL<br>　DWORD dwCreate, //创建标志，对串口操作该参数必须置为OPEN EXISTING<br>　DWORD dwAttrsAndFlags, //属性描述，用于指定该串口是否可进行异步操作，<br>　//FILE_FLAG_OVERLAPPED：可使用异步的I/O<br>　HANDLE hTemplateFile //指向模板文件的句柄，对串口而言该参数必须置为NULL<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　例如，以下程序用于以同步读写方式打开串口COM1：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>HANDLE hCom;<br>DWORD dwError;<br>hCon = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);<br>if (hCom == (HANDLE)0xFFFFFFFF)<br>{<br>　dwError = GetLastError();<br>　MessageBox(dwError);<br>}</td>
        </tr>
    </tbody>
</table>
<br>
对于dwAttrsAndFlags参数及FILE_FLAG_OVERLAPPED标志的由来，可解释如下：Windows文件操作分为同步I/O和
重叠I/O(Overlapped I/
O)两种方式，在同步I/O方式中，API会阻塞直到操作完成以后才能返回（在多线程方式中，虽然不会阻塞主线程，但是仍然会阻塞监听线程）；而在重叠I
/O方式中，API会立即返回，操作在后台进行，避免线程的阻塞。重叠I/O非常灵活，它也可以实现阻塞（例如我们可以设置一定要读取到一个数据才能进行
到下一步操作)。如果进行I/O操作的API
在没有完成操作的情况下返回，我们可以通过调用GetOverLappedResult()函数阻塞到I/O操作完成后返回。<br><br>　　配置串口<br><br>　　配置串口是通过改变设备控制块DCB(Device Control Block) 的成员变量值来实现的，接收缓冲区和发送缓冲区的大小可通过SetupComm函数来设置。<br><br>　　DCB结构体定义为：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>typedef struct _DCB { // dcb <br>　DWORD DCBlength; // sizeof(DCB) <br>　DWORD BaudRate; // current baud rate <br>　DWORD fBinary: 1; // binary mode, no EOF check <br>　DWORD fParity: 1; // enable parity checking <br>　DWORD fOutxCtsFlow:1; // CTS output flow control <br>　DWORD fOutxDsrFlow:1; // DSR output flow control <br>　DWORD fDtrControl:2; // DTR flow control type <br>　DWORD fDsrSensitivity:1; // DSR sensitivity <br>　DWORD fTXContinueOnXoff:1; // XOFF continues Tx <br>　DWORD fOutX: 1; // XON/XOFF out flow control <br>　DWORD fInX: 1; // XON/XOFF in flow control <br>　DWORD fErrorChar: 1; // enable error replacement <br>　DWORD fNull: 1; // enable null stripping <br>　DWORD fRtsControl:2; // RTS flow control <br>　DWORD fAbortOnError:1; // abort reads/writes on error <br>　DWORD fDummy2:17; // reserved <br>　WORD wReserved; // not currently used <br>　WORD XonLim; // transmit XON threshold <br>　WORD XoffLim; // transmit XOFF threshold <br>　BYTE ByteSize; // number of bits/byte, 4-8 <br>　BYTE Parity; // 0-4=no,odd,even,mark,space <br>　BYTE StopBits; // 0,1,2 = 1, 1.5, 2 <br>　char XonChar; // Tx and Rx XON character <br>　char XoffChar; // Tx and Rx XOFF character <br>　char ErrorChar; // error replacement character <br>　char EofChar; // end of input character <br>　char EvtChar; // received event character <br>　WORD wReserved1; // reserved; do not use <br>} DCB; <br>而SetupComm函数的原型则为：<br>BOOL SetupComm(<br>　HANDLE hFile, // handle to communications device<br>　DWORD dwInQueue, // size of input buffer<br>　DWORD dwOutQueue // size of output buffer<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　以下程序将串口设置为：波特率为9600，数据位数为7位，停止位为2 位，偶校验，接收缓冲区和发送缓冲区大小均为1024个字节，最后用PurgeComm函数终止所有的后台读写操作并清空接收缓冲区和发送缓冲区：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>DCB dcb;<br>dcb.BaudRate = 9600; //波特率为9600<br>dcb.ByteSize = 7; //数据位数为7位<br>dcb.Parity = EVENPARITY; //偶校验<br>dcb.StopBits = 2; //两个停止位<br>dcb.fBinary = TRUE;<br>dcb.fParity = TRUE;<br>if (!SetCommState(hCom, &amp;dcb))<br>{<br>　MessageBox("串口设置出错!");<br>} <br>SetupComm(hCom, 1024, 1024);<br>PurgeComm(hCom, PURCE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);</td>
        </tr>
    </tbody>
</table>
<br>　　超时设置<br><br>　　超时设置是通过改变COMMTIMEOUTS结构体的成员变量值来实现的，COMMTIMEOUTS的原型为：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>typedef struct _COMMTIMEOUTS<br>{<br>　DWORD ReadIntervalTimeout; //定义两个字符到达的最大时间间隔，单位：毫秒<br>　//当读取完一个字符后，超过了ReadIntervalTimeout，仍未读取到下一个字符，就会<br>　//发生超时<br>　DWORD ReadTotalTimeoutMultiplier; <br>　DWORD ReadTotalTimeoutConstant;<br>　//其中各时间所满足的关系如下：<br>　//ReadTotalTimeout = ReadTotalTimeOutMultiplier* BytesToRead + ReadTotalTimeoutConstant<br>　DWORD WriteTotalTimeoutMultiplier;<br>　DWORD WriteTotalTimeoutConstant;<br>} COMMTIMEOUTS, *LPCOMMTIMEOUTS;<br></td>
        </tr>
    </tbody>
</table>
<br>　　设置超时的函数为SetCommTimeouts，其原型中接收COMMTIMEOUTS的指针为参数：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BOOL SetCommTimeouts(<br>　HANDLE hFile, // handle to communications device<br>　LPCOMMTIMEOUTS lpCommTimeouts // pointer to comm time-out structure<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　以下程序将串口读操作的超时设定为10 毫秒：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>COMMTIMEOUTS to;<br>memset(&amp;to, 0, sizeof(to));<br>to.ReadIntervalTimeout = 10;<br>SetCommTimeouts(hCom, &amp;to);</td>
        </tr>
    </tbody>
</table>
<br>　　与SetCommTimeouts对应的GetCommTimeouts()函数的原型为：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BOOL GetCommTimeouts(<br>　HANDLE hFile, // handle of communications device<br>　LPCOMMTIMEOUTS lpCommTimeouts // pointer to comm time-out structure<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　事件设置<br><br>　　在读写串口之前，需要用SetCommMask ()函数设置事件掩模来监视指定通信端口上的事件，其原型为：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BOOL SetCommMask(<br>　HANDLE hFile, //标识通信端口的句柄<br>　DWORD dwEvtMask //能够使能的通信事件<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　有了Set当然还会有Get，与SetCommMask对应的GetCommMask()函数的原型为：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BOOL GetCommMask(<br>　HANDLE hFile, //标识通信端口的句柄<br>　LPDWORD lpEvtMask // address of variable to get event mask<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　串口上可以发生的事件可以是如下事件列表中的一个或任意组合：EV_BREAK、EV_CTS、EV_DSR、EV_ERR、EV_RING、EV_RLSD、EV_RXCHAR、EV_RXFLAG、EV_TXEMPTY。<br><br>　　我们可以用WaitCommEvent()函数来等待串口上我们利用SetCommMask ()函数设置的事件：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BOOL WaitCommEvent(<br>　HANDLE hFile, //标识通信端口的句柄<br>　LPDWORD lpEvtMask, // address of variable for event that occurred<br>　LPOVERLAPPED lpOverlapped, // address of overlapped structure<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　WaitCommEvent()函数一直阻塞，直到串口上发生我们用所SetCommMask ()函数设置的通信事件为止。一般而言，当WaitCommEvent()返回时，程序员可以由分析*lpEvtMask而获得发生事件的类别，再进行相应的处理。<br><br>　　读串口<br><br>　　对串口进行读取所用的函数和对文件进行读取所用的函数相同，读函数原型如下：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BOOL ReadFile(<br>　HANDLE hFile, // handle of file to read<br>　LPVOID lpBuffer, // pointer to buffer that receives data<br>　DWORD nNumberOfBytesToRead, // number of bytes to read<br>　LPDWORD lpNumberOfBytesRead, // pointer to number of bytes read<br>　LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　写串口<br><br>　　对串口进行写入所用的函数和对文件进行写入所用的函数相同，写函数原型如下：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BOOL WriteFile(<br>　HANDLE hFile, // handle to file to write to<br>　LPCVOID lpBuffer, // pointer to data to write to file<br>　DWORD nNumberOfBytesToWrite, // number of bytes to write<br>　LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written<br>　LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　关闭串口<br><br>　　利用API 函数实现串口通信时关闭串口非常简单，只需使用CreateFile 函数返回的句柄作为参数调用CloseHandle 即可：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BOOL CloseHandle(<br>　HANDLE hObject // handle to object to close<br>);</td>
        </tr>
    </tbody>
</table>
<br>2.例程<br><br>　　在笔者的《<a  href="http://dev.yesky.com/244/2247244.shtml" target="_blank">深入浅出Win32多线程程序设计之综合实例</a>》中我们已经给出一个利用WIN API进行串口通信的例子，这里再给出一个类似的例子，以进一步加深理解。<br><br>
<table align="center" border="0" width="90%">
    <tbody>
        <tr>
            <td>
            <div align="center"><img  src="http://dev.yesky.com/imagelist/06/02/8e7o38j51a7r.jpg" border="0"></div>
            </td>
        </tr>
    </tbody>
</table>
<br>　　对话框上控件对应的资源文件(.RC)中的内容如下：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BEGIN<br>　EDITTEXT IDC_RECV_EDIT,28,119,256,46,ES_AUTOHSCROLL<br>　GROUPBOX "发送数据",IDC_STATIC,19,15,282,70<br>　GROUPBOX "接收数据",IDC_STATIC,19,100,282,80<br>　EDITTEXT IDC_SEND_EDIT,29,33,214,39,ES_AUTOHSCROLL<br>　PUSHBUTTON "清除",IDC_CLEAR_BUTTON,248,33,50,14<br>　PUSHBUTTON "发送",IDC_SEND_BUTTON,248,55,50,14<br>END</td>
        </tr>
    </tbody>
</table>
<br>　　而整个对话框的消息映射（描述了消息及其对应的行为）如下：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BEGIN_MESSAGE_MAP(CSerialPortAPIDlg, CDialog)<br>//{{AFX_MSG_MAP(CSerialPortAPIDlg)<br>　ON_WM_SYSCOMMAND()<br>　ON_WM_PAINT()<br>　ON_WM_QUERYDRAGICON()<br>　ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClearButton)<br>　ON_BN_CLICKED(IDC_SEND_BUTTON, OnSendButton)<br>　ON_MESSAGE(COM_RECVDATA, OnRecvData)<br>//}}AFX_MSG_MAP<br>END_MESSAGE_MAP()</td>
        </tr>
    </tbody>
</table>
<br>　　我们为IDC_SEND_EDIT和IDC_RECV_EDIT编辑框控件分别添加了一个CString变量m_recv和m_send，下面的代码描述了这一行为：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>class CSerialPortAPIDlg : public CDialog<br>{<br>　// Construction<br>　public:<br>　　CSerialPortAPIDlg(CWnd* pParent = NULL); // standard constructor<br><br>　　// Dialog Data<br>　　//{{AFX_DATA(CSerialPortAPIDlg)<br>　　　enum { IDD = IDD_SERIALPORTAPI_DIALOG };<br>　　　CString m_recv; //IDC_RECV_EDIT控件对应的变量<br>　　　CString m_send; //IDC_SEND_EDIT控件对应的变量<br>　　//}}AFX_DATA<br><br>　　// ClassWizard generated virtual function overrides<br>　　//{{AFX_VIRTUAL(CSerialPortAPIDlg)<br>　protected:<br>　　virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support<br>　//}}AFX_VIRTUAL<br><br>　// Implementation<br>　protected:<br>　　BOOL OpenSerialPort1();<br>　　HICON m_hIcon;<br><br>　　// Generated message map functions<br>　　//{{AFX_MSG(CSerialPortAPIDlg)<br>　　　virtual BOOL OnInitDialog();<br>　　　afx_msg void OnSysCommand(UINT nID, LPARAM lParam);<br>　　　afx_msg void OnPaint();<br>　　　afx_msg HCURSOR OnQueryDragIcon();<br>　　　afx_msg void OnClearButton();<br>　　　afx_msg void OnSendButton();<br>　　　afx_msg void OnRecvData(WPARAM wParam, LPARAM lParam);<br>　　//}}AFX_MSG<br>　　DECLARE_MESSAGE_MAP()<br>};<br><br>CSerialPortAPIDlg::CSerialPortAPIDlg(CWnd* pParent /*=NULL*/)<br>: CDialog(CSerialPortAPIDlg::IDD, pParent)<br>{<br>　//{{AFX_DATA_INIT(CSerialPortAPIDlg)<br>　　//在构造函数中初始化变量<br>　　m_recv = _T(""); //在构造函数中初始化变量<br>　　m_send = _T("");<br>　//}}AFX_DATA_INIT<br>　// Note that LoadIcon does not require a subsequent DestroyIcon in Win32<br>　m_hIcon = AfxGetApp()-&gt;LoadIcon(IDR_MAINFRAME);<br>}<br><br>//建立编辑框控件和变量之间的映射<br>void CSerialPortAPIDlg::DoDataExchange(CDataExchange* pDX)<br>{<br>　CDialog::DoDataExchange(pDX);<br>　//{{AFX_DATA_MAP(CSerialPortAPIDlg)<br>　　DDX_Text(pDX, IDC_RECV_EDIT, m_recv);<br>　　DDX_Text(pDX, IDC_SEND_EDIT, m_send);<br>　//}}AFX_DATA_MAP<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　在对话框的OnInitDialog()函数中，我们启动窗口监听线程并将主窗口句柄传递给线程控制函数：<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>BOOL CSerialPortAPIDlg::OnInitDialog()<br>{<br>　CDialog::OnInitDialog();<br><br>　// Add "About..." menu item to system menu.<br><br>　// IDM_ABOUTBOX must be in the system command range.<br>　ASSERT((IDM_ABOUTBOX &amp; 0xFFF0) == IDM_ABOUTBOX);<br>　ASSERT(IDM_ABOUTBOX &lt; 0xF000);<br><br>　CMenu* pSysMenu = GetSystemMenu(FALSE);<br>　if (pSysMenu != NULL)<br>　{<br>　　CString strAboutMenu;<br>　　strAboutMenu.LoadString(IDS_ABOUTBOX);<br>　　if (!strAboutMenu.IsEmpty())<br>　　{<br>　　　pSysMenu-&gt;AppendMenu(MF_SEPARATOR);<br>　　　pSysMenu-&gt;AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);<br>　　}<br>　}<br><br>　// Set the icon for this dialog. The framework does this automatically<br>　// when the application's main window is not a dialog<br>　SetIcon(m_hIcon, TRUE); // Set big icon<br>　SetIcon(m_hIcon, FALSE); // Set small icon<br><br>　// TODO: Add extra initialization here<br>　//启动串口监视线程<br>　DWORD threadID;<br>　hCommThread = ::CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0,<br>　　　　　(LPTHREAD_START_ROUTINE)SerialPort1ThreadProcess, <br>　AfxGetMainWnd()-&gt;m_hWnd, 0, &amp;threadID);<br>　if (hCommThread == NULL)<br>　{<br>　　::AfxMessageBox("创建串口1处理线程失败");<br>　　::PostQuitMessage(0);<br>　}<br>　return TRUE; // return TRUE unless you set the focus to a control<br>}<br><br>//"清除"按钮函数<br>void CSerialPortAPIDlg::OnClearButton() <br>{<br>　// TODO: Add your control notification handler code here<br>　m_send = "";<br>　UpdateData(false);<br>}<br><br>//发送数据函数（"发送"按钮函数）<br>void CSerialPortAPIDlg::OnSendButton() <br>{<br>　// TODO: Add your control notification handler code here<br>　UpdateData(true);<br>　DWORD wCount = 0;<br>　WriteFile(hCom, m_send, m_send.GetLength(), &amp;wCount, NULL);//发送数据<br>}<br><br>//接收数据后（通过监听线程发来的用户自定义消息）显示<br>void CSerialPortAPIDlg::OnRecvData(WPARAM wParam, LPARAM lParam)<br>{<br>　CString recvStr((char *)wParam);<br>　m_recv += recvStr;<br>　UpdateData(false);<br>}</td>
        </tr>
    </tbody>
</table>
<br><br>　　在工程中添加SerialPortControl.h和SerialPortControl.cpp两个文件，前者声明串口控制的接口函数及外部全局变量，后者实现串口接口函数及串口监听线程控制函数。<br><br>　　SerialPortControl.h文件<br><br>
<table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%">
    <tbody>
        <tr>
            <td>#ifndef _SERIAL_PORT_CONTROL_H<br>#define _SERIAL_PORT_CONTROL_H<br><br>#define COM_RECVDATA WM_USER+1000//自定义消息<br><br>extern HANDLE hCom; //全局变量，串口句柄<br>extern HANDLE hCommThread; //全局变量，串口线程<br>//串口监视线程控制函数<br>extern DWORD WINAPI SerialPort1ThreadProcess(HWND hWnd);<br>//打开并设置PC串口1(COM1)<br>extern BOOL OpenSerialPort1();<br><br>#endif<br>SerialPortControl.cpp文件<br>#include "StdAfx.h"<br>#include "SerialPortControl.h"<br><br>HANDLE hCom; //全局变量，串口句柄<br>HANDLE hCommThread; //全局变量，串口线程<br><br>BOOL OpenSerialPort1()<br>{<br>　//打开并设置COM1<br>　hCom=CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0,NULL , OPEN_EXISTING, 0, NULL);<br>　if (hCom==(HANDLE)-1)<br>　{<br>　　AfxMessageBox("打开COM1失败");<br>　　return false;<br>　}<br>　else<br>　{<br>　　DCB wdcb;<br>　　GetCommState (hCom, &amp;wdcb);<br>　　wdcb.BaudRate=9600;//波特率：9600，其他：不变<br>　　SetCommState (hCom, &amp;wdcb);<br>　　PurgeComm(hCom, PURGE_TXCLEAR);<br>　}<br>　return true;<br>}<br><br>//以一个线程不同监控串口行接收的数据<br>DWORD WINAPI SerialPort1ThreadProcess( HWND hWnd//主窗口句柄)<br>{<br>　char str[101];<br>　DWORD wCount; //读取的字节数<br>　while(1)<br>　{<br>　　ReadFile(hCom,str, 100, &amp;wCount, NULL);<br>　　if(wCount &gt; 0) //收到数据<br>　　{<br>　　　str[wCount] = '\0';<br>　　　::PostMessage(hWnd, COM_RECVDATA, (unsigned int) str, wCount); <br>　　　//发送消息给对话框主窗口，以进行接收内容的显示<br>　　}<br>　}<br>　return TRUE;<br>}</td>
        </tr>
    </tbody>
</table>
<br><br>　　为了验证程序的正确性，我们使用串口调试助手与本程序协同工作，互相进行收发。下面的抓图显示本程序工作正确，发送和接收字符准确无误。<br><br>
<table align="center" border="0" width="90%">
    <tbody>
        <tr>
            <td>
            <div align="center"><img  src="http://dev.yesky.com/imagelist/06/02/s9deyfu7kes6.jpg" border="0"><br></div>
            </td>
        </tr>
    </tbody>
</table>
<br>　　<a  href="http://www.mydown.com/code/253/253502.html" target="_blank"><font color="#3809f7">单击此处下载本工程源代码</font></a>。<br><br><img src ="http://www.cppblog.com/jianxin0558/aggbug/69208.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jianxin0558/" target="_blank">李建新</a> 2008-12-11 19:49 <a href="http://www.cppblog.com/jianxin0558/archive/2008/12/11/69208.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC常用知识</title><link>http://www.cppblog.com/jianxin0558/archive/2008/12/05/68632.html</link><dc:creator>李建新</dc:creator><author>李建新</author><pubDate>Fri, 05 Dec 2008 03:21:00 GMT</pubDate><guid>http://www.cppblog.com/jianxin0558/archive/2008/12/05/68632.html</guid><wfw:comment>http://www.cppblog.com/jianxin0558/comments/68632.html</wfw:comment><comments>http://www.cppblog.com/jianxin0558/archive/2008/12/05/68632.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jianxin0558/comments/commentRss/68632.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jianxin0558/services/trackbacks/68632.html</trackback:ping><description><![CDATA[　　1: 得到系统时间日期(使用GetLocalTime)<br><br>
<table rules="none" width="500" align="center" bgcolor="#ddedfb" border="1" bordercolor="#55aaff" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td width="10"><br></td>
            <td>
            <p>　　CString sTime,sYear,sMonth,sDay;<br>　　SYSTEMTIME CurTime;<br>　　GetLocalTime(&amp;CurTime);<br>　　sYear.Format("%d年",CurTime.wYear);<br>　　sMonth.Format("%d月",CurTime.wMonth);<br>　　sDay.Format("%d日",CurTime.wDay);<br>　　sTime =&nbsp; sYear+ sMonth + sDay;<br>　　// CurTime.wHour<br>　　// CurTime.wMinute<br>　　// CurTime.wSecond IBM的<br>　　AfxMessageBox(sTime);</p>
            </td>
        </tr>
    </tbody>
</table>
<br>　　2: 分离字串 <br><br>
<table rules="none" width="500" align="center" bgcolor="#ddedfb" border="1" bordercolor="#55aaff" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td width="10"><br></td>
            <td>
            <p>　　CString str = "4d3f0a2278";<br>　　unsigned char a[12];<br>　　long x;<br>　　for(int i = 0;i&lt; (str.GetLength()/2);i++)<br>　　{<br>　　sscanf(str.Mid(2*i,2),"%x",&amp;x);<br>　　a[i] = x;<br>　　}</p>
            </td>
        </tr>
    </tbody>
</table>
<p>　　3: 得到当前目录 (GetCurrentDirectory)<br><br>
<table rules="none" width="500" align="center" bgcolor="#ddedfb" border="1" bordercolor="#55aaff" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td width="10"><br></td>
            <td>
            <p>　　char&nbsp; CurPath[MAX_PATH];<br>　　DWORD size=MAX_PATH;<br>　　GetCurrentDirectory(size,CurPath);<br>　　AfxMessageBox(CurPath);<br>　　<br>　　//<br>　　CString number;<br>　　int len = LineLength(LineIndex(0));<br>　　LPTSTR p=number.GetBuffer(len);<br>　　this-&gt;GetLine(0,p,len);<br>　　AfxMessageBox(number);<br>　　得到系统目录 (GetSystemDirectory)</p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>　　4: 从字符串中提取数字<br><br>
<table rules="none" width="500" align="center" bgcolor="#ddedfb" border="1" bordercolor="#55aaff" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td width="10"><br></td>
            <td>
            <p>　　CString strNum;<br>　　CString str("测试125各国87kk");<br>　　strNum = GetStr(str);<br>　　AfxMessageBox(strNum);</p>
            </td>
        </tr>
    </tbody>
</table>
<br>　　<br>　　5: 创建无模对话框<br><br>
<table rules="none" width="500" align="center" bgcolor="#ddedfb" border="1" bordercolor="#55aaff" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td width="10"><br></td>
            <td>
            <p>　　CDlg_Test *aa = new CDlg_Test;<br>　　aa-&gt;Create(IDD_DIALOG1,NULL);<br>　　aa-&gt;ShowWindow(SW_SHOW);</p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>　　6: 得到窗口绝对坐标</p>
<p>
<table rules="none" width="500" align="center" bgcolor="#ddedfb" border="1" bordercolor="#55aaff" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td width="10"><br></td>
            <td>
            <p>　　CString strNum,strNum1;<br>　　CRect rect;<br>　　GetClientRect(&amp;rect);<br>　　ClientToScreen(&amp;rect);<br>　　strNum.Format("X: %d",rect.top);<br>　　strNum1.Format("&nbsp;&nbsp; Y: %d",rect.left);<br>　　strNum = strNum + strNum1;<br>　　AfxMessageBox(strNum);</p>
            </td>
        </tr>
    </tbody>
</table>
<br>　　<br>　　7: 复制文件夹<br><br>
<table rules="none" width="500" align="center" bgcolor="#ddedfb" border="1" bordercolor="#55aaff" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td width="10"><br></td>
            <td>
            <p>　　SHFILEOPSTRUCT&nbsp; Op;<br>　　<br>　　char FromBuf[]="E:\\temp\0";<br>　　char ToBuf[]="<a>\\\\SINTEKSERVER\\</a>个人文档\\陈 伟\0";;<br>　　<br>　　Op.hwnd = NULL;<br>　　Op.wFunc = FO_COPY;<br>　　Op.pFrom = FromBuf; <br>　　Op.pTo = ToBuf; <br>　　Op.fFlags = FOF_NOCONFIRMATION | FOF_RENAMEONCOLLISION ; <br>　　Op.fAnyOperationsAborted = FALSE; <br>　　Op.hNameMappings = NULL; <br>　　Op.lpszProgressTitle = NULL;<br>　　<br>　　if(SHFileOperation(&amp;Op) == 0)<br>　　MessageBox("复制完毕","提示",MB_OK|MB_ICONINFORMATION);</p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>　　8: 捕获 Ctrl＋鼠标左键 组合<br><br>
<table rules="none" width="500" align="center" bgcolor="#ddedfb" border="1" bordercolor="#55aaff" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td width="10"><br></td>
            <td>
            <p>　　case WM_LBUTTONDOWN://鼠标消息wParam == <br>　　if (wParam &amp; MK_CONTROL)<br>　　MessageBox(hwnd,"aaa","bbb",MB_OK);<br>　　break;<br>　　或<br>　　case WM_LBUTTONDOWN:<br>　　if(GetKeyState(VK_CONTROL)&lt;0)<br>　　MessageBox(hwnd,"aaa","bbb",MB_OK);<br>　　break;</p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><br></p><img src ="http://www.cppblog.com/jianxin0558/aggbug/68632.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jianxin0558/" target="_blank">李建新</a> 2008-12-05 11:21 <a href="http://www.cppblog.com/jianxin0558/archive/2008/12/05/68632.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>