Bài giảng Visual C
Trang 1Lập trình trên môi trường Windows
Trang 2• Giúp cho người lập trình có thể xây dựng ứng dụng nhanh và ít tốn
công sức hơn so với việc sử d ng đơn thuần các hàm thư viện API
của Windows
Trang 3Giới thiệu về MFC
• Trong 1 ứng dụng MFC, ta thường không gọi hàm
Windows API trực tiếp, mà sẽ tạo các đối tượng từ những
lớp của MFC, và gọi phương thức của đối tượng đó
• Đa số các phương thức của những lớp MFC có cùng tên
với những hàm Windows API
• MFC tạo ra một Application Framework, giúp:
– Thiết lập kiến trúc của ứng dụng một cách nhất quán và khoa
học
– Che dấu đi nhiều phần chi tiết mà Windows API đòi hỏi, giúp
lập trình viên “thảnh thơi” hơn
Giới thiệu về MFC
• Version 1:
– Các lớp List, Array, String, Time, Date, File access,…
– Các lớp giao diện cơ bản
– MDI, OLE 1.0
• Version 2:
– File open, save
– Print preview, printing
– Scrolling window, Splitter window
– Toolbar, Statusbar
– Truy xuất được đến các control của VB
– Trợ giúp theo ngữ cảnh (Context-sensitive help)
– DLL
Trang 4Giới thiệu về MFC
• Version 2.5:
– Hỗ trợ ODBC (Open Database Connectivity), cho phép truy
xuất đến các CSDL Access, FoxPro, SQL Server,…
– OLE 2.01
• Version 3:
– Hỗ trợ tab dialog (property sheet)
– Docking control bar
• Version 3.1:
– Hỗ trợ các control chuẩn của Windows 95
– ODBC level 2 with Access Jet database engine
– Các lớp Winsock phục vụ lập trình TCP/IP
Giới thiệu về MFC
• Version 4.0:
– ADO (Data Access Object)
– Windows 95 docking control bar
– Bổ sung thêm lớp TreeView và RichEdit
– Các lớp đồng bộ hoá các tiểu trình
• Version 4.2:
– Các lớp WinInet
– Các lớp ActiveX document server
– Các tính năng mở rộng của ActiveX control
Trang 5– Active Document Containment, cho phép ứng dụng
MFC có thể chứa các Active Document
– OLE DB và ADO
Giới thiệ
Các thành phần của 1 ứng dụng
Trang 6Chương trình MFC đầu tiên
Trang 7Chương trình MFC đầu tiên
Trang 8Chương trình MFC đầu tiên
Tạo ứng dụng bằng MFC AppWizard
Visual Studio 2005
Chương trình MFC đầu tiên
Các thành phần của chương trình
• Các file chương trình: (xxx là tên project)
– xxx.h: header file của file xxx.cpp, chứa khai báo lớp CxxxApp để
quản lý toàn bộ ứng dụng Lớp CxxxApp kế thừa từ lớp CWinApp
của MFC
– xxxDlg.h: header file của file xxxDlg.cpp, chứa khai báo lớp
CxxxDlg để quản lý cửa sổ Dialog giao diện của ứng dụng Lớp
CxxxDlg kế thừa từ lớp CDialog của MFC
– Resource.h: header file, chứa các hằng ID của các resource được
định nghĩa trong file xxx.rc
– xxxDlg.cpp: cài đặt các hàm thành phần của lớp CxxxDlg
– xxx.cpp: cài đặt các hàm thành phần của lớp CxxxApp
– xxx.rc: mô tả các resource (tài nguyên) của ứng dụng
Trang 9Chương trình MFC đầu tiên
Các thành phần của chương trình
Chương trình MFC đầu tiên
Các thành phần của chương trình
• CWinApp: lớp chính của MFC để quản lý ứng dụng Chứa đựng vòng lặp
nhận message và phân phối message đến các cửa sổ c a ứng dụng
• CDemoApp: lớp kế thừa từ lớp CWinApp.
class CMFC01App : public CWinApp
Trang 10Chương trình MFC đầu tiên
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
Chương trình MFC đầu tiên
Các thành phần của chương trình
• CWnd: lớp chính của MFC để quản lý các loại cửa
sổ giao diện Có nhiều lớp được kế thừa từ lớp
này để quản lý các loại cửa sổ khác nhau
(CTreeCtrl, CListBox, CEdit,…)
• CDialog kế thừa từlớp CWnd, là lớp cơ bản được
dùng để hiển thị các dialog trên màn hình
Trang 11Chương trình MFC đầu tiên
Các thành phần của chương trình
• Mỗi dialog sẽ có tương ứng một lớp CxxxDlg kế thừa từ CDialog.
class CMFC01Dlg: public CDialog
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
Trang 12Message Map
• 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ổ.
Trang 13Xử lý thông điệp
• 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 CMFC01Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
MessageBox(_T("Nhan phim trai chuoi"), _T("Thong bao"), MB_OK);
Trang 15Các thông điệp của mouse
• Với mỗi thông điệp của chuột, Windows gởi kèm 2
– wParam: cho biết phím nào đang được nhấn (Ctrl,
Shift)
– lParam: cho biết toạ độ hiện tại
• LOWORD(lParam): tọa độ x
• HIWORD(lParam): tọa độ y
Trang 16Xử lý mouse
Các thông điệp của mouse
OnMouseMove
ON_WM_MOUSEMOVE WM_MOUSEMOVE
OnRButtonDblClk
ON_WM_RBUTTONDBLCLK WM_RBUTTONDBLCLK
OnRButtonUp
ON_WM_RBUTTONUP WM_RBUTTONUP
OnRButtonDown
ON_WM_RBUTTONDOWN WM_RBUTTONDOWN
OnMButtonDblClk
ON_WM_MBUTTONDBLCLK WM_MBUTTONDBLCLK
OnMButtonUp
ON_WM_MBUTTONUP WM_MBUTTONUP
OnMButtonDown
ON_WM_MBUTTONDOWN WM_MBUTTONDOWN
OnLButtonDblClk
ON_WM_LBUTTONDBLCLK WM_LBUTTONDBLCLK
OnLButtonUp
ON_WM_LBUTTONUP WM_LBUTTONUP
OnLButtonDown
ON_WM_LBUTTONDOWN WM_LBUTTONDOWN
Hàm xử lý thông điệp Message-Map Macro
Thông điệp
Xử lý mouse
Các thông điệp của mouse
• Các hàm xử lý thông điệp cho mouse có dạng:
afx_msg void OnMsgName (UINT nFlags, CPoint
point)
– point: thuộc lớp CPoint, chỉ vị trí của trỏ chuột Gốc
toạ độ được xác định theo góc trái trên của cửa sổ
– nFlags: trạng thái của các phím chuột và các phím
Ctrl, Alt.
Trang 17Xử lý mouse
Các thông điệp của mouse
• Sửdụng phép toán & để kiểm tra một trạng thái
có tồn tại không
– Ví dụ: nFlags & MK_CONTROL khác 0 kiểm tra phím
Ctrl được nhấn
Phím Shift được nhấn MK_SHIFT
Phím Ctrl được nhấn MK_CONTROL
Phím phải chuột được nhấn MK_RBUTTON
Phím giữa chuột được nhấn MK_MBUTTON
Phím trái chuột được nhấn MK_LBUTTON
Ý nghĩa Giá trị
Trang 18– Định nghĩa 2 biến m_PrevX, m_PrevY trong class CxxxDlg
– Định nghĩa hàm xử lý message WM_LBUTTONDOWN trong
• Viết code cho hàm xử lý thông điệp nhấn trái chuột
void CMouseProcessingDlg::OnLButtonDown(UINT nFlags,
Trang 19Xử lý mouse
void CMouseProcessingDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//Chuột đang di chuyển với phím trái đang nhấ
if ((nFlags & MK_LBUTTON) == MK_LBUTTON) {
Trang 20Xử lý 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
• Hàm xử lý tương ứng: CWnd::OnKeyDown, CWnd::OnKeyUp
• wParam: virtual-key code
• 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
afx_msg void OnMsgName (UINT nChar, UINT
nRepCnt, UINT nFlags)
– nChar: mã phím ảo được nhấn hoặc thả
– nRepCnt: số lần nhấn/thả phím tương ứng
– nFlags: cờ liên quan (xem thêm trong MSDN)
Trang 21Xử lý keyboard
• Mã phím ảo
Esc VK_ESCAPE
Pause VK_PAUSE
Alt VK_MENU
Ctrl VK_CONTROL
Shift VK_SHIFT
Phím số 5 (Num Lock tắt) VK_CLEAR
Tab VK_TAB
Backspace VK_BACK
Enter VK_RETURN
Ctrl-Break VK_CANCEL
Phím số 0, , 9 (Numlock được bật) VK_NUMPAD0,…,VK_NUMPAD9
Phím chức năng F1_F12 VK_F1,…,VK_F12
Insert và Ins VK_INSERT
Print Screen VK_SNAPSHOT
Down arrow VK_DOWN
Right arrow VK_RIGHT
Up arrow VK_UP
Left arrow VK_LEFT
Home VK_HOME
End VK_END
Page Down và PgDn VK_NEXT
Page Up và PgUp VK_PRIOR
Spacebar VK_SPACE
Phím tương ứng
Mã phím ả
Trang 22Xử lý keyboard
• Mã phím ảo
Phím Menu VK_APPS
Phím Windows (phải) VK_RWIN
Phím Windows (trái) VK_LWIN
Scroll Lock VK_SCROLL
Num Lock VK_NUMLOCK
Caps Lock VK_CAPITAL
Phím / (bên phải) VK_DIVIDE
Phím (bên phải) VK_DECIMAL
Phím – (bên phải) VK_SUBTRACT
Phím + (bên phải) VK_ADD
Phím * (bên phải) VK_MULTIPLY
Trang 24Lớp CWnd
Giới thiệu
• Đây là một lớp tổng quát và gặp rất nhiều lần
trong quá trình làm việc trên dialog nói riêng và
trên các ứng dụng MFC nói chung
• Lớp CWnd cung cấp các chức năng cơ bản cho
tất cả các lớp cửa sổ (các control, mainframe,
view, dialog…) trong thư viện MFC
Trang 25Các hàm cơ bản của lớp CWnd
Hàm CWnd::GetDlgItem
• CWnd* GetDlgItem(int nID ) const;
– Trả về con trỏ CWnd* của một cửa sổ con trên 1
BOOL EnableWindow(BOOL bEnable = TRUE );
– Làm cho cửa sổ có thể/không thể bị tác động bởi
Trang 26Các hàm cơ bản của lớp CWnd
Hàm CWnd::GetFocus
• static CWnd* PASCAL GetFocus( );
– Trả về con trỏ CWnd của control đang được nhận
– Đặt focus cho một đối tượng cửa sổ.
– Trả về con trỏ CWnd* của cửa sổ nhận focus trước
đó.
– Ví dụ:
CWnd* pWnd;
pWnd = GetDlgItem(IDC_EDIT1);
Trang 27Các hàm cơ bản của lớp CWnd
Hàm CWnd::GetClientRect
• void GetClientRect (LPRECT lpRect) const;
– Xác định toạ độ của hình chữ nhật bao quanh cửa
• void MoveWindow(LPCRECT lpRect,BOOL bRepaint = TRUE);
– Dịch chuyển, thay đổi kích cỡ một cửa sổ
Trang 28Các hàm cơ bản của lớp CWnd
Hàm CWnd::GetDlgCtrlID
• int GetDlgCtrlID( ) const;
– Xác định ID của một control trên dialog.
int GetDlgItemText(int nID, CString& rString) const;
– Lấy chuỗi nội dung của 1 control.
– Ví dụ : Lấy chuỗi nội dung của control có ID là
IDC_EDIT1 trên dialog.
CString str;
this->GetDlgItemText(IDC_EDIT1, str);
Trang 29• void GetWindowText(CString& rString) const;
– Lấy chuỗi nội dung cho một đối tượng cửa sổ
– Ví dụ : Lấy nội dung cho đối tượng cửa sổ có ID là IDC_TEXT
CWnd * pWnd;
CString str;
pWnd = GetDlgItem(IDC_TEXT);
pWnd->GetWindowText(str);
Trang 30Các hàm cơ bản của lớp CWnd
Hàm CWnd::SetWindowText
• void SetWindowText(LPCTSTR lpszString );
– Thiết lập chuỗi nội dung cho một đối tượng cửa sổ
– Ví dụ : Đặt chuỗi nội dung cho đối tượng cửa sổ có
• CString là lớp chuỗi cơ bản trong MFC tương tự
như char * trong C/C++ nhưng tự động quản lý
kích thước và cấp phát vùng nhớ
Trang 32Các hàm cơ bản của lớp CString
strNew = str + _T(" Nice to meet you");
Các hàm cơ bản của lớp CString
Trang 33Các hàm cơ bản của lớp CString
str = _T("Xin chao cac ban");
str.SetAt(1, str[3]); //str : “X n chao cac ban”
Các hàm cơ bản của lớp CString
Chuỗi rỗng
• Hàm CString::Empty: tạo một chuỗi rỗng
• Hàm CString::IsEmpty: kiểm tra xem một chuỗi có rỗng
Trang 34Các hàm cơ bản của lớp CString
Định dạng chuỗi
• Tương tựhàm sprintf của C
• Dùng để định dạng chuỗi theo mong muốn
CString s = _T("This is an example");
result = s.Find('i'); //kiem tu dau chuoi, result = 2
Trang 35Các hàm cơ bản của lớp CString
Các hàm cơ bản của lớp CString
Xác định chiều dài chuỗi
• CString::GetLength(): Lấy chiều dài của chuỗi đã
cho
• Ví dụ:
int result;
CString s = _T"This is an example");
result = s.GetLength();// result = 18
Trang 36Các hàm cơ bản của lớp CString
Các hàm tách chuỗi
CString CString::Left(int nCount)
CString CString::Right(int nCount)
CString CString::Mid(int Start, int nCount)
Các hàm cơ bản của lớp CString
• Hàm CString::TrimLeft: loại bỏ các ký tự đầu chuỗi
• Hàm CString::TrimRight: loại bỏ các ký tựcuối
Trang 37Các hàm cơ bản của lớp CString
Thay đổi nội dung chuỗi
• CString::MakeLower: in thường các ký tựtrong
CString s = _T("Hello, how are you");
s.MakeUpper();//HELLO, HOW ARE YOU
s.MakeLower();//hello, how are you
s.MakeReverse();//uoy era woh ,olleh
Các hàm cơ bản của lớp CString
Trang 38Các hàm cơ bản của lớp CString
• CString::Replace : Thay thế một chuỗi con bằng
Trang 39Các control
Giới thiệu
• Phiên bản hiện hành của Windows có khoảng 20
loại control
• 6 trong số đó gọi là classic control (những control
có từ phiên bản đầu tiên của Windows) Chứa
trong User.exe
• Các control còn lại gọi là common control Hầu
hết xuất hiện từWindows 95 Chứa trong
Trang 40Loại button
Trang 41Các control
• Các hàm cần quan tâm của CListBox:
Trang 42Các control
• Lấy vị trí được chọn của một ListBox có ID là
• Nguyên nhân ra đời
• Các loại dialog thường gặp
• Sửdụng bằng thư viện MFC
• Ví dụ minh hoạ
Trang 43Các dialog thường gặ
Nguyên nhân ra đời
• Trước Windows 3.1, lập trình viên phải tự viết các dialog
mở hoặc lưu file (cho phép người dùng chọn đường dẫn
file)
=> Không nhất quán giữa các ứng dụng
• Từ Windows 3.1, Windows xây dựng các dialog thường
sử dụng và chứa trong một DLL.
• Windows 95 bổ sung thêm dialog Page Setup.
• Windows 98, Windows 2000 bổ sung thêm nhiều tính
năng cho các dialog trên.
Các dialog thường gặ
Liệt kê chi tiết
• Open / Save As dialog
• Print / Print Setup dialog
• Page Setup dialog
• Find and Replace dialog
• Color dialog
• Font dialog
Trang 46Các dialog thường gặ
Color dialog
Các dialog thường gặ
Font dialog
Trang 47Các dialog thường gặ
• 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
Trang 48• Các hàm cần quan tâm của lớp CFileDialog:
– GetFileExt: lấy phần mở rộng của tập tin được
chọn
– GetFileName: lấy tên tập tin được chọn
– GetFileTitle: lấy phần tên (không có phần mở rộng)
của tập tin được chọn
– GetFolderPath: lấy thư mục của tập tin được chọn
– GetPathName: lấy đường dẫn của tập tin được
Trang 50Xử lý menu
• Một vài khái niệm
• Tạo lập menu
• Nạp và hiển thị menu
• Xử lý khi menu item được chọn
• Thay đổi trạng thái menu
• Ví dụ
Xử lý menu
Một vài khái niệm
• Menu bar: thanh menu Bao gồm nhiều drop-down menu và menu
item
• Drop-down menu: một phần của menu bar, chứa các menu item hoặc
các drop-down menu khác.
– VD File, Edit, …
• Menu item: tương ứng với 1 lệnh của chương trình Mỗi menu item
được xác định bằng 1 số nguyên phân biệt, gọi là item ID hay
command ID.
– VD Open, Save, …
• Popup menu: giống như drop-down menu, nhưng có thể xuất hiện ở
vị trí b t kỳ trên màn hình (thường khi nhấn nút phải mouse)
• System menu: chứa các lệnh hệ thống điều khiển cửa sổ.
Trang 51Xử lý menu
Một vài khái niệm
• Ví dụ về menubar, drop-down menu, menu item
Xử lý menu
Một vài khái niệm
• Xác lập đối tượng menu trong các hàm xửlý
Trang 52Xử lý menu
Tạo lập menu
• Thường có 2 cách chính để tạo menu:
– Tạo menu ở dạng resource của ứng dụng, và load
vào khi chạy
– Tạo trực tiếp bằng các hàm khi ứng dụng đang
• Tạo lập menu trong tài nguyên
IDC_DEMOWIN32 MENU DISCARDABLE
Trang 53Xử lý menu
Tạo lập menu
• Tạo lập menu bằng editor
có trong môi trường lập
trình.
Xử lý menu
• Xác định menu bar khi tạo cửa sổ:
Create(NULL, _T("My Application"),
WS_OVERLAPPEDWINDOW, rectDefault, NULL,
Trang 54Xử lý menu
– Theo tác trên menu:
• DeleteMenu: Xoá một đối tượng trên menu
• TrackPopupMenu: hiển thị menu popup nổi
– Thao tác trên các menuitem:
• AppendMenu: thêm vào cuối menu một menuitem.
• InsertMenu: thêm một đối tượng menu tại một vị trí xác định
• ModifyMenu: chỉnh sửa một đối tượng menu xác định.
Xử lý menu
– Thao tác trên các menuitem
• CheckMenuItem: thêm/bỏ dấu check phía trước một
menuitem
• CheckMenuRadioItem: check một menuitem trong một
nhóm các menuitem
• EnableMenuItem: thiết lập menuitem các trạng thái enable
(MF_ENABLED), disable (MF_DISABLED),
gray(MF_GRAYED).
Trang 55Xử lý menu
Xử lý khi menu item được chọn
• Các thông điệp của menu
• Xửlý lệnh của menu item
Xử lý khi menu item được chọn
Các thông điệp của menu
• 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:
– LOWORD(wParam): ID của menu item hoặc index của menu popup
– 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