1. 키보드로 입력이 발생되면 윈도우는 WM_CHAR, WM_KEYDOWN 메시지 발생
  입력된 문자의 코드는 WPARAM으로 전달되며 LPARAM에는 비트별로 복잡한 정보가 전달
  필요한 정보가 있으면 LPARAM을 참조하고 필요없으면 WPARAM만 사용하면 된다

2. 무효영역
  InvalidateRect 함수를 호출하여 강제로 WM_PAINT 메시지를 발생할 수 있다.
  BOOL InvalidateRect(HWND hWnd, CONST RECT * lpRect, BOOL bErase);

3. 문자를 입력하고자 할 경우는 WM_CHAR 메시지를 사용하고
  문자 이외의 키는 입력 받을 수 없다. 이럴때는 WM_KEYDOWN 메시지를 사용 한다.

4. 키보드를 입력하게 되면 Getmessage는 메시지 큐에서 메시지를 꺼낸 후 메시지를 TranslateMessage
  함수로 넘긴다. TranslateMessage 함수는 전달된 메시지가 WM_KEYDOWN 인지와 눌러진 키가
  문자키인지 검사해 보고 조건이 맞을 경우 WM_CHAR 메시지를 추가로 발생시킨다.

5. 마우스 입력
  가. 마우스 메시지는 LPARAM의 상위 워드에 마우스 버튼이 눌러진 Y좌표, 하위 워드에 X좌표를 가지며
    좌표값을 검출해 내기 위해 HIWORD, LOWORD 등의 매크로 함수를 사용한다. 즉 마우스 메시지가
    발생한 위치의 좌표는 (LOWORD(LPARAM), HIWORD(LPARAM))이 된다.
    좌표값을 음수가 발생할 수도 있다. 모니터가 2개이상일 시
  나. WPARAM에는 마우스 버튼의 상태와 키보드 조합 키(SHIFT, CTRL)의 상태가 전달된다.
  * 상, 하위 워드 추출, WORD로 부터 상, 하위 바이트 추출, 조립 매크로 들이 존재한다.
    (LOWORD, HIWORD, LOBYTE, HIBYTE <- 추출, MAKEWORD(A,B), MAKELONG(A,B) <- 조립)
  다. 더블클릭
    1) 더블클릭을 사용할시는 더블클릭 메시지를 받고자하면 윈도우 클래스의 스타일에 원한다는
      의사표시를 해야한다.
        WndClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCKS;
    2) 디폴트로 지원하지 않고 플래그를 지정하도록 되어 있는 이유는 더블클릭을 검출하는데는
      그만큼 실행시간의 감소가 요구되며 어떤 프로그램은 더블클릭보다 WM_LBUTTONDOWN을 두 번
      받기를 원할 수도 있기 때문이다. 가령 트리플 클릭을 검출하고 싶은데 더블클릭이 디폴토로 지원
      하게 되면 트리플 클릭이전에 운영체제에 의해 더블클릭이 처리되어 버리기 때문이다.

6. 타이머
  가. 한 번 지정해 놓기만 하면 일정한 시간 간격을 두고 연속적으로 계속 발생한다.
    Uint SetTimer(HWND hWnd, UINT nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc);
    BOOL KillTimer(HWND hWnd, UINT uIDEvent);
  나. LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
    강제로 메시지가 발생한 것처럼 만들어야 할 때 사용
  다. WndProc에서 첫 번째로 처리하는 메시지는 WM_CREATE 메시지이다.
  라. 두 개의 타이머
    SetTimer 함수의 두번째 인수로 지정한 값(타이머 ID)를 다르게 줌으로 가능하며
    (타이머 ID가 다른 2개의 타이머 함수 호출) 어떤 타이머로 부터 메시지가 발생하면
    WPARAM으로 타이머 ID가 전달된다.
  마. 콜백함수
    1) SetTimer의 네 번째 인수는 타이머 프로시저 함수의 포인터를 가리킨다. NULL일시는 첫 번째 인수로
      지정된 hWnd로 WM_TIMER 메시지가 전달되지만 이 인수에 타이머 함수가 지정되었을 경우는
      매 시간마다 이 함수가 대신 호출된다.
      VOID CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime);
    2) 콜백함수를 사용하는 것과 WM_TIMER 메시지를 받는 것은 사실상 거의 동일한 기법이라고
      할 수 있으며 상황에 따라 편리한 방법을 사용하면 된다. 차이점이라면 WM_TIMER 메시지는 다른
      메시지가 있을 경우 실행 순서에 밀려 늦게 호출되는 경우가 있지만 콜백함수를 사용하면
      정확한 시간에 호출된다는 점이다.; 그래서 정확도를 요하는 작업은 타이머 메시지보다는 콜백함수를
      사용하는 것이 더 좋다고 되어 있다.
  바. 일회용 타이머
    타이머를 원하는 곳에 SetTimer함수를 사용한뒤 WM_TIMER 부분에 KillTimer을 호출하면 됨

7. 윈도우 관리 메시지
  가. 작업영역의 좌표를 조사 BOOL GetClientRect(HWND hWnd, LPRECT lpRect);
  나. 윈도우의 크기가 변경될 때마다 윈도우로 부터 WM_SIZE 메시지가 전달됨
    LPARAM의 하위워드는 변경된 후의 윈도우 폭이 상위 워드에는 높이가 전달되며
    WPARAM에는 이 메시지가 발생한 이유를 나타내는 플래그가 전달됨
  다. 윈도우의 위치가 변경될 때마다 WM_MOVE 메시지가 발생됨
    LPARAM의 하위워드는 새로운 X좌표, 상위워드는 새로운 Y좌표

#include <Windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass = TEXT("Class");

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdparam, int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst = hInstance;
 
 WndClass.cbClsExtra = 0;
 WndClass.cbWndExtra = 0;
 WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
 WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 WndClass.hInstance = hInstance;
 WndClass.lpfnWndProc = WndProc;
 WndClass.lpszClassName = lpszClass;
 WndClass.lpszMenuName = NULL;
 WndClass.style = CS_HREDRAW|CS_VREDRAW;
 RegisterClass(&WndClass);
 
 hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  NULL, (HMENU)NULL, hInstance, NULL);
 ShowWindow(hWnd, nCmdShow);
 
 while( GetMessage(&Message, NULL, 0, 0) )
 {
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 
 return (int)Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;

 switch( iMessage )
 {
 case WM_CREATE:
  {
   hWndMain = hWnd;

   return 0;
  }
 case WM_PAINT:
  {
   hdc = BeginPaint(hWnd, &ps);
   EndPaint(hWnd, &ps);

   return 0;
  }
 case WM_DESTROY:
  {
   PostQuitMessage(0);
   
   return 0;
  }
 }
 
 return (DefWindowProc(hWnd, iMessage, wParam, lParam));
}

유니코드는 16비트의 단일한 값으로 지구상의 모든 문자를 표현할 수 있는 문자 코드 체계

C 타입           |        유니코드 타입
---------------------------------
char              |        TCHAR
char *            |        LPSTR
const char *   |        LPCTSRT

TCHAR는 C의 기본 타입 중 하나인 char과 일단 같지만 유니코드로 컴파일할 때는 wchar_t타입이 됨
wchar_t는 실제로 unsigned short로 정의되어 있으며 부호없는 16비트 정수형

TCHAR 타입의 실제 정의문은 다음과 같이 조건부 컴파일문으로 작성되어 있다.
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif

문자가 필요할시는 TCHAR로 문자열이 필요할 때는 LPSTR 또는 TCHAR *를 쓰는 것이 현명함

문자열처리 함수들도 C의 표준 함수를 쓰지 말고 가급적 유니코드를 인식하는 함수를 사용할 것

C 표준함수          |            유니코드 지원 함수
------------------------------------------
strlen                  |            lstrlen
strcpy                 |            lstrcpy
strcat                  |            lstrcat
strcmp                 |           lstrcmp
sprintf                  |           wsprintf

문자열 상수도 타입이 있으므로 겹 따옴표안에 바로 문자열 상수를 쓰지 말고
TEXT 매크로로 둘러싸는 것이 좋다.
TEXT 매크로는 유니코드 설정에 따라 문자열 상수의 타입을 변경한다.

cb           Count of Bytes          바이트 수
dw          double word             부호없는 long형 정수
h             handle                     윈도우, 비트맵, 파일 등의 핸들
sz           NullTerminated          Null 종료 문자열
ch          Characte                  문자형
a            Array                       배열
w           Word                        부호없는 정수형
i             integer                     정수형
p, lp       long pointer               포인터형
b            Boole                      논리형



BYTE             unsigned char
CHAR            char
WORD            unsigned short
DWORD          unsigned long
LONG            long
BOOL            int

1. DC란 출력에 필요한 모든 정보를 가지는 데이터 구조체이며 GDI 모듈에 의해 관리된다.
  문자열을 지정하는 폰트, 선의 색상과 굵기, 채움 무늬와 색상, 그리기 모드 등등이
  모두 출력에 필요한 정보들이다.

2. Uncover시 OS는 프로그램에게 WM_PAINT 메시지를 전송하므로
  모든 그래픽 출력은 WM_PAINT 메시지에서 처리해야만 한다

3. DC를 얻는 방법
  가. 일반적으로 DC를 얻는 방법
    HDC GetDC(HWND hWnd);
    int ReleaseDC(HWND hWnd, HDC hdc);
  나. WM_PAINT 메시지 처리루틴에서 사용할 수 있는 방법
    PAINTSTRUCT ps;
    HDC BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
    BOOL EndPaint(HWND hWnd, CONST PAINTSTRUCT *lpPaint);
    PAINTSTRUCT 구조체에는 그리기 속도를 비약적으로 향상시킬 수 있는 정보들이 들어 있다

4. 문자열의 출력
  가. BOOL TextOut(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString);
  나. UINT SetTextAlign(HDC hdc, UINT fMode);
  다. int DrawText(HDC hdc, LPCTSTR lpString, int nCount, LPRECT lpRect, UINT uFormat);

5. 여러 가지 출력
  가. COLORREF SetPixel(hdc, nXPos, nYpos, clrref);
  나. DWORD MoveToEx(hdc, x, y, lpPoint);
  다. BOOL LineTo(hdc, xEnd, yEnd);
  라. BOOL Rectangle(hdc, nLeftRect, nTopRectm nRightRect, nBottomRect);
  마. BOOL Ellipse(hdc, nLeftRect, nTopRect, nRightRect, nBootmRect);

6. 메시지 박스
  가. int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCation, UINT uType);

7. 메시지 비프
  가. BOOL MessageBeep(UINT uType);

// Serial.h - Definition of the CSerial class
//
// Copyright (C) 1999-2003 Ramon de Klein (Ramon.de.Klein@ict.nl)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


#ifndef __SERIAL_H
#define __SERIAL_H


//////////////////////////////////////////////////////////////////////
// The SERIAL_DEFAULT_OVERLAPPED defines if the default open mode uses
// overlapped I/O. When overlapped I/O is available (normal Win32
// platforms) it uses overlapped I/O. Windows CE doesn't allow the use
// of overlapped I/O, so it is disabled there by default.

#ifndef SERIAL_DEFAULT_OVERLAPPED
#ifndef SERIAL_NO_OVERLAPPED
#define SERIAL_DEFAULT_OVERLAPPED true
#else
#define SERIAL_DEFAULT_OVERLAPPED false
#endif
#endif


//////////////////////////////////////////////////////////////////////
//
// CSerial - Win32 wrapper for serial communications
//
// Serial communication often causes a lot of problems. This class
// tries to supply an easy to use interface to deal with serial
// devices.
//
// The class is actually pretty ease to use. You only need to open
// the COM-port, where you need to specify the basic serial
// communication parameters. You can also choose to setup handshaking
// and read timeout behaviour.
//
// The following serial classes are available:
//
// CSerial      - Serial communication support.
// CSerialEx    - Serial communication with listener thread for events
// CSerialSync  - Serial communication with synchronized event handler
// CSerialWnd   - Asynchronous serial support, which uses the Win32
//                message queue for event notification.
// CSerialMFC   - Preferred class to use in MFC-based GUI windows.
//
//
// Pros:
// -----
// - Easy to use (hides a lot of nasty Win32 stuff)
// - Fully ANSI and Unicode aware
//
// Cons:
// -----
//  - Little less flexibility then native Win32 API, however you can
//    use this API at the same time for features which are missing
//    from this class.
//  - Incompatible with Windows 95 or Windows NT v3.51 (or earlier),
//    because CancelIo isn't support on these platforms. Define the
//   SERIAL_NO_CANCELIO macro for support of these platforms as
//   well. When this macro is defined, then only time-out values of
//   0 or INFINITE are valid.
//
//
// Copyright (C) 1999-2003 Ramon de Klein
//                         (Ramon.de.Klein@ict.nl)

class CSerial
{
// Class enumerations
public:
// Communication event
typedef enum
{
 EEventUnknown      = -1,   // Unknown event
 EEventNone      = 0,    // 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
 EEventPrinterError = EV_PERR,  // Printer error occured
 EEventRx80Full    = EV_RX80FULL, // Receive buffer is 80 percent full
 EEventProviderEvt1 = EV_EVENT1,  // Provider specific event 1
 EEventProviderEvt2 = EV_EVENT2,  // Provider specific event 2
}
EEvent;

// Baudrate
typedef enum
{
 EBaudUnknown = -1,   // Unknown
 EBaud110     = CBR_110,  // 110 bits/sec
 EBaud300     = CBR_300,  // 300 bits/sec
 EBaud600     = CBR_600,  // 600 bits/sec
 EBaud1200    = CBR_1200, // 1200 bits/sec
 EBaud2400    = CBR_2400, // 2400 bits/sec
 EBaud4800    = CBR_4800, // 4800 bits/sec
 EBaud9600    = CBR_9600, // 9600 bits/sec
 EBaud14400   = CBR_14400, // 14400 bits/sec
 EBaud19200   = CBR_19200, // 19200 bits/sec (default)
 EBaud38400   = CBR_38400, // 38400 bits/sec
 EBaud56000   = CBR_56000, // 56000 bits/sec
 EBaud57600   = CBR_57600, // 57600 bits/sec
 EBaud115200  = CBR_115200, // 115200 bits/sec
 EBaud128000  = CBR_128000, // 128000 bits/sec
 EBaud256000  = CBR_256000, // 256000 bits/sec
}
EBaudrate;

// Data bits (5-8)
typedef enum
{
 EDataUnknown = -1,   // Unknown
 EData5       =  5,   // 5 bits per byte
 EData6       =  6,   // 6 bits per byte
 EData7       =  7,   // 7 bits per byte
 EData8       =  8   // 8 bits per byte (default)
}
EDataBits;

// Parity scheme
typedef enum
{
 EParUnknown = -1,   // Unknown
 EParNone    = NOPARITY,  // No parity (default)
 EParOdd     = ODDPARITY, // Odd parity
 EParEven    = EVENPARITY, // Even parity
 EParMark    = MARKPARITY, // Mark parity
 EParSpace   = SPACEPARITY // Space parity
}
EParity;

// Stop bits
typedef enum
{
 EStopUnknown = -1,   // Unknown
 EStop1       = ONESTOPBIT, // 1 stopbit (default)
 EStop1_5     = ONE5STOPBITS,// 1.5 stopbit
 EStop2       = TWOSTOPBITS // 2 stopbits
}
EStopBits;

// Handshaking
typedef enum
{
 EHandshakeUnknown  = -1, // Unknown
 EHandshakeOff   =  0, // No handshaking
 EHandshakeHardware  =  1, // Hardware handshaking (RTS/CTS)
 EHandshakeSoftware  =  2 // Software handshaking (XON/XOFF)
}
EHandshake;

// Timeout settings
typedef enum
{
 EReadTimeoutUnknown  = -1, // Unknown
 EReadTimeoutNonblocking =  0, // Always return immediately
 EReadTimeoutBlocking =  1 // Block until everything is retrieved
}
EReadTimeout;

// Communication errors
typedef enum
{
 EErrorUnknown = 0,   // Unknown
 EErrorBreak   = CE_BREAK, // Break condition detected
 EErrorFrame   = CE_FRAME, // Framing error
 EErrorIOE     = CE_IOE,  // I/O device error
 EErrorMode    = CE_MODE, // Unsupported mode
 EErrorOverrun = CE_OVERRUN, // Character buffer overrun, next byte is lost
 EErrorRxOver  = CE_RXOVER, // Input buffer overflow, byte lost
 EErrorParity  = CE_RXPARITY,// Input parity error
 EErrorTxFull  = CE_TXFULL // Output buffer full
}
EError;

// 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

}
EPort;

// Construction
public:
CSerial();
virtual ~CSerial();

// Operations
public:
// Check if particular COM-port is available (static method).
static EPort CheckPort (LPCTSTR lpszDevice);

// Open the serial communications for a particular COM port. You
// need to use the full devicename (i.e. "COM1") to open the port.
// It's possible to specify the size of the input/output queues.
virtual LONG Open (LPCTSTR lpszDevice, DWORD dwInQueue = 0, DWORD dwOutQueue = 0, bool fOverlapped = SERIAL_DEFAULT_OVERLAPPED);

// Close the serial port.
virtual LONG Close (void);

// Setup the communication settings such as baudrate, databits,
// parity and stopbits. The default settings are applied when the
// device has been opened. Call this function if these settings do
// not apply for your application. If you prefer to use integers
// instead of the enumerated types then just cast the integer to
// the required type. So the following two initializations are
// equivalent:
//
//   Setup(EBaud9600,EData8,EParNone,EStop1)
//
// or
//
//   Setup(EBaudrate(9600),EDataBits(8),EParity(NOPARITY),EStopBits(ONESTOPBIT))
//
// In the latter case, the types are not validated. So make sure
// that you specify the appropriate values.
virtual LONG Setup (EBaudrate eBaudrate = EBaud9600,
     EDataBits eDataBits = EData8,
     EParity   eParity   = EParNone,
     EStopBits eStopBits = EStop1);

// Set/clear the event character. When this byte is being received
// on the serial port then the EEventRcvEv event is signalled,
// when the mask has been set appropriately. If the fAdjustMask flag
// has been set, then the event mask is automatically adjusted.
virtual LONG SetEventChar (BYTE bEventChar, bool fAdjustMask = true);

// Set the event mask, which indicates what events should be
// monitored. The WaitEvent method can only monitor events that
// have been enabled. The default setting only monitors the
// error events and data events. An application may choose to
// monitor CTS. DSR, RLSD, etc as well.
virtual LONG SetMask (DWORD dwMask = EEventBreak|EEventError|EEventRecv);

// The WaitEvent method waits for one of the events that are
// enabled (see SetMask).
virtual LONG WaitEvent (LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);

// Setup the handshaking protocol. There are three forms of
// handshaking:
//
// 1) No handshaking, so data is always send even if the receiver
//    cannot handle the data anymore. This can lead to data loss,
//    when the sender is able to transmit data faster then the
//    receiver can handle.
// 2) Hardware handshaking, where the RTS/CTS lines are used to
//    indicate if data can be sent. This mode requires that both
//    ports and the cable support hardware handshaking. Hardware
//    handshaking is the most reliable and efficient form of
//    handshaking available, but is hardware dependant.
// 3) Software handshaking, where the XON/XOFF characters are used
//    to throttle the data. A major drawback of this method is that
//    these characters cannot be used for data anymore.
virtual LONG SetupHandshaking (EHandshake eHandshake);

// Read operations can be blocking or non-blocking. You can use
// this method to setup wether to use blocking or non-blocking
// reads. Non-blocking reads is the default, which is required
// for most applications.
//
// 1) Blocking reads, which will cause the 'Read' method to block
//    until the requested number of bytes have been read. This is
//    useful if you know how many data you will receive.
// 2) Non-blocking reads, which will read as many bytes into your
//    buffer and returns almost immediately. This is often the
//    preferred setting.
virtual LONG SetupReadTimeouts (EReadTimeout eReadTimeout);

// Obtain communication settings
virtual EBaudrate  GetBaudrate    (void);
virtual EDataBits  GetDataBits    (void);
virtual EParity    GetParity      (void);
virtual EStopBits  GetStopBits    (void);
virtual EHandshake GetHandshaking (void);
virtual DWORD      GetEventMask   (void);
virtual BYTE       GetEventChar   (void);

// Write data to the serial port. Note that we are only able to
// send ANSI strings, because it probably doesn't make sense to
// transmit Unicode strings to an application.
virtual LONG Write (const void* pData, size_t iLen, DWORD* pdwWritten = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);
virtual LONG Write (LPCSTR pString, DWORD* pdwWritten = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);

// Read data from the serial port. Refer to the description of
// the 'SetupReadTimeouts' for an explanation about (non) blocking
// reads and how to use this.
virtual LONG Read (void* pData, size_t iLen, DWORD* pdwRead = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);

// Send a break
LONG Break (void);

// Determine what caused the event to trigger
EEvent GetEventType (void);

// Obtain the error
EError GetError (void);

// Obtain the COMM and event handle
HANDLE GetCommHandle (void)  { return m_hFile; }

// Check if com-port is opened
bool IsOpen (void) const  { return (m_hFile != 0); }

// Obtain last error status
LONG GetLastError (void) const { return m_lLastError; }

// Obtain CTS/DSR/RING/RLSD settings
bool GetCTS (void);
bool GetDSR (void);
bool GetRing (void);
bool GetRLSD (void);

// Purge all buffers
LONG Purge (void);

protected:
// Internal helper class which wraps DCB structure
class CDCB : public DCB
{
public:
 CDCB() { DCBlength = sizeof(DCB); }
};

// Attributes
protected:
LONG m_lLastError;  // Last serial error
HANDLE m_hFile;   // File handle
EEvent m_eEvent;   // Event type
DWORD m_dwEventMask;  // Event mask

#ifndef SERIAL_NO_OVERLAPPED
HANDLE m_hevtOverlapped; // Event handle for internal overlapped operations
#endif

protected:
// Check the requirements
void CheckRequirements (LPOVERLAPPED lpOverlapped, DWORD dwTimeout) const;

// CancelIo wrapper (for Win95 compatibility)
BOOL CancelCommIo (void);
};

#endif // __SERIAL_H

byte order : 시스템 내부적으로 데이터를 표현하는 방법

host byte order (시스템마다 표현 방식이 다름)
network byte order (Big Endian 방식만을 사용하기로 약속)

Big Endian : 상위 바이트 값이 메모리상에 먼저 표시됨 (RISC 프로세서)
Little Endian : 하위 바이트 값이 메모리상에 먼저 표시됨 (인텔계열 프로세서)

ex)
실          제  :  0x 12 34 56 78
Big   Endian :  0x 12 34 56 78
Little Endian :  0x 78 56 34 12

unsigned short htons_cst(unsigned short htons)
{
int cnt = 0;
char temp = '\0';
char * endian = (char *)&htons;
 
temp = endian[0];
endian[0] = endian[1];
endian[1] = temp;

return htons;
}

+ Recent posts