프날 오토핫키 강좌  v2

질문 및 답변


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

  • 실제 허용 여부를 막론하고 모든 게임에 관한 질문은 받지 않습니다.
  • 홈페이지 유지 보수 및 구조 변경으로 인해 작성한 모든 글이 삭제될 수 있습니다.
  • 이 곳에 쓰는 것은 불법적인 프로그램 개발 및 사용을 하지 않음에 동의하는 것입니다.
  • 프로그래밍과 관련이 없는 글은 삭제될 수 있습니다.
총 78건의 질문
(한글 포함됨)
lightright
|
2023년 12월 06일
안녕하세요 프날님! 숫자추첨 프로그램을 만들려고 하는데 도저히 생각이 떠오르지 않아서 여쭤봅니다! 만약에 numbers = [1,2,3,4,5,6,7,8,9,10] 이라는 리스트에서 숫자를 3개를 추첨해야합니다 추첨중에는 제외해야할 숫자가 2개가 있고 꼭 넣어야 하는 숫자가 2개가 있을때 코드를 어떻게 작성을 해야할지 생각이 떠오르질 않아서 프날님 의견을 여쭤보고 싶습니다~!
프날 Pnal
|
2023년 12월 06일 | ✨
안녕하세요. random 함수를 이용하시면 쉽게 해결하실 수 있습니다. 1. 꼭 넣어야하는 숫자 2개 그 숫자 2개를 결과값 앞에 넣고, random을 1회만 수행합니다. 2. 제외해야할 숫자 2개 배열에서 그 숫자 두개를 제거한 다음(배열 전체를 Loop로 순회하며 각 요소의 값을 제외해야할 숫자와 비교한다음, 제외해야한다면 그 인덱스를 저장해뒀다가 반복을 탈출한 뒤 배열.RemoveAt()를 쓰세요) random을 3회 수행합니다. 아니면 빈 배열 하나에 제외해야할 숫자를 제외하고 원본 배열의 값을 복사해서 넣어볼 수 있습니다. 아무튼 배열에 제외해야할 숫자를 없게 하는 것을 설명드린겁니다. 혹은, 제외해야할 숫자가 나오지 않을 때까지 다시 random을 수행할 수 있는데, 이게 시간복잡도가 무한대라서 이론상 운이 안좋으면 오래걸릴 수 있습니다. 실제론 10개 숫자 중 2개 제외라면 이거나 저거나 별 시간 안걸리겠지만요.
토로
|
2023년 11월 29일
안녕하세요! 프날님 혹시라도 스크립트 자체적으로 관리자 권한으로 실행되게 하는 방법은 없을까요? A 스크립트를 실행하면 그 스크립트가 자동으로 관리자 권한으로 실행되게 끔 만들고 싶습니다.
프날 Pnal
|
2023년 11월 29일 | ✨
안녕하세요. Run 명령어로 현재 파일을 실행시킬 때 Run as 파라미터와 함께 /restart 인자를 넘겨주셔서 사용하시면 됩니다. https://www.autohotkey.com/docs/v2/lib/Run.htm#RunAs 위 도움말의 예제를 참고해보시고 만약 여러번 시도해봐도 안되시면 말씀주세요. ^^
불타는감자
|
2023년 11월 24일
너무 좋은 강좌 감사합니다. 이런 양질의 자료 덕분에 많이 배웁니다. 고맙습니다.
levan
|
2023년 11월 24일
맞습니다..
프날 Pnal
|
2023년 11월 24일 | ✨
감사합니다. 연말이나 내년 연초에 나올 Part 3 강좌도 많이 봐주세요.
Lazen
|
2023년 11월 21일
안녕하세요. 프날님 강좌를 보며 v2버전 사용중인데 간단한 난독화나 암호화 할수 있을까요? ahk2 컴파일러는 다보이더라구요..
프날 Pnal
|
2023년 11월 21일 | ✨
안녕하세요. UPX와 같은 패킹 툴로 패킹하거나, 상용 프로그램 정도의 보안이 필요하시다면 Themida 같은 전용 코드 프로텍션 솔루션을 구매해 사용하시는 것이 좋아보입니다. Themida는 개발자라이선스가 한화 30만원 정도라고 알고있는데, 개발을 취미로 하는 상태더라도 배포 프로그램이 주기적으로 하나씩 있다면 눈 딱 감고 투자하기엔 괜찮은 가격이라고 생각합니다. 다만 어느 방식을 쓰던 쉽고 어려움의 차이지 능력있는 사람이 코드를 들여다보긴 가능할 수 있다는 점을 명심하셔야 합니다. 간단한 난독화나 암호화라고 하셨으니 UPX와 같은 오픈소스 패킹 툴이 적합해보이지만, 각종 악성코드가 분석을 어렵게 하기 위해 UPX 패킹을 적용하고 있는 경우가 많아 질문자님의 프로그램 또한 악성코드로 오진될 수 있다는 점은 유의하셔야 합니다. 그리고 대부분의 패커는 압축이 목적이기 때문에 언패킹하면 그만인 경우가 많습니다. 즉, UPX로 압축된 파일은 UPX로 압축해제 할 수 있습니다.
프날 Pnal
|
2023년 11월 21일 | ✨
다만 한 가지 추천드리는 옵션 중 하나는 아예 오픈소스화 해버리는 것입니다. 저 또한 과거엔 제 코드를 보여주기 부끄러웠지만, 지금은 가능하면 오픈소스로 보여주려고 하며 오픈소스 프로젝트에 조금씩 기여하고 있습니다. 개인적인 생각이지만 오픈소스는 어떤 사상(이데올로기) 내지 신념적인 부분이 있다고 생각하고, 따라서 강요드리거나 이렇게 해야한다!는 절대적 솔루션이 될 순 없다고 생각하지만요. GitHub나 GitLab과 같은 Git 저장소에 코드를 공개하고 프로그램을 공유하는 취미는 생각보다 기쁜 일입니다. 굳이 가릴 이유가 없는 공개 가능한 코드라면 위와 같이 공개해보는 것도 좋을 것 같습니다.
Lazen
|
2023년 11월 22일
답변감사합니다! UPX정도면 아주 좋은거 같아서 사용해봤더니 보안프로그램이 잡아버려서 삭제 시켜 버리네요 ㅜㅡㅜ 업무용으로 1만줄 정도 소스 짜놓았는데 직장 동료에게 공유 하려는데 건물을 다른회사와 같이 사용하다보니 사내에서만 돌아야 할 서류들이 타회사에서 보고 있는 경유가 왕왕있어서 제가 짠 소스를 너무 간단하게 볼수만 없게 하고 싶었거든요 보안프로그램에 안걸리는 다른방법이 있을까요? 그냥 보통사람이 열었을때 이게 뭐지? 정도면 될거 같습니다.
프날 Pnal
|
2023년 11월 22일 | ✨
저는 예전에 각 백신 회사들에게 오진 수정 요청 이메일을 일일이 보냈던 적이 있네요. ^^; 또 돈 들여서 Code signing을 하기도 했었고요. 시중에 많은 패킹 툴이 있는데 적합한걸 찾아보셔도 될 것 같습니다. 이건 저도 잘 모르는데, Ahk2Exe에서 컴파일 하실때 우하단에 압축 관련 체크박스라던가 이런것들을 체크해서 컴파일하면 어떨까 싶습니다. 관련 없나 싶기도 하고요. 저는 더 모르겠네요.
levan
|
2023년 11월 18일
이 코드가 왜 정상적으로 보내지지 않는지.. 봐주실 수 있으십니까? [관리자에 의해 삭제된 부분] json 값은 정상적으로 피들러를 통해 받았습니다..ㅜ
프날 Pnal
|
2023년 11월 18일 | ✨
다른 사람의 티스토리 블로그에 댓글을 쓰는 프로그램은 일반적인 상황에선 사용하지 않는... 일종의 다른 불법 매크로(스팸댓글 등에 악용) 될 수 있기 때문에 답변드리지 못하겠습니다. 죄송합니다.
levan
|
2023년 11월 20일
먼저 말하기에 앞서..위에 지워진 부분에 나온 블로그는 제 블로그이며 링크 들어가보시면 제가 연습하려고 log 라는 이름으로 글을 작성해놓으신것까지 볼 수 있습니다..ㅜ 단순히 위 질문은 json을 winhttp로 보내는 방법이 궁금해서 예시를 들어서 질문드린것이며 불법매크로와는 단연코 정말 관련이 없습니다.. 아래에 댓글 달아주신 "Content-type 헤더 중 JSON 타입을 보낼 수 있는 헤더가 있는데, 이를 이용하시면 수신 서버에서 전송받은 문자열을 JSON으로 해석한답니다. Http request POST JSON 등으로 검색해보시면 제가 말하는 헤더가 뭔지 아실 수 있을 것입니다."라는걸 보고 헤더까지 수정하였지만 오류가 계속 떠서 해결책이 너무 궁금해서 질문드리는거니 나쁘게 생각 안해주셨으면 합니다. 받아온 json이 (피들러){"captcha":"","comment":"cccc","homepage":"","isSecret":false,"name":"aaaa","parent":null,"password":"[관리자에 의해 삭제된 부분]","mentionId":null} 이렇게 넘어왔는데 이 정보를 그대로 보내려고 send 에 넣으면 Invalid property name in object literal. 라는 문구와 함께 오류가 뜹니다 부분 코드 : comObj.Send({"captcha":"","comment":"cccc","homepage":"","isSecret":false,"name":"aaaa","parent":null,"password":"[관리자에 의해 삭제된 부분]","mentionId":null}) 그래서 이러한 json값을 뭐라고 고쳐야지 정상적으로 보낼 수 있는지 너무 궁금해서 이렇게 다시 질문드립니다..
levan
|
2023년 11월 20일
정말 불법 관련된것이 아닌 단순히 winhttp로 json 을 보내는 정상적인 코드를 한번이라도 보고싶어서 이렇게 질문남깁니다..
프날 Pnal
|
2023년 11월 21일 | ✨
네 제가 질문자님이 불법 프로그램을 만든다고 단정짓거나 그렇게 의심했던게 아니라, 이게 악용의 소지도 있고 해서 좀 선제적?으로 범위를 크게 잡아서 말씀 못드려서 그랬습니다. 이렇게 확실히 말씀해주셔서 감사합니다. JSON은 데이터 타입을 문자열로 나타내는 여러 형식 중 하나입니다. 어떤 객체나 특수한 또다른 형식이 아니라, 결국 문자열이란 뜻입니다. 다시 한 번 힌트 삼아 강조드려보면, "문자열"입니다. 질문자님이 보내신 것은 JSON형식의 어떤 객체입니다. {}로 감싸져있으니까요. 웹서버는 당연히 이런 별도 형식?을 전달받지 못하고, 문자열만 받을 수 있습니다. JSON 문자열 전체를 따옴표로 감싸서 문자열로 전달되어야 합니다. Content-Type은 잘 찾으셨습니다. ^^ 제가 말씀드리고자 했던 정답입니다. 그리고, 댓글에 Password 필드는 혹시 몰라 삭제하겠습니다. 물론 해시된 문자열론 원본 비밀번호를 알 수 없지만, 비밀번호라는 특성상 최대한 해시 문자열도 가리는게 심리적으로 좋을 것 같습니다.
levan
|
2023년 11월 17일
안녕하세요! 프날님 저번에 여기서 댓글 달기(wnhttp로) 연습했다가 비밀번호 못찾아서 프날님이 대신 지워준 그 수강생입니다. [관리자에 의해 삭제된 부분] json을 post에서 send로 보내고 싶은데 방법이 없을까요? 온갖 방법을 다 찾아봤지만 보이지 않네여...ㅜ
프날 Pnal
|
2023년 11월 18일 | ✨
안녕하세요. 우선 너무 날것의(?) 데이터가 포함되어있어서 질문을 같은 내용으로 수정했습니다. Content-type 헤더 중 JSON 타입을 보낼 수 있는 헤더가 있는데, 이를 이용하시면 수신 서버에서 전송받은 문자열을 JSON으로 해석한답니다. Http request POST JSON 등으로 검색해보시면 제가 말하는 헤더가 뭔지 아실 수 있을 것입니다.
levan
|
2023년 11월 21일
계좌불러주시면 치킨값 보내드리겠습니다
프날 Pnal
|
2023년 11월 22일 | ✨
괜찮습니다. ^^;
좋은 기능
|
2023년 11월 13일
안녕하세요. 키보드 키 변경에 대해 알아보다가 여기까지 왔는데요.. FN + F12 키가 현재 볼륨업으로 되어 있는데 이 키를 계산기를 실행시키는 키로 변경시키고 싶습니다. 이와 관련하여 봐야할 강의가 있을까요?
프날 Pnal
|
2023년 11월 14일 | ✨
안녕하세요. 원래 fn키는 핫키로 사용할 수 없으나, 키보드 제조사가 만든 방식에 따라 "볼륨 업" 기능을 핫키로 사용할 수 있습니다. Volume_Up:: 핫키를 이용하시고, 그 동작으로 본편 강의의 Run으로 계산기를 실행시켜보세요. (계산기의 경로는 인터넷에 검색해보시면 나올 겁니다.)
좋은 기능
|
2023년 11월 14일
덕분에 해결되었습니다! 너무 감사드립니다!!
독학학생.
|
2023년 10월 30일
안녕하세요 프날님.강의 너무 잘봤습니다. 오토핫키를 배우려고 프날님 사이트를 알게된뒤에 V2 버젼을 추천하셔서 열심히 공부해서 몇일동안 예제도 연습해보고 재미나게 보고있었습니다. 한 15년전에 현업 종사할때 C언어랑 JAVA를 조금 했었는데 지금은 가물가물해도 그래도 많이 도움이 되더라구요. 최신버젼인 V2버젼을 이용하여 응용소스를 만들어보려하니. 애초에 문법자체가 V1->V2로 넘어가면서 이루어지다보니 라이브러리 부터 바뀐게 많나 보더군요. 기존 라이브러리 넣었다가 오류가 무수히 나더군요. 해외포럼 뒤지다가 깃허브에 GDIP_ALL.ahk V2버젼은 있는데. GDIP_ImageSearch.ahk 라이브러리는 아직 버젼업이 안되었는지 공유가 안되어있더라구요. 어떤 유저가 ImagePut.ahk 라는 ImageSearch 펑션을 사용할수있는 라이브러리를 제공하고있다고 댓글은 남겨놨던데. 아무래도 예제 강의가 없다보니 이해가 혼자서 이것저것 시도해보다가 잘 안되서 진땀뺏네요. 심지어 한국 포럼같은곳에 가도 여전히 V1예제/질문 만 올라오더군요.. 각종 예제/레프런스 모두 V2가 나온지 한참이 지났음에도. V1의 자료만 간간히 나오는 정도가 V2같은경우는 찾기가 힘든정도라서.. 다시 V1을 배워야할지 고민이 되네요. V2와 V1을 비교해봤을때는 제 개인적으로는 V2가 예전에 하던 C나 자바와 매우 유사한 느낌을 받았기에 적응이 쉬웠는데.. 그렇다고 맨땅에 헤딩하면서 V2를 배우자니 어려움이 있을것 같아 굉장히 고민이됩니다.ㅠㅠ 앞으로 필요한 라이브러리나 이런것들도 다운받으면 왠지 애로사항이 생길것 같은 불안한 느낌이 드네요. 혹시 프날님께 실례가안된다면 Gdip_All.ahk ,Gdip_ImageSearch.ahk V2 버젼을 가지고 계시면 공유가 가능할까요?. 그걸로 여러가지 시도해보고. 어렴움에 봉착하면 프날님 V1강좌를 다시 정독하고 V1기반 시스템을 한번 구축해보려고합니다.ㅠㅠ
프날 Pnal
|
2023년 10월 30일 | ✨
안녕하세요. 저도 상기하신 이유때문에 v2를 더욱 선호하고 또 추천드리곤 합니다. 그러나 확실히 라이브러리가 많이 없긴 합니다. 정말로 맨 땅에 헤딩하듯이 직접 만드는 상황이 많이 나올 수 있습니다. Gdip이 ahkv2 버전으로 있다면, Gdip_imageSearch 라이브러리 또한 Gdip의 v2버전을 이용하도록 하여 포팅할 수 있을 것이고 또 같은 원리로 만약 Gdip이 v2버전이 없었다면 아예 Gdip도 dllcall을 이용하여 아예 v2버전을 새로 만들수도 있겠지만, 사실 일반 사용자 분들에게 추천드리는 행동이긴 어려워보입니다. 바퀴를 재발명하지 말라는데, 바퀴가 아직 발명이 안된 상황이니까요. 그래서 오토핫키를 새로 배우는 분들은 v2를 배우는 것을 추천 드리지만, 정말 지금 필요한 프로그램이 있다면 v1을 어쩔수없이 선택하는게 나을 수 있습니다. 서론은 여기까지 하고... 1. Gdip쪽 라이브러리는 v2 버전으로 갖고있는게 없습니다. 2. 상기 말씀드린 현실적인 문제 때문에, 현재 어떤 프로젝트를 당장 시작해야 한다면 v1을 이용하는 것이 차선이 될 수 있습니다. 3. 다만 추천드리는 또다른 선택지 중 하나는, 저는 오토핫키 v1을 그렇게 선호하지 않고 현재 v2가 나온지 1년이 다 되어가는 상황에서 v1을 선뜻 말씀드리기가 어렵습니다. 아무리 생각해도 v1은 정말 문법적 하자(점잖게 말하면 '파편화' 혹은 '비일관성)'가 많습니다. 그래서 저는 차라리 Python을 추천드립니다. Python도 오토핫키처럼 메이저 버전업이 되면서 문법 체계가 많이 바뀌었지만, 지금은 성공적으로 최신 문법이 자리잡아서 자료도 많고 좋습니다. 특히 기존에 C/Java를 하신 적 있으시면 해볼만 하실 것입니다.
독학학생
|
2023년 11월 12일
프날님 친절한 답변 너무감사드립니다. 파이썬과 v1을 고민하다가 일단은 지금 급한대로 v1을 통해서 일정부분 원하는 시스템을 구축했습니다. 잘안되는부분은 프날님 사이트나 타사이트 레퍼런스들을 참고하였답니다. 프날님이 말씀하신 v1의 문제점들을 제 개인적으로도 몇가지 느꼈답니다. 제 개인적으로 다중 오브젝트(배열)을 이용하면서 리터럴 "=" , ":=" 사용법이 굉장히 난해하였습니다. 특히나 세미콜론을 습관적으로 가져다 붙혀버려서 초반에는 굉장히 고생했답니다. 디버깅을 하면서도 이해가 안가는 부분이 제법 많았지만 나름 재미있게 작업했던것 같습니다.^^ 기회가 된다면 프날님이 v2강좌를 완결 내시면 오토핫키를 조금더 배워보고싶은 욕심도 나네요. 더불어 프날님께서 추천하신 파이썬도 이번 기회에 조금 맛을 봐볼까합니다. 현역때 처럼 몇시간씩 앉아서 코딩하는게 체력적으로 어려웠지만 덕분에 너무 재밌게 작업했습니다. 혹시 모르거나 난해한 부분이 있으면 염치없지만 질문드리러 오겠습니다.ㅠㅠ 날씨가 어제부터 너무 추워졌습니다. 건강에 유의하시고, 행복한 연말 되시길 바랍니다. 감사드립니다.
프날 Pnal
|
2023년 11월 12일 | ✨
파이썬은 현역때 고생하신 것보다 십 분의 일 정도의 노력만으로 원하는 작업을 할 수 있는 혁신적 언어라고 생각합니다. 기회되면 배워보시는 것을 강력히 추천드립니다. 강의 완결은 연말 내지 내년 연초를 생각중입니다. 현재 정규식 파트와 파일입출력 파트를 제외하곤 거의 다 적었으나, 기존 글도 좀 수정하고, 이미지와 동영상도 삽입해야해서 일단 올해 12월 31일을 목표로 달리고 있습니다. 행복한 연말 보내세요. 날씨가 추우니 건강 조심하세요.
무적기계
|
2023년 10월 27일
안녕하세요. 강좌 잘 보고 있습니다. 감사합니다. 다른게 아니고, 제가 영어 원문 보는 업무가 많은데, 단어 서치가 항상 번거로워 방법을 찾는중에 오토핫키를 검색하게 되었고, 프날님의 강좌를 보게 되었습니다. 단어를 드래그한 후, 제가 설정한 단축키를 누르면 네이버 영한사전에서 바로 확인할 수 있게하도록 짜고 싶은데, 기본 개념이 없다 보니 응용이 어려운게 사실이네요;; 도와주시면 감사하겠습니다 :) ^+x:: Text := Send ^c Run("https://en.dict.naver.com/#/search?query=%Text%&range=all",,"Max") exitapp
프날 Pnal
|
2023년 10월 28일 | ✨
안녕허세요. 12강 내용 중 “변수와 문자열의 연결” 부분에 완전히 동일헌 Case가 있으니 큰 참고가 되실 것 같습니다. 변수는 그대로 쓰고, 문자열 부분만 따옴표로 감싸시면 되겠습니다. ^^ 그 둘 사이는 한 칸 띄워주시고요. "문자열" 변수 "문자열" 변수 .... 질문자님 Case에선"String" var1 "String2" 형태겠네요.
levan
|
2023년 10월 24일
항상 친절하게 답변해주셔서 감사합니다. 웹사이트 크롤링에 관련해서 여쭤보려고 왔습니다. 질문 1 : 접속을 할 때 뜨는 창이 있습니다. ex)비밀번호를 변경안한지 몇일 지났습니다. 그대로 사용하실겁니까? 확인 or 아니요.. 식으로 말입니다. 그런데 이 사이트에서 정보를 받아오려고 하는데 오토핫키에서 자동으로 확인이라는 버튼을 눌렀다는 신호값을 보내고 그 사이트의 정보를 읽어오는 방법은 없을까요? 질문 2 : 특정 사이트에서 프날님이 강의해주신 winhttp post 방식을 가지고 로그인 했을때 로그인 된 상태로 제가 그 사이트를 브라우저에서 열 수 있는 방법은 없을까요? ex) 자동으로 네이버 로그인해서 정보 긁어오는건 되지만 로그인이 된 상태로 브라우저에서 그 사이트를 한번에 열고 싶습니다. 감사합니다
프날 Pnal
|
2023년 10월 25일 | ✨
1. WinHTTP 기준으로, 해당 창이 뜨는 것과 상관없이 로그인은 된 상태이므로 GET으로 원하는 웹페이지 소스를 가져올 수 있습니다. 굳이 그 확인이라는 버튼 신로를 보내야할 이유는 없어보입니다. 2. 없습니다. WinHTTP는 단지 HTTP 요청을 서버에 보내서 응답을 받은 것으로, 브라우저와는 독립적인 기술입니다. 위의 질문과도 같은 맥락으로써 창을 띄우고 실제 우리가 웹을 탐색하는 모양으로(즉, WinHTTP는 '클릭', '이동'이라는 개념이 없지만, 실제 웹 경험처럼 클릭과 페이지 이동을 기반으로 한) 웹 자동화를 하고싶다면 Selenium을 알아볼 수 있겠습니다. 하시려는 작업은 전체적으로 WinHTTP와는 동떨어져 있습니다. WinHTTP는 보이지 않는 창에 클릭하거나 페이지를 이동하는 개념이 아니라, 서버에 특정 주소의 HTML 코드를 요청하는 것 그 이상 그 이하도 아닙니다. 즉, 정보를 요청할 페이지 주소를 명확히 알고 있어야 하며, 버튼을 누르던가 그런 것과는 관계가 없는 기술입니다. (페이지 이동을 버튼 없이 주소창에 Url 입력만으로 한다고 생각해보세요. 웹페이지의 버튼을 클릭할 필요가 없을 것이며, 사실 말씀하신 비밀번호 변경 페이지가 뜨는 말든 상관이 없죠. 어처피 크롤링 할 페이지의 주소를 입력해줘야하니까요.) 오히려 Selenium 쪽을 알아보시는 것이 좋겠습니다. 이 경우 오토핫키보단 Python쪽이 더욱 양질의 자료가 많습니다. ** 추가로, 웹 크롤링은 사이트 운영자의 의사에 반하면 안됩니다 **
levan
|
2023년 10월 25일
감사합니다 프날님 도움이 많이 되었습니다!
levan
|
2023년 10월 21일
안녕하세요!프날님 질문이 있어서 이렇게 왔습니다. 현재 control send쪽을 공부하고 있는데 프날님이 내주신 그 부분의 프로그래밍 문제를 보면서 이렇게 해도 되지 않을까? 생각을 했지만 결과값이 완전 엉뚱하게 나와서 질문드립니다. 아래 코드가 정상 작동하지 않는 이유가 무엇일까요? mac := 5 gz := "병의 맥주가 벽장에 있네 " gz5 := "병의 맥주가 벽장에 있네`n" gz1 := "병의 맥주라네`n" gz2 := "하나를 내려서 차례로 돌렸네, " mac-1 "병의 맥주가 벽장에 있네`n`n" Loop 5 { ControlSend(mac gz mac gz1 gz2 mac-1 gz5 , "Edit1" ,"ahk_exe notepad.exe") mac -= A_Index }
프날 Pnal
|
2023년 10월 22일 | ✨
안녕하세요. 반복문 내 디버깅은 코드에 따른 각 반복 횟수 별 동작과, 변수의 값 변화를 보면 쉽습니다. [1회차 반복] 동작: 5병의 맥주가 벽장에 있네 5병의 맥주라네/하나를 내려서 차례로 돌렸네, 4병의 맥주가 벽장에 있네//4병의 백주가 벽장에 있네/ mac의 값: 반복문이 끝날 시점에 4 (5 - 1을 했으므로) [2회차 반복] 동작: 4병의 맥주가 벽장에 있네 4병의 맥주라네/하나를 내려서 차례로 돌렸네, 3병의 맥주가 벽장에 있네//3병의 맥주가 벽장에 있네/ mac의 값: 반복문이 끝날 시점에 2 (4 - 2를 했으므로) * 문제가 보이시나요? 우선, 한 문장이 끝난 후에 'n-1 병의 맥주가 벽장에 있네'라는 문장이 추가로 나오고요(코드 내에선 mac-1 gz5 부분), 이 부분은 완전히 삭제되는 것이 옳겠습니다. 불필요한 문장이 출력되니까요. 그리고 가장 문제는 mac의 값인데요, mac은 현재 mac의 값으로부터 반복시마다 1, 2, 3, 4, 5씩 증가하며 줄어듭니다. 따라서, 초기 5였던 값은 반복이 끝날 때마다 4, 2, -1, -5, -10이 됩니다. 실제로 반복문문 뒤에서 mac의 값을 MsgBox로 출력해보면 -10일 것입니다. 우리가 필요한 것은 반복이 끝날 때마다 1, 2, 3, 4, 5씩 줄어드는 것이 아닌, 1씩만 줄어드는 것입니다. 즉, mac은 4, 3, 2, 1, 0으로 줄어들어야 합니다. 이제 문제의 원인을 아시겠나요?
levan
|
2023년 10월 22일
감사합니다. 프날님 덕분에 해결완료했습니다 ㅜㅜ
lightright
|
2023년 10월 20일
안녕하세요 프날님 오랜만에 질문 드립니다. array에 들어있는 값을 한번에 msgbox로 출력하는 방법이 있을까요?? Array := [1,2,3,4,5] msgbox로 출력시 1,2,3,4,5 이렇게 출력되게 말이에요
프날 Pnal
|
2023년 10월 20일 | ✨
안녕하세요 오랜만입니다. 그런 함수는 기본적으로 제공하지 않는데, 직접 인수로 배열을 받는 출력 함수를 만들어보시는 것은 어떤가요? 반복문과 누적 대입 연산자(.=)로 쉽게 구현하실 수 있을 것입니다.
핫키초딩
|
2023년 10월 19일
정말 감사드립니다. Hotkey or hotstring missing it's opening brace -> 이 에러가 계속 떳는데 핫키 뒤에 {}를 넣었더니 해결되었습니다! 다시 한번 감사드립니다.
프날 Pnal
|
2023년 10월 19일 | ✨
안녕하세요. 잘 해결되었다니 다행입니다. ^^ 오류 메시지는 핫키 또는 핫스트링에 여는 중괄호가 없다는 뜻이었습니다. 오류 매시지에 답이 있었네요.
핫키초딩
|
2023년 10월 19일
질문드렸던 스크립트입니다. 뭐가 잘못된 건지 알려주시면 감사하겠습니다. CoordMode("mouse", "Screen") CoordMode("Pixel", "Screen") F1:: Loop { result := ImageSearch(&x, &y, 1440, 264, 1621, 935, "*30 signal.png") if (result=1) { MouseClick("Left", 2010, 166) send("signal generation") send("{enter}") } else if (result=0) { sleep(1000) } } return
프날 Pnal
|
2023년 10월 19일 | ✨
안녕하세요. 실행이 되지 않는다는 것이 어떤 문제인가요? - Send 구문에 의해 글씨가 입력되지 않음 - 오류 메시지가 나옴 - 프로그램이 아예 정지됨 (작업관리자에서 보았을 때 ‘응답없음’) - 아무 증상이 없이 이미지서치가 되지 않음 (반복문만 공회전함) 우선 MsgBox로 Loop 안에 A_index를 출력해보면서 몇번째 반복에서 안되는지, 아예 Loop문이 돌아가지 않는건지, 반복문은 돌아가는데 서치가 안되는건지 확인해보시길 바랍니다. 그리고 핫키 밑엔 블록의 시작({) 있어야합니다. (밑에 구문이 한 블록이라 굳이 필요가 없을 것 같긴 한데, 일단 원칙대로 해보세요.) 맨 마지막 return은 제거되어야 마땅허겠네요. 의미 없습니다.
핫키초딩
|
2023년 10월 18일
자세한 강의 너무 감사드립니다. LOOP 반복문과 IF 조건문을 이용하여 특정이미지 발생시 알림글자를 입력하는 스크립트를 짰는데, loop 문 이하로 스크립트가 잘 돌아가고 마지막으로 LOOP 이전 줄에 핫키를 지정해주는 데 핫키를 지정하고나면 실행이 되질 않습니다. 같은 핫키로 LOOP 반복문을 제거하고 IF 조건문만 있을 때도 실행이 잘 되구요. 아무리 찾아봐도 왜 그러는지 알려주는 곳이 없어 질문드립니다.
프날 Pnal
|
2023년 10월 18일 | ✨
뭐 Loop가 핫키 블록 안에 있다고 안되진 않습니다. 아마 다른 무언가가 착각되고 있는 것 같은데, 코드를 봐야 알 것 같습니다.
앤디지
|
2023년 10월 17일
제가 imagesearch를 이용하여 Dell Support Assist를 다운 받아서 실행하는 간단한 스크립트를 생성 했습니다. 해당 스크립트를 만든 랩탑에서는 실행이 잘되는데 다른 모델의 랩탑에서 실행하면 마우스 커서가 가만히 있고 움직이지 않는데 이런 경우는 보통 어떤 이유에서 그런건가요?
프날 Pnal
|
2023년 10월 17일 | ✨
안녕하세요. 델 컴퓨터 관련 파일을 고객에게 다운로드해주는 용도이신건가요? 이미지서치는 강좌 내용에도 짧게 언급했다 싶이 환경에 따라 화상이 다르게 표현되기 때문에 어떤 컴퓨터에서는 동작하던게 다른 컴퓨터에서는 동작하지 않을 수 있습니다. 즉, 모든 랩탑의 환경을 동일하게 설정하지 않는 이상(특히 해상도와 Windows 화면 배율!) 정상 동작을 기대하긴 어렵습니다... 다만, 다운로드 과정은 다운로드 주소를 Run으로 실행할 수 있을 것이고, 실행 역시 Run으로 처리할 수 있을 것입니다. 다운로드 주소란 Assist 프로그램을 다운받을 수 있는 웹사이트 주소를 말하는게 아니고요, 그 웹사이트에서 ‘다운로드’ 버튼이 가리키는 주소를 말합니다. 해당 버튼에 유클릭 메뉴를 연 후 주소를 확인할 수 있을 것입니다. (다만, Javascript로 구현한 사이트는 그렇지 않을 수 있습니다.) 이유를 여쭤보셨는데, Mouse 관련 명령어는 아마 죄가 없을 것 같고, 이미지서치에서 이미지를 찾지 못했을 가능 성이 큽니다. MsgBox로 ImageSearch의 반환값을 살펴보세요. ^^
감사합니다
|
2023년 10월 16일
강의 초반에서 scite4autohotkey 설정에서 v2(x86)으로 해주는 이유가 있을까요? 대부분 pc는 64비트인데 왜 32비트로 설정을 하는지 궁금합니다!^^
프날 Pnal
|
2023년 10월 16일 | ✨
안녕하세요. 말씀하신대로 대부분 PC는 64비트 운영체제를 사용하지만, 일부 PC는 32비트를 아직도 사용중이기 때문에 이런 PC에선 64바트 응용 프로그램이 실행되지 않습니다. 64비트 운영체제에서 32비트 프로그램을 실행하는 것은 문제가 없기 때문에, 강좌의 편의를 위해서 그렇게 설정했습니다.
앤디지
|
2023년 10월 12일
좋은 강좌 무료로 제공 해주셔서 너무 감사합니다. Part 3 강좌가 추가 되면 따로 공지를 올리 시는지 궁금하며 이메일로 통보를 받을 수 있는지 여부도 알려 주시면 감사하겠습니다.
프날 Pnal
|
2023년 10월 13일 | ✨
공지는 따로 안올리고 쥐도새도 모르게 추가되어 있을 것입니다. 이메일은 별도로 자동 발송 시스템이 갖춰져 있지도 않고 사실 전송에 보장도 드릴 수 없어서, 즐겨찾기에 이 사이트를 추가해두셨다가 내년 초에 이 사이트를 한번 더 들어오셔서 Part 3 강좌를 확인해보시는 것이 좋아보입니다.
자유인
|
2023년 10월 11일
변수에 저장된 문자열("123")을 정수(123)로 변환하는 방법 및 정수를 문자열로 변환하는 방법이 필요합니다. 감사합니다.
프날 Pnal
|
2023년 10월 11일 | ✨
안녕하세요. 오토핫키는 자료형을 상황에 맞게 변환시키기 때문에, 크게 신경쓰실 필요가 없습니다. dll로 외부 라이브러리의 함수를 사용하는 것이 아닌 이상 자료형을 바꿀 일은 거의 없을 것입니다. 그럼에도 불구하고 굳이, 내부적으로 처리되는 자료형을 정수와 문자열로 바꾸고 싶다면, 1. 변수에 문자열 123이 저장되어 있을 때 정수형으로 바꾸는 경우 > var += 0 혹은 var := var + 0.0과 같이 숫자 0과의 연산을 통해 정수로 들어있도록 바꿔줄 수 있습니다. 혹은 var := Integer(var)과 같이 명시적으로 Integer() 함수를 사용하시면 됩니다. 2. 변수에 정수 123이 저장되어 있을 때 문자열로 바꾸는 경우 > var := "" var 과 같이 문자열을 이어주는 연산을 하시면 됩니다. 혹은 var := String(var)과 같이 명시적으로 String() 함수를 사용하시면 됩니다. Integer 함수와 String 함수는 인수로 전달된 값을 각 타입으로 변환시켜서 반환해주는 함수입니다.
프날 Pnal
|
2023년 10월 11일 | ✨
참고로, Type() 함수를 사용하면 현재 값의 자료형을 알 수 있습니다. Type(var)을 해봐서 var 변수가 문자열 123을 담고있는지, 정수 123을 담고있는지 확인해보며 테스트해보세요 ^^
핫린이
|
2023년 10월 03일
강좌 매우 감사합니다. v1때도 정말 감사히 봤습니다만 v2도 좋네요. 더해서 부탁이 있습니다만... Class, method나 그 밖에 심화 내용같은 것들도 강좌에 추가해주실 수 있을까요? 잘 사용하다가 외국의 라이브러리나 코딩해놓은 것들을 보면, 물음표를 중간중간 넣기도 하고 Class aaa{}, static aaa() 뭐 이런 식으로 해놓고 밑에 휘리리릭 적어나가는데, 공부하려고 아무리 찾아봐도 잘 모르겠어서요; 그냥 함수 쓰면 될거같은데 왜 굳이 복잡하게 저렇게 하는지도 이해가 안되고... 사용법이나, 어디서 찾아서 써야하는지도 잘 모르겠더라고요. 뭔가 근본 구조적으로 이해가 되어야 할것 같은데... 지금 해주신 것만으로도 정말 감사합니다만 나중에 시간 되시면 한번 고려해주시기를 바랍니다. 외국 코드 찾다보면 아래와 같은 것들이 많던데, 공부차원에서 좀 이해하면서 써보려고 Ahk 도움말에서 expression이나 다른것들 막 찾아도 잘 모르겠는 경우가 많더라고요. For i,v in StrSplit(s, ",") { j:=i=1 ? "":"x+0", j.=InStr(v,"Pause") ? " vPause":"" Gui, Add, Button, %j% gRun, %v% } 지금까지 강좌글 정말 감사합니다. 우선 part 3 강좌 기다릴게요 ^^~!
프날 Pnal
|
2023년 10월 04일 | ✨
감사합니다. ^^ Class, Method와 같은 내용은 Part 3의 초입 부분에 할당되어 있고 이미 작성이 끝난 상태입니다. 현재 Gui에 컨트롤을 추가하는 부분까진 글 작성이 되어있고, Gui 컨트롤에 이벤트(버튼을 클릭하면 ~~한다 등 기존 g레이블에 대응되는 사용법) 부분을 작성 예정입니다. 추가로 문자열 파싱이나 파일 입출력 과정에 대하여도 써야합니다. Part 3 강좌 중 현재 글 작성이 끝난 부분은 - 객체 지향 프로그래밍(객체, 인스턴스, 클래스의 개념 및 필드(속성)와 메서드) - 배열과 맵(기존의 ‘연관 배열’에 해당) 자료구조와 객체 리터럴을 통한 효율적인 데이터 관리 - GUI 창 생성 및 컨트롤 배치 이며, 작성 예정인 부분은 - GUI 컨트롤의 이벤트 등록 및 처리 - 문자열 파싱(문자열 관련 함수와 기초 정규표현식 살짝, v1 강좌의 InStr부터의 내용과 거의 동일) - 파일 입출력(파일 저장, 읽기 등 - v1 강좌의 FileAppend, FileRead 등과 거의 동일) 입니다. 아직 삽화도 그리지 않았고 프로그램 실행 화면을 캡처 해놓지도 않았지만, 이건 일주일이면 다 할 수 있는 부분이라서요. 글이 언제 완료되냐에 따라 전체 시간이 바뀔 것 같은데, 대략 예상하길 올해 말일이나 내년 초쯤 다 완성되지 않을까 싶어요. 추가적으로 사이트도 조금 기능상 수정했고요... ㅎㅎ; 참고로 위에 말씀드린 강좌 내용은 어디까지나 기초 강좌에 맞는 부분만 설명해서, 원하시는 내용이 충분히 설명되지 않을 수 있습니다.넘 기대는 하시지 말아주세요. ㅠㅠ
프날 Pnal
|
2023년 10월 04일 | ✨
추가로 궁금해 하시는 것에 대해. 1. 일반적인 함수를 쓰지 않고 Class를 쓰는 이유? - 객체를 이용하기 위한 목적이 큽니다. 이 내용은 Part 3가 게시되먼 자세히 알 수 있지만, 객체라는게 뭐 대단히 특별한 개념은 아니고요, 그냥 ‘변수와 함수가 들어있는 하나의 그룹’이라고 보시면 됩니다. Class는 그 그룹의 설계도고요. 따라서 어떤 Class 안에 변수와 함수를 설계해놓고, 이 설계도를 바탕으로 실제 코드에서 여러 객체를 만들 수 있습니다. 굳이 그렇게 쓰는 이유? 함수가 너무 많아져서 함수끼리 복잡하게 꼬이는걸 방지하기도 하고요. 함수명 겹치는걸 피하기 위해 함수명이 너무 길어지는걸 방지해주기도 하고요. 여러 이점이 있지만 인터넷에 ’객체 지향 프로그래밍의 장점‘을 검색해보시면 더욱 자세한 설명이 나올 것 같습니다. 다만 제가 한 줄로 요약하면 [구조화된 코드 작성을 통해 유지보수를 더욱 간편하게 할 수 있는 구조] 라고 말해보겠습니다. 당연히, 유지보수를 신경쓸 필요가 없는 아주 간단하고 사소한, 작은 프로그램이면 굳이 Class를 작성해서 막 어렵게 할 필요는 없습니다. 2. 중간중간 넣는 물음표의 정체? 삼항 연산자입니다. 물음표 단독으로 쓰진 않고, 그 뒤에 콜론(:)이 쌍으로 와야합니다. 연산자의 사용 방법은 (조건식) ? A : B 이며, 조건식이 참이라면 연산의 결과는 A가 되고, 거짓이라면 B가 됩니다. 쉽게 말해서, result := x < 3 ? "Error" : 1 위 식은 x가 3보다 작으먼 Error 문자열이 result 변수에 담기고, 그렇지 않으면 1이 담깁니다. 아래 조건문을 축약해서 쓴 것입니다. if (x < 3 ) result := "Error" else result := 1 올려주신 코드의 이 부분을 해석해보면 >>>> . j := i=1 ? "" : "x+0" i가 만약 1이면 j는 빈 값으로 놔두고(j := "") , 그렇지 않다면 j := "x+0"을 하라는 말입니다.
핫린이
|
2023년 10월 06일
크... 말씀 감사합니다~ ^^*~!
핫키초보
|
2023년 09월 17일
강의 올려주신 서치부분을 공부해서 이미지를찾고 클릳하는데 까지는 성공했는데 다음줄에 send, {enter} 요걸 입력하니까 애러가 나드라구요 애러없이 앤터 명령키 넣을려면 어캐해야 하나요
프날 Pnal
|
2023년 09월 18일 | ✨
안녕하세요. 강좌 Send 부분을 다시 보시길 바랍니다. 문법이 틀리셨네요.
오토핫키린이
|
2023년 09월 08일
선생님, 지난번 말씀해주신 내용으로 해결했습니다^^ 감사합니다. 한가지 더 질문이 있는데요, 엑셀파일의 특정 셀의 내용을 복사하여 한글문서로 붙여넣는 것을 반복하는 스크립트를 작성하고 싶은데, 복사하고 붙여넣을 때마다 각각의 창을 활성화시키는 구문(WinActivate)을 사용하는 것이 맞나요? 엑셀파일과 한글문서 각각의 좌표(Client)를 입력해주면 잘 인식하는지가 궁금합니다.
프날 Pnal
|
2023년 09월 08일 | ✨
네^^ WinActivate로 활성화 후, Client 좌표로 쓰시면 되겠습니다. ^^
오토핫키린이
|
2023년 08월 30일
선생님, 안녕하세요. Run을 이용해서 특정 엑셀파일을 열려고 하는데, 만약 매일 새로운 엑셀파일이 생성되고 각각의 파일명은 해당일(예:0830, 0831)로 저장한다고 하였을 때 아래 코드처럼 매일 코드(파일명)를 수정하지 않고(0830 → 0831) 사용할 수 있는 방법은 없을까요? F2:: { Run("C:\Users\AAA\Desktop\0830.xlsx") }
프날 Pnal
|
2023년 08월 30일 | ✨
안녕하세요. 현재 날짜를 갖고 있는 내장 변수를 사용하면 되겠네요 ^^ 12강을 참고해보세요. 문자열에 변수를 결합하는 예제가 있습니다.
지나가던코리안
|
2023년 08월 18일
선생님, 정말 감사합니다 (__) 제가 오토핫키의 ㅇ 자도 모르는 상태로 다른 분이 만드신 걸 제 임의대로 수정해서 쓰려고 하던 거다 보니 선생님 입장께선 좀 답답하셨을 수도 있을 것 같은데 친절히 답변해 주셔서 정말 고맙습니다! 덕분에 잘 작동합니다, 정말 고맙습니다!
프날 Pnal
|
2023년 08월 19일 | ✨
감사합니다 ^^
오토핫키뉴비
|
2023년 08월 18일
프날님 강의 감사합니다^^ 오토핫키 사용하다가 잘 안되는 부분이 있어 문의 드려요. 아래 코드에서 F2를 누르면 마우스 클릭 반복하다가 F3을 누르면 잠시 중단하고 또다시 F2를 누르면 마우스 클릭을 반복하는 코드를 짰는데요. 실행하면 잘 안되네요. 무엇이 문제인지 한 번 봐주세요. 감사합니다^^ #SingleInstance force a := 1 F2:: { Loop 10000 { CoordMode("Mouse", "Screen") MouseClick("Left") Sleep(750) if(a = 2) { break } } } F3:: { Foo(&a) } F4:: ExitApp Foo(param) { %param% := 2 }
프날 Pnal
|
2023년 08월 18일 | ✨
안녕하세요. a가 2로 바뀌어 반복을 탈출한 이후에, 다시 F2를 누르면 a가 여전히 2이기 때문에 반복하지 않고 즉시 탈출하겠네요. 이 부분에 진행 문제가 있어보입니다. 추가러 CoordMode는 바깥으로 빼도 될것같고(매 반복마다 Coordmode를 재설정해줄 필요가 없으니까요.) Loop의 1만회 반복 횟수는 무의미(750ms씩 딜레이가 있으니 모두 실행되려면 한세월일 것입니다.)할 것이며 참조를 사용하여 변수의 값을 수정하는 것보다, 이왕 a가 전역 변수이니 global a := 2와 같이 써주는게 더 깔끔할 것 같습니다. 더불어 변수명은 가능하면 유의미하게, stop과 같은 이름이 좋을 것 같습니다. 1과 2를 사용하는 것보다, true, false(1, 0)를 사용하는게 좋겠네요.
오토핫키뉴비
|
2023년 08월 18일
답변 감사합니다^^ 코드는 아래와 같이 수정했어요. 일단 F2로 실행하다가 F3으로 중단시킨 다음, 재실행하려면 F3을 누르고 다시 F2로 눌러서 실행하는 것으로 짰어요. 그보다 좋은 방법은 못 찾겠네요 ㅎ 덕분에 이렇게라도 해결했습니다^^ #SingleInstance force stop := 1 F2:: { CoordMode("Mouse", "Screen") Loop 10000 { MouseClick("Left") Sleep(750) if(stop = -1) break } } F3:: global stop := stop*-1 F4:: ExitApp
프날 Pnal
|
2023년 08월 19일 | ✨
F2를 눌렀을 때 stop := 1을 해주면 매번 재사적시 F3을 누를 필요가 없어서 더 좋을 것 같습니다.
지나가던코리안
|
2023년 08월 16일
계속 질문해서 죄송합니다 ㅠ.ㅠ... IME_Check를 선생님께서 말씀해 주신 대로, EveryHangul의 함수로 바꿨는데, 그것과는 전혀 다른 문제가 발생하는 것 같습니다. ------------------------------------------ Error: Target window not found. Specifically: A 003: hangul := EveryHangul() 006: { ▶ 007: hWnd := WinGetID("A") --------------------------------------------------------- "A"라는 부분이, 아마도 hotkey v1에선 변수...? 로 설정한 것 같은데 V2에선 "A" 이름 그 자체라고 인식하는 것 같습니다... 그래서 A라는 이름을 못 찾는다고 하는 것 같은데, 혹시 이걸 고치려면 어떻게 해야 할까요...?
프날 Pnal
|
2023년 08월 17일 | ✨
006: { ▶ 007: hWnd := WinGetID("A") 지금 이 7번 줄은 기존에 쓰신 IME_Check 함수에 들어있던 구문 아닌가요? EveryHangul의 IsKoreanStatus() 함수는 애초에 쓰신 IME_Check(), Send_ImeControl(), ImmGetDefaultIMEwnd()의 기능이 모두 들어있는 단일 함수입니다. 관련된 함수를 남기실 필요가 없습니다. 기초적인 함수 쓰시는 방법을 아신다면 아래 가이드대로 써보세요... 1. hangul := EveryHangul() 처럼 hangul 변수를 만듭니다. 이 부분은 강좌에 나와있지 않습니다. "EveryHangul()은 함수가 아닙니다!" 2. hangul.IKoreanStatus() 처럼 함수를 호출하면, 이 함수는 0 또는 1을 반환합니다. 3. 이 함수의 반환값은 1은 한글 상태임을, 0은 그렇지 않음을 나타냅니다. 4. 따라서, 이 함수를 이용하면 기존에 적으신 모든 관련 함수를 따로 적으실 필요가 없습니다. 5. 결과적으로 ret := IME_CHECK("A")처럼 한영 상태를 판별하신 후 ret 값에 따라 조건 분기를 하셨는데, 이는 곧 ret := IsKoreanStatus() 로 적는 것과 다를 바 없습니다. 정확히 말씀드립니다. hangul := EveryHangul() 로 적으시는 부분은, 함수의 정의 부분이 아닙니다. 함수도 아닙니다. 다만 쉽게 이해하시려면, hangul 변수 안에 제가 짠 여러 함수가 들어있다고 생각하시면 됩니다. hangul.함수명() 으로 원하는 함수를 쓸 수 있게 만든 것입니다. 그 중에서도 IsKoreanStatus() 라는 함수를 쓰는 것이고요. 지금 적어주신 오류는 제가 말씀드린 함수를 쓰시면 실행될 필요가 없는 hWnd := WinGetID("A") 부분에서 나는 것입니다. 이걸 실행시킬 필요가 없는데 왜 적어주셨나요?
프날 Pnal
|
2023년 08월 17일 | ✨
지금 어떻게 쓰셨는지 모르겠는데, 다시한번 코드를 정확히 써보세요. 그 외에... 1. 쓰신 SetTimer의 주기가 너무 짧습니다. 2. "A"가 WinTitle 매개변수에서 현재 활성 창을 의미한다는 점은 v1과 v2가 같습니다. 표현을 그렇게 하신 것이겠지만 v1에서 변수도 아니었습니다. 이건 답변 요약입니다. 1. IME_Check()를 EveryHangul의 함수로 바꿨는데, 전혀 다른 문제가 발생한게 아닙니다. 처음 질문과 같은 문제입니다. 2. 지금 hWnd := WinGetID("A")에서 오류 메시지가 나오는데, 이것은 EveryHangul에 없는 구문입니다. IME_Check()에 있는 구문입니다. 따라서 처음과 같은 문제입니다. 3. 제가 EveryHangul을 드린 이유는 IME_Check()와 이것이 참조하는 나머지 두 개의 함수를 모두 없애고 EveryHangul 안의 IsKoreanStatus() 함수를 사용하시라고 드린 것이었습니다. 만약 EveryHangul에서 같은 Target window not found 문제가 나올수도 있는데, 그렇다면 result := SendMessage(0x283, 0x5, 0,,"ahk_id " DllCall("imm32\ImmGetDefaultIMEWnd", "Uint", WinExist("A")))이 줄에서 문제가 발생하지, hWnd := WinGetID("A")라는 구문은 사용하지 않으므로 이 줄에서 오류가 나오진 않을 것입니다. 다만 라이브러리란게 실제 구현은 상관 없이 함수명만 알면 쓸 수 있듯이, 실제로 저 줄(인용한 구문)을 보시진 않으셔도 됩니다. 그리고 혹시 우려스러워서 하나 첨언하자면, EveryHangul.ahk 안의 함수를 복사해서 본인 스크립트에 붙여넣는 것이 아닙니다. 스크립트 파일만 #include로 추가한다면 그 안의 함수는 이미 본인 스크립트에 load되어있는 상태인 것입니다. 호출해서 쓰시기만 하면 됩니다. 그러라고 라이브러리가 있는 것이고요.
프날 Pnal
|
2023년 08월 17일 | ✨
추가로. Windows 11 최신 버전에선 IME_Check와 해당 함수(IsKoreanStatus())가 동작하지 않는다는 이슈가 있으니 참고하시길 바랍니다. 제가 직접 확인한 이슈는 아닙니다.
지나가던코리안
|
2023년 08월 14일
#Include EveryHangul.ahk hangul := EveryHangul() ;Create Instance F13:: { MsgBox(hangul.IsKoreanStatus()) } 이렇게 소스를 짜서 실행시키면 0 이라고만 뜨는데 이게 정상적으로 작동되고 있는 건지 잘 모르겠습니다. 이때는 Target window not found 란 메시지는 뜨지 않습니다...
프날 Pnal
|
2023년 08월 15일 | ✨
IsKoreanStatus() 함수는 한글 상태이면 1, 그 외에는 0을 반환합니다. 즉, 가져오신 IME_CHECK() 함수를 대체할 수 있습니다. 만약 영문 상태이고 0이 나온다면 잘 작동하는 것입니다. if (hangul.IsKoreanStatus()) 는 한글 상태일 때를 나타낼 수 있겠죠. (그 반대는 당연히 if (!IsKoreanStatus()) 또는 if (IsKoreanStatus() = 0))
지나가던코리안
|
2023년 08월 13일
제가 어떤 분의 V1버전의 스크립트 코드를 변경해서 쓰려고 고쳐봤는데... 이게 포토샵에서 쓰고 있을 땐 잘 적용이 되는데, 다른 창으로 바꾸면 Error: Target window not found. Specifically: A ▶ 004: hWnd := WinGetID("A") Call stack: *#1 (4) : [WinGetID] hWnd := WinGetID("A") *#1 (4) : [IME_CHECK] hWnd := WinGetID("A") *#1 (33) : [check] ret := IME_CHECK("A") > Timer 이런 오류가 뜨네요... 뭘 고쳐야 할까요...?
지나가던코리안2
|
2023년 08월 13일
IME_CHECK(WinTitle) { hWnd := WinGetID("A") Return Send_ImeControl(ImmGetDefaultIMEWnd(hWnd),0x005,"") } Send_ImeControl(DefaultIMEWnd, wParam, lParam) { DetectSave := A_DetectHiddenWindows DetectHiddenWindows(true) ErrorLevel := SendMessage(0x283, wParam, lParam, , "ahk_id " DefaultIMEWnd) if (DetectSave != A_DetectHiddenWindows) DetectHiddenWindows(DetectSave) return ErrorLevel } ImmGetDefaultIMEWnd(hWnd) { return DllCall("imm32\ImmGetDefaultIMEWnd", "Uint", hWnd, "Uint") } Persistent CoordMode("mouse", "screen") sx := "" sy := "" MouseGetPos(&sx, &sy) SetTimer check, 20 return check() { global sx, sy MouseGetPos(&cx, &cy) if (cx != sx || cy != sy) { ret := IME_CHECK("A") if (ret != 0) { if WinActive("ahk_class Photoshop") { Send("{vk15sc138}") MouseGetPos(&sx, &sy) } else { MouseGetPos(&sx, &sy) } } return } }
프날 Pnal
|
2023년 08월 14일 | ✨
안녕하세요. 한영상태 확인하는 코드네요. 모두의 한글 라이브러리의 IsKoreanStatus() 를 이용해도 같은 오류가 나나요? https://github.com/devPnal/every-hangul-v2
지나가던코리안3
|
2023년 08월 14일
죄송합니다, 제가 만든 게 아니라서 뭘 바꿔야 하는지도 감이 안 잡혀서 그런데 어딜 바꿔서 써야 하는 걸까요...?
프날 Pnal
|
2023년 08월 14일 | ✨
본 강좌의 57강을 참고하여 라이브러리 파일을 추가한 후, 드린 링크의 데모 파일을 참고하여 IsKoreanStatus() 함수를 호출해보세요. MsgBox(인스턴스명.IsKoreanStatus()) 이런식으로 확인해보시면 됩니다. ‘인스턴스명’ 부분은 데모 파일을 참고해주세요. 데모 파일과 같이 hangul := EveryHangul() 과 같이 적었을땐 hangul이 인스턴스 명입니다. 그래도 Target Window not found 오류가 뜨나요?
카리스마
|
2023년 08월 12일
https://www.youtube.com/watch?v=NzmGaiew03k 여기영상에 보면 1버전2버전 같이 설치하던데 설치시 드라이브 위치가 다른지 같은지 모르겠네요?
프날 Pnal
|
2023년 08월 12일 | ✨
같은 경로에 설치하면 v1 경로 아래에 v2 폴더가 생성되며 설치될겁니다. 저는 둘 모두 기본 경로에 설치해서 잘 테스트 했습니다.
트리카이트
|
2023년 08월 07일
안녕하세요 선생님,우선 좋은강의 무료로 나눠주셔서 진심으로 감사드립니다. 개인적인 용도로 활용하기 위해 열심히 공부중입니다. 하나 궁금한 점이 controlclick을 이용할때, 너무 빠르게 클릭이 이동합니다. sleep말고 전반적으로 코딩한 오토핫키의 진행 속도를 천천히 움직이게 할수있을까요?
프날 Pnal
|
2023년 08월 08일 | ✨
안녕하세요. SetControlDelay를 알아보세요. 스크립트에 쓰인 ControlClick의 속도를 늦춥니다.
네단뵬
|
2023년 08월 01일
안녕하세요. 오토핫키 사용 중 참고 많이 하고 있습니다. 혹시 ClassNN이 따로 정의되지 않는 창의 내용물도 제어하는 방법이 있을까요? 랩뷰로 만든 프로그램이 있는데, 'Window Spy'로 확인을 해도 ClassNN이 특정되지 않으며, Window Text에도 내용이 없습니다. (참고 스크린샷 : https://i.imgur.com/RTTLUqT.png) 웹 브라우저인 Chrome 등도 탭이라든지 각종 버튼이 특정되지 않습니다. 오토핫키를 통해서 (오토핫키로 만든 GUI에서처럼) 해당 창의 모든 정보에 접근하고 입력신호를 보낼 수 있는 방법이 있을까요? (마우스나 키보드 조작 제외)
프날 Pnal
|
2023년 08월 01일 | ✨
안녕하세요. 강좌에 있는 대로 고정좌표를 이용하지 않으면 불가능합니다. ControlSend로 제어가 가능하면 이를 이용하시고요, ControlClick도 죄표로 클릭이 가능하니(강좌참고) 이를 이용해도 됩니다.
정각
|
2023년 07월 25일
안녕하세요? 좋은 강좌 만들어 주셔서 감사합니다. AHK v2 에서 혹시 정시 (예를 들어 12:00:00 정각) 에 루프를 탈출하는 함수나 구문을 혹시 만들 수 있나요? v1 에선 checktime 이라는 게 있었던 것 같은데 v2 에선 없는 것 같고 a_now 를 써도 이걸 어떻게 써야 되는지 잘 모르겠어요.. Loop { if(a_time>=20230707120000) break sleep(10) } mouseclick("left", 100, 100) 이런 코드는 작동이 안 되더라구요.. 혹시 알고 계시면 좀 가르쳐 주세요. 감사합니다!
프날 Pnal
|
2023년 07월 25일 | ✨
안녕하세요. 그런 식으로 구현하시면 됩니다. 다만 A_Time이라는 내장변수는 없습니다. 강좌를 다시 한 번 살펴보세요.
정각
|
2023년 07월 25일
Loop { if(a_now>=20230725120000) break sleep(10) } mouseclick("left", 100,100) 이렇게 해보니까 되네요 감사합니다! 정말 많은 도움 받고 있습니다.
웃는남자
|
2023년 07월 24일
안녕하세요 https://github.com/Genymobile/scrcpy scrcpy 에서는 ControlClick키 작동안하는듯 합니다. 혹시 다른 방법이 있을까요?
프날 Pnal
|
2023년 07월 24일 | ✨
안녕하세요. ControlClick 강좌 끝자락에서 살짝 언급한 것처럼, 다른 프로그램과 상호작용 하는 경우 해당 프로그램의 구현 방식에 따라 상호작용이 되지 않을 수 있습니다. 이러한 원인은 프로그램마다 다르고 실제 해결하기 위해선 여러 시도를 해봐야 합니다. 이를 제가 전부 실험해보고 알려드릴 순 없습니다. 결국 질문자님이 다른 방식으로 구현하시든 다른 방법이나 원인을 찾으시든 하셔야 합니다. 전통적인 Win32 프로그램이 아니면 Control 계열 명령어는 의도한 동작이 되지 않을 가능성이 높습니다. 다만 다른 프로그램에 신호를 직접 전송하기 때문에, 대상 프로그램의 권한보다 신호를 전송하는 프로그램(이 경우엔 만드신 오토핫키 스크립트의 실행체)의 권한이 낮으면 안됩니다. 따라서 스크립트를 관리자 권한으로 실행해보시러는게 가장 일반적이고 제가 말씀드릴 수 있는 최대한의 해결책입니다.
17강관련
|
2023년 07월 23일
17강 종합프로그래밍 문제에서 마지막 분관련 몫 도출관련하여 //과 //=의 차이가 무엇인지 궁금합니다. 결론적으로 //만 사용하는 것이 옳바른 결과를 도출하긴 하는데 //=과 어떤 차이가 있는지 궁금합니다. 강의 잘 듣고 있습니다. 감사합니다.
lightright
|
2023년 07월 24일
+(//) 와 +=(//=) 차이 아닐까용?
프날 Pnal
|
2023년 07월 24일 | ✨
안녕하세요. //=는 복합 대입 연산자로서, 연산자의 오른쪽에 있는 값을 왼쪽의 변수에 나눈 후 대입하는 역할을 합니다. 반면 //는 대입을 하지 않고 연산만 합니다. 따라서 아래 두 코드는 같습니다.var //= 10
var := var // 10
둘 모두 현재 변수의 값에 10을 나누는 코드입니다. 윗분이 말씀하신 것처럼 +와 +=의 차이와 같습니다. 14강 강좌를 참고해보세요.
brendan
|
2023년 07월 20일
안녕하세요. V1을 사용하다가 윈도우 포맷 후 V2를 설치했는데 기존 오토핫키 파일들이 정상 작동하지 않는 문제가 있었습니다. 예전에 컴파일해 놓은 exe 파일은 작동이 되어 그냥 썼었는데, 수정이 필요해서 scite에서 수정 후 실행하면 실행되지 않고 바로 에러가 발생했었습니다. 지금은 프로그램을 삭제하고 다시 V1을 설치해 사용중입니다. 혹시 저처럼 V1으로 작성한 파일을 V2에서 사용하고자 할 경우, 호환성 문제를 피하기 위해 '주요하게' 살펴봐야 할 것들이 있다면 알려 주시기 바랍니다. 오래 전에 이 오류가 발생했을 때 문의를 드렸었는데, 해당 오류에 대해서는 해법을 찾지 못 했었습니다. 기존 V1 파일의 어떤 부분에서 호환성 문제가 주로 생기는지 혹시 정리된 글이 있으면 도움 부탁드립니다. 감사합니다.
프날 Pnal
|
2023년 07월 20일 | ✨
안녕하세요. v2와 v1은 문법적으로 전혀 다르기 때문에, 하나부터 열까지 호환이 되지 않습니다. v1은 명령어 기반이기에 명령어와 매개변수 사이를 콤마로 구분했지만 v2는 함수 기반이라서 괄호를 이용합니다. v1에서 사용하는 함수의 매개변수도 v2에선 종류와 순서, 방식이 다를 수 있습니다. v1에서 핫키는 블록 처리를 해주지 않았지만 v2는 해줘야만 하며, GUI는 객체화되어 기본적인 생성부터 이벤트 연결까지 전부 바뀌었습니다. v1 스크립트를 v2 인터프리터로 작동시키기 위해... 약간 수정해서, 또는 주요한 부분만 확인해서 해결되는 정도의 호환성 문제가 아닙니다. 완전히 다른 문법을 가졌기에 스크립트를 새로 짜셔야할 부분입니다. 제가 알기로 v1과 v2를 동시에 설치하면 SciTE가 스크립트를 분석하여 v1에선 v1 인터프리터를, v2 스크립트는 v2 인터프리터를 작동시켜 주는 것으로 알고있습니다. 기존에 v1으로 만든 스크립트는 오토핫키 v1에서 유지보수 하시는 것을 추천드립니다. (저는 현재 v1을 설치하지 않았기 때문에, v1과 v2를 동시 설치해서 쓰고있진 않고있습니다.) v1과 v2를 동시에 설치하신 경우 v1을 먼저 설치하신 후 v2를 설치하셔야 할 것이며, 공식 도움말의 Using the program > Launcher와 그 밑부분을 쭉 참조해보시길 바랍니다. 각 스크립트를 컴파일할땐 우클릭 메뉴를 이용하지 말고, Ahk2Exe GUI를 사용해야할 것입니다.
UnsealedWiener
|
2023년 07월 16일
안녕하세요! 혹시 l::Right 과 l::Send "{Right}" 이 둘의 차이가 어떤 것인지 알려주실 수 있을까요? 테스트를 좀 해보니까 Alt+Tab키로 Task Switcher 킨 다음에 l키로 움직여 보려구 했는데 l::Right는 작동하는 반면 l::Send "{Right}"는 작동하지 않더라구요. 어떤 이유에서 그런 것인지 궁금합니다!
프날 Pnal
|
2023년 07월 17일 | ✨
안녕하세요. a::b 형식의 코드는 핫키라기보다 Remapping key 기능에 가깝습니다. a::b로 작성한 코드는 실행시에 적절한 핫키 코드로 대체되어 취급된다는 차이가 있습니다. 어떤 키를 리매핑 하더라도 잘 동작할 수 있게 a::b에 따라서 다르게 핫키 구문으로 변환되는 것으로 알고 있습니다. 예를 들어서, a키를 b키로 리매핑하는 a::b 구문은 실행시에 아래와 같은 구문으로 변환되어 실행됩니다. *a:: { SetKeyDelay -1 Send "{Blind}{b DownR}" } *a up:: { SetKeyDelay -1 Send "{Blind}{b Up}" }단순히 a::Send "b"랑 동치는 아닌 것입니다. 결국 키를 리매핑하기 위해선 I::Right로 쓰는 것이 좋습니다. 실제 작동하기 위해 적어준 키를 이런저런 코드로 알아서 변환해주기 때문입니다. 공식 도움말의 Remarks도 참고해보세요 ^^ https://www.autohotkey.com/docs/v2/misc/Remap.htm#remarks (When a script is launched 부터)
프날 Pnal
|
2023년 07월 17일 | ✨
아, 참고로 Alt Tab키로 윈도우 스위처를 켰을 때 I:: 핫키가 작동되지 않았던 제일 첫번째 이유는, 이미 작성자님이 Alt키를 키보드에서 누르고 있기 때문입니다. 핫키는 강좌에 나온대로 !I::나 *I::로 수식어를 붙여야 겠죠?
UnsealedWiener
|
2023년 07월 18일
안녕하세요! Remmapping Key이라는 암시적으로 해주는 부분이 존재했군요. 계속 고민하다가 결국 아래와 같이 처리하게 되었네요. 도움이 많이 되었어요. 감사합니다. GroupAdd "AltTabWindow", "ahk_class MultitaskingViewFrame" ;Window 10 GroupAdd "AltTabWindow", "ahk_class XamlExplorerHostIslandWindow" ;Window 11 #HotIf WinExist("ahk_group AltTabWindow") !j::!Left !k::!Down !l::!Right !i::!Up #HotIf !j::Left !k::Down !l::Right !i::Up
ㅇㅇ
|
2023년 06월 27일
마우스 추가키를 핫키로 지정하려면 어떻게 해야 될까요? 예를 들어 LButton:: 을 사용하면 좌클릭이 핫키가 되는데 추가키를 지칭하는 X1을 X1Button:: 으로 하면 실행이 안되는데 어떻게 해야될까요? 강의 잘 보고 있습니다 감사합니다
프날 Pnal
|
2023년 06월 27일 | ✨
안녕하세요. Xbutton1, Xbutton2 입니다. ^^
강좌에있는 비디오
|
2023년 06월 23일
41강 44강 영상이 이미지 인것처럼 클릭해도 반응이없는데 아직 영상은 없는건가요?
프날 Pnal
|
2023년 06월 23일 | ✨
넵... 아직 없습니다. Part 3 강좌를 올릴 때 같이 올릴 예정입니다.
오타인가요?
|
2023년 06월 21일
16강 프로그래밍 문제에서 문제 1. 다음 보기 중 옳지 않은 내용을 있는대로 고르세요. ㄹ 100 != "text"의 값은 0이다. 답: ㄴ, ㄷ ㄱ. 대입 연산자 :=를 사용한다. 따라서 옳은 문항. ㄴ. .= 연산자는 값을 뒤에 이어서 대입하므로 33이 된다. 따라서 틀린 문항. ㄷ. 1이 3보다 크다는 것은 거짓된 식이므로 0의 값을 가진다. 따라서 틀린 문항. ㄹ. 100은 문자열 text와 다르다는 것은 참된 식이므로 1의 값을 가진다. 따라서 옳은 문항 ㄹ은 틀린 문항 아닌가요?
프날 Pnal
|
2023년 06월 22일 | ✨
안녕하세요. 100 != "text"의 값은 1입니다. 따라서, '식의 값은 0이다' 라는 문장은 틀린 문장이 되겠습니다. 제 잘못입니다 ^^ ㅠㅠ 이번주 내로 보기를 “식의 값은 1이다”로 수정하겠습니다.
관리자권한으로 실행
|
2023년 06월 21일
관리자 권한으로 실행시키려고하는데 runas 라는게 있는거같은데 혹시 어떻게 사용하는지 예를 들어주실수있나요...
프날 Pnal
|
2023년 06월 21일 | ✨
안녕하세요. 여기를 참고해보세요,
얌얌
|
2023년 06월 21일
2. F1 블럭 코드가 실행중일때, 도중에 F2키를 눌러 F1블럭의 코드에 개입하는 방법 아래와 같이 F1::키를 눌렀을때, 블럭 내부의 내용들을 5회 반복하는 코드가 있습니다. 블럭 내부의 코드들을 전부 처리하는데에는 대략 10초가 소요되므로, 5번 반복하는데에는 대략 50초가 소요됩니다. F1:: { Loop 5 { ;반복할 내용들 } } 그런데, 해당 코드가 작동하여 반복문이 실행 중일때, 5번이 아닌 6번(혹은 그 이상으로도)반복하게 하고 싶어졌습니다. 그래서, F1::의 코드가 실행중인 중간에, F2를 누르면 반복문의 Loop횟수가 1회 더 추가되도록 하려고 합니다. 이런 경우, 코드를 어떤 방식으로 작성해야 하는지 간단한 도움말을 주실 수 있을까요?
프날 Pnal
|
2023년 06월 21일 | ✨
안녕하세요. Loop에 5회 제한을 빼시고, 내부에서 if문으로 반복횟수가 5일때 Break되게 해보세요. 그 다음, F2블록에서 전역변수 flag(임의의 변수명입니다)의 값을 true로 바꿔봅시다. 다시 F1 블록의 조건문에선, 조건을 반복횟수가 5일때가 아니라, ”반복횟수가 5이면서 flag가 false이거나, 반복횟수가 6일때“로 조건을 수정해보세요. 설명이 어렵네요. 순차적으로 따라해보세요. 혹은 그냥 변수의 값만큼 반복중일 때(즉 Loop 안의 조건이 if (A_index = n)일 때,) 변수(n)의 값을 F2블록에서 늘려도 됩니다. 당연히 전역변수여야겠죠.
얌얌
|
2023년 06월 22일
답변 내용 감사드립니다..!!
얌얌
|
2023년 06월 21일
안녕하세요. 최근에 오토핫키 코드를 작성하면서 느낀 어려움을 위주로 질문드리려고 합니다. 1. 웹 사이트에서 사용하는 아이콘에 대한 이미지 서치 웹 사이트에서 특정 아이콘을 이미지서치하여 클릭하는 코드를 작성했을 때, 이 코드가 작동하는 경우가 있고, 작동하지 않는 경우가 있습니다. 예를 들어, 이름 [김철수]를 클릭했을때 나오는 '+' 아이콘, '다운로드' 아이콘, '닫기' 아이콘 중 + 아이콘을 이미지서치하여 클릭하는 코드가 잘 작동할때, 해당 코드가 [김영희]에서도 잘 작동하지만 [홍길동]에서는 잘 작동하지 않는 식입니다. 코드를 쪼개 살펴보니, [김철수]와 [김영희] 페이지에서는 해당 이미지를 잘 찾지만, [홍길동]에서는 찾지 못하더라구요. 세 페이지 모두 병렬적이고, 똑같이 생겼는데 말입니다. 이런 경우는 사이트에서 사용하는 아이콘이 눈으로는 감지 못하도록 미세하게 다른건지, 아니면 뭔가 다른 문제가 있는건지 궁금합니다. 이 문제를 해결하기 위해 이미지서치 코드에 *n을 넣어 수치를 조정해봤지만 해결되지 않았고, [홍길동] 페이지의 +아이콘의 이미지를 따서 코드에 추가해보았지만, 또다른 [이건희] 페이지에서는 이미 따둔 + 아이콘들과는 또 다르더라구요. 이럴때는 어떻게 해결하시는지 궁금합니다. (이런 경험이 한두번도 아니고, 국내 국외 가릴것 없어 웹페이지에서 빈번하게 일어납니다 ㅜ)
프날 Pnal
|
2023년 06월 21일 | ✨
안녕하세요. 웹브라우저의 렌더링 방식에 따라 실제 다르게 아이콘이 렌더링될 수 있습니다. 그래서 아이콘 이미지가 미세하게 서로 다를 수 있고요... 애초에 ImageSearch 자체가 말씀하신 문제가 있다보니 저는 최대한 안쓰고 있습니다. 이미지서치는 강좌에 나온대로, 어느 위치에 이미지가 뜰지 모르는 상황에서 사용하면 적합합니다. 고정된 위치에 아이콘이 나오거나, 특정 픽셀 기준으로 성대적으로 같은 위치관계에 있는 아이콘의 경우 PixelGetColor나 PixelSearch를 쓰는 것이 좋습니다. ImageSearch를 쓰면서 해결하시려면 문제가 되는 아이콘 이미지를 다시 캡처해서 이미지서치를 두 번 수행할 순 있습니다. 이렇게 하면, 두 경우 모두 인식되지 않는 [김아무개]의 페이지의 아이콘이 있다면 대응할 수 없습니다. 또 이미지를 따서 세 이미지 모두에 이미지서치를 하셔야하니까요. 가장 좋은 방법은 웹에서 사용할 수 있는 별도의 자동화 기술(DOM제어, HTTP Request, Selenium 등)을 사용하는거고요, 이것이 힘들 경우 고정좌표나 PixelGetColor 둥을 사용하시는게 차선, 최악은 이미지서치입니다.
gui 질문
|
2023년 06월 20일
혹시 gui질문도 받아주시나여? 옛날 v1 에선 g레이블로 gbtn 을 이용해서 버튼을 이런식으로 썻다면 btn: msgbox, 누름 v2에서는 어떤식으로 써야하나요 MyGui.Add("Button", " x12 y50 w210 h2" , "확인") 버튼을 만드는것 까진 했는데...
프날 Pnal
|
2023년 06월 20일 | ✨
안녕하세요. 여기 답글을 보시면 간단한 코드가 있습니다. 맨 마지막 답글에 그 당시 질문자님이 적으신 코드네요. 이를 참고하시면 될 것 같습니다. 제가 짠 코드를 보시려면, 48강의 예제 프로그램 코드를 봐보세요.
gui 질문
|
2023년 06월 20일
감사합니다!
쿠우
|
2023년 06월 14일
안녕하세요 프날님. 오토핫키V1 때는 잘 작동하던 명령들이 V2 로 넘어와서는 에러로 작동이 되지않습니다. 예시로 ●예시1번 !1:: { Send, {Left} Send, {Left} sleep, 50 Send, {Left} Send, {Up} sleep, 50 Send, {F2} Send, +{Home} sleep, 50 Send, ^C Send, {Enter} sleep, 50 Send, {Down} Send, {Right} sleep, 50 Send, {Right} Send, {Right} sleep, 50 Send, {Delete} sleep, 50 Send, ^v Send, {Enter} Send, {Down} } return 기존에 V1에서는 작동되었는데 V2에서 컴파일스크립트로 변환을 하게되면 에러가 뜨면서 실행파일로 변환이 되지않는데 원인이 무엇인지를 도무지 알 수가 없습니다... 또 하나 ●예시2번 F12:: Loop 3 { Send("{Enter}") Send("{a 10}") Send("^{a}") Send("^{c}") Send("^{v}") } 여기서 Loop 3 을 빼면 잘 작동하는데 Loop 3 을 넣는순간 에러가 뜨는데 이유를 알 수 없습니다... 무엇이 문제인지 방법을 알 수 있을까요?
프날 Pnal
|
2023년 06월 14일 | ✨
안녕하세요. 뭐든 에러가 나면 무슨 에러인지 알아야 해결을 할 수 있습니다 일단, 첫번째 스크립트의 경우 v1 문법이기에 v2에서 컴파일 및 정상 실행될 수 없을 것이구요... 두번째 스크립트는 v2에서 핫키는 블록으로 그 범위를 지정해주어야합니다. 참고: https://ahkv2.pnal.dev/19
lightright
|
2023년 06월 12일
안녕하세요 프날님 혹시 버튼으로 실행하는 함수와 핫키로 실행하는 함수를 하나로 하는 방법이 있을지 문의드립니다. 예를들어 "1" 이라는 버튼을 입력했을때 1번창을 활성화하는 코드가 있습니다. mainGui.Add("Button", x10 y10 h50 w100", "1").onEvent("Click", activatewindow ) activatewindow( obj, * ) { winactivate(id[obj.text]) } 그리고 핫키를 눌렀을때 창을 활성화하는 코드가 있습니다. hotkey "1", WinActivateHotKey WinActivateHotKey(thisHotkey) { winactivate(id[thisHotkey]) } id 에는 프로그램의 id가 리스트 형태로 들어있습니다. 제가 하고 싶은건 저 두 함수를 하나로 만들수도 있을꺼같은데 생각이 나질 않습니다. 방법이 있을까요?
프날 Pnal
|
2023년 06월 13일 | ✨
안녕하세요. 한 함수에 매개변수로 obj 혹은 A_ThisHotkey를 받아서, 만약 IsObject(매개변수)가 true면 객체가 들어온 것이므로 id[obj.text] 를, false면 문자열(핫키)이 들어온 것이므로 id[매개변수]를 넣어줄 수 있도록 조건문을 구성하시면 될 것 같습니다. 핫키 등록 코드에 호출하는 함수를 버튼 이벤트 처리 함수로 해보신 후 위와 같이 처리해보세요.
lightright
|
2023년 06월 14일
뭔가 이해가 될듯하면서 이해가 되질 않네요 ㅠㅠ
프날 Pnal
|
2023년 06월 14일 | ✨
안녕하세요. Foo(param) 함수를 호출할 때 배열을 넣어서, 그리고 일반 문자열을 넣어서 함수 안에서 IsObject(param)의 값을 비교해보세요. 이를 통해서 버튼으로 클릭한건지, 핫키로 누른건지 구분할 수 있습니다. 함수 안에서 id[] 배열 안에 달리 구분해서 넣어야하는 것은, 이 차이로 조건문으로 구분해서 넣을 수 있습니다. 이를 이용해보세요.
lightright
|
2023년 06월 10일
안녕하세요 프날님 Gui 에서 변수에 Gui를 넣고 활용하는 방법에 대해서 궁금하게 있습니다. 예를 들어 버튼을 만들고 그 버튼을 변수에 넣습니다. example := mainGui.Add("Buuton", x10 y20 w50 h40", "테스트").onEvent("Click", test ) example2 := mainGui.Add("Buuton", x10 y20 w50 h40", "테스트2").onEvent("Click", test ) example3 := mainGui.Add("Buuton", x10 y20 w50 h40", "테스트3").onEvent("Click", test ) 이런식으로 Gui를 만들었을때 test ( obj, * ) { swich (obj.Name) { case example : 실행함수 case example2 : 실행함수 case example3 : 실행함수 } } 이런식으로 Gui에서 담은 변수이름에 따라 케이스를 정하고 함수를 실행하고 싶은데 msgBox( obj.Name ) 을 해보면 정보가 담겨있지 않습니다. 이럴경우에는 Gui내에 변수를 넣어서 사용해야하는건지 궁금합니다. mainGui.Add("Buuton", x10 y20 w50 h40 vexample", "테스트").onEvent("Click", test ) 이런식으로 말이죠
프날 Pnal
|
2023년 06월 10일 | ✨
안녕하세요. 네 그러셔도 되고, obj.ClassNN 에도 고유의 값이 담겨있을 것입니다. 참고로, 아래와 같이 쓰신 형태인데, 이 경우엔 var는 유의미하게 활용할 수 없을 것입니다.var := Gui.Add().OnEvent()왜냐하면 원래 저런식으로 변수에 담는 이유가 컨트롤 객체를 변수에 담기 위함인데, 지금 쓰신건 마지막에 OnEvent() 의 반환값을 담는 모양새가 되기 때문입니다. 그래서 "예를 들어 버튼을 만들고 그 버튼을 변수에 넣습니다" 라고 하셨는데, 실제로는 버튼 컨트롤 객체가 담긴게 아니라 아무 값도 담겨있지 않을 것입니다. Gui.Add() 의 반환값은 컨트롤 객체이기 때문에 원래 var := Gui.Add() 식으로는 쓸 수 있습니다. 그러나 OnEvent()는 아무 것도 반환하지 않기 때문에, var := Gui.Add().OnEvent() 의 형태로썬 var 변수가 무의미합니다. 만약 var에 컨트롤 객체가 담겨있다면, 이벤트 처리 함수 내에서 var.Hwnd와 obj.Hwnd를 비교하거나, var.ClassNN과 obj.ClassNN을 비교할 수 있습니다.
lightright
|
2023년 06월 10일
답변 감사합니다 프날님 제가 이해한바로는 example := mainGui.Add("Button", x10 y20 w50 h40", "테스트") 까지만 썻을때는 obj.name 을 쓸수 있겠지만 .onEvent 를 쓰면 못쓴다는 이야기시군요! 하지만 .onEvent 를 사용했을때는 obj.ClassNN 을 사용해서 고유값을 반환받아서 사용가능하다는 말씀이시군요! example := mainGui.Add("Button", x10 y20 w50 h40", "테스트").onEvent("Click", test ) 으로는 obj.name 을 사용할수 없구요
시작
|
2023년 06월 09일
안녕하세요 스크립트파일을 우클릭했을 때 오토핫키 관련 메뉴가 나오지않습니다ㅠ Ahk2Exe를 켜서 스크립트 파일을 추가하고나면 우클릭시에 관련 메뉴가 나오지만 스크립트파일을 한번 수정하고 나면 또 나오지 않습니다. 재설치를 해봐도 같은 문제가 계속되는데 혹시 해결방법이 있을까요?
프날 Pnal
|
2023년 06월 09일 | ✨
안녕하세요. 3강에 나온대로, SciTE4AutoHotkey 설치 시 체크박스를 모두 해제하셨나요? 해당 체크박스를 체크 하신 상태로 사용하면 우클릭 시 오토핫키 메뉴가 나오지 않습니다.
시작
|
2023년 06월 09일
네 모두 해체하고 계속 재설치를 해봐도 위에 글같은 현상이 발생합니다.
프날 Pnal
|
2023년 06월 09일 | ✨
안녕하세요. 공식 도움말에 관련 내용이 있긴 한데, 한번 참고해보세요. PC 환경에 따라 다를 수 있어서 제가 어떻게 해결법을 알진 못합니다 ㅠㅠ
시작
|
2023년 06월 09일
네 감사합니다! 혹시 해결이 안되더라도 조금 불편할 뿐이니까.. 괜찮습니다!
프날 Pnal
|
2023년 06월 10일 | ✨
안녕하세요. 문득 든 생각인데, 연결 프로그램이 SciTE 말고 오토핫키로 되어있어야 합니다. 즉, 스크립트 파일의 아이콘이 '검은 줄무니 원형 배경에 초록색 H 마크' 가 아니라, '하늘색 문서 모양 배경에 보라색 H 마크' 여야 합니다. 윈도우 10 기준 스크립트 파일 우클릭 > 연결 프로그램 > 다른 앱 선택 > "항상 이 앱을 사용하여 .ahk 파일 열기" 선택 후 "AutoHotkey" 로 선택해보세요.
array
|
2023년 06월 05일
안녕하세요 MouseGetPos 함수는 매개변수를 참조로 전달하게 되어있는데요 그 자리에 배열을 넣으려고 했더니 오류가 나네요 MouseGetPos(&foo[2], &bar[2])로 하면 ==> "&" requires a variable. MouseGetPos(foo[2], bar[2])로 하면 런타임에서 Parameter #1 of MouseGetPos requires a VarRef, but received an Integer 라고 뜹니다
프날 Pnal
|
2023년 06월 05일 | ✨
안녕하세요. 배열(및 모든 객체)은 매개변수 전달 시 자동으로 ‘참조에 의한 호출’이 일어나기 때문에, 참조를 전달하겠다고 굳이 & 기호를 전달해주지 않아도 됩니다. 다만 이건 배열 자체를 넘길때의 이야기로... 지금은 예시에서 [] 연산자를 활용해서 배열이 아닌 다른 primitive 값을 전달해준 상황입니다. (배열안에 다른 변수의 참조형식이 들어있는 모양은 논외로 함) 그래서... 1. &arr[1] 형태는 &(값) 형태이기 때문에 성립할 수 없는 구문입니다. 2. arr[1] 형태는 그냥 쌩 값만 전달했기 때문에 함수가 요구하는 인수 형식과 맞지 않습니다. 결론적으로 그 자리에 배열을 넣지 못합니다. 애초에 그 함수의 매개변수론 변수의 참조가 오는 것을 가정하고 만들어졌기 때문입니다. 더 정확하게는, 현재 오토핫키에서는 객체의 속성(=멤버 변수, 필드)에 대해 참조 형식을 만들 수 없습니다. 오토핫키에서 배열은 객체인데요, 배열의 요소는 객체의 속성에 대응됩니다. 즉, &foo.bar 나 &foo[1] 형태의 사용이 불가능하다는 것입니다. 이는 공식 문서의 ByRef parameters 부분의 known limitation에 적혀있습니다. It is not possible to construct a VarRef for a property of an object그냥 평범한 변수를 이용해서 값을 받은 후, 아랫줄에서 배열에 값을 담는 게 나아보입니다.
ㅇㅇ
|
2023년 06월 05일
바로 답변해주셔서 감사합니다!
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) { 함수() } 가 되겠군요! 역시 프날님의 깔끔하신 가르침덕분에 오늘도 기분이 좋아졌습니다!