블로그 이미지
인생의무한루프
인생에 무한루프.....

calendar

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

Notice

Tag

Recent Post

Archive

Recent Comment

Recent Trackback

2008. 12. 15. 22:55 Appication/VC++_Control

시리얼 입력창을 구현해보자. ( MFC CEdit 예제 )

그림과 같이 에디트 컨트롤이 5개 있는 화면이라고 가정해 보자..
위 화면에서 시리얼 키를 입력받는 다고 가정할 때.. 숫자영어로 조합된 5개 문자씩을 각각의
에디트에 입력받으려면 어떻게 구현해야 할까?

또한 에디트 하나에 5개의 문자가 입력되면 어떻게 자동으로 다음 에디트로 넘어갈까?
요런 자동화가 되어있지 않다면 하나씩 입력하고 5개 확인하고 탭 누르고 또 입력하고 탭 누르고..


그렇게 간단한건 아니지만 사용자 편의를 제공해야 하는 입장이라면 구현해야 할것이다.
아래는 WM_KEYDOWN메시지 하나로 몽땅 처리한 구조이다.
여러가지 방법이 존재하겠지만.. 이렇게도 구현할 수 있음을 보여주는 샘플이므로 참조해보자.

코드 자체가 난해하거나 어려운것이 아니므로, 하나씩 의미를 파악해 보면서 이렇게도 사용할 수 있구나
라는 것을 즐겨보자.. ^^;

BOOL CSssDlg::PreTranslateMessage(MSG* pMsg)
{
    if(pMsg->message == WM_KEYDOWN)
    {
        CWnd* pWnd = CWnd::FromHandle(pMsg->hwnd);
        CString str;
       
        if(isalnum(pMsg->wParam))
        {
            switch(pWnd->GetDlgCtrlID())
            {
            case IDC_EDIT1:
            case IDC_EDIT2:
            case IDC_EDIT3:
            case IDC_EDIT4:
            case IDC_EDIT5:
                GetDlgItemText(pWnd->GetDlgCtrlID(), str);
                if(str.GetLength() == 5)
                {
                    CEdit* pEdit = (CEdit*)pWnd;
                    int s, e;
                   
                    pEdit->GetSel(s, e);
                    if(s != e)
                        return CDialog::PreTranslateMessage(pMsg);
                   
                    if(pWnd->GetDlgCtrlID() != IDC_EDIT5)
                    {
                        GetDlgItem(pWnd->GetDlgCtrlID()+1)->SetFocus();
                        ((CEdit*)GetDlgItem(pWnd->GetDlgCtrlID()+1))->SetSel(0,-1);
                    }
                   
                    if(pWnd->GetDlgCtrlID() != IDC_EDIT5)
                        GetDlgItem(pWnd->GetDlgCtrlID()+1)->PostMessage(WM_KEYDOWN, pMsg->wParam, pMsg->lParam);
                   
                    return TRUE;
                }
                break;
            }
        }
        else if(pMsg->wParam == VK_BACK)
        {
            switch(pWnd->GetDlgCtrlID())
            {
            case IDC_EDIT1:
            case IDC_EDIT2:
            case IDC_EDIT3:
            case IDC_EDIT4:
            case IDC_EDIT5:
                GetDlgItemText(pWnd->GetDlgCtrlID(), str);
                if(str.GetLength() == 0)
                {
                    if(pWnd->GetDlgCtrlID() != IDC_EDIT1)
                        GetDlgItem(pWnd->GetDlgCtrlID()-1)->SetFocus();
                    return TRUE;
                }
                break;
            }
        }
        else
        {
            switch(pMsg->wParam)
            {
            case VK_HOME:
            case VK_END:
            case VK_UP:
            case VK_DOWN:
            case VK_LEFT:
            case VK_RIGHT:
            case VK_TAB:
                break;
            default:
                return TRUE;
            }
        }
    }
   
    return CDialog::PreTranslateMessage(pMsg);
}

아래는 구현된 샘플입니다.




Posted by 까막백(홈페이지 이동)
posted by 인생의무한루프
2008. 12. 15. 22:48 Appication/VC++_Control

로그인 입력창을 구현해 보자. ( MFC CEdit 예제 )


지금까지 진행해 왔던 과정을 돌이켜 보고, 몇가지 정리를 하면서 이러한 기능을 대부분 수용하는 샘플을 만들어 보았다.

1. 부모 다이알로그와 자식 다이알로그간의 데이터 전달.
2. 입력된 데이터의 올바른지 판단여부.
3. 최대 입력 수 재한
4. 데이터의 저장 및 비교
5. 글자 색상 변경
6. 다이알로그 배경색 변경

처음 프로그램을 실행 시키면 뜨는 화면


우선 가입하기 버튼을 누르면 조인할 수 있는 창이 뜬다.

우선 아이디를 입력한다. 아이디는 4-8자리 까지 제한이 있고,
영문과 숫자만 입력받는다.
[한글을 넣으면 오동작을 할 수 있다. 한글 처리는 여기서 다루지 않는다.]

아이디를 입력하고 중복 확인을 누른다.

암호를 입력하는 창이 활성화 되고 가입 버튼이 함께 활성화 된다.
적당하게 암호를 입력하고 가입을 누른다.


로그인 버튼이 활성화 되었다. 로그인 버튼을 눌러 보자.


아까전에 넣었던 정보를 정확하게 입력하면 모든 과정이 완료된다.

그러면 아래와 같은 환영 메시지가 출력되면서 모든 기능이 완료된다.





Posted by 까막백(홈페이지 이동)
posted by 인생의무한루프
2008. 12. 15. 22:40 Appication/VC++_Control

글자 배경 바꾸기 2( MFC CEdit 예제 )

에디트에 대한 기초강좌를 마무리한 시점에서 질문이 하나 들어왔다..
지금까지의 내용을 기초로 에디트의 전체 배경을 바꾸었는데.. 깜빡이거나 먼가 이상하다...??

지난 강좌를 찾아보니, 에디트에 대한 배경 처리가 제대로 마무리 되지 못한 상태에서
강좌를 마쳐 혼란을 가져온것일 수 있을꺼 같아..
질문을 토대로 배경처리 기능을 마무리 하려고 한다.


위 그림은 두가지로 그 기능이 분류된다.

1. 왼쪽 에디트
-> 글자 바탕과 배경색상을 모두 녹색으로 처리한 것
2. 오른쪽 에디트
-> 글자 바탕은 TRANSPARENT 시키고, 바탕에는 HATCH 브러쉬를 뿌린것이다.

위 두가지 구현에는 다음과 같은 차이가 있다.
1번은 글자와 배경을 모두 그려주므로, 글씨를 쓸때 잔상이 남거나 깜빡임이 전혀없다.
2번은 글자는 쓰되 배경을 그려주지 않으므로 글씨를 쓸때 깜빡임은 없으나 잔상이 남는다.
이러한 이유로 두가지의 구현 부분에 조금 차이를 가지게 된다.

기본적인 코드는 브러쉬를 2개 만든다는 점만 빼고는 헤더에 추가할 내용은 없다.

BOOL CSssDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
   
    // 솔리드, 해치 브러쉬를 각각만든다.
    m_brush1.CreateSolidBrush(RGB(0, 255, 0));
    m_brush2.CreateHatchBrush(HS_DIAGCROSS, RGB(0, 255, 0));
   
    return TRUE; // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

클래스 위저드에서 WM_CTLCOLOR 이벤트 핸들러를 추가한다.
HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   
    switch(nCtlColor)
    {
    case CTLCOLOR_EDIT:
        {
            pDC->SetTextColor(RGB(255, 0, 0));
           
            if(pWnd->GetDlgCtrlID() == IDC_EDIT1)
            {
                // 글자 바탕을 녹색으로 하고, 녹색 솔리드 브러쉬를 리턴한다.
                // 이게 전부다.

                pDC->SetBkColor(RGB(0, 255, 0));
               
return m_brush1;
            }
           
else if(pWnd->GetDlgCtrlID() == IDC_EDIT2)
            {
                // 글자의 배경을 그려주게 되면 바탕의 해치브러쉬 영역에 글자뒷 부분은
                // 녹색 사각형이 그려지게 된다.
                // 이를 막아주기 위하여, 배경그리는 기능을 제거한다. TRANSPARENT

                pDC->SetBkMode(TRANSPARENT);

                // 에디트 컨트롤 영역을 구한 후에
                // 브러쉬로 색칠해준다.

                CRect rc;
                GetDlgItem(IDC_EDIT2)->GetWindowRect(rc);
                ScreenToClient(rc);
                pDC->FillRect(rc, &m_brush2);

               
return m_brush2;
            }
        }
    }
    // TODO: Return a different brush if the default is not desired
   
return hbr;
   
}

클래스위저드에서 IDC_EDIT2의 EN_CHANGE 이벤트 핸들러를 추가한다.
이 핸들러를 추가하는 이유는 두번째 에디트는 글자의 배경이 뒤에 그려지는 해치 브러쉬의
패턴을 덥어쓰는 걸 막아주기 위하여 TRANSPARENT 속성을 주었으므로, 글씨의 뒷부분을
그려주지 않게된다. 그러므로 잔상이 남게되어 글자에 대한 변경이 발생하면
배경을 다시 그려주도록 하기 위해서이다.
void CSssDlg::OnChangeEdit2()
{
    CRect rc;
    GetDlgItem(IDC_EDIT2)->GetWindowRect(rc);
    ScreenToClient(rc);
    InvalidateRect(rc);
}




Posted by 까막백(홈페이지 이동)

posted by 인생의무한루프
2008. 12. 15. 22:20 Appication/VC++_Control

CColorDialog를 모달? 모달리스? 로 사용하기 ( MFC 모달리스 예제 )

칼라다이알로그 박스는 꼭 확인 버튼을 눌러야 색상을 얻어올 수 있습니다.
이걸 색상을 변경할 때마다 다이알로그를 닫지 않고도, 색상을 얻어올 수 있도록
수정하여 보았읍니다.

첫번째 아래그림은 그냥 색상을 선택해 본거구요..

사용자 삽입 이미지



아래 그림은 창을 닫지 않은 상태에서 다른색상을 선택해 본것입니다.
사용자 삽입 이미지






Posted by 까막백(홈페이지 이동)

posted by 인생의무한루프