Đăng nhập với Microsoft
Đăng nhập hoặc tạo một tài khoản.
Xin chào,
Chọn một tài khoản khác.
Bạn có nhiều tài khoản
Chọn tài khoản bạn muốn đăng nhập.

Triệu chứng

Thanh cuộn liên tục cuộn ngay sau khi bạn nhả nút chuột trái. Loại thanh cuộn không liên quan đến vấn đề này, tức là vấn đề xảy ra bất kể của thanh cuộn là một phần của cửa sổ hoặc là điều khiển thanh cuộn.

Nguyên nhân

Sự cố này thường xảy ra khi một vòng lặp chuyển phát thư được thực thi là kết quả của các hành động được thực hiện để cuộn khi nhận được một trong các thư thông báo của thanh cuộn. Khi cuộn, một vòng lặp chuyển phát tin nhắn nội bộ được bắt đầu trong Windows. Nhiệm vụ của vòng lặp thư này là giữ theo dõi cuộn và gửi các thư thông báo thanh cuộn thích hợp, WM_HSCROLL và WM_VSCROLL. Cuộn đã bị chấm dứt khi nhận được WM_LBUTTONUP. Nếu một vòng lặp thư khác được khởi động trong khi cuộn, WM_LBUTTONUP sẽ được truy xuất bằng thư báo tin nhắn đó, và vì một ứng dụng không có quyền truy nhập vào vòng lặp gửi tin nhắn nội bộ của thanh cuộn, WM_LBUTTONUP không thể được gửi chính xác. Vì vậy, WM_LBUTTONUP sẽ không bao giờ nhận được bằng thông báo nội bộ Retriever, và cuộn không bao giờ kết thúc. Ứng dụng đang di chuyển không phải để truy xuất thư một cách rõ ràng để gây ra sự cố này. Gọi bất kỳ hàm nào sau đây hoặc xử lý bất kỳ thư nào có vòng lặp truy xuất thông điệp, trong khi cuộn, có thể làm cho việc WM_LBUTTONUP bị mất. Các hàm được liệt kê dưới đây rơi vào thể loại này:

DialogBox() DialogBoxIndirect() DialogBoxIndirectParam() DialogBoxParam() GetMessage() MessageBox() PeekMessage()

Giải pháp

Khi cuộn, thông báo WM_LBUTTONUP sẽ không được truy xuất từ hàng đợi bằng bất kỳ vòng lặp nào đã truy xuất thư nào khác với thanh cuộn bên trong. Một ứng dụng có thể gặp vấn đề này như sau:

  • Một ứng dụng sẽ thực hiện một vòng lặp chuyển phát thư để triển khai xử lý nền, ví dụ, xử lý nền trong khi thực hiện một sơn tốn thời gian.

  • Một ứng dụng sẽ thực hiện một vòng lặp chuyển phát thư để thực hiện liên lạc với một ứng dụng hoặc DLL khác. Ví dụ, để cuộn, ứng dụng cần nhận dữ liệu từ những nơi khác.

Giải pháp thay thế có thể xảy ra

Hai giải pháp thay thế có thể được liệt kê dưới đây. Giải pháp thay thế đầu tiên được dùng bởi nhiều ứng dụng thoát và bởi Windows; Tuy nhiên, trong những trường hợp hiếm có có thể không phải là một khả thi. Trong trường hợp này, giải pháp thay thế thứ hai có thể được sử dụng. Tuy nhiên, nếu có thể, vui lòng thử tránh thực hiện việc truy xuất thư hoàn toàn khi cuộn.

  • Sử dụng bộ định giờ-xử lý dựa trên tin nhắn. Ngắt việc xử lý phức tạp thành các nhiệm vụ nhỏ hơn và theo dõi trong đó mỗi nhiệm vụ bắt đầu và kết thúc, sau đó thực hiện mỗi nhiệm vụ dựa trên một thư hẹn giờ. Khi tất cả các cấu phần của quá trình xử lý hoàn tất, hãy giết bộ hẹn giờ. Xem mục dưới đây để biết một ví dụ về giải pháp thay thế này.

  • Thực hiện một vòng lặp lại thông báo, nhưng đảm bảo rằng WM_LBUTTONUP không được truy xuất. Có thể thực hiện điều này bằng cách sử dụng bộ lọc. Xem mục dưới đây để biết một số ví dụ về giải pháp thay thế này.

Ví dụ về giải pháp thay thế 1

Một ứng dụng có một thủ tục sơn phức tạp. Cửa sổ gọi cuộn () để cuộn, tạo thông điệp vẽ. Xử lý nền diễn ra trong khi vẽ hình.

  1. Khi bạn nhận được thông báo WM_PAINT thực hiện như sau:

    1. Gọi BeginPaint ().

    2. Sao chép bỏ chọn không xác thực đến biến số toàn cầu (ví dụ: Grxpaint) sẽ được sử dụng trong bước 2. Grxpaint Global rect sẽ là một liên minh của rect đã thu được trước đó (GRC Paint) và các rect inxác thực mới (PS. rcPaint). Mã cho thao tác này sẽ giống như sau:

               RECT grcPaint;    // Should be initialized before getting the                           // first paint message.            :            :         UnionRect(&grcPaint, &ps.rcPaint,&grcPaint);
    3. Validatdựng cuộc gọi () có PS. rcPaint.

    4. Gọi cuối cuộc gọi ().

    5. Đặt hẹn giờ.

    Bằng cách này, không có thêm WM_PAINT thư nào được tạo ra, vì không có khu vực không hợp lệ và một bộ hẹn giờ được thiết lập, sẽ tạo ra các thư WM_TIMER.

  2. Khi nhận được thông báo WM_TIMER, hãy kiểm tra biến số trực tiếp toàn cầu; Nếu không có trống, hãy chụp một phần và vẽ. Sau đó, hãy điều chỉnh biến số ẩn toàn cầu để không còn bao gồm khu vực vẽ.

  3. Sau khi biến số ẩn toàn cầu bị trống thì hãy giết bộ hẹn giờ.

Ví dụ chứng minh giải pháp thay thế 2

Một ứng dụng cần có để có được một số dữ liệu thông qua DDE hoặc một số cơ chế khác từ một ứng dụng khác, sau đó sẽ được hiển thị trong cửa sổ. Để cuộn, ứng dụng cần yêu cầu và lấy dữ liệu từ một ứng dụng máy chủ. Có ba bộ lọc khác nhau có thể được dùng để thiết lập một tin nhắn () và nhận được thông tin. Có thể thiết lập bộ lọc bằng cách sử dụng tham số uFilterFirst và uFilterLast của PeekMessage (). uFilterFirst chỉ định tin nhắn viết tay trong phạm vi để được kiểm tra và uFilterLast chỉ định thư cuối cùng trong phạm vi được kiểm tra.

  1. Kiểm tra và chỉ truy xuất (các) thư liên quan để lấy dữ liệu cần thiết.

  2. Kiểm tra WM_LBUTTONUP mà không loại bỏ biểu mẫu của hàng; Nếu nó nằm trong hàng đợi, hãy ngắt. Nếu không, hãy truy xuất và gửi lại tất cả các thư.

  3. Truy xuất tất cả các thư nhỏ hơn WM_LBUTTONUP và lớn hơn WM_LBUTTONUP nhưng không truy xuất WM_LBUTTONUP.

Thông tin Bổ sung

Các bước để tái tạo vấn đề

Sau đây là trình tự các sự kiện dẫn đến việc mất thông báo WM_LBUTTONUP:

  1. Bấm vào thanh cuộn bằng chuột.

  2. Bước 1 tạo một thông điệp WM_NCLBUTTONDOWN.

  3. Bước 2 sẽ khiến cho một vòng lặp trong Windows Message được bắt đầu. Vòng lặp tin nhắn này tìm kiếm các thư liên quan đến cuộn-Bar. Mục đích của vòng lặp thư này là tạo ra WM_HSCROLL thích hợp hoặc WM_VSCROLL tin nhắn. Vòng lặp thông báo và việc di chuyển chấm dứt khi đã nhận được WM_LBUTTONUP.

  4. Khi nhận được thông báo WM_HSCROLL hoặc WM_VSCROLL, ứng dụng này sẽ được truy nhập vào một vòng lặp chuyển phát thư trực tiếp hoặc các hàm cuộc gọi dẫn đến việc truy xuất thư.

  5. WM_LBUTTONUP được loại bỏ khỏi hàng đợi bằng cách lặp thư đã đề cập trong bước 4. Sau đó, WM_LBUTTONUP được cử đến.

  6. Là kết quả của bước 5 WM_LBUTTONUP tin nhắn được chuyển đến những nơi khác và lặp lại thông báo nội bộ, được đề cập trong bước 3 không bao giờ nhận được. Vòng lặp thư trong bước 3 đang tìm kiếm WM_LBUTTONUP để ngừng cuộn. Vì nó không nhận được, thanh cuộn vẫn tiếp tục cuộn.

Bạn cần thêm trợ giúp?

Phát triển các kỹ năng của bạn

KHÁM PHÁ NỘI DUNG ĐÀO TẠO >

Sở hữu tính năng mới đầu tiên

THAM GIA NGƯỜI DÙNG NỘI BỘ MICROSOFT 365 >

Thông tin này có hữu ích không?

Bạn hài lòng đến đâu với chất lượng dịch thuật?
Điều gì ảnh hưởng đến trải nghiệm của bạn?

Cảm ơn phản hồi của bạn!

×