본문 바로가기

Language & API/WIN API

WaitCommEvent 함수

Waits for an event to occur for a specified communications device. 

The set of events that are monitored by this function is contained in the event mask associated with the device handle. 

지정된 통신 장치에서 발생하는 이벤트를 기다린다.

지정된 이벤트는 디바이스 핸들과 연관된 이벤트 마스크를 포함하며 함수에 의해 모니터된다.

 

Syntax

C++


1
2
3
4
5
BOOL WINAPI WaitCommEvent(
  _In_  HANDLE       hFile, // CreateFile HANDLE
  _Out_ LPDWORD      lpEvtMask,   // 수신 Mask 이벤트
  _In_  LPOVERLAPPED lpOverlapped  // OVERLAPPED Struct  포인터
);
cs

 

Parameters

hFile [in]

A handle to the communications device. The CreateFile function returns this handle.

CreateFile 핸들

lpEvtMask [out]

A pointer to a variable that receives a mask indicating the type of event that occurred. If an error occurs, the value is zero; otherwise, it is one of the following values.

발생한 이벤트 유형을 나타내는 마스크를 받는 변수에 대한 포인터. 오류가 발생하면 값은 0입니다.

그렇지 않으면 다음 하나입니다


Value

Meaning

EV_BREAK

0x0040

A break was detected on input.

입력시 끊어짐이 감지 되었습니다.

EV_CTS

0x0008

The CTS (clear-to-send) signal changed state.

CTS 시그널에 변화가 있습니다.

EV_DSR

0x0010

The DSR (data-set-ready) signal changed state.

DST 시그널에 변화가 있습니다.

EV_ERR

0x0080

A line-status error occurred. Line-status errors are CE_FRAMECE_OVERRUN, and CE_RXPARITY.

회선 상태 오류가 발생했습니다. 회선 상태 오류는 CE_FRAME, CE_OVERRUN CE_RXPARITY입니다.

EV_RING

0x0100

A ring indicator was detected.

링 표시기가 감지되었습니다.

EV_RLSD

0x0020

The RLSD (receive-line-signal-detect) signal changed state.

RLSD 스그널에 변화가 있습니다.

EV_RXCHAR

0x0001

A character was received and placed in the input buffer.

문자가 수신되어 입력 버퍼에 저장되었습니다.

EV_RXFLAG

0x0002

The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.

이벤트 문자를 수신하여 입력 버퍼에 넣습니다. 이벤트 문자는 DCB 구조체에 서술되며

SetCommState 함수를 사용하여 시리얼 포트에 적용됩니다.

EV_TXEMPTY

0x0004

The last character in the output buffer was sent.

출력 버퍼의 마지막 문자가 전송되었습니다.


lpOverlapped [in]

A pointer to an OVERLAPPED structure. This structure is required if hFile was opened with FILE_FLAG_OVERLAPPED.

If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the operation is complete.

If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULLWaitCommEvent is performed as an overlapped operation. In this case, the OVERLAPPED structure must contain a handle to a manual-reset event object (created by using the CreateEvent function).

If hFile was not opened with FILE_FLAG_OVERLAPPEDWaitCommEvent does not return until one of the specified events or an error occurs.

 

Overlapped 구조체 포인터입니다. 이구조체는 hFile 생성할때 FILE_FLAG_OVERLAPPED 지정해야합니다. 만약 hFile FILE_FLAG_OVERLAPPED 열었으면 NULL 입력해서는 안됩니다. 유요한 구조체 포인터여야 합니다. 만약 hFile FILE_FLAG_OVERLAPPED 열고 해당 값이 NULL이면 이함수는 완료된 정보를 올바르게 리포트 하지 않습니다. 이경우 구조체는 수동 재설정 이벤트 객체에 대한 핸들이 있어야합니다.(CreateEvent 함수를 사용하여 만들어야 합니다.)

만약 hFile FILE_FLAG_OVERLAPPED 열지 않으면 함수는 서술한 이벤트 또는  오류가 생기기 전까지 리턴하지 않습니다.

 

Return value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

 

성공한 리턴값은 NonZero입니다.

실패면 0으로 반환되고 GetLastError 확인 가능합니다.

 


** 주의 사항

lpEvtMask [out]

해당값은 or연산으로 값이 리턴됩니다.

if ((lpEvtMask & EV_RXCHAR) == EV_RXCHAR)

{

//성공

}

If(lpEvtMask  & EV_ERR) == EV_ERR)

{

//에러 발생

}

아래는 MSDN에 나오는 테스트 소스입니다. 테스트 중 계속 PENDING IO 로 떨어집니다. 이유는 여러개가 있지만 명확하지 않습니다.

3번째 파라미터를 NULL로 하면 원하는 바를 얻지만 위에서도 말했듯이 NULL이면 올바르게 리포트 하지 않을 수도 있다고 합니다. 

하지만 다른 여러 예제를 살펴 보면 NULL로 작성된 소스들도 쉽게 찾아볼 수 있습니다.  

MS사의 MTTTY 예제는 정석대로 코드를 짠듯하나 아직 이 소스를 테스트 해보진 않았습니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa363424(v=vs.85).aspx
 
#include <windows.h>
#include <tchar.h>
#include <assert.h>
#include <stdio.h>
 
void _tmain(int argc, TCHAR *argv[])
{
 
    HANDLE h_com;
    OVERLAPPED ol;
    BOOL fSuccess;
    DWORD dwEvtMask, dwErrorFlags;
    COMSTAT comstat;
 
    h_com = CreateFile(_T("COM2"),
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED,
        NULL
        );
 
    if (h_com == INVALID_HANDLE_VALUE)
    {
        printf("CreateFile failed with error %d.\n", GetLastError());
    }
 
    fSuccess = SetCommMask(h_com, EV_CTS | EV_DSR);
 
    if (!fSuccess)
    {
        printf("SetCommMask failed with error %d.\n", GetLastError());
    }
 
    
    ol.hEvent = CreateEvent(
        NULL,  //default security attributes
        TRUE,  //manual-reset event
        FALSE, //not signaled
        NULL   //no name
        );
    
    ol.Internal = 0;
    ol.InternalHigh = 0;
    ol.Offset = 0;
    ol.OffsetHigh = 0;
 
    assert(ol.hEvent);
 
    if (WaitCommEvent(h_com, &dwEvtMask, &ol))
    {
        if (dwEvtMask & EV_DSR)
        {
            printf("EV_DSR\n");
        }
 
        if (dwEvtMask & EV_CTS)
        {
            printf("EV_CTS\n");
        }
    }
    else
    {
        DWORD dwRet = GetLastError();
        if (ERROR_IO_PENDING == dwRet)
        {
            printf("I/O is pending...\n");
 
            ClearCommError(h_com, &dwErrorFlags, &comstat);
        }
        else
            printf("Wait failed with error %d.\n", GetLastError());
    }
 
    system("Pause");
    
    CloseHandle(ol.hEvent);
    CloseHandle(h_com);
}
cs

 VS2013에서 테스트 해보았습니다.

'Language & API > WIN API' 카테고리의 다른 글

SetCommMask 함수  (0) 2017.04.10