C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[895] 프로세스 아이디로 윈도우 핸들 얻기, 프로그램 실행시키고 윈도우 핸들 얻기
아제나 [azena] 23930 읽음    2009-06-13 06:54
프로그램에서 다른 프로그램을 실행시키고 SendMessage 등으로 메시지를 보내고 싶은 경우가 있는데요.

SendMessage에는 윈도우 핸들을 넣어야 하기 때문에, 실행시킨 프로그램의 윈도우 핸들을 얻어야 하죠.

FindWindow로 찾으면 간단하지만, 같은 프로그램이 여러개 실행될 가능성이 있는 경우에는 쓸 수 없죠.

구글링을 통해서 윈도우 핸들을 찾을 수 있는 코드를 만들었습니다.


// idea from http://support.microsoft.com/kb/242308/en-us

ULONG ProcIDFromWnd(HWND hwnd) // 윈도우 핸들로 프로세스 아이디 얻기
{
  ULONG idProc;
  GetWindowThreadProcessId( hwnd, &idProc );
  return idProc;
}

HWND GetWinHandle(ULONG pid) // 프로세스 아이디로 윈도우 핸들 얻기
{
  HWND tempHwnd = FindWindow(NULL,NULL); // 최상위 윈도우 핸들 찾기

  while( tempHwnd != NULL )
  {
    if( GetParent(tempHwnd) == NULL ) // 최상위 핸들인지 체크, 버튼 등도 핸들을 가질 수 있으므로 무시하기 위해
      if( pid == ProcIDFromWnd(tempHwnd) )
        return tempHwnd;
    tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT); // 다음 윈도우 핸들 찾기
  }
  return NULL;
}



사용 방법은 아래와 같습니다.


  bool result;
  STARTUPINFO si;
  ZeroMemory(&si,sizeof(si));
  si.cb = sizeof(si);
  PROCESS_INFORMATION pi;

  result = CreateProcess("SpxCaster.exe",NULL,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi); // 프로세스 만들기

  if( result )
  {
    HWND hwnd;
    DWORD startTime = timeGetTime();

    while(true) // CreateProcess 하면 바로 윈도우가 열리는게 아니므로 대기하기 위해
    {
      if( timeGetTime() - startTime > 5000 ) // 무한 대기 방지용. 5초 초과되면 루프 나가야 하므로 판단
        break;
      else
        Sleep(100); 

      hwnd = GetWinHandle(pi.dwProcessId); // 프로세스 아이디로 윈도우 핸들 얻기
      
      if( hwnd != NULL )
      {
        // 프로세스 아이디와 핸들을 이용
        m_CasterHandle = pi.hProcess; 
        m_CasterHWND = hwnd;
        break;
      }
    }

    if( hwnd == NULL )
      MsgError("핸들 발견 실패");
  }
  else
    MsgError("프로세스 생성 실패");

장성호 [nasilso]   2009-06-15 11:09 X
좋네요..
저도 가끔 이 기능이 필요해서 만들어 쓰는데..
커뮤니티에 이런 질문이 종종 올라오더군요..

그런데..
"CreateProcess 하면 바로 윈도우가 열리는게 아니므로 대기하기 위해서는..."

대게 WaitForInputIdle 이라는 API를 씁니다.
CreateProcess후 WaitForInputIdle 로 대기했다가
FindWindow하면 while문으로 찾을때까지 반복하지 않아도 찾아집니다.
혹 압니까? 첫번째Window를 생성할때까지 5초 이상 걸리지...
아제나 [azena]   2009-06-16 11:18 X
오호라 좋은 API가 있었군요.
훨씬 편리하게 쓸 수 있네요.
정보 감사합니다~
아제나 [azena]   2009-06-16 11:23 X
The WaitForInputIdle function waits until the specified process is waiting for user input with no input pending, or until the time-out interval has elapsed.

DWORD WaitForInputIdle(
  HANDLE hProcess, // 프로세스 핸들
  DWORD dwMilliseconds  // 대기 시간 (ms)
);

+ -

관련 글 리스트
895 프로세스 아이디로 윈도우 핸들 얻기, 프로그램 실행시키고 윈도우 핸들 얻기 아제나 23930 2009/06/13
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.