Tài liệu Lập trình windows: 9/13/2011
1
TRƯỜNG ĐẠI HỌC B\CH KHOA H[ NỘI
VIỆN CÔNG NGHỆ THÔNG TIN V[ TRUYỀN THÔNG
Phạm Ngọc Hưng
Bộ môn Kỹ thuật Máy tính
hungpn@soict.hut.edu.vn
LẬP TRÌNH WINDOWS
9/13/2011
2
Lập trình Windows
• Mã số: IT4781
• Thời lượng: 2 (2-1-0-4)
– Lý thuyết: 30 tiết
– Bài tập: 15 tiết
• Học phần tiên quyết:
– Ngôn ngữ lập trình C, C++
– Lập trình hướng đối tượng
2Lập trình Windows
9/13/2011
3
Nội dung
• Chương 1. Tổng quan lập trình Windows (4LT +
1BT)
• Chương 2. Lập trình Windows VC++/MFC (15LT +
6BT)
• Chương 3. Một số chủ đề nâng cao
– Tạo thư viện liên kết động (DLL) (3LT + 2BT)
– Luồng (Thread) (3LT + 2BT)
– Windows Socket (2LT + 2BT)
• Chương 4. X}y dựng ứng dụng Windows Form (3LT
+ 2BT)
• Bài tập lớn
3Lập trình Windows
9/13/2011
4
Tài liệu tham khảo
• 1. Ivor Horton’s, Beginning Visual C++ 2010
• 2. Programming Windows with MFC 2nd
• 2. VC++ and MFC Programming 2nd
• 3. Sams teach yourself VC++ 6 in 21 days
• 4. MSDN
• 5.
4Lập trình Windo...
312 trang |
Chia sẻ: Khủng Long | Lượt xem: 1237 | Lượt tải: 0
Bạn đang xem trước 20 trang mẫu tài liệu Lập trình windows, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
9/13/2011
1
TRƯỜNG ĐẠI HỌC B\CH KHOA H[ NỘI
VIỆN CÔNG NGHỆ THÔNG TIN V[ TRUYỀN THÔNG
Phạm Ngọc Hưng
Bộ môn Kỹ thuật Máy tính
hungpn@soict.hut.edu.vn
LẬP TRÌNH WINDOWS
9/13/2011
2
Lập trình Windows
• Mã số: IT4781
• Thời lượng: 2 (2-1-0-4)
– Lý thuyết: 30 tiết
– Bài tập: 15 tiết
• Học phần tiên quyết:
– Ngôn ngữ lập trình C, C++
– Lập trình hướng đối tượng
2Lập trình Windows
9/13/2011
3
Nội dung
• Chương 1. Tổng quan lập trình Windows (4LT +
1BT)
• Chương 2. Lập trình Windows VC++/MFC (15LT +
6BT)
• Chương 3. Một số chủ đề nâng cao
– Tạo thư viện liên kết động (DLL) (3LT + 2BT)
– Luồng (Thread) (3LT + 2BT)
– Windows Socket (2LT + 2BT)
• Chương 4. X}y dựng ứng dụng Windows Form (3LT
+ 2BT)
• Bài tập lớn
3Lập trình Windows
9/13/2011
4
Tài liệu tham khảo
• 1. Ivor Horton’s, Beginning Visual C++ 2010
• 2. Programming Windows with MFC 2nd
• 2. VC++ and MFC Programming 2nd
• 3. Sams teach yourself VC++ 6 in 21 days
• 4. MSDN
• 5.
4Lập trình Windows
9/13/2011
5
Chương 1. Tổng quan lập trình Windows
• 1.1. Cơ bản về lập trình Windows (1T)
• 1.2. Cấu trúc của chương trình Windows (2T)
• 1.3. Microsoft Foundation Classes (MFC)
• 1.4. Lập trình Windows với VC++ 2008
(1LT + 1BT)
5Lập trình Windows
9/13/2011
6
1.1. Cơ bản về lập trình Windows
• Windows: đồ họa trực quan, tài nguyên đa
dạng.
• Ứng dụng thân thiện với người sử dụng
thông qua giao diện đồ họa Windows.
• Các ứng dụng có giao diện tương tác giống
nhau:
– Windows, title bar, toolbar, menu bar, status bar
– Thanh thực đơn: File, Edit, Tool, Help
– Hộp thoại: thường chứa các điều khiển chung: Edit
Control, Button Control, Checkbox.
6Lập trình Windows
9/13/2011
7
Các thành phần của một cửa sổ
7Lập trình Windows
9/13/2011
8
Cơ chế lập trình Event-driven
8Lập trình Windows
9/13/2011
9
Thông điệp (Windows Messages)
• Hệ thống (Windows) ghi lại mỗi sự kiện xảy ra
(event) trong một thông điệp (message) và đặt
trong hàng đợi thông điệp (messages queue)
• Thông điệp phát sinh:
– Từ hệ thống (Windows OS)
– Từ ứng dụng
• Ví dụ: click/drag chuột, ấn phím,
minimize/maximize/close cửa sổ, thay đổi kích
thước cửa sổ,
9Lập trình Windows
9/13/2011
10
Windows Message (cont.)
• HĐH Windows đảm nhiệm việc truyền tất cả các
thông điệp của ứng dụng vào các cửa sổ khác nhau
của ứng dụng đó.
• Một chương trình Windows phải chứa một hàm
đặc biệt để xử lý các thông điệp gọi là hàm xử lý
cửa sổ WinProc (hoặc WindowProc):
– Được gọi khi có bất kỳ thông điệp được truyền
đến cửa sổ (thông qua con trỏ hàm)
– Xử lý các thông điệp đó và trả điều khiển về cho
hệ thống.
• Nhiều thông điệp trả lại cho Windows xử lý, gọi
hàm DefWindowProc( )
10Lập trình Windows
9/13/2011
11
Windows Message (cont.)
11Lập trình Windows
9/13/2011
12
Windows API
• Application Programming Interface: Giao
diện lập trình ứng dụng
• Cung cấp các hàm truy cập tài nguyên trong
hệ thống (Windows) chứa trong các thư viện
liên kết động DLL.
• Các ứng dụng có thể truy cập đến các hàm
API
• Các hàm GDI (Graphics Device Interface) cho
phép ứng dụng làm việc với nhiều kiểu thiết
bị đồ họa.
12Lập trình Windows
9/13/2011
13
Windows Data Types (1)
• Định nghĩa nhờ từ khóa typedef trong các tập tin (windef.h;
winbase.h, winuser.h được include trong windows.h).
• Ví dụ:
– typedef int INT;
– typedef unsigned int UINT;
– char * PSTR
• WPARAM (UINT) và LPARAM (LONG) đều 32 bit
• LRESULT: kiểu LONG
• HANDLE: Một gi| trị 32bits không dấu (unsigned) do HĐH
tạo ra để l{m định danh cho 1 đối tượng (file, cửa sổ, vùng
nhớ, menu, toolbar). Ví dụ : HWND, HINSTANCE,
hPrevInstance
13Lập trình Windows
9/13/2011
14
Windows Data Types (2)
Kiểu Ý nghĩa
HANDLE Số nguyên 32-bit, định danh.
HWND Số nguyên 32-bit, định danh.
BYTE Giá trị 8-bit không dấu.
WORD Số nguyên 16-bit không dấu.
DWORD Số nguyên 32-bit không dấu.
UINT Số nguyên không dấu 32-bit.
LONG long 32-bit.
BOOL Kiểu logic True/False
LPSTR Con trỏ chuỗi. (char *)
LPCSTR Hằng con trỏ chuỗi.
WPARAM 32-bit.
LPARAM 32-bit.
BSTR Giá trị 32-bit trỏ đến kí tự.
LPVOID Con trỏ 32-bit đến một kiểu không xác định.
LPTSTR Giống như LPSTR nhưng có thể chuyển sang dạng Unicode và
DBCS.
LPCTSTR Giống như LPCTSTR nhưng có thể chuyển sang dạng Unicode và
DBCS.
14Lập trình Windows
9/13/2011
15
Microsoft style (1)
• Tất cả c|c kiểu dữ liệu mở rộng của windows , tên class, tên
struct, tên hằng số định sẵn đều được viết in hoa
Ví dụ :
Tên kiểu dữ liệu : UINT , ATOM , HANDLE, HWND, BYTE,.
Tên cấu trúc : MSG, PAINSTRUCT, WNDCLASS ,....
Tên hằng số định sẵn : NULL, IDI_APPLICATION,
CS_VREDRAW,..
• Tất cả c|c method (c|c h{m, c|c phương thức) đều được viết
hoa (pascal notation).
Ví dụ :
LoadIcon()
LoadCursor()
SomeOtherName()
15Lập trình Windows
9/13/2011
16
Microsoft Style (2)
• Qui ước: bắt đầu (tiền tố) chữ thường thể
hiện kiểu dữ liệu biến.
• Ví dụ: szCmdLine là một biến lưu chuỗi nhập
từ dòng lệnh, sz là thể hiện cho biến kiểu
chuỗi kết thúc ký tự 0,
• hInstance và hPrevInstance, trong đó h viết
tắt cho kiểu handle.
16Lập trình Windows
9/13/2011
17
Microsoft Style (3) – Tiền tố tên biến
Tiền tố Kiểu dữ liệu
c char, WCHAR, TCHAR
by BYTE
n short
i int
x,y biến lưu tọa độ x, y
b BOOL
w WORD
l long
dw DWORD
s string
sz chuỗi kết thúc bởi kí tự 0
h handle
p pointer
Lpsz con trỏ dài chuỗi ký tự kết thúc kí tự 0
17Lập trình Windows
9/13/2011
18
Microsoft style (4) - Calling convention
• Định nghĩa kiểu h{m gọi bởi Windows OS
#define CALLBACK __stdcall
#define WINAPI __stdcall
#define APIENTRY WINAPI
#define APIPRIVATE __stdcall
#define PASCAL __stdcall
• Thêm vào trước tên hàm để chỉ ra cho
compiler rằng hàm này có cách tổ chức phục
vụ cho việc gọi đến như thế nào.
18Lập trình Windows
9/13/2011
19
1.2. Cấu trúc của chương trình Windows
19Lập trình Windows
9/13/2011
20
1.2. Cấu trúc của chương trình Windows
• Chương trình Windows đơn giản (dùng hàm API)
gồm 2 hàm WinMain() và hàm xử lý cửa sổ
WinProc().
• WinMain() thực hiện các chức năng:
– Tell Windows what kind of window the program requires
– Create the program window
– Initialize the program window
– Retrieve Windows messages intended for the program
• WinProc(): xử lý các thông điệp liên quan đến cửa
sổ của nó.
20Lập trình Windows
9/13/2011
21
1.2.1. Hàm WinMain()
• Hàm chính của ứng dụng trên Windows
• Program entry point
• hInstance, is a handle to the instance of the program you
are writing.
• hPrevInstance, is used if your program had any previous
instance. If not, this argument can be ignored.
• szCmdLine, is a string that represents all items used on the
command line to compile the application.
• nCmdShow, controls how the window you are building will
be displayed.
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
21Lập trình Windows
9/13/2011
22
Hàm WinMain (cont.)
• Tìm hiểu hàm WinMain mẫu:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("HelloWin"); // tên ứng dụng
HWND hwnd;
MSG msg;
WNDCLASS wndclass; // biến để định danh một cửa sổ
/* Ðịnh nghĩa kiểu cửa sổ */
wndclass.style = SC_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc; // Hàm thủ tục cửa sổ
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance; // Ðịnh danh ứng dụng
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCusor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL; // Không có menu
22
9/13/2011
23
Tìm hiểu hàm WinMain mẫu (cont.)
wndclass.lpszClassName = szAppName; // tên ứng dụng
/* Ðăng ký lớp cửa sổ */
if (!RegisterClass(&wndclass)) return 0;
/* Tạo thể hiện lớp cửa sổ đã định nghĩa */
hwnd = CreateWindow(szAppName, // Tên cửa sổ
"Hello Program", // Tiêu đề
WS_OVERLAPPEDWINDOW, // Kiểu cửa sổ
CW_USEDEFAULT, // Toạ độ x
CW_USEDEFAULT, // Toạ độ y
CW_USEDEFAULT, // Chiều rộng
CW_USEDEFAULT, // Chiều dài
NULL, // Cửa sổ cha
NULL, // Không có menu
hInstance, // Ðịnh danh ứng dụng
NULL); // Tham số bổ sung
/* Hiển thị cửa sổ */
ShowWindow (hwnd, iCmdShow);
UpdateWindow (hwnd);
/* Chu trình xử lý các thông điệp*/
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
23
Lập trình Windows
9/13/2011
24
Định nghĩa lớp cửa sổ WNDCLASS
• Windows cung cấp một cấu trúc WNDCLASS (file
winuser.h) gọi là lớp cửa sổ.
• Lớp này chứa các thuộc tính tạo thành một cửa sổ
typedef struct _WNDCLASS
{
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASS, *PWNDCLASS;
24Lập trình Windows
9/13/2011
25
Định nghĩa lớp cửa sổ WNDCLASS
• Ý nghĩa thuộc tính lớp cửa sổ WNDCLASS:
Thuộc tính Ý nghĩa Ghi chú
style Kiểu lớp
Kết hợp nhiều kiểu giá
trị khác nhau bằng
toán tử OR.
lpfnWndProc Con trỏ đến thủ tục xử lý cửa sổ
cbClsExtra
Số byte được cấp phát thêm sau
cấu trúc window-class
Mặc định
cbWndExtra
Số byte được cấp phát thêm sau
một instance của window
Mặc định
hInstance
Định danh chứa thủ tục cửa sổ
của lớp window
hIcon Định danh của biểu tượng Dùng hàm LoadIcon
hCursor Định danh của con trỏ chuột Dùng hàm LoadCursor
hbrBackground Định danh của chổi tô nền
Dùng hàm
GetStockObject
lpszMenuName Tên thực đơn
Tên thực đơn gắn với
cửa sổ, thực đơn này
được khai báo trong
tập tin tài nguyên.
lpszClassName Tên lớp
25
9/13/2011
26
Đăng ký lớp cửa sổ
• Sau khi định nghĩa lớp cửa sổ phải đăng ký
bằng hàm RegisterClass:
ATOM RegisterClass(CONST WNDCLASS * lpWndClass);
26Lập trình Windows
9/13/2011
27
Tạo cửa sổ
• Lớp cửa sổ thể hiện đặc tính chung cửa sổ. Cho
phép tạo nhiều thể hiện cửa sổ của lớp
• Dùng hàm CreateWindow, chỉ định các đặc tính
riêng của cửa sổ, và phân biệt nó với các cửa sổ
khác tạo ra cùng một lớp.
HWND CreateWindow(LPCSTR lpClassName, // Tên lớp cửa sổ đã đăng ký
LPCSTR lpwindowName, // Tên của cửa sổ
DWORD dwStyle, // Kiểu của cửa sổ
int x, // Vị trí ngang ban đầu
int y, // Vị trí dọc ban đầu
int nWidth, // Ðộ rộng ban đầu
int nHeight, // Ðộ cao ban đầu
HWND hWndParent, // Ðịnh danh của cửa sổ cha
MENU hMenu, // Ðịnh dang của thực đơn
INSTANCE hInstance, // Ðịnh danh thể hiện ứng dụng
PVOID lpParam // Các tham số ban đầu
);
27Lập trình Windows
9/13/2011
28
Hiển thị cửa sổ
• Sau khi tạo cửa sổ định danh cửa sổ HWND
• Để xuất hiện cửa sổ gọi hàm ShowWindow
BOOL ShowWindow(HWND hWnd, // Ðịnh danh của cửa sổ cần thể hiện
int iCmdShow // Trạng thái hiển thị
);
• Một số trạng thái hiển thị (iCmdShow):
SW_HIDE: Ẩn cửa sổ.
SW_MAXIMIZE: Phóng cửa sổ ra toàn bộ màn hình.
SW_MINIMIZE: Thu nhỏ thành biểu tượng trên màn hình.
SW_RESTORE: Hiển thị dưới dạng chuẩn.
28Lập trình Windows
9/13/2011
29
1.2.2. Hàm xử lý thông điệp WinProc
• Có thể có nhiều hơn một hàm xử lý thông điệp
• Luôn đi kèm cửa sổ của nó
• Giao tiếp với hệ thống (Windows), toàn bộ các
thông điệp gửi tới được xử lý qua hàm này
• Thường khai báo như sau:
• Trong đó tham số đầu tiên là định danh của cửa sổ,
tham số thứ 2 là định danh thông điệp, và cuối cùng
là 2 tham số WPARAM và LPARAM bổ sung thông
tin kèm theo thông điệp.
LRESULT CALLBACK WinProc (HWND, UINT, WPARAM, LPARAM);
29Lập trình Windows
9/13/2011
30
Message Loop
• Windows duy trì một hàng đợi thông điệp cho mỗi
chương trình
• Khi sự kiện nhập thông tin xuất hiện, Windows
dịch sự kiện thành dạng thông điệp và đưa vào
hàng đợi thông điệp của ứng dụng tương ứng.
• Ứng dụng nhận thông điệp từ hàng đợi bằng đoạn
mã:
MSG msg; // Windows message structure
while (GetMessage(&msg, NULL, 0,0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
30Lập trình Windows
9/13/2011
31
Message Loop
• Trong đó msg là một biến cấu trúc kiểu MSG được
định nghĩa trong winuser.h
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *PMSG;
• POINT là kiểu tọa độ điểm, định nghĩa trong windef.h
typedef struct tagPOINT {
LONG x;
LONG y;
} POINT, *PPOINT; 31
9/13/2011
32
Message Loop
• Hàm GetMessage sẽ trả về 0 nếu msg chứa
thông điệp có định danh WM_QUIT
(0x0012), khi đó vòng lặp thông điệp ngưng
và ứng dụng kết thúc.
• Ngược lại thì hàm sẽ trả về một giá trị khác 0
với các thông điệp khác.
32Lập trình Windows
9/13/2011
33
Multitasking
33Lập trình Windows
9/13/2011
34
Hàm xử lý thông điệp WinProc - Ví dụ
• Tìm hiểu một hàm xử lý cửa sổ:
LRESULT CALLBACK WinProc (HWND hwnd, UINT msg, WPARAM
wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
/*Xử lý các thông điệp cần thiết với ứng dụng*/
switch (msg){
case WM_CREATE:
/*Viết đoạn mã khi tạo cửa sổ*/
return 0;
case WM_PAINT:
/*Viết đoạn mã khi tô vẽ lại cửa sổ*/
hdc = BeginPaint (hwnd, &ps);
GetClientRect (hwnd, &rect);
34Lập trình Windows
9/13/2011
35
• Thông thường chỉ chặn để xử lý các thông điệp cần thiết, còn
lại giao cho hàm xử lý mặc địnhDefWindowProc
DrawText(hdc, "Hello", -1, &rect,
DT_SINGLELINE| DT_CENTER| DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
case WM_SIZE:
/*Viết đoạn mã khi kích thước cửa sổ thay
đổi*/
return 0;
case WM_DESTROY:
/*Cửa sổ bị đóng*/
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, msg, wParam, lParam);
}
35
9/13/2011
36
Tóm tắt
36Lập trình Windows
9/13/2011
37
1.2.3. Chương trình Windows đơn giản
- Chương trình: HelloWorld (Sử dụng trực tiếp
Windows API)
- 2 hàm chính
- Hàm WinMain: thực hiện c|c chức năng
- Khai b|o lớp cửa sổ
- Đăng ký lớp cửa sổ vừa khai b|o
- Tạo v{ hiển thị lớp cửa sổ
- Vòng lặp nhận thông điệp v{ gửi tới thủ tục xử lý
- Hàm WinProc: H{m xử lý thông điệp gửi đến. C|c
thông điệp được Windows xử lý mặc định bằng h{m
DefWindowProc()
37Lập trình Windows
9/13/2011
38
Win32 Application in Visual C++ Developer Studio
38Lập trình Windows
9/13/2011
39
HelloWorld (1)
/* HELLOWORLD.C */
#include
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR
szCmdLine, int iCmdShow)
{
static TCHAR szAppName [] = TEXT ("HelloWorld");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass (&wndclass)) {
MessageBox(NULL, TEXT (" The program requires Windows"),
szAppName,
MB_ICONERROR);
return 0;
39
Lập trình Windows
9/13/2011
40
HelloWorld (2)
hwnd = CreateWindow(szAppName, // Tên lớp cửa sổ
TEXT (" The Hello World Program"), //
Tiêu đề cửa sổ
WS_OVERLAPPEDWINDOW, // Kiểu cửa sổ
CW_USEDEFAULT, // Toạ độ x
CW_USEDEFAULT, // Toạ độ y
CW_USEDEFAULT, // Chiều ngang
CW_USEDEFAULT, // Chiều dọc
NULL, // Cửa sổ cha
NULL, // Thực đơn
hInstance, // Ðịnh danh
NULL); // Tham số
ShowWindow (hwnd, iCmdShow);
UpdateWindow (hwnd);
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
} // End WinMain
40Lập trình Windows
9/13/2011
41
HelloWorld (3)
LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM
lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (msg) {
case WM_CREATE:
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
GetClientRect (hwnd, &rect);
DrawText(hdc, TEXT("Hello World"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint (hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage (0);
return 0;
} // End switch
return DefWindowProc (hwnd, msg, wParam, lParam);
}
41Lập trình Windows
9/13/2011
42
HelloWorld (run)
42Lập trình Windows
9/13/2011
43
Ý nghĩa các hàm trong HelloWorld
Tên hàm Ý nghĩa
LoadIcon Nạp một biểu tượng để sử dụng trong chương trình.
LoadCursor Nạp một con trỏ chuột cho chương trình.
GetStockObject
Nhận một đối tượng đồ họa, trong trường hợp của
chương trình thì lấy một chổi tô để tô lại nền của cửa
sổ.
RegisterClass
Đăng ký một lớp cửa sổ cho cửa sổ ứng dụng trong
chương trình.
MessageBox Hiển thị một thông điệp.
CreateWindow Tạo một cửa sổ dựa trên một lớp cửa sổ.
ShowWindow Hiển thị cửa sổ lên màn hình.
UpdateWindow Yêu cầu cửa sổ vẽ lại chính bản thân nó.
GetMesssage Nhận một thông điệp từ hàng đợi thông điệp.
TranslateMessage Dịch thông điệp bàn phím.
DispatchMessage Gởi thông điệp đến hàm xứ lý cửa sổ.
BeginPaint Khởi tạo chức năng vẽ của cửa sổ.
GetClientRect Lấy hình chữ nhật lưu vùng làm việc.
DrawText Hiển thị một chuỗi văn bản.
EndPaint Kết thúc việc vẽ cửa sổ.
PostQuitMessage Đưa thông điệp thoát vào hàng đợi thông điệp.
DefWindowProc Thực hiện việc xử lý mặc định các thông điệp.
43
9/13/2011
44
1.3. Microsoft Foundation Classes (MFC)
• MFC = Microsoft Foundation Classes
• Thư viện c|c lớp đóng gói c|c h{m Win32
API
• Tập hợp các lớp C++ (methods, members) và
hàm toàn cục
• Phát triển ứng dụng Windows dễ dàng, rút
ngắn thời gian (so với lập trình Windows
API).
• Program user interface
44Lập trình Windows
9/13/2011
45
MFC và Win32 API
• Win32 API: tập hợp các hàm, cấu trúc, thông
điệp, macros và interfaces
– Cho phép phát triển ứng dụng Win32 platforms.
– Program low-level, tiêu tốn thời gian.
• MFC:
– Tái sử dụng code (reuse) và phát triển các thư
viện.
– Đơn giản hóa và tăng tốc phát triển ứng dụng
bằng cách cung cấp một tập các lớp C++ đóng gói
các đặc điểm của Win32 API
45Lập trình Windows
9/13/2011
46
MFC và Win32 API – Ví dụ
• Khái niệm Win32 của một cửa sổ (window) được
đóng gói bởi lớp CWnd trong MFC.
• CWnd chứa 1 biến thành viên kiểu HWND (kiểu dữ
liệu định nghĩa Win32 biểu diễn một cửa sổ).
• CWnd chứa các phương thức đóng gói gọi đến các
hàm Win32 mà dùng HWND như 1 tham số.
• Ví dụ:
– Hàm: BOOL ShowWindow(HWND hWnd, int nCmdShow);
– Được đóng gói trong MFC:
BOOL CWnd::ShowWindow(int nCmdShow);
46Lập trình Windows
9/13/2011
47
MFC Application Framework
• Ngoài việc đóng gói của Win32 API, MFC còn định
nghĩa một nhóm các lớp để biểu biễn các object ứng
dụng chung và thiết lập mối quan hệ trong nhóm
này để thực thi các hành vi của ứng dụng.
• Application Framework: một nền tảng để xây dựng
các ứng dụng.
• Dùng MFC Wizard để tạo ra tập hợp các lớp dẫn
xuất từ các lớp của framework.
• Hoặc xây dựng các lớp mới theo yêu cầu sử dụng
47Lập trình Windows
9/13/2011
48
48Lập trình Windows
9/13/2011
49
Cấu trúc ứng dụng MFC
• Ứng dụng MFC cung cấp:
– Một lớp biểu diễn ứng dụng (Application Class)
– Một lớp biểu diễn cửa sổ chính của ứng dụng
(Main Window)
– Triển khai h{m WinMain() (được ẩn đi)
(WinMain() Function)
49Lập trình Windows
9/13/2011
50
1.4. Lập trình Windows với VC++ 2008
• 3 c|ch tạo ứng dụng Windows với VC++:
– Ứng dụng sử dụng trực tiếp Windows API
(Win32 Project)
– Ứng dụng sử dụng MFC
(MFC Application)
– Ứng dụng Windows Form
(CLR/Windows Form Application)
50Lập trình Windows
9/13/2011
51
Môi trường phát triển tích hợp VC++ (2008)
IDE:
• The Solution (Workspace)
• Output Pane
• Editor Area
• Menu Bar
• Rearranging on the IDE
51Lập trình Windows
9/13/2011
52
VC++ 2008 Developer Studio Environment
-Solution
Explorer
-Class View
-Resource View
Properties
Editor Area
Output
ToolBox
52Lập trình Windows
9/13/2011
53
The Solution
• Solution Explorer: allows you to view and
navigate all the files that make up your
application.
• Class View allows you to navigate and
manipulate your source code on a C++ class
level.
• Resource View: allows you to find and edit
each of the various resources in your
application, including dialog window
designs, icons, and menus.
53Lập trình Windows
9/13/2011
54
Output Pane & Editor Area
• Output Pane:
– Cung cấp thông tin cho người lập trình
– Compiler progress statements
– Warnings, error messages
– Thông tin debugger:
– Current values of variables when step through code. (Cửa
sổ Watch)
• Editor Area:
– Soạn thảo m~ lệnh
– Thiết kế giao diện (Design mode)
– Icon Editor
54Lập trình Windows
9/13/2011
55
Menu Bar + Rearranging IDE
• Menu bar + Tool bars
• Standard toolbar
• Build toolbar
• Text Editor
• .
• Add/remove Toolbars
• Kéo thả, bố trí c|c cửa sổ l{m việc
• Floating, Dock, Auto hiden, .
55Lập trình Windows
9/13/2011
56
C|c th{nh phần ứng dụng ph|t triển với VC++
56
9/13/2011
57
Character Sets, và _T macro (1)
• Old Windows: Tập ký tự ANSI 8 bit
• Windows NT: Tập ký tự Unicode 16 bit (bao
trùm ANSI).
• Biên dịch ứng dụng VC++ trên Windows NT
có thể chọn sử dụng Unicode hoặc không.
• Nếu một chuỗi “Hello” thì trình biên dịch sẽ
thể hiện dạng ANSI (8bit/1 ký tự).
• Nếu chuỗi L”Hello” thì trình biên dịch sẽ thể
hiện dạng chuỗi Unicode.
57Lập trình Windows
9/13/2011
58
Character Sets, và _T macro (2)
• Dùng macro _T (của MFC) cho chuỗi dạng
_T(“Hello”) thì kết quả sẽ được thể hiện dạng
Unicode nếu ký hiệu tiền xử lý _UNICODE
được định nghĩa (chọn kiểu chuỗi ký tự
Unicode cho ứng dụng), nếu không mặc định
l{ ký tự ANSI.
58
9/13/2011
59
Character Sets và _T macro (3)
• Kiểu TCHAR (dùng thay cho kiểu char):
– L{ wchar_t (Unicode 16 bit) nếu _UNICODE được định
nghĩa
– L{ char (ANSI 8 bit) nếu _UNICODE không được định
nghĩa
• Tương tự, nên dùng TCHAR* hoặc LPTSTR (con
trỏ chuỗi) thay cho wchar_t*, hoặc char*.
• LPCTSTR: con trỏ tới chuỗi hằng
• Sử dụng sizeof(TCHAR) để x|c định độ rộng ký tự
(8 hay 16 bit)
• Sử dụng c|c macro trong thư viện tchar.h thay cho
c|c h{m xử lý ký tự/chuỗi của thư viện C-runtime.
Ví dụ: _tcscpy thay cho h{m strcpy( ) 59
9/13/2011
60
Exercises Chapter 1.
• Ex1-1. HelloWorld
– Tạo project Win32 Project như ví dụ lý thuyết
– Triển khai h{m WinMain, WinProc, cơ chế thông
điệp
• Ex1-2. HelloMFC
– Tìm hiểu sử dụng IDE Visual studio
– Tạo project MFC appllication, sử dụng Wizard
– Code view, design view
– Compile, debug, run
60Lập trình Windows
9/13/2011
61
Create a project
Tên ứng dụng
61Lập trình Windows
9/13/2011
62
Sử dụng Wizard
62
Lập trình Windows
Chọn kiểu ứng
dụng
Sử dụng thư viện
Unicode
9/13/2011
63
Thiết kế giao diện ứng dụng (Dialog)
63Lập trình Windows
9/13/2011
64
Add code to greeting (1)
• Button “Hello”: Right Mouse/Add Event Handler
Chọn sự kiện,
tên hàm xử lý
64Lập trình Windows
9/13/2011
65
Add code to greeting (2)
void CHelloMFCDlg::OnBnClickedButtonHello()
{
// TODO: Add your control notification handler
code here
MessageBox(L"Xin chào ! Lập trình Windows",
L"First MFC Application");
}
Ví dụ gọi hộp thoại
thông báo
65Lập trình Windows
9/13/2011
66
Compile, Build, Debug, Run
Compile (Ctrl+F7),
Build (F6),
Debug (F5),
Run without Debug (Ctrl+F5)
Set Breakpoint (F9) and Run Debug
9/13/2011
67
Chương 2. Lập trình Windows VC++/MFC
• 2.1. \nh xạ thông điệp trong MFC
• 2.2. Document/View trong MFC
• 2.3. Menu và Toolbar
• 2.4. Xử lý vẽ (Drawing)
• 2.5. Giao tiếp b{n phím/chuột
• 2.6. Hộp thoại (Dialogs)
• 2.7. Sử dụng các điều khiển (controls)
67Lập trình Windows
9/13/2011
68
2.1. Message Map trong MFC (1)
• Lập trình MFC cho phép viết c|c h{m để xử lý c|c
thông điệp (messages) mong muốn. (Ngo{i c|c xử
lý mặc định được MFC cung cấp).
• Gọi l{ c|c message handlers (hoặc handlers).
(cũng l{ h{m th{nh viên của lớp v{ được ph}n biệt
bằng tiền tố afx_msg).
• Cơ chế liên kết giữa thông điệp v{ h{m xử lý được
x|c định bởi Message Map (\nh xạ thông điệp)
68Lập trình Windows
9/13/2011
69
2.1. Message Map trong MFC (2)
• Mỗi lớp có xử lý thông điệp sẽ triển khai một
Message Map. Sử dụng c|c macro:
– DECLARE_MESSAGE_MAP() trong file .h
– Cặp BEGIN_MESSAGE_MAP() v{ END_MESSAGE_MAP()
trong file .cpp
(Cặp n{y bao một danh s|ch c|c h{m xử lý tương ứng với
c|c thông điệp)
69Lập trình Windows
9/13/2011
70
2.1. Message Map trong MFC (3)
• Xét một ví dụ ứng dụng MFC đơn giản:
70Lập trình Windows
9/13/2011
71
Message Map trong MFC (2)
71Lập trình Windows
9/13/2011
72
Qu| trình xử lý thông điệp trong MFC
72Lập trình Windows
9/13/2011
73
Ph}n loại thông điệp trong MFC
Message
Category
Description
Windows
Messages
Thông điệp chuẩn của Windows, bắt đầu với WM_
(Ngoại trừ c|c thông điệp WM_COMMAND)
Ví dụ: WM_PAINT, WM_LBUTTONUP,
Control
Notification
Messages
Các thông điệp WM_COMMAND được gửi từ c|c điều
khiển (Controls) như Button, CheckBox, đến cửa sổ
chứa chúng, hoặc từ cửa sổ con đến cửa sổ cha.
Tham số đi kèm (IDs) cho biết gửi từ controls n{o
Command
Messages
Cũng l{ c|c thông điệp WM_COMMAND nhưng được
từ c|c th{nh phần giao diện người dùng như menu
items, toolbar buttons. (Được MFC định nghĩa c|c IDs
chuẩn, người dùng có thể tạo thêm)
73Lập trình Windows
9/13/2011
74
Add Message Handlers
• Có thể l{m thủ công
(Manual) (Viết trong
Message Map).
• Hoặc chọn
Properties/Message
74Lập trình Windows
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
ON_WM_CREATE()
ON_COMMAND(ID_WINDOW_MANAGER,
&CMainFrame::OnWindowManager)
ON_COMMAND(ID_VIEW_CUSTOMIZE,
&CMainFrame::OnViewCustomize)
ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR,
&CMainFrame::OnToolbarCreateNew)
ON_WM_CHAR()
END_MESSAGE_MAP()
9/13/2011
75
2.2. Document/View trong MFC
• Document: Tập hợp dữ liệu của ứng dụng
(dẫn xuất từ lớp CDocument)
• View: Cơ chế
hiển thị dữ liệu
trong Document
(dẫn xuất từ lớp
Cview)
75Lập trình Windows
9/13/2011
76
Document/View trong MFC
• Có thể lựa chọn Document Interfaces:
– SDI (Single Document Interface): Hiển thị một t{i
liệu (Document) mỗi lần trên một cửa sổ (view)
– MDI (Multiple Document Interface): Cho phép
mở nhiều t{i liệu một lúc
• Đều được hợp th{nh bởi c|c th{nh phần
CDocument và Cview
• Có thể tạo ứng dụng MFC kiểu kiến trúc
SDI/MDI
76Lập trình Windows
9/13/2011
77
Khung ứng dụng dạng SDI
• Chỉ mở một t{i liệu
77Lập trình Windows
9/13/2011
78
Khung ứng dụng dạng MDI
• Cho phép mở nhiều t{i liệu
78Lập trình Windows
9/13/2011
79
Ứng dụng MFC based Document/View
• Trong qu| trình tạo ứng dụng dạng SDI v{
MDI, c|c class được tạo ra hầu hết được kế
thừa (dẫn xuất) từ c|c class như:
– Với dạng SDI: CWinApp, CFrameWnd,
CDocument, CView
– Với dạng MDI: CWinApp, CMDIFrameWnd,
CMDIChildWnd, CDocument, CView
79Lập trình Windows
9/13/2011
80
Ứng dụng MFC based Document/View
• Kiểu SDI
80
9/13/2011
81
Mô tả vai trò các class
81Lập trình Windows
9/13/2011
82
Cấu trúc Document/View dạng SDI
82Lập trình Windows
9/13/2011
83
Cấu trúc Document/View dạng MDI
83Lập trình Windows
9/13/2011
84
Sự tương tác giữa Document và View
• Với cả 2 dạng SDI v{ MDI, sự liên kết thể hiện thông
qua 1 biến pointer kiểu đối tượng lớp CDocument
(biến n{y thường có tên l{ pDoc). Thông qua biến
n{y, có thể điều khiển thao t|c chuyển thông tin (từ
lớp CView sang CDocument) hay lấy thông tin về
(từ lớp CDocument sang lớp CView).
• Thông thường, với cả ứng dụng dạng SDI hay MDI
thì trong lớp CView luôn có h{m GetDocument
nhằm hỗ trợ việc lấy biến con trỏ n{y.
84Lập trình Windows
9/13/2011
85
Tương tác Document/View
• Ví dụ:
void CSDIDrawView::OnDraw(CDC* pDC)
{
CSDIDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
//Add draw code here
}
85Lập trình Windows
9/13/2011
86
Lớp CDocument
Một số phương thức quan trọng:
• virtual BOOL OnNewDocument();
• virtual BOOL OnOpenDocument(LPCTSTR
lpszPathName);
• void SetModifiedFlag(BOOL bModified =
TRUE); (Đ|nh dấu: clean/dirty)
• BOOL IsModified();
• virtual void OnCloseDocument();
• virtual BOOL OnSaveDocument(LPCTSTR
lpszPathName);
• CDocument::DeleteContents
86Lập trình Windows
9/13/2011
87
Lớp CView
• CDocument giữ nội dung t{i liệu. Để hiển thị, lớp
CView tạo ra con trỏ đến lớp CDocument
– CDocument* GetDocument() const;
• OnDraw: Vẽ cửa sổ View
• OnInitialUpdate: Được gọi trước khi một view khởi
tạo v{ hiển thị.
• OnUpdate: Được gọi khi dữ liệu đ~ thay đổi để cập
nhật lại View
• Xem MSDN
87Lập trình Windows
9/13/2011
88
C|c lớp View cung cấp sẵn
• MFC x}y dựng sẵn c|c lớp View hỗ trợ c|c dạng giao diện
hiển thị dữ liệu (chọn dẫn xuất từ lớp base tương ứng)
88Lập trình Windows
9/13/2011
89
Ex2-1. Ứng dụng TextEditor
• X}y dựng ứng dụng MFC kiến trúc SDI
• Có c|c tính năng soạn thảo đơn giản (Tương tự
Notepad)
89Lập trình Windows
9/13/2011
90
App Wizard
• X}y dựng ứng dụng kiến trúc SDI
90Lập trình Windows
9/13/2011
91
App Wizard
91Lập trình Windows
Chọn lớp CView sẽ kế
thừa (base class)
9/13/2011
92
Ex2-2. Ứng dụng Sketcher
• Tạo ứng dụng MFC kiến trúc MDI
• Sử dụng Wizard:
– Leave the default option, Multiple documents, but opt out
of Tabbed documents.
– Select MFC standard as the project style and Windows
Native/Default as the Visual style and colors option.
– Keep the Use Unicode libraries option.
– Specify the file extension as ske to get a filter for *.ske
documents defined.
– Change the Generated Classes set of options at their
default settings so that the base class for the
CSketcherView class is CView.
92Lập trình Windows
9/13/2011
93
App Wizard
93Lập trình Windows
9/13/2011
94
2.3. Menu và Toolbar
• 2.3.1. Menu
– Một v{i kh|i niệm
– Tạo lập Menu
– Xử lý
– B{i tập
94Lập trình Windows
9/13/2011
95
Menu – Một vài khái niệm
• Menu bar: bao gồm nhiều drop-down menu và
menu items
• Drop-down menu: chứa menu item hoặc drop-
down menu khác (File, Edit, )
• Menu items: tương ứng với một lệnh của chương
trình. Xác định bằng ID riêng biệt, item ID hay
command ID (Open, Save, )
• Pop-up menu: giống drop-down menu nhưng có
thể xuất hiện ở vị trí bất kỳ (thường chuột phải)
• System menu: chứa các lệnh hệ thống điều khiển
cửa sổ (Minimize, maximize, Close)
95Lập trình Windows
9/13/2011
96
Tạo lập menu
• Thường có 2 cách chính:
– Tạo menu ở dạng resource, load vào khi chạy
(Dùng menu editor)
– Tạo trực tiếp bằng các hàm (sử dụng lớp CMenu)
96
Lập trình Windows
9/13/2011
97
Sử dụng Menu Editor
97Lập trình Windows
9/13/2011
98
Add Handler for menu messages
98Lập trình Windows
9/13/2011
99
Xử lý lệnh của Menu item
• Dựa trên message WM_COMMAND
• Định nghĩa message map
BEGIN_MESSAGE_MAP(CSketcherDoc, CDocument)
ON_COMMAND(ID_COLOR_BLACK, &CSketcherDoc::OnColorBlack)
ON_COMMAND(ID_COLOR_RED, &CSketcherDoc::OnColorRed)
ON_COMMAND(ID_COLOR_GREEN, &CSketcherDoc::OnColorGreen)
ON_COMMAND(ID_COLOR_BLUE, &CSketcherDoc::OnColorBlue)
END_MESSAGE_MAP()
• Viết h{m xử lý:
void CSketcherDoc::OnColorBlack()
{
// TODO: Add your command handler code here
}
99Lập trình Windows
9/13/2011
100
Sử dụng lớp CMenu
• BOOL CreateMenu();
• BOOL CreatePopupMenu();
• BOOL LoadMenu(LPCTSTR
lpszResourceName);
• BOOL LoadMenu(UINT nIDResource);
• Thao tác trên Menu:
– DeleteMenu: Xo| một đối tượng trên menu
– TrackPopupMenu: hiển thị menu popup
100Lập trình Windows
9/13/2011
101
Sử dụng lớp CMenu
• Thao tác trên Menu item:
– 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.
– CheckMenuItem: thêm/bỏ dấu check phía trước một
menuitem
– EnableMenuItem: thiết lập menuitem c|c trạng th|i
enable (MF_ENABLED), disable (MF_DISABLED),
gray(MF_GRAYED).
101Lập trình Windows
9/13/2011
102
Popup (Context) Menu
• 2 cách:
– Thiết kế một menu đặc biệt dùng làm context
menu (bỏ qua top level)
– Sử dụng một thành phần drop-down menu
(submenu) từ menu chính
102Lập trình Windows
9/13/2011
103
Tạo pop-up menu
• Hàm xử lý CWnd::OnContextMenu
• 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)
• Viết hàm xử lý:
103
9/13/2011
104
Tạo lập menu cho dialog
• Tạo một tài nguyên menu cho ứng dụng
• Chọn menu cần gắn vào dialog trong hộp
thoại Dialog Properties.
• Hoặc sử dụng h{m
CMenu::LoadMenu()
104Lập trình Windows
9/13/2011
105
Ex2-3a. Menu
• Tạo lập Menu cho ứng dụng Sketcher trong
Ex2-2 có c|c th{nh phần:
– Element chứa c|c menu items: Line, Rectangle,
Circle, Curve
– Color chứa c|c menu items: Black, Red, Green,
Blue
• (Phục vụ việc vẽ c|c hình với m{u sắc kh|c
nhau)
105Lập trình Windows
9/13/2011
106
2.3. Menu và Toolbar (cont.)
• 2.3.2. Toolbar
– Một số dạng Toolbar
– Thiết kế Toolbar resource
– Thêm Toolbar v{o ứng dụng
– Xử lý thông điệp c|c nút lệnh trên Toolbar
– Xử lý một số dạng toolbar đặc biệt
106Lập trình Windows
9/13/2011
107
Một số dạng Toolbar
107Lập trình Windows
9/13/2011
108
Thiết kế Toolbar Resource
• Với ứng dụng kiến trúc SDI/MDI: tạo sẵn
toolbar mặc định.
• Có thể sử dụng Toolbar Editor (Mở
Resource/Toolbar) để sửa đổi toolbar đ~ có
hoặc tạo toolbar mới.
• Có thể sử dụng ảnh bitmap (thêm v{o
Resource) để thiết kế toolbar. (Sử dụng h{m
LoadBitmap( ) của lớp CToolbar để nạp)
108Lập trình Windows
9/13/2011
109
Sử dụng toolbar editor
• Resource/Toolbar
109Lập trình Wndows
9/13/2011
110
Thêm Toolbar vào ứng dụng
• Sử dụng lớp CToolBar:
(Hoặc CMFCToolBar)
– Khai b|o đối tượng lớp
– Gọi h{m tạo lập cửa sổ Toolbar
– Nạp Toolbar resource đ~ thiết kế
– Thiết lập thuộc tính cho toolbar
– Gắn toolbar v{o cửa sổ chính
110Lập trình Windows
9/13/2011
111
Khai báo đối tượng lớp CToolBar
111Lập trình Windows
9/13/2011
112
Xử lý trong hàm OnCreate – Minh họa 1
112Lập trình Windows
9/13/2011
113
Xử lý trong h{m OnCreate – Minh họa 2
113Lập trình Windows
9/13/2011
114
Toolbar Style
114Lập trình Windows
9/13/2011
115
Xử lý trong h{m Oncreate – Minh họa 2 (tt)
115Lập trình Windows
9/13/2011
116
Toolbar docking style
116Lập trình Windows
9/13/2011
117
H{m xử lý cho c|c nút lệnh trên toolbar
• Nếu toolbar là chức năng từ menu item: Chọn ID cho button
trùng ID của menu item tương ứng (tham chiếu đến h{m xử
lý của menu items)
• Nếu không có menu item tương ứng, thêm viết hàm xử lý
thông điệp (vào MESSAGE_MAP). Ví dụ ID_BUTTON_BOLD
117
9/13/2011
118
Xử lý một số dạng toolbar đặc biệt
• Có nhóm button dạng checkbox
• Có nhóm button dạng radio
• Có Combo box trên Toolbar
118Lập trình Windows
9/13/2011
119
Nhóm button dạng checkbox và radio
• Dạng checkbox: Cho chọn nhiều button trong 1 nhóm
• Dạng radio: Chỉ chọn 1 button trong 1 nhóm
• Giải ph|p: Đặt c|c biến cờ trạng th|i, phối hợp xử lý sự kiện
UPDATE_COMMAND_UI của c|c button tương tự như với menu
items
119Lập trình Windows
9/13/2011
120
Ví dụ xử lý button kiểu check box (1)
120Lập trình Windows
9/13/2011
121
Ví dụ xử lý button kiểu check box (2)
121Lập trình Windows
9/13/2011
122
Ví dụ xử lý button kiểu radio (1)
122Lập trình Windows
9/13/2011
123
Ví dụ xử lý button kiểu radio (2)
123Lập trình Windows
9/13/2011
124
Enable/Disable button
124Lập trình Windows
9/13/2011
125
Combo box trên toolbar
• Nguyên lý tạo cửa sổ con (Combox box) gắn
v{o cửa sổ cha (Toolbar)
125Lập trình Windows
9/13/2011
126
Khai báo đối tượng combo box
126Lập trình Windows
9/13/2011
127
Gắn combo box vào toolbar
127Lập trình Windows
9/13/2011
128
Ex2-3b. Toolbar
• X}y dựng toolbar cho ứng dụng Sketcher. Toolbar
triển khai c|c lệnh của menu items chọn Element v{
Color tương ứng.
• Modify từ Toolbar có sẵn của ứng dụng MDI
128Lập trình Windows
9/13/2011
129
2.4. Xử lý vẽ (Drawing)
• 2.4.1. Cơ bản về vẽ trên Windows
• 2.4.2. Truy xuất ngữ cảnh thiết bị
• 2.4.3. Một số thao t|c vẽ cơ bản
• 2.4.4. Sử dụng c|c đối tượng vẽ
129Lập trình Windows
9/13/2011
130
2.4.1. Cơ bản về vẽ trên Windows
• Hệ tọa độ cung cấp cho xử lý vẽ trên cửa sổ ?
• Vùng ứng dụng của cửa sổ (client area) ?
130Lập trình Windows
9/13/2011
131
GDI ?
• Windows cung cấp GDI (Graphics Device Interface)
– giao diện thiết bị đồ họa, giúp thực hiện thao tác
vẽ dễ dàng hơn, không phụ thuộc vào phần cứng đồ
họa của hệ thống.
• Một chương trình ứng dụng (WindowsApp) không
vẽ trực tiếp ra màn hình, máy in mà chỉ vẽ trên
“bề mặt luận lý” thể hiện bởi ngữ cảnh thiết bị
(Device Context – DC).
• Ngữ cảnh thiết bị chứa các thông tin về hệ thống,
ứng dụng và cửa sổ của WindowsApp cũng như các
đối tượng đồ họa đang được vẽ trong WindowApp
đó.
131Lập trình Windows
9/13/2011
132
Cơ chế vẽ trong MFC
• Ứng dụng MFC (kiến trúc Document/View) chứa lớp dẫn
xuất từ lớp CView (quản lý việc hiển thị dữ liệu lên vùng l{m
việc (client area) của cửa sổ ứng dụng).
• C|c xử lý vẽ trên vùng hiển thị n{y được thực hiện trong
hàm OnDraw( ) (h{m override đ|p ứng thông điệp
WM_PAINT được gọi bất cứ khi n{o vùng cửa sổ cần được vẽ
lại). Minh họa:
132
9/13/2011
133
2.4.2. Truy xuất ngữ cảnh thiết bị (1)
• Lớp CDC:
– Chứa 1 ngữ cảnh thiết bị (device context – dc) và
c|c phương thức cần thiết để xử lý vẽ trong ứng
dụng. (~ 100 h{m).
– Ví dụ: Vẽ đường (LineTo), vẽ hình chữ nhật
(Rectangle), vẽ hình Ellipse,
– L{ lớp cơ sở
133Lập trình Windows
9/13/2011
134
Truy xuất ngữ cảnh thiết bị (2)
• Ngo{i ra MFC cung cấp một số lớp ngữ cảnh thiết bị
chuyên biệt (kế thừa từ lớp CDC):
– CPaintDC: Sử dụng cho việc vẽ trong vùng ứng dụng của
cửa sổ (chỉ thao t|c với sự kiện OnPaint)
– CClientDC: Sử dụng cho việc vẽ trong vùng ứng dụng cửa
sổ (vẽ bất kỳ nơi n{o nhưng chỉ thao t|c với sự kiện
OnPaint)
– CWindowDC: (Sử dụng cho việc vẽ trong cửa sổ, bao
gồm cả vùng không l{ vùng ứng dụng cửa sổ)
– CMetaFileDC: (Sử dụng cho việc vẽ một GDI metafile)
134Lập trình Windows
9/13/2011
135
Truy xuất ngữ cảnh thiết bị (3)
• Để lấy ngữ cảnh thiết bị, khai b|o biến đối tượng
lớp, dùng:
CDC dc(this);
• Hoặc biến con trỏ CDC *pDC = GetDC( );
• Để giải phóng ngữ cảnh thiết bị, dùng:
ReleaseDC(pDC);
delete pDC;
135Lập trình Windows
9/13/2011
136
Truy xuất ngữ cảnh thiết bị (4)
• Tọa độ vẽ hiện thời (current position):
– Tọa độ điểm trên vùng vẽ
– Quan hệ tương đối, có thể thay đổi khi thực hiện
vẽ c|c thực thể (line, circle, rectangle, text)
– Có thể thiết lập bằng phương thức của lớp CDC:
136Lập trình Windows
CPoint MoveTo(int x, int y);
// Move to position x,y
CPoint MoveTo(POINT aPoint);
// Move to position defined by aPoint
9/13/2011
137
2.4.3. Một số thao t|c vẽ cơ bản (1)
• Vẽ đường thẳng (Lines): từ vị trí hiện tại đến vị trí
(x,y)
• Ví dụ:
137Lập trình Windows
BOOL LineTo(int x, int y);
// Draw a line to position x,y
BOOL LineTo(POINT aPoint);
// Draw a line to position defined by aPoint
CDC *pDC;
pDC->MoveTo(50,50); // Set the current position
pDC->LineTo(50,200); // Draw a vertical line down 150 units
pDC->LineTo(150,200); // Draw a horizontal line right 100 units
pDC->LineTo(150,50); // Draw a vertical line up 150 units
pDC->LineTo(50,50); // Draw a horizontal line left 100 units
9/13/2011
138
Một số thao t|c vẽ cơ bản (2)
• Vẽ đường tròn (circle):
• Vẽ cung (Arc):
• Ví dụ:
BOOL Ellipse(int x1, int y1, int x2, int y2);
BOOL Ellipse(LPCRECT lpRect);
BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
BOOL Arc(LPCRECT lpRect, POINT startPt, POINT endPt);
CDC *pDC;
pDC->Ellipse(50,50,150,150); // Draw the 1st (large) circle
// Define the bounding rectangle for the 2nd (smaller) circle
CRect rect(250,50,300,100);
CPoint start(275,100); // Arc start point
CPoint end(250,75); // Arc end point
pDC->Arc(&rect, start, end); // Draw the second circle
9/13/2011
139
Một số thao t|c vẽ cơ bản (3)
• CDC::Polygon
• CDC::Rectangle
• CDC::Draw3dRect
• CDC::DrawText
•
139Lập trình Windows
virtual int DrawText(
LPCTSTR lpszString,
int nCount,
LPRECT lpRect,
UINT nFormat
);
int DrawText(
const CString& str,
LPRECT lpRect,
UINT nFormat
);
9/13/2011
140
2.4.4. Sử dụng c|c đối tượng vẽ (1)
• L{m thế n{o để:
– Vẽ c|c đường vẽ có m{u sắc, phong c|ch (style)
khác nhau
– Tô m{u c|c đối tượng vẽ với m{u sắc, kiểu tô
khác nhau
– Vẽ chữ với c|c m{u sắc, kiểu c|ch kh|c nhau
• Cần sử dụng c|c đối tượng vẽ (bút vẽ, chổi tô
m{u, font chữ)
140Lập trình Windows
9/13/2011
141
Sử dụng c|c đối tượng vẽ (2)
• Bút vẽ (Pen): dùng để vẽ đường
• Chổi vẽ/cọ vẽ (Brush): dùng tô m{u
• Font
• C|c đối tượng n{y đều được quản lý bởi c|c lớp
MFC tương ứng.
141Lập trình Windows
9/13/2011
142
Sử dụng bút vẽ (1)
• Lớp CPen
• Vẽ đường với kiểu, m{u sắc, độ rộng x|c định
• Tạo bút vẽ:
142Lập trình Windows
CPen( );
CPen(
int nPenStyle,
int nWidth,
COLORREF crColor
);
CPen(
int nPenStyle,
int nWidth,
const LOGBRUSH* pLogBrush,
int nStyleCount = 0,
const DWORD* lpStyle = NULL
);
9/13/2011
143
Sử dụng bút vẽ (2)
• Ví dụ như sau tạo bút vẽ mới v{ chọn l{m bút vẽ
hiện thời, dùng:
143Lập trình Windows
9/13/2011
144
Sử dụng bút vẽ (3)
• Có thể tạo bút vẽ dùng h{m CPen::CreatePen
• Ví dụ minh họa c|ch dùng n{y:
144Lập trình Windows
// Declare a pen object and initialize it as
// a red solid pen drawing a line 2 pixels wide
CPen aPen;
aPen.CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
CPen* pOldPen = pDC->SelectObject(&aPen); // Select aPen as the pen
pDC->Ellipse(50,50,150,150); // Draw the 1st (large) circle
// Define the bounding rectangle for the 2nd (smaller) circle
CRect rect(250,50,300,100);
CPoint start(275,100); // Arc start point
CPoint end(250,75); // Arc end point
pDC->Arc(&rect,start, end); // Draw the second circle
pDC->SelectObject(pOldPen); // Restore the old pen
9/13/2011
145
Sử dụng cọ vẽ (1)
• Lớp Cbrush
• Có thể tạo cọ vẽ bằng c|ch dùng h{m tạo, hoặc dùng
hàm CreateBrush
145Lập trình Windows
CBrush( );
CBrush(
COLORREF crColor
);
CBrush(
int nIndex,
COLORREF crColor
);
explicit CBrush(
CBitmap* pBitmap
);
9/13/2011
146
Sử dụng cọ vẽ (2)
• Ví dụ tạo cọ vẽ mới v{ chọn l{m cọ vẽ hiện thời:
146Lập trình Windows
9/13/2011
147
GDI Fonts và Lớp CFont
• Ngo{i việc sử dụng font chữ mặc định, người dùng
còn có thể tạo font chữ trong chế độ đồ họa tùy
chọn.
147Lập trình Windows
9/13/2011
148
Ex2-4. Vẽ trong ứng dụng Sketcher
• Thực hiện các thao tác vẽ cơ bản trên ứng
dụng Sketcher:
– Vẽ đường thẳng, hình tròn, hình chữ nhật
– (C|c đối tượng vẽ tại vị trí hiện thời)
• Thay đổi bút vẽ (CPen), chổi vẽ (CBrush)
khác nhau
148Lập trình Windows
9/13/2011
149
2.5. Giao tiếp với chuột, b{n phím
• 2.5.1. Giao tiếp với chuột
• 2.5.2. Giao tiếp với b{n phím
149Lập trình Windows
9/13/2011
150
2.5.1. Giao tiếp với chuột
• Cần xử lý sự kiện chuột gì ?
– Phím chuột tr|i/phải được ấn/nhả (down/up)
– Giữ phím tr|i v{ di chuột (mousemove)
– Phím chuột giữa, phím chuột mở rộng (nếu có)
– Ấn phím chuột kèm phím chức năng (Control, Shift)
• Xử lý gì ? (phụ thuộc v{o ứng dụng)
• Nơi n{o (lớp n{o) nhận xử lý sự kiện chuột ?
• Ví dụ: Với ứng dụng sketcher:
– Muốn vẽ đối tượng bắt đầu khi ấn chuột tr|i (down), giữ
+ di chuột (move), ho{n th{nh khi nhả chuột (up).
– C|c đối tượng được vẽ trên lớp CSketcherView, cần bắt
sự kiện chuột trên lớp n{y.
150Lập trình Windows
9/13/2011
151
Thông điệp từ sự kiện chuột
• Chọn lớp cần xử lý thông
điệp từ chuột
• Chọn mouse messages
muốn xử lý (trong
Properties)
• Chọn h{m xử lý (message
handlers) trong cột bên
phải tương ứng message
muốn xử lý
151Lập trình Windows
9/13/2011
152
Mouse Message Handlers (1)
Thông điệp
(Messages)
Sự kiện
(Events)
Hàm xử lý
(Handlers)
WM_LBUTTONDOWN Nút tr|i chuột được nhấn xuống OnLButtonDown
WM_LBUTTONUP Nút tr|i chuột được nhả ra OnLButtonUp
WM_LBUTTONDBLCLK Nút tr|i chuột được nhấn kép OnLButtonDblClk
WM_MBUTTONDOWN Nút giữa chuột được nhấn xuống OnMButtonDown
WM_MBUTTONUP Nút giữa chuột được nhả ra OnMButtonUp
WM_MBUTTONDBLCLK Nút giữa chuột được nhấn kép OnMButtonDblClk
WM_RBUTTONDOWN Nút phải chuột được nhấn xuống OnRButtonDown
WM_RBUTTONUP Nút phải chuột được nhả ra OnRButtonUp
WM_RBUTTONDBLCLK Nút phải chuột được nhấn kép OnRButtonDblClk
WM_MOUSEMOVE Con chuột được di chuyển OnMouseMove
152Lập trình Windows
9/13/2011
153
Mouse Message Handlers (2)
• C|c h{m xử lý thông điệp có dạng:
• Ví dụ h{m xử lý thông điệp nút chuột tr|i được
nhấn trên vùng cửa sổ hiển thị
• Lập trình xử lý hoặc gọi đến handlers tương ứng
của lớp cơ sở.
153Lập trình Windows
void CSketcherView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CView::OnLButtonDown(nFlags, point);
}
afx_msg void OnMsgName(UINT nFlags, CPoint point)
9/13/2011
154
Mouse Message Handlers (3)
• 2 tham số:
– CPoint point: Tọa độ chuột lúc xảy ra sự kiện
– UINT nFlags: Cờ (32 bit) cho biết nút chuột được
nhấn v{ nhận biết c|c phím Control/Shift nếu
được bấm kèm.
– Có c|c gi| trị hằng mặt nạ (Mask) được định
nghĩa phục vụ cho x|c định nFlags n{y.
154Lập trình Windows
9/13/2011
155
nFlags
• Để nhận biết gi| trị cờ n{y, dùng phép & (bitwise)
với mặt nạ. Ví dụ nhận biết phím Ctrl có được nhấn
cùng chuột:
155Lập trình Windows
if ((nFlags & MK_CONTROL) == MK_CONTROL) {}
9/13/2011
156
Ví dụ giao tiếp với chuột (1)
void CVdMouseView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
MyDrawFunction(point);
CView::OnLButtonDown(nFlags, point);
}
void CVdMouseView::MyDrawFunction(CPoint point)
{
CDC *pDC = GetDC();
if((m_PrevPoint.x == -1)&&(m_PrevPoint.y == -1))
pDC->MoveTo(point);
else
{
pDC->MoveTo(m_PrevPoint);
pDC->LineTo(point);
}
m_PrevPoint = point;
}
9/13/2011
157
Ví dụ giao tiếp với chuột (2)
157Lập trình Windows
void CVdMouseView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call
default
CDC *pDC = GetDC();
CString szTextOut;
szTextOut.Format("Current point(%d, %d)", point.x, point.y);
pDC->TextOut(0, 0, szTextOut);
if((nFlags & MK_CONTROL)==MK_CONTROL)
MyDrawFunction(point);
CView::OnMouseMove(nFlags, point);
}
9/13/2011
158
2.5.2. Giao tiếp với b{n phím
158Lập trình Windows
• Loại sự kiện phím:
– Phím thông thường được nhấn xuống/nhả lên
(down/up)
– Phím chức năng được nhấn xuống/nhả lên
– Phím được nhấn v{ giữ (hold), đọc được nhiều
lần.
– Tổ hợp phím được nhấn (nhấn kèm c|c phím
chức năng: Alt, Ctrl, Shift)
• Mục tiêu: bắt được c|c sự kiện về phím, đọc
m~ phím để có xử lý thích hợp
9/13/2011
159
Xử lý thông điệp từ b{n phím (1)
• MFC hỗ trợ giao tiếp b{n phím bởi c|c thông
điệp v{ h{m xử lý tương ứng như sau:
159Lập trình Windows
Thông điệp
(Messages)
Sự kiện
(Events)
Hàm xử lý
(Handlers)
WM_KEYDOWN Phím thường được nhấn xuống OnKeyDown
WM_KEYUP Phím thường được nhả ra OnKeyUp
WM_SYSKEYDOWN Phím chức năng được nhấn xuống OnSysKeyDown
WM_SYSKEYYP Phím chức năng được nhả ra OnSysKeyUp
9/13/2011
160
Xử lý thông điệp từ b{n phím (2)
• C|c h{m xử lý thông điệp phím có dạng:
• Ví dụ:
160Lập trình Windows
afx_msg void OnMsgName(UINT nChar, UINT nRepCnt, UINT nFlags)
void CSketcherView::OnKeyDown(UINT nChar, UINT
nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call
default
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
9/13/2011
161
Xử lý thông điệp từ b{n phím (3)
• Ngo{i ra có thể dùng h{m:
• C|c tham số:
– nChar: x|c định m~ phím được ấn (virtual key code).
(Được định nghĩa trong Winuser.h)
– nRepCnt: Số lần lặp (khi giữ phím)
– nFlags: x|c định m~ scan code, trạng th|i phím trước,
phím nhấn/nhả,
– Ví dụ:
• Bit 13 (Context Code) =1 nếu phím Alt được nhấn kèm
• Bit 15 (Key-transition) = 0 nếu l{ nhấn (pressed), =1 nếu l{ nhả
(released)
161Lập trình Windows
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
9/13/2011
162
nChar (virtual key code) – Ví dụ
162Lập trình Windows
9/13/2011
163
Ví dụ giao tiếp b{n phím
• Thực hiện thay đổi con trỏ tương ứng với các
phím chọn
• Xử lý sự kiện:
OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
163Lập trình Windows
9/13/2011
164
2.6. Hộp thoại (Dialogs)
• 2 loại:
– Dialog (Hộp thoại thông thường/tùy biến)
– Common Dialog (C|c hộp thoại chuyên dụng)
164Lập trình Windows
9/13/2011
165
2.6.1. Hộp thoại (Dialogs)
• Dialog box:
– L{ một cửa sổ (window)
– Ứng dụng thường dùng dialogs chứa c|c điều khiển
(controls) (bản chất cũng l{ cửa sổ)
• 2 yếu tố của 1 dialog trong ứng dụng MFC:
– Diện mạo vật lý của dialog (được định nghĩa trong file
resource)
– Đối tượng lớp dialog (dùng để quản lý c|c hoạt động của
dialog v{ c|c điều khiển đặt trên nó)
• MFC cung cấp lớp cơ sở CDialog, có thể sử dụng lớp
dẫn xuất từ nó cho c|c dialog sau khi đ~ tạo ra
resource (diện mạo thiết kế).
165Lập trình Windows
9/13/2011
166
Thiết kế dialog (resource)
• Mở Resource View, cho phép:
– Thiết kế 1 dialog trên vùng l{m việc
– Lấy c|c điều khiển (control) từ ToolBox
– Tạo dialog mới bằng Insert Dialog
• Định danh dialog: IDD_DIALOG
166
9/13/2011
167
Lập trình cho dialog (1)
• Gồm 2 khía cạnh cần giải quyết:
– Hiển thị (gọi) dialog đó lên
– Lập trình xử lý sự kiện cho c|c điều khiển đặt
trên dialog đó
167Lập trình Windows
9/13/2011
168
Lập trình cho dialog (2)
• Gắn lớp quản lý
cho dialog sau
khi đ~ thiết kế
resource bằng
c|ch chọn Add
Class (chọn
chuột phải trên
dialog cần add)
168Lập trình Windows
9/13/2011
169
Lớp quản lý dialog – minh họa
169Lập trình Windows
// CPenDialog dialog
class CPenDialog : public CDialogEx
{
DECLARE_DYNAMIC(CPenDialog)
public:
CPenDialog(CWnd* pParent = NULL); // standard constructor
virtual ~CPenDialog();
// Dialog Data
enum { IDD = IDD_PENWIDTH_DLG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
9/13/2011
170
Modal và Modaless Dialogs
• Có 2 loại dialogs: kiểu modal v{ modaless (kh|c
nhau về c|ch hoạt động)
• Modal dialog:
– Khi hiển thị l{m tất cả c|c cửa sổ kh|c của ứng dụng sẽ
treo cho đến khi nó được đóng (thường l{ chọn OK,
Cancel)
– Tạo bằng c|ch khai b|o đối tượng lớp quản lý dialog, v{
gọi h{m DoModal().
• Modeless dialog: (ngược lại)
– Khi hiển thị nó, vẫn có thể chọn v{o c|c cửa sổ kh|c của
ứng dụng.
– Có thể tạo bằng c|ch dùng h{m CDialog::Create
170Lập trình Windows
9/13/2011
171
Hiển thị dialog
• X|c định khi n{o muốn hiển thị dialog (phụ thuộc
v{o ứng dụng). Ví dụ: khi chọn một menu item, click
v{o một nút lệnh,
• Viết m~ lệnh gọi hiển thị dialog đ~ chuẩn bị tại nơi
đ~ x|c định. Minh họa:
• Chú ý: Cần #include header file của lớp quản lý v{o
file m~ nguồn chứa khai b|o đối tượng lớp quản lý
dialog.
171Lập trình Windows
// Handler for the pen width menu item
void CSketcherDoc::OnPenWidth()
{
CPenDialog aDlg; // Create a local dialog object
aDlg.DoModal(); // Display the dialog as modal
}
9/13/2011
172
Đóng (close) dialog
• Nút lệnh OK, Cancel
• H{m ảo (virtual) tương ứng:
– CDialog::OnOK() trả về ID nút OK (mặc định IDOK)
– CDialog::OnCancel() trả về ID nút Cancel (IDCANCEL)
• Có thể thiết kế, Override lại h{m xử lý sự kiện click
c|c nút n{y để thực hiện những h{nh xử thích hợp
172Lập trình Windows
9/13/2011
173
Hàm MessageBox (1)
• nType: what buttons display ?
173Lập trình Windows
9/13/2011
174
Hàm MessageBox (2)
• nType: button OR Icon
174Lập trình Windows
9/13/2011
175
2.6.2. Common Dialogs (1)
• MFC cung cấp c|c hộp thoại chuyên dụng hỗ
trợ những thao t|c phổ biến trong c|c ứng
dụng trên Windows: chọn Font, chọn m{u,
Open/Save file, In ấn,
• C|c loại hộp thoại n{y đều có lớp MFC quản
lý
175Lập trình Windows
9/13/2011
176
Common Dialogs (2)
• Nguyên tắc gọi các dialogs chuyên dụng:
– Tạo đối tượng thuộc lớp Dialog cần dùng (cung
cấp các thông tin cơ bản)
– Gọi hàm DoModal() để hiển thị
– Lấy các giá trị quan tâm từ đối tượng đ~ khai báo
(Sau khi tương t|c với người dùng)
176Lập trình Windows
9/13/2011
177
CFileDialog (1)
• Lớp đóng gói làm việc với hộp thoại tập tin thông
dụng của Windows (Open, Save As, )
• H{m khởi tạo CFileDialog::CFileDialog
• Khởi tạo một đối tượng hộp thoại tập tin Windows
chuẩn.
177Lập trình Windows
CFileDialog( BOOL bOpenFileDialog,
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY |
OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL );
9/13/2011
178
CFileDialog (2)
• bOpenFileDialog:
– TRUE: Open
– FALSE: Save As
• lpszDefExt:
– Đuôi mở rộng mặc định của tên tập tin. Nếu người dùng
không nhập kèm đuôi mở rộng trong ô edit box của File
name, phần mở rộng được chỉ định bởi lpszDefExt sẽ
được tự động thêm v{o tên của tập tin. Nếu gi| trị n{y l{
NULL, sẽ không có phần mở rộng được thêm v{o.
• lpszFileName:
– Tên tập tin khởi tạo sẽ được xuất hiện trong ô edit box
của File name. Nếu gi| trị n{y l{ NULL, sẽ không có tên
tập tin n{o xuất hiện.
178Lập trình Windows
9/13/2011
179
CFileDialog (3)
• dwFlags:
– Một phép kết hợp của một hay nhiều biến cờ cho phép
tùy chỉnh hộp thoại. Khi chỉnh sửa biến th{nh viên cấu
trúc m_ofn.Flags, dùng một to|n tử OR trong những thay
đổi để giữ những thiết lập mặc định không bị ảnh
hưởng.
• lpszFilter:
– Một d~y c|c cặp chuỗi chỉ định những bộ lọc bạn có thể
|p dụng cho tập tin. Nếu bạn chỉ định bộ lọc tập tin, chỉ
những tập tin có trong bộ lọc mới xuất hiện trong list
box.
• pParentWnd:
– Một con trỏ trỏ tới đối tượng hộp thoại tập tin l{ cha hay
cửa sổ chủ. 179Lập trình Windows
9/13/2011
180
Các phương thức lớp CFileDialog
• CFileDialog::DoModal()
- H{m trả về IDOK hay IDCANCEL. (tương ứng người dùng
chọn nút OK hay nút Cancel).
- Khi người dùng click nút OK hay Cancel, hay chọn chức
năng Close từ đều khiển menu của hộp thoại, quyền điều
khiển được trao lại cho ứng dụng. Sau đó, có thể gọi c|c h{m
th{nh viên kh|c để nhận về c|c thiết lập hay c|c thông tin
m{ người dùng nhập v{o hộp thoại.
- DoModal l{ một h{m ảo kế thừa từ lớp CDialog.
180Lập trình Windows
9/13/2011
181
Các phương thức 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
chọn
181Lập trình Windows
9/13/2011
182
CFileDialog - Open
182Lập trình Windows
TCHAR szFilters[] = _T("Text files(*.txt)¦*.txt¦All files *.*)¦*.*¦¦");
CFileDialog
dlg(TRUE,_T("txt"),_T("*.txt"),OFN_FILEMUSTEXIST¦OFN_HIDEREADONLY,z
Filters);
if(dlg.DoModal() == IDOK) {
filename = dlg.GetPathName();
// Open the file and read it.
}
9/13/2011
183
CFileDialog – Save As
183Lập trình Windows
void CChildView::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();
}
9/13/2011
184
CColorDialog
• Constructor:
– CColorDialog( COLORREF clrInit = 0, DWORD dwFlags =
0, CWnd* pParentWnd = NULL )
• Methods:
– virtual int DoModal()
– COLORREF GetColor() const
– static COLORREF* PASCAL GetSavedCustomColors
– protected virtual BOOL OnColorOK()
– void SetCurrentColor( COLORREF clr )
184Lập trình Windows
9/13/2011
185
CColorDialog
185Lập trình Windows
CColorDialog dlg(RGB(255, 0, 0), CC_FULLOPEN);
if(dlg.DoModal() == IDOK)
{
///////////////////////////////////
AfxMessageBox("Chon mau", 0, 0);
m_oColor = dlg.GetColor();
}
9/13/2011
186
CFontDialog
• H{m tạo/Constructor:
– CFontDialog( const CHARFORMAT& charformat,
DWORD dwFlags = CF_SCREENFONTS,
CDC* pdcPrinter = NULL,
CWnd* pParentWnd = NULL );
186Lập trình Windows
9/13/2011
187
CFontDialog
• Parameters:
– lplfInitial: A pointer to a LOGFONT data structure that allows you to
set some of the font's characteristics.
– charFormat: A pointer to a CHARFORMAT data structure that
allows you to set some of the font's characteristics in a rich edit
control.
– dwFlagsSpecifies one or more choose-font flags. One or more
preset values can be combined using the bitwise OR operator. If you
modify the m_cf.Flags structure member, be sure to use a bitwise
OR operator in your changes to keep the default behavior intact.
For details on each of these flags, see the description of the
CHOOSEFONT structure in the Platform SDK.
– pdcPrinter: A pointer to a printer-device context. If supplied, this
parameter points to a printer-device context for the printer on
which the fonts are to be selected.
– pParentWnd: A pointer to the font dialog box's parent or owner
window.
187Lập trình Windows
9/13/2011
188
2.7. C|c điều khiển thông dụng
• 2.7.1. Các điều khiển thông dụng
• 2.7.2. Thiết kế c|c điều khiển trên hộp thoại
• 2.7.3. C|c vấn đề chính với c|c điều khiển
• 2.7.4. Lớp MFC của c|c điều khiển
• 2.7.5. B{i tập
188Lập trình Windows
9/13/2011
189
2.7.1. Các điều khiển thông dụng
• Static text
• Edit box
• Command button
• Check box
• Radio button
• Drop-down list box
(combo box)
• Sliders, tree and list controls,
progress bars,
Click &
Drag/Drop
189Lập trình Windows
9/13/2011
190
2.7.2. Thiết kế c|c điều khiển trên hộp thoại (1)
• Lựa chọn điều khiển muốn dùng trong Toolbox.
Thao t|c click hoặc kéo thả.
• Thiết kế c|c điều khiển đặt trên dialog (sắp xếp, căn
chỉnh)
190Lập trình Windows
9/13/2011
191
Thiết kế điều khiển trên hộp thoại (2)
• Thiết lập c|c thuộc tính cho điều khiển tại
thời điểm thiết kế.
• Cửa sổ Properties của điều khiển
191Lập trình Windows
9/13/2011
192
• Sử dụng Tab Order:
– Format/Tab Order (Ctrl+D): Thiết lập thứ tự chọn (focus)
bằng phím Tab cho các điều khiển
– Click chuột để chọn thứ tự.
192
Thiết kế c|c điều khiển trên hộp thoại (3)
9/13/2011
193
• Sử dụng Mnemonics:
– Dùng để thao t|c với điều khiển bằng phím tắt
(Alt + ?)
– Ký tự gạch chân trong caption của điều khiển
• Ví dụ:
– Button: “Show &Message” Alt+M
• Kiểm tra: Format/Check Mnemonic
193Lập trình Windows
Thiết kế c|c điều khiển trên hộp thoại (3)
9/13/2011
194
2.7.3. C|c vấn đề chính với c|c điều khiển (1)
• Dữ liệu được lưu trên c|c điều khiển là gì ?
(Cần lấy/input hay hiện/output dữ liệu)
• Lấy/hiện dữ liệu của c|c điều khiển bằng
cách nào ?
• Dữ liệu lấy v{o từ điều khiển có hợp lệ ?
• Loại sự kiện gì cần dùng khi tương t|c với
điều khiển ? (h{m xử lý sự kiện cần dùng)
• Có nhu cầu thao t|c vật lý đối với điều khiển
đó không ? (Thay đổi chữ, di chuyển,
enable/disable, show/hidden, )
194Lập trình Windows
9/13/2011
195
C|c vấn đề chính với c|c điều khiển (2)
• Để lấy/đưa dữ liệu từ/đến c|c điều khiển cần thông
qua biến quản lý (loại Value) được đăng ký (gắn)
với điều khiển.
• Cần sử dụng h{m cho phép đồng bộ dữ liệu giữa gi|
trị biến nắm giữ v{ nội dung hiển thị trên điều
khiển (khi tương t|c với người dùng)
• Để thực hiện thao t|c vật lý với điều khiển cần gọi
c|c phương thức thích hợp (của lớp cửa sổ). Thông
qua biến loại Control được đăng ký với điều khiển.
• Khai b|o v{ viết h{m xử lý sự kiện cho điều khiển
195Lập trình Windows
9/13/2011
196
Đăng ký biến cho điều khiển (1)
• Có 2 loại biến có thể gắn với điều khiển tùy
mục đích:
– Để tham chiếu đến điều khiển (thay đổi diện mạo)
Dùng biến loại Control
– Để nhận/đưa dữ liệu từ/đến điều khiển
Dùng biến loại Value
• Thực hiện:
– Chọn điều khiển muốn đăng ký biến
– Format/Add variable
Hoặc Right Mouse/Add variable
196Lập trình Windows
9/13/2011
197
Đăng ký biến cho điều khiển (2)
Chọn loại biến:
Control/Value
Chú thích xuất
hiện trong code
Tên, kiểu dữ
liệu của biến
197Lập trình Windows
Tên biến
9/13/2011
198
Đồng bộ dữ liệu giữa điều khiển/biến
• Mục đích:
– Đồng bộ giá trị của một điều khiển với biến loại
giá trị của nó
– Cập nhật khi cần nhận dữ liệu từ điều khiển hoặc
đưa dữ liệu ra điều khiển.
• Thực hiện bằng h{m:
– bSaveAndValidate = TRUE (1) : Dữ liệu trên điều
khiển được cập nhật v{o biến.
– bSaveAndValidate = FALSE (0) : Dữ liệu lưu giữ
trong biến được đưa ra điều khiển.
BOOL UpdateData(BOOL bSaveAndValidate)
198Lập trình Windows
9/13/2011
199
Đăng ký hàm xử lý sự kiện (1)
• Có nhiều sự kiện khác nhau với
c|c điều khiển
– Mouse down/up, DBClick, Move,
– Key down/up, pressed,
– Init, create, paint,
• Thêm h{m xử lý sự kiện mong
muốn
– C1: Right Mouse/
Add Event Handler
– C2: Properties Window/
Control Events
199Lập trình Windows
9/13/2011
200
Đăng ký h{m xử lý sự kiện (2)
• Ví dụ: Button ShowMSG Add Event Handler
Chọn sự
kiện
200Lập trình Windows
Chọn lớp nhận thông
điệp tương ứng
Tên h{m xử lý
được gợi ý
9/13/2011
201
Thao t|c vật lý với c|c điều khiển
• Cho phép/không cho phép (enable/disable) tương
t|c với điều khiển.
BOOL CWnd::EnableWindow(BOOL bEnable)
• Ẩn/Hiện (Hidden/Show) điều khiển
BOOL CWnd::ShowWindow(int iCmdShow)
• Hàm: CWnd* CWnd::GetDlgItem(int nID)
//Lấy con trỏ đến điều khiển/cửa sổ con trong cửa
sổ cha. Ví dụ
201Lập trình Windows
CEdit* pBoxOne;
pBoxOne = (CEdit*)GetDlgItem(IDC_MYEDIT);
9/13/2011
202
2.7.4. Lớp MFC của c|c điều khiển
• MFC cung cấp lớp đại diện cho c|c điều khiển.
• Một số lớp ví dụ:
• Bản chất c|c điều khiển (controls) cũng l{ c|c cửa sổ đặc
biệt. C|c lớp của điều khiển dẫn xuất từ lớp cơ sở CWnd. Do
đó có thể sử dụng đến c|c h{m thích hợp của lớp n{y.
• Ngo{i tạo điều khiển lúc thiết kế (Resource), có thể tạo điều
khiển bằng h{m Create (lớp cơ sở CWnd) lúc thực thi.
202Lập trình Windows
9/13/2011
203
2.7.4.1. Lớp CEdit (1) – Khởi tạo
• Quản lý hộp nhập, xử lý hoạt động nhập liệu, thông
tin về tình hình nhập liệu cho cửa sổ cha.
• H{m tạo: CEdit()
• H{m Create: Khởi tạo đối tượng hộp nhập với c|c
tham số.
203Lập trình Windows
BOOL Create (
DWORD dwStyle, // kiểu hộp nhập (ES_MULTILINE,
ES_PASSWORD, ES_READONLY)
const RECT& rect, // Tọa độ v{ kích thước hộp nhập
CWnd* pParentWnd, // Con trỏ tới đối tượng cửa sổ cha
UINT nID // Định danh hộp nhập
);
9/13/2011
204
Lớp CEdit (2) – Hàm thành viên
• 3 nhóm hàm thành viên:
– CEdit Attributes: Nhóm h{m về thuộc tính của hộp nhập.
(kích thước, vị trí, số dòng, undo, )
– CEdit Operations: Nhóm h{m về hoạt động của hộp nhập
– CEdit Clipboard Operations: Nhóm h{m về thao t|c soạn
thảo trên hộp nhập (Copy, paste, cut, clear, undo)
• Ví dụ một số h{m:
– void GetRect ( LPRECT lpRect);
– BOOL GetModify( );
– void SetModify(BOOL bModified = TRUE);
– BOOL SetReadOnly( BOOL bReadOnly = TRUE );
– void SetPasswordChar (TCHAR ch);
– (Xem thêm MSDN)
204Lập trình Windows
9/13/2011
205
Lớp CEdit (3) – Xử lý sự kiện
• C|c thông điệp sự kiện trên hộp nhập liệu
được gửi đến cửa sổ cha.
• Mục xử lý thông được được thêm v{o |nh xạ
thông điệp (Message Map) trong lớp cửa sổ
cha có dạng:
– ON_Notification (ID, memberFxn )
– Trong đó: ID x|c định định danh hộp nhập;
memberFxn tên h{m xử lý thông điệp tương ứng.
– Ví dụ: ON_EN_UPDATE(IDC_EDIT1,
&CMyDialogDlg::OnEnUpdateEdit1)
205Lập trình Windows
9/13/2011
206
Lớp CEdit (4) – Xử lý sự kiện
• C|c thông điệp trên hộp
nhập:
• (EN = Event Notification)
206Lập trình Windows
9/13/2011
207
Lớp CEdit (5) – Ví dụ:
207Lập trình Windows
// dynamically create an edit control
CEdit* pEdit = new CEdit;
pEdit->Create(ES_MULTILINE | WS_CHILD | WS_VISIBLE
| WS_TABSTOP | WS_BORDER, CRect(10, 10, 100, 100),
this, 1);
//get text from edit box.
CString yourname;
pEdit->GetWindowText( yourname );
MessageBox ( yourname, "Hello !", MB_OK |
MB_ICONEXCLAMATION );
9/13/2011
208
2.7.4.2. Lớp CButton (1) – Khởi tạo
• Quản lý c|c điều khiển dạng nút chọn (Button,
radio, checkbox, ) (xem button styles)
• H{m tạo CButton()
• Hàm Create()
208Lập trình Windows
BOOL Create (
LPCTSTR lpszCaption, //Nội dung thông b|o
DWORD dwStyle, //dạng nút (ví dụ BS_PUSHBUTTON)
const RECT& rect, // Tọa độ, kích thước
CWnd* pParentWnd, //Con trỏ cửa sổ cha
UINT nID // Định danh nút chọn
);
9/13/2011
209
Lớp CButton (2) – Hàm thành viên
• Các hàm thành viên (xem MSDN)
• Một số h{m:
– HBITMAP SetBitmap(HBITMAP hBitmap)
– HICON SetIcon(HICON hIcon);
– virtual void DrawItem( LPDRAWITEMSTRUCT
lpDrawItemStruct );
– int GetCheck() const;
– void SetCheck(int nCheck);
209Lập trình Windows
9/13/2011
210
Lớp CButton (3) – Xử lý sự kiện
• Thông điệp trên nút chọn
210Lập trình Windows
ON_BN_CLICKED(IDOK,
&CMyDialogDlg::OnBnClickedOk)
9/13/2011
211
Lớp CButton (4) – Ví dụ
211Lập trình Windows
CButton myButton1, myButton2, myButton3, myButton4; //Khai báo trong .h
//Thường tạo điều khiển trong OnCreate của lớp cha
// Create a push button.
myButton1.Create(_T(“Push button"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
CRect(10,10,100,30), pParentWnd, 1);
// Create a radio button.
myButton2.Create(_T(“Radio button"), WS_CHILD|WS_VISIBLE|BS_RADIOBUTTON,
CRect(10,40,100,70), pParentWnd, 2);
// Create an auto 3-state button.
myButton3.Create(_T(“3-state button"), WS_CHILD|WS_VISIBLE|BS_AUTO3STATE,
CRect(10,70,100,100), pParentWnd, 3);
// Create an auto check box.
myButton4.Create(_T(“Check box button"), WS_CHILD|WS_VISIBLE|
BS_AUTOCHECKBOX, CRect(10,100,100,130), pParentWnd, 4);
9/13/2011
212
2.7.4.3. Lớp CListBox (1)
• Lớp quản lý hộp danh s|ch c|c phần tử
• H{m tạo CListBox()
• Hàm Create()
• ListBox styles: LBS_XXX (LBS_MULTILESEL,
LBS_MULTCOLUMN, ) (Xem MDSN)
212Lập trình Windows
virtual BOOL Create(
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID );
9/13/2011
213
Lớp CListBox (2) – Hàm thành viên
• Chia thành các nhóm:
– General Operations:
• int GetCount( ) trả về số mục chọn
• GetText, GetSel,
– Single-selection Operations:
• int GetCurSel() lấy chỉ số mục được chọn,
• int SetCurSel(int nSelect) Ấn định mục chọn
– Multiple-selection Operations: GetSelCount,
GetSelItems,
– String Operations: AddString, DeleteString,
InsertString, ResetContent,
• Chi tiết: MSDN
213Lập trình Windows
9/13/2011
214
Lớp CListBox (3) – Xử lý sự kiện
• Sự kiện trên listbox v{ h{m
xử lý tương ứng
214Lập trình Windows
ON_LBN_SELCHANGE(IDC_LIST1,
&CControlDemoDlg::OnLbnSelchangeList1)
9/13/2011
215
Lớp CListBox (4) – Ví dụ
215Lập trình Windows
int CControlDemoDlg::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;
//Tạo một listbox
m_listbox- >Create (
WS_CHILD | WS_VISIBLE | WS_BORDER |
LBS_NOTIFY | WS_VSCROLL, CRect( 200, 10, 280, 80 ), this,
IDC_LISTBOX); //ID định nghĩa trong resource.h
m_listbox- >AddString( "Ong A" );
m_listbox- >AddString( "Ba B" );
m_listbox- >AddString( "Co C" );
//Tạo một edit box (dùng để hiện phần tử được chọn từ listbox
m_edit->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER,
CRect(200, 100, 280, 120), this, 1010);
return 0;
}
9/13/2011
216
Lớp CListBox – Ví dụ (tiếp)
216Lập trình Windows
void CControlDemoDlg::OnLbnSelchangeListBox()
{
CString info;
int iSel = m_listbox->GetCurSel();
if (iSel == LB_ERR) // Không có lựa chọn
iSel = 0; // Thì chọn mục đầu tiên
m_listbox->GetText(iSel, info );
m_edit->SetWindowText( info);
}
9/13/2011
217
2.7.4.4. Lớp CComboBox (1)
• Lớp quản lý combo box (hộp nhập v{ phần hỗ trợ nhập với
danh s|ch c|c phần tử cho trước)
• H{m tạo CComboBox()
• Hàm Create()
• dwStyle: C|c dạng Combo Box kh|c nhau:
– CBS_DROPDOWNLIST: Gi| trị nhập chỉ được chọn từ danh s|ch.
– CBS_SIMPLE : Như Drop list m{ danh s|ch hiển thị thường trực
– CBS_DROPDOWN: Như drop list v{ có thể nhập nội dung mới
217Lập trình Windows
BOOL Create (
DWORD dwStyle, // Kiểu comboBox
const RECT& rect,
CWnd* pParentWnd,
UINT nID
);
9/13/2011
218
Lớp CComboBox (2) – Hàm thành viên
• Nhiều h{m tương tự CListBox
• 2 nhóm:
– General Operations:
• int GetCount( ) trả về số mục chọn
• GetCurSel, SetCurSel,
• GetLBText() Lấy text của phần tử
– String Operations: AddString, DeleteString,
InsertString, ResetContent,
• Xem MSDN
218Lập trình Windows
9/13/2011
219
Lớp CComboBox (3) – Xử lý sự kiện
• Sự kiện trên ComboBox v{ h{m xử lý
219Lập trình Windows
ON_CBN_SELCHANGE(IDC_COMBO1,
&CControlDemoDlg::OnCbnSelchangeCombo1)
9/13/2011
220
Lớp CComboBox (4) – Ví dụ
220Lập trình Windows
m_pComboBox->Create(
WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST,
CRect(10,10,200,100), pParentWnd, IDC_COMBO1);
void CControlDemoDlg::OnCbnSelchangeCombo1()
{
CString info;
int iSel = m_Combobox.GetCurSel( );
if (iSel == LB_ERR) // no selection
iSel = 0;
m_pComboBox- >GetLBText( iSel, info );
m_edit->SetWindowText( info );
}
9/13/2011
221
2.7.4.5. Lớp CSpinButtonCtrl (1)
• Lớp quản lý điều khiển cho phép lựa chọn gi|
trị (tăng/giảm) trong một khoảng đ~ c{i đặt.
• Thường đi kèm với một edit box (để hiện gi|
trị muốn chọn)
• Hàm Create()
221Lập trình Windows
virtual BOOL Create(
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID );
9/13/2011
222
CSpinButtonCtrl (2) – Hàm thành viên
• CWnd* SetBuddy (CWnd* pWndBuddy);
//Ấn định đối tượng hộp nhập (edit box) m{ điều
khiển n{y hỗ trợ
• CWnd* GetBuddy( );
• int SetBase(int nBase); //thiết lập bước tăng giảm
• void SetRange ( int nLower, int nUpper);
//Ấn định phạm vi gi| trị biến thiên của nút tăng
giảm.
• void GetRange ( int &nLower, int &nUpper);
• int SetPos( int nPos ); //Đặt gi| trị nút tăng giảm
• int GetPos( int &nPos);
222Lập trình Windows
9/13/2011
223
CSpinButtonCtrl (4) – Ví dụ
223Lập trình Windows
int CControlDemoDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;
m_editAge.Create ( WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER,
CRect( 135, 45, 190, 65 ), this, IDC_EDIT);
static CSpinButtonCtrl m_spinAge;
m_spinAge.Create ( WS_CHILD | WS_VISIBLE |
UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT,
CRect(0,0,1,1), this, IDC_SPIN);
m_spinAge.SetBase(1); //Bước tăng giảm
m_spinAge.SetRange( 15, 80 );
m_spinAge.SetBuddy ( &m_editAge );
return 0;
}
9/13/2011
224
2.7.4.6. Lớp CSliderCtrl (1)
• Lớp quản lý thanh trượt
• Tương tự Spin
• Thuộc tính:
– Tick Marks
– Point: Kiểu con chạy
– Orientation: Horizontal & vertical
• Hàm Create()
224Lập trình Windows
virtual BOOL Create(
DWORD dwStyle, //TBS_HORZ, TBS_VERT,
const RECT& rect,
CWnd* pParentWnd,
UINT nID );
9/13/2011
225
Lớp CSliderCtrl (2) – Hàm thành viên
• void SetRange(int nMin, int nMax, BOOL bRedraw =
FALSE);
• void SetPos(int nPos); int GetPos(), .
• CWnd* SetBuddy (CWnd* pWndBuddy);
• CWnd* GetBuddy( );
• int GetTic(); //Lấy gi| trị bước con chạy
• int SetTic(int nTic); //Thiết lập bước con chạy
• void SetRangeMin(int nMin, BOOL bRedraw =
FALSE); GetRangeMin();
• void SetTicFreq(int nFreq);
• Xem MSDN
225Lập trình Windows
9/13/2011
226
2.7.4.7. Lớp CProgressCtrl (1)
• Lớp quản lý thanh tiến độ xử lý
• H{m tạo CProgressCtrl()
• Hàm Create()
– dwStyle:
• PBS_VERTICAL : Thanh tiến trình nằm đứng
• PBS_SMOOTH : Chỉ độ tiến độ m{u liên tục
226Lập trình Windows
virtual BOOL Create( DWORD dwStyle,
const RECT& rect, CWnd* pParentWnd,
UINT nID );
9/13/2011
227
CProgressCtrl (2) – Hàm thành viên
• void SetRange ( int nLower, int nUpper);
//Ấn định phạm vi gi| trị biến thiên của thanh tiến độ
• void GetRange ( int &nLower, int &nUpper);
• int SetPos( int nPos ); //Đặt gi| trị vị trị tiến độ
• int GetPos( int &nPos);
• int SetStep(int nStep); //Thiết lập bước tăng
• int GetStep();
• int OffsetPos( int nPos ); //Ấn định mức tăng giảm
trên một đơn vị th{nh tiến độ bằng nPos, đồng thời
cập nhật thanh tiến độ theo gi| trị ấn định mới.
• int StepIt(); //Thay đổi chỉ mục tiến độ một bước
227Lập trình Windows
9/13/2011
228
CProgressCtrl (3) – Ví dụ
228Lập trình Windows
static CProgressCtrl myCtrl;
// Create a smooth child progress control.
myCtrl.Create(WS_CHILD|WS_VISIBLE|PBS_SMOOTH,
CRect(10,10,200,30), this, 1012);
// Set the range to be 0 to 100.
myCtrl.SetRange(0, 100);
// Set the position to be half, 50.
myCtrl.SetPos(50);
// Offset the position by one-fourth of the total range.
int nLower, nUpper;
myCtrl.GetRange(nLower, nUpper);
myCtrl.OffsetPos((nUpper-nLower)/4);
// Advance the position to the next step.
myCtrl.StepIt();
9/13/2011
229
2.7.4.8. Lớp CScrollBar
• Lớp quản lý điều khiển thanh cuộn
• Hàm Create()
– dwStyle: SBS_HORZ, SBS_VERT, .
• Các hàm thành viên:
– void SetScrollRange ( int nLower, int nUpper);
– void GetScrollRange ( int &nLower, int &nUpper);
– int SetScrollPos( int nPos );
– int GetScrollPos( int &nPos);
– void ShowScrollBar ( BOOL bShow = TRUE ); //Bật/tắt
thanh cuộn
229Lập trình Windows
virtual BOOL Create( DWORD dwStyle,
const RECT& rect, CWnd* pParentWnd,
UINT nID );
9/13/2011
230
Xử lý sự kiện với c|c điều khiển dạng cuộn
• Sự kiện thường dùng
– CWnd::OnHScroll() nếu điều khiển dạng đứng,
– CWnd::OnVScroll() nếu điều khiển dạng ngang
• Sự kiện n{y được gửi đến lớp cửa sổ cha chứa điều
khiển (kế thừa từ lớp CWnd)
• 2 h{m xử lý sự kiện l{ chung cho
c|c điều khiển có dạng cuộn
(Spin, Progress, slider, scroll),
cần x|c định điều khiển n{o g}y ra
bằng c|ch kiểm tra ID
230Lập trình Windows
9/13/2011
231
2.7.5. Bài tập – Common Controls (1)
• Ex2-7a. Sử dụng một số điều khiển thông dụng
231Lập trình Windows
9/13/2011
232
Thiết lập thuộc tính cho các control
• Ví dụ: Button “Show Message”
– ID: IDC_BT_SHOWMSG
– Caption: Show &Message
232Lập trình Windows
9/13/2011
233
Thiết lập thuộc tính cho các control
• Ví dụ: Combo box
– ID: IDC_CB_PROG
– Data: Notepad;Spider;Solitaire
233Lập trình Windows
9/13/2011
234
B{i tập Common Controls (2)
• Ex2-7b. UserProfile :
– Combo box
– Listbox
– Radio button
– Spin
– Slider
234Lập trình Windows
9/13/2011
235
Chương 3. Một số chủ đề nâng cao
• 3.1. DLL
• 3.2. Thread
• 3.3. Windows Socket
235Lập trình Windows
9/13/2011
236
3.1. Dynamic Link Libraries - DLLs
• 3.1.1. Giới thiệu DLL ?
• 3.1.2. Ph}n loại DLLs
• 3.1.3. C|ch thức gọi DLL trong ứng dụng
• 3.1.4. Viết DLL
• 3.1.5. Ứng dụng sử dụng DLL
• B{i tập
236Lập trình Windows
9/13/2011
237
3.1.1. Giới thiệu DLL
• DLL (Dynamic Link Library): Thư viện liên kết
động.
• L{ một file nhị ph}n chứa một hoặc nhiều h{m thực
thi. Cho phép ứng dụng kh|c sẽ có thể gọi đến.
• Một DLL có thể được nhiều ứng dụng sử dụng đồng
thời.
• C|c h{m trong DLL được chia l{m 2 loại:
– Export (h{m xuất: c|c h{m cho phép ứng dụng bên ngo{i
sử dụng).
– Internal (h{m nội bộ: những h{m chỉ sử dụng trong nội
bộ của DLL)
237Lập trình Windows
9/13/2011
238
Static Library
• Thư viện liên kết
tĩnh (statically
link library) ?
• Ví dụ: h{m ceil()
thư viện to|n
học cmath.h
238Lập trình Windows
9/13/2011
239
How DLL Works ?
• DLL chỉ
được nạp
v{o bộ
nhớ khi
chương
trình thực
thi.
239Lập trình Windows
9/13/2011
240
Ưu điểm sử dụng DLL
• L{m kích thước ứng dụng nhỏ.
• Nhiều ứng dụng có thể dùng chung 1 DLL, tiết kiệm
bộ nhớ. (C|c ứng dụng có bộ dữ liệu riêng, nhưng
có thể chia sẻ m~ lệnh).
• Khi không còn sử dụng, có thể giải phóng DLL khỏi
bộ nhớ
• Khi cần n}ng cấp, chỉ cần thay thế file DLL, c|c file
chương trình kh|c không bị ảnh hưởng.
• Nhược điểm: Lập trình xử lý nhiều thao t|c phức
tạp hơn.
240Lập trình Windows
9/13/2011
241
Nội dung DLL
• M~ lệnh của c|c h{m (functions)
• C|c lớp (Classes)
• Biến to{n cục (global variables)
• Resource (bitmap, font)
• Ví dụ: Solitaire game sử dụng Cards.dll chứa
cards images + functions
• Chỉ những thành phần được export của
DLL mới có thể được truy xuất từ bên
ngoài.
241Lập trình Windows
9/13/2011
242
Hàm DllMain()
• DLL không thực thi như một chương trình
độc lập, nhưng có chứa h{m main đặc biệt
gọi l{ DllMain().
• Được gọi bởi Windows khi nó được nạp v{o
bộ nhớ lần đầu tiên. Để thực hiện khởi tạo
trước khi sử dụng nội dung của DLL.
• Cũng được gọi khi giải phóng khỏi bộ nhớ để
thực hiện những giải phóng cần thiết.
242Lập trình Windows
9/13/2011
243
3.1.2. Ph}n loại DLLs
• Có 3 loại: (trong MFC)
– DLL mở rộng (MFC Extension DLL)
– DLL thông thường với liên kết tĩnh MFC
(Regular DLL with MFC statically linked).
– DLL thông thường với liên kết động MFC
(Regular DLL with MFC dynamically linked)
243Lập trình Windows
9/13/2011
244
MFC Extension DLL
• Cho phép sử dụng c|c lớp (trong DLL) dẫn xuất từ
c|c lớp MFC.
• Cho phép ứng dụng dùng DLL có thể sử dụng c|c
lớp của nó.
• MFC Extension DLL liên kết với c|c DLL của MFC
theo dạng liên kết động.
• C|c DLLs dạng n{y chỉ sử dụng cho ứng dụng MFC
có tính năng “Use MFC in a Shared DLL”
• Không dùng được bởi c|c ứng dụng sử dụng liên kết
tĩnh đến thư viện MFC (Statically linked to MFC)
244Lập trình Windows
9/13/2011
245
Regular DLL – Statically linked to MFC
• L{ c|c DLL sử dụng c|c lớp của MFC dưới dạng liên
kết tĩnh. (c|c đoạn m~ trong DLL của MFC được
chèn v{o Regular DLL mỗi khi h{m tương ứng được
sử dụng đến). L{m cho Regular DLL kiểu n{y có
kích thước lớn.
• Có thể được sử dụng bởi c|c ứng dụng MFC hoặc
Win32 Application (không cần môi trường MFC)
• Chỉ cho export c|c h{m, không cho export c|c lớp
có trong DLL.
245Lập trình Windows
9/13/2011
246
Regular DLL – Dynamically linked to MFC
• L{ DLL sử dụng c|c lớp MFC dạng liên kết
động (không thêm m~ lệnh của lớp MFC v{o
DLL n{y, chỉ gọi đến khi được dùng).
• Kích thước giảm so với kiểu Regular DLL liên
kết tĩnh MFC.
• Có thể được sử dụng bởi ứng dụng MFC hoặc
bất kỳ ứng dụng Win32 (nhưng cần có DLL
của MFC tương ứng đi kèm)
246Lập trình Windows
9/13/2011
247
3.1.3. C|ch gọi DLL trong ứng dụng
• 2 kiểu:
– Gọi lúc ứng dụng được nạp (load time dynamic
linking hay early binding).
– Gọi lúc thực thi (runtime dynamic linking hay
late binding)
247Lập trình Windows
9/13/2011
248
Gọi lúc ứng dụng được nạp (load time)
• DLL được nạp v{o bộ nhớ khi ứng dụng sử
dụng nó được nạp v{o bộ nhớ để thực thi.
• DLL được nạp ngay từ đầu bất kể ứng dụng
yêu cầu nạp nó có sử dụng đến c|c h{m của
nó trong qu| trình thực thi hay không.
• Liên kết đến c|c h{m DLL muốn dùng được
thiết lập ngay từ đầu.
• Có thể bất tiện: Tốn bộ nhớ nạp DLL, ứng
dụng có thể không hoạt động nếu DLL yêu
cầu nạp không tồn tại.
248Lập trình Windows
9/13/2011
249
Gọi lúc thực thi (run time)
• Lập trình viên quyết định khi n{o cần nạp DLL lên
bộ nhớ. (Được nạp khi có một h{m của DLL được
ứng dụng yêu cầu sử dụng).
• Khó khăn: Tốn công sức lập trình cho việc nạp DLL,
gọi h{m DLL.
– Cần dùng h{m API LoadLibrary() để nạp DLL khi nó
được yêu cầu.
– Hàm GetProcAddress() để lấy địa chỉ h{m (con trỏ h{m)
của h{m DLL cần dùng.
– Hàm FreeLibrary() để deattach DLL khi ứng dụng không
còn dùng đến. (DLL sẽ được giải phóng khi không còn
ứng dụng n{o dùng đến)
249Lập trình Windows
9/13/2011
250
250Lập trình Windows
Minh họa gọi DLL lúc
thực thi ứng dụng
9/13/2011
251
3.1.4. Viết DLL
• Minh họa x}y dựng một Regular DLL (dạng
liên kết động với MFC)
• DLL n{y chứa 2 h{m tính to|n (cộng v{ nh}n)
cho phép ứng dụng kh|c gọi đến.
• Tạo Project MFC/MFC DLL
• Chọn kiểu Regular DLL using shared MFC
DLL
251Lập trình Windows
9/13/2011
252
Minh họa viết DLLRegular
252Lập trình Windows
9/13/2011
253
Khai b|o h{m xuất
253Lập trình Windows
9/13/2011
254
• Khai b|o h{m xuất đặt trong tệp tin .cpp hoặc
.h
• H{m nội bộ của DLL khai b|o v{ triển khai
như h{m của ứng dụng thông thường
254Lập trình Windows
9/13/2011
255
Thực thi h{m xuất
• Đặt macro AFX_MANGE_STATE đầu tiên
trong thân hàm.
255Lập trình Windows
//TODO: If this DLL is dynamically linked against the MFC DLLs,
// any functions exported from this DLL which call into
// MFC must have the AFX_MANAGE_STATE macro added at the
// very beginning of the function.
//
// For example:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // normal function body here
// }
9/13/2011
256
Thực thi h{m xuất (minh họa)
• Phần thực thi h{m cộng:
• Phần thực thi h{m nh}n:
256Lập trình Windows
9/13/2011
257
Biên dịch DLL
• Như biên dịch ứng dụng thông thường
• Tập tin kết quả: .dll v{ .lib
• C|c ứng dụng sử dụng dll n{y cần dùng đến 2
tập tin trên.
257Lập trình Windows
9/13/2011
258
3.1.5. Minh họa ứng dụng sử dụng DLL
• Gọi DLLRegular đ~ viết lúc nạp ứng dụng (load
time)
• Tạo ứng dụng đơn giản (kiểu dialog base)
• Chứa tập tin .dll v{ .lib cùng thư mục project
• Add tập tin .lib v{o Project (Project/Add Existing
Items)
258Lập trình Windows
9/13/2011
259
Khai b|o c|c h{m import trong ứng dụng
• Muốn sử dụng h{m xuất (export) n{o từ DLL,
ứng dụng sẽ khai b|o import cho h{m đó.
• Dạng khai b|o tổng qu|t
259Lập trình Windows
9/13/2011
260
Viết m~ thực thi cho c|c chức năng
• Viết m~ xử lý nút cộng, nh}n gọi h{m cong,
nhan tương ứng của DLL
• Ví dụ: H{m xử lý sự kiện click chuột nút cộng
260Lập trình Windows
9/13/2011
261
Minh họa ứng dụng gọi DLL kiểu runtime
• C|ch thức nạp h{m từ DLL:
– Nạp DLL bằng h{m LoadLibrary. Kiểm tra xem
DLL có tồn tại không bằng c|ch xem kết quả trả
về có kh|c NULL hay không
– Nạp h{m cần thiết bằng h{m GetProcAddress.
Kiểm tra việc gọi h{m th{nh công hay không.
– Giải phóng DLL khỏi bộ nhớ bằng h{m
FreeLibrary.
261Lập trình Windows
9/13/2011
262
Ứng dụng gọi DLL kiểu Run time
• Khai b|o con trỏ h{m cho h{m muốn import
v{o ứng dụng. (Phụ thuộc v{o h{m export
trong DLL)
• Với ví dụ DLLRegular, h{m xuất có dạng:
• Định nghĩa con trỏ h{m cho 2 h{m n{y:
262Lập trình Windows
9/13/2011
263
C|ch thức nạp h{m từ DLL
263Lập trình Windows
9/13/2011
264
Ví dụ: Gọi h{m nh}n
264Lập trình Windows
9/13/2011
265
Thử nghiệm cho c|ch gọi kiểu run time
• Không chép file .dll v{o cùng thư mục ứng
dụng sử dụng dll. Chạy ứng dụng được không
? Có thực thi được c|c chức năng (cộng,
nh}n) của ứng dụng không ?
• Không tắt ứng dụng, chép file .dll v{o cùng
thư mục ứng dụng. Thực thi được c|c chức
năng của ứng dụng không ?
265Lập trình Windows
9/13/2011
266
Ex-3.? DLL
• Viết một Extension DLL cho ứng dụng
Sketcher
266Lập trình Windows
9/13/2011
267
3.2. Thread (Tiểu trình/Luồng)
• 3.2.1. Một số kh|i niệm
• 3.2.2. Lập trình đa luồng
• 3.2.3. Tạo Worker Thread
• 3.2.4. Tạo UI Thread
• 3.2.5. Kết thúc một Thread
• 3.2.6. Đồng bộ c|c Thread
• 3.2.7. Ví dụ minh họa
267Lập trình Windows
9/13/2011
268
3.2.1. Một số kh|i niệm (1)
• Trên Windows, mỗi ứng dụng đang chạy l{ một tiến
trình (Process)
• Một tiến trình có thể chứa một hoặc nhiều tiểu
trình/hay luồng (thread) thực thi. (path of execution)
268Lập trình Windows
• Main Thread/
Primary Thread: là
thread chính/mặc định
của một ứng dụng.
• Secondary Thread: các
thread kh|c (nếu
chương trình được lập
trình tạo thêm thread)
9/13/2011
269
Một số kh|i niệm (2)
• Multithreading: Nhiều thread cùng chạy đồng thời
(Được Windows lập lịch - schedule)
• Hệ điều h{nh ph}n chia thời gian CPU cho c|c
thread – cơ chế đa nhiệm (multitasking)
• Tại sao cần đa luồng ?
– Ứng dụng muốn thực hiện nhiều nhiệm vụ đồng thời.
– Thường c|c nhiệm vụ xử lý được chạy “hậu cảnh”
(background) trong khi c|c xử lý tương t|c người dùng
chạy “tiền cảnh” (foreground)
– Ví dụ: ứng dụng MS Word với thread check spelling
grammar.
269Lập trình Windows
9/13/2011
270
3.2.2. Lập trình đa luồng
• Lập trình đa luồng (multithreading):
– Multithreading in pure C
– Multithreading in Win32 API
– Multithreading in MFC
• Lớp CWinThread: lớp cơ sở đóng gói c|c hoạt động
thực thi của thread.
• MFC ph}n biệt 2 loại thread:
– Worker Thread (Tiểu trình xử lý nội): hỗ trợ thực hiện
c|c xử lý bên trong, “hậu cảnh” (background).
– User Interface Thread (Tiểu trình giao diện): trực tiếp
tiếp nhận yêu cầu người dùng (cơ chế Windows
Messages)
270Lập trình Windows
9/13/2011
271
Lớp CWinThread
• Data members
– m_hThread: The current thread handle
– m_nThreadID: The current thread ID
– m_bAutoDelete:
(TRUE/FALSE) thread được thiết lập tự động giải phóng hoặc không.
• Data Functions:
– CreateThread: Bắt đầu thực thi thread
– SuspendThread: Tạm dừng/ngưng một thread (tăng biến đếm số
lần suspend)
– ResumeThread: Tiếp tục một thread bị tạm dừng (giảm biến đếm số
lần suspend).
– SetThreadPriority: Thiết lập mức độ ưu tiến của thread (tương đối
so với mức độ ưu tiên của process) ( LOW, BELOW LOW or HIGH)
– GetThreadPriority: Lấy mức độ ưu tiên của thread.
271Lập trình Windows
CObject
CCmdTarget
CWinThread
CWinApp
9/13/2011
272
3.2.3. Tạo Worker Thread
• H{m to{n cục AfxBeginThread, bắt đầu một thread
trong MFC
• Có 2 dạng cho 2 kiểu thread.
• Cú ph|p dạng tạo Worker Thread:
– 2 tham số đầu: quan trọng
– 4 tham số sau: tùy chọn (có thể sử dụng hoặc không)
272Lập trình Windows
CWinThread* AfxBeginThread( AFX_THREADPROC ThreadProc,
LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0, DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
9/13/2011
273
Tạo Worker Thread (2)
273Lập trình Windows
• Ý nghĩa c|c tham số h{m AfxBeginThread
Các tham số Mô tả
ThreadProc
controlling function, cannot be NULL. This function must be declared
as follows: UINT MyControllingFunction( LPVOID pParam );
pParam
Parameter to be passed to the controlling function as shown in the
parameter to the function declaration in pfnThreadProc.
nPriority Thread priority.
nStackSize
Specifies the size in bytes of the stack for the new thread. If 0, the
stack size defaults to the same size stack as the creating thread.
dwCreateFlags
additional flag and can be any of these two CREATE_SUSPENDED or
0. CREATE_SUSPENDED starts the thread with a suspend count of
one. The thread will not execute until ResumeThread is called. 0
Start the thread immediately after creation.
lpSecurityAttrs
Points to a SECURITY_ATTRIBUTES structure. See
SECURITY_ATTRIBUTES for more details.
9/13/2011
274
Thread Function (1)
• H{m thực thi của một thread (Thread
Function/ThreadProc)
• L{ h{m callback (Được gọi bởi hệ điều h{nh), cần
khai b|o static hoặc to{n cục (bên ngo{i c|c lớp).
• Có dạng:
• pParam l{ con trỏ đến 1 cấu trúc dữ liệu của thread
do người lập trình định nghĩa. Được truyền cho
h{m thông qua tham số thứ 2 của h{m
AfxBeginThread
274Lập trình Windows
UINT ThreadFunc (LPVOID pParam)
9/13/2011
275
Thread Function (2)
• Ví dụ:
275Lập trình Windows
CwinThread *pThread =
AfxBeginThread( ThreadFunction, &data);
UINT ThreadFunction(LPVOID param) {
UINT nIterations = (UINT) pParam;
for (int i=0; i<nIterations; i++);
//do something
return 0;
}
9/13/2011
276
Thread Priorities (1)
• C|c tiến trình (process) được hệ điều h{nh lập lịch
thực thi với cấp độ ưu tiên kh|c nhau (chiếm thời
gian CPU kh|c nhau). Bao gồm:
REALTIME_PRIORITY_CLASS
HIGH_PRIORITY_CLASS
NORMAL_PRIORITY_CLASS
IDLE_PRIORITY_CLASS
• Cấp độ ưu tiên của tiến trình được thiết lập tương
đối với c|c độ ưu tiên của process nó thuộc về.
• Có thể thiết lập khi gọi h{m AfxBeginThread( ),
hoặc dùng h{m: CWinThread::SetThreadPriority
276Lập trình Windows
9/13/2011
277
Thread Priorities (2)
277Lập trình Windows
THREAD_PRIORITY_TIME_CRITICAL
Normal for HIGH, NORMAL, or
IDLE. Double for REALTIME.
THREAD_PRIORITY_HIGHEST = Process Priority + 2.
THREAD_PRIORITY_ABOVE_NORMAL = Process Priority +1.
THREAD_PRIORITY_NORMAL = Process Priority.
THREAD_PRIORITY_BELOW_NORMAL = Process Priority -1.
THREAD_PRIORITY_LOWEST = Process Priority -2.
THREAD_PRIORITY_IDLE
Normal for REALTIME, 1 for
HIGH, NORMAL,
9/13/2011
278
Suspending and Resuming Threads
• Mỗi thread có thể chuyển đổi qua c|c nhiều trạng th|i hoạt
động như sơ đồ.
• Tạm ngừng: H{m SuspendThread
• Khôi phục: H{m ResumeThread
• Trạng th|i “ngủ”: H{m Sleep
278Lập trình Windows
CWinThread* pThread =
AfxBeginThread (ThreadFunc,
&threadInfo,
THREAD_PRIORITY_NORMAL, 0,
CREATE_SUSPENDED);
pThread->ResumeThread ();
// Start the thread
9/13/2011
279
3.2.4. Tạo User Interface Thread (1)
• UI Thread có giao diện GUI với vòng lặp thông điệp
(message loop).
• C|c bước chính tạo UI Thread:
– Tạo lớp dẫn xuất từ CWinThread v{ override c|c h{m:
279Lập trình Windows
Function name Purpose
InitInstance Perform thread instance initialization. Must be overridden.
Run
Controlling function for the thread. Contains the message pump.
Rarely overridden.
OnIdle Perform thread-specific idle-time processing. Not usually overridden.
PreTranslateMessage
Filter messages before they are dispatched to TranslateMessage and
DispatchMessage. Not usually overridden.
ProcessWndProcExcept
ion
Intercept unhandled exceptions thrown by the thread's message and
command handlers. Not usually overridden.
ExitInstance Perform cleanup when thread terminates. Usually overridden.
9/13/2011
280
Tạo User Interface Thread (2)
– Gọi h{m AfxBeginThread cho UI Thread
– Tham số đầu tiên l{ con trỏ lớp Thread dẫn xuất
đ~ tạo.
– C|c tham số còn lại l{ tùy chọn (có thể dùng hoặc
không)
280Lập trình Windows
CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass,
int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
9/13/2011
281
3.2.5. Kết thúc một Thread
• Với Worker Thread: 2 trường hợp kết thúc:
– Khi h{m thực thi của thread (ThreadFunction)
kết thúc (trả về return)
– Khi có h{m ở bất kỳ đầu gọi h{m kết thúc thread
AfxEndThread() (h{m to{n cục)
281Lập trình Windows
CwinThread *pThread = AfxBeginThread(ThreadFunction, &data);
UINT ThreadFunction(LPVOID param) {
DWORD result =0 ;
// do somthing
AfxEndThread(exitCode);
return result;
}
9/13/2011
282
Kết thúc một Thread (2)
• Với UI Thread:
– Kết thúc khi có thông điệp WM_QUIT gửi đến
h{ng đợi thông điệp của nó.
– Hoặc khi bản th}n thread gọi h{m AfxEndThread
• Khi kết thúc trả về m~ (exit code 32 bit), có thể
kiểm tra m~ n{y:
282Lập trình Windows
DWORD dwExitCode;
::GetExitCodeThread (pThread->m_hThread, &dwExitCode);
if (dwExitCode == STILL_ACTIVE) {
// The thread is still running. }
else { // The thread has terminated. Delete the CWinThread object.
delete pThread;
}
9/13/2011
283
3.2.6. Đồng bộ c|c thread
• Thread Synchronization
• Vấn đề ?
• Giải ph|p ?
• Windows cung cấp 4 cơ chế đồng bộ c|c thread:
– Critical sections
– Mutexes
– Events
– Semaphores
• T{i liệu:
– Chapter 17, Programming Windows with MFC
– MSDN
283Lập trình Windows
9/13/2011
284
3.2.7. Ví dụ Thread
• C|c ví dụ đơn giản minh họa sử dụng thread dùng
Win32 API, MFC
• Minh họa Worker Thread
– Tiểu trình xử lý nội (Worker Thread) c{i đặt một h{m có
nhiệm vụ thực hiện chạy chữ trong dòng thông b|o cho
đến khi có tín hiệu ngừng.
– Tiểu trình chính của ứng dụng thực hiện giao tiếp người
dùng.
Nút Start/Stop, Close
284Lập trình Windows
9/13/2011
285
Ex3-?. Prime Sieve
• X}y dựng ứng dụng s{ng số nguyên tố (Prime
Sieve) với tiểu trình xử lý nội (Worker
Thread) cho việc xử lý giải thuật s{ng số
nguyên tố.
285Lập trình Windows
9/13/2011
286
3.3 Lập trình Windows Socket
• 3.3.1. Một số kh|i niệm
• 3.3.2. Lập trình Socket với WINSOCK
• 3.3.3. Lập trình Socket với MFC
• 3.3.4. Ví dụ minh họa
286Lập trình Windows
9/13/2011
287
3.3.1. Một số kh|i niệm (1)
• Winsock (Windows Socket):
– Xuất xứ từ BSD (Berkeley Software Distribution –
UNIX)
– Giao diện c|c dịch vụ x}y dựng trên nền giao
thức truyền thông TCP(UDP)/IP
• Port:
– Số hiệu cổng dịch vụ, ph}n biệt giữa c|c tiến
trình trên cùng một host đồng thời sử dụng giao
thức TCP/IP.
287Lập trình Windows
9/13/2011
288
Một số kh|i niệm (2)
• Socket ? (= IP + Port)
– Điểm truyền thông đầu cuối cho phép ứng dụng
gửi v{ nhận c|c gói tin qua đường truyền mạng.
– Cung cấp giao diện để một chương trình kết nối,
trao đổi dữ liệu với một chương trình trên một
m|y tính kh|c trong mạng
288Lập trình Windows
9/13/2011
289
Một số kh|i niệm (3)
• C|c loại Socket:
– Datagram socket – sử dụng
UDP
• Ít tin cậy
• Không gửi lại
• Không kết nối (Connectionless)
– Stream socket – using TCP
• Tin cậy
• Có gửi lại
• Hướng kết nối (Connection-
oriented)
– Raw and others
289Lập trình Windows
9/13/2011
290
Lập trình Socket trên Windows
• Ứng dụng Win 32: Sử dụng thư viện Winsock
• Ứng dụng MFC: sử dụng lớp CAsyncSocket
(đóng gói c|c h{m Winsock API)
290Lập trình Windows
9/13/2011
291
3.3.2. Lập trình Socket với Winsock
• Khai b|o thư viện winsock2.h v{ file .lib (ws2_2.lib)
• Khởi tạo Winsock
291Lập trình Windows
#include
#pragma comment (lib,"ws2_32.lib")
int WSAStartup(WORD wVersionRequested, LPWSADATA
lpWSAData);
9/13/2011
292
Ví dụ khởi tạo Winsock
292Lập trình Windows
#include "stdafx.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA SData;
int iResult = WSAStartup(0x0202,&SData);
if (iResult!=0){
cout << "KHONG THE KHOI DONG WINSOCK";
return 1;
}
cout << "KHOI TAO SOCKET THANH CONG: \n";
cout << "Phien ban: "<< SData.wVersion << "\n";
cout << "Phien ban co the ho tro: "<< SData.wHighVersion << "\n";
cout << "Ghi chu: " << SData.szDescription << "\n";
cout << "Thong tin cau hinh: " << SData.szSystemStatus << "\n";
WSACleanup();
return 0;
}
9/13/2011
293
Giao tiếp Client – Server với TCP
293
9/13/2011
294
9/13/2011
295
Giao tiếp Client – Server với UDP
socket()
bind()
recvfrom()
sendto()
UDP Server
socket()
UDP Client
sendto()
recvfrom()
close()
blocks until datagram
received from a client
data request
data reply
9/13/2011
296
9/13/2011
297
Các hàm Winsock (1)
• SOCKET create a new socket
• BIND attach a local address to a socket
• LISTEN announce a willingness to accept
connections
• ACCEPT block the caller process until a
connection attempt arrives
• CONNECT actively attempt to establish a connection
• SEND send some data over the connection
• RECEIVE receive some data from the connection
• CLOSE release the connection (the port)
297Lập trình Windows
9/13/2011
298
Hàm socket( )
• Tạo Socket bằng h{m:
• Ví dụ:
298Lập trình Windows
SOCKET socket (
int af, //giao thức kết nối (IF_NET cho TCP/IP)
int type, //giao thức vận chuyển (SOCK_DIAGRAM,
SOCK_STREAM, SOCK_RAW)
int protocol //chỉ định rõ lại giao thức
);
SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
9/13/2011
299
Hàm bind( )
int bind(
SOCKET s,
const struct sockaddr FAR* name,
int namelen
);
Tác dụng dụng của BIND là sẽ giúp cho SOCKET của
SERVER biết rằng nó sẽ chờ đợi kết nối và nhận dữ
liệu trên IP nào và PORT bao nhiêu?
Hàm Bind gồm có 3 thông số:
- SOCKET s: Socket được thiết lập
- sockaddr name: Cấu trúc ADDR bao gồm địa chỉ IP
và PORT
- int namelen: Kích thước của cấu trúc sockaddr
299Lập trình Windows
9/13/2011
300
Hàm listen( )
• int listen(
SOCKET s,
int backlog
);
•
Kể từ khi gọi hàm này thì SERVER sẽ bắt đầu lắng
nghe kết nối của mình.
Hàm LISTEN gồm có 2 thông số:
- SOCKET s: Socket đ~ được thiết lập IP và PORT.
- int backlog: Số kết nối cho phép chờ trong hàng đợi
khi Server chưa chấp nhận kết nối. (vì đôi lúc có thể
có tới 2 hay 3 client kết nối tới cùng 1 lúc). Giá trị tốt
nhất là khoảng từ 5 – 10.
300Lập trình Windows
9/13/2011
301
Connect
• int connect(
SOCKET s,
struct sockaddr *serv_addr,
int addrlen );
•
Hàm được gọi từ CLIENT nếu nó muốn kết nối
tới SERVER
- SOCKET s: Socket đ~ được khởi tạo.
- sockaddr *serv_addr: IP và PORT của Server.
- int addrlen: Sizeof của cấu trúc sockaddr.
301Lập trình Windows
9/13/2011
302
Accept
• Chấp nhận một kết nối đến
• SOCKET accept(
SOCKET s,
struct sockaddr FAR* addr,
int FAR* addrlen
);
• Tham số:
- SOCKET s: Socket lắng nghe của SERVER.
- sockaddr addr: Là cấu trúc sockaddr lưu địa chỉ IP và PORT của CLIENT
kết nối tới SERVER.
- int addrlen: Kích thước cấu trúc địa chỉ IP này.
• Trả về: 1 SOCKET mới
Socket mới được tạo này đại diện cho 1 Connection (kết nối) mới giữa
Server và Client. Sau khi đ~ truyền dữ liệu thì ta phải đóng SOCKET này
lại bằng hàm close như closesocket(connect);
302Lập trình Windows
9/13/2011
303
REVC/SEND
• Nhận dữ liệu trên giao thức TCP
• int recv(
SOCKET s,
char FAR* buf,
int len,
int flags
);
• Gửi dữ liệu giao thức TCP
• int send(
SOCKET s,
const char FAR * buf,
int len,
int flags
);
- SOCKET s: Là SOCKET được tạo ra khi
Server chấp nhận kết nối từ CLIENT
- char FAR* buf: Là dữ liệu (dạng BYTE –
char) nhận hay gửi.
- int len: Kích thước của dữ liệu.
- int flags: Một số cờ hiệu đi kèm (thông
thường là 0).
303Lập trình Windows
9/13/2011
304
REVCFROM/SENDTO
• Được sử dụng trên giao thức UDP
• int recvfrom(
SOCKET s,
char FAR* buf,
int len,
int flags,
struct sockaddr *from,
int *fromlen);
• Các thông số:
- SOCKET s: Là SOCKET được tạo ra ban đầu.
- char FAR* buf: Là dữ liệu (dạng BYTE – char) nhận
- int len: Kích thước của dữ liệu nhận.
- int flags: Một số cờ hiệu đi kèm (thông thường là 0).
- sockaddr *from: IP và PORT từ bên gửi.
- int *fromlen: Sizeof cấu trúc addr.
304Lập trình Windows
9/13/2011
305
REVCFROM/SENDTO
• int sendto(
SOCKET s,
const char FAR *buf,
int len,
int flags,
const struct sockaddr* to,
int tolen
);
• - SOCKET s: Là SOCKET được tạo ra ban đầu.
- char FAR* buf: Là dữ liệu (dạng BYTE – char) gửi
- int len: Kích thước của dữ liệu gửi.
- int flags: Một số cờ hiệu đi kèm (thông thường là 0).
- sockaddr *to: IP và PORT tới bên nhận.
- int tolen: Sizeof cấu trúc addr.
305Lập trình Windows
9/13/2011
306
Close/Shutdown
• int shutdown(
SOCKET s,
int how
);
• int closesocket (SOCKET s);
Hủy SOCKET sau một kết nối hoặc kết thúc chương
trình.
Tham số how của shutdown:
- SD_RECEIVE: Đóng SOCKET, không cho phép NHẬN
nhưng cho phép GỬI.
- SD_SEND: Đóng SOCKET, không cho phép GỬI
nhưng cho phép NHẬN.
- SD_BOTH: Không cho GỬI và NHẬN (giống gọi hàm
closesocket).
306Lập trình Windows
9/13/2011
307
3.3.3. Lập trình Socket với MFC
• Thư viện sử dụng AfxSock.h
• Khởi động Winsock:
– BOOL AfxSocketInit ( WSADATA* lpwsaData =
NULL );
– Thực hiện trong InitInstance( )
– Đảm nhận thực hiện WSAStartup khi bắt đầu ứng
dụng v{ WSACleanup khi ứng dụng kết thúc
307Lập trình Windows
9/13/2011
308
Lớp CAsyncSocket
• Lớp quản lý Socket
• Đóng gói c|c dịch vụ Winsock API
• H{m tạo: CAsyncSocket()
• Hàm Create()
308Lập trình Windows
BOOL Create (
UINT nSocketPort = 0,
int nSocketType = SOCK_STREAM,
long lEvent = FD_READ | FD_WRITE | FD_OOB |
FD_ACCEPT | FD_CONNECT | FD_CLOSE,
LPCTSTR lpszSocketAddress = NULL
);
9/13/2011
309
Lớp CAsyncSocket - Các hàm thành viên
• Bind( )
• SetSockOpt( )
• Listen( )
• Connect( )
• Accept( )
• Send( )/SendTo( )
Các file đính kèm theo tài liệu này:
- tailieu.pdf