요약
Windows 기반 응용 프로그램은 종종 데이터 입력 대화 상자를 표시 하 여 사용자에 게 정보를 요청 합니다. 이러한 대화 상자에는 여러 edit 컨트롤과 확인 및 취소 라는 레이블이 붙은 두 개의 명령 (누름) 단추가 포함 될 수 있습니다. 데이터 입력 대화 상자의 예로는 사용자의 주민 등록 번호, 주소, id (ID) 번호, 날짜/시간 등의 개인 정보를 요청 하는 예가 나와 있습니다. 이러한 항목은 각각 편집 컨트롤에 입력 됩니다. 기본적으로 TAB 키는 대화 상자에서 edit 컨트롤 간에 포커스를 이동 하는 데 사용 됩니다. 그러나 일반적으로 사용자 인터페이스는 ENTER (반환) 키를 사용 하 여 편집 컨트롤 간에 이동할 수 있습니다 (예: 사용자가 정보를 입력 한 후 ENTER 키를 눌러 포커스를 다음 필드로 이동). ENTER 키를 사용 하 여 편집 컨트롤 간에 이동할 수 있는 몇 가지 방법이 있습니다. 한 가지 방법은 편집 컨트롤 및 단추에 대 한 대화 상자에서 함께 제공할 WM_COMMAND 및 알림 메시지를 사용 하는 것입니다. 다른 방법으로는 편집 컨트롤의 서브클래싱이 필요 합니다. 세 번째 작업은 App Studio 및 클래스 마법사를 사용 하 고 새 대화 상자 멤버 함수를 만드는 것입니다.
추가 정보
방법 I: (WM_COMMAND)
이 메서드는 대화 상자의 다음 동작 (대화 상자 관리자)과 Windows의 포커스 처리를 기반으로 합니다. 대화 상자 또는 컨트롤 중 하나에 현재 입력 포커스가 있는 경우 ENTER 키를 누르면 Windows에서 idItem (wParam) 매개 변수를 기본 명령 단추 ID로 설정 하 여 WM_COMMAND 메시지를 보냅니다. 대화 상자에 기본 명령 단추가 없는 경우 idItem 매개 변수는 기본적으로 IDOK로 설정 됩니다. 응용 프로그램이 기본 명령 단추 ID로 설정 된 idItem이 있는 WM_COMMAND 메시지를 수신 하는 경우 ENTER 키를 누르기 전에 포커스가 있던 컨트롤에 포커스가 유지 됩니다. 이 시점에서 GetFocus ()를 호출 하면 ENTER 키를 누르기 전에 포커스를 둔 컨트롤의 핸들이 반환 됩니다. 응용 프로그램은이 컨트롤 핸들을 확인 하 고 대화 상자에 있는 편집 컨트롤에 속하는지 여부를 결정할 수 있습니다. 그렇지 않은 경우 사용자는 편집 컨트롤 중 하나에 데이터를 입력 하 고 ENTER 키를 누른 후 입력을 누릅니다. 이 시점에서 응용 프로그램은 대화 상자에 WM_NEXTDLGCTL 메시지를 보내 포커스를 다음 컨트롤로 이동할 수 있습니다. 그러나 명령 단추 (취소 또는 확인) 중 하나를 사용 하는 경우에는 GetFocus ()에서 button 컨트롤 핸들을 반환 하 고,이 경우 한 지점에서 대화 상자를 닫을 수 있습니다. 이 논리의 의사 코드는 응용 프로그램의 대화 상자 프로시저에 다음과 유사 합니다.
case WM_COMMAND: if(wParam=IDOFDEFBUTTON || IDOK) { // User has hit the ENTER key. hwndTest = GetFocus() ; retVal = TesthWnd(hWndTest) ; //Where retVal is a boolean variable that indicates whether //the hwndTest is the handle of one of the edit controls. if(hwndTest) { //Focus is with an edit control, so do not close the dialog. //Move focus to the next control in the dialog. PostMessage(hDlg, WM_NEXTDLGCTL, 0, 0L) ; return TRUE ; } else { //Focus is with the default button, so close the dialog. EndDialog(hDlg, TRUE) ; return FALSE ; } } break ;
방법 II
이 메서드는 대화 상자에서 편집 컨트롤을 서브클래싱/superclassing 하는 것과 관련이 있습니다. 편집 컨트롤이 서브클래싱된 경우 또는 superclassed 경우 대화 상자에 기본 명령 단추가 있는지 여부에 관계 없이 모든 키보드 입력에 현재 입력 포커스가 있는 편집 컨트롤의 하위 클래스/슈퍼 클래스 프로시저가 전송 됩니다. 이 응용 프로그램은 키의 하위 (또는 문자) 메시지를 트랩 하 고 ENTER 키를 찾아 적절 하 게 처리할 수 있습니다. 다음은 ENTER 키를 찾는 샘플 하위 클래스 프로시저입니다.
//*------------------------------------------------------------------- //| Title: //| SubClassProc //| //| Parameters: //| hWnd - Handle to the message's destination window //| wMessage - Message number of the current message //| wParam - Additional info associated with the message //| lParam - Additional info associated with the message //| //| Purpose: //| This is the window procedure used to subclass the edit control. //*--------------------------------------------------------------------- long FAR PASCAL SubProc(HWND hWnd, WORD wMessage,WORD wParam,LONG lParam) { switch (wMessage) { case WM_GETDLGCODE: return (DLGC_WANTALLKEYS | CallWindowProc(lpOldProc, hWnd, wMessage, wParam, lParam)); case WM_CHAR: //Process this message to avoid message beeps. if ((wParam == VK_RETURN) || (wParam == VK_TAB)) return 0; else return (CallWindowProc(lpOldProc, hWnd, wMessage, wParam, lParam)); case WM_KEYDOWN: if ((wParam == VK_RETURN) || (wParam == VK_TAB)) { PostMessage (ghDlg, WM_NEXTDLGCTL, 0, 0L); return FALSE; } return (CallWindowProc(lpOldProc, hWnd, wMessage, wParam, lParam)); break ; default: break; } /* end switch */
방법 3
이 메서드는 App Studio 및 클래스 마법사를 사용 하 고 새 대화 상자 멤버 함수를 만드는 것과 관련이 있습니다. 이 메서드는 사용자가 ENTER 키를 누를 때 포커스를 다음 편집 컨트롤로 이동할 수 있도록 합니다. 현재 대화 상자의 마지막 편집 컨트롤에 포커스가 있는 경우 포커스는 첫 번째 edit 컨트롤로 이동 합니다. 먼저, 앱 Studio를 사용 하 여 대화 상자의 확인 단추에 대 한 ID를 변경 합니다. 앱 Studio의 기본 동작은 ID IDOK에 게 OK 단추를 제공 하는 것입니다. 확인 단추의 ID는 IDC_OK 등의 다른 값으로 변경 해야 합니다. 또한 기본 누름 단추가 되지 않도록 확인 단추의 속성을 변경 합니다. 다음으로, 클래스 마법사를 사용 하 여 새 대화 상자 구성원 funciton을 만듭니다. 새 멤버 함수의 이름을 OnClickedOK와 같이 선택 합니다. 이 함수는 IDC_OK 컨트롤의 BN_CLICKED 메시지에 연결 되어야 합니다. 이 작업이 완료 되 면 OnClickedOK 함수의 본문을 작성 합니다. 일반적으로 OnOK 함수에 포함 되는 코드는 클래스의 OnOK 함수를 포함 하 여 새 OnClickedOK 함수에 넣어야 합니다. 대화 상자의 헤더 파일에 다음 프로토타입을 추가 합니다.
protected: virtual void OnOK();
대화 상자에 OnOK 함수를 추가 하면 다음과 같은 코드를 볼 수 있습니다.
void CMyDialog::OnOK() { CWnd* pwndCtrl = GetFocus(); CWnd* pwndCtrlNext = pwndCtrl; int ctrl_ID = pwndCtrl->GetDlgCtrlID(); switch (ctrl_ID) { case IDC_EDIT1: pwndCtrlNext = GetDlgItem(IDC_EDIT2); break; case IDC_EDIT2: pwndCtrlNext = GetDlgItem(IDC_EDIT3); break; case IDC_EDIT3: pwndCtrlNext = GetDlgItem(IDC_EDIT4); break; case IDC_EDIT4: pwndCtrlNext = GetDlgItem(IDC_EDIT1); break; case IDOK: CDialog::OnOK(); break; default: break; } pwndCtrlNext->SetFocus(); }