Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 10 của 10
  1. #1

  2. #2
    Bác thử post cái đoạn source code đó lên xem nào.

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    ở lớp dialog á!

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    NÈ! mã của nó đây!
    http://www.box.net/shared/3go0mq1cm5
    Về cái bàn phím thì tui có thử tạo bảng phím nhưng tới hồi xử lý chả được. Khi lấy nguyên bảng trạng thái bàn phím thì làm được. Thiết nghĩ, có lẽ, các phần mềm thường làm bằng cái này


    Ở trường và ở tiệm, chức năng đính kèm file của diễn đàn đều 0 được. "Việc upload file bị thất bại". file rar chỉ cỡ 40kb nhưng 0 sao upload được. Dùng IE ở trường, dùng FF ở tiệm

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Chương trình của bác nó không chịu xử lý phím là đúng rồi, bởi vì khi bác chạy một chương trình bất kỳ, cửa sổ (window) nhận các message là cửa sổ có "input focus" (tại một thời điểm, đối với một ct cụ thể, chỉ có đúng một thằng là có input focus).

    Program này có tất cả là 4 cửa sổ : cửa sổ ứng dụng chính (dialog window), 2 button (Ok và Cancel) và một static text. Static text thì đương nhiên không thể nhận input focus nên một trong 3 thằng còn lại sẽ có. Và bác thử đoán xem là thằng nào ? Chính là Button Ok và đây là nguyên nhân khiến cho các thông điệp bàn phím không tài nào "bò" đến được cửa sổ chính.

    Bác có thể kiểm tra điều này rất dễ bằng cách thêm vào code sau (trong file hoptoai1Dlg.cpp):

    Mã:
    WNDPROC OldButtonOkProc;
    LRESULT CALLBACK NewButtonOkProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    		/*case WM_KEYDOWN:
    			::MessageBox (NULL, TEXT ("Where are you, WM_KEYDOWN ?"), TEXT ("Thuongsoo"), MB_OK);
    			::MessageBox (NULL, TEXT ("I'm here, thuongsoo"), TEXT ("WM_KEYDOWN"), MB_OK);
    			break;*/
    		
    		case WM_KEYUP:
    			::MessageBox (NULL, TEXT ("Where are you, WM_KEYUP ?"), TEXT ("Thuongsoo"), MB_OK);
    			::MessageBox (NULL, TEXT ("I'm sorry I can contact you, thuongsoo."), TEXT ("WM_KEYUP"), MB_OK);
    			break;
    
    		default:
    			break;		
    	}
    	return ::CallWindowProc (OldButtonOkProc, hwnd, message, wParam, lParam);
    }
    Sửa lại OnInitDialog:
    Mã:
    BOOL CHoptoai1Dlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// Set the icon for this dialog.  The framework does this automatically
    	//  when the application's main window is not a dialog
    	SetIcon(m_hIcon, TRUE);			// Set big icon
    	SetIcon(m_hIcon, FALSE);		// Set small icon
    	
    	// TODO: Add extra initialization here
    	OldButtonOkProc = (WNDPROC) SetWindowLong (HWND (m_ButtonOk.m_hWnd), GWL_WNDPROC, LONG (NewButtonOkProc));
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
    Bây giờ bác thử ấn các phím xem sẽ thấy "khác" ngay.

    Giải pháp: Dùng accelerator (bảng phím ?).

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Xin lỗi mọi người vì quá lâu mà 0 vô đây! thiệt tình thì có vô nhưng 0 có máy ở gần nên 0 thể kiểm tra được

    @ilovecplusplus: Tui đang viết MFC nên đâu có xài winproc được ? Tui 0 truy cập được m_buttonOk, tui cũng 0 biết làm sao để truy cập nút này trong lớp CDialog.

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bác sửa :
    Mã:
    OldButtonOkProc = (WNDPROC) SetWindowLong (HWND (m_ButtonOk.m_hWnd), GWL_WNDPROC, LONG (NewButtonOkProc));
    thành :
    Mã:
    OldButtonOkProc = (WNDPROC) SetWindowLong (HWND (*GetDlgItem (IDOK)), GWL_WNDPROC, LONG (NewButtonOkProc));
    Thuongsoo viết:
    Tui đang viết MFC nên đâu có xài winproc được ? Tui 0 truy cập được m_buttonOk, tui cũng 0 biết làm sao để truy cập nút này trong lớp CDialog.

    1. MFC thực chất là Win32API Wrapper. Hơn nữa, nếu bác viết ct trên Win thì bất cứ control nào cũng có hwnd và một winproc tương ứng (cho dù ct đó có viết bằng language không phải là C++). Tóm lại, MFC or không thì cũng đều có winproc và đoạn code trên của tui đơn giản là "nối" thêm một ít lệnh vào cái winproc có sẵn của Button Ok sau khi đã biết cái hwnd của nó.

    2. Chắc bác mới dùng MFC ? Nếu vậy, ráng lên mạng tìm tài liệu (codeproject rất tuyệt) về nó. Khuyến nghị nên dùng tài liệu tiếng Anh vì tài liệu tiếng Việt đều chỉ dịch lại thôi mà nhiều khi dịch đến "lởm" (chưa kể nhiều khi còn không thèm ghi tên sách + tác giả của bản gốc tiếng Anh). Một trong số những ebook tương đối tốt về MFC mà bác có thể tìm là Programming Windows with MFC (Author: Jeff Prosise, Publisher: Microsoft Press).

    Gook luck!

  8. #8
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Cảm ơn ilovecplusplus rất nhiều!
    tui vẫn chưa hiểu về đoạn mã sẽ thêm vô
    Mã:
    WNDPROC OldButtonOkProc;
    LRESULT CALLBACK NewButtonOkProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    		/*case WM_KEYDOWN:
    			::MessageBox (NULL, TEXT ("Where are you, WM_KEYDOWN ?"), TEXT ("Thuongsoo"), MB_OK);
    			::MessageBox (NULL, TEXT ("I'm here, thuongsoo"), TEXT ("WM_KEYDOWN"), MB_OK);
    			break;*/
    		
    		case WM_KEYUP:
    			::MessageBox (NULL, TEXT ("Where are you, WM_KEYUP ?"), TEXT ("Thuongsoo"), MB_OK);
    			::MessageBox (NULL, TEXT ("I'm sorry I can contact you, thuongsoo."), TEXT ("WM_KEYUP"), MB_OK);
    			break;
    
    		default:
    			break;		
    	}
    	return ::CallWindowProc (OldButtonOkProc, hwnd, message, wParam, lParam);
    }
    Sửa lại OnInitDialog:

    Mã:
    BOOL CHoptoai1Dlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// Set the icon for this dialog.  The framework does this automatically
    	//  when the application's main window is not a dialog
    	SetIcon(m_hIcon, TRUE);			// Set big icon
    	SetIcon(m_hIcon, FALSE);		// Set small icon
    	
    	// TODO: Add extra initialization here
    	OldButtonOkProc = (WNDPROC) SetWindowLong (HWND (*GetDlgItem (IDOK)), GWL_WNDPROC, LONG (NewButtonOkProc));
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
    Hình như làm vậy thì cái window procedure của button OK vẫn chưa được sửa đúng hôn ? Vì tui thấy đâu có chỗ nào gọi hàm OldButtonOkProc? và hàm NewButtonOkProc?
    Làm sao gán lại hàm xử lý mới lại cho button OK?

  9. #9
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    1. Window Procedure mới của button Ok không làm gì cả. Tất cả những gì nó làm gọi lại Window Procedure cũ của button Ok (thông qua câu lệnh CallWindowProc). Việc "nối" mã lệnh chỉ được thực hiện trong trường hợp message là WM_KEYUP (or WM_KEYDOWN).

    2. Hàm SetWindowLong dùng để thay thế một giá trị "LONG" nào đó thuộc sở hữu của một cửa sổ bất kỳ. Giá trị trả về từ SetWindowLong chính là giá trị "LONG" cũ. Trong tình huống trên, tui đã dùng SetWindowLong để thay window procedure của nút Ok nhưng bản chất là thay địa chỉ của Window Procedure (địa chỉ của một hàm trong Win32 App cũng là một số LONG (32 bit)). Vì thế, giá trị trả về từ SetWindowLong sẽ là địa chỉ của Window Procedure cũ. Nhờ vậy, việc "nối" mã lệnh mới có thể thực hiện được.

    3. Prototype của một Window Procedure luôn có dạng:
    Mã:
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
    CALLBACK có nghĩa là Window Procedure sẽ không được gọi bởi chương trình mà chính hệ điều hành sẽ gọi Window Procedure khi thích hợp (chẳng hạn khi cần vẽ lại một cửa sổ bị che bởi cửa số khác).

    4. Để gán một user-defined Window Procedure cho một cửa sổ bất kỳ, bác cần biết HWND tương ứng của cửa số đó. Sau đó, dùng hàm SetWindowLong để "connect" cửa sổ đó với địa chỉ của user-defined winproc.

    5. Cuối cùng, bác hãy viết code, dịch thành chương trình để chạy thử. Em đảm bảo bác sẽ "thấy" ngay.

  10. #10
    Ngày tham gia
    Sep 2015
    Đang ở
    Số 60 Thái Hà, Đống Đa, Hà Nội
    Bài viết
    0
    khè khè!
    Làm được rồi! [IMG]images/smilies/smile.png[/IMG]
    Cảm ơn ilovecplusplus nhiều lắm!
    Để tui tổng kết sơ sơ:
    Hàm SetWindowLong: thay đổi giá trị của window . Với tham số là GWL_WNDPROC thì thay đổi hàm xử lý cho Window, tức là thay đổi winproc.
    Hay quá! Cảm ơn nhiều nhe!

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •