만드느라 힘들었네요 ㅎㅎ
Gui는 센스가 없어서 아직 못 꾸미고 천천히 만들려고 합니다.
구현 못한게 많은데..
loop문이 아닌 hook을 이용해서 카톡서브윈도우 깜박거릴때 인식되게하는거랑,
메시지보낼때 비활성에선 되는데 최소화에서 postmessage로 엔터 입력안되는부분..은 숙제입니다.
사용방법은 소통할 채팅방의 제목을 스크립트 전역변수 선언부분에 수동으로 입력해줍니다 관리할 갯수만큼.
카톡자동반응() 함수안에서 자동반응할 내용들을 입력하면 됩니다.
카톡메시지전송(), 카톡파일전송(), 카톡사진전송() 함수로 만드실 수 있습니다.
심심하지마시라고 스마트폰에서 원격으로 !음악켜 하면 컴퓨터 스피커로 음악 들을 수 있게 음악틀기()함수도 넣었으니 응용해보세요 ㅎ
모든카톡채팅은 채팅버퍼에 저장됬다가 1줄씩 뱉어냅니다.
그리고 약간의 도배방지 처리되있어서 한명이 연속으로 같은 문장 입력하면 읽씹합니다. ㅋ
부족하지만 소스 오픈합니다. 함수들 필요하신거 맘대로 가져가시고,
이 스크립트를 성능 개선하실 분은 더욱 유용한 프로그램 만드셨으면 좋겠습니다.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn ; Recommended for catching common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#WinActivateForce ; 오토핫키에 특정윈도우활성화권한을 줌
; 글로벌 변수 선언
채팅방수:=10 ; 생성할 총 채팅방수를 입력합니다.
자동반응속도:=500 ; 자동반응속도 밀리초단위입니다.
제외할이름=하이요,오핫초보 ; 응답하지 않을 닉네임들을 입력합니다. 본인이름 작성, 또는 상대방. 여러명 추가시 콤마로 구분합니다.
loop,% 채팅방수
소통할채팅방%a_index%:=""
소통할채팅방1=오토핫키 개발자 모임 ; 소통할카톡방 타이틀, 방갯수에 따라 넘버링
소통할채팅방2=오토핫키 개발자들의 모임
소통할채팅방3=정
loop,% 채팅방수
채팅버퍼%a_index%:="" ; 채팅버퍼, 카톡방수 만큼 자동 넘버링
return
/* 카톡자동응답에 매크로를 작성합니다.
*/
카톡자동응답(방이름,이름,시간,내용,메시지종류)
{
global 제외할이름
if ( 메시지종류="채팅" )
{
트레이출력(방이름,메시지종류,이름,시간,내용)
if 이름 contains %제외할이름%
return false
else if 내용 contains 안녕,ㅎㅇ,하이
카톡메시지전송(방이름,이름 "님 안녕하세요~")
else if 내용 contains 계신,계시
카톡메시지전송(방이름,이름 "님 필요하신거라도..? ㅎ")
else if 내용 contains hello,hi
카톡메시지전송(방이름,"hi " 이름 "~")
else if 내용 contains !실검
{
실검=네이버실시간검색순위
카톡메시지전송(방이름,실검)
}
else if 내용 contains !현재상황
카톡사진전송(방이름)
else if 내용 contains !사진파일
카톡파일전송(방이름,"test1")
else if 내용 contains !노래켜,!노래틀,!음악켜,!음악틀
노래틀기("on")
else if 내용 contains !노래꺼,!노래멈,!음악켜,!음악멈
노래틀기("off")
}
else if ( 메시지종류="시스템" )
{
if ( 내용 = "입장" )
카톡메시지전송(방이름,이름 "님 어서오세요(방긋)")
if ( 내용 = "퇴장" )
카톡메시지전송(방이름,이름 "님 안녕히가세요(눈물)")
}
return true
}
시작() ; 카톡방 여러개를 동시에 관리하려면 여기서 추가해줍니다. 채팅버퍼2, 소통할채팅방2.... 위에서 전역변수 설정 필요합니다.
{
global 채팅버퍼1, 소통할채팅방1,자동반응속도
반환된이름:="", 반환된시간:="", 반환된내용:="", 반환된메시지종류:=""
Clipboard:= ; 클립보드 내용을 지웁니다.
loop
{
loop,10
{
if not ( 소통할채팅방%a_Index%="" )
if 새로운카톡문자가져오기(채팅버퍼%a_index%,소통할채팅방%a_index%,반환된이름,반환된시간,반환된내용,반환된메시지종류)
카톡자동응답(소통할채팅방%a_index%,반환된이름,반환된시간,반환된내용,반환된메시지종류)
}
자동반응속도:= (자동반응속도<100) ? 100 : 자동반응속도 ; 자동반응속도 100이하는 100으로 자동조정 됩니다.
sleep,% 자동반응속도
}
return
}
카톡메시지전송(방이름,문장) ;카톡으로 메시지 보내기
{
IfWinExist, %방이름%
{
SendMessage, 0xC, 0, &문장, RichEdit20W1, %방이름% ; 문장을 콘트롤에 set 합니다.
sleep,1
PostMessage, 0x100, 0xd, 0x1c0001,RichEdit20W1, %방이름% ; Enter키를 입력합니다.
}
}
카톡사진전송(방이름) ; 클립보드에 있는 이미지를 보냅니다
{
send,{PrintScreen}
ControlSend,EVA_VH_ListControl_Dblclk1,{Ctrl down}v{Ctrl up},%방이름%
WinWait,ahk_class #32770,,1
WinGetClass,팝업확인,%방이름%
PostMessage, 0x100, 0xd, 0x1c0001, , ahk_class %팝업확인%
}
; 확장자명을 생략하면 PNG입니다. 복수개 파일보낼때는 가름자로 `n을 사용합니다. ex)카톡파일전송("test1.bmp`ntest2") -> test1.bmp와 test2.png를 동시에!
카톡파일전송(방이름,fname)
{
PostMessage, 0x233, HDrop(fname), 0,, % 방이름
WinWait,ahk_class EVA_Window_Dblclk,,1
PostMessage, 0x100, 0xd, 0x1c0001,, ahk_class EVA_Window_Dblclk
}
HDrop(fnames,x=0,y=0)
{
characterSize := A_IsUnicode ? 2 : 1
fns:=RegExReplace(fnames,"\n$")
fns:=RegExReplace(fns,"^\n")
/*
함수 첫번째 파라메터에 파일명 리스트를 라인피드로 구분해서 작성하면 여러 파일도 한번에 전달이 됩니다.
라인피드는 오토핫키에서 `n 입니다.
fnames=%A_ScriptDir%\Green.png`n%A_ScriptDir%\BALLOON2.png
이런식으로요
너무 길어질거 같으면 변수입력시에는 파일명만 입력하고
경로는 함수내에서 입력할 수 있도록 처리해주면 되죠
위 함수의 fns:=RegExReplace(fns,"^\n") 바로 아랫라인에 아래 코드를 삽입해 보세요
절대경로인 경우는 그대로 사용
상대경로인 경우는 스크립트 경로를 앞에 추가
확장자가 없으면 .png 추가 하는 스크립트입니다. by Hangoon 님
*/
Loop,Parse,fns,`n,`r
{
SplitPath, A_LoopField,OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive
tmp := (!OutDrive ? A_ScriptDir "\" : "" ) A_LoopField (!OutExtension ? ".png" : "")
fns := (A_Index=1) ? tmp : fns "`n" tmp
}
hDrop:=DllCall("GlobalAlloc","UInt",0x42,"UInt",20+(StrLen(fns)*characterSize)+characterSize*2)
p:=DllCall("GlobalLock","UInt",hDrop)
NumPut(20, p+0) ;offset
NumPut(x, p+4) ;pt.x
NumPut(y, p+8) ;pt.y
NumPut(0, p+12) ;fNC
NumPut(A_IsUnicode ? 1 : 0, p+16) ;fWide
p2:=p+20
Loop,Parse,fns,`n,`r
{
DllCall("RtlMoveMemory","UInt",p2,"Str",A_LoopField,"UInt",StrLen(A_LoopField)*characterSize)
p2+=StrLen(A_LoopField)*characterSize + characterSize
}
DllCall("GlobalUnlock","UInt",hDrop)
Return hDrop
}
트레이출력(방이름,메시지종류,이름,시간,내용)
{
TrayTip,%방이름%,% 메시지종류 ", " 이름 ", " 시간 ", " 내용
return
}
노래틀기(스위치)
{
if ( 스위치="on" )
{
Random, track, 1, 6
soundset,100
soundplay,%A_WorkingDir%\sound\bosstime%track%.wma
}
else if ( 스위치="off" )
SoundPlay, Nonexistent.avi
return
}
; 채팅버퍼에 새로운 채팅 기록, 없으면 채팅마지막줄 기록, 수정된 채팅버퍼값 유지를 위해 byref로 되돌립니다.
채팅버퍼에새로운문장기록(ByRef 채팅버퍼,방이름)
{
카톡채팅2클립보드(방이름) ; 카톡방의 채팅을 클립보드로 가져옵니다.
if not 채팅버퍼="" ; 도배에 대한 예외처리. 채팅버퍼에 내용이 있을때
{
도배채팅갯수:=0
while InStr(Clipboard,채팅버퍼,false,1,A_Index) ; 같은문장이 있으면 1이상의 포지션을 반환하는걸로 if문 판별
도배채팅갯수++
loop,% 도배채팅갯수-1 ; 도배된문장중 마지막 하나만 빼고 ""으로 다바꿉니다
StringReplace, Clipboard, Clipboard, %채팅버퍼%
}
if not Clipboard=""
채팅버퍼:= 채팅버퍼="" ? SubStr(Clipboard,InStr(Clipboard,"`n",false,0,2)+1) : SubStr(Clipboard,InStr(Clipboard,채팅버퍼))
/*
채팅버퍼가 빈값이면, 클립보드에서 `n문장을 뒤부터 찾아 두번째 `n의시작위치를 반환하고, 시작위치에+1을 더해 `n을제거한후 문장 끝까지를 다시 채팅버퍼에 기록합니다. 즉 마지막채팅기록이 들어가게됩니다.
채팅버퍼에 기존내용(마지막채팅기록)이 있으면, 클립보드에서 채팅버퍼의 문장을 찾아 시작위치를 반환하고, 시작위치 부터 끝까지를 다시 채팅버퍼에 기록합니다.
*/
Clipboard:= ; 클립보드 내용을 지웁니다.
return
}
카톡채팅2클립보드(방이름)
{
ControlSend,EVA_VH_ListControl_Dblclk1,{Ctrl down}a{Ctrl up},%방이름% ; 비활성 ctrl+a
sleep,1
ControlSend,EVA_VH_ListControl_Dblclk1,{Ctrl down}c{Ctrl up},%방이름% ; 비활성 ctrl+c
;PostMessage, 0x301,0,0,ahk_id 0x70872,%방이름% ; 비활성 ctrl+c
;PostMessage, 0x100,3,0,EVA_VH_ListControl_Dblclk1,%방이름% ; 비활성 ctrl+c
;ControlClick,EVA_VH_ListControl_Dblclk1,%방이름% ; 비활성 카톡방 에디트콘트롤 클릭, 선택된화면을 없에기 위함.
return
}
; 버퍼에서 1줄씩 로딩해서 세부내용을 함수밖으로 반환합니다.
새로운카톡문자가져오기(ByRef 채팅버퍼,방이름,ByRef 반환될이름,ByRef 반환될시간,ByRef 반환될내용,ByRef 반환될메시지종류)
{
채팅버퍼에새로운문장기록(채팅버퍼,방이름) ; 새로운 채팅이 있으면 버퍼에 추가합니다.
sPos:=InStr(채팅버퍼,"`n")+1 ; 채팅버퍼에서 두번째문장(새로운첫채팅) 시작위치, ""이거나 새로운문장이 있을 수 있습니다.
if not SubStr(채팅버퍼,sPos,1)="" ; 새로운 문장이 있으면
{
채팅버퍼:=SubStr(채팅버퍼,sPos) ; 채팅버퍼에서 최상위1줄을 제외(삭제)하고 다시 저장합니다.
if InStr(채팅버퍼,"[")=1 ; instr()함수는 변수 채팅버퍼%a_index%의 문자열에서 [ 문자의 위치값을 리턴합니다.
{
반환될메시지종류:="채팅"
StringGetPos,ep, 채팅버퍼,]
StringGetPos,ep2, 채팅버퍼,],L2
StringGetPos,ep3, 채팅버퍼,`r
StringMid,반환될이름, 채팅버퍼, 2, % ep-1
StringMid,반환될시간, 채팅버퍼, % ep+4, % ep2-ep-3
StringMid,반환될내용, 채팅버퍼, % ep2+3, % ep3-ep2-2
; [아무개] [오후 2:23] 사진 <--- 누군가 사진을 보냈을때 형식
}
else ; 카톡 시스템 메시지입니다.
{
반환될메시지종류:="시스템"
if Position:=InStr(채팅버퍼,"나갔습니다.")
{
반환될내용:="퇴장"
StringLeft, 반환될이름, 채팅버퍼, Position-1
}
else if Position:=InStr(채팅버퍼,"님이 들어왔습니다.")
{
반환된내용:="입장"
StringLeft, 반환될이름, 채팅버퍼, Position-1
}
}
return true ; 새로운문장이 있음을 반환합니다.
}
else
return false ; 새로운문장이 없음을 반환합니다.
}
F1::Pause
Insert::시작()
Delete::
GuiClose:
exitapp
그리고 이거 시작은 스크립트 구동하고 insert키 눌러야됩니다. 소통할 카톡창은 켜져있어야 작동합니다.