Tìm hiểu lập trình API trong window
ĐẠI HỌC BÁCH KHOA HÀ NỘI Khoa Công Nghệ Thông Tin BÁO CÁO BÀI TẬP LỚN MÔN HỆ ĐIỀU HÀNH Đề tài : Tìm hiểu lập trình API window Giáo viên hướng dẫn : Nhóm Mục lục Mục lục .2 I.MỞ ĐẦU: II, SƠ BỘ WINDOW API, CÁCH THỨC LÀM VIỆC Các thư viện lập trình Windows SDK – Software Development Kit: Các khái niệm bản: .4 Các thành phần giao diện đồ họa (GUI – Graphics User Interface) 4 Qui trình hoạt động chương trình ứng dụng: 5 Ví dụ III, MỘT SỐ THÀNH PHẦN CƠ BẢN .11 Tài nguyên ứng dụng (Resources) .11 Một số kiểu liệu mới: 12 Một số hàm đồ họa sở: .14 4.HỘP THOẠI VÀ ĐIỀU KHIỂN 16 IV.Kết luận 20 I.MỞ ĐẦU: Các ứng dụng Windows dễ sử dụng, khó người tạo lập chúng Để đạt tính dễ dùng đòi hỏi người lập trình phải bỏ nhiều công sức để cài đặt Lập trình Windows khó phức tạp nhiều so với lập trình DOS Tuy nhiên lập trình Windows giải số vấn đề khó khăn môi trường DOS xây dựng giao diện người dùng, quản lý nhớ ảo, độc lập thiết bị vào ra, thâm nhập Internet, khả chia sẻ tài nguyên, Windows cung cấp hàm để người lập trình thâm nhập đặc trưng hệ điều hành gọi giao diện lập trình ứng dụng (Application Programming Interface – API) Những hàm đặt thư viện liên kết động (Dynamic Link Library – DLL) Các chương trình ứng dụng sử dụng chúng thông qua lời gọi hàm chia sẻ máy có cài đặt Windows II, SƠ BỘ WINDOW API, CÁCH THỨC LÀM VIỆC Các thư viện lập trình Windows SDK – Software Development Kit: - Là thư viện lập trình tảng HĐH Windows - Cung cấp tất công cụ cần thiết để xây dựng ứng dụng Windows - Được sử dụng thư viện sở để tạo thư viện cao cấp ngôn ngữ lập trình VD: OWL BorlandC, MFC Visual C++,… - Một số thành phần SDK: • Win32 API • GDI/GDI+ • Windows Multimedia • OpenGL • DirectX • COM/COM+ • ADO (ActiveX Data Object) • OLE DB •… Các khái niệm bản: Message: Trao đổi thông tin chương trình ứng dụng hệ điều hành Thủ tục Window: Được gọi hệ thống để xử lý Message nhận Hàng đợi Message: Mỗi chương trình có hàng đợi Message để chứa Message Mỗi chương trình có vòng lặp Message Handle: Một giá trị 32 bits không dấu (unsigned) HĐH tạo để làm định danh cho đối tượng (cửa sổ, file, vùng nhớ, menu,…) ID (Identifier): Một giá trị nguyên ứng dụng tạo để làm định danh cho đối tượng (menu item, control) Instance: Một giá trị nguyên HĐH tạo để định danh thể thực thi ứng dụng Callback: Thuộc tính hàm/ thủ tục gọi HĐH, ứng dụng Các thành phần giao diện đồ họa (GUI – Graphics User Interface) Các dạng GUI bản: - SDI – Single Document Interface: + Một cửa sổ làm việc + Cho phép thay đổi kích thước cửa sổ (Resizeable) + Không có cửa sổ + Ví dụ: NotePad, Paint,… - MDI – Multi Document Interface: + Một cửa sổ làm việc (Frame window) nhiều cửa sổ (Child window) + Cho phép thay đổi kích thước cửa sổ (Resizeable) + Cho phép Maximize/Minimize/Close cửa sổ + Ví dụ: Word, Excel, VC++,… - Dialog: + Một cửa sổ làm việc + Thường có kích thước cố định + Thường menu bar + Thường có button, edit box, list-box,… + Ví dụ: Calculator, CD Player,… - Cửa sổ: - Định nghĩa: + Là vùng chữ nhật hình + Dùng để hiển thị kết output + Và nhận input từ người dùng - Công việc ứng dụng GUI tạo cửa sổ làm việc - Nguyên tắc quản lý: + Mô hình phân cấp: cửa sổ có cửa sổ cha (parent window), ngoại trừ cửa sổ Desktop + Tại thời điểm, có cửa sổ nhận input từ user (Active/Focused window) - Phân loại: + Cửa sổ Desktop + Cửa sổ tiêu chuẩn + Cửa sổ hộp thoại (Dialog box) + Các control Qui trình hoạt động chương trình ứng dụng: - Cửa sổ hiển thị lên hình - Chờ cửa sổ gửi thông điệp - Các thông điệp Windows gửi trả lại chương trình ứng dụng thông qua lời gọi hàm chúng chương trình ứng dụng - Khi nhận thông điệp, chương trình ứng dụng gọi hàm API hàm riêng chúng để thực công việc mong muốn - Lập trình Windows lập trình sở thông điệp, trình trao đổi thông tin điều khiển dựa thông điệp Có nhiều thông điệp phát sinh ngẩu nhiên nhấn phím hay chuột, chọn menu, - Tương tác ứng dụng với người sử dụng thông qua hay nhiều cửa sổ, tạo lập cửa sổ cần thiết quản lý thông tin Ví dụ #include LRESULT CALLBACK XulyMessage (HWND,UNIT,WPARAM,LPARAM); char szAppName [ ] = “Vidu”; int WINAPI WinMain (HANDLE hInst, HANDLE hPrevInst, LPSTR lpszCmdLine, int nCmdShow) { HWND hwnd; MSG msg; WNDCLASSEX wndclass; wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = XulyMessage; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInst; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); RegisterClassEx(&wndclass); hwnd = CreateWindow(szAppName, “Vi du mo dau”, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInst, NULL); ShowWindow (hwnd, nCmdShow); UpdateWindow (hwnd); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } return msg.wParam; } LRESULT CALLBACK XulyMessage (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; switch (iMsg) { case WM_PAINT: hdc = BeginPaint (hwnd, &ps); GetClientRect (hwnd, &rect); DrawText (hdc, “Lap trinh C for Win”, -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); EndPaint (hwnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc (hwnd, iMsg, wParam, lParam); } return 0; } Ta khảo sát ví dụ để nắm nguyên lý hoạt động chúng Trên đoạn chương trình đơn giản Windows, chương trình hiển thị khung cửa sổ dòng chữ có nhiều lệnh mà cú pháp khó nhớ Do vậy, nguyên tắc lập trình Windows chủ yếu chép chỉnh sửa nơi cần thiết dựa vào chương trình mẫu có sẵn a Hàm WinMain() thực hay gọi điểm vào chương trình Ta thấy hàm có tham số: + hInst, hPrevinst: Chỉ số chương trình chúng chạy Vì Windows hệ điều hành đa nhiệm, có nhiều chương trình chạy vào thời điểm nên phải quản lý chặt chẽ chúng hInst số chương trình vừa khởi động, hPrevinst số khởi động trước chúng có giá trị NULL + lpszCmdLine: chứa địa đầu xâu ký tự đối số dòng lệnh + nCmdShow: Cho biết cách thức hiển thị cửa sổ chương trình khởi động Windows gán giá trị SW_SHOWNORMAL hay SW_SHOWMINNOACTIVE Các tham số hệ điều hành truyền vào Định nghĩa lớp cửa sổ đăng ký với Windows + Lớp cửa sổ (window class): Là tập thuộc tính mà HĐH Windows sử dụng làm khuôn mẫu (template) tạo lập cửa sổ Mỗi lớp cửa sổ đặc trưng tên (class-name) dạng chuỗi Phân loại class: - Lớp cửa sổ hệ thống (System class): Được địnhnghĩa trước HĐH Windows Các ứng dụng hủy bỏ - Lớp cửa sổ ứng dụng định nghĩa: Được đăng ký ứng dụng Có thể hủy bỏ không sử dụng - Lớp toàn cục ứng dụng (Application global class) - Lớp cục ứng dụng (Application local class) Mỗi cửa sổ thuộc lớp xác định Khi lần đầu chạy, ứng dụng phải định nghĩa đăng ký lớp với cửa sổ (Window Class) Đây cấu trúc liệu mô tả tính chất cửa sổ, ta gán giá trị ban đầu cho thành phần cấu trúc lớp cửa sổ, bao gồm: Kích thước, kiểu, địa hàm xử lý thông điệp cửa sổ, định nghĩa hình dạng cho trỏ chuột (cursor) biểu tượng (Icon), màu nền, tên lớp cửa sổ struct WNDCLASSEX { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; }; + Sau định nghĩa thành phần lớp cửa sổ ta phải đăng ký lớp cửa sổ với hệ điều hành (RegisterClassEX) ATOM RegisterClassEx (CONST WNDCLASSEX *lpWClass); với: Kiểu giá trị ATOM định nghĩa window.h WORD; lpWClass trỏ đến cấu trúc lớp cửa sổ; hàm trả số lớp cửa sổ +Có hai nguyên nhân dẫn đến việc đăng ký cửa sổ thất bại: - Trùng tên ứng dụng hệ điều hành - Không đủ nhớ + Tạo lập cửa sổ làm việc (Frame Window) - Sau đăng ký thành công ta tạo lập cửa sổ thông qua hàm CreateWindow() HWND CreateWindow ( LPCSTR lpClassName, LPCSTR lpWinName, DWORD dwStyle, int X, int Y, int Width, int Height, HWND hParent, HMENU hMenu, HINSTANCE hInst, LPVOID lpszAdditional); - Gọi hàm ShowWindow()để hiển thị cửa sổ BOOL ShowWindow (HWND hwnd, int nShow); với: hwnd số cửa sổ cần hiển thị nShow cách thức hiển thị cửa sổ, tham số nhận giá trị lần hàm WinMain() - Để thông báo cho ứng dụng biết phải vẽ lại vùng làm việc cửa sổ, ta phải gọi hàm UpdateWindow() yêu cầu Windows gửi thông điệp đến hàm xử lý thông điệp cửa sổ + Vòng lặp thông điệp - Khi nhấn phím hay chuột, Windows chuyển đổi kiện thành thông điệp đặt vào hàng đợi thông điệp Vòng lặp thông điệp có nhiệm vụ nhận xử lý thông điệp hàng đợi - TranslateMessage: Dịch thông điệp sang dạng tiêu chuẩn - DispatchMessage: Phân phối thông điệp đến hàm xử lý thông điệp tương ứng b Thủ tục xử lý thông điệp + Nhận xử lý thông điệp chương trình + Một chương trình có nhiều thủ tục window + Một lớp cửa sổ khai báo thủ tục window + Các thông điệp sau xử lý nên trả giá trị + Dạng tổng quát: LRESULT CALLBACK WndProc( HWND hWnd, //handle window nhận message UINT message, //ID thông điệp (tên thông điệp) WPARAM wParam, //thamsố thứ message (WORD) LPARAM lParam) //thamsố thứ hai message (LONG) { switch (message) { case WM_COMMAND: return 0; case WM_PAINT: return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, message, wParam, lParam); } } Thông điệp WM_PAINT: Cập nhật lại thông tin vẽ hình Các trạng thái xuất thông điệp WM_PAINT: i Tạo cửa sổ Hiển thị Cập nhật CreateWindow ShowWindow UpdateWindow ii Xuất hộp thoại (Dialog box), thông báo (Message box) làm che phần toàn cửa sổ, hộp thoại đóng phải gọi WM_PAINT để vẽ lại cửa sổ iii Khi thay đổi kích thước cửa sổ WS_HREDRAW | WS_VREDRAW iv Cửa sổ minimize ,maximize HDC: (Handle to a device context) đến ngữ cảnh thiết bị gồm thiếtbị phần cứng trình điều khiển thiết bị BeginPaint: Lấy ngữ cảnh thiết bị EndPaint: Giải phóng ngữ cảnh thiết bị Thông điệp WM_DESTROY: + Xuất người dùng chọn nút close cửa sổ nhấn Alt+F4 + Nhiệm vụ PostQuitMessage đặt thông điệp WM_QUIT vào hàng đợi 10 III, MỘT SỐ THÀNH PHẦN CƠ BẢN Tài nguyên ứng dụng (Resources) + Là đối tượng (object) sử dụng ứng dụng (VD: menu bar, dialog, bitmap, icon, cursor, …) + Được định nghĩa bên thêm vào file thi hành ứng dụng biên dịch (linking) + Các dạng resource: 11 Một số kiểu liệu mới: 12 13 Một số hàm đồ họa sở: 3.1 Nhóm hàm vẽ + COLORREF GetPixel(HDC hDC, int nXPos, int nYPos); Lấy giá trị màu vị trí (nXPos, nYPos) hDC, trả -1 điểm nằm vùng hiển thị +COLORREF SetPixel(HDC hDC, int nXPos, int nYPos, COLORREF clrRef); Vẽ điểm màu clrRef vị trí (nXPos, nYPos) lên hDC Giá trị trả màu điểm (nXPos, nYPos) -1 điểm nằm vùng hiển thị +DWORD MoveToEx(HDC hDC, int x, int y); Di chuyển bút vẽ đến tọa độ (x, y) hDC Giá trị trả tọa độ cũ bút vẽ, x = LOWORD, y = HIWORD 14 +BOOL LineTo(HDC hDC, int xEnd, int yEnd); Vẽ đoạn thẳng từ vị trí hành đến vị trí (xEnd, yEnd) hDC Hàm trả TRUE thành công, FALSE thất bại +BOOL Polyline(HDC hDC, const POINT FAR *lpPoints, int nPoints); Vẽ đường gấp khúc lên hDC đoạn thẳng liên tiếp, số đỉnh nPoints với tọa độ đỉnh xác định lpPoints Hàm trả TRUE thành công, FALSE thất bại +BOOL Polygon(HDC hDC, const POINT FAR *lpPoints, int nPoints); Vẽ đa giác có nPoints đỉnh, tọa độ đỉnh xác định lpPoints Hàm trả TRUE thành công, FALSE thất bại +BOOL Rectangle(HDC hDC, int left, int top, int right, int bottom); Vẽ hình chữ nhật có tọa độ left, top, right, bottom lên hDC +HPEN CreatePen(int penStyle, int penWidth, COLORREF penColor); Tạo bút vẽ có kiểu penStyle, độ dày nét vẽ penWidth, màu penColor Hàm trả handle bút vẽ thành công trả NULL thất bại Các giá trị penStyle sau : 3.2 Nhóm hàm miền HBRUSH CreateSolidBrush(COLORREF cRef); Tạo mẫu tô đặc với màu cRef HBRUSH CreateHatchBrush(int bStyle, COLORREF cRef); Tạo mẫu tô dạng lưới kiểu bStyle với màu cRef Các kiểu bStyle : HS_HORIZONTAL HS_VERTICAL HS_FDIAGONAL 15 HS_BDIAGONAL HS_CROSS HS_DIAGCROSS BOOL FloodFill(HDC hDC, int xStart, int yStart, COLORREF cRef); Tô màu vùng kín, màu đường biên cRef BOOL ExtFloodFill(HDC hDC, int xStart, int yStart, COLORREF cRef, UINT fillStyle); Tô màu vùng kín, fillStyle định cách tô : - FLOODFILLBORDER : Tô màu vùng có màu đường biên cRef -FLOODFILLSURFACE : Tô vùng có màu cRef 4.HỘP THOẠI VÀ ĐIỀU KHIỂN 4.1 Hộp thoại Hộp thoại phối hợp người sử dụng với chương trình số phần tử điều khiển mà phần tử nhận nhiệm vụ thu nhận thông tin từ người dùng cung cấp thông tin đến người dùng người dùng tác động đến phần tử điều khiển Các phần tử điều khiển nhận cửa sổ cha hộp thoại Các phần tử điều khiển thường Button, List Box, Combo Box, Check Box, Radio Button, Edit Box, Scroll Bar, Static Hộp thoại trạng thái (modal) Hộp thoại không trạng thái (modeless) Hộp thoại thông dụng (common dialog) 4.2Thiết kế hộp thọai Ví dụ: IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 196, 102 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION CAPTION "Logon" 16 FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,24,81,50,14 PUSHBUTTON "Cancel",IDCANCEL,109,81,50,14 LTEXT "User name",IDC_STATIC,7,23,40,15 LTEXT "Password",IDC_STATIC,7,50,40,16 EDITTEXT DC_EDT_NAME,52,19,137,16,ES_AUTOHSCROLL EDITTEXT IDC_EDT_PASSWORD, 52, 48, 137, 16, ES_AUTOHSCROLL END 4.3Các kiểu điều khiển Các kiểu điều khiển khai báo resource script có dạng 17 sau, ngoại trừ kiểu điều khiển LISTBOX, COMBOBOX, SCROLLBAR, EDITTEXT Control-type "text", id, xPos, yPos, xWidth, yHeight, iStyle Các kiểu điều khiển LISTBOX, COMBOBOX, SCROLLBAR, EDITTEXT khai báo resource script với cấu trúc trường "text" Thêm thuộc tính cho kiểu điều khiển cách thay đổi tham số iStyle Ví dụ ta muốn tạo radio button với chuỗi diễn đạt nằm bên trái nút ta gán trường iStyle BS_LEFTTEXT cụ thể sau: RADIOBUTTON Radio1",IDC_RADIO1,106,10,53,15,BS_LEFTTEXT 4.4 Thủ tục xử lý hộp thọai Đặc điểm : • Mỗi hộp thọai cần có thủ tục xử lý riêng • Các thông điệp không gửi tới hàm xử lý cửa sổ • Là hàm xử lý cửa sổ Mẫu hàm BOOL CALLBACK Tên hàm (HWND, UINT, WPARAM, LPARAM) ; • Có nhiều thông điệp khác • Không cần xử lý WM_PAINT WM_DESTROY • Xử lý thông điệp trả TRUE, không trả FALSE • Thường phải xử lý hai thông điệp chính: WM_INITDIALOG WM_COMMAND: LOWORD(WPARAM) chứa ID điều khiển 4.5 Hộp thoại trạng thái Hiển thị hộp thoại INT_PTR DialogBox( HINSTANCE hInstance, // handle to module LPCTSTR lpTemplate, // dialog box template HWND hWndParent, // handle to owner window DLGPROC lpDialogFunc // dialog box procedure ); Ví dụ: DialogBox (hInstance, TEXT ("DIALOG1"), hwnd, DialogProc) ; Gởi thông điệp đến hàm WndProc yêu cầu xử lý hộp thoại mở nhờ hàm SendMessage: SendMessage(GetParent(hDlg), message, wParam, lParam); Thêm tiêu đề cho hộp thoại: SetWindowText(hDlg,TEXT("Hello Dialog")); xử lý thông điệp WM_INITDIALOG 18 Đóng hộp thoại BOOL EndDialog( HWND hDlg, // handle to dialog box INT_PTR nResult // value to return ); 4.6 Hộp thoại không trạng thái Hiển thị hộp thoại HWND hDlgModeless=CreateDialog(hInstance, szTemplate, hwndParent, DialogProc); ShowWindow(hDlgModeless,SW_SHOW); while(GetMessage(&msg, NULL, 0, 0)) { if (hDlgModeless==0 || !IsDialogMessage (hDlgModeless, &msg); { TranslateMessage(&msg); DispatchMessage(&msg); } } while(GetMessage(&msg, NULL, 0, 0)) { if (hDlgModeless==0 || !IsDialogMessage(hDlgModeless, &msg); { if(TranslateAccelerator (hwnd, hAccel, &msg) { TranslateMessage(&msg); DispatchMessage(&msg); } } } Đóng hộp thoại Đặt hDlgModeless giá trị BOOL DestroyWindow( HWND hWnd // handle to window to destroy ); 19 IV.Kết luận Sau thời gian làm việc chung , đóng góp ý kiến giúp đỡ lẫn tìm hiểu lập trình Windows API , chúng em thu kiến thức lập trình API Trong trình nghiên cứu ,chúng em nhận thấy lĩnh vực hay , đáng để nghiên cứu , học hỏi sâu Mặc dù cố gắng lần đầu tiếp xúc với lập trình Windows API nên chúng em không tránh khỏi sai sót Vì chúng em mong thầy góp ý thêm cho làm nhóm Một lần nữa, chúng em xin cảm ơn nhiệt tình thầy giáo giúp nhóm hoàn thành tập lớn 20