Hàm GetWindowRect cho kết quả khác nhau ở các Version Excel (2 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Tôi tuân thủ nội quy khi đăng bài

Mr.hieudoanxd

Thành viên thường trực
Tham gia
25/10/19
Bài viết
346
Được thích
159
Em chào cả nhà!
Lâu rồi không hỏi đáp gì đó trên diễn đàn. Em có một băn khoăn nhỏ về hàm trong quá trình sử dụng API tìm kiếm các cửa sổ của Excel, phát hiện ra lỗi và chưa sửa được. Loay hoay mãi không ra kết quả hỏi các bác trên diễn đàn tìm lời khuyên phù hợp!
Cụ thể với hàm GetWindowRect cho kết quả RECT khác nhau ở các version Excel làm các thông số em lấy được từ hàm trên để sử dụng đưa ra kết quả sai lệch (như file em đính kèm). Các version Excel em có và đã test thử ra kết quả như em thống kê.
Vậy, em muốn biết liệu có cách nào khắc phục sai sót trên không? có hàm API khác hay hơn thay thế không?.

P/s Em đã thử vài hàm khác như GetClientRect (hàm này luôn có left và top = 0) không phù hợp với nhu cầu của em
 

File đính kèm

Ý tưởng của bác xác định theo ô "A1" em hiểu và đã từng làm theo phương pháp ấy. Tuy nhiên để thực hiện thì lại phát sinh nhiều lỗi. Ví dụ để show form đúng vị trí ô A1 thì ô A1 luôn phải nằm đúng vị trí trên cùng bên trái. Nếu trường hợp thanh scroll bar kéo qua kéo lại kéo lên kéo xuống thì useform đi ra xa bờ ngay lập tức. Bác thử mà xem
A1 là ví dụ chỉ dùng để dễ nói chuyện thôi, để nói cho ngắn gọn. Còn dụng ý của bạn thì tôi đã nói rất rõ, không thể rõ hơn: "Bạn ấy không muốn đặt ở "bên phải, bên trên, phía dưới, bên trái" của màn hình mà là của ActiveWindow.VisibleRange". Tức nếu ActiveWindow.VisibleRange = W26:AA31 (zoom = 400) thì đặt ở W26 ("bên trái" hoặc "phía trên")
 
Upvote 0
A1 là ví dụ chỉ dùng để dễ nói chuyện thôi, để nói cho ngắn gọn. Còn dụng ý của bạn thì tôi đã nói rất rõ, không thể rõ hơn: "Bạn ấy không muốn đặt ở "bên phải, bên trên, phía dưới, bên trái" của màn hình mà là của ActiveWindow.VisibleRange". Tức nếu ActiveWindow.VisibleRange = W26:AA31 (zoom = 400) thì đặt ở W26 ("bên trái" hoặc "phía trên")
Em cũng đã viết là em đã thử phương án trên rồi. Thế thì nhờ bác giải quyết tiếp tục với lỗi phát sinh thứ 2. ActiveWindow.VisibleRange=W26:AA31 tuy nhiên Scroll chuột thì lại để ở giữa dòng
 

File đính kèm

  • Untitled.png
    Untitled.png
    30.9 KB · Đọc: 2
Upvote 0
Cho dù bạn dùng SetParent thì cũng chỉ là thiết lập quan hệ cha - con. Lúc đó UserForm sẽ được định vị trong CLIENT AREA của CHA.
Để dễ nói chuyện ta lấy qui ước là bài đầu của tôi. CLIENT AREA của EXCEL7 có góc trên bên trái chính là điểm Q. Mà bạn muốn UserForm ở điểm P cơ mà. Bạn vẫn phải tính được a = "độ rộng của thanh tiêu đề hàng" (1, 2, 3, …), và b = "độ cao của thanh tiêu đề cột" (A, B, C, …). Lúc đó bạn phải thiết lập tọa độ của CON: Con.Left = a, Con.Top = b để CON dịch tới điểm P.

Nhưng nếu bạn biết cách tính a và b thì cần gì SETPARENT? Lúc đó theo như tôi viết ở bài đầu: "... vị trí của điểm Q, rồi từ đó thử "dịch một tí sang phải và một tí xuống dưới" để có Left và Top của P". "dịch một tí sang phải và một tí xuống dưới" hàm ý "dịch sang phải a đơn vị và dịch xuống dưới b đơn vị"

Và nên nhớ là khi dùng SETPARENT thì rất có thể sẽ phải có code để phục vụ các message (vd. nhấn nút ở đâu đó trên Form). Không dễ ăn đâu bạn. Tùy controls CON. Có những sự kiện về CON mà Windows gửi message tới CHA đấy. Mà làm sao can thiệp vào hàm cửa sổ của EXCEL7 bây giờ? SetWindowLong? Mà các controls trên UserForm không hẳn là các controls của Windows (Edit, ListBox, Button, …) nên chưa chắc khi sảy ra sự kiện với chúng thì Windows sẽ gửi message. Thậm chí ListBox VBA không phải là ListBox của Windows nên hàm cửa sổ của UserForm không phục vụ các message liên quan ListBox VBA

Tôi nghĩ là mấu chốt là tính được a và b. Dùng GetWindowRect để có rect. Lúc đó x = UserForm.Left (pixel) = rect.Left + a, y = UserForm.Top (pixel)= rect.top + b. Sau đó dùng MoveWindow hoặc SetWindowPos.
MoveWindow hwnd (UserFrom), x, y, ...
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom