Vâng đúng như anh đoán, code chính nằm ở HookExcelWindow.dll, nhưng file này và file Excel nằm trong EXE. Có thể nói, file EXE đóng vai trò gói tất cả các file cần thiết để đạt được ý đồ của chương trình (giống cách làm của các pm Portable, chỉ cần một file để chạy). Cái gì mình muốn che giấu thực sự thì cho vào DLL hay trong file EXE còn không thì viết trong VBA cũng được.
Em cũng có nghĩ tới (rất khoái là khác) việc tạo ra một chương trình hoàn chỉnh cho phép người dùng tạo ra file EXE và gói file Excel của họ lại, người dùng thích khóa chức năng nào của Excel thì chọn. Tuy nhiên có một số khó khăn:
1. Làm sao để người dùng chạy SP của mình biên dịch/tạo ra được file EXE (Cách tạo một file EXE từ chính phần mềm của mình).
2. Khi file EXE chạy và mở file Excel, sau quá trình soạn thảo muốn lưu lại thì không. Vấn đề này LOCKXLS, XLStoEXE cũng bị vậy thì phải.
Vụ này e rằng phải một thời gian nữa mới có thể thực hiện được.
Thực ra mấy vụ này không có gì khó. Một program có thể làm mọi chuyện, kể cả đóng Windows, vậy mấy trò mở cửa sổ in, in 100 bản, đóng cửa sổ nào đó, kết nối internet v...v thì có gì to tát.
Việc pm tạo EXE cũng không có gì lớn. Nếu tôii không lầm thì có thể làm như sau: EXE được tạo trước pm. Khi EXE khởi động thì nó nap chính nó từ đĩa cứng vào bộ nhớ --> nhẩy xuống cuối của mình (nhẩy bao nhiêu bai thì sẽ được ghi ở một "ô" định sẵn) --> đọc tất cả từ chỗ nhẩy tới cuối của EXE trên đĩa (EXE tạo trước pm và EXE ở trên đĩa là 2 EXE khác nhau, tạm gọi là A và B) --> ghi ra đĩa ở nơi kín đáo gọi là xyz.XLS --> khởi động XLS. Tác giả tạo EXE làm các việc trên xong (EXE A) thì kiểm tra xem nó có bao nhiêu bai (độ lớn EXE A) rồi ghi vào "ô" định sẵn ở trên (vd. dùng Hex Editor).
Bây giờ pm muốn gói XLS nào thì đọc EXE A (là "đồ" soạn trước) --> ghi thêm vào cuối EXE A toàn bộ XLS --> EXE A có thêm XLS được ghi trên đĩa với tên xyz.EXE (EXE B) và cung cấp cho người dùng. Khi khởi động xyz.EXE thì thực ra là EXE A chạy và nó làm tất cả các chuyện nói trên.
Cũng có thể tạo EXE A làm các việc: khi khởi động thì đọc resource (trong EXE) --> nếu có thì ghi lại trên đĩa với tên xyz.XLS --> khởi động XLS. Một EXE A như vậy khi tạo xong sẽ không có cái "resource - XLS" kia và khởi động nó chả làm gì cả. Nhưng pm khi có XLS rồi thì nó nạp EXE A kia (là "đồ" của nó) và "nhồi" vào nó resource (nhồi được, vd. bắt chước Resource Hacker), cuối cùng ghi lại EXE đó. EXE B này khi chạy thì do đã có resource nên nó ghi ra đĩa ở dạng XLS.
Như tôi đã nói thì chuyện pm làm được tất cả mọi chuyện "tầy đình" (in 100 bản, đóng Windows) là đương nhiên. Việc đó có thể làm bất cứ lúc nào, không cần cớ. Chuyện người ta dùng SetWindowsHookEx chỉ là muốn làm những việc "tầy đình" chỉ khi có một "sự kiện" nào đó sẩy ra. Nhưng vỏ quýt dầy có móng tay nhọn. SetWindowsHookEx hoạt động như sau: tất cả ai muốn theo dõi 1 sự kiện nào đó (bàn phím, chuột, cửa sổ ...) thì đăng ký với Windows (SetWindowsHookEx) và xếp hàng chờ. Khi sẩy ra sự kiện thì Windows thông báo cho anh A. Anh A có thể: làm gì đó nhân dịp này, vd. ghi vào sổ theo dõi. Hàm HookProc phải trả về một giá tri 0 hoặc 1. Nếu trả về 0 thì sự kiện được "báo" cho anh B. Anh B cũng làm những việc như A. Nếu tất cả các anh đăng ký đều trả về 0 thì sự kiện được "báo" cho cửa sổ đích (vd. người dùng nhấn trong Notepad phím "a" thì nó được báo cho Notepad). Nếu có anh D trả về 1 thì anh E, F, ... và cửa sổ đích sẽ không được thông báo. Vì trả về 1 có nghĩa là nói với Windows không truyền tiếp nữa. Nếu không được thông báo thì cái anh EXE tởm kia làm gì biết sự kiện để mà làm chuyện tầy đình nhi?
Vậy thì khi tôi gặp cái anh làm chuyện tầy đình kia thì tôi sẽ khởi động EXE của mình --> EXE đăng ký SetWindowsHookEx --> HookProc của tôi trả về 1 --> anh kia không được thông báo nữa. Mà nếu tôi "hứng" thì tôi làm chuyện tầy đình hơn: tôi tìm và tắt anh kia luôn. Chuyện cái gì đó được ghi ra đĩa thì ngay dùng công cụ của Windows cũng tìm ra được.
Ngoài chuyện "ghi vào sổ" thì pm có thể làm nhiều việc. Vd. chính Unikey đăng ký theo dõi bàn phím. Khi có phím nhấn thì nó được báo và nó kiểm tra. Vd. nếu đó là "u" thì nó ghi nhớ ("u" được báo cho cửa sổ đích vd. Notepad). Nếu lần tiếp theo nó thấy là "w" thì: nó simulate nhấn phím Backspace (notepad sẽ xóa "u") --> simulate ký tự "ư" - bằng cách gửi "vài bai" (notepad sẽ "nhập" "ư") v...v