대략 1년 후... 2부를 쓰게됩니다. 게으름의 극치를 보여주는군요....ㅋㅋㅋ
이번 글에서는 카카오톡이 켜져있는지의 여부를 확인하는 방법, 열린 채팅방 목록을 가져오는 것,
그리고 채팅방에 텍스트를 입력/전송하는 것을 설명함으로써 마치려고 합니다.
만약, 1부를 읽지 않으셨다면 "꼭" 1부를 읽고 와주시면 좋겠어요!
1부에서는 설명드리지 않았는데, 카카오톡의 클래스 구조는 다음 그림에서 확인하실 수 있습니다.
위 그림을 트리 구조로 표현하면 다음과 같이 표현할 수 있습니다.
+ #32770
+ #32770
+ #32770
- Edit
+ EVA_VH_ListControl
- _EVA_CustomScrollCtrl
+ EVA_VH_ListControl
- _EVA_CustomScrollCtrl
+ #32770
- Edit
+ EVA_VH_ListControl
- _EVA_CustomScrollCtrl
+ EVA_VH_ListControl
- _EVA_CustomScrollCtrl
+ EVA_Windowㅋ
- _EVA_CustomScrollCtrl
+ EVA_Window
- _EVA_CustomScrollCtrl
+ #32770
- Edit
- EVA_Window
이 구조를 응용하면, 카카오톡이 실행 중인지 아닌지를 확인할 수 있게 됩니다.
카카오톡이 실행 중인지 확인하는 방법
- 의사 코드 (Pseudo code)
- FindWindow/FindWindowEx API를 사용하여 클래스 이름이 #32770 인 윈도우를 찾는다.
- GetWindowText API를 사용하여 해당 윈도우의 텍스트를 가져온다.
- API가 실패한 경우 다음 윈도우로 넘어간다.
- 해당 윈도우의 텍스트가 "카카오톡" 인 경우 FindWindowEx API를 사용하여 구조를 확인한다.
- 실제 코드 (C#)
// 창 핸들인지 확인한다.
if (!IsWindow(hWnd)) return false;
// 윈도우의 제목을 가져온다.
string name = GetWindowText(hWnd);
if (name == null) return false;
// 총 2개의 하위 다이얼로그가 있으므로
// 핸들을 가져온다.
IntPtr hChildDialog1 = FindWindowEx(hWnd, IntPtr.Zero, "#32770", null);
IntPtr hChildDialog2 = FindWindowEx(hWnd, hChildDialog1, "#32770", null);
// 두 개의 다이얼로그 중 하나의 값이라도 받아오지 못한 경우
// 정상적인 카카오톡 창이 아니다.
if (hChildDialog1 == IntPtr.Zero || hChildDialog2 == IntPtr.Zero) return false;
// 이제 다이얼로그의 하위 구조를 확인한다.
IntPtr hDialogChildDialog1 = FindWindowEx(hChildDialog1, IntPtr.Zero, "#32770", null);
IntPtr hDialogChildDialog2 = FindWindowEx(hChildDialog1, hDialogChildDialog1, "#32770", null);
IntPtr hDialogChildEvaWindow1 = FindWindowEx(hChildDialog1, IntPtr.Zero, "EVA_Window", null);
IntPtr hDialogChildEvaWindow2 = FindWindowEx(hChildDialog1, hDialogChildEvaWindow1, "EVA_Window", null);
// 네 개의 윈도우 핸들이 유효하다면 정상적인 카카오톡 창이다.
// 더 깊게 들어가야 하지만, 이 정도만 검사하면 된다.
return
hDialogChildDialog1 != IntPtr.Zero &&
hDialogChildDialog2 != IntPtr.Zero &&
hDialogChildEvaWindow1 != IntPtr.Zero &&
hDialogChildEvaWindow2 != IntPtr.Zero;
}
열린 채팅방을 가져오는 방법은 더 쉽습니다. 위 코드를 약간 응용하기만 하면 되는데요,
본격적으로 들어가기에 앞서 1부에서 보여드렸던 카카오톡 채팅방 구조를 슬쩍 보시고 넘어가면 되겠습니다.
채팅방 구조를 트리 구조로 표현하면 다음과 같이 표현할 수 있습니다.
+ #32770
+ EVA_VH_ListControl
- _EVA_CustomScrollCtrl
- RichEdit20W
이 구조를 이해하시면 지정된 다이얼로그가 채팅방인지 아닌지 아주 손쉽게 검사할 수 있게 됩니다.
카카오톡 채팅방인지 아닌지 검사하는 방법
- 의사 코드 (Pseudo code)
- FindWindow/FindWindowEx API를 사용하여 클래스 이름이 #32770 인 윈도우를 찾는다.
- FindWindowEx API를 사용하여 1단계에서 찾은 #32770 핸들의 자식 핸들을 찾는다.
- 찾는 클래스 이름은 각각 RichEdit20W / EVA_VH_ListControl
- EVA_VH_ListControl 핸들을 찾은 다음에는 _EVA_CustomScrollCtrl 핸들을 찾으면 된다.
- 실제 코드 (C#)
if (!IsWindow(hWnd)) return false;
IntPtr hEdit, hList, hScrl;
hEdit = FindWindowEx(hWnd, IntPtr.Zero, "RichEdit20W", null);
hList = FindWindowEx(hWnd, IntPtr.Zero, "EVA_VH_ListControl", null);
hScrl = FindWindowEx(hList, IntPtr.Zero, "_EVA_CustomScrollCtrl", null);
return (hEdit != IntPtr.Zero) && (hList != IntPtr.Zero) && (hScrl != IntPtr.Zero);
}
카카오톡 윈도우인지 확인하는 방법과 카카오톡 채팅방인지 확인하는 방법은 모두 설명드렸습니다.
이제 마지막 남은 RichEdit20W 컨트롤에 텍스트를 설정하고 전송하는 방법을 설명해 드리도록 하겠습니다.
어떻게 보면 텍스트를 설정/전송하는 것이 가장 쉽게 느껴지실 수도 있습니다.
SendMessage API를 이용하여 RichEdit20W 컨트롤에 텍스트를 설정한 후 PostMessage API로 키 입력을 시뮬레이션하면 ~~끝!
카카오톡 채팅방에 텍스트 설정/전송하는 방법
- 의사 코드 (Pseudo code)
- SendMessage API와 WM_SETTEXT 메세지를 이용하여 RichEdit20W 컨트롤에 텍스트를 설정
- PostMessage API와 WM_KEYDOWN, WM_KEYUP 메세지를 이용하여 키 입력을 시뮬레이션함
- 실제 코드 (C#)
SendMessage(hEdit, WM_SETTEXT, IntPtr.Zero, text);
PostMessage(hEdit, WM_KEYDOWN, VK_ENTER, IntPtr.Zero);
PostMessage(hEdit, WM_KEYUP, VK_ENTER, IntPtr.Zero);
}
코드가 간단한 순서는 텍스트 전송 > 채팅방 확인 > 카카오톡 확인 순이네요.
하지만 코드 하나하나가 복잡하지 않기 때문에 이해하시기도 쉬울 것 같습니다.
단, 주의하실 점은 플랫폼 호출(P/Invoke)에 대한 이해도가 어느 정도 있으셔야 합니다.
코드를 무작정 복/붙 하시고 "SendMessage 같은 함수는 어디있나요?" 라고 물으시는 분이 없으셨으면 좋겠습니다.
(불법적인 목적이 아닌 공부 목적으로만 사용하셨으면 좋겠습니다)
'잡담' 카테고리의 다른 글
GitHub) 내가 한 커밋에 서명(sign)을 하는 방법 (0) | 2018.09.30 |
---|---|
한성컴퓨터 ULTRON 2759G 구매 후기 (2) | 2018.09.01 |
카카오톡 파헤치기 - 1부 (8) | 2015.12.15 |
후미아 다이아몬드J 이어폰 개봉기 (0) | 2015.11.15 |
[초대장] 2015년 11월 초대장 배포 (2장) (215) | 2015.11.12 |