2013-07-24 32 views
13

Tôi biết một phương pháp ngăn hộp thoại MFC đóng khi các phím Nhập hoặc Esc được nhấn, nhưng tôi muốn biết thêm chi tiết về quy trình và tất cả các phương pháp thay thế phổ biến để làm như vậy.Làm thế nào để ngăn chặn đóng hộp thoại MFC trên các phím Enter và Escape?

Cảm ơn trước vì đã được trợ giúp.

+3

Cho rằng có hai câu trả lời mà dường như để giải quyết các vấn đề cao bình chọn, tôi không chắc chắn những gì này đã bị đóng không rõ ràng. –

+1

Đó là cách * quá dễ dàng đối với những người có * không có đầu mối * để bỏ phiếu cho các câu hỏi gần như không rõ ràng. – rustyx

Trả lời

26

Khi người dùng nhấn phím Enter trong một hộp thoại hai điều có thể xảy ra:

  1. Hộp thoại có một điều khiển mặc định (xem CDialog::SetDefID()). Sau đó, WM_COMMAND có ID của điều khiển này được gửi đến hộp thoại.
  2. Hộp thoại không có điều khiển mặc định. Sau đó WM_COMMAND với ID = IDOK được gửi đến hộp thoại.

Với tùy chọn đầu tiên, có thể xảy ra điều khiển mặc định có ID bằng IDOK. Sau đó, kết quả sẽ giống nhau trong tùy chọn thứ hai.

Theo mặc định, lớp CDialog có một handler cho WM_COMMAND(IDOK) đó là gọi để CDialog::OnOk(), đó là một hàm ảo, và theo mặc định nó gọi EndDialog(IDOK) đó đóng hộp thoại.

Vì vậy, nếu bạn muốn tránh hộp thoại bị đóng, hãy thực hiện một trong các thao tác sau.

  1. Đặt điều khiển mặc định thành khác IDOK.
  2. Đặt trình xử lý cho WM_COMMAND(IDOK) không gọi EndDialog().
  3. Ghi đè CDialog::OnOk() và không gọi triển khai cơ sở.

Giới thiệu IDCANCEL, nó tương tự nhưng không tương đương SetDefID() và phím ESC được mã hóa cứng. Vì vậy, để tránh hộp thoại bị đóng:

  1. Đặt trình xử lý cho WM_COMMAND(IDCANCEL) không gọi EndDialog().
  2. Ghi đè CDialog::OnCancel() và không gọi triển khai cơ sở.
22

Có một giải pháp thay thế cho câu trả lời trước, rất hữu ích nếu bạn vẫn muốn có nút OK/Đóng. Nếu bạn ghi đè lên các chức năng PreTranslateMessage, bạn có thể bắt việc sử dụng VK_ESCAPE/VK_RETURN như vậy:

BOOL MyCtrl::PreTranslateMessage(MSG* pMsg) 
{ 
    if(pMsg->message == WM_KEYDOWN) 
    { 
     if(pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE) 
     { 
      return TRUE;    // Do not process further 
     } 
    } 

    return CWnd::PreTranslateMessage(pMsg); 
} 
+2

Không chắc chắn những gì bạn muốn thực hiện ở đây, nhưng nó có lẽ được thực hiện tốt hơn với 'WM_GETDLGCODE'. – rodrigo

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