그림과 같이 에디트 컨트롤이 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);
}

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

17.zip
0.04MB

+ Recent posts