Lập trình C trên
Windows
Nguyễn Đạt Thông
www.ndthong.info
Giới thiệu
■ Lập trình C trên Windows
■ Nội dung
■ Lý thuyết: 45 tiết
■ Thực hành: 30 tiết
■ Môn học tiên quyết
■ Kỹ thuật lập trình
■ Cấu trúc dữ liệu
■ Giảng viên
■ Nguyễn Đạt Thông, ndthong@math.hcmus.edu.vn
2 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Mục tiêu
■ Kiến thức
■ các kỹ thuật lập trình trên Windows,
■ các thành phần giao diện (GUI) trên Windows,
■ các thư viện sẵn có của Windows,
■ Kỹ năng
■ xây dựng các ứng dụng giao diện Windows,
■ xây dựng các ứng dụng tương tác với hệ thống
Windows,
3 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Yêu cầu
■ Yêu cầu đối với sinh viên
■ Đọc trước tài liệu bài giảng,
■ Tham dự các buổi lý thuyết, bài tập và minh họa,
■ Tự thực hiện các bài minh họa,
■ Tự nghiên cứu các kỹ thuật lập trình cao hơn trên
Windows.
■ Ngoài ra, sinh viên cần
■ Tìm hiểu thêm về các khái niệm quan trọng của
ngôn ngữ C: con trỏ và bộ nhớ, con trỏ hàm, …
4 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Nội dung
Windows và Messages
Nhập liệu (User Inputs)
Các thành phần giao diện
Lập trình
C trên
Windows
Các tiện ích trên Windows
Các chủ đề nâng cao
■ Tham khảo
■ Charles Petzold, Programming Windows, 5th Ed.,
Microsoft Press, 1998.
5 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tài liệu tham khảo
■ Tài liệu chính
■ Charles Petzold, Programming Windows, 5th
Edition, Microsoft Press, 1998.
■ Tham khảo
■ Trần Đan Thư, Lập trình C trên Microsoft
Windows, Hà Nội, 1996.
■ Lập trình C trên Windows, Thư viện điện tử khoa
học công nghệ, Vĩnh Long. (Link)
6 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Đánh giá
■ Quá trình
■ Điểm danh: 10%
■ Thực hành
■ Thi trên máy: 40%
■ Đánh giá
■ Thi tự luận: 50%
■ Được sử dụng tài liệu
7 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
8 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Phần 1
Windows và
Mesages
Nguyễn Đạt Thông
www.ndthong.info
Nội dung
■ Windows và Messages
■ Chương trình Windows
■ Lập trình Windows
■ Windows và Messages
■ Drawing và Device Context
■ Region và Clipping
10 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Chương trình Windows
■ “Hello World”
■ Tập tin header của Windows
■ Program Entry Point
■ Biên dịch và liên kết
■ Giới thiệu MS Visual Studio 2008
■ Windows và Unicode
11 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Chương trình C
■ Chương trình C/C++ – hàm main()
#include
void main()
{
printf("hello, world\n");
}
#include
int main()
{
printf("hello, world\n");
return 0;
}
12 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Chương trình Windows C
■ Chương trình Windows C – hàm
WinMain()
#include
int WINAPI WinMain(
HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
MessageBox(NULL, "Hello World!",
"HelloMsg", MB_OK);
return 0;
}
■ windows.h: tập tin header của Windows.
13 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tập tin header của Windows
■ Tập tin header của Windows
■ các macro và các biến môi trường,
■ các kiểu dữ liệu và cấu trúc dữ liệu,
■ các hằng số,
■ prototype của các hàm lập trình Windows.
■ WINDOWS.H là tập tin header cơ bản
■ WINDEF.H: định nghĩa các kiểu dữ liệu cơ bản.
■ WINNT.H: định nghĩa các kiểu dữ liệu Unicode.
■ WINBASE.H: các hàm cơ bản của Windows
■ WINUSER.H: các hàm lập trình Windows
■ WINGDI.H: các hàm vẽ giao diện
14 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Program Entry Point
■ Hàm WinMain()
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
■ Trong đó
■ WINAPI – stdcall
■ HINSTANCE – instance handle
■ PSTR – pointer to character string
15 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Message Box
■ Hàm MessageBox
int WINAPI MessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType);
■ Trong đó
■ HWND – window handle
■ LPCTSTR – long pointer to constant character string
■ Yêu cầu
■ winuser.h (được include trong windows.h)
■ User32.lib và User32.dll
MessageBox: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=vs.85).aspx
16 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tùy chỉnh Message Box
■ Tham số uType
#define MB_OK
#define MB_OKCANCEL
#define MB_ABORTRETRYIGNORE
#define MB_YESNOCANCEL
#define MB_YESNO
#define MB_RETRYCANCEL
#define MB_CANCELTRYCONTINUE
0x00000000L
0x00000001L
0x00000002L
0x00000003L
0x00000004L
0x00000005L
0x00000006L
#define MB_ICONHAND
#define MB_ICONQUESTION
#define MB_ICONEXCLAMATION
#define MB_ICONASTERISK
0x00000010L
0x00000020L
0x00000030L
0x00000040L
17 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
18 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Biên dịch và liên kết
■ Command line
■ Visual Studio projects
■ Tạo solution và project
■ Thêm tập tin mã nguồn vào project
■ Biên dịch và liên kết
19 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
MS Visual Studio 2008
■ Tạo solution và project
20 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
MS Visual Studio 2008
■ Tạo solution và project
21 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
MS Visual Studio 2008
■ Tạo solution và project
22 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
MS Visual Studio 2008
■ Thêm tập tin mã nguồn vào project
23 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
MS Visual Studio 2008
■ Biên dịch và liên kết
■ Chọn menu “Build → Build Solution”
■ Debug chương trình
■ Trong Solution Explorer, chọn project “HelloMsg”
■ Chọn menu “Debug → Start Debugging”
■ Đặt Breakpoint
■ Mở tập tin mã nguồn “HelloMsg.c”
■ Chọn menu “Debug → Toggle Breakpoint”
24 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
MS Visual Studio 2008
■ Debug chương trình “Step-by-Step”
■ Step Over (F10)
■ Step Into (F11)
■ Step Out (Shift + F11)
■ Run to line (Ctrl + F10)
■ Continue (F5)
■ Dừng debug (Shift + F5)
25 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
MessageBox trong Studio
■ Chạy chương trình HelloMsg từ VS2008
■ Tại sao?
26 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Windows và Unicode
■ Unicode là mở rộng của mã ASCII
■ Ký tự ASCII được biểu diễn bởi 1 byte dữ liệu
■ Ký tự Unicode (còn gọi là “wide char”) được biểu
diễn bởi 2 byte dữ liệu.
■ Windows hỗ trợ Unicode
■ Lập trình Windows cũng hỗ trợ Unicode
27 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Char và Wide char
■ Kiểu dữ liệu char
char c = 'A';
char *p = "Hello!";
char a[10];
char a[] = "Hello!";
■ Kiểu dữ liệu wchar_t
typedef unsigned short wchar_t;
wchar_t c = 'A';
wchar_t *p = L"Hello!";
wchar_t a[] = L"Hello!";
wchar_t c2 = L'A';
28 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hàm xử lý chuỗi
■ Kiểu dữ liệu char
char *pc = "Hello!";
int iLength = strlen(pc);
■ Kiểu dữ liệu wchar_t
wchar_t *pw = L"Hello!";
int iLength = wcslen(pw);
29 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Viết code cho Unicode
■ “Define” một macro chung
typedef char TCHAR;
#define _tcslen strlen
#define __T(x) x
typedef wchar_t TCHAR;
#define _tcslen wcslen
#define __T(x) L##x
■ Sử dụng macro
TCHAR *p = __T("Hello”);
int iLength = _tcslen(p);
30 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
UNICODE
■ Định danh UNICODE
#ifdef UNICODE
typedef char TCHAR;
#define _tcslen strlen
#define __T(x) x
#else
typedef wchar_t TCHAR;
#define _tcslen wcslen
#define __T(x) L##x
#endif
#define TEXT(x) __T(x)
■ Đã được khai báo trong WINNT.H
31 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Visual Studio và UNICODE
■ Mặc định MS Visual Studio khai báo
định danh UNICODE
32 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
HelloMsg hỗ trợ UNICODE
■ Mã nguồn của HelloMsg.c
#include
int WINAPI WinMain(
HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
MessageBox(NULL,
TEXT("Cannot finish operation. Try again?"),
TEXT("Details"),
MB_ICONWARNING | MB_CANCELTRYCONTINUE);
return 0;
}
33 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
34 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Lập trình Windows
■ Synchronous và Asynchronous
■ Callbacks
■ Lập trình Windows
35 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Synchronous và Asynchronous
■ Vấn đề
■ 7:00, ăn sáng, sau đó xem trước bài giảng
■ 8:00, vào lớp học
■ 9:15, giải lao
■ 9:30, tiếp tục học
■ 11:00, kết thúc
■ Synchronous?
■ Asynchronous?
36 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Synchronous và Asynchronous
■ Synchronous
■ Gọi hàm
■ Chờ cho đến khi hàm thực hiện xong
■ Gọi hàm khác…
■ Asynchronous
■ Gọi hàm và đăng ký “số điện thoại”
■ Gọi hàm khác…
37 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Số điện thoại
■ Định dạng?
■ 10 số?
■ 11 số?
■ Vùng phủ sóng?
■ Việt Nam?
■ Quốc tế?
38 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Don't Call Me, I'll Call You
■ Program gọi một hàm của Windows
■ Di chuyển window tới tọa độ (200, 200),
■ Disable nút “Back” và enable nút “Next”,
■ Tạo thư mục “test” trong thư mục gốc “D:\”
■ …
■ Windows gọi hàm của Program?
■ Khi nào?
39 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Windows call you…
■ Windows sẽ gọi Program, yêu cầu
Program xử lý khi:
■ Người dùng click lên button “Ok”,
■ Người dùng chọn radio button “Female”,
■ Người dùng thu nhỏ và phóng to window,
■ Người dùng đóng Program,
■ Windows chuẩn bị shutdown,
■ …
40 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Callbacks
■ Callback là hàm của Program
■ Được đăng ký trước trên Windows,
■ Tuân theo đúng prototype quy ước của Windows
■ Windows sẽ gọi Program thông qua các
hàm Callback
■ WndProc()
■ Windows cần gọi Program xử lý, nhưng
không có Callback tương ứng?
41 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Queue
■ Tại mỗi thời điểm, Program chỉ xử lý
một yêu cầu.
■ Windows yêu cầu Program xử lý
■ Program đang xử lý một yêu cầu trước đó?
■ Program đang thực hiện một tính toán riêng?
■ Windows chờ Program?
42 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Message Queue
■ Yêu cầu của Windows được hiện thực
dưới dạng một “message”.
■ Các yêu cầu (message) của Windows
được đặt vào trong “Message Queue”
của Program.
■ Program lần lượt xử lý các message
trong queue.
43 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Send và Post
■ Send
■ Windows “send” một message vào “queue” của
Program
■ Windows chờ cho Program xử lý message
■ Windows tiếp tục send các message khác…
■ Post
■ Windows “post” một message vào “queue” của
Program
■ Windows tiếp tục post các message khác…
44 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Get in and out fast
■ Windows có thể “send” hoặc “post” các
message cho Program.
■ Các message sẽ được xử lý tuần tự.
■ Program bị “Not Responding”?
■ Thời gian xử lý một message phải ngắn.
■ Nếu không thể ngắn?
45 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cửa sổ window
46 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Lập trình Windows
■ Hiển thị window và các child window
■ Program hay Windows?
■ Phát hiện thao tác của người sử dụng
■ Program hay Windows?
■ Xử lý tương tác của người sử dụng
■ Program hay Windows?
47 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Lập trình Windows
■ Với mỗi window
■ Viết hàm callback để vẽ window
■ Viết hàm callback để xử lý các thao tác
■ Đăng ký các hàm callback này cho Windows
■ Nếu có 100 loại thao tác?
■ Nếu có 1000 window?
48 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
49 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Windows và Messages
■ “Hello World 2”
■ Làm việc với window
■ Message Loop
■ Window Procedure
50 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
“Hello World 2”
■ Chương trình “Hello World 2”
■ Tạo và vẽ nên một window
■ Vẽ chuỗi “Hello World” tại vị trí chính giữa window
■ Xử lý (handle) một số thao tác cơ bản
51 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
“Hello World 2” – Step-by-Step
Bước 4
• Tạo một window
• Hiển thị window
Bước 3
• Viết hàm
Bước 2
• Xác định các thuộc tính của window
• Đăng ký một “class” mới
Bước 1
• Tạo Entry Point
• Xử lý các Message
52 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bước 1: entry point
#include
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(
HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("HelloWorld2") ;
MSG msg;
// step 2: register window class...
// pre-process messages
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
53 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bước 2: window class
= CS_HREDRAW | CS_VREDRAW;
= hInstance;
= LoadIcon(NULL, IDI_APPLICATION);
= LoadCursor(NULL, IDC_ARROW);
WNDCLASS wndclass;
wndclass.style
wndclass.lpfnWndProc = WinProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance
wndclass.hIcon
wndclass.hCursor
wndclass.hbrBackground = (HBRUSH)
GetStockObject(WHITE_BRUSH);
= NULL;
wndclass.lpszMenuName
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(0, TEXT("Program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}
54 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bước 3a: WinProc()
LRESULT CALLBACK WinProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message) {
case WM_CREATE:
return 0;
case WM_PAINT:
// TODO: draw text "Hello World!"
return 0;
case WM_DESTROY:
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
55 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bước 3b: Vẽ chuỗi
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
// ...
case WM_PAINT:
// draw text "Hello World!"
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;
// ...
}
56 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bước 4: tạo window
int WINAPI WinMain(
HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow) {
// ... HWND hwnd;
hwnd = CreateWindow(szAppName,// window class name
TEXT("Hello World 2"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
600, // initial x size
300, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
// ...
}
57 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
“Hello World 2”: Run
■ “Hello World 2” (source)
■ Chạy chương trình
■ Minimize rồi restore window
■ Thay đổi kích thước window
58 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Code Style
■ Kiểu dữ liệu
■ Viết hoa tất cả, không “underscope”
■ Nếu là structure hỗ trợ Unicode, kết thúc bằng A
(ASCII) hoặc W (Unicode)
■ UINT, WNDCLASSA, MOUSEINPUT,
MENUITEMINFOW, …
■ Hàm
■ Viết hoa các ký tự đầu, không “underscope”
■ Nếu là hàm hỗ trợ Unicode, kết thúc bằng A
(ASCII) hoặc W (Unicode)
■ RegisterClassW, TranslateMessage, …
59 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Code Style
■ Hằng số
■ Viết hoa tất cả, có “underscope”
■ Gồm 2 phần: nhóm hằng số và tên hằng số
■ WM_PAINT, LB_GETTEXT, WS_OVERLAPPED,
BS_RADIOBUTTON, …
■ Biến
■ Bắt đầu bằng “prefix”
■ Viết hoa các chữ đầu, không khoảng cách
■ szCmdLine, hPrevInstance, wParam, …
60 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tiền tố
Tiền tố
c
by
n
i
x, y
cx, cy
b hoặc f
w
l
dw
Ý nghĩa
char – ký tự
byte – số nguyên không âm có độ dài 8 bit
short – số nguyên có độ dài 16 bit
int – số nguyên có độ dài 32 bit
int – tọa độ Descartes
int – tọa độ Descartes (hằng số)
BOOL – cờ, có giá trị đúng/sai
WORD – số nguyên không âm có độ dài 16 bit
LONG – số nguyên có độ dài 32 bit
DWORD – số nguyên không âm có độ dài 32 bit
fn
sz
h
Hàm, phương thức
Chuỗi ký tự
handle
61 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Kiểu dữ liệu cơ bản
Kiểu dữ liệu
Ý nghĩa
HANDLE
HWND
BYTE
WORD
DWORD
UINT
LONG
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 32 – bit không dấu
Long 32 – bit
BOOL
Bool
LPSTR
LPCSTR
WPARAM
Con trỏ chuỗi
Hằng con trỏ chuỗi
32 – bit
LPARAM
32 – bit
LPVOID
Con trỏ 32 – bit đến một kiểu không xác định
62 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
63 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Làm việc với window
■ window
■ Tạo – CreateWindow
■ Hiển thị – ShowWindow
■ Cập nhật – UpdateWindow
■ Truy vấn window cha – GetParent
■ Truy vấn kích thước window – a
■ Di chuyển – MoveWindow
■ Hủy – DestroyWindow
■ Yêu cầu
■ WINUSER.H
■ User32.lib / User32.dll
64 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tạo window
■ CreateWindow / CreateWindowEx
HWND WINAPI CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
CreateWindow: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632679(v=vs.85).aspx
CreateWindowEx: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680(v=vs.85).aspx
65 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hiển thị window
■ ShowWindow
BOOL WINAPI ShowWindow(
HWND hWnd,
int nCmdShow
);
■ nCmdShow
■ SW_SHOW
■ SW_HIDE
■ SW_MAXIMIZE
■ SW_MINIMIZE
■ SW_RESTORE
ShowWindow: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
66 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cập nhật window
■ UpdateWindow
BOOL UpdateWindow(
HWND hWnd
);
UpdateWindow: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145167(v=vs.85).aspx
■ InvalidateRect
BOOL InvalidateRect(
HWND hWnd,
const RECT *lpRect,
BOOL bErase
);
InvalidateRect: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145002(v=vs.85).aspx
67 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Truy vấn window cha
■ GetParent
HWND WINAPI GetParent(
HWND hWnd
);
GetParent: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633504(v=vs.85).aspx
■ GetDesktopWindow
HWND WINAPI GetDesktopWindow(void);
GetWindowDesktop: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633504(v=vs.85).aspx
68 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Truy vấn kích thước window
■ GetWindowRect
BOOL WINAPI GetWindowRect(
HWND hWnd,
LPRECT lpRect
);
GetWindowRect: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633519(v=vs.85).aspx
■ GetClientRect
BOOL WINAPI GetClientRect(
HWND hWnd,
LPRECT lpRect
);
GetClientRect: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633503(v=vs.85).aspx
69 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Di chuyển window
■ MoveWindow
BOOL WINAPI MoveWindow(
HWND hWnd,
int X,
int Y,
int nWidth,
int nHeight,
BOOL bRepaint
);
■ (X, Y) là vị trí tương đối so với window cha.
MoveWindow: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633534(v=vs.85).aspx
70 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hủy window
■ DestroyWindow
BOOL WINAPI DestroyWindow(
HWND hWnd
);
DestroyWindow: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632682(v=vs.85).aspx
■ PostQuitMessage
VOID WINAPI PostQuitMessage(
int nExitCode
);
PostQuitMessage: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644945(v=vs.85).aspx
71 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Message Loop
■ Message Loop
■ Vòng lặp xử lý thông điệp (message)
■ Mỗi window sẽ xử lý các message riêng
■ Mỗi window có một message loop riêng
72 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Messages
■ Message được Windows định nghĩa.
■ Biểu diễn một loại thao tác cần xử lý.
■ Cấu trúc thông điệp
typedef struct tagMSG
{
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, * PMSG ;
73 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Một số message thông dụng
■ WM_CREATE
■ Được gửi khi window cần khởi tạo.
■ WM_DESTROY
■ Được gửi khi window cần hủy.
■ WM_PAINT
■ Được gửi khi window cần vẽ lại
■ WM_MOVE
■ Được gửi sau khi window di chuyển
74 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Một số message thông dụng
■ WM_SHOWWINDOW
■ Được gửi khi window cần hiển thị hoặc ẩn đi.
■ WM_SIZE
■ Được gửi sau khi window thay đổi kích thước.
■ WM_WINDOWPOSCHANGED
■ Được gửi sau khi window thay đổi vị trí hoặc kích
thước.
■ WM_QUIT
■ Được gửi khi chương trình chuẩn bị thoát.
75 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Translate Message
■ Xử lý message
while (GetMessage(&msg, NULL, 0,0))
{
TranslateMessage (&msg);
DispatchMessage(&msg);
}
■ GetMessage: nhận message từ Windows
■ TranslateMessage: chuyển đổi các message từ
bàn phím.
■ DispatchMessage: chuyển message đến
window tương ứng.
76 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Mô hình xử lý message
77 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Window Procedure
■ Mỗi khi có message cần xử lý, Windows
sẽ gọi “Window Procedure” của window.
■ Prototype của “Window Procedure”
được Windows qui định trước.
■ “Window Procedure” của một window là
hàm WinProc().
78 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hàm WinProc()
■ Hàm WinProc() là một Callback
LRESULT CALLBACK WinProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam
);
■ Được gọi khi có message cần xử lý.
■ Message gửi đến window nào thì WinProc của
window đó xử lý.
WinProc: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx
79 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hàm WinProc()
Window handle: cho biết
window nào cần xử lý.
Message: cho biết loại thao tác
cần xử lý
HWND hwnd
UINT message
WPARAM wParam
LPARAM lParam
WORD parameter: tham số cần
thiết cho việc xử lý
LONG parameter: tham số cần
thiết cho việc xử lý
Các tham số của hàm WinProc()
80 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
81 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Drawing và Device Context
■ Vẽ (Painting) và vẽ lại (repainting)
■ Device Context
■ Hệ tọa độ
■ Vẽ chữ
■ Vẽ hình và tô màu
■ Path và Region
82 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Vẽ và vẽ lại
■ Vẽ window
■ Mỗi window được vẽ dựa vào các thuộc tính nội
tại của chính window đó.
■ Vẽ lại window
■ Mỗi window được vẽ lại khi phần hiển thị của nó
“không còn hợp lệ nữa”
■ Bị xóa hoặc bị di chuyển đến vị trí khác,
■ Bị window khác che lấp,
■ Thông tin nội tại của window bị thay đổi,
When to Draw in a Window: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145199(v=vs.85).aspx
83 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cập nhật window
■ Program muốn thay đổi của sự hiển thị
của window?
■ Làm sao để vẽ thêm?
■ Làm sao để việc vẽ thêm xuất hiện khi
vẽ lại?
84 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Mô hình cập nhật window
Yêu cầu vẽ lại
Cập nhật thông tin
Gửi message WM_PAINT
yêu cầu window vẽ lại.
Cập nhật thông tin nội tại
phục vụ cho việc vẽ
window.
Cập nhật
window
Vẽ window
Xử lý message WM_PAINT:
Vẽ window dựa vào các
thông tin nội tại của window
đó.
85 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Trở lại “Hello World 2”
■ Thay đổi kích thước window:
■ Window có được yêu cầu vẽ lại không?
■ Thông tin nội tại nào bị thay đổi?
■ Việc vẽ lại có áp dụng thông tin mới không?
86 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
87 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
GDI
■ Graphics Device Interface (GDI)
■ Thư việc hàm của Windows
■ Bao gồm các hàm “vẽ”
■ Để vẽ các thành phần của window
■ Truy vấn “device context” của window
■ Sử dụng các hàm thư viện GDI
■ Yêu cầu
■ WINGDI.H (đã được include trong WINDOWS.H)
■ Gdi32.lib / Gdi32.dll
Windows GDI: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145203(v=vs.85).aspx
88 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Device Context
■ Device Context (DC)
■ Cấu trúc dữ liệu
■ Lưu giữ các thông tin cần thiết cho các hàm GDI
■ Device context đại diện cho một thiết bị
“hiển thị”
■ Màn hình (các window)
■ Máy in
■ Ảnh bitmap
Device Context: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162467(v=vs.85).aspx
89 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Truy vấn HDC
■ Truy vấn HDC của một window
PAINTSTRUCT ps;
HDC hdc; // handle to DC
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
// [use GDI functions]
EndPaint(hwnd, &ps);
return 0;
■ BeginPaint: “validate” tất cả các vùng bị
“invalidate”.
■ Khi xử lý WM_PAINT:
■ Có thể không gọi hàm GDI,
■ Bắt buộc phải gọi BeginPaint() và EndPaint().
WM_PAINT Message: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145137(v=vs.85).aspx
90 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
PAINTSTRUCT
■ Cấu trúc PAINTSTRUCT
typedef struct tagPAINTSTRUCT
{
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT;
■ hdc: Device Context Handle
■ fErase: cho biết Program có cần xóa trước khi vẽ
■ rcPaint: cho biết vùng cần vẽ (không hợp lệ)
PAINTSTRUCT: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162768(v=vs.85).aspx
91 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
rcPaint
■ rcPaint trong PAINTSTRUCT
92 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
GetDC và ReleaseDC
■ Hàm GetDC() và ReleaseDC()
HWND hwnd;
HDC hdc;
hdc = GetDC(hwnd);
[use GDI functions]
ReleaseDC(hwnd, hdc);
■ GetDC() và ReleaseDC()
■ phải đi chung với nhau
■ có thể sử dụng khi xử lý các message khác nhau
■ được dùng để vẽ trực tiếp lên window
GetDC: http://msdn.microsoft.com/en-us/library/windows/desktop/dd144871(v=vs.85).aspx
ReleaseDC: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162920(v=vs.85).aspx
93 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Client Area
■ Program có thể tự do vẽ
■ trên vùng “client” của window.
■ Non-client area của window
■ Title bar, menu bar, scrollbar, và border.
94 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
GetWindowDC
■ Truy vấn DC ứng với toàn bộ window
HDC GetWindowDC(
HWND hWnd
// handle to window
);
■ Sau khi vẽ xong, phải gọi hàm ReleaseDC.
■ Nếu tham số hWnd là NULL, GetWindowDC sẽ trả
về DC ứng với toàn màn hình.
GetWindowDC: http://msdn.microsoft.com/en-us/library/windows/desktop/dd144947(v=vs.85).aspx
95 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
WM_NCPAINT
■ Message WM_NCPAINT được gửi khi
Windows yêu cầu Program vẽ “Non-
Client Area” của window.
PAINTSTRUCT ps;
HDC hdc; // handle to DC
case WM_NCPAINT:
hdc = GetWindowDC(hwnd);
// [use GDI functions]
ReleaseDC(hwnd, hdc);
return 0;
WM_NCPAINT Message: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145137(v=vs.85).aspx
96 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thuộc tính của DC
■ Hàm GetDeviceCaps
int GetDeviceCaps(
HDC hdc,
int nIndex
);
■ Các thuộc tính
■ LOGPIXELSX, LOGPIXELSY
■ PHYSICALWIDTH, PHYSICALHEIGHT
■ HORZSIZE, VERTSIZE
GetDeviceCaps: http://msdn.microsoft.com/en-us/library/windows/desktop/dd144877(v=vs.85).aspx
97 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
98 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hệ tọa độ
■ Hệ tọa độ trong DC
■ X: từ trái qua phải
■ Y: từ trên xuống dưới
■ O: góc trên bên trái
99 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tọa độ tương đối
■ Relative position là tọa độ vị trí của
window so với window cha.
100 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Chuyển đổi tọa độ
■ ClientToScreen() – ScreenToClient()
ClientToScreen: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183434(v=vs.85).aspx
ScreenToClient: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162952(v=vs.85).aspx
101 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Chuyển đổi tọa độ
■ Chuyển đổi tọa độ tương đối giữa các
window
■ Chuyển đổi từ (x,y) sang (x,y) và ngược lại?
102 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Vẽ chữ
■ Hàm TextOut
BOOL TextOut(
HDC hdc,
int nXStart,
int nYStart,
LPCTSTR lpString,
int cchString
// length in characters
);
■ Vẽ chuỗi ký tự trên DC
■ Là dạng kết hợp của TextOutA và TextOutW
TextOut: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145133(v=vs.85).aspx
103 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Vẽ chữ
■ Hàm DrawText
int DrawText(
HDC hDC,
LPCTSTR lpchText,
int nCount,
LPRECT lpRect,
UINT uFormat
);
■ uFormat
■ DT_NOCLIP
■ DT_SINGLELINE, DT_CENTER, DT_VCENTER
DrawText: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162498(v=vs.85).aspx
DrawTextEx: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162499(v=vs.85).aspx
104 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Màu chữ
■ Hàm SetTextColor
COLORREF SetTextColor(
HDC hdc,
COLORREF crColor
);
■ Hàm GetTextColor
COLORREF GetTextColor(
HDC hdc
);
■ Sử dụng macro RGB để tạo giá trị COLORREF
■ RGB(255, 255, 255) – màu trắng
■ RGB(255, 0, 0) – màu đỏ
SetTextColor: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145093(v=vs.85).aspx
GetTextColor: http://msdn.microsoft.com/en-us/library/windows/desktop/dd144934(v=vs.85).aspx
105 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Màu nền
■ Hàm SetBkColor
COLORREF SetBkColor(
HDC hdc,
COLORREF crColor
);
■ Hàm SetBkMode
int SetBkMode(
HDC hdc,
int iBkMode
);
■ iBkMode
■ OPAQUE hoặc TRANSPARENT
SetBkColor: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162964(v=vs.85).aspx
SetBkMode: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162965(v=vs.85).aspx
106 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Font chữ
■ Hàm CreateFont
HFONT CreateFont(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int fnWeight,
DWORD fdwItalic,
DWORD fdwUnderline,
DWORD fdwStrikeOut,
DWORD fdwCharSet,
DWORD fdwOutputPrecision,
DWORD fdwClipPrecision,
DWORD fdwQuality,
DWORD fdwPitchAndFamily,
LPCTSTR lpszFace
// font name
);
CreateFont: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183499(v=vs.85).aspx
107 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Font chữ
■ Hàm CreateFont yêu cầu Windows
■ tạo một cấu trúc LOGFONT
■ lưu trữ các thuộc tính font chữ vào LOGFONT
■ trả về một “handle to LOGFONT” - HFONT
■ Hàm CreateFontIndirect
HFONT CreateFontIndirect(
const LOGFONT *lplf
);
LOGFONT: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145037(v=vs.85).aspx
CreateFontIndirect: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183500(v=vs.85).aspx
108 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thay đổi font chữ
■ Hàm (macro) SelectFont
HFONT SelectFont(
HDC hdc,
HFONT hFont
);
■ Sử dụng hàm SelectFont
■ thay đổi font chữ cho DC
■ truy vấn font chữ hiện tại của DC
SelectFont http://msdn.microsoft.com/en-us/library/windows/desktop/dd162956(v=vs.85).aspx
109 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Xóa font chữ
■ Hàm (macro) DeleteFont
BOOL DeleteFont(
HFONT hfont
);
■ Sử dụng hàm DeleteFont
■ xóa cấu trúc LOGFONT đã tạo ra trước đó
■ Chỉ được xóa font chữ khi nó không phải là font
chữ hiện tại của DC.
DeleteFont: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183535(v=vs.85).aspx
110 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Đọc thêm
■ Text Metrics
http://msdn.microsoft.com/en-us/library/windows/desktop/dd144934(v=vs.85).aspx
■ Text Alignment
http://msdn.microsoft.com/en-us/library/windows/desktop/dd144932(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145091(v=vs.85).aspx
111 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
112 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Vẽ điểm
■ Hàm SetPixel
COLORREF SetPixel(
HDC hdc,
int X,
int Y,
COLORREF crColor
);
SetPixel: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145078(v=vs.85).aspx
113 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Vẽ đường thẳng
■ Hàm MoveToEx và LineTo
BOOL MoveToEx(
HDC hdc,
int X,
int Y,
LPPOINT lpPoint
);
BOOL LineTo(
HDC hdc,
int nXEnd,
int nYEnd
);
MoveToEx: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145069(v=vs.85).aspx
LineTo: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145029(v=vs.85).aspx
114 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hình dạng của đường
115 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bút vẽ – Pen
■ Hàm CreatePen()
HPEN CreatePen(
int fnPenStyle,
int nWidth,
COLORREF crColor
);
■ Các loại bút vẽ
■ PS_SOLID
■ PS_DASH
■ PS_DOT
■ PS_DASHDOT
■ PS_DASHDOTDOT
CreatePen: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183509(v=vs.85).aspx
116 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bút vẽ – Pen
■ Hàm CreatePen yêu cầu Windows
■ tạo một cấu trúc LOGPEN
■ lưu trữ các thuộc tính bút vẽ vào LOGPEN
■ trả về một “handle to LOGPEN” - HPEN
■ Hàm CreatePenIndirect
HPEN CreatePenIndirect(
const LOGPEN *lplgpn
);
LOGPEN: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145041(v=vs.85).aspx
CreatePenIndirect: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183510(v=vs.85).aspx
117 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thay đổi bút vẽ
■ Hàm SelectObject
HGDIOBJ SelectObject(
HDC hdc,
HGDIOBJ hgdiobj
);
■ Sử dụng hàm SelectObject với tham số là
HPEN
■ thay đổi bút vẽ cho DC
■ truy vấn bút vẽ hiện tại của DC (kết quả trả về là HPEN)
SelectObject http://msdn.microsoft.com/en-us/library/windows/desktop/dd162957(v=vs.85).aspx
118 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Xóa bút vẽ
■ Hàm DeleteObject
BOOL DeleteObject(
HGDIOBJ hObject
);
■ Sử dụng hàm DeleteObject với tham số là
HPEN
■ xóa cấu trúc LOGPEN đã tạo ra trước đó
■ Chỉ được xóa bút vẽ khi nó không phải là bút vẽ
hiện tại của DC.
DeleteObject: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183539(v=vs.85).aspx
119 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Vẽ hình
■ Vẽ hình chữ nhật
BOOL Rectangle(
HDC hdc,
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect
);
■ Hình chữ nhật được vẽ bằng bút vẽ hiện tại của
DC.
■ Hình chữ nhật được tô màu gì?
Rectanlge: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85).aspx
120 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bút tô – Brush
■ Hàm CreateSolidBrush()
HBRUSH CreateSolidBrush(
COLORREF crColor
);
CreateSolidBrush: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183518(v=vs.85).aspx
121 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bút tô – Brush
■ Hàm CreateHatchBrush()
HBRUSH CreateHatchBrush(
int fnStyle,
COLORREF clrref
);
■ Các loại bút tô Hatch
■ HS_BDIAGONAL
■ HS_FDIAGONAL
■ HS_CROSS
■ HS_DIAGCROSS
■ HS_HORIZONTAL
■ HS_VERTICAL
CreateHatchBrush: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183504(v=vs.85).aspx
122 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bút tô – Brush
■ Hàm CreateXxxxxBrush yêu cầu
Windows
■ tạo một cấu trúc LOGBRUSH
■ lưu trữ các thuộc tính bút tô vào LOGBRUSH
■ trả về một “handle to LOGBRUSH” - HBRUSH
■ Hàm CreateBrushIndirect
HBRUSH CreateBrushIndirect(
const LOGBRUSH *lplb
);
LOGBRUSH: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145035(v=vs.85).aspx
CreateBrushIndirect: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183487(v=vs.85).aspx
123 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thay đổi và xóa bút tô
■ Thay đổi bút tô
■ Sử dụng hàm SelectObject với tham số là
HBRUSH
■ Xóa bút tô
■ Sử dụng hàm DeleteObject với tham số là
HBRUSH
■ xóa cấu trúc LOGBRUSH đã tạo ra trước đó
■ Chỉ được xóa bút tô khi nó không phải là bút tô
hiện tại của DC.
124 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Vẽ hình
■ Hình tròn – ellipse
Ellipse: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162510(v=vs.85).aspx
Chord: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183428(v=vs.85).aspx
Pie: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162799(v=vs.85).aspx
125 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Đọc thêm
■ Vẽ đa giác
PolyLine: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162815(v=vs.85).aspx
PolyLineTo: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162816(v=vs.85).aspx
■ Vẽ đường cong
Arc: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183357(v=vs.85).aspx
ArcTo: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183358(v=vs.85).aspx
AngleArc: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183358(v=vs.85).aspx
■ Vẽ đường Bezier
PolyBezier: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162811(v=vs.85).aspx
PolyBezierTo: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162812(v=vs.85).aspx
126 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Vẽ đường và hình (exe)
/*--------------------------------------------------
LINEDEMO.C -- Line-Drawing Demonstration Program
(c) Charles Petzold, 1998
--------------------------------------------------*/
#include
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
127
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("LineDemo") ;
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 ;
Nguyễn Đạt Thông
Lập trình C trên Windows - 2013
Ví dụ
■ Vẽ đường cong Bezier (exe)
/*---------------------------------------
BEZIER.C -- Bezier Splines Demo
(c) Charles Petzold, 1998
---------------------------------------*/
#include
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
128
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Bezier") ;
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 ;
Nguyễn Đạt Thông
Lập trình C trên Windows - 2013
Ví dụ
■ Vẽ đường Sin (exe)
/*-----------------------------------------
SINEWAVE.C -- Sine Wave Using Polyline
(c) Charles Petzold, 1998
-----------------------------------------*/
#include
#include
#define NUM 1000
#define TWOPI (2 * 3.14159)
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("SineWave") ;
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) ;
129 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
130 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Path
■ Path
■ Một tập hợp nhiều hình vẽ
■ Được vẽ đường biên
■ Được tô
■ Được vẽ và tô
131 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tạo Path
■ Hàm BeginPath() và EndPath()
PAINTSTRUCT ps;
HDC hdc; // handle to DC
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
BeginPath(hdc);
// [use GDI functions to draw path]
EndPath(hdc);
EndPaint(hwnd, &ps);
return 0;
BeginPath: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183363(v=vs.85).aspx
EndPath: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162599(v=vs.85).aspx
132 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Vẽ Path
■ Vẽ đường viền
BOOL StrokePath(
HDC hdc
);
■ Tô màu
BOOL FillPath(
HDC hdc
);
■ Vẽ đường viền và tô
BOOL StrokeAndFillPath(
HDC hdc
);
133 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Region
■ Region
■ Một tập hợp nhiều vùng hiển thị trên DC
■ Region tương tự như Path
■ Vẽ biên và tô màu
■ Kết hợp nhiều vùng hiển thị
■ Hit – test
134 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tạo Region
■ Tạo một region hình chữ nhật
HRGN CreateRectRgn(
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect
);
■ Khi không còn sử dụng region
■ Sử dụng hàm DeleteObject để giải phóng region
CreateRectRgn: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183514(v=vs.85).aspx
135 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tạo Region
■ Tạo Region hình ellipse
CreateEllipticRgn: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183496(v=vs.85).aspx
■ Tạo Region hình đa giác
CreatePolygonRgn: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183511(v=vs.85).aspx
136 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Vẽ và tô màu Region
■ Hàm PaintRgn
BOOL PaintRgn(
HDC hdc,
HRGN hrgn
);
■ Hàm FillRgn
BOOL FillRgn(
HDC hdc,
HRGN hrgn,
HBRUSH hbr
);
PaintRgn: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162767(v=vs.85).aspx
FillRgn: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162720(v=vs.85).aspx
137 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Kết hợp các Region
■ Hàm CombineRgn
int CombineRgn(
HRGN hrgnDest,
HRGN hrgnSrc1,
HRGN hrgnSrc2,
int fnCombineMode
);
■ fnCombineMode
CombineRgn: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183465(v=vs.85).aspx
138 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hit Test Region
■ Hit Test
■ Kiểm tra vị trí chuột
■ Hit Test Region: kiểm tra vị trí chuột có nằm trong
Region không.
■ Hàm PtInRgn
BOOL PtInRegion(
HRGN hrgn,
int X,
int Y
);
PtInRgn: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162883(v=vs.85).aspx
139 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
140 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
View Port
■ Các hệ tọa độ
■ Clipping
141 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Các hệ tọa độ
■ GDI có 2 hệ tọa độ
■ Hệ tọa độ Logical (hay tọa độ thực – world)
■ Hệ tọa độ Viewport (hay hệ tọa độ hiển thị trên
window).
■ Các hàm vẽ của GDI
■ sử dụng hệ tọa độ Logic.
142 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Các hệ tọa độ
143 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Di chuyển gốc tọa độ ViewPort
144 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Di chuyển gốc tọa độ Viewport
■ Hàm SetViewportOrgEx
BOOL SetViewportOrgEx(
HDC hdc,
int X,
int Y,
LPPOINT lpPoint
);
■ Thiết lập gốc tọa độ O của viewport tương ứng với
điểm (X, Y) trong hệ tọa độ “world”.
SetViewportOrgEx: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145099(v=vs.85).aspx
145 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Clipping
■ Clipping
■ Hạn chế vùng hiển thị
■ Clipping Region
■ Giới hạn vùng hiển thị trong một region
■ Clipping Path
■ Giới hạn vùng hiển thị trong một path
146 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Clipping
147 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Region Clipping
■ Hàm SelectClipRgn
int SelectClipRgn(
HDC hdc,
HRGN hrgn
);
■ Region hrgn sẽ được copy
■ Có thể sử dụng lại cho các DC khác
■ Có thể giải phóng bằng DeleteObject
SelectClipRgn: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162955(v=vs.85).aspx
148 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thay đổi Clipping Region
■ GetClipRgn
■ Truy vấn clipping region hiện tại
■ ExcludeClipRect
■ “exclude” clipping region với một rectangle
■ IntersectClipRect
■ “intersect” clipping region với một retangle
■ OffsetClipRgn
■ Di chuyển clipping region
149 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Đọc thêm
■ GDI Mapping Mode
SetWindowExtEx: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145100(v=vs.85).aspx
SetViewportExtEx: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145098(v=vs.85).aspx
■ Transforming: xoay và zoom
ScaleViewportExtEx: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162947(v=vs.85).aspx
ScaleWindowExtEx: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162948(v=vs.85).aspx
SetWorldTransform: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145104(v=vs.85).aspx
CombineTransform: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183466(v=vs.85).aspx
150 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
151 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Phần 2
Nhập liệu
(User Inputs)
Nguyễn Đạt Thông
www.ndthong.info
Nội dung
■ Nhập liệu
■ Keyboard
■ Mouse
■ Timer
153 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Keyboard
■ Bàn phím và ký tự
■ Message về bàn phím
■ Message về ký tự
■ Caret
154 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Bàn phím
■ Thao tác từ bàn phím
■ Nhấn phím ký tự
■ Nhấn phím chức năng (F1, F2, Esc, Home, …)
■ Nhấn phím điều khiển (Ctrl, Alt, Shift)
■ Windows xử lý các thao tác bàn phím
■ Thông qua hàm “TranslateMsg”
■ Gửi message “keystroke” hoặc message
“command” đến window
155 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Window Focus
■ Windows sẽ gửi các message
“keystroke” đến window đang “focus”
■ Focus
■ Khi được focus, window sẽ nhận được message
WM_SETFOCUS
■ Khi mất focus, window sẽ nhận được message
WM_KILLFOCUS
156 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Keystroke queue
■ Người sử dụng gõ bàn phím
■ Program lần lượt xử lý các keystroke
■ Người sử dụng gõ quá nhanh?
■ Các keystroke được đặt trong message queue của
“focus” window?
157 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Keystroke queue
■ Focus window xử lý keystroke message
■ Việc xử lý làm cho window mất focus?
■ Việc xử lý làm cho window đóng lại?
■ Những keystroke message còn trong
queue sẽ được xử lý như thế nào?
■ Các keystroke sẽ được đặt trong message queue
của Windows
158 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Keystroke và ký tự
■ Keystroke là thao tác nhấn phím
■ Chẳng hạn nhấn phím ‘A’
■ Chẳng hạn nhấn phím ‘1’
■ Chẳng hạn nhấn phím ‘Del’
■ Ký tự là kết quả của thao tác nhấn phím
■ Chẳng hạn ‘a’, ‘A’, hoặc ‘Ctrl-A’?
■ Chẳng hạn ‘1’, ‘!’, ‘Ctrl-1’, hoặc ‘Ctrl-Shift-1’?
■ Chẳng hạn ‘Del’?
159 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Message keystroke
■ Đối với mỗi keystroke
■ Windows sẽ gửi message keystroke.
■ Nếu keystroke tương ứng với một ký tự
■ Windows sẽ gửi thêm message ký tự.
160 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Message keystroke
■ Windows gửi các cặp message
■ WM_KEYDOWN và WM_KEYUP
■ WM_SYSKEYDOWN và WM_SYSKEYUP
■ Program thường không xử lý “SysKey”
■ Gọi hàm DefWindowProc để Windows xử lý
WM_KEYDOWN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646280(v=vs.85).aspx
WM_KEYUP: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646281(v=vs.85).aspx
WM_SYSKEYDOWN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646286(v=vs.85).aspx
WM_SYSKEYUP: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646287(v=vs.85).aspx
161 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Xử lý các message keystroke
■ Trong hàm WinProc
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
break;
case WM_KEYDOWN:
// TODO: process keydown
return 0;
case WM_KEYUP:
// TODO: process keyup
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
162 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tham số wParam
■ Tham số wParam của message
keystroke
■ Cho biết mã ảo (virtual keycode) của phím được
nhấn.
■ Mã ảo của phím
■ Đại diện cho từng phím
■ Độc lập với loại bàn phím (keyboard layout)
163 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Virtual Keycode
Code
Mô tả
0x41 – 0x5A
Phím ‘A’ – ‘Z’
0x30 – 0x39
Phím ‘0’ – ‘9’
VK_RETURN (0x0D)
Phím Enter
VK_SHIFT (0x10)
Phím Shift
VK_CTRL (0x11)
Phím Ctrl
VK_MENU (0x12)
Phím Alt
VK_PAUSE (0x13)
Phím Pause
VK_CAPITAL (0x14)
Phím CAPS LOCK
VK_TAB (0x09)
Phím Tab
VK_BACK (0x08)
Phím Backspace
VK_ESCAPE (0x1B)
Phím ESC
VK_SPACE (0x20)
Phím Spacebar
Virtual Keycodes: http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
164 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tham số lParam
■ Tham số lParam chứa các thông tin
■ Repeat Count
■ OEM Scan Code: mã phím phụ thuộc bàn phím
■ Extended Key Flag: cho biết loại bàn phím
■ Context Code: cho biết trạng thái phím Alt
165 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Các phím chức năng
■ Các phím chức năng
■ Alt, Ctrl, Shift
■ Caps Lock, Num Lock, Scroll Lock
■ Khi nhận được message keystroke
■ Program cần biết trạng thái hiện tại của các phím
chức năng.
166 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Các phím chức năng
■ Hàm GetKeyState
SHORT WINAPI GetKeyState(
int nVirtKey
);
■ Cho biết trạng thái của các phím chức năng
■ Không phải tại thời điểm gọi hàm,
■ Mà tại thời điểm xảy ra keystroke
■ Kết quả trả về
■ Bit thấp nhất (0x0001) cho biết trạng thái “toggled”
■ Bit cao nhất (0x0008) cho biết trạng thái “pressed”
GetKeyState: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx
GetAsynKeyState: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx
167 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Xử lý message keystroke
■ Không xử lý WM_SYSKEYDOWN và
WM_SYS_KEYUP
■ Có thể xử lý một, hoặc cả hai message
WM_KEYDOWN và WM_KEYUP
■ Không xử lý message keystroke như
message ký tự
■ Keystroke là ‘3’, trạng thái Shift là “Press”?
168 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Message ký tự
■ Windows gửi message WM_CHAR
■ Nếu keystroke tương ứng tạo ra một ký tự.
■ Windows “translate” message keystroke
thành message ký tự
■ TranslateMsg
WM_CHAR: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646276(v=vs.85).aspx
169 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tham số wParam
■ wParam cho biết ký tự được nhấn
TCHAR c;
case WM_KEYDOWN:
c = (TCHAR)wParam;
// TODO: process character c here
return 0;
■ Ký tự được nhấn
■ Là ký tự Unicode nếu Program hỗ trợ Unicode
■ Là ký tự ANSI nếu Program không hỗ trợ Unicode
170 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tham số lParam
■ Tham số lParam chứa các thông tin
■ Repeat Count
■ OEM Scan Code: mã phím phụ thuộc bàn phím
■ Extended Key Flag: cho biết loại bàn phím
■ Context Code: cho biết trạng thái phím Alt
171 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thứ tự message
■ Khi nhấn phím ‘A’
WM_KEYDOWN
WM_CHAR
WM_KEYUP
Virtual key code for 'A' (0x41)
Character code for 'a'
(0x61)
Virtual key code for 'A' (0x41)
■ Khi nhấn Shift + ‘A’
WM_KEYDOWN
WM_KEYDOWN
WM_CHAR
WM_KEYUP
WM_KEYUP
Virtual key code VK_SHIFT (0x10)
Virtual key code for 'A' (0x41)
Character code for 'A'
(0x41)
Virtual key code for 'A' (0x41)
Virtual key code VK_SHIFT (0x10)
172 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thứ tự message
■ Khi nhấn và giữ phím ‘A’
WM_KEYDOWN
WM_CHAR
Virtual key code for 'A' (0x41)
(0x61)
Character code for 'a'
WM_KEYDOWN
WM_CHAR
Virtual key code for 'A' (0x41)
(0x61)
Character code for 'a'
WM_KEYDOWN
WM_CHAR
Virtual key code for 'A' (0x41)
(0x61)
Character code for 'a'
...
WM_KEYUP
Virtual key code for 'A' (0x41)
■ Trong các cặp WM_KEYDOWN và WM_CHAR
■ Có thể có “Repeat Count” lớn hơn 1.
173 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Xử lý message WM_CHAR
case WM_CHAR:
[other program lines]
switch (wParam)
{
case '\b': // backspace
[other program line]
break;
case '\t': // tab
[other program lines]
break;
case '\n': // linefeed
[other program lines]
break;
default: // character codes
[other program lines]
break;
}
return 0;
174 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Caret
■ Caret trong một Program
■ Cho biết vị trí ký tự kế tiếp sẽ xuất hiện
■ Có dạng | hoặc ▌
■ Caret trong một Windows program
■ Xuất hiện khi nhận message WM_SETFOCUS
■ Biến mất khi nhận message WM_KILLFOCUS
175 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tạo một Caret
■ Hàm CreateCaret
BOOL WINAPI CreateCaret(
HWND hWnd,
HBITMAP hBitmap,
int nWidth,
int nHeight
);
■ Caret mặc định của Windows
■ hBitmap là NULL hoặc (HBITMAP)1
■ Có thể tạo caret từ một hình bitmap
CreateCaret: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648399(v=vs.85).aspx
176 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hiển thị Caret
■ Hàm ShowCaret
BOOL WINAPI ShowCaret(
HWND hWnd
);
ShowCaret: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648406(v=vs.85).aspx
■ Hàm HideCaret
BOOL WINAPI HideCaret(
HWND hWnd
);
HideCaret: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648403(v=vs.85).aspx
177 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thay đổi vị trí Caret
■ Hàm SetCaretPos
BOOL WINAPI SetCaretPos(
int X,
int Y
);
SetCaretPos: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648405(v=vs.85).aspx
■ Hàm GetCaretPos
BOOL WINAPI GetCaretPos(
LPPOINT lpPoint
);
GetCaretPos: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648402(v=vs.85).aspx
178 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Blinking
■ Hàm SetCaretBlinkTime
BOOL WINAPI SetCaretBlinkTime(
UINT uMSeconds
);
SetCaretBlickTime: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648404(v=vs.85).aspx
■ Hàm GetCaretBlinkTime
UINT WINAPI GetCaretBlinkTime(void);
GetCaretBlinkTime: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648401(v=vs.85).aspx
179 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Chương trình “key-view” (exe)
/*--------------------------------------------------------
KEYVIEW2.C -- Displays Keyboard and Character Messages
(c) Charles Petzold, 1998
--------------------------------------------------------*/
#include
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("KeyView2") ;
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 ;
180 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Chương trình gõ văn bản (exe)
/*--------------------------------------
TYPER.C -- Typing Program
(c) Charles Petzold, 1998
--------------------------------------*/
#include
#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Typer") ;
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 ;
181 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
182 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Mouse
■ Cursor
■ Sự kiện Mouse trên Client Area
■ Sự kiện Mouse trên Non-Client Area
■ Wheel
■ Capturing Mouse
183 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Mouse
■ Các nút nhấn trên Mouse
■ Left
■ Middle (Optional)
■ Right
■ Các thao tác trên Mouse
■ Move
■ Click
■ Double Click
■ Drag
■ Wheel
184 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cursor
■ Cursor đại diện cho Mouse trên màn
hình.
■ Cursor có thể có nhiều hình dạng
■ Cursor chỉ đến 1 pixel trên màn hình.
185 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác trên Cursor
■ Ẩn – hiện Cursor
int WINAPI ShowCursor(
BOOL bShow
);
ShowCursor: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648396(v=vs.85).aspx
■ Thay đổi vị trí Cursor
BOOL WINAPI SetCursorPos(
int X, int Y
);
BOOL WINAPI GetCursorPos(
LPPOINT lpPoint
);
SetCursorPos: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648394(v=vs.85).aspx
GetCursorPos: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648390(v=vs.85).aspx
186 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Mouse Message
■ Windows sẽ gửi message về mouse
■ Khi mouse đi vào vùng hiển thị của window
■ Khi mouse được click trong window
■ Windows gửi message ngay cả khi
window không “active”.
■ Windows định nghĩa các message
■ Client-Area message
■ Non-Client-Area message
187 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Client-Area mouse message
■ Khi mouse di chuyển trong vùng Client
■ Window sẽ nhận được message WM_MOUSEMOVE.
■ Mouse di chuyển từ tọa độ (0,0) đến
tọa độ (0,1000)
■ Windows sẽ gửi 1000 message WM_MOUSEMOVE?
188 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Client-Area mouse message
■ Khi mouse được click trong vùng Client
■ Window sẽ nhận được message
Button Pressed
Release
Pressed
WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBLCLK
Left
Middle WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBLCLK
WM_RBUTTONDOWN WM_RBUTTONUP WM_RBUTTONDBLCLK
Right
WM_LBUTTONDOWN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645607(v=vs.85).aspx
WM_LBUTTONUP: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645608(v=vs.85).aspx
WM_LBUTTONDBLCLK: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645606(v=vs.85).aspx
WM_RBUTTONDOWN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645607(v=vs.85).aspx
WM_RBUTTONUP: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646243(v=vs.85).aspx
WM_RBUTTONDBLCLK: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646241(v=vs.85).aspx
WM_MBUTTONDOWN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645607(v=vs.85).aspx
WM_MBUTTONUP: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645611(v=vs.85).aspx
WM_MBUTTONDBLCLK: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645609(v=vs.85).aspx
189 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tham số lParam và wParam
■ lParam
■ tọa độ mouse tại thời điểm phát sinh message
■ tọa độ được tính trong vùng “client”
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
■ wParam
■ trạng thái các phím chức năng và phím Mouse tại
thời điểm phát sinh message
MK_LBUTTON
MK_MBUTTON
MK_RBUTTON
MK_SHIFT
MK_CONTROL
// Left button is down
// Middle button is down
// Right button is down
// Shift key is down
// Ctrl key is down
190 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Xử lý Mouse trong Client-Area
case WM_LBUTTONDOWN:
if (wParam & MK_SHIFT)
{
if (wParam & MK_CONTROL)
{
[Shift and Ctrl keys are down]
}
else
{
[Shift key is down]
}
}
case WM_RBUTTONDOWN:
[right button logic]
return 0;
191 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Double Click
■ Windows chỉ gửi message “double-click”
■ Khi window có đăng ký nhận “double-click”
wndclass.style = CS_HREDRAW | CS_VREDRAW |
CS_DBLCLKS;
Có CS_DBLCLKS
Không có CS_DBLCLKS
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDBLCLK
WM_LBUTTONUP
WM_LBUTTONDOWN
WM_LBUTTONUP
192 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Non-client area mouse message
■ Khi mouse di chuyển trong vùng Non-
Client
■ Window sẽ nhận được WM_NCMOUSEMOVE.
■ lParam
■ tọa độ mouse tại thời điểm phát sinh message
■ tọa độ được tính trong toàn màn hình (screen)
■ wParam
■ Tương tự như wParam của các message “client”
193 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Client-Area mouse message
■ Khi mouse click trong vùng Non-Client
■ Window sẽ nhận được message
Pressed
Release
Pressed
WM_NCLBUTTONDOWN
WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK
WM_NCMBUTTONDOWN
WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK
WM_NCRBUTTONDOWN
WM_NCRBUTTONUP WM_NCRBUTTONDBLCLK
WM_NCLBUTTONDOWN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645620(v=vs.85).aspx
WM_NCLBUTTONUP: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645621(v=vs.85).aspx
WM_NCLBUTTONDBLCLK: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645619(v=vs.85).aspx
WM_NCRBUTTONDOWN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645629(v=vs.85).aspx
WM_NCRBUTTONUP: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645630(v=vs.85).aspx
WM_NCRBUTTONDBLCLK: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645628(v=vs.85).aspx
WM_NCMBUTTONDOWN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645623(v=vs.85).aspx
WM_NCMBUTTONUP: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645624(v=vs.85).aspx
WM_NCMBUTTONDBLCLK: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645622(v=vs.85).aspx
194 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Mouse wheel
■ Các thao tác trên Mouse wheel
■ Nhấn
■ Wheel
■ WM_MOUSEWHEEL
■ Được gửi khi wheel mouse trong vùng hiển thị của
window (Client và non-client)
■ Tham số lParam chứa tọa độ trên màn hình.
■ Tham số wParam chứa trạng thái các nút chức
năng và WHEEL_DATA.
WM_MOUSEWHEEL: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645617(v=vs.85).aspx
195 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
WHEEL_DATA
■ Tham số wParam
fwKeys = GET_KEYSTATE_WPARAM(wParam);
zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
■ WHEEL_DATA
■ Là đơn vị khi wheel, có giá trị là 120
■ zDelta
■ Số WHEEL_DATA mà người dùng wheel
■ zDelta > 0: up, zDelta < 0: down
196 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Capturing the Mouse
■ Window chỉ nhận được message mouse
■ Khi các thao tác mouse xảy ra trong vùng Client
và Non-Client
■ Window muốn nhận các message mouse khác?
197 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Capture và Release Mouse
■ Hàm SetCapture
HWND WINAPI SetCapture(
HWND hWnd
);
SetCapture: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646262(v=vs.85).aspx
■ Hàm ReleaseCapture
BOOL WINAPI ReleaseCapture(void);
ReleaseCapture: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646261(v=vs.85).aspx
198 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Không “capture mouse” (exe)
/*-----------------------------------------
BLOKOUT1.C -- Mouse Button Demo Program
(c) Charles Petzold, 1998
-----------------------------------------*/
#include
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("BlokOut1") ;
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 ;
199 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Capture mouse (exe)
/*---------------------------------------------------
BLOKOUT2.C -- Mouse Button & Capture Demo Program
(c) Charles Petzold, 1998
---------------------------------------------------*/
#include
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("BlokOut2") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
200
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 ;
Nguyễn Đạt Thông
Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
201 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Timer
■ Khái niệm Timer
■ Sử dụng Timer
202 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Timer
■ Timer là một loại input
■ Do Windows phát sinh, không phải từ user.
■ Phát sinh liên tục sau một khoảng thời gian nhất
định.
■ Ví dụ: “Windows, send me a message every 10
minutes”.
■ Message được Windows gửi đến
Program là WM_TIMER
■ Message WM_TIMER có độ ưu tiên thấp, chỉ được
gửi khi window đang “idle”
203 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ứng dụng của Timer
■ Timer được sử dụng trong Program
■ Hiển thị đồng hồ
■ Multitasking
■ Cập nhật trạng thái liên tục
■ Autosave
■ Demo – Trial time
■ Game – di chuyển đối tượng
■ Multimedia – chơi nhạc và phim
204 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thiết lập Timer
■ Hàm SetTimer
UINT_PTR WINAPI SetTimer(
HWND hWnd,
UINT_PTR nIDEvent,
UINT uElapse,
TIMERPROC lpTimerFunc
);
■ lpTimerFunc
■ Con trỏ đến một hàm có protocol TimerProc
■ Được gọi sau mỗi khoảng thời gian uEllapse (tính theo
milisecond)
SetTimer: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906(v=vs.85).aspx
TimerProc: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644907(v=vs.85).aspx
205 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ngừng Timer
■ Khi không muốn Windows gửi message
WM_TIMER nữa
BOOL WINAPI KillTimer(
HWND hWnd,
INT_PTR uIDEvent
);
KillTimer: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644903(v=vs.85).aspx
206 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
WM_TIMER
■ Message WM_TIMER
■ wParam: định danh của Timer
■ lParam: con trỏ đến hàm TimerProc được
truyền vào khi khởi tạo Timer
■ WM_TIMER được xử lý mặc định
■ Gọi hàm TimerProc được truyền vào khi khởi tạo
case WM_TIMER:
timerProc = (TimerProc)lParam;
if (timerProc != 0)
timerProc(hwnd, WM_TIMER, wParam, GetTickCount());
break;
WM_TIMER: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644902(v=vs.85).aspx
207 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Xử lý Timer
#define TIMER_SEC 1
#define TIMER_MIN 2
SetTimer (hwnd, TIMER_SEC, 1000, NULL) ;
SetTimer (hwnd, TIMER_MIN, 60000, NULL) ;
// ...
case WM_TIMER:
switch (wParam)
{
case TIMER_SEC:
[once-per-second processing]
break;
case TIMER_MIN:
[once-per-minute processing]
break;
}
return 0;
208 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Đổi màu theo thời gian (exe)
/*----------------------------------------
BEEPER2.C -- Timer Demo Program No. 2
(c) Charles Petzold, 1998
----------------------------------------*/
#include
#define ID_TIMER 1
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
VOID CALLBACK TimerProc (HWND, UINT, UINT, DWORD ) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Beeper2") ;
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) ;
209 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Đồng hồ điện tử (exe)
/*-----------------------------------------
DIGCLOCK.c -- Digital Clock
(c) Charles Petzold, 1998
-----------------------------------------*/
#include
#define ID_TIMER 1
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("DigClock") ;
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 ;
210 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
211 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Phần 3
Các thành phần
giao diện
Nguyễn Đạt Thông
www.ndthong.info
Nội dung
■ Các thành phần giao diện
■ Window con
■ Button
■ Một số thành phần giao diện
■ Menu và Resource
■ Dialog
■ Multiple-Document Interface (MDI)
213 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Window cha – con
■ Window cha – con
■ SendMessage
■ Standard và Owner-Draw
214 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Window cha – con
■ Một window có thể có các window “con”
■ Window này được coi là cha “cha”
■ Một window “con” có thể có các window
“con” khác.
■ “Desktop” là window cha của tất cả các
window khác (trực tiếp hoặc gián tiếp)
■ Window cha của “Desktop” là NULL.
215 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Window cha – con
■ Tạo window con với CreateWindow
HWND WINAPI CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
■ dwStyle: bao gồm WS_CHILD
■ hWndParent = NULL: window cha là “Desktop”
216 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Window cha – con
■ Truy vấn window cha với GetParent
HWND WINAPI GetParent(
HWND hWnd
);
GetParent: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633510(v=vs.85).aspx
■ Giao tiếp với window cha
SendMessage(hwndParent, message, wParam, lParam);
■ Window con sẽ giao tiếp (send message) với
window cha khi nó phát sinh sự kiện gì đó
217 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Standard và Owner-Draw
Standard là các
thành phần giao diện
chuẩn của Windows,
Owner-Draw là các
thành phần giao diện
được tùy biến bởi lập trình
viên.
- Owner-Draw control có giao
diện được vẽ bởi lập trình viên.
- Standard control có giao
diện theo chuẩn của
Windows.
Owner-Draw control giao tiếp với
window cha theo cách được
định nghĩa bởi lập trình viên.
- Standard control giao tiếp
với window cha theo chuẩn
của Windows.
218 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Button
■ Button chuẩn của Windows
■ Giao tiếp của các Button chuẩn
■ Các thao tác cơ bản trên Button
■ Push button, Check box, Radio button
■ Owner-Draw button
219 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Button chuẩn
■ Button chuẩn của Window
■ Có “win class” được đăng ký bởi Windows với tên
là “BUTTON”
// button text
// handle to parent window
// id of child window
CreateWindow(TEXT("button"),
szText,
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
x,
y,
width,
height,
hwndParent,
(HMENU) id,
hInstance,
NULL);
220 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Style của Button
■ Button chuẩn của Windows bao gồm
CheckBox
BS_CHECKBOX
Radio
BS_RADIOBUTTON
AutoCheck
BS_AUTOCHECKBOX
Button
BS_PUSHBUTTON
TriState
Owner-Draw
BS_3STATE
BS_OWNERDRAW
GroupBox
BS_GROUPBOX
221 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Các loại Button
222 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Giao tiếp của Button chuẩn
■ Button “chuẩn” giao tiếp với window cha
thông qua message WM_COMMAND
■ lParam: handle của button
■ LOWORD(wParam): định danh (ID) của button
■ HIWORD(wParam): mã xác định thông tin
Mã thông điệp
Mô tả
BN_CLICKED
Button được click
BN_DBLCLK
Button được double-click
BN_DOUBLECLICKED
BN_DISABLE
BN_KILLFOCUS
Button bị vô hiệu hóa
Button không còn focus
BN_SETFOCUS
Button nhận được focus
Button Message: http://msdn.microsoft.com/en-us/library/windows/desktop/bb775941(v=vs.85).aspx
223 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Giao tiếp của Button chuẩn
■ Window cha giao tiếp với Button “chuẩn”
thông qua cơ chế SendMessage
■ Các thao tác
■ Thực hiện Click lên button
■ Truy vấn trạng thái “check” của button
■ Vô hiệu hóa button
■ …
224 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác cơ bản trên Button
■ Ẩn – hiện button
ShowWindow(hwndChild, SW_SHOWNORMAL);
ShowWindow(hwndChild, SW_HIDE);
IsWindowVisible(hwndChild);
■ Vô hiệu hóa button
EnableWindow(hwndChild, FALSE);
EnableWindow(hwndChild, TRUE);
IsWindowEnabled(hwndChild);
225 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Push Button
■ Style của Push button
■ BS_PUSHBUTTON
■ BS_DEFPUSHBUTTON
■ Thao tác
// make button depressed
SendMessage(hwndButton, BM_SETSTATE, 1, 0);
// make button normal
SendMessage(hwndButton, BM_SETSTATE, 0, 0);
226 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Checkbox
■ Style của Checkbox
■ BS_CHECKBOX
■ BS_AUTOCHECKBOX
■ BS_3STATE
■ Thao tác
// make checkbox check manually when use BS_CHECKBOX
// 0: unchecked, 1: checked, 2: gray-checked
SendMessage(hwndButton, BM_SETCHECK, 1, 0);
// get the "check" of the checkbox
iCheck = (int)SendMessage(hwndButton, BM_GETSTATE,
0, 0);
227 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Radio button
■ Style của Radio button
■ BS_RADIOBUTTON
■ BS_AUTORADIOBUTTON
■ Thao tác
// make radio button check
SendMessage(hwndButton, BM_SETCHECK, 1, 0);
// get the "check" of the radio button
iCheck = (int)SendMessage(hwndButton, BM_GETSTATE,
0, 0);
228 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Group box
■ Style của Group box
■ BS_GROUPBOX
■ Group box không giao tiếp gì với
window cha
A Sample group box
229 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Owner-Draw button
■ Style của Owner-Draw button
■ BS_OWNERDRAW
230 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Các loại button (exe)
/*----------------------------------------
BTNLOOK.C -- Button Look Program
(c) Charles Petzold, 1998
----------------------------------------*/
#include
struct
{
int iStyle ;
TCHAR * szText ;
}
button[] =
{
BS_PUSHBUTTON, TEXT ("PUSHBUTTON"),
BS_DEFPUSHBUTTON, TEXT ("DEFPUSHBUTTON"),
BS_CHECKBOX, TEXT ("CHECKBOX"),
BS_AUTOCHECKBOX, TEXT ("AUTOCHECKBOX"),
BS_RADIOBUTTON, TEXT ("RADIOBUTTON"),
BS_3STATE, TEXT ("3STATE"),
BS_AUTO3STATE, TEXT ("AUTO3STATE"),
BS_GROUPBOX, TEXT ("GROUPBOX"),
BS_AUTORADIOBUTTON, TEXT ("AUTORADIO"),
BS_OWNERDRAW, TEXT ("OWNERDRAW")
} ;
#define NUM (sizeof button / sizeof button[0])
231 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Owner-Draw button (exe)
/*---------------------------------------------
OWNDRAW.C -- Owner-Draw Button Demo Program
(c) Charles Petzold, 1998
---------------------------------------------*/
#include
#define ID_SMALLER 1
#define ID_LARGER 2
#define BTN_WIDTH (8 * cxChar)
#define BTN_HEIGHT (4 * cyChar)
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
HINSTANCE hInst ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("OwnDraw") ;
MSG msg ;
HWND hwnd ;
WNDCLASS wndclass ;
hInst = hInstance ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
232 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
233 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Một số thành phần giao diện
■ Static Text
■ Edit box
■ List box
■ ScrollBar
234 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Static Text
■ Static Text của Windows
■ Có “win class” được đăng ký bởi Windows với tên
là “STATIC”
■ không xử lý các sự kiện bàn phím và mouse
■ không giao tiếp với window cha qua message
235 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Edit box
■ Edit box của Windows
■ Có “win class” được đăng ký bởi Windows với tên
là “EDIT”
■ Hỗ trợ xử lý các thao tác
■ Gõ chuỗi hoa – thường
■ Di chuyển “caret”, Del, Backspace, Home, End
■ Copy (Ctrl+C) và Paste (Ctrl+V)
Edit Control: http://msdn.microsoft.com/en-us/library/windows/desktop/bb775458(v=vs.85).aspx
236 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Style của Edit box
■ Window style
■ WS_CHILD
■ Edit box style
Mô tả
Style
ES_LEFT, ES_CENTER, ES_RIGHT Canh lề chuỗi được nhập
ES_LOWERCASE, ES_UPPERCASE
ES_NUMBER, ES_PASSWORD
ES_MULTILINE
ES_READONLY
Chuyển chuỗi hoa – thường
Xác định loại chuỗi nhập
Cho phép nhập nhiều dòng
Chỉ đọc, không thể nhập
Edit box style: http://msdn.microsoft.com/en-us/library/windows/desktop/bb775464(v=vs.85).aspx
237 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Giao tiếp của Edit box
■ Edit box giao tiếp với window cha thông
qua message WM_COMMAND
■ lParam: handle của edit box
■ LOWORD(wParam): định danh (ID) của edit box
■ HIWORD(wParam): mã xác định thông tin
Mã thông điệp
Mô tả
EN_CHANGE
EN_UPDATE
EN_SETFOCUS
EN_KILLFOCUS
Chuỗi nhập sẽ được thay đổi
Chuỗi nhập đã được thay đổi
Edit box được focus
Edit box mất focus
238 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác cơ bản trên Edit box
■ Thực hiện các thao tác trên Edit box
■ Sử dụng các hàm (macro)
■ Gửi message đến edit box
Macro
Message
Edit_GetText
Edit_GetTextLength
Edit_GetSel
EM_GETSEL
Edit_ReplaceSel
EM_REPLACESEL
Edit_LimitText
EM_LIMITTEXT
Edit_SetPasswordChar
EM_SETPASSWORDCHAR
Edit_SetReadOnly
EM_SETREADONLY
Edit_SetText
239 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cắt – dán trên Edit box
■ Thực hiện các thao tác trên Edit box
// cut current selected text
SendMessage(hwndEdit, WM_CUT, 0, 0);
// copy current selected text
SendMessage(hwndEdit, WM_COPY, 0, 0);
// clear (de-select) current selected text
SendMessage(hwndEdit, WM_CLEAR, 0, 0);
// paste clipboard text to the edit box
SendMessage(hwndEdit, WM_PASTE, 0, 0);
240 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
List box
■ List box của Windows
■ Có “win class” được đăng ký bởi Windows với tên
là “LISTBOX”
■ Hỗ trợ xử lý các thao tác
■ Hiển thị danh sách các item
■ Chọn 1 hoặc nhiều item trong danh sách
■ Highlight các item được chọn
■ Duyệt các item thông qua các phím di chuyển
List Box Control: http://msdn.microsoft.com/en-us/library/windows/desktop/bb775146(v=vs.85).aspx
241 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Style của List box
■ Window style
■ WS_CHILD
■ WS_BORDER
■ WS_VSCROLL
■ List box style
Style
LBS_NOTIFY
Mô tả
Giao tiếp với window cha bằng WM_COMMAND
LBS_SORT
LBS_MULTIPLESEL
Tự động sắp xếp các item
Cho phép chọn nhiều item
242 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Giao tiếp của List box
■ List box giao tiếp với window cha thông
qua message WM_COMMAND
■ lParam: handle của list box
■ LOWORD(wParam): định danh (ID) của list box
■ HIWORD(wParam): mã xác định thông tin
Mã thông điệp
Mô tả
LBN_SELCHANGE
LBN_DBLCLK
LBN_SELCANCEL
LBN_SETFOCUS
LBN_KILLFOCUS
Sự lựa chọn item có thay đổi
Double-click trên một item
Bỏ chọn tất cả item
List box được focus
List box mất focus
243 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác cơ bản trên List box
■ Thao tác trên danh sách của List box
■ Thêm một item vào danh sách
SendMessage(hwndList, LB_ADDSTRING,
0, (LPARAM) szItem);
■ Chèn một item vào danh sách
SendMessage(hwndList, LB_INSERTSTRING,
iIndex, (LPARAM) szItem);
■ Xóa một item khỏi danh sách
SendMessage(hwndList, LB_DELETESTRING, iIndex, 0);
244 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác cơ bản trên List box
■ Thao tác trên danh sách của List box
■ Xóa toàn bộ danh sách item
SendMessage(hwndList, LB_RESETCONTENT, 0, 0);
■ Vẽ lại List box khi danh sách thay đổi
■ Thêm hoặc xóa một item
■ Thêm hoặc xóa 1000 item?
// temporary stop update the display of List box
SendMessage(hwndList, WM_SETREDRAW, FALSE, 0);
// turn back
SendMessage(hwndList, WM_SETREDRAW, TRUE, 0);
245 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác cơ bản trên List box
■ Theo tác lựa chọn các item
■ Truy vấn số lượng item có trong List box
iCount = SendMessage(hwndList, LB_GETCOUNT, 0, 0);
■ Truy vấn chuỗi ký tự của một item
// get text length of an item
iLength = SendMessage(hwndList, LB_GETTEXTLEN,
iIndex, 0);
// get item text
iLength = SendMessage(hwndList, LB_GETTEXT,
iIndex, (LPARAM) szBuffer) ;
246 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác cơ bản trên List box
■ Thao tác lựa chọn các item
■ Truy vấn item đang được chọn
iIndex = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
■ Chọn một item
// iIndex = -1: deselect all items
SendMessage(hwndList, LB_SETCURSEL, iIndex, 0);
// select item which starts with a search string
iIndex = SendMessage(hwndList, LB_SELECTSTRING,
iIndex, (LPARAM) szSearchString) ;
247 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác cơ bản trên List box
■ Thao tác lựa chọn các item
■ Truy vấn một trong các item đang được chọn
iSelect = SendMessage(hwndList, LB_GETSEL,
iIndex, 0);
■ Chọn thêm một item
// select an item
SendMessage (hwndList, LB_SETSEL, TRUE, iIndex);
// de-select an item
SendMessage (hwndList, LB_SETSEL, FALSE, iIndex);
248 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Liệt kê biến môi trường (exe)
/*----------------------------------------
ENVIRON.C -- Environment List Box
(c) Charles Petzold, 1998
----------------------------------------*/
#include
#define ID_LIST 1
#define ID_TEXT 2
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Environ") ;
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) (COLOR_WINDOW + 1) ;
249 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
250 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Scrollbar
■ Window Scrollbar
■ Tích hợp vào window có style WS_VSCROLL hoặc
WS_HSCROLL
■ Không có handle riêng.
■ Thành phần giao diện Scrollbar
■ Có “win class” được đăng ký bởi Windows với tên
là “SCROLLBAR”
■ Có style là SBS_VERT hoặc SBS_HORZ
■ Là một thành phần giao diện, có handle riêng.
Scrollbar Control: http://msdn.microsoft.com/en-us/library/windows/desktop/bb787529(v=vs.85).aspx
251 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Window Scrollbar & Scrollbar
252 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Scrollbar
■ Scrollbar của Windows hỗ trợ xử lý
■ Các phím di chuyển Up, Down, Left, Right
■ Các phím Home, End, PageUp, PageDown
■ Giao tiếp với window cha
■ Thông qua message WM_VSCROLL và
WM_HSCROLL
■ lParam: handle của scrollbar (NULL: window scrollbar)
■ LOWORD(wParam): thông tin scroll
■ HIWORD(wParam): thông tin thêm về vị trí scroll
WM_HSCROLL: http://msdn.microsoft.com/en-us/library/windows/desktop/bb787575(v=vs.85).aspx
WM_VSCROLL: http://msdn.microsoft.com/en-us/library/windows/desktop/bb787577(v=vs.85).aspx
253 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Scrolling
254 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Giao tiếp với window cha
■ Message WM_VSCROLL và WM_HSCROLL
Thao tác
LOWORD(wParam)
HIWORD(wParam)
Scrolling
SB_LINEUP,
SB_LINELEFT,
SB_LINEDOWN,
SB_LINERIGHT
Page
scrolling
SB_PAGEUP,
SB_PAGEDOWN,
SB_PAGELEFT,
SB_PAGERIGHT
SB_ENDSCROLL
Stop
scrolling
Moving
thumb
SB_THUMBPOSITION,
SB_THUMBTRACK
Vị trí của thumb khi kết thúc
Vị trí hiện tại của thumb
255 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác cơ bản trên Scrollbar
■ Thao tác trên Scrollbar
■ Thiết lập giới hạn của scrollbar
// default range
iMin = 0, iMax = 100
// hwnd: handle of window
// set range for window scrollbar
SetScrollRange(hwnd, SB_VERT, iMin, iMax, bRedraw);
SetScrollRange(hwnd, SB_HORZ, iMin, iMax, bRedraw);
// hwndScroll: handle of scrollbar control
// set range for scrollbar control
SetScrollRange(hwndScroll, SB_CTL,
iMin, iMax, bRedraw);
SetScrollRange: http://msdn.microsoft.com/en-us/library/windows/desktop/bb787599(v=vs.85).aspx
256 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác cơ bản trên Scrollbar
■ Thao tác trên Scrollbar
■ Thiết lập vị trí hiện tại của scrollbar
// iPos: an integer value
// hwnd: handle of window
// set thumb position of window scrollbar
SetScrollPos(hwnd, SB_VERT, iPos, bRedraw);
SetScrollPos(hwnd, SB_HORZ, iPos, bRedraw);
// hwndScroll: handle of scrollbar control
// set thumb position of scrollbar control
SetScrollPos(hwndScroll, SB_CTL, iPos, bRedraw);
SetScrollPos: http://msdn.microsoft.com/en-us/library/windows/desktop/bb787597(v=vs.85).aspx
257 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác cơ bản trên Scrollbar
■ Thao tác scroll window
BOOL ScrollWindow(
HWND hWnd,
int XAmount,
int YAmount,
const RECT *lpRect,
const RECT *lpClipRect
);
■ Scroll client-area (hoặc một phần client-area) của
window, và đánh dấu các vùng “invalid”.
■ Phát sinh message WM_PAINT nếu xuất hiện vùng
“invalid”
ScrollWindow: http://msdn.microsoft.com/en-us/library/windows/desktop/bb787591(v=vs.85).aspx
ScrollWindowEx: http://msdn.microsoft.com/en-us/library/windows/desktop/bb787593(v=vs.85).aspx
258 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Window scrollbar (exe)
/*----------------------------------------------------
SYSMETS3.C -- System Metrics Display Program No. 3
(c) Charles Petzold, 1998
----------------------------------------------------*/
#define WINVER 0x0500
#include
#include "sysmets.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("SysMets3") ;
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 ;
259 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Scrollbar control (exe)
/*----------------------------------------
COLORS1.C -- Colors Using Scroll Bars
(c) Charles Petzold, 1998
----------------------------------------*/
#include
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK ScrollProc (HWND, UINT, WPARAM, LPARAM) ;
int idFocus ;
WNDPROC OldScroll[3] ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Colors1") ;
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) ;
260 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
261 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Menu và Resource
■ Resource
■ Menu
■ Keyboard Accelerators
262 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Resource
■ Resource là nơi lưu trữ
■ Hình ảnh icon
■ Hình ảnh cursor
■ Hình ảnh bitmap
■ Menu
■ Toolbar
■ Dialog
263 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tập tin Resource
■ Tập tin .rc
■ Mô tả từng thành phần resource
■ Tập tin .h
■ Định danh từng thành phần resource
■ Tập tin .RES
■ Các thành phần resource đã được biên dịch
■ Được sử dụng để liên kết với các tập tin object
264 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tạo một tập tin .rc
■ Trong Visual Studio
265 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thêm một Resource
■ Trong Resource View
266 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thêm một icon
■ Trong “icon editor”
267 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tập tin .rc
■ Chứa mô tả của icon
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
268 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tập tin .h
■ Chứa định danh của icon
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by myres.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
269 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Biên dịch tập tin Resource
■ Biên dịch bằng Visual Studio
■ Biên dịch bằng command line
270 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Menu
■ Thêm menu vào Resource bằng “Menu
editor”
Menus: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646977(v=vs.85).aspx
271 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tập tin Resource của Menu
■ Tập tin .rc
// Menu
MYMENU MENU
BEGIN
POPUP "&File"
BEGIN
ID_FILE_NEW40001
MENUITEM "&New...\tCtrl+N",
MENUITEM SEPARATOR
MENUITEM "E&xit\tAlt+X",
ID_FILE_EXIT
END
// ...
END
272 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tập tin Resource của Menu
■ Tập tin .h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by myres.rc
//
#define IDI_ICON1 101
#define ID_FILE_NEW40001 40001
#define ID_FILE_EXIT 40002
#define ID_VIEW_BASIC 40003
#define ID_VIEW_ADVANCED 40004
#define ID_ADVANCED_MOREADVANCED 40005
#define ID_ADVANCED_MOREMORE 40006
#define ID_MOREMORE_MOREMOREMORE 40007
273 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Sử dụng Menu
■ Gán Menu cho một window
■ Khi đăng ký window class hoặc CreateWindow
WNDCLASS wndclass ;
wndclass.lpszMenuName
= TEXT("MYMENU");
■ Khi khởi tạo window với LoadMenu và SetMenu
HMENU hMenu ;
switch (message)
{
case WM_CREATE:
hMenu = LoadMenu(hInst, TEXT("MYMENU"));
SetMenu(hwnd, hMenu);
return 0 ;
LoadMenu: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648002(v=vs.85).aspx
SetMenu: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647995(v=vs.85).aspx
274 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Giao tiếp của Menu
■ Menu giao tiếp với window cha thông
qua message WM_COMMAND
■ lParam: 0
■ LOWORD(wParam): định danh của menu item
■ HIWORD(wParam): 0
MENUITEM "E&xit",
ID_FILE_EXIT
#define ID_FILE_EXIT
40002
WM_MENUSELECT: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646352(v=vs.85).aspx
275 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Xử lý message Menu
■ Trong hàm WinProc
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_FILE_NEW40001:
return 0;
case ID_FILE_EXIT:
return 0;
case ID_VIEW_BASIC:
return 0;
case ID_ADVANCED_MOREADVANCED:
return 0;
}
276 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác trên Menu
■ Truy vấn Menu của một Window
HMENU WINAPI GetMenu(
HWND hWnd
);
GetMenu: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647640(v=vs.85).aspx
■ Truy vấn Menu con của một Menu
HMENU WINAPI GetSubMenu(
HMENU hMenu,
int nPos
);
GetSubMenu: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647984(v=vs.85).aspx
277 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác trên Menu
■ Truy vấn thông tin của một Menu item
BOOL WINAPI GetMenuItemInfo(
HMENU hMenu,
UINT uItem,
BOOL fByPosition,
LPMENUITEMINFO lpmii
);
■ fByPosition
■ TRUE: uItem là vị trí của menu item
■ FALSE: uItem là định danh của menu item
GetMenuItemInfo: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647980(v=vs.85).aspx
MENUITEMINFO: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647578(v=vs.85).aspx
278 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác trên Menu
■ Vô hiệu hóa một Menu item
BOOL WINAPI EnableMenuItem(
HMENU hMenu,
UINT uIDEnableItem,
UINT uEnable
);
■ uEnable bao gồm
■ MF_BYCOMMAND: uIDEnableItem là định danh
■ MF_BYPOSITION: uIDEnableItem là vị trí
■ MF_DISABLE: menu item không thể được chọn
■ MF_ENABLE: menu item có thể được chọn
■ MF_GRAY: menu item bị mờ và không thể được chọn
EnableMenuItem: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647636(v=vs.85).aspx
279 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác trên Menu
■ Đánh dấu (check) một Menu item
DWORD WINAPI CheckMenuItem(
HMENU hmenu,
UINT uIDCheckItem,
UINT uCheck
);
■ uCheck bao gồm
■ MF_BYCOMMAND: uIDCheckItem là định danh
■ MF_BYPOSITION: uIDCheckItem là vị trí
■ MF_CHECKED: đánh dấu menu item
■ MF_UNCHECKED: bỏ đánh dấu menu item
CheckMenuItem: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647619(v=vs.85).aspx
280 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thao tác trên Menu
■ Tạo menu bằng code (programmatically)
CreateMenu: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647624(v=vs.85).aspx
CreatePopupMenu: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647626(v=vs.85).aspx
TrackPopupMenu: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648002(v=vs.85).aspx
■ Thêm menu item
AppendMenu: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647616(v=vs.85).aspx
InsertMenu: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647987(v=vs.85).aspx
InsertMenuItem: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647988(v=vs.85).aspx
281 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Accelerator
■ Accelerator là các phím tắt để chọn
Menu item.
■ Tạo bảng accelerator
282 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tập tin Resource Accelerator
■ Tập tin .rc
/////////////////////////////////////////////////////
//
// Accelerator
//
MYACC ACCELERATORS
BEGIN
VIRTKEY, ALT, NOINVERT
"X",
"N",
VK_F1, ID_HELP,
ID_FILE_EXIT,
ID_FILE_NEW40001, VIRTKEY, CONTROL, NOINV
VIRTKEY, CONTROL, NOINV
END
283 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Sử dụng Accelerator
■ Hàm LoadAccelerators
HACCEL WINAPI LoadAccelerators(
HINSTANCE hInstance,
LPCTSTR lpTableName
);
■ lpTableName: tên của Accelerator table
■ Kết quả trả về là một HACCEL – handle của
Acclerator table
HACCEL hAcc = LoadAccelerators(hInstance, "MYACC");
LoadAccelerators: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646370(v=vs.85).aspx
284 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Sử dụng Accelerator
■ Hàm TranslateAccelerator
HACCEL hAcc = LoadAccelerators(hInstance, "MYACC");
while (GetMessage(&msg, NULL, 0, 0))
{
if (TranslateAccelerator(hwnd, hAcc, &msg) == 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
TranslateAccelerator: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648002(v=vs.85).aspx
285 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Giao tiếp của Accelerator
■ Accelerator giao tiếp với window cha
thông qua message WM_COMMAND
■ lParam: 0
■ LOWORD(wParam): định danh của menu item
■ HIWORD(wParam): 1
"X",
ID_FILE_EXIT,
VIRTKEY, ALT, NOINVERT
#define ID_FILE_EXIT
40002
286 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Xử lý message Accelerator
■ Trong hàm WinProc
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_FILE_EXIT:
if (HIWORD(wParam) == 1)
{
[process accelerator Alt-X]
}
else
{
[process menu item File -> Exit]
}
return 0;
}
287 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
288 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Dialog
■ Hộp thoại
■ Hộp thoại “Modal” và “Modeless”
■ Một số hộp thoại thông dụng
289 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hộp thoại Dialog
■ Hộp thoại Dialog được sử dụng để
■ Thu thập thêm thông tin input
■ Hiển thị thêm thông tin
■ Dialog cũng là một window
■ có hàm xử lý message gọi là “dialog procedure”
■ chứa các các thành phần giao diện để thu thập
thông tin
■ thường không xử lý các thao tác chuột và bàn
phím
290 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Dialog và Window
■ Dialog là “con” đặc biệt của một window
■ có thể nằm ngoài vùng “client-area” của window
cha
■ có thanh “caption”, “control buttons” riêng
■ không thể maximine / minimize
■ giao tiếp với window cha theo những cách thức
riêng biệt
291 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Modal và Modeless
Modeless Dialog
Modal Dialog
Mục đích: thu thập thông tin
đến đâu, xử lý trên window cha
đến đó.
Mục đích: thu thập đầy đủ
thông tin rồi mới thực hiện
thao tác trên window cha.
Đặc điểm: Cho phép xử lý thao
tác trên cả window cha và
dialog.
Đặc điểm: Không cho phép
xử lý thao tác trên window cha
nếu chưa đóng dialog.
292 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tạo một Dialog
293 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tạo một Dialog
294 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tập tin Resource của Dialog
■ Tập tin .rc
////////////////////////////////////////////////////
//
// Dialog
//
IDD_MYDIALOG DIALOGEX 0, 0, 289, 139
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS |
WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,177,118,50,14
PUSHBUTTON "Cancel",IDCANCEL,232,118,50,14
LTEXT "Password",IDC_STATIC,7,19,32,8
EDITTEXT IDC_EDIT2,43,16,137,14,ES_PASSWORD
| ES_AUTOHSCROLL
END
295 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Xử lý message trên Dialog
■ Hàm DlgProc
BOOL CALLBACK DlgProc(HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND :
switch (LOWORD (wParam)) {
case IDOK:
case IDCANCEL:
EndDialog(hDlg, 0);
return TRUE ;
}
break;
}
return FALSE ;
}
296 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hàm DlgProc
■ Phải được khai báo CALLBACK
■ Tương tự như WinProc, ngoại trừ
■ WinProc trả về LRESULT, DlgProc trả về BOOL
■ Nếu không xử lý message, WinProc gọi hàm
DefWindowProc trong khi DlgProc trả về FALSE
■ WinProc xử lý WM_CREATE trong khi DlgProc xử
lý WM_INITDIALOG
■ DlgProc không cần phải xử lý WM_PAINT và
WM_DESTROY
297 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hiển thị Modal Dialog
■ Hàm DialogBox
INT_PTR WINAPI DialogBox(
HINSTANCE hInstance,
LPCTSTR lpTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc
);
■ lpTemplate: tên template của Dialog. Ví dụ
“IDD_MYDIALOG”
■ Kết quả trả về cho biết kết quả của Dialog. Ví dụ:
Ok, Cancel, Abort, Retry, Ignore, …
DialogBox: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645452(v=vs.85).aspx
298 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Kết thúc Modal Dialog
■ Hàm EndDialog
BOOL WINAPI EndDialog(
HWND hDlg,
INT_PTR nResult
);
■ nResult: Thiết lập kết quả của Dialog.
■ Các kết quả thông thường
■ IDOK, IDCANCEL,
■ IDABORT, IDRETRY, IDIGNORE, IDCONTINUE,
■ IDYES, IDNO
EndDialog: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645472(v=vs.85).aspx
299 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tạo Modeless Dialog
■ Hàm CreateDialog
HWND WINAPI CreateDialog(
HINSTANCE hInstance,
LPCTSTR lpTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc
);
■ lpTemplate: tên template của Dialog. Ví dụ
“IDD_MYDIALOG”
■ Kết quả trả về là “handle” của Dialog, sử dụng
hàm ShowWindow để hiển thị Dialog.
CreateDialog: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645434(v=vs.85).aspx
300 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tab Stop
■ Khi nhấn Tab trên Dialog
■ “Focus” sẽ được lần lượt chuyển từ thành phần
này sang thành phần khác.
■ Chỉ những thành phần có WS_TABSTOP mới được
nhận “Focus” bởi việc nhấn Tab.
■ LTEXT, CTECT, RTEXT, và ICON
■ Không có WS_TABSTOP
■ Thường được đặt cuối cùng
301 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Modal Dialog (exe)
/*------------------------------------------
ABOUT2.C -- About Box Demo Program No. 2
(c) Charles Petzold, 1998
------------------------------------------*/
#include
#include "resource.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;
int iCurrentColor = IDC_BLACK,
iCurrentFigure = IDC_RECT ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("About2") ;
MSG msg ;
HWND hwnd ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance, szAppName) ;
302 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ Modeless Dialog (exe)
/*------------------------------------------------
COLORS2.C -- Version using Modeless Dialog Box
(c) Charles Petzold, 1998
------------------------------------------------*/
#include
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
BOOL CALLBACK ColorScrDlg (HWND, UINT, WPARAM, LPARAM) ;
HWND hDlgModeless ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Colors2") ;
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 = CreateSolidBrush (0L) ;
303 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
304 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Một số Dialog thông dụng
■ Message Box
■ File Dialog
■ Color Chooser Dialog
■ Font Chooser Dialog
■ Find & Replace Dialog
305 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Dialog: Open và Save file
■ Hàm GetOpenFileName và
GetSaveFileName
BOOL WINAPI GetOpenFileName( // GetSaveFileName
LPOPENFILENAME lpofn
);
■ Modal dialog
■ Trả về kết quả >0 nếu chọn “OK”
■ Yêu cầu
■ COMMDLG.H (có sẵn trong WINDOWS.H)
■ COMMDLG.LIB, COMMDLG.DLL
GetOpenFileName: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646927(v=vs.85).aspx
GetSaveFileName: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646928(v=vs.85).aspx
306 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cấu trúc OPENFILENAME
■ Các thành phần chính
Khai báo
Mô tả
DWORD lStructSize
phải được thiết lập bởi
sizeof(OPENFILENAME)
HWND hwndOwner
LPCTSTR lpstrFilter
Handle của window cha
Chuỗi filer, phải kết thúc bởi \0
LPTSTR lpstrFile
DWORD nMaxFile
LPCTSTR lpstrDefExt
LPCTSTR lpstrInitDir
LPCTSTR lpstrTitle
DWORD Flags
Chuỗi chứa full-path của tập tin
Chiều dài tối đa của full-path
Phần mở rộng mặc định
Thư mục khởi đầu khi mở File Dialog
Tiều đề của File Dialog
Các tùy chọn của File Dialog
OPENFILENAME: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx
307 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cấu trúc OPENFILENAME
■ Tùy chọn Flags
Mô tả
Tùy chọn
OFN_ALLOWMULTISELECT Cho phép chọn nhiều tập tin
OFN_CREATEPROMPT
OFN_DONTADDTORECENT
Nếu chọn một tập tin chưa có, File Dialog
sẽ hiện thông báo xác nhận
Không đưa tập tin được chọn vào “Recent
Files”
OFN_ENABLESIZING
OFN_EXPLORER
OFN_FILEMUSTEXIST
OFN_HIDEREADONLY
Cho phép thay đổi kích thước File Dialog
Sử dụng “style” của Windows Explorer
Chỉ có thể chọn file đã tồn tại
Ẩn các file có thuộc tính “read-only”
...
308 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ: File Dialog
OPENFILENAME ofn;
char szFileName[MAX_PATH] = "";
ZeroMemory(&ofn, sizeof(ofn));
= hwnd;
= szFileName;
= MAX_PATH;
= OFN_EXPLORER | OFN_FILEMUSTEXIST;
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner
ofn.lpstrFilter = "Text Files\0*.txt\0All Files\0*.*\0";
ofn.lpstrFile
ofn.nMaxFile
ofn.Flags
ofn.lpstrDefExt = "txt";
if (GetOpenFileName(&ofn))
{
// Do something with the filename in szFileName
}
309 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ: File Dialog
310 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Dialog: Color chooser
■ Hàm ChooseColor
BOOL WINAPI ChooseColor(
LPCHOOSECOLOR lpcc
);
■ Modal dialog
■ Trả về kết quả >0 nếu chọn “OK”
■ Yêu cầu
■ COMMDLG.H (có sẵn trong WINDOWS.H)
■ COMMDLG.LIB, COMMDLG.DLL
ChooseColor: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646912(v=vs.85).aspx
311 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cấu trúc CHOOSECOLOR
■ Các thành phần chính
Khai báo
Mô tả
DWORD lStructSize
phải được thiết lập bởi
sizeof(CHOOSECOLOR)
HWND hwndOwner
COLORREF rgbResult
Handle của window cha
Giá trị màu được chọn
COLORREF *lpCustColors Danh sách 16 màu tùy chọn
DWORD Flags
Các tùy chọn của Color Chooser Dialog
■ Tùy chọn Flags
Tùy chọn
Mô tả
CC_FULLOPEN
CC_RGBINIT
Mở tất cả chức năng của Color Chooser
Sử dụng rgbResult làm màu ban đầu
CHOOSECOLOR: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646830(v=vs.85).aspx
312 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ: Color chooser Dialog
// common dialog box structure
// owner window
CHOOSECOLOR cc;
COLORREF acrCustClr[16]; // array of custom colors
HWND hwnd;
DWORD rgbCurrent = 0; // initial color selection
// Initialize CHOOSECOLOR
ZeroMemory(&cc, sizeof(cc));
cc.lStructSize = sizeof(cc);
cc.hwndOwner = hwnd;
cc.lpCustColors = (LPDWORD)acrCustClr;
cc.rgbResult = rgbCurrent;
cc.Flags = CC_FULLOPEN | CC_RGBINIT;
if (ChooseColor(&cc)==TRUE)
{
rgbCurrent = cc.rgbResult;
// Process current selected color here
}
313 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ: Color chooser Dialog
314 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Dialog: Font chooser
■ Hàm ChooseFont
BOOL WINAPI ChooseFont(
LPCHOOSEFONT lpcf
);
■ Modal dialog
■ Trả về kết quả TRUE nếu chọn “OK”
■ Yêu cầu
■ COMMDLG.H (có sẵn trong WINDOWS.H)
■ COMMDLG.LIB, COMMDLG.DLL
ChooseFont: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646914(v=vs.85).aspx
315 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cấu trúc CHOOSEFONT
■ Các thành phần chính
Khai báo
Mô tả
DWORD lStructSize
phải được thiết lập bởi
sizeof(CHOOSEFONT)
HWND hwndOwner
LPLOGFONT lpLogFont
COLORREF rgbResult
Handle của window cha
Giá trị font được chọn
Giá trị màu được chọn
LPTSTR lpszStyle
INT iPointSize
WORD nFontType
Giá trị style (kết hợp các lựa chọn)
Font size được chọn
Font type được chọn, bao gồm:
BOLD_FONTTYPE, ITALIC_FONTTYPE,
REGULAR_FONTTYPE
DWORD Flags
Các tùy chọn của Font Chooser Dialog
CHOOSEFONT: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646832(v=vs.85).aspx
316 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ: Font chooser Dialog
CHOOSEFONT cf; // common dialog box structure
static LOGFONT lf; // logical font structure
static DWORD rgbCurrent; // current text color
HFONT hfont;
// Initialize CHOOSEFONT
ZeroMemory(&cf, sizeof(cf));
cf.lStructSize = sizeof (cf);
cf.hwndOwner = hwnd;
cf.lpLogFont = &lf;
cf.rgbColors = rgbCurrent;
cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
if (ChooseFont(&cf)==TRUE)
{
hfont = CreateFontIndirect(cf.lpLogFont);
// ...
}
317 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ: Font chooser Dialog
318 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Dialog: Find & Replace
■ Hàm FindText và ReplaceText
// ReplaceText
HWND WINAPI FindText(
LPFINDREPLACE lpfr
);
■ Modeless dialog
■ Trả về kết quả là “handle” của dialog
■ Yêu cầu
■ COMMDLG.H (có sẵn trong WINDOWS.H)
■ COMMDLG.LIB, COMMDLG.DLL
FindText: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646918(v=vs.85).aspx
ReplaceText: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646946(v=vs.85).aspx
319 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cấu trúc FINDREPLACE
■ Các thành phần chính
Mô tả
Khai báo
DWORD lStructSize
phải được thiết lập bởi
sizeof(FINDREPLACE)
HWND hwndOwner
LPTSTR lpstrFindWhat
Handle của window cha
Chuỗi cần tìm
WORD wFindWhatLen
Độ dài chuỗi cần tìm
LPTSTR lpstrReplaceWith Chuỗi cần thay thế
WORD wReplaceWithLen
DWORD Flags
Độ dài chuỗi cần thay thế
Các tùy chọn của Find & Replace
Dialog
FINDREPLACE: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646835(v=vs.85).aspx
320 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Cấu trúc FINDREPLACE
■ Tùy chọn Flags
Tùy chọn
Mô tả
FR_DOWN
Chọn “Down”, nếu không có sẽ chọn “Up”
FR_HIDEUPDOWN
FR_NOMATCHCASE
FR_HIDEMATCHCASE
Ẩn lựa chọn tìm kiếm “Up/Down”
Không chọn “Match case”
Ẩn lựa chọn tìm kiếm “Match case”
FR_NOWHOLEWORD
FR_HIDEWHOLEWORD
FR_FINDNEXT
FR_REPLACE
FR_REPLACEALL
Không chọn “Whole word”
Ẩn lựa chọn tìm kiếm “Whole word”
Cho biết người dụng chọn “Find Next”
Cho biết người dùng chọn “Replace”
Cho biết người dùng chọn “Replace All”
...
321 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Message FINDMSGSTRING
■ Message FINDMSGSTRING
■ Được gửi khi người sử dụng nhấn “Find Next”,
“Replace”, hoặc “Replace All”
// message identifier for FINDMSGSTRING
UINT uFindReplaceMsg =
RegisterWindowMessage(FINDMSGSTRING);
■ wParam: không sử dụng
■ lParam: pointer đến cấu trúc FINDREPLACE
■ Cho biết thông tin trạng thái hộp thoại
FINDMSGSTRING: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646872(v=vs.85).aspx
322 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ: Find & Replace
FINDREPLACE fr; // common dialog box structure
HWND hwnd; // owner window
CHAR szFindWhat[80]; // buffer receiving string
CHAR szReplaceWith[80];// buffer receiving string
HWND hdlg = NULL; // handle to Find dialog box
// Initialize FINDREPLACE
ZeroMemory(&fr, sizeof(fr));
fr.lStructSize = sizeof(fr);
fr.hwndOwner = hwnd;
fr.lpstrFindWhat = szFindWhat;
fr.wFindWhatLen = 80;
fr.lpstrReplaceWith = szReplaceWith;
fr.wReplaceWithLen = 80;
fr.Flags = 0;
hdlg = ReplaceText(&fr); // FindText(&fr);
ShowWindow(hdlg, SW_SHOW);
323 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ: Find & Replace
default:
if (message == uFindReplaceMsg)
{
LPFINDREPLACE lpFindMsg = (LPFINDREPLACE)lParam;
TCHAR msg[1024];
_stprintf(msg, TEXT("Find what: %s"),
lpFindMsg->lpstrFindWhat);
if (lpFindMsg->Flags & FR_FINDNEXT)
MessageBox(NULL, msg,
TEXT("Click: Find"), MB_ICONASTERISK);
else if (lpFindMsg->Flags & FR_REPLACE)
MessageBox (NULL, msg,
TEXT("Click: Replace"), MB_ICONASTERISK);
else if (lpFindMsg->Flags & FR_REPLACEALL)
MessageBox (NULL, msg,
TEXT("Click: Repl. All"), MB_ICONASTERISK);
}
}
324 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ: Find & Replace
325 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Dialog: Print
■ Hàm FindText và ReplaceText
HWND WINAPI PrintDlg(
LPPRINTDLG lppd
);
■ Modeless dialog
■ Trả về kết quả là “handle” của dialog
■ Yêu cầu
■ COMMDLG.H (có sẵn trong WINDOWS.H)
■ COMMDLG.LIB, COMMDLG.DLL
FindText: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646918(v=vs.85).aspx
ReplaceText: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646946(v=vs.85).aspx
326 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Đọc thêm
■ Print Dialog
PrintDlg: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646940(v=vs.85).aspx
PrintDlgEx: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646942(v=vs.85).aspx
PageSetupDlg: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646937(v=vs.85).aspx
■ Sử dụng các loại hộp thoại thông dụng
Using Common Dialog Boxes
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646829(v=vs.85).aspx
327 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
328 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Multi-Document Interface
■ MDI
■ Các thành phần của MDI
■ Ví dụ
329 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
MDI
■ Multiple-Document Interface (MDI)
■ Là ứng dụng Windows xử lý nhiều tài liệu trong
cùng một window.
■ Trong MDI
■ Mỗi tài liệu được hiển thị trong một window con
■ Các window con có thể minimize, maximize trong
phạm vi của window cha
330 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Các thành phần của MDI
■ Window chính
■ Có title bar, menu, icon, và các nút điều khiển
■ Có vùng client area gọi là “workspace”
■ Không được sử dụng để hiển thị nội dung window
■ Được sử dụng để chứa các document window
■ Document window
■ Có title bar, icon, scrollbar và các nút điều khiển
■ Không có menu
■ Có vùng client area để hiển thị tài liệu
331 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Nguyên tắc hoạt động của MDI
■ Tất cả các document window được “clip”
trong vung workspace của window chính
■ Tại mỗi thời điểm, chỉ có duy nhất một
document window là “active”
332 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Nguyên tắc hoạt động của MDI
333 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Nguyên tắc hoạt động của MDI
■ Các document window
334 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Ví dụ
■ MDI Application (exe)
/*--------------------------------------------------------
MDIDEMO.C -- Multiple-Document Interface Demonstration
(c) Charles Petzold, 1998
--------------------------------------------------------*/
#include
#include "resource.h"
#define INIT_MENU_POS 0
#define HELLO_MENU_POS 2
#define RECT_MENU_POS 1
#define IDM_FIRSTCHILD 50000
LRESULT CALLBACK FrameWndProc (HWND, UINT, WPARAM, LPARAM) ;
BOOL CALLBACK CloseEnumProc (HWND, LPARAM) ;
LRESULT CALLBACK HelloWndProc (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK RectWndProc (HWND, UINT, WPARAM, LPARAM) ;
// structure for storing data unique to each Hello child window
typedef struct tagHELLODATA
{
UINT iColor ;
COLORREF clrText ;
}
HELLODATA, * PHELLODATA ;
335 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Notes
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
…………………………………………………
336 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Phần 4
Các tiện ích trên
Windows
Nguyễn Đạt Thông
www.ndthong.info
Nội dung
■ Các tiện ích trên Windows
■ Clipboard
■ Tập tin và thư mục
■ Biến môi trường
■ Registry
■ Sound và Music
338 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Clipboard
■ Text và Clipboard
■ Đối tượng và Clipboard
339 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Tập tin và thư mục
■ Thao tác trên thư mục
■ Tạo tập tin
■ Đọc và ghi tập tin
340 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Biến môi trường
■ Working Directory
■ Các biến môi trường của Windows
■ Thiết lập biến môi trường
341 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Registry
■ Cấu trúc Registry
■ Truy vấn Registry
■ Lưu trữ thông tin trong Registry
342 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Sound và Music
■ Chơi nhạc
■ WAVE audio
■ MIDI và Music
343 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Phần 5
Các chủ đề
nâng cao
Nguyễn Đạt Thông
www.ndthong.info
Nội dung
■ Các chủ đề nâng cao
■ Thư viện DLL
■ Đa luồng (Multithreading)
■ Kết nối mạng (Networking)
■ Hooking
■ Serial Port
■ MFC – Microsoft Foundation Classes
345 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Nội dung
Hooking
Threading
Synchroni-
zation
Networking
346 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Thư viện DLL
■ DLL
■ Thư viện chuẩn của Windows
■ Tạo thư viện
■ Liên kết và sử dụng thư viện
■ Static load và Dynamic load
347 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Đa luồng
■ Khái niệm
■ Chia sẻ tài nguyên
■ Đồng bộ hóa
348 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Kết nối mạng
■ IP và Port
■ Kết nối TCP và UDP
■ Gửi và nhận dữ liệu
■ Blocking và Non-Blocking
349 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Hooking
■ Khái niệm Hooking
■ Các loại hình Hooking
■ “Hot Keys” và “Key logger”
350 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Serial Port
■ Cổng COM và USB
■ Giao tiếp qua cổng Serial
■ Đọc và ghi dữ liệu
351 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
MFC
352 Nguyễn Đạt Thông Lập trình C trên Windows - 2013
Nguyễn Đạt Thông
www.ndthong.info