소스 코드 올립니다..

개학하면 바뻐서 업데이트 할 시간이 자주 없을듯 하네요..--;;

4학년 되면 취업준비한다고 바쁠테고.. 암튼 소스코드 올립니다. 언젠가는 더이상 업데이트 못 할날이 올지도 모르기 때문에..

솔직히 업데이트 하는게 기본적인틀이 잡혀 있어 어렵지는 않은데 약간은 귀찮네요..--;; 버그들도 많이 있는데.. 솔직히 손데면 일이 커질지도 모르고.. 귀찮고 해서요..

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

김정민님이 어떻게 윈도우를 찾느냐고 물어보셔서~~ 작성합니다.. 많은 도움이 되었으면 좋겠네요..

CMelOnSniperMacro는 매크로를 수행하는 클래스입니다.

이 클래스의 맴버변수로는 변환해야할 파일들 현재 몇번째 파일 변환중인지.. 몇번째 스텝인지 등을 저장하는 변수들이 있습니다.

다이어로그 클래스에서 실제 이 Macro클래스 인스턴스가 만들어집니다.. 타이머에 의해 m_DoMacro맴버 함수가 정해진 시간에 호출 됩니다. 맴버 변수가 가지고 있는 현재 상태를 가지고 매크로를 수행하는 부분입니다.

그 중 윈도우창을 찾는 부분의 소스들입니다. 중복되는것은 생략했습니다.
 

bool CMelOnSniperMacro::m_FindMainWindow(void)
{
 m_wndMelon.m_hWnd = ::FindWindow(TEXT("MelOnFrameV30"),NULL);
 if(m_wndMelon.m_hWnd == false) return false;
 return true;
}

::FindWindow(TEXT("MelOnFrameV30"),NULL); 이 함수는
첫번째 인자로 윈도우의 클래스 이름
두번째 인자는 캡션 이름
으로 윈도우를 찾고 핸들을 반환합니다.. 최상위 윈도우를 찾을 수 있습니다. NULL을 입력 할 수 있습니다.

m_wndMelonCWnd타입입니다.

만약 윈도우 내부에 있는 자식 윈도우를 찾고자 하거나 특정 윈도우 다음에 위치한 윈도우를 얻고자 할때 는
FindWindowEx(HWND, HWND, LPCWSTR, LPCWSTR);함수를 사용하시면 됩니다..
첫번째 인자는 부모 윈도우의 핸들
두번째 인자는 인자 윈도우에 다음에 위치하는 윈도우 핸들을 얻어 옵니다.
세번째 인자는 클래스명
네번쨰 인자는 캡션 명입니다..

물론 NULL값을 인자로 넘겨 줄 수 있습니다.

int CMelOnSniperMacro::m_DoMacro()
{
 
 switch(m_nStep)
 {
  case 2://찾아보기창 띄우기
  //컨버팅 변환창에서 파일 찾기 버튼 누르기
  {
   CWnd* wndDCFConverting =m_findWindow(TEXT("#32770"), _T(""), 530,455);
   if(wndDCFConverting->m_hWnd != NULL){
    wndDCFConverting->PostMessage(WM_COMMAND,0x836,0x0);
    m_nStep++;
   }
   delete(wndDCFConverting);
  }
  break;
 }
 return 0;
}

그러나 멜론 3.0으로 업데이트 되면서 대부분의 윈도우에 캡션이 없습니다. 특이 윈도우 디자인에 이미지가 많은 경우 대부분 FindWindow로 한번에 찾기 어렵습니다..

또한 클래스명 또한 다이얼로그 박스에 기본값인 #32770입니다. 따라서 같은 클래스명과 이름의 윈도우가 수개 내지 수십개가 됩니다.

그래서 윈도우를 구별하기위해 윈도우 크기를 가지고 윈도우를 찾는 함수 m_findWindow라는 함수를 구현 했습니다... 물론 이 방법은 윈도우크기가 고정되어 바꿀 수 없는 윈도우에 한해서 쓰일 수 있는 방법입니다.. 윈도우 크기가 바뀔수 있는 경우라면 또 다른 방법을 생각 해봐야겠죠..

CWnd* wndDCFConverting =m_findWindow(TEXT("#32770"), _T(""), 530,455);

윈도우를 받아 옵니다.

    wndDCFConverting->PostMessage(WM_COMMAND,0x836,0x0);

혹시 윈도우를 찾지 못할 수도 있으므로 if문을 사용 찾은 경우에만 원하는 메세지를 찾은 창에 보냅니다. 위 다른 윈도우에 명령을 보내는 방법은 PostMessageSendMessage함수 가 있습니다.

PostMessage는 비동기로 메세지를 보내고 SendMessage는 동기로 메세지를 보냅니다..

이 함수의 인자, Msg와 wParam, lParam의 값은 Spy++이나 별도의 유틸을 통해서 쉽게 얻을 수 있습니다. WM_COMMAND, 0x836, 0x0은 멜론 스나이퍼에서 [파일찾기] 버튼을 눌러주는 역활을 합니다.

아래가 윈도우의 크기로 창을 얻어오는 함수의 실제 구현입니다.

CWnd* CMelOnSniperMacro::m_findWindow( CString strClass, CString strWindow, int height, int width)
{
 CWnd* findWindow = new CWnd();
 
 do{  
  findWindow->m_hWnd = ::FindWindowEx(NULL,findWindow->m_hWnd,strClass, strWindow);
  RECT r;
  //창의 크기로 윈도우 판별함
  findWindow->GetWindowRect(&r);
  int thisHeight = r.bottom-r.top;
  int thisWidth = r.right - r.left;
  if(thisHeight == height && thisWidth==width){
   return findWindow;
  }

 }while(findWindow->m_hWnd != NULL);

 findWindow->m_hWnd = NULL;
 return findWindow;
}


findWindow->m_hWnd = ::FindWindowEx(NULL,findWindow->m_hWnd,strClass, strWindow);
우선 가장 처음 do{}while()반복무을 수행할 경우 findWindow->m_hWndNULL입니다.. 따라서 해당 클래스이름과 윈도우명을 가진 첫번째 윈도우를 찾습니다..

그 다음 윈도우크기를 비교해 크기까지 동일하면 우리가 찾으려 했던 윈도우이므로~~ 해당 윈도우를 반환하고..

만약 윈도우 크기가 다르면 다음 윈도우를 찾아야합니다.

do{}while()반복문이 처음이 두번째 수행되는 것이라면  findWindow->m_hWnd가 이전에 찾았던 윈도우입니다.

FindWindowEx에서 두번째 인자가 이 다음 윈도우를 찾아라 하는 인자입니다.. 그럼으로 두번째 해당윈도우 클래스명과 이름을 가지는 두번째 윈도우를 찾게 되는 것입니다.
findWindow->m_hWnd = ::FindWindowEx(NULL,findWindow->m_hWnd,strClass, strWindow);

계속 해서 찾다가 더이상 다음 윈도우가 없을경우~~ null을 반환하고 while()문을 빠져 나오게 됩니다..
신고
크리에이티브 커먼즈 라이선스
Creative Commons License


티스토리 툴바