FindWindow를 사용해 보자 - NSIS

프로그래밍/NSIS 2007/02/08 10:06 게으른 엔지니어
인스톨러를 만들때 좀 자유롭게 인스톨러 화면을 바꾸고자 할때 주로 사용하는 함수가 바로 FindWindow와 SendMessage 이다. FindWindow는 화면상에서 바꿀려고 하는 아이템의 핸들을 받아 올때 사용하고, SendMessage는 아이템에 실제로 바꾸고자 하는 내용을 전달하는 함수 이다. 윈도우용 프로그램을 해보았다면, 아마 사용해본 함수들일 것이다. 윈도우용 함수와 거의 똑같은 용도로 사용하므로 친숙할 것이다. 예제 파일들을 보다 보면 자주 보이는 함수들이므로 여기서 한번 정리하고 가도록 하자

일단 메뉴얼에 어떻게 적혀 있는지 확인부터 해보자

4.9.14.5 FindWindow

user_var(hwnd output) windowclass [windowtitle] [windowparent] [childafter]

Searches for a window. Behaves like the win32 FindWindowEx(). Searches by windowclass (and/or windowtitle if specified). If windowparent or childafter are specified, the search will be restricted as such. If windowclass or windowtitle is specified as "", they will not be used for the search. If the window is not found, the user variable returned is 0. To accomplish old-style FindWindow behavior, use FindWindow with SendMessage.

[code]FindWindow $0 "#32770" "" $HWNDPARENT
FindWindow $0 "my window class" "my window title"[/code]
위의 설명을 보면 내용은 간다하다. 즉 FindWindow 다음에 있는 변수에 윈도우 클래스를 적어 주면 찾아서 그 핸들을 넘겨 준다고 생각하면 된다. 만약에 찾는 윈도우 클래스가 없으면 유저 변수에 0이 저장된다. 실제 작동하는 코드를 가지고 생각해 보자.

[code]# set the name of the installer
outfile "FindWindow"

!include WinMessages.nsh


; Kill all instances of Internet Explorer
Function .onInit
;Finding all IE Windows
loop:
    FindWindow $0 "IEFrame"
    IntCmp $0 0 done
    IsWindow $0 0 done
    MessageBox MB_YESNO $0 IDYES close_window IDNO sleep

close_window:
    System::Call 'user32::PostMessageA(i,i,i,i) i($0,${WM_CLOSE},0,0)'

sleep:
    Sleep 100
    Goto loop
done:
FunctionEnd

# create a default section.
section

sectionEnd[/code]

4 : WinMessages.nsh 를 포함시키는 것은 17번째줄에서 사용하는 WM_CLOSE 메시지 때문이다.
8 ~ 23 : .onInit 함수이므로 실제로 인스톨 화면을 보여 주기 전에 실행되는 callback이다. 앞에 포스팅 된 글을 참고 하기 바란다.
11 : FindWindow로 윈도우 클래스가 IEFrame 인 윈도우를 찾아서 그 핸들을 $0 에 저장하는 것이다. 앞에 포스팅 된 글에서 언급했듯이 $0는 미리 지정된 유저가 사용할 수 있는 변수이다.
12 : IntCmp1 는 첫 번째 인수와 두 번째 인수를 정수값으로 비교하는 명령어 이다. 문자열 비교는 StrCmp를 쓰게 된다. 여기서는 $0가 0이면 done으로 가라는 명령이므로 만약 IE를 찾지 못했을 경우 done으로 가라는 명령이다.
13 : IsWindow2는 첫 번째 인수로 받은 핸들이 윈도우인 경우 바로 다음줄로 가고 아닌 경우 done 레이블로 가라는 뜻이다.
14 : MessageBox에서 "Yes" 버튼을 클릭하면 close_window 레이블로 가고 "No" 버튼을 클릭하면 sleep 레이블로 가게 된다.
17 : 실제로 받은 핸들에 WM_CLOSE 메시지를 보낸다. 즉 위에서 찾은 핸들을 close 하도록 한다. 여기는 할 말이 아주 많으므로 다음에 한번 정리 하도록 하겠다.
20 : 밀리 초 단위로 잠시 연기 하는 명령어 이다. 즉 100 밀리 초 이므로 0.1초 동안 잠시 연기 했다가 그 다음 명령어로 넘어 가게 된다.

위의 코드는 실제로 한번 인스톨한 프로그램을 다시 인스톨할때 만약 인스톨할려는 프로그램이 실행중이면 실행을 닫아야 하므로 상당히 유용한 코드이다. 실제 function 부분은 NSIS 공식 싸이트에서 발췌한 내용이다.

위와 같이 FindWindow를 사용할려고 하면 문제가 되는 부분이 윈도우 클래스를 알아 내는 부분이다. 이 부분을 알아 내기 위한 프로그램이 있는데3 Win32Spy 이다. freeware라서 편의를 위해서 여기에 같이 첨부하겠다.4파일 크기가 아주 작고 인스톨할 필요도 없는 편리한 프로그램 같다. 사실 아직 내가 직접 써보지는 않았다.

적다 보니 내용이 길어 지는 듯해서 여기서 그만 끊고, SendMessage는 다음 포스팅에서 설명하도록 하겠다.
크리에이티브 커먼즈 라이센스
Creative Commons License
  1. IntCmp $0 5 is5 lessthan5 morethan5 와 같이 사용할 경우 $0에 저장된 값과 5를 비교하여 같을 경우 is5로 가고, $0가 5보다 작을 경우 lessthan5로 $0가 5보다 큰 경우 morethan5로 가라는 명령이다. [Back]
  2. IsWindow $0 0 +3 와 같은 경우 $0에 저장된 핸들이 윈도우인 경우 바로 다음줄로 가고 윈도우가 아닌 경우 3번째 명령어로 가라는 뜻이다. [Back]
  3. 이 역시 NSIS에 나와 있는 부분이다. [Back]
  4. 파일 첨부 방법을 몰라서 일단은 첨부하지 않고, 알아 내는데로 여기에 첨부하겠다. T.g [Back]
이올린에 북마크하기(0) 이올린에 추천하기(0)
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.cipher.pe.kr/tt/cipher/rss/response/131

댓글+트랙백 ATOM :: http://www.cipher.pe.kr/tt/cipher/atom/response/131

트랙백 주소 :: http://www.cipher.pe.kr/tt/cipher/trackback/131

트랙백 RSS :: http://www.cipher.pe.kr/tt/cipher/rss/trackback/131

트랙백 ATOM :: http://www.cipher.pe.kr/tt/cipher/atom/trackback/131

댓글을 달아 주세요

댓글 RSS 주소 : http://www.cipher.pe.kr/tt/cipher/rss/comment/131
댓글 ATOM 주소 : http://www.cipher.pe.kr/tt/cipher/atom/comment/131
[로그인][오픈아이디란?]