locked
How to get a window handle RRS feed

  • Question

  • Hi, All

    I meet a issue with get window handle using FindWindow(...),

    In my application, I want startup process B and give parameter tell him what I  need opened by him. this can be done.

    another one I want to do is before main window of B visible,  get his window handle and set it to position where I want.

    Problem is: if I pass the file name  FILENAME to call B, after B initialize, its title will be "B - FILENAME [X]",

    and [X] depends on the setting in project of FILENAME, I don't konw what it is.

    so pass title as parameter not work as I know,

    And I try to pass class name as its parameter to FindWidnow, using Spy++ to get B's main window handle,

    I get "Afx:00400000:8:00010013:00000000:00860A9F", and 00860A9F changed when I test another instance of process B.

    so what can i do if i want to get B's main window handle?

    Appreciate your reply.

    Thanks,

    Levi
    One world, one dream
    Friday, May 8, 2009 9:42 AM

Answers

  • If you can access the source code of the process B, you can try either Scott's suggestion or any other way like that.
    Otherwise, the snippet below can help you under the assumption that there should be only one B process at a time.

    // construct the former part of the window title.
    // the FILENAME is assumed to be stored in the 'strFileName'.
    
    CString strTitle = _T("B - ");
    strTitle += strFileName;
    
    HWND hChild = NULL;
    TCHAR szTitle[1024];
    
    do 
    {
        hChild = ::FindWindowEx(NULL, hChild, NULL, NULL);
        if (hChild)
        {
            ::GetWindowText(hChild, szTitle, 1023);
            CString str(szTitle);
            if (0 == str.Find(strTitle))
                break;
        }
    }
    while (hChild);
    
    if (hChild)
    {
        // the most probable candidate of the B was found.
    }



    It's not an exact solution because it is possible that there is another application which has the same part of string in its title as that of the B process.
    But if you are not able to get the exact title of the B and not to modify the source code of B either, it might be the only way of getting access to the window handle of B.

    Regards,
    • Marked as answer by Levi Zhou Thursday, May 21, 2009 12:49 AM
    Monday, May 11, 2009 3:04 AM
  • When you call CreateProcess() to start the program, you can get its main thread ID from PROCESS_INFORMATION.dwThreadId.  That allows you to enumerate its windows with EnumThreadWindows(), considerably cutting down on the possible number of matches.

    Hans Passant.
    • Marked as answer by Levi Zhou Thursday, May 21, 2009 12:49 AM
    Friday, May 8, 2009 11:58 AM

All replies

  • When you call CreateProcess() to start the program, you can get its main thread ID from PROCESS_INFORMATION.dwThreadId.  That allows you to enumerate its windows with EnumThreadWindows(), considerably cutting down on the possible number of matches.

    Hans Passant.
    • Marked as answer by Levi Zhou Thursday, May 21, 2009 12:49 AM
    Friday, May 8, 2009 11:58 AM
  • When you call CreateProcess() to start the program, you can get its main thread ID from PROCESS_INFORMATION.dwThreadId.  That allows you to enumerate its windows with EnumThreadWindows(), considerably cutting down on the possible number of matches.

    Hans Passant.

    The problem is it was not started up by call CreateProcess, but using IDispatch call CreateDispatch.

    what can i do about this interface to get the related info?

    Thanks,

    Levi
    One world, one dream
    Monday, May 11, 2009 1:13 AM
  • Do you have source code for Process B?  If so you can change and control the window title, and the class name of the main window.  MFC makes up a random class name when it runs (Afx:....) but you can substitute your own unchanging class name instead.  Use AfxRegisterClass in CMainFrame::PrecreateWindow.

     

    Monday, May 11, 2009 2:36 AM
  • If you can access the source code of the process B, you can try either Scott's suggestion or any other way like that.
    Otherwise, the snippet below can help you under the assumption that there should be only one B process at a time.

    // construct the former part of the window title.
    // the FILENAME is assumed to be stored in the 'strFileName'.
    
    CString strTitle = _T("B - ");
    strTitle += strFileName;
    
    HWND hChild = NULL;
    TCHAR szTitle[1024];
    
    do 
    {
        hChild = ::FindWindowEx(NULL, hChild, NULL, NULL);
        if (hChild)
        {
            ::GetWindowText(hChild, szTitle, 1023);
            CString str(szTitle);
            if (0 == str.Find(strTitle))
                break;
        }
    }
    while (hChild);
    
    if (hChild)
    {
        // the most probable candidate of the B was found.
    }



    It's not an exact solution because it is possible that there is another application which has the same part of string in its title as that of the B process.
    But if you are not able to get the exact title of the B and not to modify the source code of B either, it might be the only way of getting access to the window handle of B.

    Regards,
    • Marked as answer by Levi Zhou Thursday, May 21, 2009 12:49 AM
    Monday, May 11, 2009 3:04 AM
  • Hello Levi,

    Did you resolved the issue? If you have any other question, welcome to post here.

    Thanks,
    Rong-Chun Zhang
    Please mark the replies as answers if they help and unmark if they don't.
    Welcome to the All-In-One Code Framework, a sample code project owned by the MSDN Forum Support team!
    Thursday, May 14, 2009 10:28 AM
  • Hi, Rong-Chun

     I think Yangghi's post is answer, but i need to get confirm if it meet the requirement, if yes I'll mark it as answer.

     Its help.

    One world, one dream
    Thursday, May 14, 2009 11:24 AM