http://blog.naver.com/dsuniv_cjs
교수님 이메일 jschoi@ssu.ac.kr
3/14
리소스는 정적이거나 자주사용할 아이콘이나 그림 등???
OnDraw 는 뷰에 대한 객체가 변경이 되거나 하면 항상 실행을 하게되는 멤버함수
CClientDC dc(this);
CDC로부터 상속받은 클래스로서 출력장치의 자료구조를 정의하기 위해 사용
CDC에서 제공하는 DrawText()함수나 TextOut() 함수를 이용하여 화면에 문자열을 출력
3/21
OnNewDocument 창이 하나 뜰때마다 이 함수가 실행이 됨. (초기화가 진행이됨.)
GetDC(); 로 호출해놓고 releaseDC 안해주면 화면에 계속 남아있는듯
Release 안해주면 힙 메모리에 계속 남아있어서 메모리 누수가 발생.
3/28
2010에서 오류날때
text _T( ) 매칭시켜주는것으로 TCHAR( ) 로 쓰거나 _T 로 쓰는식으로 뭐 하면되는것같음
문자의 바이트수가 안맞아서 발생하는 문제라고 함.
DC = Device Context
CDC의 문제점을 해결한게 CClientDC 인듯 생성자에서 Get 을 자동으로 해주고
소멸자에서 Release 를 자동으로 해주는듯함.
선그리기
CPen 선언. -> Pen 의 속성값 부여, ->
메시지 종류
윈도우 메시지(Window Message)
WM_으로 시작하는 메시지로 매개 변수를 가지고 있어 메시지를 어떻게 처리할 것인지를 결정하는데 사용
(단, WM_COMMAND 메시지는 제외)
윈도우 관리 메시지, 초기화 메시지, 입력 메시지
제어통지 메시지(Control Notification Message)
제어 객체나 자식 윈도우에서 부모 윈도우로 보내는 메시지
부모 윈도우와 컨트롤 사이의 메시지 전달
명렁 메시지(Command Message)
메뉴, 툴 바, 액셀러레이터 키와 같은 사용자 인터페이스 객체로부터 발생되는 WM_COMMAND 메시지
예제4-2
nChar => 입력된 문자의 아스키코드값 인듯
4/4
void CMenunu1View::OnDraw(CDC* pDC)
{
CMenunu1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(dot==true)
{
CPen pen, *oldpen;//펜 객체 선언
pen.CreatePen(PS_SOLID, 3, RGB(255,0,0));//실선, 굵기1, 검은색 펜
oldpen = pDC->SelectObject(&pen); //펜 객체를 DC에 지정
pDC->MoveTo(10, 10); //선의 시작점
pDC->LineTo(100, 10); //선의 끝점
}
if(aot==true)
{
CPen pen, *oldpen;//펜 객체 선언
pen.CreatePen(PS_SOLID, 3, RGB(0,0,255));//실선, 굵기1, 검은색 펜
oldpen = pDC->SelectObject(&pen); //펜 객체를 DC에 지정
pDC->MoveTo(10, 10); //선의 시작점
pDC->LineTo(100, 10); //선의 끝점
}
}
void CMenunu1View::OnDraw(CDC* pDC)
{
CMenunu1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(dot==true)
{
CPen pen, *oldpen;//펜 객체 선언
pen.CreatePen(PS_SOLID, 3, RGB(255,0,0));//실선, 굵기1, 검은색 펜
oldpen = pDC->SelectObject(&pen); //펜 객체를 DC에 지정
pDC->MoveTo(10, 10); //선의 시작점
pDC->LineTo(100, 10); //선의 끝점
}
if(aot==true)
{
CPen pen, *oldpen;//펜 객체 선언
pen.CreatePen(PS_SOLID, 3, RGB(0,0,255));//실선, 굵기1, 검은색 펜
oldpen = pDC->SelectObject(&pen); //펜 객체를 DC에 지정
pDC->MoveTo(10, 10); //선의 시작점
pDC->LineTo(100, 10); //선의 끝점
}
}
void CMenunu1View::Onsjum()
{
// TODO: Add your command handler code here
dot = true;
aot = false;
Invalidate();
}
void CMenunu1View::Onssil()
{
// TODO: Add your command handler code here
aot = true;
dot = false;
Invalidate();
}
4/11
대화상자(Dialog Box) = 사용자와 프로그램간의 정보 교류를 위한 하나의 독립된 윈도우
SDI 형태의 프로그램
SDI의 CView 파생클래스는 윈도우가 처음 실행될 때 WM_PAINT 메시지가 발생하면 OnDraw함수를 호출
Dialog-based 프로그램
대화상자가 처음 생성될 때 윈도우 운영체제는 WM_INITDIALOG 메시지를 보내게 되는데 이때 호출되는 함수가 OnInitDialog 멤버함수
DDX(Dialog Data Exchange) 에서
컨트롤의 값을 변수로 전달할때는 UpdateData(TRUE)
변수값을 컨트롤러에 전달할때는 UpdateData(FALSE)
DDV(Dialog Data Validation)
유효성에 대한 검사를 변수 자체에서 해주는것.
edit 박스를 컨트롤 누른채로 더블클릭하면 변수 생성할수있음.
void CPersonDlg::OnButton1()
{
// TODO: Add your control notification handler code here
m_str_name = "홍길똥";
m_str_age = "21";
m_str_sex = "여성";
UpdateData(false);
}
void CPersonDlg::OnButton2()
{
// TODO: Add your control notification handler code here
m_str_name = "";
m_str_age = "";
m_str_sex = "";
UpdateData(false);
}
void CPersonDlg::OnButton3()
{
// TODO: Add your control notification handler code here
UpdateData(true);
m_str_name = m_str_inputName;
m_str_age = m_str_inputAge;
m_str_sex = m_str_inputSex;
UpdateData(false);
}
void CPersonDlg::OnButton5()
{
// TODO: Add your control notification handler code here
CEdit *ptrEdit;
ptrEdit = (CEdit *)GetDlgItem(IDC_EDIT8);
ptrEdit->SetWindowText("오큘러스가 사고싶어요...");
}
5/2
모 달 : 대화상자가 종료되기 전엔 다른 윈도우를 사용할 수 없음. 스택/힙 가능
모달리스 : 자식 윈도우가 활성화 되어 있어도 부모 윈도우 사용가능 힙만 가능
모 달 -> class -> DoModal( ) 헤더파일 사용.
모달리스 -> class -> create 클래스형 변수 변수화 하여 사용.
void CModal_dlgView::OnMenuCal()
{
// TODO: Add your command handler code here
CModalCal dlg;
dlg.DoModal();
}
이렇게만 하고 빌드하면 에러 4개 뜸 Cmodal 을 찾을수없다고.
이렇게 #include "ModalCal.h" 라고 만든 모달클래스 넣어주면 에러 사라짐.
chapter07.ppt 19p
void CModalCal::OnButtonOk()
{
// TODO: Add your control notification handler code here
CModal_dlgView *pView = (CModal_dlgView *) ((CMainFrame *)AfxGetMainWnd())->GetActiveView();
pView->m_sz_Result.Format("지금까지 모달 형태의 계산기 프로그램을 수행하였습니다.");
pView->Invalidate(TRUE);
OnOK();
}
((CMainFrame *)AfxGetMainWnd())->GetActiveView();
▶ c메인 프레임이 가진 메인윈도우의 핸들러를 얻어와서 그 안에있는 뷰에 접근해서 가져옴.
이제 헤더파일들 include 해줘야됨.
줠라어렵구만
visual 6.0 C++ 디버그 하는법
f9 로 브레이크 포인트를 만들고
f5 로 디버그를 시작하면 디버깅 상황이 어떤지 볼수 있음.
우측하단을 보면
변수명 추가하면 그 변수값이 뭔지 볼수있음.
5/9
폼뷰 싱글 다큐먼트로 만드는데 다이얼로그처럼 사용함
파일
CFileDialog fDlg(TRUE); 파일 열기
CFileDialog fDlg(FALSE); 파일 저장
CFileDialog fDlg(false,"txt", NULL, OFN_FILEMUSTEXIST, "Txt Files(*.txt)|*.txt|ALL Files(*,*)|*,*||",NULL);
이런식으로 뒤에 옵션값을 넣어주면 저장 형식을 지정해줄수 있음.
기본값으로 냅두면 .txt 로 만들어짐.
폰트
logfont 구조체 = 폰트의 구조체
5/16
복습함
5/23
버튼관련
void CADlg::OnButton1() // 등록
{
CRegKey reg;
if(reg.Create(HKEY_CURRENT_USER, "SOFTWARE\\PClick") != ERROR_SUCCESS)
{
MessageBox("등록 실패");
}
if(reg.Open(HKEY_CURRENT_USER, "SOFTWARE\\PClick") == ERROR_SUCCESS)
{
reg.SetValue("Path", "1" );
reg.Close();
MessageBox("등록 성공");
}
else
MessageBox("등록 실패");
}
void CADlg::OnButton2() // 읽기
{
CRegKey reg;
CString str;
DWORD dw = 1024;
if(reg.Open(HKEY_CURRENT_USER,"Software\\PClick") == ERROR_SUCCESS)
{
if(reg.QueryValue("Path", str.GetBuffer(dw), &dw) == ERROR_SUCCESS)
{
str.ReleaseBuffer();
reg.Close();
MessageBox(str);
}
reg.Close();
}
}
====@ 메뉴만들어서 클래스 위자드 간다음 dlg 에서 WMCONTEXTMENU 생성한 후 에디트코드로 아래입력
void CADlg::OnContextMenu(CWnd* pWnd, CPoint point)
{
CMenu popup;
CMenu* pMenu;
popup.LoadMenu(IDR_MENU1);
pMenu = popup.GetSubMenu(0);
CMenu mnuPopupSubmit;
mnuPopupSubmit.LoadMenu(IDR_MENU2); // 메뉴의 포인터 얻어오기
CButton *pButton;
pButton = reinterpret_cast<CButton *>(GetDlgItem(IDC_BUTTON1)); //버튼의 영역(크기) 구하기
CRect Button1;
pButton->GetWindowRect(&Button1); // 메뉴의 첫번째 아이템에 포인터 얻어오기
CMenu *mnuPopupMenu = mnuPopupSubmit.GetSubMenu(0);
ASSERT(mnuPopupMenu); // 사용자가 우클릭한 버튼이 어떤 것인가 알아내기
if(Button1.PtInRect(point))
{
mnuPopupMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x , point.y , this);
}
else
pMenu->TrackPopupMenu(TPM_LEFTALIGN || TPM_RIGHTBUTTON, point.x , point.y , this);
}
동적 버튼 생성
void CADlg::OnButton2() // 원래 버튼3 만들어서 하는건데 난 안되서 버튼2 를 수정했음
{
CString str;
for(int i = 0; i < 5; i++)
{
str.Format("Test %d", i + 1);
mp_test_button[i] = new CButton();
mp_test_button[i]->Create(str, WS_CHILD | WS_VISIBLE
| BS_PUSHBUTTON, CRect(10 + i*100, 10, 100 + i*100, 36),
this, 25000 + i);
}
}
동적 버튼 삭제
간단함
void CADlg::OnButton6()
{
// TODO: Add your control notification handler code here
for(int i=0;i<MAX_BUTTON_COUNT;i++)
{
delete mp_test_button[i];
}
}
5/30
트레이 아이콘
클래스 만들어주고
TrayIconDlgDlg.h 의 public 에
#define WM_DIALOG_SHOW WM_USER + 101
//다이얼로그감추기/보이기
#define WM_APP_EXIT WM_USER + 102
//다이얼로그종료
#define WM_TRAYICON WM_USER + 103
//트레이아이콘메시지
추가
CTrayIconMng 클래스 추가(기본 클래스 Cobject)
멤버변수 추가 // 트레이아이콘이생성되었는지여부 (True : 생성됨)
bool m_bAdded;
// 다이얼로그가감춰진상태인지여부 (True : 숨겨짐)
bool m_bHide;
// 팝업메뉴생성
TrayIconMng.h 의 pbulic 에
void MakePopupMenu(HWND hWnd, int x, int y);
// 팝업메뉴의이벤트발생시처리함수
void ProcTrayMsg(HWND hWnd, WPARAM wParam, LPARAM lParam);
// 트레이아이콘생성
bool AddTrayIcon(HWND hWnd);
// 트레이아이콘제거
bool DelTrayIcon(HWND hWnd);
추가
#define WM_DIALOG_SHOW WM_USER + 101
//다이얼로그감추기/보이기
#define WM_APP_EXIT WM_USER + 102
//다이얼로그종료
#define WM_TRAYICON WM_USER + 103
//트레이아이콘메시지
CTrayIconMng.cpp 에다 아래 소스코드 추가
void CTrayIconMng::MakePopupMenu(HWND hWnd, int x, int y)
{
HMENU hMenu = CreatePopupMenu();
if(m_bHide) //다이얼로그가 감춰진 상태라면
{
AppendMenu(hMenu, MF_STRING, WM_DIALOG_SHOW, "다이얼로그보이기");
}
else // 다이얼로그가 숨겨진 상태라면
{
AppendMenu(hMenu, MF_STRING, WM_DIALOG_SHOW, "다이얼로그감추기");
}
AppendMenu(hMenu, MF_STRING, WM_APP_EXIT, "종료");
SetForegroundWindow(hWnd); //생성된 팝업메뉴밖을 클릭할때 팝업닫기
TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, hWnd, NULL); //팝업
}
void CTrayIconMng::ProcTrayMsg(HWND hWnd, WPARAM wParam, LPARAM lParam) //팝업메뉴 이벤트 처리
{
HMENU hMenu = NULL;
POINT pos;
if(lParam == WM_LBUTTONDOWN)
{
GetCursorPos(&pos);
MakePopupMenu(hWnd, pos.x, pos.y); // 팝업 메뉴 생성 및 출력
}
}
bool CTrayIconMng::AddTrayIcon(HWND hWnd)
{
if(m_bAdded) //이미트레이아이콘이있다면종료
{return FALSE;}
NOTIFYICONDATA nid; //아이콘을생성하여설정
ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.uCallbackMessage = WM_TRAYICON;
sprintf((char*)nid.szTip, (char*)_T("TrayTest"));
nid.uID = 0;
nid.hIcon = theApp.LoadIcon(IDR_MAINFRAME);
if(Shell_NotifyIcon(NIM_ADD, &nid)==0) //트레이아이콘표시
{return FALSE;}
m_bAdded = true;
return TRUE;
}
bool CTrayIconMng::DelTrayIcon(HWND hWnd)
{
NOTIFYICONDATA nid;
ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uFlags = NULL;
if(Shell_NotifyIcon(NIM_DELETE, &nid)==0) //트레이아이콘삭제
{
return FALSE;
}
return TRUE;
}
6.0 에선 여기까지 했을때 theApp 에러남
TrayIconDlg.h 에서 맨 아랫부분 아래와 같이 추가
DECLARE_MESSAGE_MAP()
};
extern CTrayIconDlgApp theApp;
TrayIconDlgDlg.cpp 클래스에 헤더 추가
#include “TrayIconMng.h”
TrayIconDlgDlg 클래스 멤버변수 추가
CTrayIconMng m_myTray;
bool m_bHide;
TrayIconDlgDlg.h 클래스 멤버함수 추가
long OnTrayIcon(WPARAM wParam, LPARAM lParam);
void OnAppExit(void);
void OnDialogShow(void);
TrayIconDlgDlg.cpp OninitDialog() 마지막부분 (return TRUE; 전) 에 추가
m_myTray.m_bHide = m_bHide;
m_myTray.AddTrayIcon(GetSafeHwnd());
TrayIconDlgDlg.cpp 여기 BEGIN_MESSAGE_MAP(CTrayIconDlgDlg, CDialog) 안에
ON_MESSAGE(WM_TRAYICON, OnTrayIcon)
ON_COMMAND(WM_APP_EXIT, OnAppExit)
ON_COMMAND(WM_DIALOG_SHOW, OnDialogShow)
그리고 맨 아랫부분에
long CTrayIconDlgDlg::OnTrayIcon(WPARAM wParam, LPARAM lParam)
{
m_myTray.ProcTrayMsg(GetSafeHwnd(), wParam, lParam);
return 0;
}
void CTrayIconDlgDlg::OnAppExit(void)
{
m_myTray.DelTrayIcon(GetSafeHwnd());
CDialog::OnCancel();
}
void CTrayIconDlgDlg::OnDialogShow(void)
{
if(!m_bHide) ShowWindow(false); //보이는 상태라면 숨기고
else ShowWindow(true); //숨겨진 상태라면 보이게
m_bHide = !m_bHide;
m_myTray.m_bHide = m_bHide;
}
소스코드 추가
기말고사 범위
6장 ddx, ddv 부터
7장 모달, 모달리스, 폼뷰
8장 공통 다이얼로그 (공통 대화상자) 파일 불러오기, 쓰기, 폰트 변경하기, (컬러는 이론적인것만 코드는안냄)
etc 레지스터, 팝업메뉴, 동적생성
예제 안한거 안나온다고 함.
7장 19p 빨간색 2줄 안나옴. 인터넷 검색해서 쓰라고함.
7장 31p 폼뷰 계층도 COBject CWnd CView CFormView 폼뷰는 싱글도큐먼트를 이용하니
CView 밑에 생성됨?
레지스트 코드는 않나와도 이론적인건 나오는듯 함.