tags:

views:

37

answers:

1

I am new to WINAPI and have figured out how to send a message to another program. The program I am using however I would like to be able to have it click on a specific button. From what I have learned by viewing Spy++ windows handles change for the programs every time they are reloaded and so do the handles for their controls. The control ID stays the same. After two days of trying to figure it out I am here.

under SendMesssageA if I specify the current handle as viewable by Spy++ and use that and run the code it works fine and clicks the button on my external application. I am attempting to use GetDlgItem as I have read that I can get the handle for the control (child window) using it. I am doing something wrong however since no matter what I do it returns 0 or 'null'.

How can I get GetDlgItem to return the child control handle so that I may use it to sendmessage to click that control in the external application?

Thanks for your help an input ahead of time.

    [DllImport("User32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    Process[] myProcess = Process.GetProcessesByName("program name here");

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int SendMessageA(IntPtr hwnd, int wMsg, int wParam, uint lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr GetDlgItem(int hwnd, int childID);

    public const int WM_LBUTTONDOWN = 0x0201;
    public const int WM_LBUTTONUP = 0x0202;


    public void SendClick()
    {
        IntPtr hwnd = myProcess[0].MainWindowHandle;
        SetForegroundWindow(hwnd);

        int intCID = 1389;
        IntPtr ptrTest = GetDlgItem(hwnd, intCID);
        SendKeys.SendWait(" ");
        Thread.Sleep(1000);
        SendKeys.SendWait("various text to be sent here");
        Thread.Sleep(1000);
        SendKeys.SendWait("{ENTER}");
        Thread.Sleep(1000);

        SendMessageA(ptrTest, WM_LBUTTONDOWN, WM_LBUTTONDOWN, 0);
    }
A: 

I think you have to use the Win32 API to find the "receiving" application window, and then find a child window of that handle. This is something I found googling Win32 API FindWindow

http://www.c-sharpcorner.com/UploadFile/shrijeetnair/win32api12062005005528AM/win32api.aspx

Marco
well the code I posted does work for establishing the parent window, or the main application where the button is. The only thing that wont work with the code posted is the GetDlgItem to find the handle for the child control. According to MSDN GetDlgItem uses the handle of the parent which I have using myprocess and it also uses the child control's control ID which I have as the variable intCID. GetDlgItem returns 0 or 'null' however.
Nicholas C
Are you sure hwnd points to what you think it does? You need to verify it with Spy++. MainWindowHandle is the first (visible?) window created by the process, which may or may not be the dialog you are trying to use (depending on the architecture of the application in question).
Luke
Yes, hwnd points to the first process named for the program. I know it does because it sets it as the active window and sendkeys sends the text to it which it receives. When it gets to sendmessageA if I change the ptrTest variable to hwnd it WILL send the click to the program. My problem however, is I need the click send to a specific child control of the parent window which I was trying to establish with GetDlgItem. ptrTest keeps comming up at '0' and I am unsure how to set ptrTest to the child control handle (which I can indentify with the control ID)
Nicholas C
I thin you need to enumerate the windows using EnumChildWindows:http://support.microsoft.com/kb/183009
Marco
yeah enumchildwindows is right, thanks marco
Nicholas C