如果是从串口提取数据的话,我有一个类可以访问串口。
是我改进的,有些属性设置还没有做。已经测试通过,支持事件(WM_SERIAL_RECEIVE)。
用的时候需要定义一个外部的hInstance.我把它公布出来,请大家不吝指正。
//serial.h文件
#ifndef __SERIAL_H
#define __SERIAL_H
#include <vcl.h>
#pragma hdrstop
#define WM_SERIAL_RECEIVE (WM_APP + 400)
extern HINSTANCE hInstance;
class CSerialCtr
{
private:
HWND Handle;//窗口句柄;
public:
typedef enum
{
EEventNone = -1, // Event trigged without cause
EEventBreak = EV_BREAK, // A break was detected on input
EEventCTS = EV_CTS, // The CTS signal changed state
EEventDSR = EV_DSR, // The DSR signal changed state
EEventError = EV_ERR, // A line-status error occurred
EEventRing = EV_RING, // A ring indicator was detected
EEventRLSD = EV_RLSD, // The RLSD signal changed state
EEventRecv = EV_RXCHAR, // Data is received on input
EEventRcvEv = EV_RXFLAG, // Event character was received on input
EEventSend = EV_TXEMPTY, // Last character on output was sent
}
EEvent;
// Port availability
typedef enum
{
EPortUnknownError = -1, // Unknown error occurred
EPortAvailable = 0, // Port is available
EPortNotAvailable = 1, // Port is not present
EPortInUse = 2 // Port is in use
CSerialCtr::EPort CSerialCtr::CheckPort (LPCTSTR lpszDevice)
{
// Try to open the device
HANDLE hFile = ::CreateFile(lpszDevice,
GENERIC_READ|GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
// Check if we could open the device
if (hFile == INVALID_HANDLE_VALUE)
{
// Display error
switch (::GetLastError())
{
case ERROR_FILE_NOT_FOUND:
// The specified COM-port does not exist
return EPortNotAvailable;
case ERROR_ACCESS_DENIED:
// The specified COM-port is in use
return EPortInUse;
default:
// Something else is wrong
return EPortUnknownError;
}
}
// Close handle
::CloseHandle(hFile);
// Port is available
return EPortAvailable;
}
LONG CSerialCtr::Open (LPCTSTR lpszDevice, DWORD dwInQueue, DWORD dwOutQueue)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the port isn't already opened
if (m_hFile)
{
m_lLastError = ERROR_ALREADY_INITIALIZED;
return m_lLastError;
}
// Open the device
m_hFile = ::CreateFile(lpszDevice,
GENERIC_READ|GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (m_hFile == INVALID_HANDLE_VALUE)
{
// Reset file handle
m_hFile = 0;
// Create the event handle for internal overlapped operations (manual reset)
m_hevtOverlapped = ::CreateEvent(0,true,false,0);
if (m_hevtOverlapped == 0)
{
// Obtain the error information
m_lLastError = ::GetLastError();
// Close the port
::CloseHandle(m_hFile);
m_hFile = 0;
// Return the error
return m_lLastError;
}
// Setup the COM-port
if (!::SetupComm(m_hFile,dwInQueue,dwOutQueue))
{
// Display a warning
long lLastError = ::GetLastError();
// Close the port
Close();
// Save last error from SetupComm
m_lLastError = lLastError;
return m_lLastError;
}
// Setup the default communication mask
SetMask();
// Setup the device for default settings
Setup();
// Non-blocking reads is default
SetupReadTimeouts(EReadTimeoutNonblocking);
// Default is no handshaking
SetupHandshaking(EHandshakeOff);
///////////////////////////// Set Timer For Receiving ////////////////////
SetTimer(Handle,0,1000, NULL);
// Return successful
return m_lLastError;
}
LONG CSerialCtr::Close (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// If the device is already closed,
// then we don't need to do anything.
if (m_hFile == 0)
{
return m_lLastError;
}