- 대화상자는 사용자와 윈도우 간의 인터페이스 기능을 합니다.
- 단일문사=마우스, 키보드 메시지 / 다이얼로그 = 컨트롤 메시지
CDialogEx 클래스
- 대화상자는 CDialogEx 클래스로 정의합니다.
- CDiaglogEx 클래스는 CDialog 클래스로부터 파생된 파생클래스입니다.
- CDialogEx 클래스의 모든 기능 + 배경색과 배경그림 바꾸는 기능까지 추가되었습니다.
대화상자 기반의 프로그램
- 대화상자 기반의 프로그램은 애플리케이션 클래스와 다이얼로그 클래스(대화상자 클래스)로 구성됩니다.
- 대화상자 클래스는 대화상자의 기능을 구현하는 실제적인 클래스입니다.
- 애플리케이션 클래스는 프로젝트 전체를 관리하는 클래스입니다.
- MDI, SDI 프로그램과 클래스 구조가 다릅니다.
1. 대화상자 프로그램의 동작
- 대화상자 프로그램 실행하면 !! 우선 생성자 함수 호출
- -> OnCreate() 함수 호출 = CWnd 객체가 제대로 생성된다면 0 반환, 프로그램이 종료되면 OnDestroy() 함수 호출되어서 -1 반환
- -> OnInitDialog() 함수 호출 = 대화상자가 화면에 보이기 바로 전에 실행되므로 여기에서 초기화 기능 부여, 대화상자에서 사용된 컨트롤들의 초깃값 부여하는 작업 실행
- ->OnPaint() 함수 = OnDraw() 함수와 같은 기능
- DoDataExchange() 함수 = 컨트롤을 어떤 방식으로 이용할 것인지 결정-VALUE와 CONTROL이 존재
MFC 기본 컨트롤
- 컨트롤: 사용자와 인터페이스를 이루는 도구입니다.
- 프로그램은 실행 중에 끊임없이 사용자와 통신하는데 컨트롤을 통해 명령, 정보 받아들이고, 컨트롤을 통해 결과를 사용자에게 보고합니다.
(1) Static Text
- 화면에 문자열 배치할 때 사용하며, 사용자로부터 명령을 받아들이지도 않고, 출력을 내보내지도 않는다. 레이블 용도
(2) Edit Control
- 문자열 입력하고 편집 가능한 컨트롤
- 사용자가 값 입력 가능
- 변수와 연결해서 사용함 -> 변수 연결 방식 두 가지
(3) Gruop Box
- 서로 연관된 컨트롤들을 시각적으로 그룹을 지어 다른 컨트롤과 구분하는 용도로 사용합니다. 그룹 박스로 묶는다고 기능이 변경되지는 x
(4) Button Control
- 마우스로 클릭하여 어떤 동작을 수행하는 용도로 사용합니다.
(5) Check Box
- 버튼 컨트롤의 일종으로 독립적인 옵션을 선택할 때 사용합니다. 마우스로 클릭하면 체크표시가 on/off. 여러 옵션 중 임의의 개수를 선택할 때 사용합니다. (2~3개 ㄱㄴ)
(6) Radio Button
- 버튼 컨트롤의 일종으로 상호 배타적인 옵션을 선택할 때 사용합니다. 마우스로 클릭하면 라디오 표시가 on/off. 여러 옵션 중 하나만 선택할 때 사용합니다. (2~3개 ㄱㄴ)
(7) List Box
- 여러 개의 선택 항목을 나열하고 선택할 수 있도록 해주는 컨트롤입니다. 하나 또는 여러 개 선택 ㄱㄴ
(8) Combo Box(리스트 박스+에디트 컨트롤)
- 리스트 박스의 단점을 해결. 리스트 박스+에디트 컨트롤 합쳐놓은 모양입니다.
- 기존의 항목을 선택할 때는 아래쪽의 리스트 박스에서 선택하고 직접 입력해야 할 항목은 에디트 컨트롤에서 입력할 수 있으며, 콤보 박스는 리스트 박스를 평소에 닫아두므로 화면 면적 차지 적습니다.
1. 실습 4-1 MFC 기본 컨트롤 사용법 익히기 ok
updateCombo() 함수는 리스트박스에 아이템이 들어가거나 없어질때마다 호출되어야 함
에디트 컨트롤에 문자열 입력 후 "데이터 추가" 버튼을 클릭하면 리스트 박스에 바로 보여줘야 함
리스트박스 화면에 출력되어있는 순서의 인덱스와 콤보 박스의 인덱스 동일
리스트 멤버변수.AddString() 과 콤보박스 멤버변수.AddString() 하면 그냥 바로 넣어줌 문자열 !
에디트박스의 멤버변수는 IsEmpty()와 Empty() 멤버함수만 있음
- 폼 만들기
- 리스트 박스, 에디트 컨트롤, 콤보 박스와 매개변수 연결하기
- updateComboBox 함수 만들기(void형)-> 리스트박스의 수만큼 콤보박스 매개변수에 문자열 추가하기
- radio 버튼 1, 2 메시지 헨들러 함수 작성->클릭하면 리스트박스에 문자열 추가->updateCombo() 함수 호출
- check 버튼 bool 변수 추가 ( bool[2] m_bChecked; 복수 허용하므로 배열형태로 만들고 체크박스1, 체크박스2의 체크상태를 확인/인덱스0, 1 사용 -> 변수 초기화(생성자함수))->체크박스 메시지 헨들러 함수 추가
- 에디트박스 "데이터 추가" 버튼 메시지 헨들러 함수 추가(문자열 입력 후 "데이터 추가" 버튼 누르면 리스트 박스에 바로 보임 / 입력한 문자열 없는데 "데이터 추가" 버튼 눌렀으면 오류난다는 메시지 박스 보여주기)
- 콤보 박스 옆의 "삽입" 버튼
- 콤보 박스 옆의 "삭제" 버튼
폼 구성 -> DDX(값이나 컨트롤 형식으로 매개변수와 연결) -> 클래스 마법사에서 컨트롤에 메시지 핸들러 함수 적용 -> 실행하면 그 컨트롤에 메시지 가해지면 핸들러 함수 안의 내용이 실행
- 폼 구성 -> 멤버변수로 컨트롤을 다루기 위해서 컨트롤들과 멤버변수를 연결해야 합니다.
- 컨트롤을 멤버 변수와 연결하는 방법 두 가지가 있습니다.
- 변수 연결한 뒤에(값이나 컨트롤로 ddx) 각 컨트롤에 대한 메시지 핸들러 함수를 만듭니다.(각 컨트롤을 사용자가 선택했을 때의 이벤트 처리-우리가 각 컨트롤마다 연결했던 매개변수 위주로 코딩)
컨트롤(대화상자)을 멤버 변수와 연결하는 방법
(1) DDX(값/컨트롤)을 이용한 방법 - 우리가 거의 사용하는 방법 -
-> Value: 컨트롤에 설정되어 있는 값만 연결, DDX_Text 계열 함수를 이용하여 자원을 연결 / 해당 컨트롤에서 값만 가져오겠다. updateData() 함수를 통해서 매개변수에 t/f 넣으면서 값을 컨트롤에 보내고 가져오고 함
-> Control: 해당 컨트롤을 제어할 수 있는 컨트롤 클래스와 연결, DDX_Control 계열의 함수를 이용하여 자원 연결 / 해당 컨트롤의 클래스와 연결되니깐 클래스의 멤버 함수 사용 가능
(2) 컨트롤의 핸들을 가져와서 클래스와 연결하는 방법
- 컨트롤의 핸들을 얻기 위해 컨트롤의 포인터를 받을 포인터 변수 선언
- GetDlgItem() 함수를 이용해서 컨트롤의 포인터를 선언된 포인터 변수에 치환
- 클래스의 멤버를 이용해서 컨트롤을 다룹니다.(핸들과 클래스 연결)
CListBox *pList; //리스트박스 컨트롤 가르키는 포인터 생성
//GetDlgItem() 함수를 사용하여 해당 리스트 박스 컨트롤의 핸들을 얻어와 pList에 대입, 명시적 형변환
pList = (CListBox *) GetDlgItem(IDC_LIST); // IDC_LIST은 리스트박스 컨트롤의 ID
//클래스의 멤버(함수)를 이용해서 컨트롤을 다룬다.
pList->AddString("데이터");
visual c++에서 DDX로 연결하는 방법
1. 클래스 마법사에서 [멤버 변수] 탭에서 컨트롤 ID 선택 -> [변수 추가]
2. ctrl 키 누른 상태에서 대화 상자 내의 해당 컨트롤 더블클릭
DoDataExchage() 함수: 매개변수와 컨트롤 연결
- DoDataExchange() 함수는 주로 대화상자나 폼뷰에서 사용되며, 데이터와 UI 요소 간의 일관성을 유지하고 데이터 입력에 대한 유효성 검사를 수행하는 등의 역할을 수행합니다.
- 대화상자의 여러 자원을 연결하는 기능을 하는 함수입니다.(컨트롤을 값이나 컨트롤 형식으로 연결)
- 이 함수 안에는 DDX_Text와 DDX_Control 함수를 이용하여 자원과 연결할 수 있습니다. -매개변수 OR 클래스
- DDX_Control 형태로 연결되었을 경우는 변수가 클래스로부터 상속 받았으므로 클래스의 멤버 함수를 마음대로 사용 가능
UpdatData() 함수: 매개변수와 컨트롤의 값을 업데이트
- DDX_Value 형태로 연결돼었을 경우는 UpdateData() 함수를 사용해서 자원을 update 합니다.
- 방향을 잘 확인해야 합니다.
- UpdateData(TRUE) - 버튼 클릭 시에 컨트롤에 있는 데이터를 변수에 가져오는 것
- UpdateData(FALSE) - 변수에 특정 값을 주고 그 값을 컨트롤에 보내기, 화면갱신
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// 다이얼로그 상의 컨트롤 값을 멤버 변수에 읽어옴
UpdateData(FALSE);
return TRUE;
}
void CMyDialog::OnBtnClicked()
{
// 사용자가 버튼을 클릭하였을 때, 컨트롤의 값을 멤버 변수에 읽어옴
UpdateData(TRUE);
// 멤버 변수의 값을 이용하여 작업 수행
// ...
}
void CMyDialog::OnOK()
{
// 다이얼로그의 OK 버튼을 클릭하였을 때, 컨트롤의 값을 멤버 변수에 저장
UpdateData(TRUE);
// 멤버 변수의 값을 이용하여 작업 수행
// ...
CDialog::OnOK();
}
CListBox 클래스의 주요 멤버 함수-CONTROL로 연결
- 왜 알아야 되나? 우리가 컨트롤과 매개변수를 DDX 함수로 연결을 할 수 있었어. 그 형식은 값만 가져오는 Value(DDX_Text() 함수)하고, 컨트롤의 클래스 연결(DDX_Control() 함수)가 있었지?
- 근데 여기서 DDX_Control 함수는 클래스와 연결되기때문에 컨트롤과 연결된 매개변수가 그 컨트롤 클래스의 멤버함수까지 사용할 수 있어. 따라서 멤버 함수를 쓰기 위해선 알아둬야 해 ~~
- MFC(Microsoft Foundation Classes)에서 제공하는 리스트 박스 컨트롤을 다루는 클래스
함수명 | 기능 |
GetCount() 함수 | 리스트박스의 아이템 수를 알기 위해 사용하는 함수 int GetCount() const; 반환값으로는 현재 리스트 박스에 있는 아이템의 개수를 반환합니다. 이 함수를 사용하면 CListBox 클래스를 통해 현재 리스트 박스에 추가된 아이템의 개수를 알 수 있습니다. 예를 들어, 리스트 박스에 목록을 추가하고 삭제하는 동작을 수행할 때, GetCount() 함수를 사용하여 현재 목록의 개수를 확인하고 이를 기반으로 추가적인 동작을 수행할 수 있습니다. |
AddString() 함수 | 리스트박스의 맨 뒤에 문자열을 추가할 때 사용하는 함수 int AddString(LPCTSTR lpszItem); 인자로는 추가할 문자열의 포인터를 전달합니다. 반환값은 리스트 박스에 추가된 문자열의 인덱스를 반환합니다. 그냥 바로 문자열 추가해보림 |
GetText() 함수 | 리스트박스로부터 문자열을 얻어올 때 사용되는 함수 vint GetText(int nIndex, LPTSTR lpszBuffer) const; -> 몇번째 인덱스에 있는 문자열을 버퍼에 저장해 인자로는 가져올 문자열의 인덱스와 문자열을 저장할 버퍼의 포인터를 전달합니다. 반환값은 가져온 문자열의 길이를 반환합니다. |
DeleteString() 함수 | 리스트박스의 아이템을 삭제할 때 사용하는 함수 int DeleteString(UINT nIndex); 인자로는 삭제할 문자열의 인덱스를 전달합니다. 반환값은 삭제된 문자열의 인덱스를 반환합니다. |
CComboBox 클래스의 주요 멤버 함수
- MFC(Microsoft Foundation Classes)에서 제공하는 콤보 박스 컨트롤을 다루는 클래스
함수 | 기능 |
AddString() 함수 | 콤보 박스의 맨 뒤에 새로운 문자열을 추가하는 함수 int AddString(LPCTSTR lpszString); 인자로는 추가할 문자열의 포인터를 전달합니다. 반환값은 콤보 박스에 추가된 문자열의 인덱스를 반환합니다. 그냥 바로 문자열 추가해보림 |
GetCurSel() 함수 | 현재 선택된 아이템의 인덱스를 가져오는 함수 int GetCurSel() const; 반환값으로는 현재 선택된 아이템의 인덱스를 반환합니다. |
ResetContent() 함수 | 콤보박스의 모든 아이템을 제거할 때 사용하는 함수 void ResetContent() |
CString 클래스의 주요 멤버 함수
함수 | 기능 |
IsEmpty() 함수 | 문자열 버퍼가 비어 있는지 체크하는 함수 BOOL IsEmpty() const 버퍼가 비어있으면 true, 비어있지 않으면 false 반환 |
Empty() 함수 | 문자열을 삭제하여 버퍼를 비우는데 사용하는 함수 void Empty() |
모달 대화상자와 모덜리스 대화상자(부모 뷰에서 작업 가능 여부)
모달 대화상자
- 모달 대화상자는 출력되면 애플리케이션 내의 다른 윈도우에서 작업을 할 수 없습니다.
- -> 모달 대화상자를 닫아야 애플리케이션 내의 다른 윈도우에 포커스를 둘 수 있습니다.
- -> DoMadal() 함수를 이용해서 출력
모달리스 대화상자
- 모달리스 대화상자는 종료시키지 않아도 다른 윈도우에서 사용자가 작업을 계속 할 수 있습니다.
- 추가적인 정보 띄어두고 동시에 작업 ㄱㄴ
- 출력방식이 모달 대화상자보다 좀 더 복잡..
- 첫 째로 출력할 대화상자 클래스에 대한 변수 선언(객체 생성)-아무것도 구성 X
- Create() 함수를 이용해서 대화상자 만들기 인수는 대화상자 id=리소스에서 부여되는 ID, 부모 윈도우의 포인터(cwnd)-
- 두 번째로는 생성한 대화상자를 화면에 보여줘야하므로 ShowWindow(SW_SHOW)
공용 대화상자(모달 대화상자,DoMadal() 함수 사용)
- MFC에서 대부분 애플리케이션에 들어가는 공통적인 대화상자들을 클래스로 만들어 놓은 것이 공용 대화상자
- 파일 대화상자, 폰트 대화상자, 색상 대화상자 등이 있다.
1. 파일 대화상자
- 파일의 열기, 저장, 다른 이름으로 저장 동작할 때 사용되는 대화상자
- CFileDialog 클래스에 정의
//생성자 함수의 인수가 true일 때는 Open 대화상자 지젇, false일 때는 SaveAs 대화상자로 지정
//파일 대화상자의 객체 생성. 매개변수가 T이면 대화상자 열고, F이면 저장
CFileDialog pDlg(TRUE); //생성자 함수 호출
pDlg.DoMadal(); //대화상자 출력ㅊ
◼ CFileDialog의 생성자 함수
CFileDialog( //클래스
BOOL bOpenFileDialog, //오픈할지 세이브할지
LPCTSTR lpszDefExt = NULL, //확장자
LPCTSTR lpszFileName = NULL, //디폴트에 해당하는 파일명
DWORD dwFlags = OFN_HIDEREADONLY | //속성 정의하는 플래그
OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL, //검색에 사용할 필터
CWnd* pParentWnd = NULL //부모 윈도우 지정
);
//=이 있다는 것은 굳이 지정하지 않아도 된다는 것임.
//Open 대화상자 출력 예
char Filter[ ] = _T("Text File(*.txt) | *.txt| 모든 파일(*.*)|*.*|“);
//파일 대화상자 객체 생성 OPEN 파일 저장형태 =TXT
CFileDialog pDlg(TRUE, _T("text file(*.txt)", "*.txt“),
OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, Filter, NULL);
if(pDlg.DoModal() == IDOK) //대화상자 출력
{
data = pDlg.GetPathName(); //실제 파일의 경로 얻어와서 그때 가지고 있는 데이타 얻어옴
…
…
…
}
//Save 대화상자 출력 예
2023-04-17 S23-1/ Windows Programming 9
char Filter[ ] = _T("Text File(*.txt) | *.txt| 모든 파일(*.*)|*.*|“);
//파일 대화상자 객체 생성 SAVE 파일 저장형태 =TXT
CFileDialog pDlg(FALSE, _T("text file(*.txt)", "*.txt“),
OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, Filter, NULL);
if(pDlg.DoModal() == IDOK)
{
data = pDlg.GetPathName();
…
…
…
}
2. 폰트 대화상자
- 애플리케이션에서 사용되지만 주로 텍스트 기반의 애플리케이션에서 사용
- 텍스트의 글꼴이나 크기, 쿤자 속성 등을 지정할 수 있는 대화상자
- 해당 클래스는 CFontDialog
//폰트 대화상자 출력
//클래스로부터 객체 생성
CFontDialog fontDlg;
fontDlg.DoMadal(); //실제 오픈!
//목적은 지정한 폰트 읽어오는 것 -> 폰트 구조체로 받음
//폰트 대화상자는 파일 대화상자보다 훨씬 쉽게 동작
//사용자가 폰트 선택 -> 확인 버튼 누그면 폰트 받음
// 글꼴 설정
CFont font;
font.CreateFontIndirect(&logfont);
//DC의 글꼴 선택함으로써 글꼴 사용 ㄱㄴ
3. 색상 대화상자
- 사용자에 의해 색을 선택하는 공용 대화상자
- 해당 클래스는 CColorDialog
//DoModal() 함수를 통해 불러온 두 GetColor() 함수를 통해 선택된 색상 값 저장해서 사용
CColorDialog colorDlg; //객체 생성
if(colorDlg.DoMadal() ==IDOK) //
COLORREF m_color = colorDlg.GetColor(); //칼라를 선택했으면 그 색상을 실제로 받아옴
4. 실습 4-2 단위 변환 프로그램 만들기
모달 대화상자 + 모달리스 대화상자(단위 변환한 것 확인)
- 폼 구성
- 매개변수와 컨트롤 연결하기 (DDX 함수 사용)
- radio 버튼에 대한 메세지 핸들러 함수 추가하기-> 길이, 무게 비교할수 있는 변수 하나 만들고, 각각에 대해서 대화상자 화면 값들 초기화하고 UpdateData(FALSE)를 통해서 화면 갱신
- 값 변환하기 위한 함수 추가하기(//현재유닛, 변환될 유닛 클릿 후 현재 값 입력하면 변환된 값이 눈에 보이도록 해줌)
- EDIT CONTROL에 대한 명령 추가 ComputeUnitValue(); 넣어서 변환된 값으로 업데이트되도록 !!! -> 현재 값 입력하면 단위마다 변환된 값으로 출력됨
- 현재 값 입력 에디트 텍스트 ( ) -> 변한 값 에디트 텍스트 ( ) ( ) 바꿔주기 + 리스트 박스 위에 ( 리스트의 text) -> (리스트의 text ) 까지 !! 리스트 박스 선택된 것에 따라서 !! -> 원래 list 컨트롤에 (list box)에 대한 메시지 핸들러 함수 생성
- 왼쪽 리스트 박스와 오른쪽 리스트 박스 모두 해줘야 함 !
- 변하지 않는 부분은 static으로
- 변하는 부분은 edit control=사용자에 입력을 받거나 / 사용자에게 계속적으로 다른 부분을 보여줘야할 때(단위 선택하면 계속 다른 값 보여줌 = 읽기전용을 true로 !!
- 리스트와 에디트 컨트롤 모두 멤버 변수와 연결해야 됨
- 변환 부분만 숫자, 나머지는 문자형태의 변수와 ddx로 연결하기
- 라디오버튼은 사용자의 선택
- UPDATEDATA(FALSE):변수의 값-> 화면(컨트롤)
- updatedate(true):화면(컨트롤 ..에디트 컨트롤 등등)->변수의값
- 줄맞추기 기능도 있다.
- 라디오버튼 처음 그룹 true, 마지막은 false로 하면 하나의 묶음이라고 생각함.(같은 그룹으로 인식)
라디오 버튼에 따라 길이인지 무게인지 변경
'윈도우프로그래밍' 카테고리의 다른 글
[윈도우 프로그래밍 7장] 그래픽 객체의 사용 (0) | 2023.06.05 |
---|---|
[윈도우 프로그래밍 5장] 도큐먼트, 파일 입출력 (0) | 2023.06.05 |
[윈도우 프로그래밍] 윈도우 프로그래밍의 이해 (0) | 2023.04.16 |
[윈도우 프로그래밍] MFC 개요 및 아키텍처 (0) | 2023.04.16 |
[윈도우 프로그래밍] 메시지 처리 (0) | 2023.04.16 |