Tài liệu thi lại Lập trình Win!
+2
oanhtktrinh
lqhlam
6 posters
Trang 1 trong tổng số 1 trang
Tài liệu thi lại Lập trình Win!
link tải về:
http://www.mediafire.com/download.php?ytniimyd5j2
Dưới đây là tài liệu tự soạn của bạn ngocnam
http://www.mediafire.com/download.php?wrmqjn5yzwi
http://www.mediafire.com/download.php?ytniimyd5j2
Dưới đây là tài liệu tự soạn của bạn ngocnam
http://www.mediafire.com/download.php?wrmqjn5yzwi
lqhlam- Tổng số bài gửi : 90
Join date : 17/03/2009
Re: Tài liệu thi lại Lập trình Win!
Bạn ơi cho mình hỏi có slide của môn học không? Mình lục hết trên frum mà không tìm thấy. Môn này quả là kinh khủng với lý thuyết. Thầy giảng nhanh mình không lãnh hội nỗi. Kiểu này tiêu chắc. Có tài liệu slide thì pm yahooo mình với nhé. web4youpro@yahoo.com
lqhlam đã viết:link tải về:
http://www.mediafire.com/download.php?ytniimyd5j2
Dưới đây là tài liệu tự soạn của bạn ngocnam
http://www.mediafire.com/download.php?wrmqjn5yzwi
Re: Tài liệu thi lại Lập trình Win!
Đây là tài liệu tự soan của bạn Yến
1. Qui trình hoạt động của chương trình ứng dụng :
• Cửa sổ được hiển thị lên màn hình.
• Windows chờ cửa sổ gửi thông điệp.
• Các thông điệp được Windows gửi trả lại chương trình ứng dụng thông qua lời gọi hàm của chúng trong chương trình ứng dụng.
• Khi nhận được thông điệp, chương trình ứng dụng gọi các hàm API và hàm của riêng chúng để thực hiện công việc mong muốn.
2. Phát sinh và xử lý thông điệp :
3. Qui trình xử lý thông điệp :
4. Ví dụ xử lý vòng lập thông điệp :
// Vòng lặp xử lý thông điệp trong 1 ứng dụng –
// Message loop
MSG msg;
// lấy thông điệp ra khỏi hàng đợi của ứng dụng
while (GetMessage (&msg, NULL, 0, 0))
{
/*chuyển đổi các phím ảo (virtual key) thành các thông điệp ký tự*/
TranslateMessage(&msg);
// chuyển message đến hàm xử lý thông điệp của cửa
// sổ tương ứng
DispatchMessage(&msg);
}
return msg.wParam;
5. Làm sao để xử lý 1 thông điệp ???
MFC dùng Message Map để liên kết các thông điệp với những hàm thành phần của lớp cửa
sổ.
Mỗi thông điệp sẽ được xử lý bởi 1 hàm thành phần tương ứng
BEGIN_MESSAGE_MAP(CDemoDlg, CDialog)
//{{AFX_MSG_MAP(CDemoDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
ON_WM_PAINT là 1 macro được định nghĩa trong Afxmsg_.h, mặc nhiên liên kết thông điệp
WM_PAINT với hàm OnPaint
Thêm xử lý thông điệp WM_LBUTTONDOWN
Bổ sung thêm khai báo hàm xử lý thông điệp afx_msg void OnLButtonDown(UINT nFlags, CPoint
point);
Bổ sung 1 macro trong khai báo message map
ON_WM_LBUTTONDOWN()
Viết hàm thực thi OnLButtonDown
void CDemoDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
MessageBox("Nhan phim trai chuot", "Mouse",MB_OK);
CDialog::OnLButtonDown(nFlags, point);
}
Sử dụng ClassWizard
(Ctrl-W)
Click chuột phải, chọn
ClassWizard
Trên hộp thoại MFC ClassWizard, chọn tab Message Maps.
Chọn lựa lớp (trong Class name), ID của đối tượng (Object IDs) cần thêm sự
kiện vào (Messages). Chọn Add Functions Các khai báo hàm, cấu trúc hàm được thêm tự động vào
những vị trí thích hợp trên tập tin .CPP và .H của lớp.Viết hàm xử lý thông điệp WM_LBUTTONDBCLK dùng ClassWizard.
Chọn CDemoDlg trong Class name
Chọn CDemoDlg trong Object IDs. Chọn WM_LBUTTONDBCLK trong Messages.
Nhấn Add Functions.
Môi trường lập trình chèn khai báo hàm afx_msg void OnLButtonDblClk(UINT nFlags, CPoint
point);
trong khai báo lớp CDemoDlg
Hàm thực thi đã được chèn
void CDemoDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
/* TODO: Add your message handler code here and/or
call default*/
CDialog::OnLButtonDblClk(nFlags, point);
}
Chỉnh sửa hàm xử lý thông điệp:
void CDemoDlg::OnLButtonDblClk(UINT nFlags, CPoint
point)
{
/* TODO: Add your message handler code here and/or
call default */
MessageBox("Nhan kep phim trai chuot",
"Mouse",MB_OK);
Dialog::OnLButtonDblClk(nFlags, point);
}
6. Cô cheá gôûi – nhaän thoâng ñieäp
Moïi söï kieän xaûy ra treân moät chöông trình Windows ñeàu thoâng qua nhöõng thoâng ñieäp (messages).
Thoâng ñieäp ñoù laø: nhaán moät nuùt treân baøn phím, dichuyeån hoaëc nhaán chuoät, thay ñoåi kích thöôùc cöûa soå…
Caùc thoâng ñieäp ñöôïc gôûi qua laïi giöõa öùng duïng vaøWindows, giöõa caùc öùng duïng vôùi nhau.
Khi nhaän ñöôïc thoâng ñieäp naøy thì chöông trình öùng duïng seõ coù haønh ñoäng thích hôïp vôùi thoâng ñieäp nhaän ñöôïc.
7. Mô hình lập trình Windows
Kỹ thuật lập trình sử dụng các hàm Windows API còn gọi là lập trình Windows SDK. Một ứng dụng xây dựng theo kỹ thuật này chứa đựng hàm WinMain (xử lý các thông báo (message) nhận được/gửi đi nhằm đáp ứng yêu cầu tương tác của người dùng và của hệ thống cũng như của ứng dụng khác) và hàm DefWinProc (điều phối hoạt động tương ứng với các thông báo nhận được). Tổ chức hệ thống của ứng dụng Windows dạng SDK như sau:
WM_CHAR:Moät kyù töï nhaäp töø baøn phím
WM_CREATE: Moät cöûa soå ñöôïc taïo ra.
WM_DESTROY: Huûy moät cöûa soå.
WM_LBUTTONDOWN: Nhaán phím traùichuoät.
WM_LBUTTONUP: Nhaû phím chuoät
WM_PAINT:Veõ laïi moät cöûa soå
WM_QUIT: Keát thuùc öùng duïng
WM_SIZE : Thay ñoåi kích thöôùc cöûa soå
WM_TIMER : Söï kieän veà thôøi gian
Windows duøng moät haøng ñôïi ñeå chöùa thoâng ñieäp nhaän ñöôïc, moãi moät chöông trình ñeàu coù
moät haøng ñôïi chöùa thoâng ñieäp rieâng.
Windows seõ chuyeån thoâng ñieäp töø haøng ñôïi chöùa thoâng ñieäp cuûa heä thoáng ñeán haøng ñôïi
chöùa thoâng ñieäp cuûa chöông trình.
Haøng ñôïi chöùa thoâng ñieäp cuûa chöông trình chòu traùch nhieäm giöõ taát caû caùc thoâng ñieäp
cuûa taát caû caùc cöûa soå thuoäc chöông trình.
Message: Trao đổi thông tin giữa chương trình ứng dụng và hệ điều hành.
Thủ tục Window: Được gọi bởi hệ thống để xử lý các Message nhận được.
Hàng đợi Message: Mỗi chương trình có 1 hàng đợi Message để chứa các Message. Mỗi chương trình có vòng lặp Message.
8. Quá trình làm việc của các ánh xạ thông báo (Message Map) :
Quá trình làm việc này khảo sát các macro DECLARE_MESSAGE_MAP, BEGIN_MESSAGE_MAP, và
END_MESSAGE_MAP trong Afxwin.h và mã lệnh cho hàm CWnd::WindowProc trong Wincore.cpp
// In the class declaration
DECLARE_MESSAGE_MAP()
// In the class implementation
BEGIN_MESSAGE_MAP(CMainWindow, CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
Để phân phối thông báo, khung ứng dụng gọi hàm ảo WindowProc (mà lớp CMainWindow kế thừa từ CWnd).
Hàm WindowProc gọi OnWndMsg mà trong đó gọi tiếp hàm GetMessageMap để lấy con trỏ chỉ đến
CMainWindow::messageMap và tìm kiếm CMainWindow::_messageEntries cho những thông báo có ID trùng với ID của các thông báo đang chờ xử lý. Nếu kết quả tìm thấy, lớp CMainWindow tương ứng (của những địa chỉ được lưu trong dãy _messageEntries với ID của thông báo) được gọi. Ngược lại, OnWndMsg tham khảo CMainWindow::messageMap cho một con trỏ chỉ tới CFrameWnd::messageMap và lặp lại quá trình cho lớp cơ sở. Nếu lớp cơ sở không có một điều khiển (handler) cho thông báo, khung ứng dụng the framework phát triển lên mức khác và tham khảo đến lớp cơ sở cha.
Các ánh xạ thông báo CMainWindow thể hiện dạng sơ đồ như hình dưới đây và thể hiện các nhánh truy
xuất/tìm kiếm cho một điều khiển trùng với ID của thông báo đã cho, bắt đầu với các ánh xạ thông báo cho
CMainWindow.
9. Trình töï thöïc hieän moät chöông trình Windows
Ñaêng kyù lôùp cöûa soå
Taïo cöûa soå, hieån thò cöûa soå
Xöû lyù caùc thoâng ñieäp nhôø voøng laëp message vaø thuû tuïc cöûa soå
10. Caáu truùc cuûa thoâng ñieäp
typedef struct tagMSG
{
HWND hwnd; //trò ñieàu quaûn
UINT message; // kieåu thoâng ñieäp
WPARAM wParam; //tuøy theo loaïi
LPARAM lParam; //thoâng ñieäp
DWORD time; //thôøi gian thoâng ñieäp
ñaët trong haøng ñôïi
POINT pt; //vò trí con troû chuoät
} MSG;
Trò ñieàu quaûn : laø tham chieáu ñeán cöûa soå maø thoâng ñieäp ñöôïc gôûi tôùi.
Kieåu thoâng ñieäp: ñaây laø moät trong nhöõng ñònh nghóa ñöôïc xaùc ñònh trong taäp tin tieâu ñeà windows.h hay nhöõng taäp tin tieâu ñeà töông ñöông. Cuï theå nhö: thoâng ñieäp Windows laø WM_ (ví duï: WM_PAINT, WM_CLOSE, v..v)
lParam vaø wParam : chuùng ñöôïc cung caáp nhö laø caùc thoâng tin coäng theâm caàn thieát ñeå laøm saùng toû thoâng ñieäp. Noäi dung cuûa hai tham soá naøy khaùc nhau tuøy thuoäc vaøo loaïi thoâng ñieäp cuï theå.
11. Caáu truùc lôùp cöûa soå
Typedef struct _WNDCLASSEX{
UINT cbSize; //kích thöôùc cuûa caáu truùc
UINT style; //kieåu thanh cuoän
WNDPROC lpfnWndProc;//con troû ñeán thuû tuïc cöûa soå
int cbClsExtra;//caùc byte phuï troäi ñeå theâm
vaøo caáu truùc WNDCLASS khi ñaêng kyù
int cbWndExtra; ;//caùc byte phuï troäi ñeå theâm
vaøo caùc ñoái töôïng cöûa soå ñöôïc taïo bôûi lôùp naøy
HANDLE hInstance; //istance laøm chuû class naøy
HICON hIcon; //bieåu töông khi cöûa soå hieån thò
HCURSOR hCursor; //con troû chuoät
HBRUSH hbrBackground; //maøu neàn
LPCTSTR lpszMenuName; //teân menu
LPCTSTR lpszClassName; //teân lôùp nhaän bieát
WNDCLASS naøy cho heä thoáng
} WNDCLASSEZ;
12. NGỮ CẢNH THIẾT BỊ
Nhôø thieát bò ngöõ caûnh, caùc haøm veõ trôû neân ñôn giaûn hôn vôùi caùc tham soá ñöôïc giaûm ñeán möùc toái thieåu. Ñeå nhaän moät thieát bò ngöõ caûnh , öùng duïng MFC seõ goïi CWnd::GetDC ñeå taïo moät ñoái töôïng CDC ñaïi dieän moät ngöõ caûnh thieát bò Windows vaø giaûi phoùng noù khi hoaøn thaønh taùc vuï veõ baèng caùch goïi CWnd::ReleaseDC.
Caùc lôùp ngöõ caûnh thieát bò :
CPaintDC: Veõ moät vuøng trong cöûa soå, ñaùp öùng vôùi söï kieän WM_PAINT, chæ duøng trong
haøm OnPaint()
CClientDC:taïo ra moät ngöõ caûnh thieát bò coù theå söû duïng ngoaøi haøm OnPaint().
CWindowDC: Veõ baát kyø moät cöûa soå
CMetaFileDC: Veõ moät GDI metafile
13. CÁC PHƯƠNG PHÁP VẼ
Quy trình vẽ :
Möôïn DC
Thöïc hieän caùc thao taùc veõ
Traû laïi DC cho Windows
Hai haøm möôïn vaø traû DC thoâng duïng laø
BeginPaint vaø EndPaint.
Ví duï:
PAINTSTRUCT ps;
CDC* pDC = BeginPaint (&ps);
// Do some drawing
EndPaint (&ps);
Coù theå duøng GetDC vaø RealeaseDC ñeå thöïc hieän thao taùc veõ ngay khi coù bieán coá nhaäp nhö chuoät hay baøn phím ñöôïc nhaán. GetDC traû veà handle ñeán toaøn boä vuøng client cuûa cöûa soå öùng duïng.
Ví duï:
CDC* pDC = GetDC ();
// Do some drawing
ReleaseDC (pDC);
14. Taïo moät ñoái töôïng ngöõ caûnh thieát bò :
Vi dụ :
CRect rect;
GetClientRect (&rect);
CClientDC dc (this);
dc.MoveTo (rect.left, rect.top);
dc.LineTo (rect.right, rect.bottom);
dc.MoveTo (rect.right, rect.top);
dc.LineTo (rect.left, rect.bottom);
Ñeå löïa choïn moät ñoái töôïng ngöõ caûnh thieát bò,duøng haøm SelectObject
VD: dc.SelectObject (pPen);
dc.SelectObject (pBrush);
dc.Ellipse (0, 0, 100, 100);
Caùc ñoái töôïng coù theå ñöôïc choïn vôùi SelectObject:
•Pens, •Brushes, •Fonts, •Bitmaps, •Palettes, •Regions
Veõ ñöôøng thaúng vaø ñöôøng cong :
MoveTo: Ñaët vò trí hieän haønh tröôùc khi veõ.
LineTo : veõ ñoaïn thaúng töø vò trí hieän taïi ñeán ñieåm cuoái ñoaïnthaúng
Polyline : Veõ ñöôøng thaúng gaáp khuùc ñoaïn thaúng vöøa veõ.PolylineTo: Veõ ñoaïn thaúng vaø ñaët vò trí hieän haønh taïi cuoái.
Arc : Veõ moät cung
ArcTo : Veõ moät cung vaø ñaët vò trí hieän haønh taïi ñieåm cuoái cung vöøa veõ.
PolyBezier: Veõ moät hoaëc nhieàu ñöôøng cong baát kyø.
PolyBezierTo: Veõ ñöôøng cong vaø ñaët vò trí hieän haønh taïi cuoái ñöôøng cong vöøa veõ.
Ví dụ 1 :
dc.MoveTo (0,0);
dc.LineTo (0,100);
dc.LineTo (100,100);
Ví dụ 2 :
POINT aPoint[5] = {0,0,0,100,100,100,100,0,0,0};
dc.Polyline (aPoint, 5);
Taïo moät buùt veõ :
CPen pen (PS_SOLID, 1, RGB (255, 0, 0));
CPen pen;
pen.CreatePen (PS_SOLID, 1,RGB(255,0, 0))
Söû duïng caáu truùc LOGPEN
LOGPEN lp;
lp.lopnStyle = PS_SOLID;
lp.lopnWidth.x = 1;
lp.lopnColor = RGB (255, 0, 0);
pen.CreatePenIndirect (&lp);
Taïo moät coï veõ:
CBrush brush (RGB (255, 0, 0));
Hoaëc
CBrush brush;
brush.CreateSolidBrush(RGB(255,0, 0));
CBrush brush (HS_DIAGCROSS, RGB(255, 0, 0));
Hoaëc:
CBrush brush;
brush.CreateHatchBrush (HS_DIAGCROSS,RGB (255, 0, 0));
Söû duïng caáu truùc LOGBRUSH
LOGBRUSH logBrush;
logBrush.lbStyle = BS_HATCHED;
logBrush.lbColor = RGB(0, 192, 192);
logBrush.lbHatch = HS_CROSS;
CBrush brush;
brush.CreateBrushIndirect(&logBrush);
Söû duïng maãu Bitmap
CBrush brush;
CBitmap *pBitmap=new CBitmap;
pBitmap->LoadBitmap(IDB_BITMAP1);
brush.CreatePatternBrush(pBitmap);
15. Hieån thò hình aûnh :
Taïo moät bipmap:
CBitmap bitmap;
bitmap.CreateCompatibleBitmap (&dc, nWidth, nHeight);
Sao cheùp bitmap:
o Haøm BitBlt cuûa lôùp CDC coù taùc duïng cheùp noäi dung bitmap töø DC nguoàn sang DC ñích.
BOOL BitBlt(int x, int y, int nWidth, int nHeight,
CDC* pSrcDC, int xSrc, int ySrc,DWORD dwRop);
- x, y: goùc traùi treân cuûa vuøng DC ñích
-nWidth, nHeight: kích thöôùc vuøng DC ñích
-pSrcDC: con troû ñeán DC nguoàn
-xSrc, yScr: goùc traùi treân cuûa vuøng aûnh ñöôïc cheùp trongDC nguoàn
-dwRop: cheá ñoä cheùp aûnh
o Haøm StrechBlt gioáng nhö haøm BitBlt, cho pheùp phoùng tohay thu nhoû aûnh.
BOOL StrechBlt( int x, int y, int nWidth, int nHeight,CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth,int nSrcHeight, DWORD dwRop);
- x, y: goùc traùi treân cuûa vuøng DC ñích
- nWidth, nHeight: kích thöôùc vuøng DC ñích
- pPSrcDC: con troû ñeán DC nguoàn
- xSrc, yScr: goùc traùi treân cuûa vuøng aûnh ñöôïc cheùp trong DC nguoàn
- nSrcWidth, nSrcHeight: kích thöôùc vuøng DC nguoàn
- dwRop: cheá ñoä cheùp aûnh
Söû duïng bipmap töø taøi nguyeân:
o Import aûnh bitmap vaøo Resource
-Vaøo Resource View, choïn Import.
- Neáu aûnh bitmap nhieàu hôn 256 maøu thì khoâng theå xem hay söûa ñoåi trong Resource View cuûa Visual C++.
o Load aûnh bitmap töø Resource
- Söû duïng haøm LoadBitmap cuûa lôùp CBitmap ñeåà load aûnh bitmap trong resource.
- Sau khi söû duïng xong thì caàn huûy ñoái töôïng bitmap baèng haøm DeleteObject.
Ví duï:
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);
. . .
bmp.DeleteObject();
Hieån thò Bitmap:
CPaintDC dc(this);
CRect rect;
GetClientRect(rect);
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);
BITMAP bm;
CDC TempDC;
TempDC.CreateCompatibleDC(&dc);
TempDC.SelectObject(&bmp);
bmp.GetBitmap(&bm);
dc.BitBlt(rect.TopLeft().x , rect.TopLeft().y, bm.bmWidth,
bm.bmHeight,&TempDC, 0, 0, SRCCOPY)
TempDC.DeleteDC()
16. MOUSE
Thoâng ñieäp WM_NCHITTEST
Khi moät cöûa soå nhaän moät thoâng ñieäp töø chuoät, noù nhaän thoâng ñieäp WM_NCHITTEST
Thoâng ñieäp naøy cho bieát vuøng naøo treân cöûa soå xaûy ra söï kieän chuoät
Ñeå bieát ñöôïc vuøng naøo xaûy ra söï kieän chuoät, ta khai baùo nhö sau:
afx_msg UINT OnNcHitTest( CPoint point );
ON_WM_NCHITTEST () // In the message map
UINT CMainWindow::OnNcHitTest (CPoint point)
{
UINT nHitTest = CFrameWnd::OnNcHitTest (point);
return nHitTest;
}
Thoâng ñieäp WM_MOUSELEAVE
Khi moät con troû di chuyeån treân cöûa soå , cöûa soå seõ nhaän ñöôïc thoâng ñieäp WM_MOUSEMOVE
Khi con troû rôøi khoûi cöaû soå -> cöûa soå seõ nhaän ñöôïc thoâng ñieäp WM_MOUSELEAVE
Khi con troû coøn naèm treân cöaû soå , cöûa soå seõ nhaän ñöôïc thoâng ñieäp M_MOUSEHOVER
Ñeå nhaän ñöôïc nhöõng thoâng ñieäp treân, ta duøng haøm TrackMouseEvent
::TrackMouseEvent chaáp nhaän duy nhaát moät giaù trò: Ñoù laø con troû cuûa caáu truùc TRACKMOUSEEVENT . Caáu truùc naøy ñöôïc ñònh nghóa trong taäp tin Winuser.h:
typedef struct tagTRACKMOUSEEVENT {
DWORD cbSize;
DWORD dwFlags;
HWND hwndTrack;
DWORD dwHoverTime;
} TRACKMOUSEEVENT
Thay đổi con trỏ chuột :
Coù theå duøng haøm CWnd::SetCursor đcó thể thay đổi hình dạng con trỏ chuột.
Ví duï
BOOL CMouseDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(m_bCursor)
{
SetCursor(AfxGetApp()->
LoadCursor(IDC_DRAW_CURSOR));
return TRUE;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
17. KEYBOARD :
Thông điệp của keyboard
WM_KEYDOWN / WM_KEYUP: phát sinh khi 1 phím (không phải là phím hệ thống) được nhấn xuống/thả ra
o Hàm xử lý tương ứng: CWnd::OnKeyDown, CWnd::OnKeyUp
o wParam: virtual-key code
o lParam: chứa các thông tin khác (số lần lặp lại phím, scan code, extended key,…)
WM_CHAR: là kết quả phát sinh do message WM_KEYDOWN, báo hiệu 1 ký tự in được (printed character) đã được tạo ra
o Hàm xử lý tương ứng: CWnd::OnChar
o wParam: mã ký tự
o lParam: chứa các thông tin khác (số lần lặp lại do nhấn giữ phím, có phím Alt nhấn kèm,…)
Các hàm xử lý thông điệp liên quan đến bàn phím có dạng:
afx_msg void OnMsgName (UINT nChar, UINT nRepCnt, UINT nFlags)
o nChar: mã phím ảo được nhấn hoặc thả
o nRepCnt: số lần nhấn/thả phím tương ứng
o nFlags: cờ liên quan (xem thêm trong MSDN)
18. DIALOG :
Nguyên tắc gọi các dialog thường gặp (trừ dialog Find and Replace):
Tạo đối tượng thuộc lớp dialog quan tâm (cung cấp các thông tin cơ bản theo qui định)
Gọi hàm DoModal() để hiển thị
Lấy các giá trị quan tâm từ đối tượng đã khai báo
19. LOAD VÀ HIỂN THỊ MENU :
Xác định menu bar khi tạo cửa sổ:
Create(NULL, _T("My Application"),
WS_OVERLAPPEDWINDOW, rectDefault, NULL,
MAKEINTRESOURCE(IDR_MAINFRAME));
Thay đổi menu bar:
CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
SetMenu(&menu);
menu.Detach();
MAKEINTRESOURCE: macro dùng để chuyển đổi 1 số nguyên (resource ID) thành dạng PSTR
CMenu::LoadMenu: load 1 resource menu bar và gán vào đối tượng CMenu
CWnd::SetMenu: gán menu bar cho 1 cửa sổ
CMenu::Detach: gỡ bỏ menu bar ra khỏi đối tượng
CMenu, để menu bar không bị huỷ bỏ cùng với đối tượng CMenu khi ra khỏi phạm vi khai báo
Lớp CMenu
• Theo tác trên menu:
o DeleteMenu: Xoá một đối tượng trên menu
o TrackPopupMenu: hiển thị menu popup nổi
• Thao tác trên các menuitem:
o AppendMenu: thêm vào cuối menu một menuitem.
o InsertMenu: thêm một đối tượng menu tại một vị trí xác định
o ModifyMenu: chỉnh sửa một đối tượng menu xác định.
Lớp CMenu
• Thao tác trên các menuitem
o CheckMenuItem: thêm/bỏ dấu check phía trước một menuitem
o CheckMenuRadioItem: check một menuitem trong một nhóm các menuitem
o EnableMenuItem: thiết lập menuitem các trạng thái enable (MF_ENABLED), disable (MF_DISABLED), gray(MF_GRAYED).
o GetMenuItemCount: lấy số lượng menuitem trong một menu
20. XỬ LÝ KHI MENU ITEM ĐƯỢC CHỌN :
WM_MENUSELECT: phát sinh khi user tác động lên menu. Thông điệp này có thể dùng để cập nhật trạng thái của menu (trường hợp menu thay đổi theo ngữ cảnh – Context-sensitive Menu)
• Hàm xử lý tương ứng: CWnd::OnMenuSelect
wParam:
o LOWORD(wParam): ID của menu item hoặc index của menu popup
o HIWORD(wParam): các thông tin khác (trạng thái menu, loại menu, …). MF_POPUP; MF_CHECKED;
MF_DISABLED, MF_GRAYED; MF_SEPARATOR;
MF_SYSMENU,…
lParam: handle của menu
WM_COMMAND: phát sinh khi user chọn 1 menu item
• Hàm xử lý tương ứng: CWnd::OnCommand
• wParam:
o LOWORD(wParam): ID của menu item hoặc của control
o HIWORD(wParam): nguồn gốc phát sinh, 1 nếu sinh ra do 1 phím tắt; 0 nếu chọn trực tiếp từ menu
• lParam:
o NULL nếu message này phát sinh từ menu
o Nếu message phát sinh từ 1 control, lParam sẽ chứa handle của control đó.
Xử lý lệnh của menu item
• Dựa trên message WM_COMMAND
• Định nghĩa message map
ON_COMMAND(IDM_ABOUT, OnAbout)
ON_COMMAND(IDM_EXIT, OnExit)
Viết hàm xử lý
void CDialogDemoDlg::OnAbout()
{
// TODO: Add your command handler code here
MessageBox("Hello! World");
}
Tạo pop-up menu
o Sử dụng ClassWizard để thêm xử lý cho thông điệp WM_CONTEXTMENU
o Hàm xử lý CWnd::OnContextMenu
o Hiển thị một menu pop-up nổi
BOOL CMenu::TrackPopupMenu(UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect=0);
nFlags: cờ vị trí trên màn hình
(TPM_CENTERALIGN , TPM_LEFTALIGN , TPM_RIGHTALIGN), cờ chỉ phím nhấn của chuột
(TPM_LEFTBUTTON, TPM_RIGHTBUTTON)
Tạo pop-up menu
• Viết hàm xử lý
void CDialogDemoDlg::OnContextMenu(CWnd* pWnd,
CPoint point)
{
// TODO: Add your message handler code here
CMenu menu;
menu.LoadMenu(IDR_MENU1);
menu.GetSubMenu(1)-> TrackPopupMenu
(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x,
point.y, this);
}
21. THAY ĐỔI TRẠNG THÁI MENU :
Cách xử lý:
void CDialogDemoDlg::OnHelpTest2()
{
// TODO: Add your command handler code here
CMenu *pMenu;
pMenu = GetMenu();
pMenu->CheckMenuItem(ID_HELP_TEST2,
MF_CHECKED | MF_BYCOMMAND);
MessageBox("Hello! Test 2");
}
Nhóm lệnh :
Là 1 nhóm menu item hoạt động theo nguyên tắc “Chỉ có 1 phần tử được chọn tại 1 thời điểm”
VD. Chức năng vẽ hình “Line / Circle / Rectangle”
Cách thức xử lý ?
Cách 1: map tất cả xử lý của các menu item này vào chung 1 hàm xử lý
Cách 2: dùng macro ON_COMMAND_RANGE
Cách 1: map tất cả xử lý của các menu item này vào
chung 1 hàm xử lý
// Định nghĩa Message map
ON_COMMAND (ID_DRAW_LINE, Draw)
ON_COMMAND (ID_DRAW_CIRCLE, Draw)
ON_COMMAND (ID_DRAW_RECTANGLE, Draw)
• // Hàm xử lý chung, xác định item hiện hành
void CAAADlg::Draw () {
m_nCurrentDraw = (UINT)
LOWORD(GetCurrentMessage()->wParam);
}
Cách 2: dùng macro ON_COMMAND_RANGE
Lưu ý: các ID đặt trong macro này phải có giá trị liên
tục
// Định nghĩa Message map
ON_COMMAND_RANGE (ID_DRAW_LINE,
ID_DRAW_RECTANGLE, Draw)
• // Hàm xử lý chung, xác định item hiện hành
void CAAADlg::Draw (UINT nID) {
m_nCurrentDraw = nID;
}
22. TIẾN TRÌNH XỬ LÝ SỰ KIỆN :
Haøm AfxWndProc() nhaän thoâng baùo, tìm ñoái töôïng CWnd cuûa thoâng baùo vaø goïi haøm fxCallWndProc()
Haøm AfxCallEndProc() löu thoâng baùo vaø goïi haøm WindowProc()
Haøm WindowProc() gôûi thoâng baùo ñeán haøm OnWndMsg() vaø neáu chöa ñöôïc xöû lyù thì goïi haøm DefWindowProc()
Haøm OnWndMsg() goïi haøm OnCommand (cho caùc thoâng baùo WM_COMMAND), hoaëc OnNotify() (cho caùc thoâng baùo WM_NOTIFY). Caùc thoâng baùo coøn laïi, haøm OnWndMsg() tìm kieám moät sô ñoà thoâng baùo (Message map) cuûa lôùp cho boä phaän ñieàu khieån ñeå xöû lyù. Neáu haøm OnWndMsg() khoâng tìm thaáy boä phaän ñieàu khieån, noù seõ traû veà thoâng baùo cho haøm WindowProc() ñeå gôûi ñeán haøm DefWindowProc().
Haøm OnCommand() kieåm tra neáu ñoù laø moät khai baùo ñieàu khieån (lParam khaùc NULL) thì phaûn hoài thoâng baùo cho ñieàu khieån taïo ra khai baùo. Ngöôïc laïi haøm OnCommand() seõ goïi haøm OnCmdMsg().
Haøm OnNotify() cuõng phaûn hoài thoâng baùo ñeán ñieu khieån taïo ra khai baùo, neáu thaát baïi seõ goïi haøm OnCmdMsg()
Haøm OnCmdMsg() phuï thuoäc vaøo lôùp nhaän thoâng baùo, seõ laø caùc thoâng baùo leänh vaø khai baùo ñieàu khieån coù trong moät ñöôøng truyeàn leänh (Command Routing). Noù kieåm tra sô ñoà thoâng baùo vaø goïi haøm xöû lyù töông öùng.
23. CONTROL
Moät control gôûi thoâng baùo ñeán cöûa soå chính qua message WM_COMMAND
Tuøy theo moãi loaïi control maø thoâng baùo naøy bieán ñoåi ôû hai tham soá lParam vaø wParam. Hai tham soá naøy cho pheùp nhaän daïng control ñaõ gôûi message vaø haønh ñoäng naøo.
Ví duï: Khi nhaán chuoät vaøo moät PushButton -> phaùt sinh thoâng ñieäp BN_CLICKED.
Haàu heát öùng duïng MFC cung caáp saün caùc haøm vaø khai baùo cho nhöõng söï kieän cuûa caùc controls.
Ví duï: Khi nhaán chuoät vaøo moät PushButton coù ID laø IDC_BUTTON -> Haøm xöû lyù söï kieän naøy laø OnButtonClicked:
ON_BN_CLICKED (IDC_BUTTON, OnButtonClicked)
Push Button :
Push Button laø moät control button ñöôïc taïo vôùi style laø BS_PUSHBUTTON
Khi ñöôïc choïn, push button seõ gôûi ñeán cöûa soå chính thoâng baùo BN_CLICKED trong WM_COMMAND message.
Haøm xöû lyù
ON_BN_CLICKED (IDC_BUTTON, OnButtonClicked)
void CMainWindow :: OnButtonClicked(){
MessageBox (_T(“I’ve been clicked!”);
}
Check Boxes :
Check Boxes laø moät control button ñöôïc taïo vôùi style laø
BS_CHECKBOX, BS_AUTOCHECKBOX, BS_3STATE hoaëc BS_AUTO3STATE.
BS_CHECKBOX vaø BS_AUTOCHECKBOX coù theå coù 2 traïng thaùi: choïn vaø khoâng choïn.
Moät check boxes ñöôïc choïn hoaëc khoâng choïn vôùi haøm CButton::SetCheck.
m_wndCheckBox.SetCheck (BST_CHECKED);
m_wndCheckBox.SetCheck (BST_UNCHECKED);
Ñeå bieát ñöôïc moät check boxes ñang ñöôïc choïn hay khoâng choïn, duøng haøm CButton :: GetCheck.
void CMainWindow::OnCheckBoxClicked () {
m_wndCheckBox.SetCheck (m_wndCheckBox.GetCheck () ==
BST_CHECKED ? BST_UNCHECKED : BST_CHECKED);
}
24. Customizing a Control's Color :
MFC hoã trôï hai kyõ thuaät ñeå thay ñoåi moät control color, döïa vaøo cô cheá laø moät control khi ñöôïc veõ laïi seõ gôûi ñeán cöûa soå chính moat message bao haøm handle cuûa thieát bò ngöõ caûnh duøng ñeå veõ.
Cöûa soå chính cuûa öùng duïng coù theå goïi hai haøm CDC::SetTextColor vaø CDC::SetBkColor.
Message maø moät control gôûi ñeán cöûa soå chính cuûa öùng duïng thay ñoåi tuøy theo moãi loaïi control.
Ví duï:
Moät listbox gôûi WM_CTLCOLORLISTBOX message.
Moät static control gôûi WM_CTLCOLORSTATIC message.
HaØm xöû lyù :
afx_msg HBRUSH OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor)
Cấu trúc Document / Wiew :
Vai trò của mỗi class được mô tả như sau:
Lớp Vai trò
CWinApp Tạo tất cả thành phần khác trong ứng dụng. Đây là lớp nhận thông báo sự kiện
và truyền tới lớp CView và CDocument
CFrameWnd
- Tạo và quản lý khung cửa sổ, chứa menu, toolbar, scrollbar và các đối tượng nhìn thấy được gắn vào cửa sổ.
- Xác định số tài liệu nhìn thấy được trong một thời điểm bất kỳ
CMDIFrameWnd
- (thể hiện bởi CMainFrame trong project) là khung chính của ứng dụng
- Cung cấp không gian bao bọc trên màn hình nền diễn ra toàn bộ tương tác ứng
dụng.
- Cửa sổ này là khung được gắn menu và thanh công cụ
CMDIChildFrameWnd - (thể hiện bởi CChildFrame trong project) là khung chứa lớp CView- Là lớp truyền thông điệp (message) và sự kiện (event) tới các lớp hiển thị để
xử lý hay hiển thị.
CDocument
- Chứa tài liệu của ứng dụng. Đây là nơi sẽ lưu trữ cấu trúc dữ liệu cần thiết để
chứa và thao tác dữ liệu tạo nên tài liệu.
- Lớp này nhận dữ liệu từ lớp CView và truyền thông tin sang lớp CView.
- Lưu giữ và lấy dữ liệu về tài liệu từ các file
CView
- Quản lý phần hiển thị phần trình bày nhìn thấy của tài liệu cho người dùng
xem.
- Truyền thông tin vào lớp CDocument và nhận thông tin từ lớp CDocument.
Việc tương tác và trao đổi thông tin giữa CView và CDocument được thể hiện như sau:
Hay:
Với dạng SDI, sự liên kết thể hiện như sau:
Với dạng MDI, sự liên kết thể hiện như sau:
1. Qui trình hoạt động của chương trình ứng dụng :
• Cửa sổ được hiển thị lên màn hình.
• Windows chờ cửa sổ gửi thông điệp.
• Các thông điệp được Windows gửi trả lại chương trình ứng dụng thông qua lời gọi hàm của chúng trong chương trình ứng dụng.
• Khi nhận được thông điệp, chương trình ứng dụng gọi các hàm API và hàm của riêng chúng để thực hiện công việc mong muốn.
2. Phát sinh và xử lý thông điệp :
3. Qui trình xử lý thông điệp :
4. Ví dụ xử lý vòng lập thông điệp :
// Vòng lặp xử lý thông điệp trong 1 ứng dụng –
// Message loop
MSG msg;
// lấy thông điệp ra khỏi hàng đợi của ứng dụng
while (GetMessage (&msg, NULL, 0, 0))
{
/*chuyển đổi các phím ảo (virtual key) thành các thông điệp ký tự*/
TranslateMessage(&msg);
// chuyển message đến hàm xử lý thông điệp của cửa
// sổ tương ứng
DispatchMessage(&msg);
}
return msg.wParam;
5. Làm sao để xử lý 1 thông điệp ???
MFC dùng Message Map để liên kết các thông điệp với những hàm thành phần của lớp cửa
sổ.
Mỗi thông điệp sẽ được xử lý bởi 1 hàm thành phần tương ứng
BEGIN_MESSAGE_MAP(CDemoDlg, CDialog)
//{{AFX_MSG_MAP(CDemoDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
ON_WM_PAINT là 1 macro được định nghĩa trong Afxmsg_.h, mặc nhiên liên kết thông điệp
WM_PAINT với hàm OnPaint
Thêm xử lý thông điệp WM_LBUTTONDOWN
Bổ sung thêm khai báo hàm xử lý thông điệp afx_msg void OnLButtonDown(UINT nFlags, CPoint
point);
Bổ sung 1 macro trong khai báo message map
ON_WM_LBUTTONDOWN()
Viết hàm thực thi OnLButtonDown
void CDemoDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
MessageBox("Nhan phim trai chuot", "Mouse",MB_OK);
CDialog::OnLButtonDown(nFlags, point);
}
Sử dụng ClassWizard
(Ctrl-W)
Click chuột phải, chọn
ClassWizard
Trên hộp thoại MFC ClassWizard, chọn tab Message Maps.
Chọn lựa lớp (trong Class name), ID của đối tượng (Object IDs) cần thêm sự
kiện vào (Messages). Chọn Add Functions Các khai báo hàm, cấu trúc hàm được thêm tự động vào
những vị trí thích hợp trên tập tin .CPP và .H của lớp.Viết hàm xử lý thông điệp WM_LBUTTONDBCLK dùng ClassWizard.
Chọn CDemoDlg trong Class name
Chọn CDemoDlg trong Object IDs. Chọn WM_LBUTTONDBCLK trong Messages.
Nhấn Add Functions.
Môi trường lập trình chèn khai báo hàm afx_msg void OnLButtonDblClk(UINT nFlags, CPoint
point);
trong khai báo lớp CDemoDlg
Hàm thực thi đã được chèn
void CDemoDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
/* TODO: Add your message handler code here and/or
call default*/
CDialog::OnLButtonDblClk(nFlags, point);
}
Chỉnh sửa hàm xử lý thông điệp:
void CDemoDlg::OnLButtonDblClk(UINT nFlags, CPoint
point)
{
/* TODO: Add your message handler code here and/or
call default */
MessageBox("Nhan kep phim trai chuot",
"Mouse",MB_OK);
Dialog::OnLButtonDblClk(nFlags, point);
}
6. Cô cheá gôûi – nhaän thoâng ñieäp
Moïi söï kieän xaûy ra treân moät chöông trình Windows ñeàu thoâng qua nhöõng thoâng ñieäp (messages).
Thoâng ñieäp ñoù laø: nhaán moät nuùt treân baøn phím, dichuyeån hoaëc nhaán chuoät, thay ñoåi kích thöôùc cöûa soå…
Caùc thoâng ñieäp ñöôïc gôûi qua laïi giöõa öùng duïng vaøWindows, giöõa caùc öùng duïng vôùi nhau.
Khi nhaän ñöôïc thoâng ñieäp naøy thì chöông trình öùng duïng seõ coù haønh ñoäng thích hôïp vôùi thoâng ñieäp nhaän ñöôïc.
7. Mô hình lập trình Windows
Kỹ thuật lập trình sử dụng các hàm Windows API còn gọi là lập trình Windows SDK. Một ứng dụng xây dựng theo kỹ thuật này chứa đựng hàm WinMain (xử lý các thông báo (message) nhận được/gửi đi nhằm đáp ứng yêu cầu tương tác của người dùng và của hệ thống cũng như của ứng dụng khác) và hàm DefWinProc (điều phối hoạt động tương ứng với các thông báo nhận được). Tổ chức hệ thống của ứng dụng Windows dạng SDK như sau:
WM_CHAR:Moät kyù töï nhaäp töø baøn phím
WM_CREATE: Moät cöûa soå ñöôïc taïo ra.
WM_DESTROY: Huûy moät cöûa soå.
WM_LBUTTONDOWN: Nhaán phím traùichuoät.
WM_LBUTTONUP: Nhaû phím chuoät
WM_PAINT:Veõ laïi moät cöûa soå
WM_QUIT: Keát thuùc öùng duïng
WM_SIZE : Thay ñoåi kích thöôùc cöûa soå
WM_TIMER : Söï kieän veà thôøi gian
Windows duøng moät haøng ñôïi ñeå chöùa thoâng ñieäp nhaän ñöôïc, moãi moät chöông trình ñeàu coù
moät haøng ñôïi chöùa thoâng ñieäp rieâng.
Windows seõ chuyeån thoâng ñieäp töø haøng ñôïi chöùa thoâng ñieäp cuûa heä thoáng ñeán haøng ñôïi
chöùa thoâng ñieäp cuûa chöông trình.
Haøng ñôïi chöùa thoâng ñieäp cuûa chöông trình chòu traùch nhieäm giöõ taát caû caùc thoâng ñieäp
cuûa taát caû caùc cöûa soå thuoäc chöông trình.
Message: Trao đổi thông tin giữa chương trình ứng dụng và hệ điều hành.
Thủ tục Window: Được gọi bởi hệ thống để xử lý các Message nhận được.
Hàng đợi Message: Mỗi chương trình có 1 hàng đợi Message để chứa các Message. Mỗi chương trình có vòng lặp Message.
8. Quá trình làm việc của các ánh xạ thông báo (Message Map) :
Quá trình làm việc này khảo sát các macro DECLARE_MESSAGE_MAP, BEGIN_MESSAGE_MAP, và
END_MESSAGE_MAP trong Afxwin.h và mã lệnh cho hàm CWnd::WindowProc trong Wincore.cpp
// In the class declaration
DECLARE_MESSAGE_MAP()
// In the class implementation
BEGIN_MESSAGE_MAP(CMainWindow, CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
Để phân phối thông báo, khung ứng dụng gọi hàm ảo WindowProc (mà lớp CMainWindow kế thừa từ CWnd).
Hàm WindowProc gọi OnWndMsg mà trong đó gọi tiếp hàm GetMessageMap để lấy con trỏ chỉ đến
CMainWindow::messageMap và tìm kiếm CMainWindow::_messageEntries cho những thông báo có ID trùng với ID của các thông báo đang chờ xử lý. Nếu kết quả tìm thấy, lớp CMainWindow tương ứng (của những địa chỉ được lưu trong dãy _messageEntries với ID của thông báo) được gọi. Ngược lại, OnWndMsg tham khảo CMainWindow::messageMap cho một con trỏ chỉ tới CFrameWnd::messageMap và lặp lại quá trình cho lớp cơ sở. Nếu lớp cơ sở không có một điều khiển (handler) cho thông báo, khung ứng dụng the framework phát triển lên mức khác và tham khảo đến lớp cơ sở cha.
Các ánh xạ thông báo CMainWindow thể hiện dạng sơ đồ như hình dưới đây và thể hiện các nhánh truy
xuất/tìm kiếm cho một điều khiển trùng với ID của thông báo đã cho, bắt đầu với các ánh xạ thông báo cho
CMainWindow.
9. Trình töï thöïc hieän moät chöông trình Windows
Ñaêng kyù lôùp cöûa soå
Taïo cöûa soå, hieån thò cöûa soå
Xöû lyù caùc thoâng ñieäp nhôø voøng laëp message vaø thuû tuïc cöûa soå
10. Caáu truùc cuûa thoâng ñieäp
typedef struct tagMSG
{
HWND hwnd; //trò ñieàu quaûn
UINT message; // kieåu thoâng ñieäp
WPARAM wParam; //tuøy theo loaïi
LPARAM lParam; //thoâng ñieäp
DWORD time; //thôøi gian thoâng ñieäp
ñaët trong haøng ñôïi
POINT pt; //vò trí con troû chuoät
} MSG;
Trò ñieàu quaûn : laø tham chieáu ñeán cöûa soå maø thoâng ñieäp ñöôïc gôûi tôùi.
Kieåu thoâng ñieäp: ñaây laø moät trong nhöõng ñònh nghóa ñöôïc xaùc ñònh trong taäp tin tieâu ñeà windows.h hay nhöõng taäp tin tieâu ñeà töông ñöông. Cuï theå nhö: thoâng ñieäp Windows laø WM_ (ví duï: WM_PAINT, WM_CLOSE, v..v)
lParam vaø wParam : chuùng ñöôïc cung caáp nhö laø caùc thoâng tin coäng theâm caàn thieát ñeå laøm saùng toû thoâng ñieäp. Noäi dung cuûa hai tham soá naøy khaùc nhau tuøy thuoäc vaøo loaïi thoâng ñieäp cuï theå.
11. Caáu truùc lôùp cöûa soå
Typedef struct _WNDCLASSEX{
UINT cbSize; //kích thöôùc cuûa caáu truùc
UINT style; //kieåu thanh cuoän
WNDPROC lpfnWndProc;//con troû ñeán thuû tuïc cöûa soå
int cbClsExtra;//caùc byte phuï troäi ñeå theâm
vaøo caáu truùc WNDCLASS khi ñaêng kyù
int cbWndExtra; ;//caùc byte phuï troäi ñeå theâm
vaøo caùc ñoái töôïng cöûa soå ñöôïc taïo bôûi lôùp naøy
HANDLE hInstance; //istance laøm chuû class naøy
HICON hIcon; //bieåu töông khi cöûa soå hieån thò
HCURSOR hCursor; //con troû chuoät
HBRUSH hbrBackground; //maøu neàn
LPCTSTR lpszMenuName; //teân menu
LPCTSTR lpszClassName; //teân lôùp nhaän bieát
WNDCLASS naøy cho heä thoáng
} WNDCLASSEZ;
12. NGỮ CẢNH THIẾT BỊ
Nhôø thieát bò ngöõ caûnh, caùc haøm veõ trôû neân ñôn giaûn hôn vôùi caùc tham soá ñöôïc giaûm ñeán möùc toái thieåu. Ñeå nhaän moät thieát bò ngöõ caûnh , öùng duïng MFC seõ goïi CWnd::GetDC ñeå taïo moät ñoái töôïng CDC ñaïi dieän moät ngöõ caûnh thieát bò Windows vaø giaûi phoùng noù khi hoaøn thaønh taùc vuï veõ baèng caùch goïi CWnd::ReleaseDC.
Caùc lôùp ngöõ caûnh thieát bò :
CPaintDC: Veõ moät vuøng trong cöûa soå, ñaùp öùng vôùi söï kieän WM_PAINT, chæ duøng trong
haøm OnPaint()
CClientDC:taïo ra moät ngöõ caûnh thieát bò coù theå söû duïng ngoaøi haøm OnPaint().
CWindowDC: Veõ baát kyø moät cöûa soå
CMetaFileDC: Veõ moät GDI metafile
13. CÁC PHƯƠNG PHÁP VẼ
Quy trình vẽ :
Möôïn DC
Thöïc hieän caùc thao taùc veõ
Traû laïi DC cho Windows
Hai haøm möôïn vaø traû DC thoâng duïng laø
BeginPaint vaø EndPaint.
Ví duï:
PAINTSTRUCT ps;
CDC* pDC = BeginPaint (&ps);
// Do some drawing
EndPaint (&ps);
Coù theå duøng GetDC vaø RealeaseDC ñeå thöïc hieän thao taùc veõ ngay khi coù bieán coá nhaäp nhö chuoät hay baøn phím ñöôïc nhaán. GetDC traû veà handle ñeán toaøn boä vuøng client cuûa cöûa soå öùng duïng.
Ví duï:
CDC* pDC = GetDC ();
// Do some drawing
ReleaseDC (pDC);
14. Taïo moät ñoái töôïng ngöõ caûnh thieát bò :
Vi dụ :
CRect rect;
GetClientRect (&rect);
CClientDC dc (this);
dc.MoveTo (rect.left, rect.top);
dc.LineTo (rect.right, rect.bottom);
dc.MoveTo (rect.right, rect.top);
dc.LineTo (rect.left, rect.bottom);
Ñeå löïa choïn moät ñoái töôïng ngöõ caûnh thieát bò,duøng haøm SelectObject
VD: dc.SelectObject (pPen);
dc.SelectObject (pBrush);
dc.Ellipse (0, 0, 100, 100);
Caùc ñoái töôïng coù theå ñöôïc choïn vôùi SelectObject:
•Pens, •Brushes, •Fonts, •Bitmaps, •Palettes, •Regions
Veõ ñöôøng thaúng vaø ñöôøng cong :
MoveTo: Ñaët vò trí hieän haønh tröôùc khi veõ.
LineTo : veõ ñoaïn thaúng töø vò trí hieän taïi ñeán ñieåm cuoái ñoaïnthaúng
Polyline : Veõ ñöôøng thaúng gaáp khuùc ñoaïn thaúng vöøa veõ.PolylineTo: Veõ ñoaïn thaúng vaø ñaët vò trí hieän haønh taïi cuoái.
Arc : Veõ moät cung
ArcTo : Veõ moät cung vaø ñaët vò trí hieän haønh taïi ñieåm cuoái cung vöøa veõ.
PolyBezier: Veõ moät hoaëc nhieàu ñöôøng cong baát kyø.
PolyBezierTo: Veõ ñöôøng cong vaø ñaët vò trí hieän haønh taïi cuoái ñöôøng cong vöøa veõ.
Ví dụ 1 :
dc.MoveTo (0,0);
dc.LineTo (0,100);
dc.LineTo (100,100);
Ví dụ 2 :
POINT aPoint[5] = {0,0,0,100,100,100,100,0,0,0};
dc.Polyline (aPoint, 5);
Taïo moät buùt veõ :
CPen pen (PS_SOLID, 1, RGB (255, 0, 0));
CPen pen;
pen.CreatePen (PS_SOLID, 1,RGB(255,0, 0))
Söû duïng caáu truùc LOGPEN
LOGPEN lp;
lp.lopnStyle = PS_SOLID;
lp.lopnWidth.x = 1;
lp.lopnColor = RGB (255, 0, 0);
pen.CreatePenIndirect (&lp);
Taïo moät coï veõ:
CBrush brush (RGB (255, 0, 0));
Hoaëc
CBrush brush;
brush.CreateSolidBrush(RGB(255,0, 0));
CBrush brush (HS_DIAGCROSS, RGB(255, 0, 0));
Hoaëc:
CBrush brush;
brush.CreateHatchBrush (HS_DIAGCROSS,RGB (255, 0, 0));
Söû duïng caáu truùc LOGBRUSH
LOGBRUSH logBrush;
logBrush.lbStyle = BS_HATCHED;
logBrush.lbColor = RGB(0, 192, 192);
logBrush.lbHatch = HS_CROSS;
CBrush brush;
brush.CreateBrushIndirect(&logBrush);
Söû duïng maãu Bitmap
CBrush brush;
CBitmap *pBitmap=new CBitmap;
pBitmap->LoadBitmap(IDB_BITMAP1);
brush.CreatePatternBrush(pBitmap);
15. Hieån thò hình aûnh :
Taïo moät bipmap:
CBitmap bitmap;
bitmap.CreateCompatibleBitmap (&dc, nWidth, nHeight);
Sao cheùp bitmap:
o Haøm BitBlt cuûa lôùp CDC coù taùc duïng cheùp noäi dung bitmap töø DC nguoàn sang DC ñích.
BOOL BitBlt(int x, int y, int nWidth, int nHeight,
CDC* pSrcDC, int xSrc, int ySrc,DWORD dwRop);
- x, y: goùc traùi treân cuûa vuøng DC ñích
-nWidth, nHeight: kích thöôùc vuøng DC ñích
-pSrcDC: con troû ñeán DC nguoàn
-xSrc, yScr: goùc traùi treân cuûa vuøng aûnh ñöôïc cheùp trongDC nguoàn
-dwRop: cheá ñoä cheùp aûnh
o Haøm StrechBlt gioáng nhö haøm BitBlt, cho pheùp phoùng tohay thu nhoû aûnh.
BOOL StrechBlt( int x, int y, int nWidth, int nHeight,CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth,int nSrcHeight, DWORD dwRop);
- x, y: goùc traùi treân cuûa vuøng DC ñích
- nWidth, nHeight: kích thöôùc vuøng DC ñích
- pPSrcDC: con troû ñeán DC nguoàn
- xSrc, yScr: goùc traùi treân cuûa vuøng aûnh ñöôïc cheùp trong DC nguoàn
- nSrcWidth, nSrcHeight: kích thöôùc vuøng DC nguoàn
- dwRop: cheá ñoä cheùp aûnh
Söû duïng bipmap töø taøi nguyeân:
o Import aûnh bitmap vaøo Resource
-Vaøo Resource View, choïn Import.
- Neáu aûnh bitmap nhieàu hôn 256 maøu thì khoâng theå xem hay söûa ñoåi trong Resource View cuûa Visual C++.
o Load aûnh bitmap töø Resource
- Söû duïng haøm LoadBitmap cuûa lôùp CBitmap ñeåà load aûnh bitmap trong resource.
- Sau khi söû duïng xong thì caàn huûy ñoái töôïng bitmap baèng haøm DeleteObject.
Ví duï:
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);
. . .
bmp.DeleteObject();
Hieån thò Bitmap:
CPaintDC dc(this);
CRect rect;
GetClientRect(rect);
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);
BITMAP bm;
CDC TempDC;
TempDC.CreateCompatibleDC(&dc);
TempDC.SelectObject(&bmp);
bmp.GetBitmap(&bm);
dc.BitBlt(rect.TopLeft().x , rect.TopLeft().y, bm.bmWidth,
bm.bmHeight,&TempDC, 0, 0, SRCCOPY)
TempDC.DeleteDC()
16. MOUSE
Thoâng ñieäp WM_NCHITTEST
Khi moät cöûa soå nhaän moät thoâng ñieäp töø chuoät, noù nhaän thoâng ñieäp WM_NCHITTEST
Thoâng ñieäp naøy cho bieát vuøng naøo treân cöûa soå xaûy ra söï kieän chuoät
Ñeå bieát ñöôïc vuøng naøo xaûy ra söï kieän chuoät, ta khai baùo nhö sau:
afx_msg UINT OnNcHitTest( CPoint point );
ON_WM_NCHITTEST () // In the message map
UINT CMainWindow::OnNcHitTest (CPoint point)
{
UINT nHitTest = CFrameWnd::OnNcHitTest (point);
return nHitTest;
}
Thoâng ñieäp WM_MOUSELEAVE
Khi moät con troû di chuyeån treân cöûa soå , cöûa soå seõ nhaän ñöôïc thoâng ñieäp WM_MOUSEMOVE
Khi con troû rôøi khoûi cöaû soå -> cöûa soå seõ nhaän ñöôïc thoâng ñieäp WM_MOUSELEAVE
Khi con troû coøn naèm treân cöaû soå , cöûa soå seõ nhaän ñöôïc thoâng ñieäp M_MOUSEHOVER
Ñeå nhaän ñöôïc nhöõng thoâng ñieäp treân, ta duøng haøm TrackMouseEvent
::TrackMouseEvent chaáp nhaän duy nhaát moät giaù trò: Ñoù laø con troû cuûa caáu truùc TRACKMOUSEEVENT . Caáu truùc naøy ñöôïc ñònh nghóa trong taäp tin Winuser.h:
typedef struct tagTRACKMOUSEEVENT {
DWORD cbSize;
DWORD dwFlags;
HWND hwndTrack;
DWORD dwHoverTime;
} TRACKMOUSEEVENT
Thay đổi con trỏ chuột :
Coù theå duøng haøm CWnd::SetCursor đcó thể thay đổi hình dạng con trỏ chuột.
Ví duï
BOOL CMouseDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(m_bCursor)
{
SetCursor(AfxGetApp()->
LoadCursor(IDC_DRAW_CURSOR));
return TRUE;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
17. KEYBOARD :
Thông điệp của keyboard
WM_KEYDOWN / WM_KEYUP: phát sinh khi 1 phím (không phải là phím hệ thống) được nhấn xuống/thả ra
o Hàm xử lý tương ứng: CWnd::OnKeyDown, CWnd::OnKeyUp
o wParam: virtual-key code
o lParam: chứa các thông tin khác (số lần lặp lại phím, scan code, extended key,…)
WM_CHAR: là kết quả phát sinh do message WM_KEYDOWN, báo hiệu 1 ký tự in được (printed character) đã được tạo ra
o Hàm xử lý tương ứng: CWnd::OnChar
o wParam: mã ký tự
o lParam: chứa các thông tin khác (số lần lặp lại do nhấn giữ phím, có phím Alt nhấn kèm,…)
Các hàm xử lý thông điệp liên quan đến bàn phím có dạng:
afx_msg void OnMsgName (UINT nChar, UINT nRepCnt, UINT nFlags)
o nChar: mã phím ảo được nhấn hoặc thả
o nRepCnt: số lần nhấn/thả phím tương ứng
o nFlags: cờ liên quan (xem thêm trong MSDN)
18. DIALOG :
Nguyên tắc gọi các dialog thường gặp (trừ dialog Find and Replace):
Tạo đối tượng thuộc lớp dialog quan tâm (cung cấp các thông tin cơ bản theo qui định)
Gọi hàm DoModal() để hiển thị
Lấy các giá trị quan tâm từ đối tượng đã khai báo
19. LOAD VÀ HIỂN THỊ MENU :
Xác định menu bar khi tạo cửa sổ:
Create(NULL, _T("My Application"),
WS_OVERLAPPEDWINDOW, rectDefault, NULL,
MAKEINTRESOURCE(IDR_MAINFRAME));
Thay đổi menu bar:
CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
SetMenu(&menu);
menu.Detach();
MAKEINTRESOURCE: macro dùng để chuyển đổi 1 số nguyên (resource ID) thành dạng PSTR
CMenu::LoadMenu: load 1 resource menu bar và gán vào đối tượng CMenu
CWnd::SetMenu: gán menu bar cho 1 cửa sổ
CMenu::Detach: gỡ bỏ menu bar ra khỏi đối tượng
CMenu, để menu bar không bị huỷ bỏ cùng với đối tượng CMenu khi ra khỏi phạm vi khai báo
Lớp CMenu
• Theo tác trên menu:
o DeleteMenu: Xoá một đối tượng trên menu
o TrackPopupMenu: hiển thị menu popup nổi
• Thao tác trên các menuitem:
o AppendMenu: thêm vào cuối menu một menuitem.
o InsertMenu: thêm một đối tượng menu tại một vị trí xác định
o ModifyMenu: chỉnh sửa một đối tượng menu xác định.
Lớp CMenu
• Thao tác trên các menuitem
o CheckMenuItem: thêm/bỏ dấu check phía trước một menuitem
o CheckMenuRadioItem: check một menuitem trong một nhóm các menuitem
o EnableMenuItem: thiết lập menuitem các trạng thái enable (MF_ENABLED), disable (MF_DISABLED), gray(MF_GRAYED).
o GetMenuItemCount: lấy số lượng menuitem trong một menu
20. XỬ LÝ KHI MENU ITEM ĐƯỢC CHỌN :
WM_MENUSELECT: phát sinh khi user tác động lên menu. Thông điệp này có thể dùng để cập nhật trạng thái của menu (trường hợp menu thay đổi theo ngữ cảnh – Context-sensitive Menu)
• Hàm xử lý tương ứng: CWnd::OnMenuSelect
wParam:
o LOWORD(wParam): ID của menu item hoặc index của menu popup
o HIWORD(wParam): các thông tin khác (trạng thái menu, loại menu, …). MF_POPUP; MF_CHECKED;
MF_DISABLED, MF_GRAYED; MF_SEPARATOR;
MF_SYSMENU,…
lParam: handle của menu
WM_COMMAND: phát sinh khi user chọn 1 menu item
• Hàm xử lý tương ứng: CWnd::OnCommand
• wParam:
o LOWORD(wParam): ID của menu item hoặc của control
o HIWORD(wParam): nguồn gốc phát sinh, 1 nếu sinh ra do 1 phím tắt; 0 nếu chọn trực tiếp từ menu
• lParam:
o NULL nếu message này phát sinh từ menu
o Nếu message phát sinh từ 1 control, lParam sẽ chứa handle của control đó.
Xử lý lệnh của menu item
• Dựa trên message WM_COMMAND
• Định nghĩa message map
ON_COMMAND(IDM_ABOUT, OnAbout)
ON_COMMAND(IDM_EXIT, OnExit)
Viết hàm xử lý
void CDialogDemoDlg::OnAbout()
{
// TODO: Add your command handler code here
MessageBox("Hello! World");
}
Tạo pop-up menu
o Sử dụng ClassWizard để thêm xử lý cho thông điệp WM_CONTEXTMENU
o Hàm xử lý CWnd::OnContextMenu
o Hiển thị một menu pop-up nổi
BOOL CMenu::TrackPopupMenu(UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect=0);
nFlags: cờ vị trí trên màn hình
(TPM_CENTERALIGN , TPM_LEFTALIGN , TPM_RIGHTALIGN), cờ chỉ phím nhấn của chuột
(TPM_LEFTBUTTON, TPM_RIGHTBUTTON)
Tạo pop-up menu
• Viết hàm xử lý
void CDialogDemoDlg::OnContextMenu(CWnd* pWnd,
CPoint point)
{
// TODO: Add your message handler code here
CMenu menu;
menu.LoadMenu(IDR_MENU1);
menu.GetSubMenu(1)-> TrackPopupMenu
(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x,
point.y, this);
}
21. THAY ĐỔI TRẠNG THÁI MENU :
Cách xử lý:
void CDialogDemoDlg::OnHelpTest2()
{
// TODO: Add your command handler code here
CMenu *pMenu;
pMenu = GetMenu();
pMenu->CheckMenuItem(ID_HELP_TEST2,
MF_CHECKED | MF_BYCOMMAND);
MessageBox("Hello! Test 2");
}
Nhóm lệnh :
Là 1 nhóm menu item hoạt động theo nguyên tắc “Chỉ có 1 phần tử được chọn tại 1 thời điểm”
VD. Chức năng vẽ hình “Line / Circle / Rectangle”
Cách thức xử lý ?
Cách 1: map tất cả xử lý của các menu item này vào chung 1 hàm xử lý
Cách 2: dùng macro ON_COMMAND_RANGE
Cách 1: map tất cả xử lý của các menu item này vào
chung 1 hàm xử lý
// Định nghĩa Message map
ON_COMMAND (ID_DRAW_LINE, Draw)
ON_COMMAND (ID_DRAW_CIRCLE, Draw)
ON_COMMAND (ID_DRAW_RECTANGLE, Draw)
• // Hàm xử lý chung, xác định item hiện hành
void CAAADlg::Draw () {
m_nCurrentDraw = (UINT)
LOWORD(GetCurrentMessage()->wParam);
}
Cách 2: dùng macro ON_COMMAND_RANGE
Lưu ý: các ID đặt trong macro này phải có giá trị liên
tục
// Định nghĩa Message map
ON_COMMAND_RANGE (ID_DRAW_LINE,
ID_DRAW_RECTANGLE, Draw)
• // Hàm xử lý chung, xác định item hiện hành
void CAAADlg::Draw (UINT nID) {
m_nCurrentDraw = nID;
}
22. TIẾN TRÌNH XỬ LÝ SỰ KIỆN :
Haøm AfxWndProc() nhaän thoâng baùo, tìm ñoái töôïng CWnd cuûa thoâng baùo vaø goïi haøm fxCallWndProc()
Haøm AfxCallEndProc() löu thoâng baùo vaø goïi haøm WindowProc()
Haøm WindowProc() gôûi thoâng baùo ñeán haøm OnWndMsg() vaø neáu chöa ñöôïc xöû lyù thì goïi haøm DefWindowProc()
Haøm OnWndMsg() goïi haøm OnCommand (cho caùc thoâng baùo WM_COMMAND), hoaëc OnNotify() (cho caùc thoâng baùo WM_NOTIFY). Caùc thoâng baùo coøn laïi, haøm OnWndMsg() tìm kieám moät sô ñoà thoâng baùo (Message map) cuûa lôùp cho boä phaän ñieàu khieån ñeå xöû lyù. Neáu haøm OnWndMsg() khoâng tìm thaáy boä phaän ñieàu khieån, noù seõ traû veà thoâng baùo cho haøm WindowProc() ñeå gôûi ñeán haøm DefWindowProc().
Haøm OnCommand() kieåm tra neáu ñoù laø moät khai baùo ñieàu khieån (lParam khaùc NULL) thì phaûn hoài thoâng baùo cho ñieàu khieån taïo ra khai baùo. Ngöôïc laïi haøm OnCommand() seõ goïi haøm OnCmdMsg().
Haøm OnNotify() cuõng phaûn hoài thoâng baùo ñeán ñieu khieån taïo ra khai baùo, neáu thaát baïi seõ goïi haøm OnCmdMsg()
Haøm OnCmdMsg() phuï thuoäc vaøo lôùp nhaän thoâng baùo, seõ laø caùc thoâng baùo leänh vaø khai baùo ñieàu khieån coù trong moät ñöôøng truyeàn leänh (Command Routing). Noù kieåm tra sô ñoà thoâng baùo vaø goïi haøm xöû lyù töông öùng.
23. CONTROL
Moät control gôûi thoâng baùo ñeán cöûa soå chính qua message WM_COMMAND
Tuøy theo moãi loaïi control maø thoâng baùo naøy bieán ñoåi ôû hai tham soá lParam vaø wParam. Hai tham soá naøy cho pheùp nhaän daïng control ñaõ gôûi message vaø haønh ñoäng naøo.
Ví duï: Khi nhaán chuoät vaøo moät PushButton -> phaùt sinh thoâng ñieäp BN_CLICKED.
Haàu heát öùng duïng MFC cung caáp saün caùc haøm vaø khai baùo cho nhöõng söï kieän cuûa caùc controls.
Ví duï: Khi nhaán chuoät vaøo moät PushButton coù ID laø IDC_BUTTON -> Haøm xöû lyù söï kieän naøy laø OnButtonClicked:
ON_BN_CLICKED (IDC_BUTTON, OnButtonClicked)
Push Button :
Push Button laø moät control button ñöôïc taïo vôùi style laø BS_PUSHBUTTON
Khi ñöôïc choïn, push button seõ gôûi ñeán cöûa soå chính thoâng baùo BN_CLICKED trong WM_COMMAND message.
Haøm xöû lyù
ON_BN_CLICKED (IDC_BUTTON, OnButtonClicked)
void CMainWindow :: OnButtonClicked(){
MessageBox (_T(“I’ve been clicked!”);
}
Check Boxes :
Check Boxes laø moät control button ñöôïc taïo vôùi style laø
BS_CHECKBOX, BS_AUTOCHECKBOX, BS_3STATE hoaëc BS_AUTO3STATE.
BS_CHECKBOX vaø BS_AUTOCHECKBOX coù theå coù 2 traïng thaùi: choïn vaø khoâng choïn.
Moät check boxes ñöôïc choïn hoaëc khoâng choïn vôùi haøm CButton::SetCheck.
m_wndCheckBox.SetCheck (BST_CHECKED);
m_wndCheckBox.SetCheck (BST_UNCHECKED);
Ñeå bieát ñöôïc moät check boxes ñang ñöôïc choïn hay khoâng choïn, duøng haøm CButton :: GetCheck.
void CMainWindow::OnCheckBoxClicked () {
m_wndCheckBox.SetCheck (m_wndCheckBox.GetCheck () ==
BST_CHECKED ? BST_UNCHECKED : BST_CHECKED);
}
24. Customizing a Control's Color :
MFC hoã trôï hai kyõ thuaät ñeå thay ñoåi moät control color, döïa vaøo cô cheá laø moät control khi ñöôïc veõ laïi seõ gôûi ñeán cöûa soå chính moat message bao haøm handle cuûa thieát bò ngöõ caûnh duøng ñeå veõ.
Cöûa soå chính cuûa öùng duïng coù theå goïi hai haøm CDC::SetTextColor vaø CDC::SetBkColor.
Message maø moät control gôûi ñeán cöûa soå chính cuûa öùng duïng thay ñoåi tuøy theo moãi loaïi control.
Ví duï:
Moät listbox gôûi WM_CTLCOLORLISTBOX message.
Moät static control gôûi WM_CTLCOLORSTATIC message.
HaØm xöû lyù :
afx_msg HBRUSH OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor)
Cấu trúc Document / Wiew :
Vai trò của mỗi class được mô tả như sau:
Lớp Vai trò
CWinApp Tạo tất cả thành phần khác trong ứng dụng. Đây là lớp nhận thông báo sự kiện
và truyền tới lớp CView và CDocument
CFrameWnd
- Tạo và quản lý khung cửa sổ, chứa menu, toolbar, scrollbar và các đối tượng nhìn thấy được gắn vào cửa sổ.
- Xác định số tài liệu nhìn thấy được trong một thời điểm bất kỳ
CMDIFrameWnd
- (thể hiện bởi CMainFrame trong project) là khung chính của ứng dụng
- Cung cấp không gian bao bọc trên màn hình nền diễn ra toàn bộ tương tác ứng
dụng.
- Cửa sổ này là khung được gắn menu và thanh công cụ
CMDIChildFrameWnd - (thể hiện bởi CChildFrame trong project) là khung chứa lớp CView- Là lớp truyền thông điệp (message) và sự kiện (event) tới các lớp hiển thị để
xử lý hay hiển thị.
CDocument
- Chứa tài liệu của ứng dụng. Đây là nơi sẽ lưu trữ cấu trúc dữ liệu cần thiết để
chứa và thao tác dữ liệu tạo nên tài liệu.
- Lớp này nhận dữ liệu từ lớp CView và truyền thông tin sang lớp CView.
- Lưu giữ và lấy dữ liệu về tài liệu từ các file
CView
- Quản lý phần hiển thị phần trình bày nhìn thấy của tài liệu cho người dùng
xem.
- Truyền thông tin vào lớp CDocument và nhận thông tin từ lớp CDocument.
Việc tương tác và trao đổi thông tin giữa CView và CDocument được thể hiện như sau:
Hay:
Với dạng SDI, sự liên kết thể hiện như sau:
Với dạng MDI, sự liên kết thể hiện như sau:
phuong.ntt-08h1010074- Tổng số bài gửi : 137
Join date : 05/05/2009
Re: Tài liệu thi lại Lập trình Win!
Cảm ơn tai liệu của bạn !!!
thanchon- Tổng số bài gửi : 15
Join date : 17/05/2009
Similar topics
» Tai lieu lap trinh web 14-10
» Tài liệu môn Lâp trình Cơ sơ dữ liệu
» Tài liệu Lập Trình Window??
» Lap trinh Co So Du Lieu
» Tài liệu Lập trình WEB
» Tài liệu môn Lâp trình Cơ sơ dữ liệu
» Tài liệu Lập Trình Window??
» Lap trinh Co So Du Lieu
» Tài liệu Lập trình WEB
Trang 1 trong tổng số 1 trang
Permissions in this forum:
Bạn không có quyền trả lời bài viết