baøi taäp chương 1 - tài liệu học...
TRANSCRIPT
TH Lập trình Windows Chương 1-2
Baøi taäp chương 1
1. Viết chương trình hiển thị màn hình như sau:
Hướng dẫn:
1/9
TH Lập trình Windows Chương 1-2
2/9
TH Lập trình Windows Chương 1-2
3/9
TH Lập trình Windows Chương 1-2
4/9
TH Lập trình Windows Chương 1-2
2. Từ chương trình câu 1, thay đổi một số thuộc tính của cửa sổ lần lượt như sau:
5/9
TH Lập trình Windows Chương 1-2
- 3. Lần lượt thay đổi trạng thái cửa sổ như sau:
• Nằm ở giữa màn hình, kích thước 640x480 • Luôn nằm trên các cửa sổ khác . • Không thể thay đổi kích thước • Cửa sổ phóng to đầy màn hình
Gợi ý: sử dụng các hàm thuộc lớp CWnd: Create, ShowWindow, SetWindowPos
Baøi taäp chương 2
1. Bài 1
6/9
TH Lập trình Windows Chương 1-2
Gợi ý: - Sử dụng hàm GetClientRect để lấy kích thước vùng Client - Chia vùng Client thành 4 phần bằng nhau, mỗi phần là một hình chữ nhật - Sử dụng các đối tượng CPen, CBrush và các hàm Ellipse, Chord, Pie, RoundRect,
SetTextColor, SetBkMode, DrawText Ví dụ: hàm vẽ Ellipse:
7/9
TH Lập trình Windows Chương 1-2
2. Bài 2
Gợi ý:
- Tính kích thước bitmap, mỗi ảnh sau có kích thước gấp 2 lần ảnh trước - Sử dụng hàm BitBlt và StretchBlt.
8/9
TH Lập trình Windows Chương 1-2
3. Bài 3
9/9
TH Lập trình Windows Chương 3
Baøi taäp chương 3
1. Dùng MFC AppWizard xây dựng ứng dụng sau: Chuỗi Hello!MFC có thể chuyển động theo các phương:
- Sang trái : khi nhấn phím ← - Sang phải: khi nhấn phím → - Đi lên: khi nhấn phím ↑ - Đi xuống: khi nhấn phím ↓ - Phím S: Start – Stop chuyển động
Gợi ý:
- Sử dụng MDC và các hàm LoadBitmap, StretchBlt để load ảnh nền. - Tạo font chữ, sử dụng các hàm SetTextColor, DrawText để xuất chuỗi
Hello!MFC - Chuỗi Hello!MFC nằm trong một frame hình chữ nhật (CRect). Để thay đổi vị trí
chuỗi, chỉ cần di chuyển frame. Chú ý: Để tính toán kích thước frame trên, sử dụng hàm GetTextMetrics kết hợp với độ dài chuỗi.
- Khai báo hàm xử lý sự kiện WM_TIMER. Trong hàm OnTimer, cập nhật lại vị trí frame tuỳ theo chiều di chuyển đang được chọn
- Khai báo hàm xử lý sự kiện WM_KEYDOWN. Trong hàm OnKeyDown, cập nhật lại chiều chuyển động dựa vào giá trị các phím được nhấn
1/7
TH Lập trình Windows Chương 3
Ví dụ: - Khai báo các biến thuộc lớp CChildView:
- Tạo MDC:
- Load ảnh nền:
- Tính kích thước và vị trí frame chứa chuỗi Hello!MFC:
2/7
TH Lập trình Windows Chương 3
- Xử lý sự kiện nhấn phím:
- Xử lý sự kiện WM_TIMER:
3/7
TH Lập trình Windows Chương 3
2. Dùng MFC AppWizard xây dựng ứng dụng vẽ tự do như sau:
Yêu cầu:
- Giữ chuột trái rê vẽ tự do - Khi nhấn một trong các phím:
o ‘R’, ‘G’, ‘B’: nét vẽ chuyển sang màu tượng ứng (Red, Green, Blue) o Phím ‘A’, ‘C’: thay đổi con trỏ chuột (tùy ý), phím ‘E’: về dạng mặc định o Phím ↑, ↓: thay đổi độ dày nét vẽ ( 1 ≤ nét vẽ ≤ 20) o Phím Delete: xóa màn hình
- Khi click chuột trên thanh tiêu đề: thay đổi tiêu đề cửa sổ
Gợi ý: - Để thực hiện được thao tác vẽ, sử dụng các hàm xử lý sự kiện nhấn chuột
(WM_LBUTTONDOWN) để bắt đầu chọn vị trí vẽ và di chuyển chuột (WM_MOUSEMOVE ) thực hiện thao tác vẽ.
4/7
TH Lập trình Windows Chương 3
- Thay đổi con trỏ chuột và độ dày nét vẽ thực hiện trong hàm OnKeyDown - Để thay đổi tiêu đề khi click trên thanh tiêu đề cửa sổ, xử lý sự kiện
WM_NCLBUTTONDOWN của lớp CmainFrame Ví dụ: Trong lớp CChildView, khai báo các biến, các hàm và viết code cho các hàm: // CChildView.h
//Hàm thay đổi con trỏ chuột
//Nhấn nút trái chuột
//Di chuyển chuột
5/7
TH Lập trình Windows Chương 3
//Nhấn phím
//Thay đổi con trỏ chuột
6/7
TH Lập trình Windows Chương 3
//Nhấn nút trái chuột ngoài vùng client
7/7
TH Lập trình Windows Chương 4
Baøi taäp chương 4
Duøng MFC AppWizard xaây döïng öùng duïng veõ caùc ñoaïn thaúng nhö sau:
Yeâu caàu: Duøng chuoät reâ veõ caùc ñoaïn thaúng, cho pheùp löu vaøo file coù teân Lines.dat
- Chuùc naêng baøn phím: Thay ñoåi maøu veõ:
Phím R: ñoû Phím G: maøu xanh laù Phím B: maøu xanh döông
Löu vaøo file: phím S Load töø file: phím L Xoaù maøn hình: phím C
Gợi ý: Xây dựng lớp CLine kế thừ từ CObject:
1/2
TH Lập trình Windows Chương 4
Định nghĩa hàm Serialize:
Trong lớp CChildView , khai báo danh sách các đối tượng CLine: CArray <CLine*,CLine*> m_arrLines;
Để vẽ một đoạn thẳng, sử dụng các hàm xử lý sự kiện: - Nhấn chuột (WM_LBUTTONDOWN): xác định hai điểm của đoạn thẳng,
đưa đoạn thẳng vào danh sách m_arrLines. - Di chuyển chuột (WM_MOUSEMOVE ): cập nhật vị trí điểm thứ hai của
đoạn thẳng và thực hiện thao tác vẽ. - Nhả chuột (WM_LBUTTONUP): kết thúc thao tác vẽ đoạn thẳng.
Để lưu và load danh sách các đoạn thẳng đã vẽ, trong lớp CChildView, khai báo và định nghĩa hàm Serialize:
2/2
THỰC HÀNH BÀI DRAWS
PHẦN I:
1) Tạo ứng dụng SDI:
2) Tạo class CShape
Trong file Shape.h, khai báo marco và các biến như sau:
Khai báo hàm Draw:
Định nghĩa hàm Draw:
void CShape::Draw(CDC *pDC)
{
CBrush br (clrBkColor);
CBrush *pOldBr = pDC->SelectObject(&br);
CPen pen(PS_SOLID, nPenWidth, clrBorderColor);
CPen *pOldPen =pDC->SelectObject(&pen);
switch (nShape)
{
case 0://ve doan thang
pDC->MoveTo(pLeftTop);
pDC->LineTo(pRightBottom);
break;
case 1://ve ellipse
pDC-> Ellipse (pLeftTop.x, pLeftTop.y, pRightBottom.x,
pRightBottom.y);
break;
case 2://ve hinh chu nhat
pDC-> Rectangle (pLeftTop.x, pLeftTop.y, pRightBottom.x,
pRightBottom.y);
break;
}
pDC->SelectObject(pOldBr);
pDC->SelectObject(pOldPen);
br.DeleteObject();
pen.DeleteObject();
}
Khai báo hàm ảo Serialize:
Bổ sung marcro IMPLEMENT_SERIAL(CShape, CObject,1)trên
hàm Serialize và định nghĩa hàm này như sau:
IMPLEMENT_SERIAL(CShape, CObject,1)
void CShape::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{ // storing code (luu du lieu)
ar << nShape << clrBkColor << clrBorderColor << nPenWidth <<
pLeftTop << pRightBottom;
}
else
{ // loading code (load du lieu)
ar >> nShape >> clrBkColor >> clrBorderColor >> nPenWidth >>
pLeftTop >> pRightBottom;
}
}
3) Trong class CDrawsDoc, khai báo các biến:
Trong hàm Serialize của lớp CDrawsDoc, bổ sung đoạn code
sau:
Trong hàm OnNewDocument, khởi tạo giá trị ban đầu cho các
biến:
4) Chuyển sang class CDrawsView, khai báo các biến:
Tạo hàm xử lý sự kiện WM_CREATE:
Trong hàm OnCreate, tạo memdc:
Trong hàm OnDraw:
Tạo hàm xử lý sự kiện WM_LBUTTONDOWN:
Tạo hàm xử lý sự kiện WM_MOUSEMOVE:
Tạo hàm xử lý sự kiện WM_ERASEBKGND, chặn sự kiện xóa
view:
Chạy thử ứng dụng, dùng chuột vẽ các ellipse màu đỏ, đóng
và save thành file
Mở lại ứng dụng, mở file đã lưu, xem kết quả.
PHẦN II: Bổ sung Dialog option cho phép lựa chọn các thuộc tính
vẽ
1) Bổ sung hộp thoại Option dialog: Trong tab Resource view,
click phải trên mục Dialog:
Thiết kế hộp thoại như sau:
Double click vào vùng trống trên hộp thoại, tạo class gắn
với hộp thoại như sau:
2) Tạo class CColorStatic kế thừa từ class CStatic để hiển thị
màu chữ, màu nền cho đối tượng Static:
Để thấy được class mới tạo trong cửa sổ Class View, khai
báo file tiêu đề colorstatic.h trên phần khai báo lớp
COptionDlg như sau:
Trong class CColorStatic, khai báo các biến sau:
Tạo hai hàm SetBkColor và SetTextColornhư sau:
Viết code cho hai hàm vừa tạo:
Tạo hàm xử lý sự kiện =WM_CTRLCOLOR:
Viết code cho hàm vừa tạo:
3) Khai báo các biến cho các control trên hộp thoại Options:
4) Chuyển sang tab ResourceView, chọn Menu IDR_MAINFRAME, bổ
sung thêm menu Tools, Options:
Click phải trên menu Options:
5) Trong class COptionDlg, khai báo các biến sau:
Thêm hàm ảo OnInitDialog vào class COptionDlg:
Tạo hàm xử lý sự kiện cho hai control Static:
Thiêt lập thuộc tính Notify cho hai control Static này là
True:
Viết code cho hai hàm xử lý sự kiện vừa tạo:
6) Cuộn lên trên đầu file CDrawsDoc.cpp, khai báo tiêu đề file
“OptionDlg.h”:
Viết code xử lý sự kiện menu:
Kết thúc
TH Lập trình Windows chương 5 Dialog - Controls
HÖÔÙNG DAÃN THÖÏC HAØNH CHÖÔNG 5
2 Dialog vaø caùc Controls
2.1 Baøi taäp 1 (FontView) Böôùc 1: Tạo project (Dialog base), thieát keá giao dieän theo yeâu caàu
Böôùc 2: Khai baùo caùc bieán thaønh vieân öùng vôùi caùc controls :
Loaïi control ID Caption Bieán ñoái töôïng ComboBox IDC_COMBOSIZE m_cbSize
ListBox IDC_LIST_FONT m_lbFonts Editbox IDC_CONTENT m_editContent
CheckBox IDC_CHECK_TRUETYPE m_chkCheckbox CheckBox IDC_B m_chkB CheckBox IDC_I m_chkI CheckBox IDC_U m_chkU
Static IDC_STATIC_FONTVIEW m_staticFontView
1/19
TH Lập trình Windows chương 5 Dialog - Controls
Böôùc 3: Taïo menu:
Böôùc 4: Khai baùo vaø ñònh nghóa haøm xöû lyù font : int CALLBACK EnumFontfamProc (LPENUMLOGFONT lpelf, LPNEWTEXTMETRIC lpntm, DWORD nFonttype, long lParam);
Böôùc 5: Trong lôùp CFontViewDlg, khai baùo vaø ñònh nghóa caùc haøm
2/19
TH Lập trình Windows chương 5 Dialog - Controls
//Haøm lieät keâ vaø hieån thò font
//Haøm taïo vaø choïn font döïa vaøo caùc löïa choïn
3/19
TH Lập trình Windows chương 5 Dialog - Controls
//Haøm kieåm tra coù ñoaïn vaên baûn naøo ñang ñöôïc choïn trong EditBox
//Haøm caäp nhaät traïng thaùi menu
4/19
TH Lập trình Windows chương 5 Dialog - Controls
//Taïo danh saùch caùc côõ chöõ trong ComboBox
Böôùc 5: Trong lôùp CFontViewDlg, khai baùo vaø ñònh nghóa caùc haøm xöû lyù söï kieän //Trong OnInitDialog
// Thay ñoåi löïa choïn font trong ListBox
//Check – uncheck ComboBox True Type
5/19
TH Lập trình Windows chương 5 Dialog - Controls
// Söï kieän töø menu
6/19
TH Lập trình Windows chương 5 Dialog - Controls
//söï kieän click vaøo menu -> caäp nhaät traïng thaùi menu
//Xöû lyù söï kieän phím
//Check – uncheck caùc CheckBox B, I, U
//Thay ñoåi löïa choïn treân ComboBox Size
7/19
TH Lập trình Windows chương 5 Dialog - Controls
2.2 Baøi taäp 2 (ColorText) Böôùc 1: Tạo project (Dialog base), thieát keá giao dieän theo yeâu caàu
Böôùc 2: Taïo caùc lôùp CColorStatic keá thöøa töø lôùp cô sôû CStatic vaø CiconListBox keá thöøa töø lôùp cô sôû CListBox (xem trong slides) Böôùc 3: Trong lôùp CcolorTextDlg khai baùo caùc bieán :
Böôùc 4: Khai baùo caùc bieán thaønh vieân öùng vôùi caùc controls :
Loaïi control ID Caption Bieán ñoái töôïng CColorStatic IDC_STATIC_TEXT Advanced
Control Programming
m_staticText
CIconListBox IDC_LIST_ICON m_lbIcon Böôùc 5: Khai baùo caùc vaø ñònh nghóa caùc haøm xöû lyù söï kieän : //Trong OnInitDialog
8/19
TH Lập trình Windows chương 5 Dialog - Controls
//Trong OnPaint
// Caùc söï kieän töø Radio Button, ListBox
9/19
TH Lập trình Windows chương 5 Dialog - Controls
10/19
TH Lập trình Windows chương 5 Dialog - Controls
2.3 Baøi taäp 3 (SampleEditor) Böôùc 1: Tạo project (Dialog base), thieát keá giao dieän theo yeâu caàu
ListBox
EditBox
CheckBox
ComboBo
11/19
TH Lập trình Windows chương 5 Dialog - Controls
Böôùc 2: Xaây döïng caùc lôùp ñaùp öùng yeâu caàu thieát keá giao dieän • ComboBox hieån thò maøu saéc:
12/19
TH Lập trình Windows chương 5 Dialog - Controls
• ListBox hieån thò maøu cho text: Taïo lôùp CColorListBox keá thöøa töø lôùp cô sôû CListBox: File ColorListbox.h
…
…
File ColorListbox.cpp // //Theâm moät chuoãi vaøo ListBox vôùi maøu text laø cColor
// Thieát laäp kích thöôùc cho moãi item
13/19
TH Lập trình Windows chương 5 Dialog - Controls
// Veõ laïi ListBox
14/19
TH Lập trình Windows chương 5 Dialog - Controls
• Lôùp CEditColor : keá thöøa töø lôùp cô sôû CEdit, theâm caùc chöùc naêng choïn maøu vaên baûn,
maøu neàn //File EditColor.h
…
15/19
TH Lập trình Windows chương 5 Dialog - Controls
…
//File EditColor.cpp
16/19
TH Lập trình Windows chương 5 Dialog - Controls
Böôùc 3: Khai baùo caùc bieán thaønh vieân öùng vôùi caùc controls :
Loaïi control ID Caption Bieán ñoái töôïng ComboBox IDC_COMBOCOLOR m_cbColor
(COwnerDrawComboBox)ComboBox IDC_COMBOSIZE m_cbSize
ListBox IDC_FONTLIST m_lbFonts (CColorListBox)
Editbox IDC_CONTENT m_editContent (CEditColor)
CheckBox IDC_CHECKB m_bB CheckBox IDC_CHECKI m_bI CheckBox IDC_CHECKU m_bU
Böôùc 4: // file SimpleEditor.h Khai baùo vaø ñònh nghóa haøm xöû lyù font : int CALLBACK EnumFontfamProc (LPENUMLOGFONT lpelf, LPNEWTEXTMETRIC lpntm, DWORD nFonttype, long lParam);
… … //file SimpleEditor.cpp
17/19
TH Lập trình Windows chương 5 Dialog - Controls
18/19
TH Lập trình Windows chương 5 Dialog - Controls
//Trong haøm OnInitDialog()
… …
19/19
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
HÖÔÙNG DAÃN THÖÏC HAØNH CHÖÔNG 5
3 Kieán truùc Documents/Views
3.1 SdiSquares Böôùc 1: Taïo öùng duïng SDI vôùi project name: SdiSquares Böôùc 2: Thieát keá laïi menu
Böôùc 3: Trong lôùp CSquaresDoc:
ID_COLOR_RED Red ID_COLOR_YELLOW Yellow ID_COLOR_GREEN Green ID_COLOR_CYAN Cyan ID_COLOR_BLUE Blue ID_COLOR_WHITE White
• Khai baùo hai bieán COLORREF m_clrCurrentColor; // maøu toâ hieän taïi
COLORREF m_clrGrid[4][4]; // maøu toâ trong caùc oâ • Xaây döïng caùc haøm: // Ñaët giaù trò maøu (color) cho oâ thöù [i][j] // Baùo taøi lieäu ñaõ ñöôïc thay ñoåi, caäp nhaät caùc view void CSquaresDoc::SetSquare(int i, int j, COLORREF color) { ASSERT (i >= 0 && i <= 3 && j >= 0 && j <= 3); m_clrGrid[i][j] = color; SetModifiedFlag (TRUE); UpdateAllViews (NULL); } //Laáy giaù trò maøu cuûa oâ thöù [i][j] COLORREF CSquaresDoc::GetSquare(int i, int j) { ASSERT (i >= 0 && i <= 3 && j >= 0 && j <= 3); return m_clrGrid[i][j]; } // Laáy giaù trò maøu hieän taïi COLORREF CSquaresDoc::GetCurrentColor() { return m_clrCurrentColor; } • Khôûi taïo giaù trò caùc bieán trong haøm OnNewDocument()
for (int i =0; i<4; i++) for (int j=0; j<4; j++) m_clrGrid[i][j] = RGB (255, 255, 255);
1
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
m_clrCurrentColor = RGB (255, 0, 0); • Khai baùo caùc haøm xöû lyù söï kieän ON_COMMAND,
ON_UPDATE_COMMAND_UI cho caùc menu ID_COLOR_RED ->ID_COLOR_WHITE
• Xöû lyù vieäc löu vaø laáy giaù trò caùc bieán trong haøm Serialize if (ar.IsStoring()) { for (int i=0; i<4; i++) for (int j=0; j<4; j++) ar << m_clrGrid[i][j]; ar << m_clrCurrentColor; } else { for (int i=0; i<4; i++) for (int j=0; j<4; j++) ar >> m_clrGrid[i][j]; ar >> m_clrCurrentColor; }
Böôùc 4: Trong lôùp CSquaresView: • Thöïc hieän thao taùc veõ trong haøm OnDraw
CSquaresDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // veõ vaø toâ maøu caùc oâ trong löôùi vôùi giaù trò töø caùc bieán cuûa lôùp Doc for (int i=0; i<4; i++) { for (int j=0; j<4; j++) { COLORREF color = pDoc->GetSquare (i, j); CBrush brush (color); int x1 = (j * 100) + 50; int y1 = (i * 100) + 50; int x2 = x1 + 100; int y2 = y1 +100; CRect rect (x1, y1, x2, y2); pDC->FillRect (rect, &brush); } }
// veõ caùc ñöôøng thaúng theo phöông ñöùng for (int x=50; x<=450; x+=100) { pDC->MoveTo (x, 50); pDC->LineTo (x, 450); }
// veõ caùc ñöôøng thaúng theo phöông ngang for (int y=50; y<=450; y+=100) { pDC->MoveTo (50, y);
2
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
pDC->LineTo (450, y); }
• Khai baùo haøm xöû lyù söï kieän khi nhaán nuùt traùi chuoät if (point.x >= 50 && point.x <= 450 && point.y >= 50 && point.y <= 450) { int i = (point.y-50)/100; int j = (point.x - 50) / 100; CSquaresDoc* pDoc = GetDocument (); COLORREF clrCurrentColor = pDoc->GetCurrentColor (); pDoc->SetSquare (i, j, clrCurrentColor); }
3.2 MDIDrawEllipse Böôùc 1: Taïo öùng duïng MDI vôùi project name: MDIDrawEllipse Böôùc 2: Thieát keá laïi menu
3
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
Böôùc 3: Xaây döïng lôùp CEllipse class CEllipse : public CObject { DECLARE_SERIAL(CEllipse) CPoint m_P1, m_P2; COLORREF m_clrBorderColor, m_clrFillColor; BOOL m_bThick; public: CEllipse(); virtual ~CEllipse(); void Draw(CDC *pDC); void SetPoint2(CPoint p); void SetPoint1(CPoint p); void SetBorderColor(COLORREF clrBorderColor); void SetFillColor(COLORREF clrFillColor); void SetPenWidth(int nPenWidth); CPoint GetPoint2(); CPoint GetPoint1(); COLORREF GetBorderColor(); COLORREF GetFillColor(); BOOL GetPenWidth(); void Serialize(CArchive& ar); }; // Ellipse.cpp CEllipse::CEllipse() { m_P1 = m_P2 = CPoint(0,0); m_clrBorderColor = RGB(0,0,0); m_clrFillColor = RGB(255, 255, 255); m_bThick=FALSE; } IMPLEMENT_SERIAL(CEllipse, CObject,1) . . . void CEllipse::Draw(CDC* pDC) { CPen NewPen, *pOldPen = NULL; CBrush NewBrush, *pOldBrush = NULL; if(m_bThick) NewPen.CreatePen(PS_SOLID, 5, m_clrBorderColor); else NewPen.CreatePen(PS_SOLID, 0, m_clrBorderColor); NewBrush.CreateSolidBrush(m_clrFillColor); pOldPen = pDC->SelectObject(&NewPen);
4
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
pOldBrush = pDC->SelectObject(&NewBrush); pDC->Ellipse(CRect(m_P1, m_P2)); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); NewPen.DeleteObject(); NewBrush.DeleteObject(); } void CEllipse::Serialize(CArchive& ar) { CObject::Serialize(); if (ar.IsStoring()) { ar << m_P1<<m_P2<<m_clrFillColor<<m_clrBorderColor<<m_bThick; } else { ar >> m_P1>>m_P2>>m_clrFillColor>>m_clrBorderColor>>m_bThick; } } Böôùc 4: Trong lôùp CMDIDrawEllipseDoc: • Khai baùo caùc bieán:
COLORREF m_clrBkColor, m_clrBorderColor; BOOL m_bThick; CArray<CEllipse*,CEllipse*> m_Objects; // danh saùch caùc Ellipses • Xaây döïng haøm:
void CMDIDrawEllipseDoc::SetEllipse(CPoint point) { CEllipse *pEllipse = new CEllipse; pEllipse->SetPoint1(point); pEllipse->SetPoint2(point); pEllipse->SetFillColor(m_clrBkColor); pEllipse->SetPenWidth (m_bThick); pEllipse->SetBorderColor (m_clrBorderColor); m_Objects.Add(pEllipse); SetModifiedFlag (TRUE); UpdateAllViews (NULL); }
• Khôûi taïo giaù trò caùc bieán trong haøm OnNewDocument() m_Objects.RemoveAll();
5
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
m_clrBkColor = RGB (255, 0, 0); m_clrBorderColor = RGB(255,255,0); m_bThick=FALSE; • Khai baùo caùc haøm xöû lyù söï kieän ON_COMMAND,
ON_UPDATE_COMMAND_UI cho caùc menu. • Xöû lyù vieäc löu vaø laáy giaù trò caùc bieán trong haøm Serialize
if (ar.IsStoring()) { ar<<m_clrBkColor<<m_clrBorderColor<<m_bThick; for(int i=0;i<m_Objects.GetSize();i++) ar << m_Objects[i]; }
else { ar>>m_clrBkColor>>m_clrBorderColor>>m_bThick; while(!ar.IsBufferEmpty()) { CEllipse *pEll=new CEllipse(); Ar >> pEll ; m_Objects.Add (pEll); } } Böôùc 5: Trong lôùp CMDIDrawEllipseView: • Khai baùo caùc bieán:
CDC m_MemDC; CBitmap m_MemBitmap, *m_pOldBitmap; • Khai baùo vaø ñònh nghóa haøm
// MDIDrawEllipseView.h afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); // MDIDrawEllipseView.cpp ON_WM_CREATE() //BEGIN MESSAGEMAP //… int CMDIDrawEllipseView::OnCreate(LPCREATESTRUCT
lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // lay kich thuoc man hinh CClientDC dc(this); int MaxX = ::GetSystemMetrics(SM_CXSCREEN); int MaxY = ::GetSystemMetrics(SM_CYSCREEN); //Tao ra MemDC tuong thich voi dc cua man hinh m_MemDC.CreateCompatibleDC(&dc);
6
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
//tao doi tuong CBitmap(kich thuoc MaxX,MaxY) tuong thich voi dc man hinh
m_MemBitmap.CreateCompatibleBitmap (&dc,MaxX,MaxY); // Dua doi tuong bitmap m_MemBitmap vao m_MemDC m_pOldBitmap=m_MemDC.SelectObject(&m_MemBitmap); return 0; }
• Thöïc hieän thao taùc veõ trong haøm OnDraw CMDIDrawEllipseDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc); CRect rect; GetClientRect(&rect); m_MemDC.FillSolidRect(rect,RGB(255,255,255)); int i, n = pDoc->m_Objects.GetSize(); for (i=0; i<n; i++) pDoc->m_Objects[i]->Draw(&m_MemDC); pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_MemDC,0,0,SRCCOPY); • Khai baùo haøm xöû lyù söï kieän khi nhaán nuùt traùi chuoät
CMDIDrawEllipseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDoc->SetEllipse (point); • Khai baùo haøm xöû lyù söï kieän khi di chuyeån chuoät
CMDIDrawEllipseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (nFlags & MK_LBUTTON==MK_LBUTTON) if (pDoc->m_Objects.GetSize()>0) { CEllipse* pEllipse= pDoc->m_Objects[pDoc->m_Objects.GetSize()-1]; pEllipse->SetPoint2(point); Invalidate(); } • Khai baùo haøm xöû lyù söï kieän khi nhaû nuùt traùi chuoät
CMDIDrawEllipseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (pDoc->m_Objects.GetSize()>0) { CEllipse* pEllipse= pDoc->m_Objects[pDoc->m_Objects.GetSize()-1]; pEllipse->SetPoint2(point); CClientDC dc(this); pEllipse->Draw(&dc); pDoc->SetModifiedFlag (TRUE); pDoc->UpdateAllViews (NULL);
7
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
} • Huûy caùc ñoái töôïng trong haøm
CMDIDrawEllipseView::~CMDIDrawEllipseView() m_MemDC.DeleteDC();
m_MemBitmap.DeleteObject();
4 Dialog, Property Sheets
4.1 DlgDemo (Modal dialog) Böôùc 1: Taïo öùng duïng SDI (boû choïn Document/View) Thieát keá laïi menu File: Goàm hai menu Options vaø Exit. Böôùc 2: Töø menu Insert, choïn Resource, Dialog, New ñeå theâm vaøo öùng duïng moät hoäp thoaïi dialog. Thieát keá laïi dialog (IDD_OPTIONS ) vaø theâm caùc controls theo yeâu caàu
Double click vaøo dialog ñeå taïo lôùp môùi COptionsDialog : public CDialog vaø khai baùo caùc bieán cho caùc controls töông öùng:
Loaïi control ID Caption Bieán ñoái
töôïng Command Button
IDC_RESET Reset
Editbox IDC_WIDTH m_nWidth Editbox IDC_HEIGHT m_nHeight
Radio Button IDC_INCHES (group)
Inches m_nUnits
8
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
Radio Button IDC_CENTIMETERS CentimetersRadio Button IDC_PIXELS Pixels
Böôùc 3: Trong lôùp CChildView khai baùo caùc bieán:
int m_nUnits; int m_nHeight; int m_nWidth; Trong haøm OnPaint() void CChildView::OnPaint() { CPaintDC dc(this); // Device context for painting.
CBrush brush (RGB (255, 0, 255)); CBrush* pOldBrush = dc.SelectObject (&brush); switch (m_nUnits) { case 0: // Inches. dc.SetMapMode (MM_LOENGLISH); dc.Rectangle (0, 0, m_nWidth * 100, -m_nHeight * 100); break; case 1: // Centimeters. dc.SetMapMode (MM_LOMETRIC); dc.Rectangle (0, 0, m_nWidth * 100, -m_nHeight * 100); break; case 2: // Pixels. dc.SetMapMode (MM_TEXT); dc.Rectangle (0, 0, m_nWidth, m_nHeight); break; } dc.SelectObject (pOldBrush);
} Khai baùo haøm xöû lyù söï kieän cho menu File -> Option void CChildView::OnFileOptions() { COptionsDialog dlg;
dlg.m_nWidth = m_nWidth; dlg.m_nHeight = m_nHeight; dlg.m_nUnits = m_nUnits; if (dlg.DoModal () == IDOK) { m_nWidth = dlg.m_nWidth;
9
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
m_nHeight = dlg.m_nHeight; m_nUnits = dlg.m_nUnits; Invalidate ();
} }
4.2 DlgDemo (Modeless dialog) Böôùc 1-2:
Taïo öùng duïng vaø thieát keá hoäp thoaïi Options gioáng baøi taäp 3.1
Right click vaøo lôùp COptionsDlg , choïn Add Windows Message Handler, choïn söï kieän WM_INITDIALOG ñeå theâm haøm OnInitDialog cho lôùp naøy. BOOL COptionsDialog::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here CMainFrame* pMain = (CMainFrame*)AfxGetApp()->GetMainWnd(); m_nWidth = pMain->m_nWidth; m_nHeight = pMain->m_nHeight; m_nUnits = pMain->m_nUnits; UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control } Khai baùo haøm xöû lyù söï kieän cho caùc nuùt OK, Cancel vaø Reset void COptionsDialog::OnReset() { m_nWidth = 4; m_nHeight = 2; m_nUnits = 0; UpdateData (FALSE); } void COptionsDialog::OnOK() { UpdateData(TRUE); CMainFrame* pMain = (CMainFrame*)AfxGetApp()->GetMainWnd(); pMain->m_nWidth = m_nWidth; pMain->m_nHeight = m_nHeight; pMain->m_nUnits = m_nUnits; pMain->Invalidate (); CDialog::OnOK(); }
10
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
void COptionsDialog::OnCancel() { ShowWindow(SW_HIDE); CDialog::OnCancel(); } Böôùc 3: Trong lôùp CMainFrame khai baùo caùc bieán:
int m_nUnits; int m_nHeight; int m_nWidth; Böôùc 4: Trong lôùp CChildView Khai baùo bieán :
COptionsDialog pDialog; Khai baùo haøm xöû lyù söï kieän cho menu File -> Option void CChildView::OnFileOptions() { if(!pDialog) pDialog.Create(IDD_OPTIONS); pDialog.ShowWindow(SW_SHOW); }
4.3 PropDemo (Property Sheets) Böôùc 1: Taïo öùng duïng SDI nhö baøi taäp 3.1. Böôùc 2: Insert hai dialog, thieát keá giao dieän nhö yeâu caàu vaø taïo hai lôùp môùi töông öùng vôùi hai dialog treân: class CSizePage : public CPropertyPage { . . . // Dialog Data //{{AFX_DATA(CSizePage) enum { IDD = IDD_SIZEPAGE }; int m_nHeight; int m_nWidth; int m_nUnits; //}}AFX_DATA . . . // Implementation protected: // Generated message map functions //{{AFX_MSG(CSizePage) afx_msg void OnChange(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; void CSizePage::OnChange() { SetModified (TRUE);
11
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
} class CColorPage : public CPropertyPage { . . .
// Dialog Data //{{AFX_DATA(CColorPage) enum { IDD = IDD_COLORPAGE }; int m_nColor; //}}AFX_DATA . . . // Implementation protected: // Generated message map functions //{{AFX_MSG(CColorPage) afx_msg void OnChange(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; void CColorPage::OnChange() { SetModified (TRUE); } Böôùc 3: Taïo lôùp môùi keá thöøa töø lôùp CPropertySheet class CMyPropertySheet : public CPropertySheet { . . . // Attributes public: CColorPage m_colorPage; CSizePage m_sizePage; . . . // Generated message map functions protected: //{{AFX_MSG(CMyPropertySheet) //}}AFX_MSG afx_msg void OnApply (); DECLARE_MESSAGE_MAP() }; // MyPropertySheet.cpp BEGIN_MESSAGE_MAP(CMyPropertySheet, CPropertySheet) //{{AFX_MSG_MAP(CMyPropertySheet) //}}AFX_MSG_MAP ON_BN_CLICKED (ID_APPLY_NOW, OnApply) END_MESSAGE_MAP()
12
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
///////////////////////////////////////////////////////////////////////////// void CMyPropertySheet::OnApply () {
GetActivePage ()->UpdateData (TRUE); CMainFrame* pMain = (CMainFrame*)AfxGetApp()->GetMainWnd(); pMain->m_nWidth = m_sizePage.m_nWidth; pMain->m_nHeight = m_sizePage.m_nHeight; pMain->m_nUnits = m_sizePage.m_nUnits; pMain->m_nColor = m_colorPage.m_nColor; pMain->Invalidate ();
} Böôùc 4: Trong lôùp CChildView: Trong haøm OnPaint() void CChildView::OnPaint() { CPaintDC dc(this); CMainFrame* pMain = (CMainFrame*)AfxGetApp()->GetMainWnd(); CBrush brush (CColorPage::m_clrColors[pMain->m_nColor]); CBrush* pOldBrush = dc.SelectObject (&brush); switch (pMain->m_nUnits) { case 0: // Inches. dc.SetMapMode (MM_LOENGLISH); dc.Ellipse (0, 0, pMain->m_nWidth * 100, -pMain->m_nHeight * 100); break; case 1: // Centimeters. dc.SetMapMode (MM_LOMETRIC); dc.Ellipse (0, 0, pMain->m_nWidth * 100, -pMain->m_nHeight * 100); break; case 2: // Pixels. dc.SetMapMode (MM_TEXT); dc.Ellipse (0, 0, pMain->m_nWidth, pMain->m_nHeight); } dc.SelectObject (pOldBrush); } Khai baùo haøm xöû lyù söï kieän cho menu File -> Propertiers void CChildView::OnFilePropertiers() {
13
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
CMainFrame* pMain = (CMainFrame*)AfxGetApp()->GetMainWnd(); CMyPropertySheet ps (_T ("Properties")); ps.m_sizePage.m_nWidth = pMain->m_nWidth; ps.m_sizePage.m_nHeight = pMain->m_nHeight; ps.m_sizePage.m_nUnits = pMain->m_nUnits; ps.m_colorPage.m_nColor = pMain->m_nColor; if (ps.DoModal () == IDOK) { pMain->m_nWidth = ps.m_sizePage.m_nWidth; pMain->m_nHeight = ps.m_sizePage.m_nHeight; pMain->m_nUnits = ps.m_sizePage.m_nUnits; pMain->m_nColor = ps.m_colorPage.m_nColor; pMain->Invalidate (); } }
4.4 Phones(Common Dialog) Böôùc 1: Taïo öùng duïng dialog vaø thieát keá giao dieän theo yeâu caàu
ListBox (m_lbPhoneList
14
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
Böôùc 2: Taïo lôùp CEditNumber keá thöøa töø lôùp CEdit: class CEditNumber : public CEdit { . . . //{{AFX_MSG(CEditNumber) afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); //}}AFX_MSG . . . }; //EditNumber.cpp void CEditNumber::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if (((nChar >= _T ('0')) && (nChar <= _T ('9'))) || (nChar == VK_BACK) || (nChar == _T ('(')) || (nChar == _T (')')) || (nChar == _T ('-')) || (nChar == _T (' '))) CEdit::OnChar(nChar, nRepCnt, nFlags); } Böôùc 3: Insert dialog
• Taïo lôùp môùi CAddPhoneDlg :public CDialog vaø khai baùo caùc
bieán cho caùc controls töông öùng
Loaïi control
ID Caption Bieán ñoái töôïng
Editbox IDC_NAME m_editName Editbox IDC_PHONE CEditNumber
m_editPhone Command IDOK (Bitmap) OK m_btOk
15
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
Button Command Button
IDCANCEL (Bitmap)
Cancel m_btCancel
• Trong haøm OnInitDialog() BOOL CAddPhoneDlg::OnInitDialog() { CDialog::OnInitDialog(); HBITMAP hbitmap=::LoadBitmap (::AfxGetInstanceHandle (),
MAKEINTRESOURCE(IDB_OK)); m_buttonOk.SetBitmap (hbitmap); hbitmap=::LoadBitmap (::AfxGetInstanceHandle (),
MAKEINTRESOURCE(IDB_CANCEL)); m_buttonCancel.SetBitmap (hbitmap); return TRUE; } Böôùc 4: Insert menu vaø thieát keá menu File theo yeâu caàu
Böôùc 5: Trong lôùp CPhonesDlg
• Khai baùo bieán CString m_strPathName; • Khai baùo vaø ñònh nghóa caùc haøm:
// Löu döõ lieäu töø ListBox vaøo file BOOL CPhonesDlg::SaveFile(LPCTSTR pszFile) { BOOL bResult = FALSE; try {
CStdioFile file (pszFile, CFile::modeWrite | CFile::modeCreate); DWORD dwCount = m_lbPhoneList.GetCount (); file.Write (&dwCount, sizeof (dwCount)); if (dwCount)
{ for (int i=0; i<(int) dwCount; i++) {
CString string; m_lbPhoneList.GetText (i, string); string += _T ("\n");
16
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
file.WriteString (string); } } bResult = TRUE; } catch (CFileException* e) { e->ReportError (); e->Delete (); } return bResult; }
17
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
//Ñoïc file ñöa vaøo ListBox BOOL CPhonesDlg::LoadFile(LPCTSTR pszFile) { BOOL bResult = FALSE; try { CStdioFile file (pszFile, CFile::modeRead); m_lbPhoneList.ResetContent (); DWORD dwCount; file.Read (&dwCount, sizeof (dwCount)); if (dwCount) { for (int i=0; i<(int) dwCount; i++) { CString string; file.ReadString (string); m_lbPhoneList.AddString (string); } } bResult = TRUE; } catch (CFileException* e) { e->ReportError (); e->Delete (); } return bResult; }
• Khai baùo caùc haøm xöû lyù söï kieän töø menu void CPhonesDlg::OnFileNew() { CAddPhoneDlg dlg; if(dlg.DoModal ()==IDOK) { CString str=dlg.m_sName +_T("\t")+dlg.m_sPhone ; m_lbPhoneList.AddString (str); } } void CPhonesDlg::OnFileOpen() { CFileDialog dlg (TRUE, _T ("phn"), _T ("*.phn"), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, m_szFilters); if (dlg.DoModal () == IDOK) { if (LoadFile (dlg.GetPathName ())) { m_strPathName = dlg.GetPathName (); m_lbPhoneList.SetCurSel (0);
18
TH Laäp trình Windows chöông 5 Kiến trúc Documents/Views – Dialog, Property Sheets
} } } void CPhonesDlg::OnFileSave() {
if (!m_strPathName.IsEmpty ()) SaveFile (m_strPathName); else OnFileSaveAs (); } void CPhonesDlg::OnFileSaveAs() { CFileDialog dlg (FALSE, _T ("phn"), m_strPathName, OFN_OVERWRITEPROMPT |
OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, m_szFilters);
if (dlg.DoModal () == IDOK) if (SaveFile (dlg.GetPathName ())) m_strPathName = dlg.GetPathName (); } void CPhonesDlg::OnFileExit() { OnOK(); } // bieán m_szFilters[] ñöôïc khai baùo ñaàu file PhoneDlg.cpp nhö sau: TCHAR m_szFilters[] = _T ("My files (*.phn)|*.phn|All files (*.*)|*.phn||");
19