Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 12 kết quả

Đề tài: Window spy - Hổ trợ lập trình API

  1. #1
    Ngày gia nhập
    12 2009
    Bài viết
    73

    Mặc định Window spy - Hổ trợ lập trình API

    Phiên bản 1.0:
    + Tìm các handle của các object trên window.
    + Trả về các thông tin của Handle hiện tại.
    + Generate Function (C#) tìm đến handle hiện tai để copy vào Code và sử dụng.

    Ví dụ sử dụng WindowSpy để giúp tạo handle chat Skype thông qua C#.

    Bước 1: Tạo control
    Tao 1 form với 1 Richtext và 1 button

    Bước 2: Chuẩn bị các hàm API
    Trong file Form1.cs copy và paste phần này vào chổ nào đó cũng được:

    Visual C# Code:
    1. private const int WM_SETTEXT = 0x000C;
    2.         private const int WM_KEYDOWN = 0x0100;
    3.         private const int WM_CHAR = 0x0102;
    4.         private const int WM_KEYUP = 0x0101;
    5.  
    6.         [DllImport("user32.dll", CharSet=CharSet.Auto)]
    7.         private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

    sau khi copy xong nó tương tự thế này:
    Visual C# Code:
    1. private const int WM_SETTEXT = 0x000C;
    2.         private const int WM_KEYDOWN = 0x0100;
    3.         private const int WM_CHAR = 0x0102;
    4.         private const int WM_KEYUP = 0x0101;
    5.  
    6.         [DllImport("user32.dll", CharSet=CharSet.Auto)]
    7.         private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
    8.        
    9.         public Form1()
    10.         {
    11.             InitializeComponent();
    12.         }

    Bước 3: Tạo hàm tìm đến handle cần làm việc (Trường hợp này là text area của Skype). Dùng WindowSpy
    1. Mở WindowSpy lên.
    2. Drag cái FinderTool đến ô mà gỏ text để chát của Skype.
    3. Nhả chuột
    4. Copy toàn bộ code mà WindowSpy generate được bỏ vào Form1.cs

    Visual C# Code:
    1. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    2. public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
    3.  
    4. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    5. public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
    6.  
    7. public static IntPtr FindWindow()
    8. {
    9. IntPtr hwnd = FindWindow("tSkMainForm", null);
    10. hwnd = FindWindowEx(hwnd, IntPtr.Zero, "TConversationForm", null);
    11. hwnd = FindWindowEx(hwnd, IntPtr.Zero, "TChatEntryControl", null);
    12. hwnd = FindWindowEx(hwnd, IntPtr.Zero, "TChatRichEdit", null);
    13. return hwnd;
    14. }

    Bước 4: Tiến hành code.
    1. Gửi text từ rich text đến Skype
    chúng ta sẻ dùng cấu trúc này:
    Visual C# Code:
    1.                 SendMessage(skype, WM_SETTEXT, IntPtr.Zero, Marshal.StringToHGlobalAuto(this.richTextBox1.Text));

    2. Gửi tổ hợp phím Enter
    Visual C# Code:
    1.                 SendMessage(skype, WM_KEYDOWN, (IntPtr)0x0000000D, (IntPtr)0x001C0001);
    2.                 SendMessage(skype, WM_CHAR, (IntPtr)0x0000000D, (IntPtr)0x001C0001);
    3.                 SendMessage(skype, WM_KEYUP, (IntPtr)0x0000000D, (IntPtr)0x001C0001);

    như vậy code của sự kiện click của button1 chính là:
    Visual C# Code:
    1. IntPtr skype = FindWindow();
    2.             if (skype != IntPtr.Zero)
    3.             {
    4.                 SendMessage(skype, WM_SETTEXT, IntPtr.Zero, Marshal.StringToHGlobalAuto(this.richTextBox1.Text));
    5.                 SendMessage(skype, WM_KEYDOWN, (IntPtr)0x0000000D, (IntPtr)0x001C0001);
    6.                 SendMessage(skype, WM_CHAR, (IntPtr)0x0000000D, (IntPtr)0x001C0001);
    7.                 SendMessage(skype, WM_KEYUP, (IntPtr)0x0000000D, (IntPtr)0x001C0001);
    8.             }
    Attached Thumbnails Attached Thumbnails screen_find.png   screen_normal.png  
    Attached Files Attached Files
    Đã được chỉnh sửa lần cuối bởi dungnn07 : 09-06-2011 lúc 11:29 PM. Lý do: Nâng cấp phiên bản

  2. #2
    Ngày gia nhập
    12 2009
    Bài viết
    73

    Mặc định Phiên bản 1.1

    Sau khi viết xong cái bản đầu. Nếu dùng bạn sẽ để ý là một số handle chương trình chưa nhận dạng được. Ví dụ như là cái text số của Calculator.
    Nguyên nhân là do handle được che lấp trong handle parent...

    Phiên bản 1.1:
    + Không sử dụng form FinderMask. Thay vào đó dùng GDI++ với DrawRevFrame (Vẽ ngược màu) cho mỗi handle.
    + Hổ trợ các handle bị che lấp. Sử dụng hàm GetWidow để duyệt qua các handle. Lấy handle chứa Curent point và có Bound phù hợp

    Dự kiến phiên bản sau:
    + Hổ trợ monitor các sự kiện trên từng Handle.
    + Hổ trợ các hàm API để chèn vào VS (Thư viện hàm lấy từ PINVOKE.COM).
    Attached Thumbnails Attached Thumbnails window_spy1.png   window_spy2.png   window_spy3.png   window_spy4.png  
    Attached Files Attached Files

  3. #3
    Ngày gia nhập
    12 2009
    Bài viết
    73

    Mặc định Bản Fix.

    Bản fix: v1.2.0
    Đối với các handle của các window cùng cấp có thể trùng Class name. Vì vậy phương thức FindWindow của WindowSpy tạo ra chỉ lấy được handle đầu tiên trong các handle cùng cấp và cùng Class name. Vì vậy có thể bạn sẽ không lấy được handle như ý. Ví dụ như khi bạn muốn lấy cái handle của phần ký tự số của calculator, đối với phương thức FindWindow của WS nó sẽ trả về cái handle của phần tên phép tính (như là =sqrt(10)...). Vì vậy bạn không lấy được kết quả.
    Bản fix này cung cấp thêm việc generate ra phương thức GetWindow. Phương thức này sử dụng việc xác định handle của window theo chỉ mục (Z-ORDER) để trả về chính xác handle mà bạn chọn.

    ===============================
    Một ví dụ cho bài toán: Viết chương trình khi chạy tự động copy kết quả từ calculate vào notepad.
    Cái này đã có một topic bàn về cái này tại CViet. Ở đó mình cũng làm một cách là sử dụng message command. Còn có bạn gì đó thì Duyệt qua từng window rồi dùng GetWindowText, tuy nhiên nếu duyệt qua từng window rồi xác định cái nào !empty thì nó vẫn bị bug nếu như window không phải là kết quả mà có text !empty thì sẻ toi ví dụ như bạn dùng phép toán căn... Thì nó trả về tên phép tính chứ không phải là kết quả.

    Nếu dùng WindowSpy bạn có thể lấy ra đúng handle cần thiết để xữ lý:

    Mình sẻ tạo một ví dụ để vừa lấy tên phép tính và kết quả rồi đưa vào notepad. Sử dụng window spy.

    Bước 1: Chuẩn bị code:
    Tạo class Form1 với 1 button.

    Bạn copy đoạn code sau bỏ vào class của bạn ví dụ Form1 (Form1.cs)

    Visual C# Code:
    1.         private const int WM_SETTEXT = 0x000C;
    2.         private const int WM_GETTEXT = 0x000D;
    3.  
    4.         [DllImport("user32.dll", CharSet = CharSet.Auto)]
    5.         private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);


    Bước 2: Dùng WindowSpy tạo ra 3 hàm tìm đến các handle:
    1: Tìm handle edit của notepad. (Do đối với note pad các window con của nó khá đơn giản nên chúng ta chỉ cần sử dụng phương thức FindWindow mà sẽ không sợ bị sai với các window cùng cấp):

    Tại mục Method Option bạn chọn FindWindow

    Visual C# Code:
    1. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    2. public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
    3.  
    4. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    5. public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
    6.  
    7. public static IntPtr FindWindowNotepad()
    8. {
    9. IntPtr hWnd = FindWindow("Notepad", null);
    10. hWnd = FindWindowEx(hWnd, IntPtr.Zero, "Edit", null);
    11. return hWnd;
    12. }

    2: Tìm đến handle tên phép tính của calculate (Vì class name của Handle này trùng với Class name của handle kết quả nên ta sẻ dùng phương thức GetWindow)
    Tại mục Method Option bạn chọn GetWindow
    Bạn dùng Finder tool của Window spy đưa chuột đến mép trên của phần kết quả rồi nhả chuột.

    Visual C# Code:
    1. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    2. public static extern IntPtr GetWindow(IntPtr hwnd, int wFlag);
    3.  
    4. public static IntPtr GetWindowCalName()
    5. {
    6. IntPtr hWnd = FindWindowNotepad("CalcFrame", null);
    7. hWnd = GetWindow(hWnd, 5);
    8. hWnd = GetWindow(hWnd, 5);
    9. hWnd = GetWindow(hWnd, 2);
    10. hWnd = GetWindow(hWnd, 5);
    11. return hWnd;
    12. }

    Bạn bỏ phần này vì đã có rồi. Và đổi tên thành: GetWindowCalName

    Visual C# Code:
    1. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    2. public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);

    3: Bạn lấy handle kết quả của calculate
    Tại mục Method Option bạn chọn GetWindow
    Bạn dùng Finder tool của Window spy đưa chuột đến phần chính của phần kết quả rồi nhả chuột.


    Visual C# Code:
    1. public static IntPtr GetWindowCalValue()
    2. {
    3. IntPtr hWnd = FindWindow("CalcFrame", null);
    4. hWnd = GetWindow(hWnd, 5);
    5. hWnd = GetWindow(hWnd, 5);
    6. hWnd = GetWindow(hWnd, 2);
    7. hWnd = GetWindow(hWnd, 5);
    8. hWnd = GetWindow(hWnd, 2);
    9. hWnd = GetWindow(hWnd, 2);
    10. return hWnd;
    11. }


    Bỏ phần này (vì đã có rồi)
    Visual C# Code:
    1. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    2. public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
    3.  
    4. [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    5. public static extern IntPtr GetWindow(IntPtr hwnd, int wFlag);

    Bước 3: Code
    Gải sử tại calculate bạn gỏ 9 rồi căn, kết quả lại phần phía trên là "sqrt(9)" và tại ô giá trị là "3". Ta đưa các thông tin này vào notepad.

    hàm lấy text là

    Visual C# Code:
    1.                 IntPtr memmory = Marshal.AllocHGlobal(100);
    2.                 SendMessage(calName, WM_GETTEXT, (IntPtr)100, memmory);
    3.                 string text = Marshal.PtrToStringAuto(memmory);

    hàm settext là
    Visual C# Code:
    1. SendMessage(notepad, WM_SETTEXT, IntPtr.Zero, Marshal.StringToHGlobalAuto(text));

    vậy nội dung của sự kiện click là:

    Visual C# Code:
    1.         private void button1_Click(object sender, EventArgs e)
    2.         {
    3.             IntPtr calName = GetWindowCalName();
    4.             IntPtr calValue = GetWindowCalValue();
    5.            
    6.             if (calValue != IntPtr.Zero)
    7.             {
    8.                 IntPtr memmory = Marshal.AllocHGlobal(100);
    9.                 SendMessage(calName, WM_GETTEXT, (IntPtr)100, memmory);
    10.                 string text = Marshal.PtrToStringAuto(memmory);
    11.  
    12.                 text += Environment.NewLine;
    13.  
    14.                 SendMessage(calValue, WM_GETTEXT, (IntPtr)100, memmory);
    15.                 text += Marshal.PtrToStringAuto(memmory);
    16.  
    17.                 IntPtr notepad = FindWindowNotepad();
    18.                 if (notepad != IntPtr.Zero)
    19.                 {
    20.                     SendMessage(notepad, WM_SETTEXT, IntPtr.Zero, Marshal.StringToHGlobalAuto(text));
    21.                 }
    22.             }
    23.         }
    Attached Thumbnails Attached Thumbnails window_spy1.png   window_spy2.png   window_spy3.png  
    Attached Files Attached Files
    Đã được chỉnh sửa lần cuối bởi dungnn07 : 09-06-2011 lúc 01:36 PM.

  4. #4
    Ngày gia nhập
    08 2009
    Bài viết
    23

    Nhìn chương trình của anh cũng đáng nể đó chứ.

  5. #5
    Ngày gia nhập
    12 2009
    Bài viết
    73

    Trích dẫn Nguyên bản được gửi bởi a1master.moon Xem bài viết
    Nhìn chương trình của anh cũng đáng nể đó chứ.
    Hi. Cảm ơn bạn vì đã quan tâm. Mình đang muốn phát triển nó thành công cụ bổ sung vào Visual studio để thực hiện các hàm API của window.

  6. #6
    Ngày gia nhập
    10 2009
    Bài viết
    13

    Mặc định Window spy - Hổ trợ lập trình API

    Bài viết rất hay ^^ . Reply ủng hộ bạn 1 phát

  7. #7
    Ngày gia nhập
    04 2013
    Bài viết
    2

    Cảm ơn bài viết và công cụ của Anh !
    Bài viết chi tiết !
    Công cụ hay !

  8. #8
    Ngày gia nhập
    08 2013
    Bài viết
    5

    tool hỗ trợ hay nhưu thế này mà không ai sử dụng hết vậy

  9. #9
    Ngày gia nhập
    09 2016
    Bài viết
    1,009

    Trích dẫn Nguyên bản được gửi bởi datrocket Xem bài viết
    tool hỗ trợ hay nhưu thế này mà không ai sử dụng hết vậy
    Số lượng download là khá lớn sao lại nói không ai sử dụng !

    Để lấy handler của control thì có nhiều cách, một topic liên quan gần với đề tài này có thể xem:
    http://diendan.congdongcviet.com/threads/t379512::winapi-nhay-dup-chuot-vao-syslistview32-item.cpp

    Phọt mô xa 2017

  10. #10
    Ngày gia nhập
    08 2013
    Bài viết
    5

    Trích dẫn Nguyên bản được gửi bởi fms17 Xem bài viết
    Số lượng download là khá lớn sao lại nói không ai sử dụng !

    Để lấy handler của control thì có nhiều cách, một topic liên quan gần với đề tài này có thể xem:
    http://diendan.congdongcviet.com/threads/t379512::winapi-nhay-dup-chuot-vao-syslistview32-item.cpp

    Phọt mô xa 2017
    ý là không ai bình luận hết

    Tiện cho mình lấy dữ liệu datagridview mình làm như thế nào bạn?
    Mình shearch rồi mà không tìm ra cách

Các đề tài tương tự

  1. Trả lời: 1
    Bài viết cuối: 13-07-2014, 08:06 AM
  2. Làm thế nào để tạo một OpenGL Window bên trong một Main Window?
    Gửi bởi bachhaiduong trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 2
    Bài viết cuối: 10-01-2012, 10:09 AM
  3. lỗi không thấy window khi cắm lan ubuntu thật + window ảo :D
    Gửi bởi zstar trong diễn đàn Thắc mắc chung
    Trả lời: 4
    Bài viết cuối: 16-04-2011, 08:10 PM
  4. cho em hỏi về cái bảng tính của window
    Gửi bởi tienlongtran trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 1
    Bài viết cuối: 18-09-2009, 02:57 PM
  5. Không paint lại vùng main window bị child window đè
    Gửi bởi hieubm trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 11
    Bài viết cuối: 27-01-2007, 07:44 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn