怎么检测串口 的 DSR 引脚或 DTR 的电平变化

如何检测串口 的 DSR 引脚或 DTR 的电平变化?
我是这么理解的:

 SetCommMask 设置一个串口事件
 GetCommMask 来获取一个事件的发生



SetCommMask(hCom, EV_DSR);
GetCommMask(hCom, &dwEvtMask);
if(dwEvtMask & EV_DSR) 
{
     // DSR 电平发生了跳变!
}


但是这样是不行的

请问:如何 知道 DSR 或 DTR 的电平跳变了,求给点代码提示,谢谢了!
串口 C/C++

------解决方案--------------------
SetCommMask(hCom, EV_DSR);
GetCommMask(hCom, &dwEvtMask);
if(dwEvtMask & EV_DSR) 
{
     // DSR 电平发生了跳变!
}

WaitCommEvent(hCom, &dwEvtMask, &OverLapped);  执行一次就不执行了,DTR远还没有出线就挂了,

太简单了,必须弄一个阻塞线程来等待这个信号量,接受消息就必须在窗口下面,所有的消息都是发往窗口的,在窗口下拦截这个消息,这个就不会占CPU, 0% 因为windows太快了,

如果你用单片机的方式
while(1)
{
    WaitCommEvent(hCom, &dwEvtMask, &OverLapped);  也可以,那windows啥也不干就等信号量
}
------解决方案--------------------
98年老外VC下有个CSerialPort类封装,很好的解决这个问题,具体看《串口通讯XX》,VC下将该类加到你的窗口,两三句就解决问题了,我试过,用该类,开10个串口57600高速读写,CPU占用率最多2%,用了N年很稳定,,不要考虑自己弄了,有现在很好用
------解决方案--------------------
专门一个线程:

// an work thread to monitor the _CTS and RX_CHAR 
UINT CUload::CommWatchRead(LPVOID lpParam)
{   // return 0=OK 1=Error
    CUload     *pUload=(CUload*)lpParam;
OVERLAPPED os;
DWORD dwEventMask,dwTransfer;

memset(&os,0,sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);// attrb,Manual,init,name
if (os.hEvent==NULL)
{
AfxMessageBox("Can't create Event",MB_ICONSTOP);
return 1;// error
}
// set 2 events !
    if (!SetCommMask(pUload->m_idComDev,EV_RXCHAR
------解决方案--------------------
EV_CTS)) return 1;
    while (pUload->m_bConnected)
{ // break,only if m_bConnected=NULL 
dwEventMask=0;
        if(!WaitCommEvent(pUload->m_idComDev,&dwEventMask,&os))
{ // function fails
if (GetLastError()==ERROR_IO_PENDING)
{// TRUE=WaitForSingleObject() should be called inside
                GetOverlappedResult(pUload->m_idComDev,&os,&dwTransfer,TRUE);
os.Offset+=dwTransfer;
}
}
if((dwEventMask & EV_RXCHAR)==EV_RXCHAR)
{ // some chats received.
             ResetEvent(pUload->m_hPostEventRead);// first reset 
             pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)1,   // EV_RXCHAR
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
// if not at same time,use else if
if((dwEventMask & EV_CTS)==EV_CTS)
{  // CTS changed
ResetEvent(pUload->m_hPostEventRead);// first reset 
            pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)0,   // EV_CTS
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
}
CloseHandle(os.hEvent);
return 0;// OK
}