Trang 1 trên 1

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

Đã gửi: T.Hai 22/01/2018 9:24 am
gửi bởi dong
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.

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

Đã gửi: T.Hai 22/01/2018 6:12 pm
gửi bởi FlyingFox

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

Đã gửi: T.Năm 25/01/2018 3:05 pm
gửi bởi dong
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);
            }
  }

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

Đã gửi: T.Sáu 26/01/2018 3:44 pm
gửi bởi FlyingFox
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. }

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

Đã gửi: CN 28/01/2018 5:00 pm
gửi bởi dong
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.

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

Đã gửi: T.Hai 29/01/2018 10:52 am
gửi bởi FlyingFox
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)

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

Đã gửi: T.Năm 01/02/2018 2:06 pm
gửi bởi dong
nếu viết kiểu này thì không có liên quan gì sử dụng đến biến m.Msg

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

Đã gửi: T.Sáu 02/02/2018 6:00 am
gửi bởi FlyingFox
Vẩn phải viết như cách đầu tiên, chỉ sữa lại dòng IF đó thôi.

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

Đã gửi: T.Hai 05/02/2018 2:41 pm
gửi bởi dong
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 ?

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

Đã gửi: T.Hai 12/02/2018 2:48 pm
gửi bởi FlyingFox
ở dòng thứ 9 đó Control child = ctl.GetChildAtPoint(ctl_coords, GetChildAtPointSkip.Invisible);

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

Đã gửi: T.Tư 14/03/2018 11:25 am
gửi bởi dong
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

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

Đã gửi: T.Năm 15/03/2018 5:29 pm
gửi bởi FlyingFox
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.         }

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

Đã gửi: T.Tư 11/04/2018 8:52 am
gửi bởi dong
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,...

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

Đã gửi: T.Tư 11/04/2018 11:38 am
gửi bởi FlyingFox
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. }