mình sẽ trình bày loạt bài về lập trình C trên window sử dụng API windows. dưới đây là code tạo 1 cửa sổ đơn giản nhất. có chỗ nào không hiểu xin hỏi mình sẽ cố gắng giải thích trong khả năng, bạn nào có nhã hứng thì liên hệ mình cùng học. Mã: #include <windows.h> const char g_szClassName[] = "myWindowClass"; // Step 4: the Window Procedure 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; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg; //Step 1: Registering the Window Class 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); 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; } // Step 2: Creating the Window hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "Phan mem dau tien chay tren Windows", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL); if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); // Step 3: The Message Loop while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; }
giải thích các đoạn code của chương trình: hàm API của windows chứa trong các file dll (Dynamic Link Library) -->có trong bộ visual studio Không nên dùng API trong các thủ tục thiết kế chính của mình --> tạo các wraper chứa các hàm API để đơn giản hóa, các wraper chứa hàm API trong đó, thực hiện 1 công việc gì cụ thể. khi gọi đỡ rắc rối hơn. --> khai báo các API cụ thể thì Private. còn khái wraper cho Public. tránh lỗi hệ thống. Hàm API không chỉ trả về kết quả cho bản thân hàm mà còn trả về kết quả cho các biến truyền vào hàm. mỗi chương trình đang chạy có nhiều cửa sổ phục vụ cho nó như form, dialog.... mỗi cửa sổ đều có 1 cán (handle) để hệ thống nhận biết cửa sổ do windows tạo ra. mỗi ứng dụng hay hdh đều có hàng đợi thông điệp. message queue. khi có sự kiện hay có lệnh từ chương trình sẽ được chuyển vào hàng đợi hệ thống system mesage queue Các thư viện lập trình SDK - Software development Kit bộ thư viện nền tảng của windows thư viện cơ sở tạo nên Object WIndows Library OWL và Micrsofft Foundation Classes MFC 1 ứng dụng có thể viêt bằng SDK hoặc SDK kết hợp với OWL, MFC ... các loại ứng dụng: + win 32console + win 32 SDK - ứng dụng chỉ sử dụng SDK + win 32 dll: ứng dụng 32 bít, dạng liên kết động (DLL), sd SDK + win 32 LIB: ứng dụng 32 bít, dạng liên kết tĩnh (Static linked labrary) + MFC exe: ứng dụng 32 bit, sử dụng MFC + MFc DLL: ứng dụng 32 bit, sử dụng MFC, dạng DLL + ..... cơ bản: - message: trao đổi thông tin giữa ứng dụng và HDH, tất cả qua thông điệp - thủ tục windows: hàm được gọi để xử lý thông điệp. - hàng đợi messages, hàng đợi chứa các messages được lặp. - handle: cán, định danh cho cửa sổ,vùng nhớ, đối tượng. 1 giá trị 32 bit không dấu (unsigned) -ID: một giá trị nguyên do ứng dụng tạo ra để định danh cho 1 đối tượng (item control) -Instance: giá trị do HDH tạo ra để định danh 1 thể hiện sự thực thi của ứng dụng -Callback: thuộc tính của một hàm/ thủ tục được gọi bởi HDH, không phải bởi ứng dụng. Hàng đợi hệ thống (SYSTEM QUEUE) nhận thông điệp từ thiết bị nhập(chuột, bàn phím).. đưa vào hàng đợi hệ thống. Quy trình xử lý thông điệp như sau: Thiết bị nhập gửi tín hiện được driver chuyển thành thồng điệp hệ thống, thông điệp này được nạp nào hàng đợi hệ thống. hàng đợi sự kiện hệ thống sẽ tương ứng với ứng dụng trong hàng đợi ứng dụng mà gửi thông điệp vào. hàng đợi này có 3 nguồn nhận thông điệp: +từ hàng đợi hệ thống +từ ứng dụng khác gửi vàos +từ chính chương trình gửi vào chính chương trình gửi vào như sau: get messages Translate message --> dịch chỉ lệnh(thông điệp) thành tín hiệu khác rồi gửi vào lại hàng đợi app. có 2 kiểu: SendMessage: ưu tiên xử lý xong mới chuyển qua message khác. Postmessage: đưa vào hàng đợi. Dispatch message--> nhận lệnh từ hàm get message gửi vào cho hệ thống, hệ thống sẽ gửi lại thông điệp cho ứng dụng Sau đó ứng dụng được đưa vào cho hàm WinProc hay WinMain xử lý các thành phần giao diện đồ họa: SDI: Single Document Interface MDI: Multi Documen Interface: gồm nhiều cửa sổ con Dialog: 1 cửa sổ, không có menubar Cửa sổ là gì: vùng chữ nhật trên màn hình, dùng để nhận, gửi thông tin cho người dùng - Công việc đầu tiên của một ứng dụng GUI là tạo cửa sổ. Nguyên tắc quản lý: Desktop là cửa sổ cha cho tất cả. desktop không có cửa sổ cha. mỗi thời điểm chỉ có 1 cửa sổ nhận input từ user //------------- Đi vào tạo ứng dụng------------------// 1. Hàm main Đầu tiên phải có hàm WinMain --> thực hiện đầu tiên(điểm vào của chương trình) --> có 4 tham số + hInst --> chỉ số của chương trình + hPrevinst --> chỉ số của chương trình trước đó có thể đây là danh sách liên kết các ứng dụng để quản lý ??? + lpszCmdLine --> chứa địa chỉ đầu của xâu các đối số dòng lệnh +nCmdShow --> cách thức hiển thị cửa sổ chương trình. --> các tham số của hàm Main do HDH truyền vào --> default Quy trình hoạt động: Cửu sổ được tạo lập --> WD chờ ứng dụng gửi thông điệp --> thông điệp sau khi xử lý trả lại ứng dụng qua lời gọi hàm --> nhận được thông điệp ứng dụng gọi API và hàm của chúng để thực hiện việc. Quy ước đặt tên: - tên hằng viết hoa - tên biến viết thường, kèm kiểu dữ liệu. iTong --> biến Tong kiểu int Phân loại lớp: lớp cửa sổ hệ thống --> được định nghĩa bởi hdh lớp cửa sổ do ứng dụng định nghĩa 2. Định nghĩa lớp Cấu trúc dữ liệu đăng ký lớp với cửa sổ typedef struc WNDCLASSEX{ kích thước; kiểu; địa chỉ hàm xử lý thông điệp cửa sổ; định nghĩa hình dạng trỏ chuột; icon; màu nền; tên lớp cửa sổ; } Định nghĩa lớp (done) --> đăng ký lớp 3. Đăng ký lớp ATOM RegisterClass (CONST WNDCLASSEX *lpWClass) ATOM --> kiểu WORD *lpWClass --> con trỏ tới cấu trúc cửa sổ --> hàm trả về chỉ số lớp cửa sổ trong danh sách cửa sổ đã đăng ký. Đăng ký thất bại : +Trùng tên ứng dụng +Không đủ bộ nhớ. 4. tạo cửa sổ làm việc. HWND - 1 kiểu dữ liệu nào đó HWND CreateWindow ( LPCSTR lpClassName, LPCSTR lpWinName, DWORD dwStyle, int X, int Y, int Width, int Height, HWND hParent, HMENU hMenu, HINSTANCE hInst, LPVOID lpszAdditional); 5. Gọi ShowWindow() để hiển thị cửa sổ BOOL ShowWindow(HWND hwnd,int nShow) hwnd --> chỉ số cửa sổ cần hiển thị nShow --> cách thức hiển thị cửa sổ. tham số này nhận giá trị lần đầu từ hàm winmain 6. vẽ lại cửa sổ UpdateWindow() 7. Vòng lặp thông điệp --> Window liên tục nhận sự kiện và dịch nó để đưa vào hàng đợi xử lý. bởi 2 hàm: TranslateMessage DispatchMessage: phân phối thông điệp đến hàm xử lý tương ứng. Phần sau mình sẽ tiếp tục nghiên cứu và cập nhật. integer
bạn giai thich hộ mình bài này dc ko: #include<windows.h> int n=2, a[100][100], x0,y0, cw,ch, i,j, w=30; void HamTaoLuoi(int kt) { n = kt; for(i=0;i<n;i++) for(j=0;j<n;j++) a[j] = rand()%2; } void HamVeLuoi(HWND cs) { HDC d = GetDC(cs); HPEN p = CreatePen(1,3,RGB(255,0,0)); HBRUSH b = CreateSolidBrush(RGB(0,0,255)); RECT r; GetClientRect(cs,&r); cw = r.right-r.left; ch = r.bottom-r.top; x0 = (cw-n*w)/2; y0 = (ch-n*w)/2; SelectObject(d,p); for(i=0;i<n;i++) for(j=0;j<n;j++) { HBRUSH b2 = CreateSolidBrush(RGB(255,255,255)); SelectObject(d,b2); Rectangle(d,x0+j*w,y0+i*w,x0+j*w+w,y0+i*w+w); if(a[j]==1) { SelectObject(d,b); Rectangle(d,x0+j*w,y0+i*w,x0+j*w+w,y0+i*w+w); } } } void DaoTT(int i,int j) { if(i>=0 && i<n && j>=0 && j<n) a[j]=(a[j]+1)%2; } bool KetThuc() { for(i=0;i<n;i++) for(j=0;j<n;j++) if(a[j]==1) return false; return true; } //////////////////////////////////////////////////////////////// LRESULT CALLBACK HCS(HWND t1,UINT t2,WPARAM t3,LPARAM t4) { if(t2==WM_PAINT) HamVeLuoi(t1); if(t2==WM_CLOSE) PostQuitMessage(0); if(t2==WM_LBUTTONDOWN) { int x=LOWORD(t4), y=HIWORD(t4); int j=(x-x0)/w, i=(y-y0)/w; if(i>=0 && i<n && j>=0 && j<n) { DaoTT(i,j); HamVeLuoi(t1); if(KetThuc()) HamTaoLuoi(n+1); HamVeLuoi(t1); } else PostQuitMessage(0); } return DefWindowProc(t1,t2,t3,t4); } int WINAPI WinMain(HINSTANCE t1,HINSTANCE,LPSTR,int) { HamTaoLuoi(7); WNDCLASS a; ZeroMemory(&a,sizeof(a)); a.style = 1; a.hbrBackground = CreateSolidBrush(RGB(255,255,255)); a.hInstance = t1; a.lpszClassName = TEXT("CS1"); a.lpfnWndProc = HCS; RegisterClass(&a); HWND b = CreateWindow(TEXT("CS1"),TEXT("Bai Tap Lon De 4-Nguyen Huu Khuon-STT 22"),WS_OVERLAPPEDWINDOW,100,100,400,400,0,0,t1,0); ShowWindow(b,1); UpdateWindow(b); HamVeLuoi(b); MSG m; while(GetMessage(&m,0,0,0)) { TranslateMessage(&m); DispatchMessage(&m); } return 0; } dễ hiểu chút bạn nhé. và minh muôn thêm hàm này nữa thì làm như thế nào.: • Xử lý nhấn phím F1 đếm sô ô được tô màu trên lưới thank bạn trước mình đang cần gấp