int WINAPI WinMainHINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow... B ướ c 1: entry point#include LRESULT CALLBACK WndProcHWND, UINT, WPARAM, LPARAM; int WIN
Trang 1Nguyễn Đạt Thông
Windows
Trang 3M ụ 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,
Trang 4Yê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, …
Trang 6Tà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
■ L ậ p trình C trên Windows, Th ư vi ệ n đ i ệ n t ử khoa
h ọ c công ngh ệ , V ĩ nh Long (Link)
Trang 8………
………
………
………
………
………
………
………
………
………
………
Trang 11Ch ươ 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
Trang 13int WINAPI WinMain(
HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
Trang 14T ậ 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,
Trang 15Program Entry Point
■ Hàm WinMain()
■ Trong đ ó
■ WINAPI – stdcall
■ HINSTANCE – instance handle
■ PSTR – pointer to character string
int WINAPI WinMain(
HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine,
int iCmdShow)
Trang 17Tùy ch ỉ nh Message Box
Trang 18………
………
………
………
………
………
………
………
………
………
………
Trang 20MS Visual Studio 2008
■ T ạ o solution và project
Trang 21MS Visual Studio 2008
■ T ạ o solution và project
Trang 22MS Visual Studio 2008
■ T ạ o solution và project
Trang 23MS Visual Studio 2008
■ Thêm t ậ p tin mã ngu ồ n vào project
Trang 24MS 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”
Trang 26MessageBox trong Studio
■ Ch ạ y ch ươ ng trình HelloMsg t ừ VS2008
■ T ạ i sao?
Trang 27Windows 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
Trang 28Char và Wide char
char a[] = "Hello!";
typedef unsigned short wchar_t;
wchar_t c = 'A';
wchar_t *p = L"Hello!";
wchar_t a[] = L"Hello!";
wchar_t c2 = L'A';
Trang 30Vi ế t code cho Unicode
■ “Define” m ộ t macro chung
■ S ử d ụ ng macro
typedef char TCHAR;
#define _tcslen strlen
#define T(x) x
typedef wchar_t TCHAR;
#define _tcslen wcslen
#define T(x) L##x
TCHAR *p = T("Hello”);
int iLength = _tcslen(p);
Trang 31■ Đị nh danh UNICODE
■ Đ ã đượ c khai báo trong WINNT.H
#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)
Trang 32Visual Studio và UNICODE
■ M ặ c đị nh MS Visual Studio khai báo
đị nh danh UNICODE
Trang 33HelloMsg h ỗ tr ợ UNICODE
■ Mã ngu ồ n c ủ a HelloMsg.c
#include <windows.h>
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;
}
Trang 35L ậ p trình Windows
■ Synchronous và Asynchronous
■ Callbacks
■ L ậ p trình Windows
Trang 39Don't Call Me, I'll Call You
Trang 40Windows 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,
Trang 41■ 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
Trang 42■ 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?
Trang 43Message 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
Trang 44Send 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…
Trang 45Get 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?
Trang 46C ử a s ổ window
Trang 47L ậ p trình Windows
■ Hi ể n th ị window và các child window
■ Program hay Windows?
Trang 52“Hello World 2” – Step-by-Step
Trang 53B ướ c 1: entry point
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(
HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
Trang 54B ướ c 2: window class
Trang 55B ướ c 3a: WinProc()
LRESULT CALLBACK WinProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam) {
Trang 56B ướ c 3b: V ẽ chu ỗ i
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam) {
DT_SINGLELINE | DT_CENTER | DT_VCENTER); EndPaint (hwnd, &ps);
return 0;
//
}
Trang 57B ướ c 4: t ạ o window
int WINAPI WinMain(
HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow) {
// HWND hwnd;
TEXT("Hello World 2"), // window caption
ShowWindow (hwnd, iCmdShow);
UpdateWindow(hwnd);
//
}
Trang 58“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
Trang 60■ Vi ế t hoa các ch ữ đầ u, không kho ả ng cách
■ szCmdLine , hPrevInstance , wParam , …
Trang 61Ti ề n t ố
Ti ề n t ố Ý ngh ĩ a
c char – ký tự
by byte – số nguyên không âm có độ dài 8 bit
n short – số nguyên có độ dài 16 bit
i int – số nguyên có độ dài 32 bit
x, y int – tọa độ Descartes
cx, cy int – tọa độ Descartes (hằng số)
b hoặc f BOOL – cờ, có giá trị đúng/sai
w WORD – số nguyên không âm có độ dài 16 bit
l LONG – số nguyên có độ dài 32 bit
dw DWORD – số nguyên không âm có độ dài 32 bit
fn Hàm, phương thức
sz Chuỗi ký tự
h handle
Trang 62Ki ể u d ữ li ệ u c ơ b ả n
Ki ể u d ữ li ệ u Ý ngh ĩ a
HANDLE Số nguyên 32 – bit, định danh
HWND Số nguyên 32 – bit, định danh
BYTE Giá trị 8 – bit không dấu
WORD Số nguyên 16 – bit không dấu
UINT Số nguyên 32 – bit không dấu
LONG Long 32 – bit
Trang 64■ Truy v ấ n window cha – GetParent
■ Truy v ấ n kích th ướ c window – a
Trang 65int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu,
HINSTANCE hInstance, LPVOID lpParam
);
Trang 67BOOL InvalidateRect(
HWND hWnd, const RECT *lpRect, BOOL bErase
);
Trang 68Truy v ấ n window cha
HWND WINAPI GetDesktopWindow(void);
Trang 69Truy v ấ n kích th ướ c window
BOOL WINAPI GetClientRect(
HWND hWnd, LPRECT lpRect );
Trang 70int Y, int nWidth, int nHeight, BOOL bRepaint );
Trang 71VOID WINAPI PostQuitMessage(
int nExitCode );
Trang 72Message 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
Trang 76Translate Message
■ X ử lý message
■ GetMessage : nh ậ n message t ừ Windows
■ TranslateMessage : chuy ể n đổ i các message t ừ
Trang 77Mô hình x ử lý message
Trang 78Window 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()
Trang 79Hàm WinProc()
■ Hàm WinProc() là m ộ t Callback
■ Đượ 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
LRESULT CALLBACK WinProc(
HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
Trang 80Message: cho bi ế t lo ạ i thao tác
Trang 82Drawing và Device Context
Trang 83■ 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
Trang 85C ậ p nh ậ t window
đ ó.
Yêu c ầ u v ẽ l ạ i
G ử i message WM_PAINT yêu c ầ u window v ẽ l ạ i.
Trang 86Tr ở 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?
Trang 89Device 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 ị
Trang 91■ C ấ u trúc 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 ệ )
Trang 92■ rcPaint trong PAINTSTRUCT
Trang 93GetDC và ReleaseDC
■ Hàm GetDC() và ReleaseDC()
■ 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
Trang 94Client 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.
Trang 95■ Truy v ấ n DC ứ ng v ớ i toàn b ộ window
■ Sau khi v ẽ xong, ph ả i g ọ i hàm ReleaseDC
■ N ế u tham s ố hWnd là NULL , GetWindowDC s ẽ tr ả
Trang 96■ Message WM_NCPAINT đượ c g ử i khi
Windows yêu c ầ u Program v ẽ “
WM_NCPAINT Message: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145137(v=vs.85).aspx
Trang 100T ọ a độ t ươ ng đố i
■ Relative position là t ọ a độ v ị trí c ủ a
window so v ớ i window cha.
Trang 101Chuy ể n đổ i t ọ a độ
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
Trang 103);
Trang 104LPRECT lpRect, UINT uFormat );
Trang 105COLORREF GetTextColor(
HDC hdc );
Trang 106int SetBkMode(
HDC hdc, int iBkMode );
Trang 107DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet, DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality,
DWORD fdwPitchAndFamily,
);
Trang 108Font 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
Trang 110Xóa font ch ữ
■ 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
BOOL DeleteFont(
HFONT hfont );
Trang 114BOOL LineTo(
HDC hdc, int nXEnd, int nYEnd );
Trang 115Hình d ạ ng c ủ a đườ ng
Trang 116COLORREF crColor );
Trang 117Bú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
Trang 119Xóa bút v ẽ
■ Hàm DeleteObject
■ 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
BOOL DeleteObject(
HGDIOBJ hObject );
Trang 123Bút tô – Brush
■ Hàm Create Xxxxx Brush 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
Trang 124Thay đổ i và xóa bút tô
■ 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
Trang 127LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
Trang 128
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
Trang 129
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
Trang 133BOOL FillPath(
HDC hdc );
BOOL StrokeAndFillPath(
HDC hdc );
Trang 134■ 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
Trang 137V ẽ và tô màu Region
BOOL FillRgn(
HDC hdc, HRGN hrgn, HBRUSH hbr );
Trang 139Hit Test Region
int Y );
Trang 141View Port
■ Các h ệ t ọ a độ
■ Clipping
Trang 142Cá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.
Trang 143Các h ệ t ọ a độ
Trang 144Di chuy ể n g ố c t ọ a độ ViewPort
Trang 147Clipping
Trang 149Thay đổ i Clipping Region
Trang 155■ Thông qua hàm “ TranslateMsg ”
■ G ử i message “keystroke” ho ặ c message
“command” đế n window
Trang 157Keystroke 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?
Trang 158Keystroke 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
Trang 162X ử lý các message keystroke
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
Trang 165Tham s ố lParam
■ Tham s ố lParam ch ứ a các thông tin
Trang 166Cá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.
Trang 167■ 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
SHORT WINAPI GetKeyState(
int nVirtKey );
Trang 170Tham s ố wParam
■ wParam cho bi ế t ký t ự đượ c nh ấ n
■ 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
Trang 171Tham s ố lParam
■ Tham s ố lParam ch ứ a các thông tin
Trang 172Th ứ t ự message
■ Khi nh ấ n phím ‘A’
■ Khi nh ấ n Shift + ‘A’
Trang 173Th ứ t ự message
■ Khi nh ấ n và gi ữ phím ‘A’
■ Trong các c ặ p WM_KEYDOWN và WM_CHAR
■ Có th ể có “Repeat Count” l ớ n h ơ n 1.