- Dự án mã nguồn mở này là một ứng dụng Todo Windows native gọn nhẹ được xây dựng chỉ bằng C và Win32 API
- Ứng dụng hoạt động với dung lượng tối thiểu (tối đa 26.5KB) không phụ thuộc vào framework, đồng thời tự triển khai trực tiếp GUI Windows nâng cao và tích hợp hệ thống
- Ngoài các tính năng cơ bản như thêm, sửa, xóa, đánh dấu hoàn thành các mục Todo, ứng dụng còn cung cấp các tính năng năng suất thực tế như tích hợp khay hệ thống và tùy chọn tự khởi động
- Kho lưu trữ mang tính bền vững bằng tệp nhị phân, lưu tối đa 100 danh sách việc cần làm trong thư mục AppData
- Điểm mạnh là phong cách lập trình cổ điển bám rất sát hệ điều hành, không dùng framework lớn và có môi trường chạy cực nhẹ
🌟 Simple Todo (C / WinAPI)
Tổng quan dự án
- Dự án này tạo ra một ứng dụng Todo Windows native hiện đại chỉ bằng C và Win32 API
- Thể hiện năng lực lập trình GUI Windows nâng cao và tích hợp hệ thống
- Dung lượng dự án rất nhỏ (tối đa 26.5KB) và giữ nguyên giao diện đặc trưng của Windows
✨ Tính năng chính
- Có thể tạo, chỉnh sửa, xóa mục việc cần làm
- Có thể đánh dấu hoàn thành công việc
- Lưu bền vững trong AppData để dữ liệu luôn được bảo toàn
- Tích hợp với khay hệ thống, khi thu nhỏ sẽ chuyển vào khay
- Mang giao diện theo phong cách Windows native
- Cung cấp tùy chọn tự chạy khi Windows khởi động
🛠️ Chi tiết kỹ thuật
- Toàn bộ được viết bằng C thuần
- Chỉ dùng Win32 API để triển khai GUI
- Kích thước tệp thực thi cực nhỏ (26.5KB khi nén bằng UPX)
- Tính năng tích hợp khay hệ thống
- Áp dụng visual style hiện đại thông qua manifest
💾 Lưu trữ dữ liệu
- Toàn bộ việc cần làm được lưu trong một tệp nhị phân duy nhất
- Đường dẫn lưu:
%APPDATA%\TodoApp\todos.dat
- Định dạng nhị phân và có thể lưu tối đa 100 mục
📋 Yêu cầu bắt buộc
- Cần môi trường hệ điều hành Windows
- Cần MinGW-w64 (trình biên dịch GCC) và Windows SDK
🎮 Cách sử dụng
- Chạy
bin/todo.exe rồi dùng giao diện để thực hiện các thao tác sau
- Thêm việc cần làm mới bằng nút "Add"
- Chọn mục rồi nhấn "Edit" để chỉnh sửa
- Xóa mục bằng "Delete"
- Đánh dấu hoàn thành bằng "Complete"
- Có thể đặt mức ưu tiên cho từng mục
🏗️ Cấu trúc dự án
- Thư mục
src/ chứa điểm vào chính (main.c), logic quản lý việc cần làm (todo.c), khai báo struct (todo.h), phần triển khai GUI (gui.c)
bin/ chứa tệp thực thi đã biên dịch
- Bao gồm script build (
build.bat) và tài liệu dự án
🔧 Thành phần phát triển
- Win32 API: triển khai quản lý cửa sổ và toàn bộ GUI
- Common Controls: sử dụng các thành phần UI hiện đại
- UXTheme: hỗ trợ áp dụng visual style Windows
- File I/O: hiện thực lưu trữ dữ liệu bền vững
📝 Giấy phép
- Có thể tự do sử dụng và chỉnh sửa theo giấy phép MIT
🤝 Hướng dẫn đóng góp
- Hoan nghênh Pull Request
- Bất kỳ ai cũng có thể tham gia dự án
📫 Liên hệ và liên kết
3 bình luận
Đúng là rất có chất lãng mạn.
Ý kiến trên Hacker News
strcpy,sprintf, nhưng nếu lập trình nghiêm túc thì nhất định phải dùng các biến thể có kiểm tra độ dài. Cũng lạ là trình biên dịch không cảnh báo ngay. Win32 API có nhiều hàm thay thế các hàm thư viện C tiêu chuẩn; nếu muốn giảm kích thước file thực thi hơn nữa thì tôi khuyên thử chỉ dùng<Windows.h>và viết mà không cần cstdlib. Có thể dùngZeroMemorythay chomemset,CopyMemorythay chomemcpy. Tất nhiên đến một lúc nào đó viết C thuần sẽ trở nên cực kỳ đau khổ, nhưng vài lần đầu tự làm bằng C thuần là cách học tốt nhất, vì nó giúp tích lũy cảm giác về cách cấu thành khi xử lý những chi tiết nhỏ như vậy. Nếu muốn tìm hiểu thêm về lập trình GUI win32 thì tôi cũng muốn giới thiệu WTL (Windows Template Library), nó bọc Win32 API bằng C++ nên giúp nắm nguyên lý hoạt động dễ hơn nhiềustrncpythay chostrcpy, nếu không ai cũng sẽ cứ liên tục chỉ ra chuyện đó. Một trong những lý do lớn để dùng zig là nó làm giảm những lỗi phổ biến kiểu này. Tất nhiên C cũng ổnZeroMemorythay chomemset,CopyMemorythay chomemcpy, intrinsic của MSVC dùng lệnhrep stos/movsnên mã còn nhỏ hơn gọi hàm và cũng giảm kích thước import tableZeroMemoryvàCopyMemorythay chomemsetvàmemcpy: tại sao họ lại phải tạo những thứ này thay vì dùng luôn thư viện C chuẩn?CreateWindowmỗi lần, người ta thường viết tài nguyên hộp thoại bằng file.rc(Visual Studio còn có cả dialog editor) rồi dùngCreateDialog. Khi đó mọi control được tạo một lần luôn. Chỉ cần thêm application manifest là có thể hỗ trợ giao diện hiện đại và DPI độ phân giải caouser32:SetProcessDpiAwarenessContext,shcore:SetProcessDpiAwareness,user32:SetProcessDPIAware), còn nếu quá cũ thì sẽ không gọi gì cảbuild.batkhông chạy đúng khi cấu hìnhcore.autocrlf=false. Đổi sangcore.autocrlf=truerồi clone lại thì build thành công. Một toolchain mingw cụ thể tạo ra file.exe102KB, tức hiệu quả hơn nhiều so với 278KB. Nếu muốn giảm thêm thì có thể thêm cờ cho GCC; vớigcc -s -Oz -fltothậm chí còn xuống được 47KB. Nếu chỉ quan tâm đến kích thước binary thì vẫn còn rất nhiều chỗ để tối ưuquickrun.exechỉ 15KB, chỉ dùng C và Win32 API thuần. Không có mẹo gì đặc biệt để giảm binary, dùng trình biên dịch Mingw32, đây là ứng dụng GUI để chạy app nhanh bằng aliasstd::string,std::array,std::list, anonymous namespace và bỏmallocđi thì có lẽ bạn sẽ thấy code ngắn đi một nửa và bug cũng ít hơnstd::string,std::listkhông có nghĩa assembly sinh ra sẽ giống nhau; ý kiến đó cho thấy là chưa thật sự hiểu cách mọi thứ hoạt động bên dướiLPWSTR(wide string) sẽ hợp với API hơnstd::stringvà cũng đáng khuyến nghị hơn. So với cách cũ nhưchar[]thìLPWSTRhợp lý hơn, cònstd::arrayhaylistcó lẽ cũng không làm code tốt hơn bao nhiêuHơi thở phả ra như muốn truyền tới tận đây vậy...