Link to home
Create AccountLog in
Avatar of ak5745
ak5745

asked on

Using FindWindow to find MDI Client window(s)

Hi all,

I'm in the process of sending text from a textbox in AppA (my app) to a textbox in AppB (third party app) with FindWindow using the receiving textbox's control id found with Spy++. My problem is AppB has a main window with multiple other windows in it - as I understand it, it's an MDI client.

I'd like to be able to access all the smaller windows (child?) on the main window (parent?) - each child window has a textbox or two I need to send text to. The hierarchy would look like MDIParent, MDIChild, textbox.

Am I still able to use FindWindow to access all windows I need, or will I need to change gears because it's MDI? If I can, how might I go about that?

Any help would be greatly appreciated.

Thank you!
Avatar of trestan
trestan
Flag of Canada image

Yes. For a quick hint, please check the usage of EnumWindow and EnumChildWindows. It will give you all the handles of all windows and controls using a parent handle. Something like:

#include <windows.h>
BOOL CALLBACK EnumChildProc(HWND hWnd,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    char className[]="notepad";
    HWND hWnd=::FindWindow(className,NULL);
    if(hWnd)
    {
        ::EnumChildWindows(hWnd,EnumChildProc,0);
        return 0;
    }
    MessageBox(NULL,"fail!","fail",MB_OK);
    return 0;
}
BOOL CALLBACK EnumChildProc(HWND hWnd,LPARAM lParam)
{
    char temp1[256],temp2[256];
    ::GetWindowText(hWnd,temp1,255);
    wsprintf(temp2,"hwnd:%x text: %s",hWnd,temp1);
    MessageBox(NULL,temp2,"cwnd",MB_OK);
    return true;
}
Avatar of ak5745
ak5745

ASKER

@trestan:

Thank you for the response. I feel horrible to ask if you could put that in C# for me. I can definitely tell what it's doing, but I would definitely mess it up if I tried translating it. Maybe it's just time for me to learn C++.

Thanks!
ASKER CERTIFIED SOLUTION
Avatar of trestan
trestan
Flag of Canada image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
Avatar of ak5745

ASKER

trestan,

Thank you for that code! Not sure if it's what I'm doing or the fact that this might be over my head, but EnumChildWindow and how it works is eluding me. The following snippet was given to me by Mez4343 on a past question I asked here: https://www.experts-exchange.com/questions/26703064/Using-Sendkeys-to-pass-variable-to-textbox-in-other-app.html

It works great for one window, and am now trying to add EnumChildWindow to it (currently it's just FindWindow). The code below allows me to use the specific ControlID in hexadecimal - in this case, a textbox.

Would it be possible to add EnumChildWindow to the snippet below, then use the rest (i.e. InteropSetText() and SendMessage)? I've tried, but have failed miserably. Any tips?



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication8
{
    public partial class Form1 : Form
    {
        //Import the FindWindow API to find our window
        [DllImportAttribute("User32.dll")]
        private static extern IntPtr FindWindow(String ClassName, String WindowName);
        [DllImportAttribute("User32.dll")]
        public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
        [DllImportAttribute("User32.dll")]
        public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, string lParam);
        public const uint WM_SETTEXT = 0x000C;
        public const int textbox_controlid = 0x11B6E;


        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Find the window, using the CORRECT Window Title
            IntPtr hWnd = FindWindow(null, "AppB");
            if (hWnd != IntPtr.Zero) //If found
            {
                Console.WriteLine("found AppB");                
                // IntPtr htextbox = GetDlgItem(hWnd, 110); //110 is control id of textbox in AppB gotten using Spy++
                InteropSetText(hWnd,textbox_controlid,textBox1.Text.ToString());
            }
            else //Not Found
            {
                MessageBox.Show("Window Not Found!");
            }
        }
       private void InteropSetText(IntPtr iptrHWndDialog, int iControlID, string strTextToSet)
       {
           IntPtr iptrHWndControl = GetDlgItem(iptrHWndDialog, iControlID);
           HandleRef hrefHWndTarget = new HandleRef(null, iptrHWndControl);
           SendMessage(hrefHWndTarget, WM_SETTEXT, IntPtr.Zero, strTextToSet); }
    }
}