https://m-hjsoft.tistory.com/54
💬 C# WinForms + AutoHotkey를 활용한 메시지 자동 입력 예제
🔧 참고한 자료 엑셀 카카오톡 자동화프로그램만들기(윈도우API응용) - 오빠두엑셀 : 강의 인상적으로 봤습니다 감사합니다.AutoHotkey와 Excel을 연동하여 구현한 예제를 보고 VB소스를 > C# WinForm
m-hjsoft.tistory.com
자동 발송에 이어 내용수집
※ 본 게시물은 비상업적 목적의 기술 공유입니다.
오직 개인 학습과 테스트를 위한 코드입니다.
🛠️ 개발환경
- C# .NET WinForm (.NET Framework 4.7 이상)
- AutoHotkey.Interop (NuGet 패키지 설치 또는 직접 DLL 참조)
- Windows 10/11
- 카카오톡 PC 버전
자동 발송에 이어
① 대화방 찾기 → ② 대화방 띄우기 → ③ 대화 내용 추출
① 첫번째리스트 → ② 대화방 띄우기 → ③ 대화 내용 추출
private void button3_Click(object sender, EventArgs e)
{
string target = textBox1.Text;
if (string.IsNullOrWhiteSpace(target))
{
MessageBox.Show("대화방 이름을 입력하세요.");
return;
}
ActiveChat(target, 1000, true);
IntPtr hwndKakaoTalk = FindTopWindowByTitleContains(target);
if (hwndKakaoTalk == IntPtr.Zero)
{
MessageBox.Show("대화창을 찾을 수 없습니다.");
return;
}
string content = ReadChatContent(hwndKakaoTalk, 250);
if (string.IsNullOrWhiteSpace(content))
{
MessageBox.Show("대화 내용을 읽지 못했습니다.");
return;
}
textBox3.Text = content;
}
private void button4_Click(object sender, EventArgs e)
{
IntPtr hwndMain = FindHwndEVA();
if (hwndMain == IntPtr.Zero)
{
MessageBox.Show("카카오톡 메인창을 찾을 수 없습니다.");
return;
}
IntPtr roomList = FindRoomListWindow(hwndMain);
if (roomList == IntPtr.Zero)
{
MessageBox.Show("대화 리스트를 찾을 수 없습니다.");
return;
}
RECT rect;
if (!GetWindowRect(roomList, out rect))
{
MessageBox.Show("대화 리스트 위치를 읽지 못했습니다.");
return;
}
int width = rect.Right - rect.Left;
int clickX = rect.Left + Math.Min(width - 10, Math.Max(120, width / 4));
int clickY = rect.Top + 35;
SetForegroundWindow(hwndMain);
Thread.Sleep(120);
DoubleClickAt(clickX, clickY);
IntPtr chatWindow = FindRecentChatWindow();
if (chatWindow == IntPtr.Zero)
{
MessageBox.Show("대화창을 찾을 수 없습니다.");
return;
}
string content = ReadChatContent(chatWindow, 250);
if (string.IsNullOrWhiteSpace(content))
{
MessageBox.Show("대화 내용을 읽지 못했습니다.");
return;
}
textBox3.Text = content;
}
private string ReadChatContent(IntPtr hwndKakaoTalk, int delay)
{
IntPtr listHwnd = FindChatListWindow(hwndKakaoTalk);
if (listHwnd == IntPtr.Zero)
{
return null;
}
SetForegroundWindow(hwndKakaoTalk);
Thread.Sleep(delay);
FocusWindowByClick(listHwnd);
Thread.Sleep(delay);
string previousClipboard = null;
TryGetClipboardText(out previousClipboard);
string content = null;
for (int attempt = 0; attempt < 5; attempt++)
{
SetForegroundWindow(hwndKakaoTalk);
Thread.Sleep(delay);
SafeClipboardClear();
FocusWindowByClick(listHwnd);
Thread.Sleep(delay + (attempt * 30));
RECT rect;
if (GetWindowRect(listHwnd, out rect))
{
int width = rect.Right - rect.Left;
int height = rect.Bottom - rect.Top;
int clickX = rect.Left + Math.Min(width - 10, Math.Max(160, width / 3));
int clickY = rect.Top + Math.Min(height - 10, Math.Max(120, height / 3));
ClickAt(clickX, clickY);
Thread.Sleep(delay);
RightClickAt(clickX, clickY);
Thread.Sleep(delay + 150);
POINT p;
if (GetCursorPos(out p))
{
ClickContextMenuItem(p.X, p.Y, 10); // 전체 선택
}
else
{
SendKey(VK_A); // 전체 선택
}
Thread.Sleep(delay);
RightClickAt(clickX, clickY);
Thread.Sleep(delay);
if (GetCursorPos(out p))
{
ClickContextMenuItem(p.X, p.Y, 10); // 복사
}
else
{
SendKey(VK_C); // 복사
}
Thread.Sleep(delay + 250);
}
else
{
SendCtrlKey(VK_A);
Thread.Sleep(delay + (attempt * 20));
SendCtrlKey(VK_C);
Thread.Sleep(delay + 80);
}
TryGetClipboardText(out content);
if (!string.IsNullOrWhiteSpace(content))
{
break;
}
}
TrySetClipboardText(previousClipboard);
return content ?? string.Empty;
}
'HJSoft' 카테고리의 다른 글
| MAUI [다중 선택] 사진 업로드에서 iOS와 Android의 위치정보(EXIF) 차이 정리 (1) | 2026.02.04 |
|---|---|
| [앱스토어 등록 대장정]MAUI iOS 앱 아이콘 복구부터 WCF 로그인 성공까지 (0) | 2026.01.31 |
| “단순히 사진을 올리는 앱이 아닙니다.여러분의 증빙 데이터를 지켜주는 기술입니다.” (0) | 2026.01.12 |
| 안드로이드 사진 [다중선택] 위치정보(GPS 태그)는 왜 사라질까? 그리고 어떻게 보전했을까 (1) | 2026.01.08 |
| 우리가 몰랐던 ‘폐기물 처리 과정’, 실제로는 이렇게 됩니다 (0) | 2026.01.06 |