엑셀 카카오톡 자동화 프로그램 만들기 (윈도우 API 응용)

엑셀 VBA와 Win32 API를 사용하여 카카오톡 문자보내기 자동화를 위한 전체 명령문 및 동작원리를 단계별로 살펴봅니다.

# VBA

작성자 :
오빠두엑셀
최종 수정일 : 2024. 10. 09. 06:02
URL 복사
메모 남기기 : (94)

엑셀 카카오톡 자동화 프로그램 만들기 (윈도우 API 응용)

엑셀 카카오톡 자동화 목차 바로가기
영상강의

큰 화면으로 보기

.

라이브 강의 전체영상도 함께 확인해보세요!

위캔두 회원이 되시면 매주 오빠두엑셀에서 진행하는 라이브강의 풀영상을 확인하실 수 있습니다.


예제파일 다운로드

오빠두엑셀의 강의 예제파일은 여러분을 위해 자유롭게 제공하고 있습니다.

  • [VBA프로젝트] 엑셀 카카오톡 자동화 프로그램 (Win32 API 응용)
    예제파일
  • ✨ 엑셀 카카오톡 문자보내기 자동화 서식
    회원자료

hWnd 란 무엇인가요?

윈도우 hwnd
윈도우에서 실행되는 모든 프로그램에는 고유한 hWnd 값이 주어집니다.

hWnd 란 'Handle to the Window"의 약자로 윈도우에서 실행중인 프로그램의 창 고유값을 이야기 합니다. 윈도우에서 실행되는 모든 프로그램의 모든 창(Window)는 각각의 고유값을 가지며, 이번 강의에서 다룰 카카오톡 또한 각 단계별로 실행되는 각각의 창 마다 고유한 값을 가지게 됩니다.

Window Detective (윈도우 hWnd 조회 프로그램) 다운로드

이번 강의 초반부에 간략히 설명해드린 hWnd(Handle to Window : 실행 중인 프로그램의 고유 창 번호)을 조회하려면 Window Detective 라는 프로그램이 필요합니다. (이 외에도 Spy++, WinSpy++ 등 여러 다른 프로그램을 사용할 수도 있습니다.)

현재 사용중인 PC에서 실행되고 있는 카카오톡 또는 다른 프로그램의 창 번호를 직접 조회하며 강의를 실습하시려면 아래 링크로 이동하여 Window Detective 프로그램을 설치한 뒤 강의를 진행해주세요.

(아래 적어드린 최종 명령문에는 카카오톡에 사용된 모든 클래스 이름 및 창 이름을 적어드렸으므로, Window Detective는 꼭 설치하지 않으시더라도 강의를 진행할 수 있습니다.)

윈도우 API 살펴보기

윈도우 API 란 마이크로소프트에서 윈도우 운영체제에서 실행되는 다양한 프로그램를 제어하기 위하여 제공하는 API(Application Programming Interfaces) 입니다. 윈도우 API는 각 윈도우 운영체제 버전에 따라 다양하게 제공되며, 현재 대표적으로 사용되는 API 버전은 Win32 API 입니다.

Win32 API는 윈도우 95 부터 제공되기 시작하였고, 2020년 기준으로 마이크로소프트에서는 Win32 대신 Win64 API 를 사용할 것을 권장하고 있습니다. 하지만 아직까지는 혹시라도 모를 호환성 문제로 인하여 VBA로 윈도우 API를 사용할 경우에는 Win32 API를 사용할 것을 권장드립니다.

윈도우 API는 윈도우 운영체제 버전에 따라 다양하게 지원됩니다.

  • Win16 / Win32 / WIn32s / Win64 / WinCE

윈도우 API 에서 제공되는 함수는 크게 8개의 카테고리로 구분할 수 있습니다. 특히 엑셀 VBA에서 자주 사용되는 윈도우 API 라이브러리는 User32.dll 이며, 이번 강의에서도 user32.dll 라이브러리에서 제공되는 함수만 사용하였습니다.

  1. Base Service (kernel32.dll) :
    파일 시스템, 장치, 스레드, 오류처리 등의 중요 리소스 접근에 사용됩니다.
  2. Advanced Service (advapi32.dll) :
    윈도우 레지스트리, 시스템 재부팅, 시작, 종료, 계정 생성 등 부가기능 접근에 사용됩니다.
  3. Graphics Device Service (gdi32.dll) :
    모니터, 프린터, 출력장치 접근에 사용됩니다.
  4. ★ User Interface (user32.dll) :
    화면, 마우스, 키보드, 윈도우 GUI 연동 등 대부분의 엑셀과 외부 프로그램 연동 시 사용되는 라이브러리입니다.
  5. Common Dialog Box Library (comdlg32.dll) :
    응용프로그램 실행, 파일 저장 등을 위한 대화상자 접근에 사용됩니다.
  6. Common Control Library (comctl32.dll) :
    상태표시줄, 도구모음 등 일부 프로그램에서 제공하는 옵션 컨트롤에 접근에 사용됩니다.
  7. Windows Shell (shell32.dll) :
    셸(Shell) 접근에 사용됩니다. 다양한 명령문을 통한 프로그램 제어에 사용됩니다.
  8. Network Services :
    인터넷 익스프롤러, FTP 접속 등 네트워킹 기능 제어에 사용됩니다.

강의에 사용된 전체 명령문

Option Explicit
 
#If VBA7 Then
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowa
Private Declare PtrSafe Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
                                                        (ByVal lpClassName As String, _
                                                        ByVal lpWindowName As String) As Long
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowexa
Private Declare PtrSafe Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _
                                                            (ByVal hwndParent As Long, _
                                                            ByVal hwndChildAfter As Long, _
                                                            ByVal lpszClass As String, _
                                                            ByVal lpszWindow As String) As Long
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagea
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal wMsg As Long, _
                                                            ByVal wParam As Long, _
                                                            ByRef lParam As Any) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea
Private Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal wMsg As Long, _
                                                            ByVal wParam As Long, _
                                                            ByRef lParam As Any) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-keybd_event
Private Declare PtrSafe Sub keybd_event Lib "user32.dll" _
                                                            (ByVal bVk As Byte, _
                                                            ByVal bScan As Byte, _
                                                            ByVal dwFlags As Long, _
                                                            ByVal dwExtraInfo As Long)
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getkeystate
Private Declare PtrSafe Function GetKeyState Lib "user32" ( _
                                                            ByVal nVirtKey As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindow
Public Declare PtrSafe Function GetWindow _
                                                        Lib "user32" _
                                                        (ByVal hwnd As Long, _
                                                        ByVal wCmd As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclassname
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal lpClassName As String, _
                                                            ByVal nMaxCount As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtexta
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal lpString As String, _
                                                            ByVal cch As Long) As Long
#Else
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowa
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
                                                        (ByVal lpClassName As String, _
                                                        ByVal lpWindowName As String) As Long
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowexa
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _
                                                            (ByVal hwndParent As Long, _
                                                            ByVal hwndChildAfter As Long, _
                                                            ByVal lpszClass As String, _
                                                            ByVal lpszWindow As String) As Long
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagea
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal wMsg As Long, _
                                                            ByVal wParam As Long, _
                                                            ByRef lParam As Any) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal wMsg As Long, _
                                                            ByVal wParam As Long, _
                                                            ByRef lParam As Any) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-keybd_event
Private Declare Sub keybd_event Lib "user32.dll" _
                                                            (ByVal bVk As Byte, _
                                                            ByVal bScan As Byte, _
                                                            ByVal dwFlags As Long, _
                                                            ByVal dwExtraInfo As Long)
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getkeystate
Private Declare Function GetKeyState Lib "user32" ( _
                                                            ByVal nVirtKey As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindow
Public Declare Function GetWindow _
                                                        Lib "user32" _
                                                        (ByVal hwnd As Long, _
                                                        ByVal wCmd As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclassname
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal lpClassName As String, _
                                                            ByVal nMaxCount As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtexta
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal lpString As String, _
                                                            ByVal cch As Long) As Long
#End If
 
'######################################
' 공통 상수 선언
'######################################
' 가상키 ASCII 코드
Public Const WM_SETTEXT = &HC
Public Const WM_KEYDOWN = &H100
Public Const WM_KEYUP = &H101
Public Const VK_RETURN = &HD
Public Const VK_CONTROL = &H11
Public Const VK_ESC = &H1B
Public Const KEYEVENTF_KEYUP As Long = 2
Public Const VK_A = &H41
Public Const VK_V = &H56
Public Const VK_C = &H43
Public Const VK_DOWN = &H28
Public Const VK_UP = &H26
 
'######################################
' 친구에게 카카오톡 메세지를 전송합니다.
'######################################
Function SendKakao(Target As String, Message As String, Optional ChatRoomSearch As Boolean = False, Optional iDelay As Long = 1) As Boolean
 
' 변수 선언
Dim hwnd_RichEdit As Long       ' 채팅입력창 hwnd
 
' 친구 채팅입력창 hwnd 찾기
hwnd_RichEdit = FindRecepientHwnd(Target, ChatRoomSearch, iDelay)
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
 
'보낼 대상의 채팅창 없을 경우 안내메세지 출력 후 종료
If hwnd_RichEdit = 0 Then MsgBox "보낼 대상의 카카오톡 대화창을 찾을 수 없습니다.": Exit Function
 
' 메세지 보내기
Send_TextMsg Message, hwnd_RichEdit
 
End Function
 
'######################################
' 카카오톡 메세지를 전송합니다.
'######################################
Sub Send_TextMsg(Message As String, hwnd_RichEdit As Long)
 
' 대화상대 채팅 입력창 hWnd 에 메세지 입력
Call SendMessage(hwnd_RichEdit, WM_SETTEXT, 0, ByVal Message)
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
' 사용자 Ctrl 키 입력여부 확인
If IsCtrlKeyDown = False Then
    ' Ctrl 키 미입력 시, 메세지 전송
    Call PostMessage(hwnd_RichEdit, WM_KEYDOWN, VK_RETURN, 0)
Else
    ' Ctrl 키 입력중일 경우, 강제로 Ctrl 키 올림 -> 메세지 전송 -> Ctrl 키 재입력
    keybd_event VK_CONTROL, 0, KEYEVENTF_KEYUP, 0
    Call PostMessage(hwnd_RichEdit, WM_KEYDOWN, VK_RETURN, 0)
    keybd_event VK_CONTROL, 0, 0, 0
End If
 
End Sub
 
'######################################
' 보낼 대상의 hWnd 값을 찾습니다.
' 보낼 대상의 채팅창이 없을 경우 False를 반환합니다.
'######################################
Function FindRecepientHwnd(Target As String, ChatRoomSearch As Boolean, iDelay As Long) As Long
 
' 변수 선언
Dim dStart As Double
Dim hwnd_KakaoTalk As Long   ' 친구 채팅창 hwnd
Dim hwnd_RichEdit As Long       ' 채팅입력창 hwnd
 
' 보낼대상의 카톡창 실행
ActiveChat Target, iDelay, ChatRoomSearch
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
 
' 보낼대상의 카톡창 Hwnd 찾기
hwnd_KakaoTalk = FindWindow(vbNullString, Target)
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
 
dStart = Now
While hwnd_KakaoTalk = 0
    hwnd_KakaoTalk = FindWindow(vbNullString, Target)
    ' 1초 지날때까지 창을 못찾으면 함수 결과로 False 반환 후 종료
    If DateDiff("s", dStart, Now) > 1 Then FindRecepientHwnd = 0: Exit Function
Wend
 
' 친구의 채팅입력창 hWnd 찾기
hwnd_RichEdit = FindWindowEx(hwnd_KakaoTalk, 0, "RichEdit50W", vbNullString)  '카카오톡 버전에 따른 RichEdit ClassName 차이
If hwnd_RichEdit = 0 Then hwnd_RichEdit = FindWindowEx(hwnd_KakaoTalk, 0, "RichEdit20W", vbNullString)
 
FindRecepientHwnd = hwnd_RichEdit
 
End Function
 
'############################
' 친구 채팅창이 열려있지 않을 경우 채팅창을 검색 후 활성화합니다.
'############################
Function ActiveChat(Target As String, iDelay As Long, ChatRoomSearch As Boolean)
 
' 변수 설정
Dim hWndMain As Long: Dim hWndChild1 As Long: Dim hWndChild2 As Long: Dim hWndEdit As Long
Dim i As Long
 
' 대화상대 창 이미 열려있을 시 명령문 종료
If FindWindow(vbNullString, Target) > 0 Then Exit Function
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
 
' 카카오톡 메인 hWnd 검색 [▶▶▶▶▶F5키]
hWndMain = FindHwndEVA
' 카카오톡 메인 창 없으면 카톡 실행 안됨 -> 함수 False 반환 후 명령문 종료
If hWndMain = 0 Then ActiveChat = False: Exit Function
 
' 메인 [▶▶▶▶▶F5키]
hWndChild1 = FindWindowEx(hWndMain, 0, "EVA_ChildWindow", vbNullString)
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
' 연락처 목록 검색 -> EVA_Window 첫번째 항목
hWndChild2 = FindWindowEx(hWndChild1, 0, "EVA_Window", vbNullString)
' 채팅창 목록 검색 -> EVA_Window 두번째 항목
If ChatRoomSearch = True Then hWndChild2 = FindWindowEx(hWndChild1, hWndChild2, "EVA_Window", vbNullString)
' EVA_Window의 대화상대 검색창
hWndEdit = FindWindowEx(hWndChild2, 0, "Edit", vbNullString)
 
' 검색창에 대화상대 복사/붙여넣기
Call SendMessage(hWndEdit, WM_SETTEXT, 0, ByVal Target): MyDelay iDelay
' 채팅창 목록 검색일 경우 윗쪽방향키 눌러서 첫번째 항목 활성화
If ChatRoomSearch = True Then Call PostMessage(hWndEdit, WM_KEYDOWN, VK_UP, 0): MyDelay iDelay
' 엔터키로 채팅창 열기
Call PostMessage(hWndEdit, WM_KEYDOWN, VK_RETURN, 0): MyDelay iDelay
 
End Function
 
'############################
' 카카오톡 실행여부 확인 후, 실행중일 시 메인창의 hWnd 를 반환합니다.
'############################
Private Function FindHwndEVA() As Long
 
' 변수 설정
Dim hwnd As Long: Dim lngT As Long: Dim strT As String
 
' 현재 Desktop에서 실행중인 첫번째 프로그램 hWnd
hwnd = FindWindowEx(0, 0, vbNullString, vbNullString)
 
' 모든 hWnd 를 돌아가며 검색
While hwnd <> 0
    ' hWnd를 돌아가며 ClassName을 확인
    strT = String(100, Chr(0))
    lngT = GetClassName(hwnd, strT, 100)
    ' hWnd 의 ClassName 에 "EVA_Window_DblClk"이 포함될 경우
    If InStr(1, Left(strT, lngT), "EVA_Window_Dblclk") > 0 Then
        ' 해당 hWnd의 채팅창이름을 받아옵니다.
        strT = String(100, Chr(0))
        lngT = GetWindowText(hwnd, strT, 100)
        ' 채팅창 이름이 "카카오톡" 또는 "KakaoTalk"(영문OS 사용시)일 경우, hWnd 을 함수 결과로 반환 후 종료
        If InStr(1, Left(strT, lngT), "카카오톡") > 0 Or InStr(1, Left(strT, lngT), "KakaoTalk") > 0 Then FindHwndEVA = hwnd: Exit Function
    End If
hwnd = FindWindowEx(0, hwnd, vbNullString, vbNullString)
Wend
 
End Function
 
'###############################################################
'오빠두엑셀 VBA 사용자지정함수 (https://www.oppadu.com)
'▶ MyDelay 함수
'▶ 임시 지연 코드
'▶ ______________iDelay    : 지연 속도 조절 (클수록 많은 지연, 1 ≒ 4ms)
'###############################################################
Sub MyDelay(Optional iDelay As Long = 1)
 
Dim i As Long
For i = 1 To iDelay * 10000000:        i = i + 1:        Next
 
End Sub
 
'###############################################################
'오빠두엑셀 VBA 사용자지정함수 (https://www.oppadu.com)
'▶ IsCtrlKeyDown 함수
'▶ 키보드 Ctrl 키 누름여부를 확인합니다.
'▶ 인수 설명
'_____________LeftRightKey : 왼쪽/오른쪽 Ctrl 키 누름여부를 정합니다.
' 1 : 왼쪽 Ctrl키 입력시 TRUE
' 2 : 오른쪽 Ctrl키 입력시 TRUE
' 3 : 양쪽 Ctrl키 동시 입력시 TRUE
' 0 : 둘 중 하나라도 입력시 TRUE
'###############################################################
 
Private Function IsCtrlKeyDown(Optional LeftRightKey As Long = 0) As Boolean
 
Const VK_LCTRL = &HA2: Const VK_RCTRL = &HA3: Const KEY_MASK As Integer = &HFF80
 
Dim Result As Long
 
Select Case LeftRightKey
    '왼쪽 CTRL 키 입력여부 확인
    Case 1:        Result = GetKeyState(VK_LCTRL) And KEY_MASK
    '오른쪽 CTRL 키 입력여부 확인
    Case 2:        Result = GetKeyState(VK_RCTRL) And KEY_MASK
    '양쪽 CTRL 키 동시 입력여부 확인
    Case 3:        Result = GetKeyState(VK_LCTRL) And GetKeyState(VK_RCTRL) And KEY_MASK
    'CTRL 키 둘중 하나의 입력여부 확인
    Case Else:    Result = GetKeyState(vbKeyControl) And KEY_MASK
End Select
 
IsCtrlKeyDown = CBool(Result)
 
End Function

강의에 사용된 보조 명령문 목록

엑셀 카카오톡 자동화 명령문 순서
엑셀 카카오톡 자동화 명령문에는 크게 4개의 보조명령문이 사용되었습니다.

이번 강의에서 제작한 SendKakao 명령문은 크게 4개의 보조 명령문으로 나뉘어 제작되었으며 각 보조 명령문의 구성은 아래와 같습니다.

  1. FindHwndEVA 함수 : 카카오톡 실행여부 확인 및 카카오톡 메인 윈도우의 hWnd 를 반환합니다.
    '############################
    ' 카카오톡 실행여부 확인 후, 실행중일 시 메인창의 hWnd 를 반환합니다.
    '############################
    Private Function FindHwndEVA() As Long
     
    ' 변수 설정
    Dim hwnd As Long: Dim lngT As Long: Dim strT As String
     
    ' 현재 Desktop에서 실행중인 첫번째 프로그램 hWnd
    hwnd = FindWindowEx(0, 0, vbNullString, vbNullString)
     
    ' 모든 hWnd 를 돌아가며 검색
    While hwnd <> 0
        ' hWnd를 돌아가며 ClassName을 확인
        strT = String(100, Chr(0))
        lngT = GetClassName(hwnd, strT, 100)
        ' hWnd 의 ClassName 에 "EVA_Window_DblClk"이 포함될 경우
        If InStr(1, Left(strT, lngT), "EVA_Window_Dblclk") > 0 Then
            ' 해당 hWnd의 채팅창이름을 받아옵니다.
            strT = String(100, Chr(0))
            lngT = GetWindowText(hwnd, strT, 100)
            ' 채팅창 이름이 "카카오톡" 또는 "KakaoTalk"(영문OS 사용시)일 경우, hWnd 을 함수 결과로 반환 후 종료
            If InStr(1, Left(strT, lngT), "카카오톡") > 0 Or InStr(1, Left(strT, lngT), "KakaoTalk") > 0 Then FindHwndEVA = hwnd: Exit Function
        End If
    hwnd = FindWindowEx(0, hwnd, vbNullString, vbNullString)
    Wend
     
    End Function
  2. ActiveChat 함수 : 카카오톡의 친구목록에서 친구 검색 후, 엔터키를 입력하여 친구 채팅창을 활성화합니다.

    인수 설명
    Target As String 친구목록에서 검색할 친구 이름입니다.
    iDelay As Long 친구목록 검색 시 적용할 지연 시간입니다. (1 = 약 0.04s)
    ChatRoomSearch As Boolean TRUE 일 경우 대화목록에서 검색합니다.
    '############################
    ' 친구 채팅창이 열려있지 않을 경우 채팅창을 검색 후 활성화합니다.
    '############################
    Function ActiveChat(Target As String, iDelay As Long, ChatRoomSearch As Boolean)
     
    ' 변수 설정
    Dim hWndMain As Long: Dim hWndChild1 As Long: Dim hWndChild2 As Long: Dim hWndEdit As Long
    Dim i As Long
     
    ' 대화상대 창 이미 열려있을 시 명령문 종료
    If FindWindow(vbNullString, Target) > 0 Then Exit Function
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
     
    ' 카카오톡 메인 hWnd 검색 [▶▶▶▶▶F5키]
    hWndMain = FindHwndEVA
    ' 카카오톡 메인 창 없으면 카톡 실행 안됨 -> 함수 False 반환 후 명령문 종료
    If hWndMain = 0 Then ActiveChat = False: Exit Function
     
    ' 메인 [▶▶▶▶▶F5키]
    hWndChild1 = FindWindowEx(hWndMain, 0, "EVA_ChildWindow", vbNullString)
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
    ' 연락처 목록 검색 -> EVA_Window 첫번째 항목
    hWndChild2 = FindWindowEx(hWndChild1, 0, "EVA_Window", vbNullString)
    ' 채팅창 목록 검색 -> EVA_Window 두번째 항목
    If ChatRoomSearch = True Then hWndChild2 = FindWindowEx(hWndChild1, hWndChild2, "EVA_Window", vbNullString)
    ' EVA_Window의 대화상대 검색창
    hWndEdit = FindWindowEx(hWndChild2, 0, "Edit", vbNullString)
     
    ' 검색창에 대화상대 복사/붙여넣기
    Call SendMessage(hWndEdit, WM_SETTEXT, 0, ByVal Target): MyDelay iDelay
    ' 채팅창 목록 검색일 경우 윗쪽방향키 눌러서 첫번째 항목 활성화
    If ChatRoomSearch = True Then Call PostMessage(hWndEdit, WM_KEYDOWN, VK_UP, 0): MyDelay iDelay
    ' 엔터키로 채팅창 열기
    Call PostMessage(hWndEdit, WM_KEYDOWN, VK_RETURN, 0): MyDelay iDelay
     
    End Function
  3. FindRecepientHwnd 함수 : 친구채팅창의 채팅입력창 hWnd 를 반환합니다.
    인수 설명
    Target As String 친구목록에서 검색할 친구 이름입니다.
    iDelay As Long 친구목록 검색 시 적용할 지연 시간입니다. (1 = 약 0.04s)
    ChatRoomSearch As Boolean TRUE 일 경우 친구이름을 대화목록에서 검색합니다.
    '######################################
    ' 보낼 대상의 hWnd 값을 찾습니다.
    ' 보낼 대상의 채팅창이 없을 경우 False를 반환합니다.
    '######################################
    Function FindRecepientHwnd(Target As String, ChatRoomSearch As Boolean, iDelay As Long) As Long
     
    ' 변수 선언
    Dim dStart As Double
    Dim hwnd_KakaoTalk As Long   ' 친구 채팅창 hwnd
    Dim hwnd_RichEdit As Long       ' 채팅입력창 hwnd
     
    ' 보낼대상의 카톡창 실행
    ActiveChat Target, iDelay, ChatRoomSearch
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
     
    ' 보낼대상의 카톡창 Hwnd 찾기
    hwnd_KakaoTalk = FindWindow(vbNullString, Target)
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
     
    dStart = Now
    While hwnd_KakaoTalk = 0
        hwnd_KakaoTalk = FindWindow(vbNullString, Target)
        ' 1초 지날때까지 창을 못찾으면 함수 결과로 False 반환 후 종료
        If DateDiff("s", dStart, Now) > 1 Then FindRecepientHwnd = 0: Exit Function
    Wend
     
    ' 친구의 채팅입력창 hWnd 찾기
    hwnd_RichEdit = FindWindowEx(hwnd_KakaoTalk, 0, "RichEdit50W", vbNullString)  '카카오톡 버전에 따른 RichEdit ClassName 차이
    If hwnd_RichEdit = 0 Then hwnd_RichEdit = FindWindowEx(hwnd_KakaoTalk, 0, "RichEdit20W", vbNullString)
     
    FindRecepientHwnd = hwnd_RichEdit
     
    End Function
  4. Send_TextMsg 함수 : 채팅입력창에 메시지를 입력 후 엔터키를 눌러 메시지를 전송합니다.
    인수 설명
    Message As String 친구에게 보낼 메시지입니다.
    hwnd_RichEdit As Long 보낼 메시지를 입력할 채팅입력창의 hWnd 입니다.
    '######################################
    ' 카카오톡 메세지를 전송합니다.
    '######################################
    Sub Send_TextMsg(Message As String, hwnd_RichEdit As Long)
     
    ' 대화상대 채팅 입력창 hWnd 에 메세지 입력
    Call SendMessage(hwnd_RichEdit, WM_SETTEXT, 0, ByVal Message)
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
    ' 사용자 Ctrl 키 입력여부 확인
    If IsCtrlKeyDown = False Then
        ' Ctrl 키 미입력 시, 메세지 전송
        Call PostMessage(hwnd_RichEdit, WM_KEYDOWN, VK_RETURN, 0)
    Else
        ' Ctrl 키 입력중일 경우, 강제로 Ctrl 키 올림 -> 메세지 전송 -> Ctrl 키 재입력
        keybd_event VK_CONTROL, 0, KEYEVENTF_KEYUP, 0
        Call PostMessage(hwnd_RichEdit, WM_KEYDOWN, VK_RETURN, 0)
        keybd_event VK_CONTROL, 0, 0, 0
    End If
     
    End Sub
  5. SendKakao 함수 : 지정한 친구에게 메시지를 전송합니다.
    인수 설명
    Target As String 메시지를 보낼 친구 이름입니다.
    Message As Long 친구에게 보낼 메시지입니다.
    ChatRoomSearch As Boolean TRUE 일 경우 친구이름을 대화목록에서 검색합니다.
    iDelay As Long 친구이름 검색 시 적용할 지연시간입니다.
    '######################################
    ' 친구에게 카카오톡 메세지를 전송합니다.
    '######################################
    Function SendKakao(Target As String, Message As String, Optional ChatRoomSearch As Boolean = False, Optional iDelay As Long = 1) As Boolean
     
    ' 변수 선언
    Dim hwnd_RichEdit As Long       ' 채팅입력창 hwnd
     
    ' 친구 채팅입력창 hwnd 찾기
    hwnd_RichEdit = FindRecepientHwnd(Target, ChatRoomSearch, iDelay)
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
     
    '보낼 대상의 채팅창 없을 경우 안내메세지 출력 후 종료
    If hwnd_RichEdit = 0 Then MsgBox "보낼 대상의 카카오톡 대화창을 찾을 수 없습니다.": Exit Function
     
    ' 메세지 보내기
    Send_TextMsg Message, hwnd_RichEdit
     
    End Function
4.8 49 투표
게시글평점
94 댓글
Inline Feedbacks
모든 댓글 보기
94
0
여러분의 생각을 댓글로 남겨주세요.x