2008/09/18

프로세스 아이디로 윈도우 핸들 찾기

STARTUPINFO sInfo;
memset( &sInfo, 0, sizeof(sInfo) );
sInfo.cb = sizeof(sInfo);

PROCESS_INFORMATION pInfo;
memset( &pInfo, 0, sizeof(pInfo) );

if ( !CreateProcess( _T("C:\Windows\
otepad.exe"), 
        NULL, NULL, NULL, FALSE, 
        NULL, NULL, NULL, &sInfo, &pInfo ) )
{
    CString strMsg;
    strMsg.Format( _T("Create Failed\n\nLast Error : %d"), 
        GetLastError() );

    AfxMessageBox( strMsg );
}
else
{
//     HWND h = ::GetTopWindow(0 );
//     while ( h )
//     {
//         DWORD pid;
//         DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
// 
//         if ( pid == pInfo.dwProcessId )
//         {
//             AfxMessageBox( _T("Finded!!") );
// 
//             HWND hParent = ::GetParent( h );
//             break;
//         }
//         h = ::GetNextWindow( h , GW_HWNDNEXT);
//     }

    HWND hWnd = ::GetDesktopWindow();
    HWND hTmpWnd = NULL;
    BOOL bFoundWnd = FALSE;
    DWORD dwPID;

    while ( hWnd != NULL && !bFoundWnd )
    {
        hTmpWnd = hWnd;
        hWnd = ::GetWindow( hWnd, GW_CHILD );
        if ( hWnd )
        {
            ::GetWindowThreadProcessId( hWnd, &dwPID );

            if ( dwPID == pInfo.dwProcessId )
                if ( ::IsWindow( hWnd ) && 
                    ::IsWindowVisible( hWnd ) )
                    bFoundWnd = TRUE;
        }
        else
        {
            hWnd = hTmpWnd;
            hWnd = ::GetWindow( hWnd, GW_HWNDNEXT );

            if ( hWnd )
            {
                ::GetWindowThreadProcessId( hWnd, &dwPID );

                if ( dwPID == pInfo.dwProcessId )
                    if ( ::IsWindow( hWnd ) && 
                        ::IsWindowVisible( hWnd ) )
                        bFoundWnd = TRUE;
            }
            else
            {
                hWnd = hTmpWnd;
                hWnd = ::GetParent( hWnd );
                if ( hWnd )
                {
                    BOOL bFoundBranch = FALSE;

                    while ( !bFoundBranch && !bFoundWnd && hWnd )
                    {
                        hTmpWnd = hWnd;
                        hWnd = ::GetWindow( hWnd, GW_HWNDNEXT );
                        if ( hWnd )
                        {
                            bFoundBranch = TRUE;

                            ::GetWindowThreadProcessId( hWnd, &dwPID );
                            if ( dwPID == pInfo.dwProcessId )
                                if ( ::IsWindow( hWnd ) && 
                                    ::IsWindowVisible( hWnd ) )
                                    bFoundWnd = TRUE;
                        }
                        else
                        {
                            hWnd = hTmpWnd;
                            hWnd = ::GetParent( hWnd );
                        }
                    }
                }
            }
        }
    }

    if ( bFoundWnd )
    {
        HWND myWnd;
        if ( ::GetParent( hWnd ) )
            myWnd = ::GetParent( hWnd );
        else
            myWnd = hWnd;
    }
}

ProcessID로 Window Handle 을 찾는 방법이다.

위의 코드는 완벽한 코드는 아니다. 프로세스 아이디 한개에 여러개의 핸들이 연결되어 있기때문에 원하는 윈도우 핸들을 정확하게 찾기 위해서는 동일한 프로세스 아이디를 갖는 여러개의 핸들 중에서 하나를 골라내는 방법이 개선 되어야 한다. 위의 코드는 단순히 윈도우 핸들인가와 윈도우가 Visible 인가만을 체크해서 골라내고 있다.
동일한 프로세스 아이디를 갖는 핸들들

동일한 프로세스 아이디를 갖는 핸들들

Original Post : http://neodreamer-dev.tistory.com/165

No comments :

Post a Comment