CTRLTEST 샘플: 사용자 지정 컨트롤 구현
업데이트: 2007년 11월
CTRLTEST 샘플에서는 사용자 지정 컨트롤을 구현하고 사용하는 다음의 몇 가지 기술을 보여 줍니다.
라이브러리 컨트롤 클래스에서 기능이 파생된 특수 Edit 컨트롤인 CParsedEdit 구현과, 사용자 지정 컨트롤을 사용하는 세 가지 메서드
Spin 컨트롤 사용. Spin 컨트롤에는 값을 증가시키거나 감소시키는 작은 위쪽/아래쪽 화살표 단추가 있습니다.
CBitmapButton을 사용하여 Custom 메뉴 명령에 대한 비트맵 단추 구현
메뉴 및 목록 상자의 소유자(부모 창) 그리기. CMenu 클래스와 CListBox 클래스에서 파생된 해당 컨트롤 클래스에서는 개체 지향 방식으로 이 기능을 제공합니다.
Microsoft Visual C++ 리소스 편집기에서 유지 관리할 수 없는 리소스 파일 사용. 여기에서는 헤더 파일에 상수로 정의된 스타일의 사용자 지정 컨트롤이 있는 대화 상자에서 .rc2 파일을 사용할 때의 장점과 단점을 보여 줍니다.
CTRLTEST 샘플에서 보여 주는 모든 기능은 메뉴 명령을 통해 시작됩니다.
보안 정보: |
---|
이 샘플 코드는 개념을 보여 주기 위해 제공되며 가장 안전한 코드 작성 방법을 제시하지 않을 수 있으므로 응용 프로그램이나 웹 사이트에서 사용할 수 없습니다. Microsoft는 샘플 코드를 원래 용도 이외의 다른 용도로 사용하는 경우 발생하는 부수적이나 파생적인 손해에 대해 책임을 지지 않습니다. |
샘플 및 이를 설치하기 위한 지침을 가져오려면
Visual Studio의 도움말 메뉴에서 샘플을 클릭합니다.
자세한 내용은 샘플 파일 찾기를 참조하십시오.
최신 버전 및 전체 샘플 목록은 Visual Studio 2008 Samples 페이지에서 온라인으로 사용할 수 있습니다.
컴퓨터의 하드 디스크에서도 샘플을 찾을 수 있습니다. 기본적으로 샘플과 추가 정보 파일은 \Program Files\Visual Studio 9.0\Samples\ 아래의 폴더에 복사됩니다. Visual Studio Express Edition의 경우에는 모든 샘플이 온라인에 있습니다.
샘플 빌드 및 실행
CTRLTEST 샘플을 빌드하고 실행하려면
솔루션 파일인 Ctrltest.sln을 엽니다.
빌드 메뉴에서 빌드를 클릭합니다.
디버그 메뉴에서 디버깅하지 않고 시작을 클릭합니다.
예제: 사용자 지정 컨트롤 구현 및 사용
사용자 지정 컨트롤은 CWnd에서 파생시켜 구현할 수도 있지만, 표준 Windows 컨트롤의 기능을 사용할 수 있는 경우에는 라이브러리에 있는 컨트롤 클래스에서 파생시키는 것이 더 쉽습니다. CTRLTEST에서는 이 방법으로 특수 edit 컨트롤인 CParsedEdit를 구현합니다. 이 Edit 컨트롤에서는 숫자, 영문자, 비제어 문자 등의 지정된 문자 집합만 사용자 입력으로 받아들입니다. CParsedEdit는 CEdit에서 파생되며, 문자를 필터링하기 위한 OnChar 메시지 처리기가 포함되어 있습니다.
Simple 메뉴의 명령 구현에서는 사용자 지정 컨트롤을 사용하는 세 가지 메서드를 보여 줍니다. 이 세 메서드는 응용 프로그램에서 대화 상자의 컨트롤 인스턴스를 CParsedEdit 클래스와 연결하는 방식에 따라 구분됩니다. 각 Simple 메뉴 명령은 네 개의 CParsedEdit 컨트롤 인스턴스가 있는 대화 상자를 표시합니다. 이 대화 상자에 입력된 데이터는 디버그 포트에 TRACE 출력으로 보내집니다. 세 개의 Simple 메뉴 명령은 다음과 같습니다.
Test C++ Derived Class
CParsedEdit 컨트롤은 대화 상자 클래스의 데이터 멤버입니다. 이 컨트롤은 CParsedEdit::CreateSet를 호출하여 대화 상자의 OnInitDialog 함수에서 명시적으로 만들어집니다. Dertest.cpp를 참조하십시오.
Test WNDCLASS Registered
CParsedEdit 컨트롤은 대화 상자 템플릿 리소스(IDD_WNDCLASS_EDIT)에서 WNDCLASS가 "paredit"로 식별되는 사용자 지정 컨트롤로 레이아웃됩니다. Visual C++ 대화 상자 편집기를 사용하여 이러한 사용자 지정 컨트롤의 속성을 검사하는 것이 좋습니다.
Caption blank - CParsedEdit 컨트롤에 표시되는 초기 값입니다.
Class:paredit - 대화 상자가 호출되기 전에 PAREDIT2.CPP에서 CParsedEdit::RegisterControlClass에 의해 등록되는 WNDCLASS 이름입니다.
Visible:checked - 컨트롤이 표시됩니다.
Tabstop:checked - 사용자가 이 컨트롤로 탭 이동할 수 있습니다.
네 개의 구문 분석된 Edit 컨트롤에 대한 Style:0x5081002, 0x5081001, 0x5081003, 0x5081ffff - 스타일 0x500000은 WS_CHILD 및 WS_VISIBLE에 대한 스타일이고, 0x1000은 WS_TABSTOP에 대한 스타일입니다. 모든 사용자 지정 컨트롤에는 WS_CHILD 스타일이 있습니다. WS_VISIBLE 및 WS_TABSTOP 스타일은 사용자가 Visible 및 Tabstop 스타일을 선택할 때 대화 상자 편집기에서 자동으로 설정합니다. 0x80000은 WS_BORDER에 대한 스타일입니다. 사용자 지정 컨트롤에 대한 대화 상자 편집기 속성 페이지에서는 WS_BORDER 등의 모든 창 스타일을 제공하므로 \Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include\WINUSER.H에서 상수를 찾아야 합니다. 스타일 0x0001, 0x0002, 0x0004 및 0x0ffff는 PAREDIT.H에서 각각 PES_NUMBERS, PES_LETTERS, PER_OTHERCHARS 및 PES_ALL로 정의됩니다.
사용자 지정 컨트롤 속성 페이지의 16진수 스타일은 자체적으로 작성되지 않습니다. 따라서 PES_NUMBERS 및 PES_LETTERS 등의 기호로 된 스타일을 사용해야 하는 경우에는 컴파일 타임에 리소스 컴파일러에 의해 포함되지만 편집할 때는 Visual C++에서 읽을 수 없는 RES\Ctrltest.rc2 등의 별도의 리소스 파일을 사용자가 직접 편집할 수 있습니다. .rc2 파일에서 사용자 지정 컨트롤 대화 상자를 수동으로 편집할 때의 장/단점에 대한 자세한 내용은 Visual C++ 리소스 편집기에서 유지 관리할 수 없는 리소스 파일 사용을 참조하십시오.
Test Dynamic Subclassed
컨트롤은 대화 상자 템플릿 리소스(IDD_SUB_EDIT in Ctrltest.rc)에 표준 Edit 컨트롤로 레이아웃되며, 대화 상자 클래스에서 CParsedEdit 데이터 멤버로 선언됩니다. 대화 상자의 OnInitDialog 함수는 CParsedEdit::SubClassEdit를 호출하고 CParsedEdit::SubClassEdit는 CWnd::SubclassDlgItem을 호출하여 Edit 컨트롤의 각 특정 인스턴스를 CParsedEdit 클래스와 연결합니다. Paredit.cpp를 참조하십시오.
예제: Spin 컨트롤
CTRLTEST 샘플에서는 Spin 컨트롤도 구현합니다. Spin 컨트롤에는 값을 증가시키거나 감소시키는 작은 위쪽/아래쪽 화살표 단추가 있습니다.
Spin Control 명령은 각각 하나의 Spin 컨트롤과 연결된 네 개의 CParsedEdit 컨트롤이 있는 대화 상자를 호출합니다. 이 대화 상자의 CParsedEdit 컨트롤에 입력된 데이터는 음이 아닌 정수만 허용하도록 필터링됩니다. 사용자는 CParsedEdit 컨트롤에 값을 입력하거나 관련 Spin 컨트롤을 사용하여 숫자 데이터를 입력할 수 있습니다.
예제: 비트맵 단추
다음의 Custom 메뉴 명령 구현에서는 CBitmapButton의 사용 방법을 보여 줍니다.
Bitmap Button 1 - 이 대화 상자 생성자는 CBitmapButton::LoadBitmaps를 호출하여 해당 단추의 세 가지 상태(누르지 않음, 누름, 포커스) 각각에 대해 비트맵 리소스를 명시적으로 로드합니다.
Bitmap Button 2 - 이 대화 상자의 OnInitDialog 함수는 CBitmapButton::Autoload를 호출하여 다음 명명 규칙에 따라 비트맵 리소스를 로드합니다. 컨트롤의 창 텍스트는 기본 리소스 이름의 역할을 하며, 누르지 않음, 누름 및 포커스 상태에 대한 세 개의 각 비트맵 이미지에 대한 리소스 이름을 만들 때 문자 U, D 및 F가 추가됩니다. 예를 들어, OK 단추에 대한 세 개의 비트맵 리소스 이름은 각각 OKU, OKD 및 OKF로 지정됩니다.
Bitmap Button 3 - 이 대화 상자는 위의 두 번째 대화 상자를 비활성화라는 네 번째 단추 상태를 사용하여 확장한 것입니다. 이 대화 상자를 사용하려면 표시된 숫자가 가장 작은 숫자인 1에 도달하거나 가장 큰 숫자인 10에 도달할 때까지 왼쪽 또는 오른쪽 화살표 비트맵 단추를 클릭합니다. 한계에 도달하면 단추가 비활성화되고 네 번째 비트맵 이미지가 표시됩니다. 비활성 상태에 대한 비트맵 리소스의 명명 규칙은 리소스 이름 PREVX 및 NEXTX에서와 같이 X 접미사를 사용하는 것입니다.
예제: 소유자 그리기(메뉴 및 목록 상자)
다양한 Windows 컨트롤과 메뉴에는 표준 컨트롤 동작 대신 해당 컨트롤의 클라이언트 영역에서 필요로 하는 것을 부모(또는 소유자) 창에서 그릴 수 있도록 하는 소유자 그리기 기능이 있습니다. 해당 컨트롤 클래스와 CMenu 클래스에서는 보다 편리한 개체 지향 방식으로 이 기능을 제공하며, 컨트롤 또는 메뉴 클래스에서 그리기를 처리합니다. 이러한 기능을 "자체 그리기"라고 합니다.
CTRLTEST에서는 Custom 메뉴에 다음 명령을 구현할 때 소유자 그리기의 일반적인 기술을 보여 줍니다.
Custom Menu - 이 메뉴 항목은 CMenu에서 파생된 CColorMenu 팝업 메뉴를 호출합니다. 각 하위 메뉴 항목은 자체 그리기 기능을 사용하여 8개의 색 중 하나를 표시합니다. 메시지 상자에서는 사용자가 하위 메뉴에서 선택한 색을 확인합니다.
Custom List Box - 이 메뉴 항목은 CListBox에서 파생된 CColorListBox를 표시하는 대화 상자를 호출합니다. 이 목록 상자에는 8개의 항목이 있으며 각 항목은 자체 그리기 기능을 사용하여 8개의 색 중 하나로 그려집니다. TRACE 출력에서는 사용자가 목록 상자에서 선택한 항목을 확인합니다.
예제: Visual C++ 리소스 편집기에서 유지 관리할 수 없는 리소스 파일 사용
리소스 파일 CTRLTEST\RES\Ctrltest.rc2는 Visual C++ 리소스 편집기에서 사람이 인식할 수 있는 형식으로 유지 관리할 수 없는 리소스 파일의 예입니다. Visual C++에서 Ctrltest.rc2를 연 다음 저장하는 경우, 리소스 컴파일러에서 해당 .rc2 파일을 컴파일하여 동등한 이진 .res 파일을 생성할 수는 있지만 사람이 인식할 수 있는 유용한 정보는 잃게 됩니다. 따라서 RES\Ctrltest.rc2는 Resource File Set Includes 명령으로 지정되는 컴파일 타임 지시문을 사용하여 Ctrltest.rc에 #include로 추가됩니다.
다음은 Visual C++ 리소스 편집기에서 유지 관리할 수 없고 사람이 인식할 수 있는 정보의 세 가지 범주입니다. Ctrltest.rc2에서는 이 중 두 가지 범주를 보여 줍니다.
사용자 지정 컨트롤 스타일 기호 - 예를 들어, "msctls_updown32"는 Spin 컨트롤에 대해 정의되는 스타일입니다. Visual C++에서는 이 기호를 .rc2 파일에 기록된 상태 그대로도 해석할 수 있지만, 16진수 값으로 .rc2 파일에 다시 씁니다.
표준 Windows 컨트롤 파생 클래스에서 컨트롤에 사용되는 표준 Windows WS_ 또는 컨트롤 스타일 기호 - 예를 들어, ES_AUTOHSCROLL은 IDD_SPIN_EDIT 대화 상자에서 Spin 컨트롤에 대해 정의됩니다. Visual C++에서는 이러한 기호를 .rc2 파일에 기록된 상태 그대로도 해석할 수 있지만, 16진수 값으로 .rc2 파일에 다시 씁니다.
.rc 파일의 산술 연산 - Visual C++는 IDD_SPIN_EDIT 대화 상자에서 컨트롤을 식별하는 "IDC_EDIT1+2" 등의 식을 단일 16진수 값으로 .rc2 파일에 다시 씁니다.
CTRLTEST 샘플에서는 헤더 파일에 상수로 정의된 스타일의 사용자 지정 컨트롤이 있는 대화 상자에서 .rc2 파일을 사용할 때의 장/단점을 보여 줍니다. 대화 상자 IDD_WNDCLASS_EDIT와 IDD_SPIN_EDIT에는 모두 기호로 정의된 스타일의 사용자 지정 컨트롤이 있습니다. 그러나 IDD_WNDCLASS는 Visual C++ 대화 상자 편집기에서 편집할 수 있는 .rc 파일에 지정되는 반면 IDD_SPIN_EDIT는 수동으로만 편집할 수 있는 .rc2 파일에 지정됩니다.
.rc 파일과 .rc2 파일 사용의 차이점은 다음과 같이 요약할 수 있습니다.
IDD_WNDCLASS_EDIT 대화 상자의 경우 리소스 스크립트는 Ctrltest.rc에 정의되는 반면, IDD_SPIN_EDIT 대화 상자의 경우에는 리소스 스크립트가 RES\Ctrltest.rc2에 정의됩니다. IDD_WNDCLASS_EDIT 대화 상자의 경우, WNDCLASS 사용자 지정 컨트롤은 "paredit"이고 스타일 상수는 PAREDIT.H에 정의되며 예제 스타일 상수는 PES_NUMBER입니다. IDD_WNDCLASS_EDIT는 Visual C++에서 편집할 수 있지만 #define 스타일을 사용할 수는 없습니다. 반면, IDD_SPIN_EDIT는 Visual C++에서 편집할 수 없지만 #define 스타일을 사용할 수는 있습니다.
따라서 .rc2 파일을 사용하는 경우에는 사용자 지정 컨트롤에 대해 헤더 파일에 정의되었으며 사람이 인식할 수 있는 기호 스타일을 사용할 수 있지만, Visual C++ 대화 상자 편집기를 사용하여 .rc2 파일을 편집할 수는 없다는 장단점이 있습니다. 리소스 스크립트를 수동으로 작성하는 것보다는 Visual C++를 사용하여 대화 상자를 레이아웃하는 것이 더 쉽습니다. 리소스 스크립트를 수동으로 작성하면 오류가 생기기 쉽기 때문입니다. 반면, 스타일은 Visual C++ 대화 상자 편집기에서 사용자 지정 컨트롤 속성 페이지에 16진수로 표시될 때 자체적으로 작성되지 않습니다.
키워드
이 샘플에서는 다음의 키워드를 보여 줍니다.
AfxGetInstanceHandle, AfxMessageBox, AfxThrowResourceException, CBitmapButton::AutoLoad, CDC::FillRect, CDC::FrameRect, CDialog::DoModal, CDialog::EndDialog, CDialog::OnInitDialog, CDialog::OnOK, CDialog::OnSetFont, CEdit::Create, CEdit::SetSel, CFrameWnd::Create, CListBox::AddString, CListBox::CompareItem, CListBox::DrawItem, CListBox::GetItemData, CListBox::MeasureItem, CMenu::AppendMenu, CMenu::CreateMenu, CMenu::Detach, CMenu::DrawItem, CMenu::EnableMenuItem, CMenu::FromHandle, CMenu::GetMenuString, CMenu::MeasureItem, CRect::Width, CStatic::Create, CString::Format, CString::LoadString, CWinApp::InitInstance, CWnd::Attach, CWnd::EnableWindow, CWnd::FromHandle, CWnd::GetDlgCtrlID, CWnd::GetDlgItem, CWnd::GetDlgItemInt, CWnd::GetMenu, CWnd::GetParent, CWnd::GetWindowRect, CWnd::GetWindowText, CWnd::IsWindowEnabled, CWnd::MessageBox, CWnd::OnChar, CWnd::OnCommand, CWnd::OnVScroll, CWnd::PostNcDestroy, CWnd::SendMessage, CWnd::SetDlgItemInt, CWnd::SetFocus, CWnd::SetFont, CWnd::SetWindowPos, CWnd::ShowWindow, CWnd::SubclassDlgItem, CallWindowProc, GetBValue, GetClassInfo, GetGValue, GetRValue, GetSystemMetrics, HIWORD, IsCharAlpha, IsCharAlphaNumeric, LOWORD, MAKEINTRESOURCE, MAKELONG, MessageBeep, ModifyMenu, RGB, RegisterClass, SetWindowLong
참고: |
---|
이 샘플을 비롯한 일부 샘플은 Visual C++ 마법사, 라이브러리 및 컴파일러의 변경 내용을 반영하도록 수정되지 않았지만 해당 작업의 수행 방법을 보여 줍니다. |