Học tập‎ > ‎C++‎ > ‎

Bài tập thực hành C++ .01

Bài 1: Viết ứng dụng xuất nhiều chuỗi lên vùng client với màu, font, và kích thước lấy ngẫu nhiên. Các chuỗi này xuất ở giữa vùng client.

1. Khởi động Microsoft Visual C++ 6
2. File --> New (Ctrl + N)
3. Trong tab Project --> chọn MFC AppWizard (exe) --> chọn Location: đường dẫn chứa Workspace --> gõ tên project vào Project name --> OK



4. Ở bước số 1, chọn Signle document (để tạo tạo ứng dụng SDI)--> Finish --> OK.



5.Trong BaiTap1 classes, chọn CBaiTap1View --> chọn hàm OnDraw(CDC* pDC)



6. Viết code cho hàm OnDraw:

void CBaiTap1View::OnDraw(CDC* pDC)
{
CBaiTap1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here

srand( (unsigned)time( NULL ) ); //khởi tạo số ngẫu nhiên (randomize)

//Khai báo một số font sẽ sử dụng để xuất trên vùng client

CString fontName[] = {"VNI-Times", "VNI-Swiss-Condense",
"VNI-Jamai", "VNI-Souvir"};
int numFont = 4;//Số lượng font sử dụng là 4

CRect r;
GetClientRect(&r); //Lấy kích thước vùng client
pDC->SetBkMode(TRANSPARENT); //chọn Background Mode, mặc định là OPAQUE

for (int i=0; i < 10; i++)
{
CFont font;
//Dùng Macro RGB để tạo màu ngẫu nhiên
pDC->SetTextColor(RGB(rand() % 256, rand() % 256, rand() % 256));
//lấy font ngẫu nhiên với kích thước từ 20pt đến 50pt
font.CreatePointFont(rand() % 300 + 200, fontName[rand() % numFont]);
CFont *pOldFont = pDC->SelectObject(&font);
pDC->TextOut(rand() % r.Width(),rand() % r.Height(), "Xin chào các bạn !");
pDC->SelectObject(pOldFont);
font.DeleteObject();
}
}


Bài 2: Viết ứng dụng vẽ ngẫu nhiên một số hình sau:
-Đọan thẳng, hình chữ nhật, hình chữ nhật tròn.
-Hình tròn, ellipse, hình quạt, hình viên phân.
Mỗi hình đều có pen, brush, color, width tạo một cách ngẫu nhiên.


1. Tạo số ngẫu nhiên: dùng hàm srand() để khởi tạo, và hàm rand() để lấy số ngẫu nhiên.
2. Tạo màu: dùng macro RGB.
3. Tạo Pen: dùng lớp CPen: CPen(int nPenStyle, nWidth, COLORREF crColor), xem tài liệu trang 73.
4. Tạo Brush: dùng lớp CBrush: CBrush(int nIndex, COLORREF crColor), xem tài liệu 74.
5. Dùng hàm CDC::SelectObject() để chọn pen và brush để vẽ.
6. Vẽ đoạn thẳng: dùng hàm CDC::MoveTo(int x, int y) và CDC::LineTo(int x, int y).
7. Vẽ hình chữ nhật: dùng hàm CDC::Rectangle(int x1, int y1, int x2, int y2).
8. Vẽ hình chữ nhật tròn: hàm CDC:: RoundRect(int x1, int y1, int x2, int y2, int x3, int y3) với x3, y3 xác định phần bo tròn.
9. Vẽ hình tròn: dùng hàm CDC::Ellipse(int x1, int y1, int x2, int y2).
10. Vẽ hình viên phân: CDC::Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4).


Bài 3: Viết ứng dụng hiển thị các loại bút vẽ như hình sau :

1.Tạo mảng chứa các loại pen:
int nPenStyle[] = {PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT, PS_NULL, PS_INSIDEFRAME};
2.Tạo mảng chứa tên của các loại pen:
CString sPenStyle[] = {"PS_SOLID", "PS_DASH", "PS_DOT", "PS_DASHDOT", "PS_DASHDOTDOT", "PS_NULL, PS_INSIDEFRAME"};
3.Dùng hàm CDC::TextOut() để xuất text.

4.Dùng lớp CPen để tạo pen (như bài 2).
5.Dùng hàm CDC::SelectObject() để chọn pen để vẽ.
6.Dùng hàm CDC::MoveTo() và CDC::LineTo() để vẽ đường thẳng.


Bài 4: Viết ứng dụng hiển thị các loại cọ vẽ như hình sau:


1.Tạo mảng chứa các loại brush:
int nBrushStyle[] = {HS_BDIAGONAL, HS_CROSS, HS_DIAGCROSS, HS_FDIAGONAL, HS_HORIZONTAL, HS_VERTICAL};
2.Tạo mảng chứa tên của các loại brush:
CString sBrushStyle[] = {"HS_BDIAGONAL", "HS_CROSS", "HS_DIAGCROSS", "HS_FDIAGONAL", "HS_HORIZONTAL", "HS_VERTICAL"};
3.Dùng hàm CDC::TextOut() để xuất text.
4.Dùng lớp CPen để tạo pen (như bài 2).
5.Dùng hàm CDC::SelectObject() để chọn pen để vẽ.
6.Dùng lớp CBrush để tạo brush.
7.Dùng hàm CDC::SelectObject() để chọn brush để tô.
8.Dùng hàm CDC::Rectangle() để vẽ hình vuông.


Bai 5: Viết ứng dụng nêu cách tạo alignment như hình sau:


1. Cách 1: Dùng hàm CDC::SetTextAlign(int nFlags) để canh lề cho text (xem tài liệu trang 82).
2. Cách 2: Dùng hàm CDC::GetTextExtent() để lấy thông tin về chiều rộng và chiều cao của chuỗi, từ đó tính toán và canh lề cho chuỗi (xem tài liệu trang 85).


Bài 6: Viết ứng dụng hiển thị các thông tin sau:

SM_CXSCREEN Screen width in pixels 1024
SM_CYSCREEN Screen height in pixels 768
……
SM_SHOWSOUNDS Present sounds visually 0

1. Do thông tin hiển thị trên vùng client nhiều, không đủ hiển thị trong một màn hình, do đó ta sẽ tạo thanh cuộn (ScrollBar) để mở rộng vùng hiển thị cho vùng Client.
a. Tạo project mới:
File --> New --> MFC AppWizard --> Gõ tên project: BaiTap6 --> OK.
b. Ở bước 1, chọn Signle document --> Next.
c. Next qua tiếp các bước 2, 3, 4, 5.
d. Ở bước 6, ở combobox Base class, chọn CSCrollView --> Finish --> OK.



2. Sửa lại kích thước vùng client:
- Trong BaiTap6 classs --> CBaiTap6View --> OnInitialUpdate()
- Tìm dòng: sizeTotal.cx = sizeTotal.cy = 100;
- Sửa lại là: sizeTotal.cx = 100; sizeTotal.cy = 1000;
3. Tạo mảng chứa các hằng giá trị:
int nIndex[] = { SM_CXSCREEN, SM_CYSCREEN, ……, SM_SHOWSOUNDS};
4. Tạo mảng chứa tên của các giá trị:
CString sIndex[] = {“ SM_CXSCREEN”, “SM_CYSCREEN”, ……, “SM_SHOWSOUNDS”};
5. Tạo mảng mô tả cho các giá trị:
CString sDesciption[] = {“Screen width in pixels”, “Screen height in pixels”, ……, “Present sounds visually”};
6. Dùng hàm int GetSystemMetrics(int nIndex) để lấy thông tin của hệ thống (Xem MSDN để hiểu cách sử dụng hàm này).
7. Dùng hàm sprintf() để tạo chuỗi kết quả.
8. Dùng hàm CDC::TabbedTextOut() để xuất text. (xem MSDN để hiểu rõ các tham số)
9. Đoạn code mẫu: (các bạn dùng vòng lặp for để in ra tất cả kết quả, bên dưới chỉ lấy kết quả của dòng đầu tiên, tọa độ y của mỗi dòng cách nhau 20 pixel).

char buff[300];
int value;
int nTab[] = {0, 400};

value = GetSystemMetrics(SM_CXSCREEN);
sprintf(buff, "%st %st %d", nIndex[0], sIndex[0], value);
pDC->TabbedTextOut(10, 10, buff, -1, 2, nTab, 200);


Bài 7: Viết ứng dụng liệt kê tất cả các face name của font ra vùng client.

1. Tạo Project với tên BaiTap7, dùng lớp CScrollView (như bài 6).
2. Thêm 2 dòng in đậm bên dưới vào file BaiTap7View.h: (thêm vào ở đầu file)

// BaiTap7View.h : interface of the CBaiTap7View class
//
///////////////////////////////////////////////////////////////////
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

int CALLBACK EnumFontFamProc(LPENUMLOGFONT lpelf,LPNEWTEXTMETRIC lpntm,
DWORD nFontType, long lParam);



3. Thêm biến thành viên: (tạo mảng để lưu tất cả font face của hệ thống)





- Phải chuột tai CBaiTap7View  Chọn Add Member Variable…
- Trong hộp thoại Add Member Variable:
o Variable Type: CArray
o Variable Name:m_arrayFontFace
o Access:Public
- Trong CBaiTap7View:
oDouble-Click vào m_arrayFontFace
oVà sửa lại thành: CArray<CString, CString&> m_arrayFontFace;

4. Viết code cho hàm EnumFontFamProc(): (hàm này đặt ở cuối file CBaiTap7View.cpp)

int CALLBACK EnumFontFamProc(LPENUMLOGFONT lpelf,
LPNEWTEXTMETRIC lpntm, DWORD nFontType, long lParam)
{
//Lấy con trỏ của lớp CBaiTap7View (để truy cập vào mảng m_arrayFontFace)
CBaiTap7View *pView = (CBaiTap7View*)lParam;

//Thêm font face vào mảng m_arrayFontFace
pView->m_arrayFontFace.Add(CString(lpelf->elfLogFont.lfFaceName));

// Trả về 1 để tiếp tục liệt kê font
return 1;
}


5. Viết code cho hàm OnDraw(CDC* pDC):

void CBaiTap7View::OnDraw(CDC* pDC)
{
CBaiTap7Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here

LOGFONT lf;
// Khởi tạo cấu trúc LOGFONT
lf.lfCharSet = DEFAULT_CHARSET;
strcpy(lf.lfFaceName, "");
//Khởi tạo mảng m_arrayFontFace
m_arrayFontFace.RemoveAll();

// Tạo biến DC (device context variable)
CClientDC dc (this);

//Gọi hàm liệt kê font face của hệ thống
EnumFontFamiliesEx((HDC) dc, &lf, (FONTENUMPROC) EnumFontFamProc,
(LPARAM) this, 0);

//Cập nhật lại kích thước vùng client.
CSize sizeTotal;
sizeTotal.cx = 100; sizeTotal.cy = m_arrayFontFace.GetSize()*20;
SetScrollSizes(MM_TEXT, sizeTotal);

//Xuất các Font Face trong mảng m_arrayFontFace ra vùng client
int y=0;
for (int i=0; i < m_arrayFontFace.GetSize(); i++)
{
pDC->TextOut(10, y, m_arrayFontFace[i]);
y+=20;
}
}


Bài 8: Viết ứng dụng hiển thị thông tin về thiết bị sau: HORZSIZE, VERTSIZE, …, COLORRES.

- Làm tương tự bài 6.
- Dùng hàm int GetDeviceCaps( int nIndex ) const; (xem MSDN để biết cách sử dụng hàm này).


Bài 9: Viết ứng dụng xuất một chuỗi có bóng như sau:



1. Tạo Font: dùng hàm CFont::CreatePointFont(int nPointSize, LPCTSTR lpszFaceName).
2. Dùng marco RGB để tạo màu: màu xám có 3 thành phần R, G, B bằng nhau; và màu đen có 3 thành phần R, G, B đều bằng 0.
3. Chọn màu: Dùng hàm CDC::SetTextColor(COLORREF crColor).
4.Dùng hàm CDC::TextOut() để xuất text ra client (phần bóng của chữ “Hello, MFC” xuất trước, phần chữ xuất sau).


Bài 10: Viết ứng dụng hiển thị các mapping mode:



1. Tạo project BaiTap10, tạo hàm Show() có prototype như sau trong lớp View.

void CBaiTap10View::Show(CDC *pDC, int x, int y,
int iMapMode, CString sMapMode)
{
char buffer[100] ;
CRect rect ;

pDC->SaveDC();
pDC->SetMapMode(iMapMode);
GetClientRect (&rect);
pDC->DPtoLP ((PPOINT) &rect, 2);
pDC->RestoreDC(-1);
sprintf(buffer, "%-20s %7d %7d %7d %7d",
sMapMode, rect.left, rect.right, rect.top, rect.bottom);
pDC->TextOut(x, y, buffer);
}


2. Viết code cho hàm OnDraw():

void CBaiTap10View::OnDraw(CDC* pDC)
{
CBaiTap10Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here

CString sHeading = "Mapping Mode Left Right Top Bottom";
CString sLine = "------------ ---- ----- --- ------";
int iMapMode[] = {MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH,
MM_HIENGLISH, MM_TWIPS};
CString sMapMode[]= {"TEXT (pixels)", "LOMETRIC (.1 mm)",
"HIMETRIC (.01 mm)", "LOENGLISH (.01 in)",
"HIENGLISH (.001 in)", "TWIPS (1/1440 in)"};
int x, y;
x = y = 10;
pDC->TextOut(x, y, sHeading);y+=20;
pDC->TextOut(x, y, sLine);y+=20;
for (int i=0; i < 6; i++, y+=20)
Show(pDC, x, y, iMapMode[i], sMapMode[i]);
}


Bài 11: Viết ứng dụng tạo văn bản xoay vòng sau:



1. Dùng hàm GetClientRect() để lấy kích thước vùng client.
2. Dùng hàm CFont:: CreateFont() để tạo font (xem tài liệu trang 77)
3. Do vị trí của chuỗi “Hello, MFC” nằm trên 1 vòng tròn, ta phải dùng hàm sin(), cos() để tính toán --> trong file BaiTap11View.h, khai báo thêm #include <math.h>
4. Dùng hàm CDC::TextOut() để xuất text.
5. Viết code cho hàm OnDraw()

void CBaiTap11View::OnDraw(CDC* pDC)
{
CBaiTap11Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here

float M_PI = 3.14;
int k = 360 / 24;
int x, y, r;

CRect rect;
GetClientRect(&rect);

x = rect.Width() / 2;
y = rect.Height() / 2;
r = 60;

pDC->SetBkMode(TRANSPARENT);
for (int i=0; i < 24; i++)
{
CFont font;
font.CreateFont(20,0,i*k*10,0,600,FALSE,FALSE,FALS E,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS,"Arial");
pDC->SelectObject(&font);
pDC->TextOut(x + r* sin((i*k+90)*M_PI/180),
y + r* cos((i*k+90)*M_PI/180),"Hello, MFC");
font.DeleteObject();
}
}
Comments