2009-07-28 25 views
5

MSDN khuyên rằng chức năng RegisterWindowMessage() chỉ được sử dụng để đăng ký các tin nhắn được gửi giữa các quá trình. Nếu một tin nhắn là cần thiết để gửi trong một quá trình nó có thể được lựa chọn một cách an toàn từ phạm vi WM_APP thông qua 0xBFFF.Có thể lạm dụng RegisterWindowMessage dẫn đến cạn kiệt tài nguyên không?

Tuy nhiên trong codebase của chúng tôi, tôi thường thấy rằng RegisterWindowMessage() được sử dụng cho các thư chỉ được gửi trong một quá trình. Tôi cho rằng điều này đã được thực hiện vì sự đơn giản của việc sử dụng RegisterWindowMessage() vì nó không yêu cầu phân phối thủ công các định danh thông báo trong phạm vi WM_APP..0xBFFF. Tôi có hiểu chính xác rằng nếu nhiều ứng dụng được chạy trên một máy và tất cả chúng đều gọi RegisterWindowMessage() với các chuỗi khác nhau, chúng có thể loại bỏ phạm vi nhận dạng tin nhắn được phép trả lại bởi RegisterWindowMessage() và một số trong số đó trả lại một giá trị cho thấy một thất bại? Điều gì có thể là một lý do hợp lệ để sử dụng các thông điệp RegisterWindowMessage() trong trường hợp các tin nhắn phạm vi WM_APP..0xBFFF sẽ đủ?

Trả lời

4

IMHO không có lý do chính đáng để sử dụng RegisterWindowMessage nếu bạn chỉ gửi tin nhắn cho mình

Không có (tài liệu) cách để bỏ đăng ký một thông điệp, vì vậy sau khi ứng dụng của bạn bỏ, rằng thông điệp đăng ký sẽ ở lại trong bảng nguyên tử cho đến khi khởi động lại/đăng xuất (Tôi không thể nhớ chính xác vị trí bảng nguyên tử này được lưu trữ, phiên bản trạm cửa sổ hoặc phiên máy chủ đầu cuối có thể)

5

Lý do bạn cần sử dụng RegisterWindowMessage ngay cả khi nhắn tin cho chính mình là nó bảo vệ bạn khỏi kẻ ngốc phát những tin nhắn trong phạm vi WM_APP + N.

Có, điều này xảy ra.

3

Một lợi thế có thể là Spy ++ có thể hiển thị nhiều văn bản thông tin hơn, do đó việc gỡ lỗi sẽ dễ dàng hơn một chút. Hãy so sánh

<00058> 00330CA2 S message:0x0419 [User-defined:WM_USER+25] wParam:00000000 lParam:00000000 

với

<00129> 004F0DA0 S message:0xC2B0 [Registered:"AFX_WM_ONCHANGE_ACTIVE_TAB"] wParam:00000001 lParam:02B596E8 

Tất nhiên, về nguyên tắc có một cơ hội để chạy ra khỏi ID tin nhắn. Mặt khác, trong mã nguồn của Gói tính năng MFC có 52 cuộc gọi đến RegisterWindowMessage. Vì vậy, vẫn còn 16300 ID còn lại cho các ứng dụng khác.

5

Lợi dụng RegisterWindowMessage có khả năng làm cho hộp cửa sổ trở nên vô giá. Điều này đặc biệt đúng nếu các tên thông báo của cửa sổ được tạo động và một lỗi gây ra sự phân bổ thông báo của cửa sổ điều khiển. Trong trường hợp này bảng nguyên tử toàn cục trong cửa sổ trạm/máy tính để bàn của bạn sẽ lấp đầy và bất kỳ quá trình sử dụng User32.dll (về cơ bản, bất kỳ ứng dụng nào) sẽ không khởi động được, tạo cửa sổ, v.v. Các sản phẩm Delphi/Borland đăng ký các thông điệp bắt đầu bằng ControlOfsXXXXXX, trong đó XXXX là một địa chỉ bộ nhớ (hoặc công cụ sửa đổi động khác). Các ứng dụng được bắt đầu và dừng lại thường xuyên sẽ đăng ký nhiều nguyên tử ControlOfsXXXX và cuối cùng là xả không gian nguyên tử. Để biết thêm chi tiết xem:

http://blogs.msdn.com/b/ntdebugging/archive/2012/01/31/identifying-global-atom-table-leaks.aspx

https://forums.embarcadero.com/thread.jspa?threadID=47678

+0

Không biết về điều đó lỗi trong C++ Builder/Delphi! Nasty ... –

+0

C++ Builder/Delphi (VCL) tạo tên tin nhắn từ 'HInstance' (' GetModuleHandle') và ID chủ đề.Đối với thực thi bình thường, 'HInstance' không thay đổi và phạm vi của các ID luồng bị giới hạn, không chắc rằng ứng dụng VCL làm cạn kiệt bảng nguyên tử. Đáng tin cậy hơn là nó trong trường hợp DLL được xây dựng trong VCL. Hoặc khi tập tin thực thi có ASLR (yêu cầu chứng nhận Windows 8 là gì). –

Các vấn đề liên quan