HeSanbi
Nam Nhân✨Hiếu Lễ Nghĩa Trí Tín✨
- Tham gia
- 24/2/13
- Bài viết
- 2,700
- Được thích
- 4,256
- Giới tính
- Nam
Nếu các bạn đang hăng say học VBA hoặc đang lập trình VBA và vọc mã WinAPI thì hãy học ngay mẹo này để viết cho ứng dụng của bạn gọn nhẹ hơn. Khi ứng dụng của bạn viết đa nền tảng và đa phiên bản thì gặp phải nhiều vấn đề về tương thích. Nhất là khai báo Long, LongPtr, LongLong, hoặc các hàm VarPtr, StrPtr, ...
Hoặc các bạn cần bộ nhớ kiểu biến lớn hơn là LongLong trong dự án của bạn. Để tận dụng vào các thuật toán mà bạn tạo ra.
Với mẹo vô cùng đơn giản dưới đây là các bạn có thể bỏ qua các dòng mã rườm rà làm mã của bạn rối và khó đọc.
Đơn giản thôi các bạn hãy thêm dòng mã sau vào bất kì dự án nào của bạn có sử dụng các API 32 và 64 bit.
***Lưu ý: Khi các bạn chép mã vào VBA, nếu các dòng mã Hiện màu đỏ là bình thường nhé. VBA sẽ không thông dịch mã đó, vì hệ điều hành của các bạn tương thích mã đủ điều kiện.
(Mã này không nên đặt vào module có khai báo cục bộ là Option Private Module.
Vì sẽ không thể khai báo tham chiếu biến trong Class và Module Object (Sheet, Form).
Hãy chạy thử thủ tục TestPretreatment dưới đây để xem thông tin máy tính và Office
Như đã nói trên, chỉ cần các bạn khai báo như vậy là có thể viết những dòng mã tương thích đa nền tảng mà không cần phải nhờ đến hai PC hoặc hai ứng dụng khác phiên bản để kiểm thử mã, sau khi đã viết mã tương thích.
Ví dụ khai báo như sau, sẽ làm cho mã bị rối và dài:
Bạn chỉ cần khai báo như sau, khi đã chép mã đã nói trên:
Các khai báo trước đây, như dưới đây hãy bỏ nó đi:
Và bây giờ các bạn chỉ cần khai báo, khi có mã đã nói trên, là đủ để tương thích, mà không cần khai báo tiền xử lý #:
Với mẹo khai báo biến Long như vậy, các bạn có thể chép lại mã có các API với các tham số biến LongPtr, LongLong rất đơn giản.
Nếu các bạn chép mã API đang ở nền tảng win64, thì chỉ cần bỏ PtrSafe trong dòng mã để tương thích với Nền tảng win32 (Còn tùy thuộc vào hàm API, có hàm API không có ở Win32).
Bạn không cần sửa LongPtr, LongLong thành Long để tương thích với win32 nữa. Khi đã có mã nói trên.
Lưu ý: Sửa từ API không có PtrSafe sang API có PtrSafe thì có những trường hợp Long phải sửa thành LongPtr hoặc LongLong
Ví dụ khai báo tương thích và các hàm API tương thích đa nền tảng:
Có thể các bạn đang hỏi tại sao lại có kiểu LongPtr. Đơn giản thôi, nó là kiểu khai báo tương thích. Nếu LongPtr ở môi trường 32 bit thì nó là Long, nếu nó ở 64bit thì nó là LongLong. Nó không thực sự là Long và LongLong.
Ngay từ lúc này tôi khuyên các bạn nên tận dụng Kiểu LongLong vì nó khai thác bộ nhớ lớn hơn Long khá nhiều.
Vì khi bạn đang sử dụng Win64 mà lại dùng kiểu Long cho một thuật toán mạnh mẽ thì thật là tiếc nuối cho đà phát triển của bạn.
Mẹo tôi hướng dẫn trên đây sẽ giúp các bạn đơn giản việc viết mã đa nền tảng, các bạn có thể tận dụng nó trên con đường lập trình của mình.
Chúc các bạn thành công!
-------------------------------------------
Các bạn có thể tham khảo thêm bài viết của tôi tại tag #sanbi udf
Hoặc các bạn cần bộ nhớ kiểu biến lớn hơn là LongLong trong dự án của bạn. Để tận dụng vào các thuật toán mà bạn tạo ra.
Với mẹo vô cùng đơn giản dưới đây là các bạn có thể bỏ qua các dòng mã rườm rà làm mã của bạn rối và khó đọc.
Đơn giản thôi các bạn hãy thêm dòng mã sau vào bất kì dự án nào của bạn có sử dụng các API 32 và 64 bit.
JavaScript:
#If VBA7 = 0 Then
Public Enum LongLong:[__]:End Enum
Public Enum LongPtr:[_]:End Enum
#End If
***Lưu ý: Khi các bạn chép mã vào VBA, nếu các dòng mã Hiện màu đỏ là bình thường nhé. VBA sẽ không thông dịch mã đó, vì hệ điều hành của các bạn tương thích mã đủ điều kiện.
(Mã này không nên đặt vào module có khai báo cục bộ là Option Private Module.
Vì sẽ không thể khai báo tham chiếu biến trong Class và Module Object (Sheet, Form).
Hãy chạy thử thủ tục TestPretreatment dưới đây để xem thông tin máy tính và Office
JavaScript:
Sub TestPretreatment ()
#If VBA7 Then
#If Win64 Then
Debug.Print "VBA7 64bit"
#Else
Debug.Print "VBA7 32Bit"
#End If
#ElseIf VBA6 Then
#If Win64 Then
Debug.Print "VBA6 64bit"
#Else
Debug.Print "VBA6 32Bit"
#End If
#Else
Debug.Print "________"
#End If
End Sub
Như đã nói trên, chỉ cần các bạn khai báo như vậy là có thể viết những dòng mã tương thích đa nền tảng mà không cần phải nhờ đến hai PC hoặc hai ứng dụng khác phiên bản để kiểm thử mã, sau khi đã viết mã tương thích.
Ví dụ khai báo như sau, sẽ làm cho mã bị rối và dài:
JavaScript:
#If VBA7 And Win64 Then
Private Sub TimeProc_ApiWindowFlexMove(ByVal hwnd As LongPtr, ByVal wMsg^, ByVal idEvent As LongPtr, ByVal dwTime^)
#ElseIf VBA7 Then
Private Sub TimeProc_ApiWindowFlexMove(ByVal hwnd As LongPtr, ByVal wMsg&, ByVal idEvent As LongPtr, ByVal dwTime&)
#Else
Private Sub TimeProc_ApiWindowFlexMove(ByVal hwnd&, ByVal wMsg&, ByVal idEvent&, ByVal dwTime&)
#End If
End Sub
Bạn chỉ cần khai báo như sau, khi đã chép mã đã nói trên:
JavaScript:
Private Sub TimeProc_ApiWindowFlexMove(ByVal hwnd As LongPtr, ByVal wMsg As LongLong, ByVal idEvent As LongPtr, ByVal dwTime As LongLong)
End Sub
Các khai báo trước đây, như dưới đây hãy bỏ nó đi:
JavaScript:
#If VBA7 Then
Dim hwnd As LongPtr
#Else
Dim hwnd As Long
#End If
Và bây giờ các bạn chỉ cần khai báo, khi có mã đã nói trên, là đủ để tương thích, mà không cần khai báo tiền xử lý #:
JavaScript:
Dim hwnd As LongPtr
Với mẹo khai báo biến Long như vậy, các bạn có thể chép lại mã có các API với các tham số biến LongPtr, LongLong rất đơn giản.
Nếu các bạn chép mã API đang ở nền tảng win64, thì chỉ cần bỏ PtrSafe trong dòng mã để tương thích với Nền tảng win32 (Còn tùy thuộc vào hàm API, có hàm API không có ở Win32).
Bạn không cần sửa LongPtr, LongLong thành Long để tương thích với win32 nữa. Khi đã có mã nói trên.
Lưu ý: Sửa từ API không có PtrSafe sang API có PtrSafe thì có những trường hợp Long phải sửa thành LongPtr hoặc LongLong
Ví dụ khai báo tương thích và các hàm API tương thích đa nền tảng:
JavaScript:
' Khai báo tương thích đa nền tảng
#If VBA7 = 0 Then
Public Enum LongLong:[__]:End Enum
Public Enum LongPtr:[_]:End Enum
#End If
' Các hàm API tương thích đa nền tảng
#If VBA7 Then
Private Declare PtrSafe Function IUnknown_GetWindow Lib "shlwapi" Alias "#172" (ByVal pIUnk As Any, ByVal hwnd As LongPtr) As Long
#Else
Private Declare Function IUnknown_GetWindow Lib "shlwapi" Alias "#172" (ByVal pIUnk As Any, ByVal hwnd As LongPtr) As Long
#End If
#If VBA7 Then
#If Win64 Then
Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
Declare PtrSafe Function GetClassLong Lib "user32" Alias "GetClassLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
Private Declare PtrSafe Function SetClassLong Lib "user32" Alias "SetClassLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare PtrSafe Function GetClassLong Lib "user32" Alias "GetClassLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function SetClassLong Lib "user32" Alias "SetClassLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#End If
#Else
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetClassLong Lib "user32" Alias "GetClassLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetClassLong Lib "user32" Alias "SetClassLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#End If
Có thể các bạn đang hỏi tại sao lại có kiểu LongPtr. Đơn giản thôi, nó là kiểu khai báo tương thích. Nếu LongPtr ở môi trường 32 bit thì nó là Long, nếu nó ở 64bit thì nó là LongLong. Nó không thực sự là Long và LongLong.
Ngay từ lúc này tôi khuyên các bạn nên tận dụng Kiểu LongLong vì nó khai thác bộ nhớ lớn hơn Long khá nhiều.
Vì khi bạn đang sử dụng Win64 mà lại dùng kiểu Long cho một thuật toán mạnh mẽ thì thật là tiếc nuối cho đà phát triển của bạn.
Mẹo tôi hướng dẫn trên đây sẽ giúp các bạn đơn giản việc viết mã đa nền tảng, các bạn có thể tận dụng nó trên con đường lập trình của mình.
Chúc các bạn thành công!
-------------------------------------------
Các bạn có thể tham khảo thêm bài viết của tôi tại tag #sanbi udf
Lần chỉnh sửa cuối: