드디어 마지막 시간 입니다.

이번 시간에는 지난 시간에 말씀 드린 바와 같이 UI 동작 구현 시간 입니다.


다이얼 로그 화면을 보면 OPEN 버튼이 있는데 CLOSE 버튼이 없는 것을 볼 수 있습니다.

이건 만든사람 나름인데요 저는 OPEN 되지 않은 포트를 CLOSE 할 필요 없으므로 하나의 버튼을 토글 동작으로 하기 위해 하나만 만들었던 것입니다.

OPEN된 상태에서 버튼에 CLOSE 를 보여주면 되고, CLOSE 된 상태면 OPEN을 버튼에 보여주면 되는 것이지요.

물론  상태에 따라 버튼이 눌려질 때 COM 포트를 열 것인지 닫을 것인지도 달라지게 구현 하면 됩니다.

그래서 현재 포트 상태를 나타내기 위한 변수를 하나 선언 합니다.

선언 위치는 solution view 에서 header File 중 serialDlg.h 의 public: 아래 입니다.

public:

BOOL comport_state;

CComboBox m_combo_comport_list;

CComboBox m_combo_baudrate_list;

virtual BOOL PreTranslateMessage(MSG* pMsg);

CString m_str_comport; 



1. open/close 버튼 동작 구현 하기

11.jpg 

  -> 다이얼로그에서 동작을 구현 할 때는 해당 버튼을 더블 클릭 하면 바로 구현 함수가 생성되어 해당 소스 화면으로 이동 됩니다.

       위 그림의 붉은 네모처럼 open 버튼을 마우스로 클릭해 소스코드로 이동 하면 아래와 같이 코드를 추가 합니다.

 void CserialDlg::OnBnClickedBtConnect()

{

         // TODO: Add your control notification handler code here

         if(comport_state)

         {

                  if(m_comm)        //컴포트가존재하면

                  {

                           m_comm->Close();

                           m_comm = NULL;

                           AfxMessageBox(_T("COM 포트닫힘"));

                           comport_state=false;

                           GetDlgItem(IDC_BT_CONNECT)->SetWindowText(_T("OPEN"));

                           GetDlgItem(IDC_BT_SEND)->EnableWindow(false);

                  }

         }

         else

         {

                  m_comm= new CMycomm(_T("\\\\.\\")+m_str_comport,m_str_baudrate,_T("None"),_T("8 Bit"),_T("1 Bit"));         // initial Comm port

                  if(      m_comm->Create(GetSafeHwnd()) != 0) //통신포트를열고윈도우의핸들을넘긴다.

                  {

                           AfxMessageBox(_T("COM 포트열림"));

                           comport_state=true;

                           GetDlgItem(IDC_BT_CONNECT)->SetWindowText(_T("CLOSE"));

                           GetDlgItem(IDC_BT_SEND)->EnableWindow(true);

                  }

                  else

                  {

                           AfxMessageBox(_T("ERROR!"));

                  }

 

         }

}

  -> 코드를 추가 하고 나서 생각해 보니 com_status 초기값도 없고, comport와 baudrate 초기 값도 설정 되지 않았다는 것을

      알 수 있습니다. 그래서 다이얼로그 초기화시 이 값들을 초기화 해 주는 코드를 넣어 줍니다.


22.jpg 

  -> Clsas view 에서 다이얼로그 클래스의 OninitDialog 를 더블클릭 하고, 아래 소스를 추가해 줍니다.

        // TODO: Add extra initialization here

        m_combo_comport_list.AddString(_T("COM1"));

        m_combo_comport_list.AddString(_T("COM2"));

        m_combo_comport_list.AddString(_T("COM3"));

        m_combo_comport_list.AddString(_T("COM4"));

 

        m_combo_baudrate_list.AddString(_T("9600"));

        m_combo_baudrate_list.AddString(_T("19200"));

        m_combo_baudrate_list.AddString(_T("115200"));

 

       comport_state=false;

       GetDlgItem(IDC_BT_CONNECT)->SetWindowText(_T("OPEN"));

       m_str_comport = _T("COM2");

       m_str_baudrate = _T("115200");

       UpdateData(FALSE); 

  ->  직관적으로 보면 알겠지만 comport_status 는 초기에 false 로 놓고 버튼은 open 으로 보여주며, 초기 설정 포트는 com2 

        속도는 115200bps 입니다. 


여기 까지 하고 나서 컴파일 하고 동작 시켜 보면 포트가 열리고, 닫히고, 수신된 데이터가 중앙의 edit 화면에 보여지는 것 까지 다 됩니다.

그런데 기본설정으로 된 com 포트와 속도가 변경이 되지 않는 것을 알 수 있습니다.

실제 combo box에서 선택된 값이 적용되지 않았기 때문인데요 이부분을 추가 해 주어야 합니다.


2. com 포트 선택 기능 추가 하기

33.jpg

   -> combo box 를 마우스로 선택해서 오른쪽 버튼을 눌러 properties 화면을 띄웁니다.

   -> 번개 모양 아이콘을 선택 하는데 이건 control event 며, 통칭 통지메시지 라고도 한답니다.

       이 CBN_SELCHANGE 는 COMBO BOX 에서 선택된 값이 변경되면 발생하는 이벤트 이고, 이 이벤트가 발생 했을 때 그 값을

       적용 하도록 처리 해 주면 되는 것입니다.

   -> CBN_SELCHANGE 를 선택 하고 그 옆에 화살표를 누르면 해당 함수가 생성되는데오 거기에 간단히 하래 코드를 추가 합니다.

void CserialDlg::OnCbnSelchangeComboComport()

{

        // TODO: Add your control notification handler code here

        UpdateData();

} 

  -> UpdateData(); 는 컨트롤 변수에 현재 값을 저장 하는 역할을 합니다.

       앞서 combo box의 변수로 m_combo_comport 와 m_combo_buadrate 맴버 변수를 등록해 두었으니, 현재 선택된 값을 

       이 변수에 저장 하는 기능을 해 주는 것 이지요.

       마찬가지로, 보율 선택 콤보박스도 이처럼 통지메시지를 처리하는 루틴을 추가 하고 updatedata(); 코드를 추가해 줍니다.


여기 까지 하면 원하는 통신 포트에 원하는 통신 속도로 포트를 열고 닫기가 가능 하며, 수신된 데이터가 edit box에 나타날 것입니다.


3. 화면 clear 기능 구현 하기

제목은 그럴싸 하지만 너무나 간단히 화면을 클리어 할 수 있습니다.

그냥 clear 버튼을 더블클릭해서 나오는 처리 함수에 아래 코드를 넣으면 됩니다.

void CserialDlg::OnBnClickedBtClear()

{

        // TODO: Add your control notification handler code here

               GetDlgItem(IDC_EDIT_RCV_VIEW)->SetWindowText(_T(" "));

} 

  -> edit box 의 화면을 그냥 " " .. 아무 것도 없는 것으로 출력 하는 것입니다. 


4. 송신 구현 하기

이 기능 또한 모든 것은 CMycomm 클래스에 구현돼 있기 때문에 간단히 버튼을 더블 클릭 한 후 처리 함수에 아래 코드만 넣어 주면

됩니다.

void CserialDlg::OnBnClickedBtSend()

{

        // TODO: Add your control notification handler code here

 

        CString str;

        GetDlgItem(IDC_EDIT_SEND_DATA)->GetWindowText(str);

        str+= "\r\n";

        m_comm->Send(str,str.GetLength());

} 

  -> 그냥 edit에 써진 데이터를 가져와 맨뒤에 \r\n (캐리지리턴,줄바꿈)만 추가해서 보내 주는 것입니다.


드디어 끝났습니다.

컴파일 하고 동작 시켜보면 됩니다. 

44.jpg

  -> 동작 시켜 보니 ;; 뭔가 좀 어색 하긴 합니다. ㅎ 여튼 동작은 되는군요. 

      좀더 원활한 사용을 위해 엔터를 누를 경우 send 가 되면 좋겠다는 생각이 들기도 하구요. 나머지는 이강좌를 보신분들의

      몫으로 남겨 두겠습니다. 


팁 : 혹시 컴파일시 아래와 같은 메시지를 뿌리며 컴파일 되지 않는다면. ..


1.jpg


vs2008 서비스팩 1 을 설치 하면 됩니다.

visual studio 2008 sp1

http://www.microsoft.com/ko-kr/download/details.aspx?id=10986


또는 vs2010 을 열어 open 하면 잘 되는 군요.