Tổng quan về Win 32 và lập trình Win 32
1. Tổng quan về lập trình Win 32 Để bắt đầu với Win 32 , ta cần hiểu thế nào là API. API viết tắt cho Application Programming Interface có nghĩa là “Giao diện lập trình ứng dụng”, nó cung cấp các hàm và thư viện để phục vụ cho người lập trình. Win32 là viết tắt cho cụm từ Windows ...
1. Tổng quan về lập trình Win 32
Để bắt đầu với Win 32 , ta cần hiểu thế nào là API. API viết tắt cho Application Programming Interface có nghĩa là “Giao diện lập trình ứng dụng”, nó cung cấp các hàm và thư viện để phục vụ cho người lập trình.
Win32 là viết tắt cho cụm từ Windows 32-bit, tức ở đây, Win32 API cung cấp cho ta một số lượng hàm, thủ tục nhất định để ta dễ dàng tạo ra một chương trình theo ý muốn. Đầu tiên khi mới học Win32 có thể sẽ mất nhiều thời gian nhưng khi thuần thục, nó sẽ trở nên rất hữu dụng trong nhiều trường hợp.
2. Cách tạo ra một chương trình Win 32
Dưới đây là một đoạn code cho phép chúng ta hiển thị ra một MessageBox trong Win32 :
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MessageBox(NULL, TEXT(“This is my first application !”), TEXT(“FirstApp”), MB_OK);
return 0;
}
Trước tiên chúng ta cần hiểu một số khái niệm sau :
- Handle: Một xử lí đối với chương trình của chúng ta.
- window: Cửa sổ chương trình của chúng ta.(Chú ý đây không phải là Window-Hệ điều hành ).
- Message: Mỗi quá trình hay thông điệp ta sẽ gửi đến window.
Mọi chương trình trong Window đều cần có 2 hàm là :
- WinMain() :Tương tự như hàm main() , khởi tạo ứng dụng .
- Window procedure :Nhận và xử lí các meesage gửi đến.
Các thông số trong hàm WinMain() :
HINSTANCE hInstance: Xử lí đối với việc thực thi của chương trình .
HINSTANCE hPrevInstance: Thường là NULL trong các chương trình Win32.
LPSTR lpCmdLine: Một tham số command line giống như một chuỗi nhưng không được chứa tên chương trình .
int nCmdShow: Một số nguyên cung cấp cho hàm ShowWindow(). Cái này sẽ được đề cập ở sau.
Ở đây mình sẽ dùng Visual Studio 2013 để minh họa cho chương trình trên.
Đầu tiên ta phải tạo một Empty Project trong Visual Studio 2013 bằng cách chọn File -> New -> Project hoặc dùng tổ hơp phím Ctrl + Shift + N :
Trong Visual C++ các bạn chọn Win32 và sau đó chọn Win32Project. Trong ô name các bạn chọn tên mà mình muốn đặt.Ở đây mình chọn FirstApp:
Tiếp theo bạn chọn Next rồi chọn như hình sau và kết thúc bằng click vào button Finish để tạo project:
Trên thanh Solution Explorer nằm bên tay phải (hoặc chọn View -> Solution Explorer). Ở trong đây, các bạn chuột phải vào Source Files -> Add -> New Item:
Tiếp theo các bạn chọn Visual C++ -> Code -> C++ file (.cpp) và đặt tên cho file của mình. Ở đây mình đặt tên là FirstApp:
Cuối cùng, các bạn thêm đoạn code trên vào file FirstApp.cpp và chạy thì sẽ được kết quả như hình bên dưới:
3. Cách tạo ra cửa sổ Windows trong Win 32
Ở đây ta sẽ quy ước Window là tên hệ điều hành còn window là cửa sổ của chương trình.
3.1. Khởi tạo Windows ClassMột window class sẽ lưu trữ thông tin về kiểu của window bao gồm window procedure, cái mà sẽ điều khiển window về kích thước, vị trí cũng như các icon, foreground và background của window. Do đó bạn có thể tạo ra được một window tùy theo ý của chúng ta.
Khai báo tên của window class như sau :
const char g_szClassName[] = “myWindowClass”;
Tiếp theo sẽ là thông số mà chúng ta cần khởi tạo :
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, “Window Registration Failed!”, “Error!”,
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
Đoạn chương trình trên sẽ được sử dụng trong hàm WinMain() để khởi tạo window của chúng ta. WNDCLASSEX là một struct chứa các thông tin về window của chúng ta. Các thành phần của struct này như sau:
- cbSize: Cho ta biết kích thước của struct.
- style: Thường được gán về 0.
- lpfnWndProc: Trỏ tới the window procedure cho window class này.
- cbClsExtra và cbWndExtra là các byte bổ sung. Do ta không dùng đến nó nên các giá trị này được gán về 0.
- hInstance: Khai báo handle đối với chương trình của chúng ta.
- hIcon: Khai báo icon trong chương trình(thường có kích thước 32×32).
- hCursor: Biểu tượng con trỏ được hiện lên trong chương trình của chúng ta.
- hbrBackground: Khai báo màu nền cho cửa sổ chính
- lpszMenuName: Khai báo tên menu của chương trình.Nhưng ở đây ta không khởi tạo nên giá trị này bằng 0.
- lpszClassName: Tên của cửa sổ chương trình của chúng ta.
- hIconSm: Icon của chương trình khi được hiển thị trên taskbar (thường là 16×16).
- 3.2 TẠO WINDOW
Sau khi đã khởi tạo xong ,ta có thể tạo được window. Chúng ta thực hiện điều này bằng hàm CreateWindowEx().
HWND hwnd; hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, “The title of my window”, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);
- Thông số thứ 1 WS_EX_CLIENTEDGE là thành phần mở rộng cho window style. WS_EX_CLIENTEDGE cho ta biết được window của chúng ta có phần biên bị hạ thấp xuống.Ngoài ra các bạn có thể khai báo về 0 để xem sự khác biệt.
- Thông số thứ 2 là class name g_szClassName như đã nói phần trên.
- Thông số thứ 3 là “The title of my window”.Tiltle chương trình của chúng ta.
- Thông số thứ 4 WS_OVERLAPPEDWINDOW là một thành phần của Window Style.
Bốn thông số tiếp theo CW_USEDEFAULT, CW_USEDEFAULT, 320, 240 cho ta biết được vị trí của góc trên bên trái của chương trình của chúng ta (CW_USEDEFAULT, CW_USEDEFAULT) và chiều rộng, chiều cao của window. CW_USEDEFAULT cho ta biết rằng Window sẽ chọn nơi để đặt chương trình của chúng ta.
Bốn thông số cuối (NULL, NULL, g_hInst, NULL) cho ta thấy handle đối với Parent Window, menu, application, and xem có trỏ tới data hay không.
Ta sẽ thêm vào đoạn code sau để nếu chương trình tạo window lỗi , nó sẽ hiện ra thông báo để ta có thể biết được.
if(hwnd == NULL) { MessageBox(NULL, “Window Creation Failed!”, “Error!”, MB_ICONEXCLAMATION | MB_OK); return 0; }
Sau khi đã tạo ra window ,kiểm tra hàm tạo là hợp lệ thì ta sẽ cho hiện window lên màn hình.
3.3. Tạo vòng lặp cho hàm GetMessageShowWindow(hwnd, nCmdShow);//hiển thị window UpdateWindow(hwnd);//cập nhật lại window của chúng ta khi có các hàm message được gửi đến.
Đây là phần khá quan trọng trong chương trình của chúng ta.
while(GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg); DispatchMessage(&Msg);
} return Msg.wParam;
GetMessage sẽ lấy message từ hàng đợi trong chương trình của chúng ta. Bất kì hoạt động gì như click chuột, gõ bàn phím… , message đều được sinh ra và gửi đến hàng đợi của chương trình. Điều này được thực hiện dựa vào hàm TranslateMessage. Sau đó hàm DispatchMessage sẽ gửi message của ta tới window để hiển thị.
3.4. Windows ProcedureNếu như vòng lặp của chúng ta là trái tim thì window procedure sẽ là bộ não.Đây chính là nơi các message sẽ được xử lí.
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_CLOSE: DestroyWindow(hwnd);
break;
case WM_DESTROY: PostQuitMessage(0);
break;
default: return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
WM_CLOSE được gửi khi chúng ta ấn vào hoặc ấn Alt+F4. Chương trình của chúng ta sẽ bị tắt trước khi chương trình thực hiện xong. Khi chúng ta gọi hàm DestroyWindow(), WM_DESTROY sẽ được gửi tới window, trong trường hợp này, chương trình sẽ tắt các chương trình con ta gọi ra trước khi tắt chương trình chính.
PostQuitMessage được dùng khi ta đã thực hiện xong và muốn thoát chương trình. Lúc này WM_QUIT sẽ được gửi đến vòng lặp message và ta không nhận được message nào từ hàm GetMessage() nữa. Hàm này sẽ trả lại giá trị FALSE.
Cuối cùng kết hợp các phần trên lại với nhau ta sẽ được kết quả như sau:
Trong bài này, mình đã trình bày với các bạn về cách tạo một window bằng Win32.Trong phần tới mình sẽ giới thiệu với các bạn về các kiểu dữ liệu trong Win32.
TÀI LIỆU THAM KHẢO
- https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751%28v=vs.85%29.asp
- fogers-win32-tutorial
- Wiki