Lập trình Windows
TRƯỜNG ĐẠI HỌC B\CH KHOA H[ NỘI
VIỆN CÔNG NGHỆ THÔNG TIN V[ TRUYỀN THÔNG
• 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
LẬP TRÌNH WINDOWS
• Học phần tiên quyết:
– Ngôn ngữ lập trình C, C++
Phạm Ngọc Hưng
Bộ môn Kỹ thuật Máy tính
[email protected]
Lập trình Windows
Nội dung
Tài liệu tham khảo
• 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)
2
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. http://www.functionx.com/visualc/
• Chương 4. X}y dựng ứng dụng Windows Form (3LT
+ 2BT)
• Bài tập lớn
Lập trình Windows
3
Lập trình Windows
4
1
Chương 1. Tổng quan lập trình Windows
1.1. Cơ bản về 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)
• 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….
Lập trình Windows
5
Các thành phần của một cửa sổ
Lập trình Windows
Lập trình Windows
6
Cơ chế lập trình Event-driven
7
Lập trình Windows
8
2
Thông điệp (Windows Messages)
Windows Message (cont.)
• 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ổ, …
• 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( )
Lập trình Windows
9
Windows Message (cont.)
Lập trình Windows
10
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.
Lập trình Windows
11
Lập trình Windows
12
3
Windows Data Types (1)
Windows Data Types (2)
• Đị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
Lập trình Windows
13
Kiểu
HANDLE
HWND
BYTE
WORD
DWORD
UINT
LONG
BOOL
LPSTR
LPCSTR
WPARAM
LPARAM
BSTR
LPVOID
Ý nghĩa
Số nguyên 32-bit, định danh.
Số nguyên 32-bit, định danh.
Giá trị 8-bit không dấu.
Số nguyên 16-bit không dấu.
Số nguyên 32-bit không dấu.
Số nguyên không dấu 32-bit.
long 32-bit.
Kiểu logic True/False
Con trỏ chuỗi. (char *)
Hằng con trỏ chuỗi.
32-bit.
32-bit.
Giá trị 32-bit trỏ đến kí tự.
Con trỏ 32-bit đến một kiểu không xác định.
LPTSTR
Giống như
DBCS.
LPSTR nhưng có thể chuyển sang dạng Unicode và
LPCTSTR
Giống như
DBCS.
LPCTSTR nhưng có thể chuyển sang dạng Unicode và
Lập trình Windows
14
Microsoft style (1)
Microsoft Style (2)
• 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(…)
• 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.
Lập trình Windows
Lập trình Windows
15
16
4
Microsoft Style (3) – Tiền tố tên biến
Tiền tố
Kiểu dữ liệu
c
by
n
i
x,y
b
w
l
dw
s
sz
h
p
Lpsz
char, WCHAR, TCHAR
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.
BYTE
short
int
biến lưu tọa độ x, y
BOOL
WORD
long
DWORD
string
chuỗi kết thúc bởi kí tự 0
handle
pointer
con trỏ dài chuỗi ký tự kết thúc kí tự 0
Lập trình Windows
Lập trình Windows
17
1.2. Cấu trúc của chương trình Windows
18
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ó.
Lập trình Windows
19
Lập trình Windows
20
5
1.2.1. Hàm WinMain()
Hàm WinMain (cont.)
• Hàm chính của ứng dụng trên Windows
• Program entry point
• Tìm hiểu hàm WinMain mẫu:
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
• 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.
Lập trình Windows
21
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;
}
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
Đị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;
23
Lập trình Windows
24
Lập trình Windows
6
Định nghĩa lớp cửa sổ WNDCLASS
Đăng ký lớp cửa sổ
• Ý nghĩa thuộc tính lớp cửa sổ WNDCLASS:
• Sau khi định nghĩa lớp cửa sổ phải đăng ký
bằng hàm RegisterClass:
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
hIcon
hCursor
Con trỏ đến thủ tục xử lý cửa sổ
Số byte được cấp phát thêm sau
cấu trúc window-class
Số byte được cấp phát thêm sau
một instance của window
Định danh chứa thủ tục cửa sổ
của lớp window
Định danh của biểu tượng
Định danh của con trỏ chuột
hbrBackground
Định danh của chổi tô nền
lpszMenuName
Tên thực đơn
lpszClassName
Tên lớp
cbClsExtra
cbWndExtra
hInstance
ATOM RegisterClass(CONST WNDCLASS * lpWndClass);
Mặc định
Mặc định
Dùng hàm LoadIcon
Dùng hàm LoadCursor
Dùng hàm
GetStockObject
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.
Lập trình Windows
25
Tạo cửa sổ
Hiển thị 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.
• 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ị
);
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
);
Lập trình Windows
26
• 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.
27
Lập trình Windows
28
7
1.2.2. Hàm xử lý thông điệp WinProc
Message Loop
• 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:
• 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ã:
LRESULT CALLBACK WinProc (HWND, UINT, WPARAM, LPARAM);
• 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.
Lập trình Windows
29
MSG msg;
// Windows message structure
while (GetMessage(&msg, NULL, 0,0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
Lập trình Windows
30
Message Loop
Message Loop
• Trong đó msg là một biến cấu trúc kiểu MSG được
định nghĩa trong winuser.h
• 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.
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
Lập trình Windows
32
8
Multitasking
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);
Lập trình Windows
33
Lập trình Windows
34
Lập trình Windows
36
Tóm tắt
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);
}
• 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 định DefWindowProc
35
9
1.2.3. Chương trình Windows đơn giản
Win32 Application in Visual C++ Developer Studio
- 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()
Lập trình Windows
Lập trình Windows
37
HelloWorld (1)
38
HelloWorld (2)
/* 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);
39
return 0;
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
Lập trình Windows
40
Lập trình Windows
10
HelloWorld (3)
HelloWorld (run)
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);
}
Lập trình Windows
41
Lập trình Windows
42
Ý nghĩa các hàm trong HelloWorld
1.3. Microsoft Foundation Classes (MFC)
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.
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ổ.
Đăng ký một lớp cửa sổ cho cửa sổ ứng dụng trong
chương trình.
Hiển thị một thông điệp.
Tạo một cửa sổ dựa trên một lớp cửa sổ.
Hiển thị cửa sổ lên màn hình.
Yêu cầu cửa sổ vẽ lại chính bản thân nó.
Nhận một thông điệp từ hàng đợi thông điệp.
Dịch thông điệp bàn phím.
Gởi thông điệp đến hàm xứ lý cửa sổ.
Khởi tạo chức năng vẽ của cửa sổ.
Lấy hình chữ nhật lưu vùng làm việc.
Hiển thị một chuỗi văn bản.
Kết thúc việc vẽ cửa sổ.
Đưa thông điệp thoát vào hàng đợi thông điệp.
Thực hiện việc xử lý mặc định các thông điệp.
• 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
GetStockObject
RegisterClass
MessageBox
CreateWindow
ShowWindow
UpdateWindow
GetMesssage
TranslateMessage
DispatchMessage
BeginPaint
GetClientRect
DrawText
EndPaint
PostQuitMessage
DefWindowProc
43
Lập trình Windows
44
11
MFC và Win32 API
MFC và Win32 API – Ví dụ
• Win32 API: tập hợp các hàm, cấu trúc, thông
điệp, macros và interfaces
• 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ụ:
– 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
Lập trình Windows
45
– Hàm: BOOL ShowWindow(HWND hWnd, int nCmdShow);
– Được đóng gói trong MFC:
BOOL CWnd::ShowWindow(int nCmdShow);
Lập trình Windows
46
Lập trình Windows
48
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
Lập trình Windows
47
12
Cấu trúc ứng dụng MFC
1.4. Lập trình Windows với VC++ 2008
• Ứng dụng MFC cung cấp:
• 3 c|ch tạo ứng dụng Windows với VC++:
– 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)
Lập trình Windows
– Ứ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)
Lập trình Windows
49
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
VC++ 2008 Developer Studio Environment
-Solution
Explorer
-Class View
-Resource View
ToolBox
Editor Area
Properties
Lập trình Windows
50
51
Output
Lập trình Windows
52
13
The Solution
Output Pane & Editor Area
• 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.
• Output Pane:
Lập trình Windows
–
–
–
–
–
• Editor Area:
– Soạn thảo m~ lệnh
– Thiết kế giao diện (Design mode)
– Icon Editor
53
Menu Bar + Rearranging IDE
•
•
•
•
•
•
•
•
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)
Lập trình Windows
54
C|c th{nh phần ứng dụng ph|t triển với VC++
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, ….
Lập trình Windows
55
56
14
Character Sets, và _T macro (1)
Character Sets, và _T macro (2)
• 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.
• 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.
Lập trình Windows
57
58
Character Sets và _T macro (3)
Exercises Chapter 1.
• Kiểu TCHAR (dùng thay cho kiểu char):
• Ex1-1. HelloWorld
– 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
– 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
Lập trình Windows
60
15
Create a project
Sử dụng Wizard
Chọn kiểu ứng
dụng
Tên ứng dụng
Sử dụng thư viện
Unicode
Lập trình Windows
61
Thiết kế giao diện ứng dụng (Dialog)
Lập trình Windows
62
Add code to greeting (1)
• Button “Hello”: Right Mouse/Add Event Handler
Chọn sự kiện,
tên hàm xử lý
Lập trình Windows
63
Lập trình Windows
64
16
Add code to greeting (2)
Compile, Build, Debug, Run
Compile (Ctrl+F7),
Build (F6),
Debug (F5),
Run without Debug (Ctrl+F5)
Set Breakpoint (F9) and Run Debug
Ví dụ gọi hộp thoại
thông báo
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");
}
Lập trình Windows
65
Chương 2. Lập trình Windows VC++/MFC
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)
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)
Lập trình Windows
67
Lập trình Windows
68
17
2.1. Message Map trong MFC (2)
2.1. Message Map trong MFC (3)
• 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:
• Xét một ví dụ ứng dụng MFC đơn giản:
– 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)
Lập trình Windows
69
Message Map trong MFC (2)
Lập trình Windows
Lập trình Windows
70
Qu| trình xử lý thông điệp trong MFC
71
Lập trình Windows
72
18
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)
Lập trình Windows
Add Message Handlers
• Có thể l{m thủ công
(Manual) (Viết trong
Message Map).
• Hoặc chọn
Properties/Message
73
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()
Lập trình Windows
2.2. Document/View trong MFC
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)
• Có thể lựa chọn Document Interfaces:
74
– 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
• View: Cơ chế
hiển thị dữ liệu
trong Document
(dẫn xuất từ lớp
CView)
• Đề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
Lập trình Windows
75
Lập trình Windows
76
19
Khung ứng dụng dạng SDI
Khung ứng dụng dạng MDI
• Chỉ mở một t{i liệu
• Cho phép mở nhiều t{i liệu
Lập trình Windows
Lập trình Windows
77
Ứng dụng MFC based Document/View
Ứ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ư:
• Kiểu SDI
78
– Với dạng SDI: CWinApp, CFrameWnd,
CDocument, CView
– Với dạng MDI: CWinApp, CMDIFrameWnd,
CMDIChildWnd, CDocument, CView
Lập trình Windows
79
80
20