• Vui lòng đọc nội qui diễn đàn để tránh bị xóa bài viết
  • Tìm kiếm trước khi đặt câu hỏi

Cách gỡ rối WndProc như thế nào ?

Nơi trao đổi về các vấn đề trong lập trình Windows Forms, Console dùng cú pháp ngôn ngữ Visual Basic .NET và C#

Điều hành viên: tungblt, vuathongtin

dong
Thành viên ưu tú
Thành viên ưu tú
Bài viết: 663
Ngày tham gia: T.Năm 03/04/2008 7:46 am
Has thanked: 13 time
Been thanked: 2 time

Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi dong » T.Hai 22/01/2018 9:24 am

Mình làm ví dụ nhỏ có sử dụng đến hàm protected override void WndProc(ref Message m) mình muốn gỡ rối hàm này mình thấy biến m trả về là các số nhưng mình không hiểu những con số này có liên quan đến các control như thế nào ? ví dụ trên form có 2 button, 3 listView, 4 textbox,... mình có cần cài thêm phần mềm gì để biết những con số của biến m.Msg trả về là của control nào ? hoặc bạn nào có tư liệu hướng dẫn về cách bắt lỗi và gỡ rối hàm WndProc nói trên share cho mình với.



FlyingFox
Guru
Guru
Bài viết: 811
Ngày tham gia: T.Tư 20/04/2011 9:56 am
Been thanked: 322 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi FlyingFox » T.Hai 22/01/2018 6:12 pm


dong
Thành viên ưu tú
Thành viên ưu tú
Bài viết: 663
Ngày tham gia: T.Năm 03/04/2008 7:46 am
Has thanked: 13 time
Been thanked: 2 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi dong » T.Năm 25/01/2018 3:05 pm

Mình có đọc tài liệu bạn gửi nhưng mình cũng chưa thực sự hiểu chúng. Giả sử mình cần bắt thông điệp listView và trên form có 3 listView thì biến m.Msg làm sao phân biệt được listView1, listView2, listView3,... và khi chạy xuất ra thông điệp của biến m.Msg trong file đính kèm http://www.mediafire.com/file/weab5ppsb ... ndProc.doc

Mã: Chọn hết

 protected override void WndProc(ref Message m)
   {
        Debug.Print("out if: " + m.Msg);
        if (m.Msg == WM_NOFITY)
            {
                Debug.Print("in if: " + m.Msg);
            }
  }

FlyingFox
Guru
Guru
Bài viết: 811
Ngày tham gia: T.Tư 20/04/2011 9:56 am
Been thanked: 322 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi FlyingFox » T.Sáu 26/01/2018 3:44 pm

Có thể viết như sau cho trường hợp mouse activate
  1. protected override void WndProc(ref Message m)
  2. {
  3.     const UInt32 WM_MOUSEACTIVATE = 0x0021;
  4.     if (m.Msg == WM_MOUSEACTIVATE)
  5.     {
  6.         Point screen_coords = Cursor.Position;
  7.         Control ctl = this;
  8.         Point ctl_coords = ctl.PointToClient(screen_coords);
  9.         Control child = ctl.GetChildAtPoint(ctl_coords, GetChildAtPointSkip.Invisible);
  10.         if (child != null)
  11.         {
  12.             Console.WriteLine(child.Name);
  13.         }
  14.     }
  15.     base.WndProc(ref m);
  16. }

dong
Thành viên ưu tú
Thành viên ưu tú
Bài viết: 663
Ngày tham gia: T.Năm 03/04/2008 7:46 am
Has thanked: 13 time
Been thanked: 2 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi dong » CN 28/01/2018 5:00 pm

Theo lý thuyết bạn gửi cho mình hướng dẫn sử dụng WndPoc như bạn trình bày code ở trên nhưng thực thế tế mình thử kéo thả vào form 3 cái listView và vài cái control khác, mình chỉ muốn bắt đối tượng là listView thôi, khi chạy biến m.Msg đổ ra các con số nhưng mình không biết số nào là của đối tượng listView, mình đang bí chổ này nè bạn ơi, nếu bạn biết thì chỉ giúp mình với.

FlyingFox
Guru
Guru
Bài viết: 811
Ngày tham gia: T.Tư 20/04/2011 9:56 am
Been thanked: 322 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi FlyingFox » T.Hai 29/01/2018 10:52 am

Nếu chỉ muốn bắt đối tượng là ListView thì viết như thế này: if (child != null && child is ListView)

dong
Thành viên ưu tú
Thành viên ưu tú
Bài viết: 663
Ngày tham gia: T.Năm 03/04/2008 7:46 am
Has thanked: 13 time
Been thanked: 2 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi dong » T.Năm 01/02/2018 2:06 pm

nếu viết kiểu này thì không có liên quan gì sử dụng đến biến m.Msg

FlyingFox
Guru
Guru
Bài viết: 811
Ngày tham gia: T.Tư 20/04/2011 9:56 am
Been thanked: 322 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi FlyingFox » T.Sáu 02/02/2018 6:00 am

Vẩn phải viết như cách đầu tiên, chỉ sữa lại dòng IF đó thôi.

dong
Thành viên ưu tú
Thành viên ưu tú
Bài viết: 663
Ngày tham gia: T.Năm 03/04/2008 7:46 am
Has thanked: 13 time
Been thanked: 2 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi dong » T.Hai 05/02/2018 2:41 pm

Trong hàm WndProc(ref Message m) có biến m truyền vào thôi, vậy biến child khai báo như thế nào trong hàm WndProc vậy bạn ?

FlyingFox
Guru
Guru
Bài viết: 811
Ngày tham gia: T.Tư 20/04/2011 9:56 am
Been thanked: 322 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi FlyingFox » T.Hai 12/02/2018 2:48 pm

ở dòng thứ 9 đó Control child = ctl.GetChildAtPoint(ctl_coords, GetChildAtPointSkip.Invisible);

dong
Thành viên ưu tú
Thành viên ưu tú
Bài viết: 663
Ngày tham gia: T.Năm 03/04/2008 7:46 am
Has thanked: 13 time
Been thanked: 2 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi dong » T.Tư 14/03/2018 11:25 am

Mình tạo một form kéo thả TabControl vào form và kéo thả listView1 vào TabPage1, nếu có bao nhiêu listView động thì có bấy nhiêu TabPage động.

Mã: Chọn hết

protected override void WndProc(ref Message m)
        {
            Debug.Print("out if: " + m.Msg + "; m.HWnd: " + m.HWnd);
            const UInt32 WM_MOUSEACTIVATE = 0x0021;
            if (m.Msg == WM_MOUSEACTIVATE)
            {
                Debug.Print("in WM_MOUSEACTIVATE: " + m.Msg + "; m.HWnd: " + m.HWnd);
                Point screen_coords = Cursor.Position;
                Control ctl = this;
                Point ctl_coords = ctl.PointToClient(screen_coords);
                Control child = ctl.GetChildAtPoint(ctl_coords, GetChildAtPointSkip.Invisible);
                if (child != null)
                {
                    Console.WriteLine("child.Name: " + child.Name);
                }
            }
            base.WndProc(ref m);
        }

kết quả khi chạy, không lấy được tên đối tượng listView, chỉ khi click chọn item của listview thì xuất child.Name: tabControl1

Mã: Chọn hết

out if: 792; m.HWnd: 461510
out if: 14; m.HWnd: 461510
out if: 13; m.HWnd: 461510
out if: 14; m.HWnd: 461510
out if: 13; m.HWnd: 461510
child.Name: tabControl1
out if: 528; m.HWnd: 461510
out if: 33; m.HWnd: 461510
in WM_MOUSEACTIVATE: 33; m.HWnd: 461510
out if: 20; m.HWnd: 461510
out if: 14; m.HWnd: 461510
out if: 13; m.HWnd: 461510
out if: 792; m.HWnd: 461510

FlyingFox
Guru
Guru
Bài viết: 811
Ngày tham gia: T.Tư 20/04/2011 9:56 am
Been thanked: 322 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi FlyingFox » T.Năm 15/03/2018 5:29 pm

Vậy tại sao không dùng sự kiện MouseEnter cho nó dể hơn không?
Ví dụ như trong form có TabControl với mấy cái TabPage và có một button
thì viết code như sau để add ListView vào cái TabPage hiện tại
  1. private void button1_Click(object sender, EventArgs e)
  2.         {
  3.             CreateListView(tabControl1);
  4.         }
  5.  
  6.         private void CreateListView(TabControl tabControl)
  7.         {
  8.             string listName = "listView" + (tabControl.SelectedIndex + 1).ToString();
  9.             if (!tabControl.SelectedTab.Controls.ContainsKey(listName))
  10.             {
  11.                 ListView lv = new ListView()
  12.                 {
  13.                     Name = listName,
  14.                     Bounds = new Rectangle(new Point(10, 10), new Size(300, 200)),
  15.                     View = View.Details,
  16.                 };
  17.                 tabControl.SelectedTab.Controls.Add(lv);
  18.                 lv.MouseEnter += this.listView_MouseEnter;
  19.             }
  20.         }
  21. private void listView_MouseEnter(object sender, EventArgs e)
  22.         {
  23.             ListView lv = sender as ListView;
  24.             if (lv != null)
  25.             {
  26.                 Console.WriteLine("Mouse Enter " + lv.Name);
  27.             }
  28.         }

dong
Thành viên ưu tú
Thành viên ưu tú
Bài viết: 663
Ngày tham gia: T.Năm 03/04/2008 7:46 am
Has thanked: 13 time
Been thanked: 2 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi dong » T.Tư 11/04/2018 8:52 am

vì sau khi Form1_load(...) xong là hàm protected override void WndProc(ref Message m) sẽ chạy nên mình muốn bắt các sự kiên của hàm này liên quan đến listView, trong khi đó mình chưa sử dụng đến biến cố chuột hay bàn phím,...

FlyingFox
Guru
Guru
Bài viết: 811
Ngày tham gia: T.Tư 20/04/2011 9:56 am
Been thanked: 322 time

Re: Cách gỡ rối WndProc như thế nào ?

Gửi bàigửi bởi FlyingFox » T.Tư 11/04/2018 11:38 am

Nếu muốn dùng WndProc để bắt các sự kiện cũa ListView không thì có thể tạo một control mới thừa kế từ ListView rồi override WndProc trong class đó.
  1. using System;
  2. using System.Windows.Forms;
  3. namespace WindowsFormsApplication1
  4. {
  5.     public class MyListView : ListView
  6.     {
  7.         const int WM_MOUSEMOVE = 0x200;
  8.         const int WM_MOUSEACTIVATE = 0x0021;
  9.         const int WM_NCHITTEST = 0x0084;
  10.  
  11.         protected override void WndProc(ref Message m)
  12.         {
  13.             base.WndProc(ref m);
  14.             switch (m.Msg)
  15.             {
  16.                 case WM_MOUSEMOVE:
  17.                     Console.WriteLine(this.Name + " WM_MOUSEMOVE");
  18.                     break;
  19.                 case WM_NCHITTEST:
  20.                     Console.WriteLine(this.Name + " WM_NCHITTEST)...");
  21.                     break;
  22.                 case WM_MOUSEACTIVATE:
  23.                     Console.WriteLine(this.Name + " WM_MOUSEACTIVATE");
  24.                     break;
  25.             }
  26.         }
  27.     }
  28. }


Quay về “Visual Basic .NET và C# (VB.NET & C#)”

Đang trực tuyến

Đang xem chuyên mục này: Không có thành viên nào trực tuyến.5 khách