Send a button click on another program C#

:smile: thật sự thì em không biết đặt tiêu đề tiếng Việt như thế nào cho nó phù hợp nên em mới đặt như vậy.
Chuyện là em đnag viết một cái tool nhỏ, ứng dụng của nó là khi click vào một cái button bên đây thì nó sẽ mở một cái app khác (ở đây là em mở OpenVPN) và rồi sau đó sẽ ấn một button bên app OpenVPN.
và em đang bị kẹt ở chỗ là không tài nào send được cái sự kiện click chuột qua cái app bên kia. Tức là đã bật openVPN client lên rồi, nhưng lại không có chuyện gì xảy ra sau đó :smile:.

control ID của button Disconnect trong spy++:


và đây là đoạn code của em :smile:

    private const int VM_COMMAND = 0x0111;
    private const int BN_CLICKED = 0;
    private const int ButtonId = 0xA3;
    private const string fn = @"C:\Program Files\OpenVPN\bin\openvpn-gui.exe";
    [DllImport("user32.dll")]
    static extern IntPtr GetDlgItem(IntPtr hWnd, int nIDDlgItem);
    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

    private static ProcessModule GetModule(Process p)
    {
        ProcessModule pm = null;
        try
        {
            pm = p.MainModule;
        }
        catch
        {
            return null;
        }
        return pm;
    }

    public static void openApp()
    {
        IntPtr handle = IntPtr.Zero;
        Process[] localAll = Process.GetProcesses();
        IntPtr hWndButton = GetDlgItem(handle, ButtonId);
        foreach(Process p in localAll)
        {
            if(p.MainWindowHandle != IntPtr.Zero)
            {
                ProcessModule pm = GetModule(p);
                if(pm != null && p.MainModule.FileName == fn)
                {
                    handle = p.MainWindowHandle;
                    break;
                }
            }
        }
        if(handle == IntPtr.Zero)
        {
            MessageBox.Show("Not Found.");
            return;
        }
        int wParam = (BN_CLICKED << 16) | (ButtonId & 0xffff);
        SendMessage(handle, VM_COMMAND, wParam, hWndButton);
    }

Không biết code em sai chỗ nào và có cách nào khác ngoài dùng SendMessage k ạ ? :smile: mong cách thánh chỉ giáo.

Đây là 1 đoạn chương trình mình dung để click vào nút “Thông tin” của Unikey 4.0 RC2. Bạn có thể tham khảo :slight_smile:

using System;
using System.Runtime.InteropServices;

namespace CSharp_SendMessage {
    class Program {

        [DllImport("user32.dll")]
            private static extern IntPtr FindWindow(string lpClassName,string lpWindowName);

            [DllImport("user32.dll")]
            private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,string lpszClass,string lpszWindow);

            [DllImport("user32.dll")]
            private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

            static void Main(string[] args) {
                IntPtr hwnd = FindWindow(null, "UniKey 4.0 RC2"); // Lấy Handle của Unikey theo tên cửa sổ
                IntPtr button = FindWindowEx(hwnd, IntPtr.Zero, null, "Thông tin"); // Lấy handle của nút "Thông tin" theo text
                SendMessage(button, 0x00F5, IntPtr.Zero, IntPtr.Zero); // Gửi tin nhắn BM_CLICK=0x005F để click
            }
        }
}

Kết quả :

2 Likes

Cho mình hỏi cái 0x00F5 là giá trị gì vậy ? :smile: tại lúc đầu cứ tưởng nó là control ID cho nên cứ đi mò trong control ID :smile:

0x00F5 là giá trị của tin nhắn BM_CLICK. Gửi tin nhắn (Message) này đến button nào thì sự kiện click xảy ra nếu button đó khả dụng.

1 Like

Hi. Cho mình hỏi chút. Mình có dùng lại ví dụ trên Unikey thì click được nhưng trên một số chương trình khác có tên class như WindowsForms10.BUTTON.app. …
Thì khi SendMessage lại không có hiện tượng gì xảy ra cả :((
Có ai gặp issue này không?

Cái này là vì WinForm, WPF và UWP dùng event riêng, không dùng chung Window Message với các app viết bằng Win32 Controls nhé.

2 Likes

Bạn có thể dùng thử Spy++ của visual studio xem thử event logging
(Mình cũng không chắc nó hoạt động trên mấy app C#)

Vậy làm thế nào bạn?

Mình có dùng Spy++ mò mãi mà chưa được

1 cách làm mới hiện nay là dùng WinAppDriver cho Selenium, giống như dùng Selenium để làm automation testing.

Ad ơi,
Mình muốn hỏi, ví dụ mình muốn click lên 1 vị trí x, y nào đó trên 1 máy giả lập Android ví dụ LDPlayer thì làm sao bạn?
Bạn giúp mình đc ko?
(upload://5THJrQtksWfEcnd7bsRA35rerDK.png)

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?