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