이곳에 글을 쓰면 개인정보 처리방침과 아래의 댓글 관리 정책에 동의하는 것으로 간주됩니다.
실제 허용 여부를 막론하고 모든 게임에 관한 질문은 받지 않습니다.
프로그래밍과 관련이 없는 댓글은 삭제될 수 있습니다.
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)
}
}
도 해봤는데 에러만 날뿐입니다.
혹시 프날님이시라면 어떻게 하실지 여쭤봐도 될런지요 ㅠ
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로 코드를 할껀지만 선택하면 문제 없을까요??
둘다 설치했다가 오류날까봐 무섭습니다
프날님 오늘도 질문있습니다!
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()
}
이런식으로 사용하면 될지 아니면 더 간단한 방법이 있을지 프날님의 평가 부탁드리겠습니다!
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)
{
함수 호출()
}
이렇게 될 것입니다.
댓글창은 세로 크기조정을 추가하겠습니다. 그 외에도 대댓글끼리 구분이 잘 안되네요. 이도 조정을 해야겠습니다.
질문 및 답변
이곳에 글을 쓰면 개인정보 처리방침과 아래의 댓글 관리 정책에 동의하는 것으로 간주됩니다.