Sử dụng phép toán logic quản lý nhiều checkbox trong MFC
Hi, chào mừng các bạn ghé thăm blog.
Hôm nay, tôi sẽ giới thiệu một kỹ thuật rất hay và nên sử dụng trong lập trình MFC.
Sử dụng phép toán logic quản lý nhiều checkbox
1. Bài toán đặt ra:
Giả sử chúng ta có một dialog như sau:
Tôi cần lưu trạng thái check hoặc không check của nhóm checkbox trong dialog trên vào trong một file config.
Đây là kỹ thuật mà trong các phần mềm ứng dụng sẽ thường sử dụng.
Vậy thì chúng ta làm thế nào.
Nếu theo cách thông thường, chúng ta chỉ cần sử dụng một nhóm 5 biến bool, lưu lần lượt trạng thái true hoặc false
cho từng checkbox.
Sau đó chúng ta sẽ ghi vào file config khi save xuống, và đọc trở lại khi load file config nên.
Ok. đó là cách làm cơ bản, chính xác, dễ hiểu và dễ làm.
Nhưng nếu xét về mặt tối ưu, nó chưa thực sự tốt.
Chúng ta có thể làm bài toán ở trên tối ưu hơn.
2. Phương pháp sử dụng bit dữ liệu.
Chúng ta phân tích thấy rằng.
Trạng thái của checkbox, thực chất nó chỉ là có 2 trạng thái check và không check.
Mà để biểu diễn 2 trạng thái trong dữ liệu, người ta chỉ cần sử dụng một bit là đủ.
Như vậy nếu theo cách thông thường, thì chúng ta sử dụng 5 biến bool cho 5 checkbox.
Một biến bool có kích thước là 1 byte (8 bit). Và chúng ta dùng đến 5 biến bool.
Xét về mặt logic nó có phần thừa bit cho việc lưu trữ.
Do dó, chúng ta có thể tối ưu bằng phương pháp chỉ sử dụng một bit dữ liệu để thể hiện trạng thái check hoặc không check cho control checkbox.
3. Phương pháp làm như sau:
Tôi sử dụng một biến UINT, biến này có kích thước là 4 byte.
Như vậy UINT có thể lưu đến giá trị như thế nào. Hãy xem minh họa dưới đây.
1 byte là 8 bit, 8 bit thường được biểu diễn theo nhị phân sẽ là: xxxx-xxxx là 2 chuối số 4 bít
Hoặc có thể biểu diễn theo dạng hexa đó là: 0xXX (với X là hệ hexa chạy từ 0 đến F)
Như vậy UINT là một biến có size bằng 4 byte.
Nó có thể đạt giá trị tối đa đó là: 0xFFFFFFFF
Các bạn sẽ thấy, nó đặt được giá trị tối đa như trên.
Giả sử bây giờ tôi tằng thêm một byte FF cho chuỗi giá trị ở trên, để cố tính vượt qua phạm vi 4 byte
Thì điều gì sẽ xảy ra.
Các bạn sẽ thấy, khi cố tính để một giá trị vượt quá phạm vi lữu trữ, biến val chỉ lưu trữ đến đúng giá trị cho phép của nó.
Trở lại với bài toán ở trên.
Tôi sẽ chỉ sử dụng một biến UINT này để quản lý được 2 vấn đề.
1. Nhận biết được trạng thái check và không check
2. Phân biệt được theo từng checkbox, cái nào off và cái nào on.
Step 1: Tôi sẽ tạo ra các macro define để đánh dấu riêng cho từng checkbox.
Và macro define này sẽ là chuỗi giá trị chỉ sử dụng 1 bit để đánh dấu cho từng loại checkbox.
Ơ đây tôi có 5 checkbox, nên tôi sẽ dùng 5 chuỗi số như trên để thể hiện cho 5 checkbox.
Mỗi ông đại diện bởi một bit.
Sử dụng một biến mVal_ để lưu trạng thái check và uncheck cho toàn bộ 5 checkbox.
Step2: Tại hàm bắt sự kiện của các checkbox.
Tôi thực hiện phép toán logic cộng và trừ cho giá trị của biến mVal_ như sau:
Tương tự như vậy sẽ làm với các checkbox 2 —- checkbox 5.
Các bạn sẽ tưởng tưởng thế này.
Khi các checkbox được check nhiều lên, thì giá trị của biến mVal_ cũng sẽ được bao phủ nhiều bít 1 lên.
Còn khi các checkbox được unchec dần, thì giá trị của biến mVal_ cũng sẽ giảm dần các bit 1 và thay bằng các bit 0
Step 3. Thực hiện kiểm tra giá trị để phân loại checkbox và trạng thái
Câu hỏi đặt ra là chúng ta làm gì với giá trị của biến mVal_ ở trên để biết được những checkbox nào được check và không được check
Tôi sẽ làm như sau:
sử dụng phép toán logic and để kiểm tra
Phép toán logic and sẽ giúp chúng ta check được điều kiện on và off của từng checkbox.
Sau khi chạy thử các bạn sẽ thấy kết quả ok như mong đợi.
Ok, các bạn có thể chạy thử với code sample dưới đây
============== > Link down code sample