Не прошло и полгода, ага.
kuzulis, читал, спасибо.
Слабал следующее (на Qt):
.h
| Код | #include <windows.h>
enum QParity {pNone, pOdd, pEven, pMark, pSpace}; enum QDataBits {db5 = 5, db6, db7, db8}; enum QStopBits {sb1, sb15, sb2}; enum QFlowControl {fcNone, fcSoftware, fcHardware};
struct QComPortParams { QString portName; unsigned long baudRate; QDataBits dataBits; QStopBits stopBits; QParity parity; QFlowControl flowControl; };
class QComPorts : public QObject { Q_OBJECT
public: QComPorts(); ~QComPorts();
// Достать список всех COM-портов QStringList getComPortsNames(); // Открыть порт bool open(QComPortParams* params); // Закрыть порт bool close(); // Отправить данные void write(QByteArray* sendedData);
private: // Таймер, который читает QTimer* m_pReceiveTime; // Хэндл COM-порта HANDLE m_hComm; // Настройки порта char* m_theDCB; private slots: // Слот на таймер void timerSlot();
signals: // Сигнал на получение void receivePackSignal(QByteArray* sendedData); };
|
.cpp
| Код | QComPorts::QComPorts() { // Таймер, который читает m_pReceiveTime = new QTimer();
connect(m_pReceiveTime, SIGNAL(timeout()), this, SLOT(timerSlot())); }
QComPorts::~QComPorts() { delete m_pReceiveTime; }
// Достать список всех COM-портов QStringList QComPorts::getComPortsNames() { TCHAR szDevices[65535]; DWORD dwChars = QueryDosDevice(NULL, szDevices, 65535);
// Перекинем эту строку в QString QString szDeviceList = ""; QChar chTmp; QStringList strList; QStringList result;
if (dwChars) { int nZeroCnt = 0; int i = 0; for (;;) { // Если текущий символ нулевой, то увеличим к-во нулевых символов if (szDevices[i] == 0) nZeroCnt++; // Иначе обнулим счетчик нулей else nZeroCnt = 0;
// Если более одного нуля подряд, то выходим из цикла if (nZeroCnt > 1) break;
chTmp = szDevices[i]; szDeviceList += chTmp;
i++; } }
// Разобьем эту строку на несколько по символу #0 strList = szDeviceList.split(QChar(0));
// Выберем только COM-порты for (int i = 0; i < strList.size(); i++) { // Если строка начинается с "COM" if ((strList[i].left(3).toUpper() == "COM") && // А оставшийся кусок - это число от 1 до 255 (strList[i].mid(3).toInt() >= 1) && (strList[i].mid(3).toInt() <= 255)) { result.push_back(strList[i]); } }
return result; }
// Открыть порт bool QComPorts::open(QComPortParams* params) { QString szPort; szPort = QString("\\\\.\\") + params->portName;
// Связаться с портом m_hComm = CreateFileA(szPort.toAscii().data(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
// if (m_hComm == INVALID_HANDLE_VALUE) { showMessage("Метод bool QComPorts::open" + QString(10) + "Ошибка в при открытии порта"); return false; }
m_theDCB = new char [sizeof(DCB)];
// Достанем состояние порта if (!GetCommState(m_hComm, LPDCB(m_theDCB))) { showMessage("Метод bool QComPorts::open" + QString(10) + "Ошибка при исполнения GetCommState()"); return false; }
// Устанавливаем параметры соединения LPDCB(m_theDCB)->BaudRate = params->baudRate; LPDCB(m_theDCB)->ByteSize = params->dataBits; LPDCB(m_theDCB)->StopBits = params->stopBits; LPDCB(m_theDCB)->Parity = params->parity;
// FlowControl // Эти всегда одинаковые LPDCB(m_theDCB)->XonChar = 17; LPDCB(m_theDCB)->XoffChar = 19; LPDCB(m_theDCB)->fOutxDsrFlow = false; LPDCB(m_theDCB)->fDtrControl = 0; LPDCB(m_theDCB)->fDsrSensitivity = false; LPDCB(m_theDCB)->fTXContinueOnXoff = false;
// Эти почти не меняются LPDCB(m_theDCB)->fOutxCtsFlow = false; LPDCB(m_theDCB)->fRtsControl = 0; LPDCB(m_theDCB)->fOutX = false; LPDCB(m_theDCB)->fInX = false;
switch (params->flowControl) { case fcNone: break;
case fcHardware: LPDCB(m_theDCB)->fOutxCtsFlow = true; LPDCB(m_theDCB)->fRtsControl = 2; break;
case fcSoftware: LPDCB(m_theDCB)->fOutX = true; LPDCB(m_theDCB)->fInX = true; break; }
// Изменим настройки порта if (!SetCommState(m_hComm, LPDCB(m_theDCB))) { showMessage("Метод bool QComPorts::open" + QString(10) + "Ошибка при исполнения SetCommState()"); return false; }
// Запускаем таймер m_pReceiveTime->setInterval(50); m_pReceiveTime->start();
return true; }
// Закрыть порт bool QComPorts::close() { delete [] m_theDCB; if (CloseHandle ((HANDLE)m_hComm)) { showMessage("Метод bool QComPorts::close" + QString(10) + "Ошибка при закрытии порта"); return false; }
// Останавливаем таймер m_pReceiveTime->stop();
return true; }
// Отправить данные void QComPorts::write(QByteArray* sendedData) { DWORD dwToWrite = sendedData->size();
OVERLAPPED osWrite = {0}; DWORD dwWritten; DWORD dwRes; BOOL fRes; int nLastError;
// Create this write operation's OVERLAPPED structure's hEvent. osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (osWrite.hEvent == NULL) { showMessage("Ошбика создания события"); return; };
// Issue write. if (!WriteFile(m_hComm, sendedData->data(), dwToWrite, &dwWritten, &osWrite)) { nLastError = GetLastError(); if (nLastError != ERROR_IO_PENDING) { // WriteFile failed, but isn't delayed. Report error and abort. fRes = FALSE; } else { // Write is pending. dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);
switch(dwRes) { // OVERLAPPED structure's event has been signaled. case WAIT_OBJECT_0: if (!GetOverlappedResult(m_hComm, &osWrite, &dwWritten, FALSE)) fRes = FALSE; else // Write operation completed successfully. fRes = TRUE; break; default: // An error has occurred in WaitForSingleObject. // This usually indicates a problem with the // OVERLAPPED structure's event handle. fRes = FALSE; break; } } } else // WriteFile completed immediately. fRes = TRUE;
CloseHandle(osWrite.hEvent); }
// Слот на таймер void QComPorts::timerSlot() { _COMSTAT cs; DWORD error; ClearCommError(m_hComm, &error, &cs); QByteArray result;
// Если пришли данные if (cs.cbInQue != 0) { char* lpBuf; lpBuf = (char*)(malloc(cs.cbInQue));
DWORD dwRead; BOOL fWaitingOnRead = FALSE; OVERLAPPED osReader = {0}; bool bReadResult;
osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osReader.hEvent == NULL) { // showMessage("Ошбика создания события"); return; }
bReadResult = ReadFile(m_hComm, lpBuf, cs.cbInQue, &dwRead, &osReader); if (bReadResult) { result.append(lpBuf, cs.cbInQue); }
ClearCommError(m_hComm, &error, &cs);
free(lpBuf); }
if (result.size() > 0) emit receivePackSignal(&result); }
|
|