Từ code của anh Batman1, mình test thì với Excel 32-bit thì chạy tốt nhưng để chạy chạy trên Windows 10 64-bit, Excel 64 bit thì cần chỉnh như sau: Chỉnh sửa nhánh #VBA7, #WIN64:
SetWindowLongA thành SetWindowLongPtrA
Function WindowProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
thành
Function WindowProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, _
ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Từ code của anh Batman1, mình test thì với Excel 32-bit thì chạy tốt nhưng để chạy chạy trên Windows 10 64-bit, Excel 64 bit thì cần chỉnh như sau: Chỉnh sửa nhánh #VBA7, #WIN64:
SetWindowLongA thành SetWindowLongPtrA
Function WindowProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
thành
Function WindowProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, _
ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Đúng là bây giờ nhìn lại mới thấy khai báo sai:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Nhưng bạn sửa lại vẫn chưa đúng.
Tôi chạy code đã sửa khai báo của bạn:
1. Trên Windows 10 64 bit + Excel 2007 32 bit thì không có lỗi. Cũng dễ hiểu vì Excel 2007 thì sẽ dùng SetWindowLong ở nhánh #Else nên không có lỗi.
2. Tôi chạy trên XP 32 bit + Excel 2010 32 bit thì có lỗi
3. Tôi chạy trên Windows 8 32 bit + Excel 2013 32 bit thì có lỗi
Tôi đề nghị những ai có office 64 thử như sau:
Thay
Mã:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
trong khai báo của Tuân bằng
Mã:
#If Win64 Then
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If
Có một sơ suất mình upload file của bản chưa cập nhật phần chỉnh tương thích môi trường 32-bit mặc dù bản chính thức đã sửa. Bác Batman1 báo lại mình mới kiểm tra lại file upload là lỗi. Các bạn tải lại file trong bài này nhé.
Đúng là bây giờ nhìn lại mới thấy khai báo sai:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Nhưng bạn sửa lại vẫn chưa đúng.
Tôi chạy code đã sửa khai báo của bạn:
1. Trên Windows 10 64 bit + Excel 2007 32 bit thì không có lỗi. Cũng dễ hiểu vì Excel 2007 thì sẽ dùng SetWindowLong ở nhánh #Else nên không có lỗi.
2. Tôi chạy trên XP 32 bit + Excel 2010 32 bit thì có lỗi
Tôi đề nghị những ai có office 64 thử như sau:
Thay
Mã:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
trong khai báo của Tuân bằng
Mã:
#If Win64 Then
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If
Liên quan tới api cho cháu hỏi một chút, một số api nhận tham số từ ngăn xếp, một số lại nhận tham số theo dạng thanh ghi eax, ecx... gì gì đấy. Vậy hai loại này khác nhau ở đâu, và làm sao vba nó biết cái api thuộc loại nào để nó gọi cho phù hợp.
Liên quan tới api cho cháu hỏi một chút, một số api nhận tham số từ ngăn xếp, một số lại nhận tham số theo dạng thanh ghi eax, ecx... gì gì đấy. Vậy hai loại này khác nhau ở đâu, và làm sao vba nó biết cái api thuộc loại nào để nó gọi cho phù hợp.
Cháu đang muốn nói tới calling conventions đó bác. Trong khai báo api với vba cháu không thấy có cái từ khóa nào liên quan tới calling conventions, phải chăng vba nó tự đoán được calling conventions của api để gọi cho phù hợp?
Cháu đang muốn nói tới calling conventions đó bác. Trong khai báo api với vba cháu không thấy có cái từ khóa nào liên quan tới calling conventions, phải chăng vba nó tự đoán được calling conventions của api để gọi cho phù hợp?