11 주차 비트맵버튼 & 폰트 그래픽객체의사용
This week, we will study Button 에사용자 graphic image를넣는방법 Edit box의색상변경방법 폰트의종류변경, 폰트크기 / 속성변경방법 Graphic object
비트맵버튼의생성 버튼이미지를준비 사용할버튼의크기에적합한이미지를준비. 일반적으로.BMP 이미지파일을사용. Ex) Resource 에 Bitmap 을추가 Resource View에서 Dialog 선택 Add resource 후 bitmap 선택 비트맵이미지파일 (.BMP) 을선택 Bitmap resource ID 변경
비트맵 resource 를넣기 2. Dialog 선택후마우스오른쪽버튼누름 - > Add resource 선택 3. Bitmap 선택 4. Import 선택후원하는 BMP 파일을선택함. 1. Resource Tab 선택
비트맵 resource 의이름지정 리소스이름을 IDB_BITMAP_BUTTON1 으로지정함.
Button 의속성변경 1. 다이얼로그박스선택 2. 해당버튼선택 3. 속성중 Owner Draw 를 True 로변경
Button 과연결된변수설정 1. 해당버튼선택후마우스오른쪽버튼을눌러 변수추가 를선택 2. 변수이름지정 3. Category 는 Control 4. 마지막으로 Finish 눌러종료
Header file 변경 2. Dialog 헤더파일선택 3. 이부분을 CBitmapButton m_bt 로변경함 1. Solution Tab 선택
소스코드변경 : 초기화부분 1. 소스파일선택 2. OnInitDialog() 함수에이부분을추가
실행화면
출력문자열의 Font 의변경 1 1. 헤더파일선택 2. public class 에폰트제어변수추가
Font 변경 1. 소스코드선택 2. OnInitDialog() 함수에이부분을추가 변경한폰트가표시되는 Edit 창의연결변수 BOOL CFont::CreateFont( int nheight, int nwidth, int nescapement, int norientation, int nweight, BYTE bitalic, BYTE bunderline, BYTE cstrikeout, BYTE ncharset, BYTE noutprecision, BYTE nclipprecision, BYTE nquality, BYTE npitchandfamily, LPCTSTR lpszfacename );
실행화면
GDI 의개념 Graphic Device Interface 윈도우가하드웨어를제어할수있도록응용프로그램에제공하는모든기능 응용프로그램과디바이스드라이버의중간역할 응용프로그램에대한장치독립적인그래픽동작수행
Device Context(DC) 의개념 일종의핸들 애플리케이션과출력장치를연결하는역할 애플리케이션이출력에대한허가를얻고, 또한그려지는영역을결정하는역할 GDI 에의해내부적으로유지되는데이터구조 여러가지그래픽속성에대한값을가짐 Ex) 텍스트속성 / 색상, 매핑모드, 글꼴 DC 를사용하는이유 독립적인하드웨어출력을할수있어출력장치에상관없이동일한방법으로출력을설정 DC 를얻고나면, 반드시작업완료시해제한다
DC 를얻는방법 (1) 1 2 3 4 4 가지 DC 를얻는방법 OnDraw() 함수, OnPaint() 함수를이용 GetDC() 함수를이용 CClientDC 클래스를이용 CWindowDC 클래스를이용
DC 를얻는방법 (2) 1 OnDraw() 함수, OnPaint() 함수를이용 OnDraw() 함수의인자 CDC 오브젝트 Void CPractice6_1View:: OnDraw(CDC * pdc) { } OnPaint() 함수내의 CPaintDC 오브젝트 Void CPractice6_1View::OnPaint() { CPaintDC dc(this) } 윈도우나클라이언트영역이다시그려져야할경우수행 DC의해제는 MFC 내부코드에존재한다.
DC 를얻는방법 (3) 2 GetDC() 함수를이용 이함수의포인터반환값을받아서사용 ReleaseDC() 함수를호출하여반드시해제 사용예 CDC *pdc = GetDC(); ReleaseDC(pDC); 이방법으로 DC 를얻는것은일시적인것으로윈도우의크기가변하면출력한내용이사라진다.
DC 를얻는방법 (4) 3 CClientDC 클래스를이용 CClientDC 는 CDC 클래스의파생클래스 Device Context의생성 / 해제자동적수행 생성자함수에서 GetDC() 함수를호출 소멸자함수에서 ReleaseDC() 함수를호출윈도우에대한핸들값이필요일시적으로윈도우의클라이언트영역에서그래픽개체를사용할경우에이용사용예 CClientDC dc(this)
DC 를얻는방법 (5) 4 CWindowDC 클래스를이용 윈도우 ( 프레임 ) 영역에그래픽요소를출력하고자할때사용한다. GetWindowDC() 함수를이용하여 CWindowDC 클래스의인스턴스를포인터형태로넘겨받아이용작업수행후, ReleaseDC() 함수로해제사용예 CWindowDC *pdc = GetWindowDC(); ReleaseDC();
GDI 객체 GDI 기본구성요소 선과곡선 (Lines and Curves) 직선, 사각형, 타원, 호, 베지어곡선 채워진영역 (Filled Areas) 브러시개체를이용 색상, 패턴, 비트맵이미지 비트맵 (Bitmaps) 디스플레이장치의픽셀과일치하는직사각형배열 래스터그래픽의기본적인도구 텍스트 (Text)
GDI 객체 화면에그래픽출력하기위한요소 GDI 객체 GDI 객체클래스기본값사용용도 펜 CPen 검정색, 실선, 1 픽셀크기 점, 선, 테두리 브러시 CBrush 무늬없는흰색내부 ( 영역 ) 채우기 폰트 CFont 시스템폰트문자의폰트 비트맵 CBitmap 없음비트맵출력 영역 CRgn 없음 영역만들기, 변경하기 팔레트 CPalette 없음팔레트조작
GDI 객체 객체를사용하는방법 1 GDI 객체를생성 객체클래스의 Create 계열함수이용 2 객체를 DC 에등록 SelectObject() 함수를이용 기존설정된객체는포인터로저장 3 DC 를사용하여그래픽출력 4 이전객체로환원 5 객체를삭제 DeleteObject() 함수이용
GDI 객체 펜 (Pen) 선이나영역의경계선을그릴때사용 선의두께, 선이색상, 선의스타일을설정 펜을사용하는방법 1 CPen pen *oldpen pen.createpen(ps_solid, 1,RGB(0,0,0)); 2 oldpen = pdc >SelectObject(&pen); 3 pdc >Ellipse(0,0,10,10); 4 pdc >SelectObject(oldpen); 5 pen.deleteobject();
GDI 객체 CreatePen() 함수 CreatePen() 함수는 Pen 을생성하는함수로원형은다음과같다. BOOL CreatePen(int npenstyle, int nwidth, COLORREF crcolor); npenstyle : 펜의스타일 nwidth : 펜의굵기 crcolor : 펜의색상
GDI 객체 펜의스타일 펜의스타일내용모양 PS_SOLID PS_DASH PS_DOT PS_DASHDOT PS_DASHDOTDOT PS_NULL 실선파선점선일점쇄선이점쇄선선을그리지않음
GDI 객체 브러시 (Brush) 영역의내부를채울때사용 채울색, 패턴등이사용 브러시를사용하는방법 1 CBrush brush *oldbrush brush.createsolidbrush(rgb(0,0,0)); bush.createhatchbrush(hs_cross,rgb(0,0,0)); 2 oldbrush = pdc >SelectObject(&brush); 3 pdc >Ellipse(0,0,10,10); 4 pdc >SelectObject(oldbrush); 5 brush.deleteobject();
GDI 객체 CreateSolidBrush() 함수 단일색으로칠하는브러시를생성하는함수 CreateHatchBrush() 함수 일정한패턴을가진해치브러시를생성하는함수. 해치브러쉬의스타일 해치브러시의스타일내용모양 HS_BDIAGONAL HS_CROSS HS_DIAGCROSS HS_FDIAGONAL HS_HORIZONTAL HS_VERTICAL 오른쪽에서왼쪽으로 45도내려가는빗금십자가형태의빗금 X자형태의빗금왼쪽에서오른쪽으로 45도내려가는빗금수평으로빗금수직으로빗금
그래픽함수 선그리기 MoveTo(int x, int y) 함수 LineTo(int x, int y) 함수 사각형그리기 Rectangle(int x1, int y1, int x2, int y2) 원그리기 Ellipse(int x1, int y1, int x2, int y2) 다각형그리기 Polyline(LPPOINT lppoints, int ncount) Polygon(LPPOINT lppoints, int ncount) 베지어곡선그리기 PolyBezier(const POINT* lppoints, int ncount)
대화상자에그림을그리기위한준비 > picture control toolbox Toolbox 에서 Picture control 선택 - >IDC_STATIC_CANVAS 로 ID 지정
OnPaint() 함수에 GDI 객체를추가 Picture control 화면을회색바탕으로칠하고적색사각형을그림.
실행화면
GDI example 설명 CClientDC plot(this); Parent window 의 DC(Device Context) 를얻어옴. CRect r; 그림을그리고자하는 picture control창의크기를얻기위한변수선언 GetDlgItem(IDC_STATIC_CANVAS)->GetWindowRect(r); IDC_STATIC_CANVAS의화면상의스크린좌표를얻음 ScreenToClient(r); IDC_STATIC_CANVAS의윈도우클라이언트좌표를얻음. CBrush br; 화면을채우기위한붓 (brush) 을선언 br.createsolidbrush(rgb(220,220,220)); 화면을채우기위한붓 (brush) 을생성 plot.fillrect(r,&br); 생성한붓 (brush) 으로 IDC_STATIC_CANVAS 영역을칠함. CPen penr; 화면을그리기위한펜 (pen) 을선언 penr.createpen(ps_solid,3,rgb(255,0,0)); 화면을그리기위한펜 (pen) 을생성 plot.selectobject(&penr); 생성된펜으로그리기위해해당펜을선택함. 사각형을그림. plot.rectangle(r.left+100,r.top+100,r.right-100,r.bottom-100);
선그리기, 텍스트출력 3 가지 pen 을준비함 ( 적, 청, 녹 ) 녹색펜으로선을그림 적색펜으로사각형을그림 청색펜으로원을그림 화면중앙에 TEST GDI 를출력함.
실행화면
간단한그래픽에디터의제작 1 적색값을넣는창 (Toolbox: Edit control, IDC_EDIT_RED, m_red) 녹색값을넣는창 (Toolbox: Edit control, IDC_EDIT_GREEN, m_green) 청색값을넣는창 (Toolbox: Edit control, IDC_EDIT_BLUE, m_blue) 어떤종류의도형을그릴것인지사용자가선택하는콤보박스 (Toolbox: Combo box, IDC_COMBO_SEL, m_sel) 결과가출력되는화면창 (Toolbox: Picture control, IDC_STATIC_CANVAS) 마우스의오른쪽버튼을누르면현재마우스위치의좌표 (x1, y1) 를저장하고왼쪽버튼을누르면현재마우스좌표 (x2, y2) 를저장하여좌표 (x1, y1) 과좌표 (x2, y2) 를대각선으로갖는사각형, 원, 직선을그림
간단한그래픽에디터의제작 2 변수선언부분, 3 가지도형 ( 사각형, 원, 직선 ) 을사용자가선택하여그릴수있도록준비.
간단한그래픽에디터의제작 3 R/G/B 3 가지값에대한초기값설정 메뉴항목의이름을넣고, 초기화
간단한그래픽에디터의제작 4 응용프로그램이처음시작될때만바탕을칠함. OnPaint 함수의 else 부분에추가 도형을그릴펜을준비, 적 / 청 / 녹에대한각각의값을에디트창에서받아정수값으로변환. 적 / 청 / 녹값에해당하는펜생성현재콤보박스의값을읽음. 사각형을그림 원을그림 선을그림
마우스관련핸들러설정
실행화면
비트맵 CBitmap클래스를이용하는객체로비트맵을생성하거나읽어서비트맵을출력할때사용 비트맵의래스터오퍼레이션 SRCCOPY : 배경그림무시하고비트맵출력 SRCAND : 배경그림과 AND 연산 SRCPAINT : 배경그림과 OR 연산
비트맵을사용하는방법 1 화면 DC 와메모리 DC 를생성 CClinetDC dc(this); CDC memdc; 2 화면 DC 와호환성을갖는 DC 를만든다. memdc.createcompatibledc(&dc); 3 비트맵을읽어온다 CBitmap bitmap, *oldbitmap; bitmap.loadbitmap(idb_bitmap1); 4 메모리 DC 에비트맵을설정한다. oldbitmap = memdc.selectobject(&bitmap); 5 비트맵블록을전송한다. dc.bitblt(0, 0, 450, 85, &memdc, 0, 0, SRCCOPY); 6 DC 를복원한다. memdc.selectobject(oldbitmap);
비트맵사용법실습 1) 리소스에비트맵을등록한다. 리소스로부터비트맵을읽어와화면에출력하려면리소스에비트맵이등록되어있어야한다. 2) OnDraw() 함수에비트맵을출력할코드를입력한다. 먼저호환성있는메모리 DC 를생성하고리소스에서비트맵을읽어메모리 DC 에비트맵을설정한다음비트맵출력모드에따라비트맵을출력한다. 3) 프로그램을실행시켜본다.
SDI 에서비트맵리소스추가 Step3 비트맵노드속성창에서 ID 를 IDB_BITMAP_MOZART 로한다. Step2 Bitmap 선택후해당비트맵파일을 import 한다. Step1 리소스뷰 ->.rc 를선택하여마우스오른쪽버튼눌러 리소스추가 선택
비트맵출력코드추가
실행결과
CDC::BitBlt() 함수 비트맵객체를참조하는그래픽함수로서어떤 DC 에서다른 DC로비트맵블록을전송하는함수 BOOL CDC::BitBlt(int x, int y, int nwidth, int nheight, CDC *psrcdc, int nxsrc, int nysrc, DWORD dwrop) x, y: 출력할와면의 x, y 위치 nwidth, nheight: 화면에출력할비트맵의가로 / 세로크기 psrcdc: 비트맵을전송할소스 DC의포인터 nxsrc, nysrc: 소스비트맵에서전송할 DC의시작X, Y 위치 dwrop: 래스트오퍼레이션코드
CDC::StretchBlt() 함수 비트맵객체를참조하는그래픽함수로서어떤 DC 에서다른 DC 로비트맵블록을전송하되확대또는축소를해서전송하는함수 BOOL CDC::BitBlt(int x, int y, int nwidth, int nheight, CDC *psrcdc, int nxsrc, int nysrc, int nwidthsrc, int nheightsrc, DWORD dwrop) x, y: 출력할와면의 x, y 위치 nwidth, nheight: 화면에출력할비트맵의가로 / 세로크기 psrcdc: 비트맵을전송할소스 DC 의포인터 nxsrc, nysrc: 소스비트맵에서전송할 DC 의시작 X, Y 위치 nwidthsrc, nheightsrc: 소스비트맵의가로 / 세로크기 dwrop: 래스트오퍼레이션코드
Weekly project GDI를사용하여화면에 sinewave를그리는프로그램을작성하시오. Sinewave의주기와크기, 위상등은사용자가 edit control box를이용하여입력할수있도록작성할것. 지난주에작성한 database 관리프로그램에서항목별로입력한값이막대그래프형식으로출력될수있는기능을추가하시오.