프날 오토핫키 강좌  v2

질문 및 답변


이곳에 글을 쓰면 개인정보 처리방침과 아래의 댓글 관리 정책에 동의하는 것으로 간주됩니다.

  • 실제 허용 여부를 막론하고 모든 게임에 관한 질문은 받지 않습니다.
  • 홈페이지 유지 보수 및 구조 변경으로 인해 작성한 모든 글이 삭제될 수 있습니다.
  • 이 곳에 쓰는 것은 불법적인 프로그램 개발 및 사용을 하지 않음에 동의하는 것입니다.
  • 프로그래밍과 관련이 없는 글은 삭제될 수 있습니다.
총 30건의 질문
(한글 포함됨)
sk0327
|
2023년 05월 24일
안녕하세요 강좌를 보고 오토핫키를 공부하고 있습니다. 원노트에서만 작동하도록 하고 싶은데 해당기능이 동작하질 않네요 전체프로그램에서만 실행이됩니다. 혹시 코드에 어떤 문제가 있느지 말씀해주시면감사하겠습니다. HotIfWinActive("ahk_exe ONENOTE.EXE") $Space:: { if (A_PriorHotKey == ThisHotkey and A_TimeSincePriorHotkey < 180) { Send("{BS}{Enter}") } else { Send("{Space}") } return } $F1::{ if (A_PriorHotKey == ThisHotkey and A_TimeSincePriorHotkey < 180) { Send("{Enter}") } else if (A_PriorHotKey == ThisHotkey and A_TimeSincePriorHotkey < 360) { Send("{BS}{BS}{BS}{BS}") } else { Send("{Space}{Space}{Space}{Space}") } return } HotIfWinActive 함수적은것은 신경쓰지 않으셔도 되는데 ifwinactive hot ifwinactive 둘다 작동하지않네요. 그리고 궁금한게 제가 지금 구현한 함수는 해당 시간안에 클릭을 2번하면 해당기능이 도출되도록하는건데 단축키를 2번 누르는 것이 아니라 일정시간 한번 누르고 있으면 첫번 째 동작을 생략하고 두번 째 동작만 실행되도록 할수 있을 까요? 예를들어 a를 1초간 누르고 있으면 대문자 A가 되도록하는것입니다. 또한 2초간 누르면 한글고전환하고 ㅁ이 되도록 하도록 하고싶은데 이경우에는 else if로 추가하면되는건가요??
프날 Pnal
|
2023년 05월 26일 | ✨
안녕하세요. 늦어서 죄송합니다. 개인적인 일이 있었어서요. 핫키 위에 조건은 #HotIf WinActive()처럼 해시 기호를 반드시 적어주셔야 하며 #HotIf와 조건 사이는 띄워서 적어주셔야 합니다. 키를 누르는 시간은 A_TimeSinceThisHotkey 내장 변수를 활용하면 쉽습니다.
공드리
|
2023년 05월 11일
안녕하세요 비전공자가 오토핫키 1을 배우고나서 업무에서 정말 유용하게 사용하고 있었는데 사내 브라우저가 엣지로 전부 바뀌는 바람에...못쓰게되어 2.0을 알아보다 강의를 우연히 접하고는 신세계를 만나게 되었습니다 새로운 세계를 열어주셔서 감사합니다. 제가 강의를 끝까지 보지 않고 질문부터 드리는것 같아 너무 기본적인 것 같긴 하지만 질문 남깁니다 ControlSend(Keys [, Control, WinTitle, WinText, ExcludeTitle, ExcludeText])로 엣지 브라우저의 창에 텍스트 입력을 하려 하는데 오토핫키1에서는 document.getElementByID()와 브라우저 상 개발자 도구를 통해 ID값을 알아내서 입력할 수가 있었는데 2.0에서도 똑같이 활용할 수 있는 함수(?)가 있을까요?
프날 Pnal
|
2023년 05월 26일 | ✨
안녕하세요. 늦어서 죄송합니다. 개인적인 일이 있었어서요. DOM 제어는 오토핫키 v2에서도 가능합니다. 다만 ControlSend로 쓸 순 없을 것입니다. 현대 인터넷 브라우저는 브라우저 안의 내용이 밖과 완전히 격리되어있습니다. (보안상/성능상의 이유). 그래서 그 안의 컨트롤에 접근할 수는 없습니다. 다만 브라우저를 띄우지 않고 IE COM 오브젝트를 이용하여 접근하는 것은 가능하나, 현재 띄워둔 엣지 브라우저에서 바로 그 내부의 컨트롤을 제어하는 것은 적어도 제가 아는 방법에선 어렵습니다.
공드리
|
2023년 05월 26일
친절한 답변 감사합니다
lightright
|
2023년 05월 10일
안녕하세요 프날님 오랜만에 인사드립니다. 예약카톡 발송 매크로를 제작하고 싶은데 카카오톡 API를 활용해서 엑셀로 저장된 환자의 이름과 예약내역을 다다르게 해서 발송하고 싶은데 카카오톡 API를 활용하는 방법에 대해서 강의를 해주실수 있는지 궁금합니다.
프날 Pnal
|
2023년 05월 26일 | ✨
안녕하세요. 늦어서 죄송합니다. 개인적인 일이 있었어서요. 카카오톡에서 제공하는 Rest API를 사용하면 됩니다. Rest API는 HTTP Request를 이용하기 때문에, 오토핫키에선 WinHTTP로 특정 주소로 어떠한 내용을 송수신하며 작동합니다. 따라서 오토핫키와 관련된 부분은 WinHTTP가 전부이고, 다른 사항은 타언어든 뭐든 동일하니 다른 언어를 기준(예: 파이썬)으로 한 카카오톡 API 강좌를 보시면서 HTTP Request 부분만 오토핫키에서 WinHTTP로 바꿔서 보시면 되겠습니다.
lightright
|
2023년 04월 28일
안녕하세요 프날님 editor 프로그램으로 SciTE4AutoHotkey 프로그램을 사용하시는데 혹시 VSC 는 사용 안하시나요??
프날 Pnal
|
2023년 04월 28일 | ✨
안녕하세요. 정확히는 VSCode가 아니라 VSCode에서 마이크로소프트 관련 Telemetry를 뺀 VSCodium라는 오픈 소스 에디터를 씁니다.(둘이 기능상으론 사실상 같습니다. de-microsoft된 VSCode라고 보시면 됩니다.) 그런데 오토핫키는 SciTE로만 작성하고요, C#은 VS, 나머지(자바, 파이썬, Rust, 웹코딩 등)에서 VSCodium를 씁니다.
lightright
|
2023년 05월 02일
오토핫키는 SciTE가 제일 좋아서 사용하시나요?? 가끔식 VSC로 코딩하는 유튜버라던지 강좌가 있어서요
프날 Pnal
|
2023년 05월 03일 | ✨
편하고 가벼워서 씁니다.
그냥걸었소
|
2023년 04월 27일
프날님 강좌 도움 많이 받았습니다. 개인시간 쪼개서 이렇게 도움 주니 고맙습니다. 다름 아니라 오토핫키 v1은 문법이 산만하다고 할까? 그래서 v2로 공부하는데 인터넷 예제 찾아보면 대부분 v1로 된 것 뿐이라 배우기 힘들었는데. 최근에 v1 소스를 v2로 변경해 주는 스크립트가 있어 혹시 필요한 분 있을까 해서 올립니다. 완벽하진 않습니다. 본인이 일부 손 봐야 하니 참고하세요. https://www.autohotkey.com/boards/viewtopic.php?t=25100 에서 'Lastest Download' 아래 줄 링크로 다운 받은 후에 압축 풀고 폴더 안에서 'v2converter' 스크립트 실행하면 됩니다.
프날 Pnal
|
2023년 04월 28일 | ✨
좋은 정보 감사합니다 ^^ v1 문법이 워낙 난잡해서, 가능하면 v2로 스스로 리팩토링 하는 것이 좋아보이긴 합니다만, 어떤 문법으로 바뀌는지 학습용으로도 좋아보이네요. 꽤 괜찮아보이는 프로젝트네요.
코난
|
2023년 04월 27일
함수에서 스크립트를 정지시키는 방법은 무엇인가요? 스크립트 입니다. -------------------------------- f1:: sendinput {q} sleep, 40 Mouseclick,left, 100, 200, 1, 0 sleep, 10 imagesearch,vx,vy, 500, 1000, 1100, 1500, 흰색.bmp if errorlevel = 0 { return } sendinput {q} sleep, 40 Mouseclick,left, 100, 300, 1, 0 sleep, 10 imagesearch,vx,vy, 500, 1000, 1100, 1500, 흰색.bmp if errorlevel = 0 { return } sendinput {q} sleep, 40 Mouseclick,left, 200, 200, 1, 0 sleep, 10 imagesearch,vx,vy, 500, 1000, 1100, 1500, 흰색.bmp if errorlevel = 0 { return } sendinput {q} sleep, 40 Mouseclick,left, 200, 300, 1, 0 sleep, 10 imagesearch,vx,vy, 500, 1000, 1100, 1500, 흰색.bmp if errorlevel = 0 { return } return -----------이해하기 쉽게 무슨 스크립트인지 말로 설명하겠습니다. --------- 스크립트 내용은 총 10개의 박스가 있는데, 박스를 하나씩 클릭 할때마다 흰색이 나오면 스크립트를 멈추는 스크립트 입니다. 위 내용은 글이 길어서 짤라서 올린 것입니다. 질문은 저렇게 스크립트가 길어서 분명히 짧게 줄이는 방법이 있을거같은데 모르겠습니다. 프날님 함수글 봐도 저런식으로 이미지서치하면 멈추게 하는방법을 모르겠습니다.
프날 Pnal
|
2023년 04월 28일 | ✨
안녕하세요. 이곳은 v2 강좌 질문란입니다 ^^ v1 강좌란에 질문 주시길 바랍니다. 그리고 주신 스크립트는 함수로 쉽게 묶을 수 있습니다. 변화하며 반복되는 부분을 하나의 함수로 묶는다고 생각해보세요. 그리고 이미지서치의 ErrorLevel을 함수의 반환값으로 해보시면 되겠습니다. v1은 이미지서치의 결과를 Errorlevel로 받으니까요.
디노
|
2023년 04월 21일
안녕하세요. V1 강좌로 많은 도움 받았습니다. 기존에 오토핫키 V1을 이용하여 업무에 잘 활용하고 있었는데, 새로 프로그램을 만드는 겸 V2를 배우는게 좋을까요? 기존 V1이 표현식 문자열 등이 혼재되어 있어 햇갈렸던 점도 있고, 작성해주신 V2강좌 내용을 쭉 훑어보니 좀 더 직관적이고 명료하게 바뀌었다는 생각이 듭니다. 그런데 gui쪽은 또 내용 변화가 많아서 다시 학습하기에 부담도 좀 되고, 아직 베타버전이라 얼마든지 변화가 있을 수도 있다는게 걸리네요. 아차피 class 개념은 좋은 코딩을 위해 배워놔야 할 것 같은데, 그렇다면 이참에 베타버전인걸 감안하더라도 V2를 배워둘만한 가치가 있을까요..? 아니면 넘어가더라도 베타 이후를 추천하실까요? 프날님 의견이 궁금합니다.
프날 Pnal
|
2023년 04월 21일 | ✨
안녕하세요. v2로 하시는게 어떠신지요. v2는 현재 베타버전이 아닙니다. 정식 버전이고요, v1이 Deprecated된 것입니다. 더이상 v2의 문법은 바뀌지 않습니다. 기능 추가는 있을 수 있지만요. 지금 만들어두시면 앞으로의 변화에 따라 동작하지 않는 등 걱정하실 필요는 없습니다. 적어도 되던게 안되도록 바뀌진 않습니다. v2는 작년 말부터 정식버전이니까요. 크게 어렵지 않으나 이거 쉬워요! 라고 어째 확신할 순 없네요. 배우는데 드는 노력은 기존의 숙련도와 타 프로그래밍 언어 경험에 따라 달라지기 때문입니다. 그래서 ‘조심스레’ v2로 새 프로그램을 제작하는걸 추천드립니다. v1으로 짜야하는 특별한 이유가 있지 않으면, 지금 v2를 배워서 넘어가셔도 좋습니다.
디노
|
2023년 04월 21일
감사합니다. 항상 도움 많이 받고 있습니다~!
야심찻지만
|
2023년 04월 19일
안녕하세요 프날님! 회사 전산을 컨트롤 하려고 야심차게 준비를 다하고 이제 시작! 했는데... 회사전산프로그램이 오토핫키로 컨트롤이 안되더라구요.. winmaxize, winminimize도 안먹히고 winmove도 안먹히더라구요... ControlSend도 안먹히고 심지어 send 로 tab보내는 것도 안되더라구요 근데 또 winactivate는 먹힙니다 대신 작업표시줄로 최소화를 한 상태에서 실행을 하면 말그대로 활성화만 되고 화면으로 띄우는게 안되더라구요.. 혹시 이런 방식의 프로그램들을 움직이게 하는 방법이 없을까요? 안되면 딱 그냥 winactivate로 창을 맨 앞으로 띄우는 것밖에 할 수 없을 것 같아요..ㅜㅜ 후.. 전에 1편 본게 있어서 할만 하겠다 했는데 ㄱ프로그램 자체가 컨트롤이 안될 줄이야..너무 슬프네요ㅜㅜ
프날 Pnal
|
2023년 04월 19일 | ✨
안녕하세요. 회사 프로그램의 경우 간혹 보안을 위해 소프트웨어 입력을 막는 경우가 있을 수 있습니다. 물론, 의도치 않게 그런식으로 구현되었을수도 있고요. 그러한 프로그램에서 소프트웨어 명령을 입력하는 방법에 대해서는 말씀드릴 수 없는 점 이해 부탁드립니다. 애초에 프로그램마다 다를텐데 딱 떨어지는 방법이 있지도 않을 것입니다. 다만, 회사 차원의 보안이 아니라 윈도우에서의 호환성 문제에 관해서 한가지 말씀드리면, 입력이 들어가는 프로그램의 권한이 입력을 시키는 프로그램보다 높으면 안될 것입니다. 그래서, 오토핫키 프로그램를 관리자 권한으로 실행시키는 것이 유일하게 말씀드릴 수 있는 건전하고 일반적인 해결책입니다. 이로써 해결되지 않으면 회사 프로그램에서 입력을 막았을 가능성이 있으니, 더이상 말씀 드릴 수 있는 부분이 없습니다.
킴갱
|
2023년 04월 17일
현재 일자로 부터 (년,월) 미래, 과거 계산 하는법을 모르겠습니다. 예1) 현재로 부터 2달 뒤 예2) 현재로 부터 2년 전 future:= DateAdd(a_now,+60,"days") future:= formattime(future,"yyyy-MM-dd") SendText(future) 일자(day)는 위와 같이 계산하였습니다. 도와주세요 ㅠㅠ
프날 Pnal
|
2023년 04월 17일 | ✨
당연히 DateAdd(A_now, 3, "Years")로 될 줄 알았는데 문서를 보니까 TimeUnits에는 Days까지만 가능하고 Year, Month는 들어갈 수 앖네요. 관련 PR이 있지만 작년에 요청이 있음에도 아직 병합되진 않았습니다. (다만, Close되지 않았으므로 언젠가 v2에 해당 기능이 추가될 수 있다고 기대해봅니다.) 결국 직접 함수를 만들어 쓰시는게 제일 나아보입니다. StrSplit 혹은 SubStr를 사용해서 만들어보세요. 연도 더하기/빼기는 2월 29일만 고려해서 만드시면 되고, 달 더하기/빼기는 각 달의 일 수를 고려해야하는데, 실무적으로 이럴 경우 어느 달을 기준으로 삼느냐에 따라 일수가 달라지는 문제도 있긴 합니다. 어느 달에서 3개월은 92일 일수도 있고, 어느 달에선 90일 일수도 있으니까요. 그런 경우를 자신이 만드려는 서비스에 맞게 구현해보시길 바랍니다. 관습적으로 실제 서비스에선 3달 = 90일로 계산해서 적용하는 경우가 왕왕 있으니, 정확히 달을 계산하는게 중요하지 않으면 (n * 30)일로 적용하는 것도 생각해 보세요. 이 경우 고객에게는 “3달”이 아니라 “90일”로 명확히 안내되아야 할 것입니다. 저도 이거 관련해선 깊게 생각해본 적이 없는데, 민법에 법적인 계산법이 있긴하네요.제160조(역에 의한 계산)
①기간을 주, 월 또는 연으로 정한 때에는 역에 의하여 계산한다.
②주, 월 또는 연의 처음으로부터 기간을 기산하지 아니하는 때에는 최후의 주, 월 또는 연에서 그 기산일에 해당한 날의 전일로 기간이 만료한다.
③월 또는 연으로 정한 경우에 최종의 월에 해당일이 없는 때에는 그 월의 말일로 기간이 만료한다.
즉, 각 달의 일과 상관 없이 달을 정수로 더하고(예를 들어서, 3월 20일의 3달 뒤는 6월 20일), 기산일의 전일(6월 19일)이 만료일이 되며, 만약 해당하는 날이 없는 경우 그 달의 말일(만료일이 2월 30일이 되어버렸다면 2월 28일(윤년의 경우 29일)로 만료됨)으로 한다고 정해져 있어 보입니다. 물론 이게 모든 경우에 쓰이는 보편적 계산법인지, 어떤 경우에 민법을 따르지 않는 예외가 있는지는 저는 법률 전문가가 아니니까 따로 알아보셔야 합니다. 다만 이런 복잡함을 피하기 어려우시면 (가능한 경우!) 그냥 서비스에서 기간을 주, 월, 연으로 하지 말고 일로 약정하는것이 좋아보입니다. (예: 사용자님의 백업 데이터는 7일간 보관됩니다, 사용자님의 로그 데이터는 90일간 보관됩니다. 등)
수뼈
|
2023년 04월 17일
혹시 Part 3 강의를 조금씩 푸실 생각은 없으신가요?
프날 Pnal
|
2023년 04월 17일 | ✨
다 작성하면 한번에 올릴 생각입니다 ^^; 검수도 해야하고, 예제 파일도 한번에 만들고 그러고 있어서요. 중간중간마다 검수/예제 작성 등을 하면 효율이 넘 떨어지네요 ㅠㅠ
안녕하세요
|
2023년 04월 14일
안녕하세요 v2가 시작된걸보고 부리나케 달려왔습니다 오토핫키 질문은 아니지만.. 그 편집할때 쓰는 SCITE? 이 프로그램이 원래는 예를 들어 WINACTIVE를 적고 쉼표, 를 누르면 아래쪽에 그 다음 어떤 구성으로 작성하는지 알려주는 팁? 같은게 나왔었는데 이번 업데이트 이후 그게 사라졌더라구요.. 혹시 이게 설정에서 어떤건지 알 수 있을까요? 아예 사라져버린건지.. 아무리봐도 보이질 않아서 막막하네요 ㅜㅜ
프날 Pnal
|
2023년 04월 14일 | ✨
안녕하세요. 아쉽게도, 최신 바전의 SciTE는 해당 기능을 지원하지 않습니다 ㅠㅠ 저도 그래서 옆에 문서를 띄워두고 코딩하곤 했습니다. SciTE에서 F1키를 누르면 나오는 도움말 프로그램을 참고하고 있습니다. 생각보단 없이 살만합니다.
lightright
|
2023년 04월 06일
mainGui := Gui(,"HELP") tabname := ["진료","수납","외래진료실","입원실"] tab := mainGui.Add("Tab3","x10 y10 w622 h331",tabname) loop(tabname.Length){ tab.usetab(tabname[A_Index]) check1 := mainGui.Add("checkBox", "x55 y70 h20", "체크") check2 := mainGui.Add("checkBox", "x165 y70 h20", "체크") check3 := mainGui.Add("checkBox", "x275 y70 h20", "체크") check4 := mainGui.Add("checkBox", "x385 y70 h20", "체크") check5 := mainGui.Add("checkBox", "x495 y70 h20", "체크") } 프날님 이런식으로 탭마다 체크버튼을 만들고 같이 사용하고 싶은데 이렇게 코드를 짜면 마지막 탭에 체크유무만 판단할수 있고 앞에 있는 탭에서는 체크유무를 알수없는데 탭마다 체크박스가 공유되게 사용하려면 loop문으로 체크박스 생성하는걸로는 방법이 없을까요?
프날 Pnal
|
2023년 04월 07일 | ✨
공통적으로 사용하는 체크박스는 Tab에서 빼서 놓으면 안되나요? 앞에 있던 탭에서 체크 유무를 알 수 없다는 말은 무슨 뜻인가요? 별도의 컨트롤 객체를 쓰는데 왜 값을 가져올 수 없는지... 구체적으로 들어야 알 것 같습니다.
lightright
|
2023년 04월 07일
loop 문으로 체크박스를 생성해서 그런지 첫번째 탭인 진료탭에서 체크박스에 체크를 한후 메세지박스로 값을 보면 항상 0으로 되어있고 마지막 탭인 입원실 탭에서 체크를 한후 메세지박스로 값을 보면 체크 유무에 따라 0과 1로 나타납니다~! 공통적으로 쓰는 버튼이나 체크박스를 탭에서 빼도 되나 디자인이 별로가되서 문의 드렸었습니다
오방
|
2023년 04월 01일
카페24에서 제공하는 mysqlDB를 사용하는데요 DB에서 데이터를 불러오려고 하면 어떻게 해야하나요? 예전에는 "ADO"(ActiveX Data Objects)라는 내장 라이브러리를 사용하였던거 같은데 V2에서는 어떻게 사용해야하는지 알려주실 수 있을까요?
프날 Pnal
|
2023년 04월 02일 | ✨
안녕하세요. SQL 접속을 위한 몇몇 라이브러리가 있긴 할텐데, 저도 DB 접속은 Python이나 PHP에서만 해봐서 오토핫키에선 한번 테스트해보고 말씀드릴 수밖에 없습니다. ㅠㅠ ADO는 사용하지 않아봐서 모르겠습니다. 문제는 MySQL이 오토핫키를 위한 커넥터를 (당연히) 지원하지 않는다는 것이겠죠. 다만 LoadLibrary로 FFI가 가능하니까, 외부 동적 라이브러리를 불러올 순 있을 것입니다. libmysql.dll을 이용하여 오토핫키에서 SQL에 쿼리를 하려는 시도는 v1때부터 많이 있었던 모양입니다. v1에서 됐다면 v2에서 안될리가 없죠. 게다가 dllcall로 불러오는건 v1이나 v2나 거기서 거기니까요. 공식 포럼이나 검색창에 AutoHotkey v2 MySQL lib 식으로 검색을 하거나, 혹은 직접 v1 버전의 라이브러리를 단순히 v2 문법으로 교체하기만 해도 동작은 할 것입니다. 저도 해봐야겠네요. 큰 도움은 못 드릴 것 같고, 해보고 되면 말씀 드리겠습니다... 빨리 테스트는 못하고요 ㅠㅠ 시간 나고 여유있을때 해보겠습니다. 혹여 성공하시면 말씀해주세요.
호놀롤루
|
2023년 03월 28일
run 명령어 공부중인데용 오페라 브라우저에서 네이버를 최대 크기 창으로 열려고 아래와 같이 코딩했는데요 Run("https://www.naver.com/",,'max') 코드는 실행 되지만 최대 크기 모드가 되지 않습니다. min 이나 hide도 똑같이 option 반응이 없네용. 브라우저 문제인가요?
프날 Pnal
|
2023년 03월 28일 | ✨
안녕하세요. 공식 도움말에선 몇몇 프로그램은 해장 옵션이 작동하지 않을 수 있다고 하는데, 오페라 브라우저가 그 “몇몇”에 포함되나봅니다. ^^; 코드 상 문제는 없어보입니다. 메모장을 실행시킬 때 max, min 옵션을 주어서 코드의 문제인지 확인해볼 수 있습니다. 잘못된 코드라면 메모장을 열 때도 해당 코드가 작동하지 않을 것입니다.Some applications (e.g. Calc.exe) do not obey the requested startup state and thus Max/Min/Hide will have no effect.
에스키
|
2023년 03월 26일
안녕하세요 혹시 v1 GUI와 v2 GUI도 다를까요? v2는 GUI 강좌를 할지 말지 고려하고 계시다고 하여 다르지 않다면 v1 GUI 강의로 공부하려고 합니다.
lightright
|
2023년 03월 27일
제 경험으로는 완전 달랐습니다. 지금도 헷갈릴만큼 완전 다르다고 할수있습니다. v2로 공부시작하시는게 더 나으실꺼에요
프날 Pnal
|
2023년 03월 27일 | ✨
많이 다릅니다. v1 강좌를 보는 것이 아닌, 공식 래퍼런스를 참고하시는 것이 좋을 것입니다.
lightright
|
2023년 03월 26일
안녕하세요 프날님! 혹시 class 에 대해서 강좌해주실 생각 있으신가요~?
프날 Pnal
|
2023년 03월 27일 | ✨
아무래도 v2에서 GUI쪽은 객체와 관련된 이해가 필요하다보니 당연히 클래스도 언젠간 강좌해야할 것입니다. 아마 GUI 강좌와 세트로 올라가지 않을까 싶고요... 다만 시기상(?) 언제가 될지는 장담하지 못합니다. 사실 v2의 GUI 부분과 뒷부분을 책으로 내려고 했습니다. 그런데 안그래도 사용률이 저조한 오토핫키인데 책으로 내는 것이 과연 오토핫키가 한국에서 많이 쓰이는 것에 도움을 줄 수 있는가에 대한 의문이 들어서, 일단 잠정적으로 안하기로 했습니다. 대신 홈페이지(이곳)에 Part.3 강좌를 추가하는 식으로 생각하고 있고요... 문제는 강좌 쓰는게 꽤 시간이 드는 일입니다. 지금 보시는 60강 분량의 이 곳 강좌도 여름에 시작해서 겨울에 끝낸 강좌입니다. (얼마 안걸리는 사이트 구축 시간을 포함한 기간이고, 하루에 서너시간씩 열심히 적은 기간은 한두달 남짓이긴 합니다.) 그래서 v2 강좌의 뒷부분 - 객체와 관련된 개념(클래스를 포함), GUI, 문자열 처리, 파일 입출력, 기타 등등 부분 - 은 일단 시간이 꽤 걸릴 것으로 생각됩니다. 하루에 조금씩이라도 쓰면 몇달 걸립니다. 매일 쓸 순 없으니 최소 반년을 생각하고 있습니다. 처음 홈페이지를 만들때 개떡같이 만들어놓아서 강좌 글 쓸때도 HTML을 직접 입력해서 작성해야 하는 식이라 모바일에서 작업이 불가능함은 물론, 단순히 에디터에 글쓰던 것보다 시간이 두 배로 드네요. ㅠㅠ 진작 좀 잘 만들 걸 그랬습니다. 제가 이 홈페이지를 Flask로 만들었는데, Flask가 처음이었어서 대충 만들었다보니... 기존 글이 있어서 뜯어 고치기도 그렇고 좀 그런 상황이네요. 뭐 어쩔 수 있겠습니까. 기존 강좌 글 쓰던대로 HTML로 글 써야죠... 요약드리면, 언젠간 쓰겠지만 좀 걸릴 듯 합니다. 제 생각엔 질문자님이 스스로 래퍼런스를 보시고 공부하시는 것이 훨씬 빠를 것입니다. 그리고 당초 말씀하셨던 홈페이지 수정 이제야 했습니다 ㅠㅠ. 글 쓰는 란의 세로 길이를 늘리고, 드래그로 길이를 조절할 수 있게 했습니다. 오래 기다리시게 해서 죄송합니다. 댓글도 링크는 자동으로 링크화 되어서 걸리게, 그리고 코드 조각을 잘 보이게 입력할 수 있게 해야하는데, 이건 제가 시간이 나면 하겠습니다. 일단 질문 전해지는덴 문제 없으니까요.
lightright
|
2023년 03월 28일
와 엄청 좋아졌습니다!! 의견 반영해 주셔서 감사합니다!
에스키
|
2023년 03월 25일
안녕하세요 강좌 7. 문자를 출력하는 MsgBox (하) 에서 '알림 상자의 아이콘' -> '금지(✕)'의 수가 16인데 12로 오기재 되어있습니다.
프날 Pnal
|
2023년 03월 26일 | ✨
헉.... 수정하겠습니다. 최근 바빠서 수정이 좀 늦을 수 있어서 양해 부탁드립니다.
lightright
|
2023년 03월 25일
안녕하세요 프날님 혹시 v2버전의 비활성이미지서치는 아직 안나온건가요?? 아님 할수있는 방법을 아시면 힌트주시면 공부해보겠습니다
프날 Pnal
|
2023년 03월 26일 | ✨
안녕하세요. Gdip이 v2 버전이 없나요? 안찾아봐서 모르겠습니다. 있으면 그걸 쓰면 되겠습니다. 표현식 부분의 문법은 v1과 같으니까요.
lightright
|
2023년 03월 26일
찾아봤는데 comma 에러라든지 이상한 에러가 계속 나서 사용을 못하고 있어서요 알겠습니다!
1523210ㅁ
|
2023년 03월 23일
안녕하세요! gdip가 되지않아 포럼에서 찾다보니 imageput라는 라이브러리를 찾게되었습니다.. 하지만 이것도 작동을하지못하네요 ㅠㅠ https://www.autohotkey.com/boards/viewtopic.php?t=76633 <여기에서 다운받았습니다. 제가 작성한 스크립트는 #Include imageput.ahk ; Create a base64 string. pic := ImagePutBuffer(0) ; Screen capture pic.show() ; or ImageShow(pic) ; Show image if xy := pic.ImageSearch("image.png") ; Search image MouseMove xy[1], xy[2] ; Move cursor 입니다! 오류는 Error: Parameter list too small. Specifically: -8 ---- C:\Users\shin\Desktop\오토핫키\imageput.ahk 2671: DllCall("gdiplus\GdipSetInterpolationMode", "ptr", pGraphics, "int", 7) 2674: DllCall("gdiplus\GdipCreateImageAttributes", "ptr*", &ImageAttr:=0) ▶ 2675: DllCall("gdiplus\GdipSetImageAttributesWrapMode", "ptr", ImageAttr, "int", 3) 2676: DllCall("gdiplus\GdipDrawImageRectRectI" , "ptr", pGraphics , "ptr", pBitmap , "int", 0, "int", 0, "int", w, "int", h , "int", 0, "int", 0, "int", width, "int", height , "int", 2 , "ptr", ImageAttr , "ptr", 0 , "ptr", 0) 2685: DllCall("gdiplus\GdipDisposeImageAttributes", "ptr", ImageAttr) The current thread will exit. 입니다 .. 무엇이 문제일까요?
프날 Pnal
|
2023년 03월 23일 | ✨
안녕하세요. 해당 라이브러리의 도움말 파일에 있는 예제를 그대로 쓴 것 같습니다. image.png의 경로가 정확하고 그 코드만 썼는데 안된다면 라이브러리 자체의 오류일 가능성이 있습니다. (라이브러리 제작자가 잘못된 예제를 올려놓지 않는 이상 말입니다.) 사용엔 문제가 없는 것 같은데, 해당 프로젝트에 issue 등록해보셔도 됩니다.
lightright
|
2023년 03월 24일
비활성창 이미지서치를 하려고하시는건가요?? 비활성이미지서치 하시는거면 공유좀 부탁드려도 될까요 ------------------------------- 저도 imagePut 라이브러리를 사용해봤는데요 문제없이 잘되네요
1523210a
|
2023년 03월 23일
안녕하세요 프날님 v2로 입문한 뉴비입니다, 비전공자도 이해하기 쉽게 강좌 만들어주셔서 정말 감사합니다 v1의 심화강좌중 gdip ImageSearch 으로 v2에서도 동일하게 비활성 이미지 서치를 하고 싶은데 검색해보아도 답을 모르겠어서 질문남겨요! 검색으로 v2버전 gdip를 찾았습니다! 찾았는데 Missing comma오류가 계속 나오네요 제가 버전을 잘못찾은걸까요?
프날 Pnal
|
2023년 03월 23일 | ✨
안녕하세요. 라이브러리를 어떤 걸 쓰셨는지, 전체 오류메시지는 어떤지, 함수는 어떻게 사용했는지 알아야합니다.
lightright
|
2023년 03월 22일
안녕하세요 프날님! 토글을 이용하여 While 문을 멈췄다 실행했다 하고 싶습니다. mainGui := Gui(,"HELP") mainGui.Add("Button", "x550 y300", "테스트").Onevent("click", test) mainGui.Add("Button", "x550 y330", "테스트2").Onevent("click", test2) num := mainGui.Add("Text", "x550 y280 w30", "1") mainGui.Opt("+AlwaysOnTop +ToolWindow") mainGui.Show("x0 y510 w640 h350") Stop := true test(_obj, * ) { while(Stop) { num.value++ Sleep(100) } } test2(_obj, * ) { global Stop := !Stop } 이런식으로 코드를 짰는데 test2버튼을 두번눌러야 다시 test1을 눌렀을때 이어서 실행이 됩니다 test1(_obj , * ) { static toggle := 0 toggle := !toggle while(toggle) { num.value++ Sleep(100) } } 도 해봤는데 에러만 날뿐입니다. 혹시 프날님이시라면 어떻게 하실지 여쭤봐도 될런지요 ㅠ
프날 Pnal
|
2023년 03월 23일 | ✨
안녕하세요. 제가 어제 바쁘고 오늘 겨우 정신을 차려서 ㅠㅠ 밤 늦게 해보고 답 달아드리겠습니다.
lightright
|
2023년 03월 24일
아닙니다 프날님! 천천히 답변주셔도 됩니다! 바쁘신데 죄송하고 항상 감사합니다!
프날 Pnal
|
2023년 03월 24일 | ✨
안녕하세요. 주신 예제를 수정해서 시작 버튼을 누르면 시작되고, 정지 버튼을 누르면 정지되도록 구현해보았습니다. 정지 버튼은 토글 식이 아니라 무조건 정지이므로 stop != stop 형식이 아닌 그냥 true만 전달해주었고, 주신 소스랑 구조상 다른 부분은 while문 전에 isStop값을 false로 설정해주었다는 점이 핵심입니다. 나머지 부분은 지엽적인 부분입니다. (예를 들어서, 의미상 더욱 전달되게 쉽게 변수명을 수정했습니다. Gui Close이벤트는 while문 동작 중에 GUI를 닫으면 프로그램이 종료되지 않기에 추가해주었습니다.)mainGui := Gui(,"HELP") mainGui.OnEvent("close", onGuiClose) mainGui.Add("Button", "w100", "시작").Onevent("click", start) mainGui.Add("Button", "w100", "정지").Onevent("click", stop) num := mainGui.Add("Text", "x120 y20 w30", "1") mainGui.Show("x0 y510 w640 h350") isStop := true return start(_obj, _info) { global isStop isStop := false while(!isStop) { num.value++ Sleep(100) } } stop(_obj, _info) { global isStop isStop := true } onGuiClose(_obj) { ExitApp }
프날 Pnal
|
2023년 03월 24일 | ✨
만약 두번째 주신 예제처럼 한 버튼으로 시작과 정지를 하려면 복잡해집니다. 핫키를 사용하면 #MaxThreadPerHotkey 처리를 지원하나, Gui 버튼은 또 안된단 말이죠. While문이 도는 동안 핫키는 새로 실행될 수 없습니다. Timer는 (실제가 그렇지 않더라도) 스레드를 분리해주는 효과가 있습니다. 그리고 SetTimer 함수의 주기가 음수이면 타이머를 단 한 번만 실행합니다. 따라서 타이머 함수 안에 while문을 넣고, 한 번만 타이머를 실행시키면(주기 실행이 아님에 유의) 오토핫키는 isStop값을 이전 타이머의 while값에서 다시 평가할 수 있습니다. 그래서, 아래와 같이 짜시면 버튼 하나로 처리가 가능합니다. 구문이 예쁘다고 할 순 없지만 꼭 부적절해보이진 않으니 사용하셔도 무방할 것 같습니다. mainGui := Gui(,"HELP") mainGui.OnEvent("close", onGuiClose) mainGui.Add("Button", "w100", "시작/정지").Onevent("click", toggleWhile) num := mainGui.Add("Text", "x120 y20 w30", "1") mainGui.Show("x0 y510 w640 h350") isStop := true return toggleWhile(_obj, _info) { global isStop isStop := !isStop SetTimer(loopSomething, -1) } loopSomething() { global isStop while(!isStop) { num.value++ Sleep(100) } } onGuiClose(_obj) { ExitApp }
lightright
|
2023년 03월 24일
대박입니다!! 손이 닿지 않는 간지러운 부분을 긁어주신 느낌입니다!! 답변 감사합니다 프날님!
lightright
|
2023년 03월 21일
안녕하세요 프날님! Edit에서 작성한 문장을 Enter키를 누르면 프로그램으로 전송하게 만드는걸 제작중에 있습니다. 그런데 Edit에서 작성하고 보내기를 누르면(또한 엔터키를 누르면) 전송을 하고 기존에 썻던 문장을 삭제해서 초기화 시키고 싶은데 도무지 방법이 생각이 안납니다. Edit을 변수에 넣고 _obj.value := "" 이런식으로 해봤으나 에러메세지가 뜨고 되질 않더라구요 Edit에 담겨있는 내용을 초기화 하려면 방법이 뭐가 있을까요?
프날 Pnal
|
2023년 03월 21일 | ✨
안녕하세요. TestEdit.value := "바꿀 값"이 맞습니다. 당연히 바꿀 값이 빈 값("") 이면 Edit의 내용이 지워집니다. 제가 테스트해보니 잘 됩니다. 오류 내용이 무엇인가요? _obj가 Edit 변수가 맞나요? _obj의 사용 범위가 유효한가요?(접근할 수 없는 변수 아닌가요?) 혹 다른 부분에서 오류가 나는 것은 아닌가요? v2에서 발전된 최강의 장점 중 하나는 오류가 명확하다는 것입니다. 이제 논리적으로 모순인 코드가 있으면 어정쩡 넘어가지 않고, 정확한 잘못을 오류로 알려줍니다. 코드상 문제는 없으니, 다시한번 코드를 확인해보세요. _obj 변수가 올바르지 않을 가능성이 큽니다.
lightright
|
2023년 03월 21일
mainGui.Add("Edit", "x70 y65 h20 w480 vSendvar") mainGui.Add("Button", "x560 y63 h24 Default", "보내기").OnEvent("Click", msggo) msggo(_obj, *) { output := _obj.gui.submit(0) ControlSend(output.Sendvar, , "ahk_exe notepad.exe") ControlSetText("","edit1","ahk_class AutoHotkeyGUI") } 이렇게 구현하기는 했습니다. 저기에서 ControlSetText("","edit1","ahk_class AutoHotkeyGUI") 대신에 sendvar.value := ""를 넣게 되면 This variable appears to never be assigned a value. 에러가 납니다 ㅠㅠ
프날 Pnal
|
2023년 03월 22일 | ✨
안녕하세요. 전역변수를 수정하려면 global 표지를 해주어야한다는 점을 본강좌에서 언급 드렸습니다. 함수 안에서 SendVar를 global로 사용하세요. 그리고 v변수로 표시하지 말고 컨트롤 인스턴스를 이용하시길 바랍니다.sendvar := Gui.Add()
lightright
|
2023년 03월 22일
v변수는 추천하지 않으시나요~?
프날 Pnal
|
2023년 03월 22일 | ✨
추천의 문제가 아니라, v 변수는 엄밀히 말해서 컨트롤의 “이름”입니다. 즉, Control.Name에 해당될 수 있습니다. 지금 필요한 것은 Control.Name.Value가 아니라 Control.Value입니다. 오토핫키에서 v 변수로 그 값을 바꿀 수 있게 했는진 몰라도, 일반적인 프로그래밍을 기준으로 봤을 땐 잘못된 필드 접근에 해당됩니다. Control.Name은 String이지, Object가 아니니까요. ^^
lightright
|
2023년 03월 22일
그렇군요!! 우문현답 감사합니다!
48000
|
2023년 03월 21일
프날님! 강좌 감사히봤습니다 감사합니다 혹시 opencv를 사용하여 이미지서치를 하려하는데 v2버전으로 입문했습니다. 혹시 opencv를 사용하려면 어떻게 해야할까요..? v1,v2버전중 입문하는 버전은 어느버전이건 상관이 없을까요??
프날 Pnal
|
2023년 03월 21일 | ✨
안녕하세요. opencv와 같은 라이브러리는 dll로 제공되기 때문에, dllcall() 함수를 통해 사용하시면 됩니다. 입문 버전은 상관 없고 저는 v2로 입문을 부탁드리고 싶으나, 현실적인 이유(인터넷에 v1 자료가 훨씬 많음) 때문에 v1으로 입문하셔도 괜찮을 것 같습니다. 특히나 opencv처럼 외부 라이브러리 사용에 관한 정보는 v1 버전으로 설명되어 있을 것입니다. 만약 타언어 프로그래밍 경험이 있으시면 v2로 시작하셔도 문제 없습니다.
lightright
|
2023년 03월 15일
안녕하세요 프날님 궁금한게 있습니다! ids := WinGetList("ahk_exe notepad.exe") for i in ids { global id%a_index% := IniRead("id.ini","ID",A_Index) MsgBox(id%A_Index%) } 예시는 노트패드로하였습니다. 노트패트의 id를 ini에 저장하고 불러오도록 하는 코드인데 함수안에서 global 을 선언해도 Invalid variable declaration. 이라면서 오류가 뜹니다. 제가 잘못이해를 한건지요
프날 Pnal
|
2023년 03월 15일 | ✨
안녕하세요. 에러 메시지의 뜻은 아실 것입니다. "잘못된 변수 선언" 정도의 뜻인데요, 원래 전역 변수 또한 선언과 동시에 할당을 할 수 있습니다. 그래서 global var := 1 와 같은 꼴로 쓸 수 있습니다. 그러나 가짜 배열은 동적으로 만들 수 없습니다. 공식 문서에서는 아래와 같이 설명합니다.Current versions of the language do not permit creating new variables dynamically. This is partly to encourage best practices, and partly to avoid inconsistency between dynamic and non-dynamic variable references in functions.현재 버전의 언어에서는 새 변수를 동적으로 생성할 수 없습니다. 이는 부분적으로는 모범 사례를 장려하고, 부분적으로는 함수에서 동적 및 비동적 변수 참조 간의 불일치를 피하기 위한 것입니다.배열 하나를 이용해서 그 배열에 담으면 될것을, 굳이 가짜 배열 형태로 담을 필요는 없을 것 같습니다. 권장되는 형태로 사용해주세요. (예를 들어서, id[] 배열을 이용할 수 있을 것입니다.)
lightright
|
2023년 03월 17일
아 v1에서도 가짜배열에 대해서 여쭤봤던적이 있었는데 무슨말인지 알것같습니다! 가짜 배열보다는 리스트로 사용하자! 명심하겠습니다!
lightright
|
2023년 03월 14일
v1에서 v2으로 바꾸면서 정말 궁금한게 많습니다. 프날님 다름이 아니라 v1에서 Gui에 있는 변수를 가져올려면 Gui, Submit, Nohide 를 써주고 변수를 쓰면 함수안에서도 사용이 가능했는데 v2는 또 복잡하게 바뀐거 같습니다.. mainGui := Gui(,"HELP") mainGui.Add("checkBox", "x55 y40 w100 h20 vcheck1", "check") 이라는 체크박스가 있고 msg() { if(check1) { ;체크가되어있으면 실행될 명령어 } } 를 만들고 싶은데 도무지 방법이 생각이 나질 않습니다 프날님
프날 Pnal
|
2023년 03월 14일 | ✨
안녕하세요. 복잡할 것 없습니다. GuiCtrl.Value로 가져오면 됩니다. 예를 들어서 체크박스 컨트롤을 isPass라는 변수에 담았다면, isPass.Value에는 1 아니면 0이 들어있습니다. 체크박스 컨트롤은 전역적으로 생성하셨을테니 Submit 없이 값을 가져올 수 있습니다. (그렇지 않디면 함수에 매개변수로 주거나, global을 이용하여 전역변수에 담아주세요.)
lightright
|
2023년 03월 14일
정말 스튜핏 했군요... ㅋㅋㅋ.. 죄송합니다
lightright
|
2023년 03월 14일
안녕하세요 프날님 v1 코드를 v2로 옮기는 작업을 하고 있습니다. v1과 v2 둘다 설치를 하고 에디터에서 v1으로 코드를 할껀지 v2로 코드를 할껀지만 선택하면 문제 없을까요?? 둘다 설치했다가 오류날까봐 무섭습니다
프날 Pnal
|
2023년 03월 14일 | ✨
안녕하세요. 안해봐서 모르겠지만 공식적으로는 가능하다고 알고있습니다. https://www.autohotkey.com/docs/v2/Program.htm#install 위 링크의 installing with v1을 참고하여 설치해보세요.
lightright
|
2023년 03월 13일
프날님 오늘도 질문있습니다! v1에서는 SubStr(A_GuiControl,7) 로 GUI에 있는 변수에 글자를 가져와서 함수에 쓸수 있었는데요 v2에서는 방식이 완전히 바뀌었습니다 ㅠ 그래서 제 검색실력으로 찾아보았으나 Onevent 로 대체되었다는 글만 보이고 어떻게 적용해야할지 모르겠습니다! myGui := Gui(,"HELP") myBtn := myGui.Add("Button", "x50 w100 h30 vclient1", "통계창") myBtn.OnEvent("Click", OpenNewWindow) myBtn := myGui.Add("Button", "x160 ys w100 h30 vclient2", "외래진료실") myBtn.OnEvent("Click", OpenNewWindow) 여기에서 vclient 부분의 뒤에 숫자를 가져와서 사용하고 싶은데 방법을 모르겠습니다!
프날 Pnal
|
2023년 03월 13일 | ✨
안녕하세요. 컨트롤 객체의 Name 필드가 v레이블 값이 들어가있네요. 만약 컨트롤 인스턴스의 이름이 Control이라면 Control.Name으로 사용할 수 있을 것입니다. 주신 예제에서는 myBtn이라는 이름을 사용했군요(물론 주신 스크립트는 큰 문제가 있는데, 후술합니다.). 그러면 myBtn.Name에는 client2가 들어있을 것입니다. 그러나 지금 버튼 컨트롤의 인스턴스가 겹치죠? 통계창 버튼의 변수명이 myBtn이었는데, 여기에 다시 외래 버튼을 대입하니까 통계창 버튼을 이용할 방법이 없습니다. 두 변수명은 달라야지 각각의 컨트롤을 이용할 수 있죠. (같은 이벤트 처리 함수를 사용해도, 변수명은 달라도 됩니다. myBtn.onEvent()와 myBtn2.onEvent()로 같은 이벤트 처리기를 등록하면 됩니다.) 그래서, 주신 예제를 이용해서 보여드리면 아래와 같습니다. 이벤트 처리 함수에 전달된 컨트롤 객체를 이용해서 값을 가져왔습니다. myGui := Gui(,"HELP") myBtn := myGui.Add("Button", "x50 w100 h30 vclient1", "통계창") myBtn.OnEvent("Click", OpenNewWindow) myGui.Show("") return OpenNewWindow(_obj, _info) { MsgBox(_obj.Name) }참고로, 지금 myBtn 변수가 전역 변수이기 때문에 아래와 같이 직접 이용할 수도 있습니다. myGui := Gui(,"HELP") myBtn := myGui.Add("Button", "x50 w100 h30 vclient1", "통계창") myGui.Show("") return F1:: { MsgBox(myBtn.Name) }예제 스크립트가... 의료쪽 종사자신가요? 멋있으십니다.
lightright
|
2023년 03월 14일
정말 초보자의 눈높이에서 쏙쏙 알아들을수 있게 설명 해주셔서 너무너무 감사합니다! 그런데 문제가 생겼습니다! 버튼의 변수명을 다르게 하다보니 SubStr(myBtn.Name,7) 이런식으로 가져와야하는데 하나의 이벤트함수로 처리를 할수가 없게 되어버리네요 왜냐면 두번째 버튼은 SubStr(myBtn2.Name,7) 이런식으로 되어야 하니까 말이에요 다른방법을 찾아봐야겠습니다. 어렵네요 ㅠ
프날 Pnal
|
2023년 03월 14일 | ✨
안녕허세요. 버튼 객체를 하나의 배열에 담았다가 반복문으로 순회하면서 SubStr시켜도 되고요, 어차피 버튼 객체는 이벤트 처리 함수에서 obj 매개변수로 받으니까 같은 처리 함수를 할당해줘도 됩니다. MyBtn2에도 OpenNewWindow 함수를 이벤트 처리기로 걸면 obj 매개변수로 그 변수명을 Name으로 가져올 수 있을 것입니다. 방법은 여러가지이니 잘 고민해보세요. ^^
천프로
|
2023년 03월 12일
안녕하세요. 프날님 오토핫키를 배워보려고 하는데 첫 시작부터 난관에 봉착하네요. scite4autohotkey를 설치하려는데 윈도우 버전을 지원하지 않는다고 합니다. (This version of microsoft windows is not supported by scite4autohotkey.) 제컴 환경은 윈도우10pro 32비트 사용중입니다.
프날 Pnal
|
2023년 03월 13일 | ✨
안녕하세요. 강좌에서 사용한 Windows는 10 pro 64비트입니다. 32비트 PC는 보유하고 있지 않아서 테스트가 까다롭네요. 찾아보니 v2를 대응하는 SciTE4AHK는 32비트 윈도우 지원을 하지 않습니다. 설치 과정에서 사용자 PC가 64비트가 아니면 해당 메시지를 출력하도록 되어있네요. 설치 프로그램으로 받지 말고, 포터블 버전(설치 사이트에서 Portable .zip 링크)으로 한번 받아보셔서 설정해보시길 바랍니다. 대신 이 경우 파일 경로를 수동으로 지정해주어야 할 것입니다. 구버전 에디터에서는 32 비트 지원이 되는데, 오토핫키 v2 지원은 안되어서요.
lightright
|
2023년 03월 10일
Gui에서 버튼을 누르면 새로운 Gui를 만들고 두번째 Gui창에서 버튼을 누르면 메인 Gui창을 표시하도록 만들었습니다. myGui := Gui(,"메인창") MyBtn := myGui.Add("Button", "w200 h100", "설정창") MyBtn.OnEvent("Click", OpenNewWindow) MyGui.Opt("+AlwaysOnTop +ToolWindow") myGui.Show() NewGui := Gui(,"설정창") NewBtn := NewGui.Add("Button", "w100 h30", "설정완료") NewBtn.OnEvent("Click", ShowMyGui) NewGui.Opt("+AlwaysOnTop +ToolWindow") OpenNewWindow(_obj, _info) { myGui.submit(1) NewGui.Show() } ShowMyGui(_obj,_info) { NewGui.submit(1) myGui.Show() } 이런식으로 사용하면 될지 아니면 더 간단한 방법이 있을지 프날님의 평가 부탁드리겠습니다!
프날 Pnal
|
2023년 03월 13일 | ✨
안녕하세요. 답글을 드린 줄 알았는데 착각했습니다. 늦어서 죄송합니다. 말씀하신대로 사용하시면 됩니다^^
lightright
|
2023년 03월 09일
v2 첫질문을하게되어 영광입니다. 프날님! 답변을 읽어보았는데도 이해가 가질 않습니다 ㅠㅠ 함수에 매개변수가 들어가야 한다는 말씀이신가요? https://www.autohotkey.com/docs/v2/lib/GuiControls.htm#Button 오토핫키 공식문서에서는 다른건 내용이 없어서 이해가 되질 않습니다.
프날 Pnal
|
2023년 03월 09일 | ✨
안녕하세요. 해당 문서가 아니라 Gui Events 문서를 보시길 바랍니다. 이 문서는 GUI 이벤트에 관련해서 적혀있는 문서입니다. v2에선 GUI에서 일어나는 일을 감지하려면 일관적으로 이벤트를 이용합니다. 해당 부분에 보시면 각 이벤트마다 이를 처리하는 이벤트 처리 함수의 원형을 어떻게 처리해야하는지 알 수 있습니다. 컨트롤을 클릭했을 때 일어나는 Click 이벤트는 Ctrl_Click(GuiCtrlObj, Info)라는 원형을 갖고있다고 적혀있습니다. 두 매개변수의 이름은 자유롭게 해도 됩니다. 'GuiCtrlObj'는 컨트롤 객체가, 'Info'는 이벤트 정보가 들어있는 변수입니다. 저는 간단하게 _obj, _info로 적는 편이긴 합니다. 각 변수에 어떤 값이 들어가는지는 역시 해당 문서의 같은 문단을 보시면 됩니다. (다만 해당 도움말에 보시면 버튼 컨트롤에서 Info 매개변수는 현재 아무 값도 들어있지 않을 것입니다.) 다시 본론으로 돌아와서, Click 이벤트 처리 함수는 두 개의 매개변수를 받야아한다는 것입니다. 그래서 함수에 매개변수 두 개를 넣어 정의해주세요. 지금은 아무 매개변수도 받지 않는 형태십니다. 버튼을 클릭할 때 메시지박스를 띄우는 간단한 예제가 48강의 예제 파일로 있습니다. 48강의 실습에 제공된 예제 프로그램은 제가 강좌를 위해 짤막하게 제작한 프로그램인데, 스크립트로 제공하니 이 스크립트를 한번 봐보세요. 'TestButton' 객체에 OnEvent() 함수로 TestButton_OnClick 함수를 이벤트 처리 함수로 등록한 점을 볼 수 있습니다. 처리 함수의 본문을 살펴보시면, TestButton_OnClick(_obj, _info) { MsgBox("버튼이 클릭되었습니다.") } 처럼 두 개의 매개변수를 받는 것을 볼 수 있죠. 활용하지 않아도 이는 꼭 적어주셔야 하는 매개변수입니다. 추가 질문은 [글타래 추가] 버튼을 이용해주시면 됩니다.
lightright
|
2023년 03월 09일
이해 했습니다! 그렇다면 일반 클릭 함수를 만들때 Noaml_Click(_obj,_info, PID, &x, &y, imageName ) { 명령어 } 이런식으로 만들어야 하나요? 현재는 disableClick( programid, x, y, WhichButton := "left", Clickcount := 1 , img := "" ) { if (img != "") { y -= 20 } coord := x|y<<16 PostMessage, 0x200, 0, %coord%,, ahk_id %programid% Sleep 60 if ( Clickcount = 1 ) { if ( WhichButton = "left" ) { PostMessage, 0x201, 1, %coord%,, ahk_id %programid% sleep, 50 PostMessage, 0x202, 0, %coord%,, ahk_id %programid% } else if ( WhichButton = "right" ) { PostMessage, 0x204, 1, %coord%,, ahk_id %programid% sleep, 50 PostMessage, 0x205, 0, %coord%,, ahk_id %programid% } } if ( Clickcount = 2 ) { PostMessage, 0x203, 1, %coord%, , ahk_id %programid% } randSleep(50,90) } 이런식으로 제작 했는데 매개변수 부분에만 _obj,_info 를 추가해줘야 하는건지 궁금합니다
프날 Pnal
|
2023년 03월 09일 | ✨
아니요. 이벤트 처리 함수와는 분리를 해주세요. 이벤트 처리 함수 내레서 만드신 그 함수를 호출하는 식이면 될 것 같습니다.
lightright
|
2023년 03월 10일
버튼을 눌렀을때 이벤트를 할 함수안에 클릭함수를 넣는건가요?? Ctrl_Click(GuiCtrlObj, Info) { disableClick( programid, x, y, WhichButton := "left", Clickcount := 1 , img := "" ) { postmessage... } } 이런식으로가 되겠군요! 뭔가 v1 보다 더 복잡해진 느낌입니다 ㅠㅠ 여기 글쓰는 부분 좀더 넓게 해주실수 있나요?? 세로부분이 5줄밖에 표시되지 않아 좁다는 느낌이 듭니다!
프날 Pnal
|
2023년 03월 10일 | ✨
함수의 호출부만 적어주어서 호출하시면 됩니다.... 총 코드는 이벤트 처리 함수(obj, info) { 함수 호출() } 이렇게 될 것입니다. 댓글창은 세로 크기조정을 추가하겠습니다. 그 외에도 대댓글끼리 구분이 잘 안되네요. 이도 조정을 해야겠습니다.
lightright
|
2023년 03월 10일
정리 하자면 myGui := Gui() MyBtn := myGui.AddButton("w80", "Click me!") MyBtn.OnEvent("Click", 이벤트호출함수) MyGui.Opt("+AlwaysOnTop +ToolWindow") myGui.Show("h200 w200") 이벤트호출함수(_obj,_info) { 함수() } 가 되겠군요! 역시 프날님의 깔끔하신 가르침덕분에 오늘도 기분이 좋아졌습니다!