Hey all. First time user here :)

Im making a Windows XP C++ console application with Code Blocks (GNU GCC Compiler). This program is written to control another program that is missing some features i need (read input from external source). Last thing im missing from my program is little serial port handling. I made a loopback plug to serial port with few on/off switches and its working great. I have tried to look for a code to read the CTS (clear to send) / DSR (data set ready) states from serial port but no avail.

I know winapi has some (Serial Communications in Win32) solutions to these (Communications Event Flags? WaitCommEvent function?) but i cant really understand winapi because im just getting to know C++. Im assuming i need to initialize the serial port first (to get things going) with CreateFile function and after that i could read the event flags from the loopback plug.

Is there a better way to init serial port and read status of dsr/cts signals from loopback plug than winapi event flags? Anyone feeling to share some piece of code to init and check these statuses of serial port? Any help would be appreciated.

Dani AI

Generated

Quick summary and a compact how‑to that fills the gaps in the thread: open the COM port with CreateFile, put the port into a known state (DCB + timeouts), then either poll the modem lines with GetCommModemStatus or wait for changes with SetCommMask + WaitCommEvent (overlapped I/O is recommended so the console/thread doesn’t block). already has a loopback plug; ’s MSDN pointers are useful background, so the examples below focus on practical, runnable patterns and common pitfalls.

A minimal polling pattern (good for a quick test):

#include <windows.h>
#include <iostream>

int main() {
    HANDLE h = CreateFileA("\\\\.\\COM1",
        GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (h == INVALID_HANDLE_VALUE) return 1;

    // optional: assert output lines so loopback lines become active
    EscapeCommFunction(h, SETDTR);
    EscapeCommFunction(h, SETRTS);

    DWORD modemState = 0;
    if (GetCommModemStatus(h, &modemState)) {
        std::cout << "CTS=" << ((modemState & MS_CTS_ON) ? "ON" : "OFF")
                  << "  DSR=" << ((modemState & MS_DSR_ON) ? "ON" : "OFF") << "\n";
    }
    CloseHandle(h);
    return 0;
}

Event-driven pattern (does not block caller thread if using OVERLAPPED):

SetCommMask(h, EV_CTS | EV_DSR);
OVERLAPPED ov = {}; ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DWORD mask = 0;
if (!WaitCommEvent(h, &mask, &ov) && GetLastError() == ERROR_IO_PENDING) {
    WaitForSingleObject(ov.hEvent, INFINITE);
    GetOverlappedResult(h, &ov, &mask, FALSE);
}
if (mask & EV_CTS) { /* CTS changed */ }
if (mask & EV_DSR) { /* DSR changed */ }
CloseHandle(ov.hEvent);

Troubleshooting checklist (common causes): ensure correct DB9 wiring (DTR pin 4 <-> DSR pin 6; RTS pin 7 <-> CTS pin 8; ground pin 5), use the "\\.\COMn" name for COM10+, confirm no other app owns the port, verify the adapter actually exposes hardware lines (many USB‑serial adapters do not), and remember EscapeCommFunction can be used to toggle DTR/RTS if the loopback depends on them. Code::Blocks/MinGW only needs <windows.h>; no extra libraries are normally required.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.