윈도우 프로그램에서 제가 만들고 싶은 것 중 하나가 트레이 방식으로 동작하는 겁니다. 

시스템 감시와 같은 것들을 하고 싶을때가 많기 때문이죠

메신저도 만들어 보고 싶고 ...

그래서 이번 강좌는 tray 형식의 프로그램을 만들어 보려고 합니다. 

이전 강좌에서 win 이벤트를 다루고 메뉴를 다루었던 것들이

다 이유가 있어서 입니다 .

ㅋㅋ

자 그럼 우리가 만들 프로그램에 대해서 상상해 봅시다. 

먼저 프로그램을 실행하면 tray 아이콘화 되고 

이때 tray icon 을 클릭하면 창이 활성화 되고 

미니마이즈 버튼을 클릭하면 tray 아이콘화 되고 

종료 버튼을 클릭하면 종료 되도록 하는 것으로 하겠습니다. 

트레이 아이콘에서 오른쪽 버튼을 클릭하면 Exit 메뉴가 활성화 되고 

이 메뉴를 선택하면 종료 하는 것으로 하겠습니다..

뭐 기본 동작만 살펴 볼 것이기 때문에 간단합니다. ^^


다음과 같이 package.json 파일을 만듭니다. 

----[package.json]--------------------------------------------------------------
{
"name": "tray",
"main": "index.html",
"window": 
{
"toolbar" : false
}
}
--------------------------------------------------------------------------------

그리고 창을 표출하기 이한 index.html 파일을 다음과 같이 만듭니다. 

----[index.html]----------------------------------------------------------------
<html>
<head>
<meta http-equiv="content-Type" content="text/html; charset=utf-8" /> 
<title>TRAY</title>
<script type="text/javascript" src="js/jquery-2.0.3.min.js"></script>
</head>
<body>
<h1>TRAY</h1>
<script type="text/javascript" src="main.js"></script>  
</body>
</html>
--------------------------------------------------------------------------------

이제 진짜 트레이 아이콘 프로그램을 구현합니다. 

먼저 소스를 보고 하나씩 분석해 봅시다. 

----[main.js]-------------------------------------------------------------------
$(function(){

var gui = require('nw.gui');
var win = gui.Window.get();
var tray;

var 트레이메뉴 = new gui.Menu();
var 종료메뉴항목    = new gui.MenuItem({ label: 'Exit'});
종료메뉴항목.click = function() {
win.close();
}
트레이메뉴.append( 종료메뉴항목 );

win.on('minimize', function() {
this.hide();
if(tray == null) {
tray = new gui.Tray({ icon: 'img/tray.png' });
tray.menu = 트레이메뉴;
tray.on('click', function() {
win.show();
win.focus();
});
}
});
win.on('close', function() {
this.hide();
if(tray != null) {
tray.remove();
tray = null;
}
if (win != null) { 
win.close(true);
}
this.close(true);
});
win.on('closed', function() {
win = null;
});
win.minimize() ;

});
--------------------------------------------------------------------------------

가장 먼저 윈도우를 다루기 위한 준비를 다음 문장과 같이 수행합니다. 

var gui = require('nw.gui');
var win = gui.Window.get();

그리고 tray 처리를 위한 변수를 다음 문장과 같이 수행합니다. 

var tray;

트레이 아이콘에서 오른쪽 버튼을 클릭하기 위한 메뉴 준비를 다음과 같이 합니다. 

var 트레이메뉴 = new gui.Menu();
var 종료메뉴항목    = new gui.MenuItem({ label: 'Exit'});
종료메뉴항목.click = function() {
win.close();
}
트레이메뉴.append( 종료메뉴항목 );

이 상태는 트레이메뉴 만을 만들 뿐이지 

아직까지는 트레이 객체와 연결을 하지 않은 상태가 됩니다.

이제 윈도우 이벤트와 트레이를 연결해야 합니다. 

트레이가 활성화 되기 위해서 수행하는 것은 프로그램 가장 마지막 처리인 

win.minimize() ;

에서 발생합니다. 윈도우를 최소화 시키도록 요구하면 

최소화 된 이후에 minimize 이벤트가 발생합니다. 

이 이벤트에서 프로그램을 트레이 처리하기 위한 트레이 객체를 생성합니다. 

win.on('minimize', function() {
:
:
});
이 이벤트 처리에서 가장 먼저 하는 것은 윈도우를 감추는 것입니다. 

this.hide();

윈도우를 감추지 않으면 최소화 상태임을 표시하는 것이 작업줄에 표시되기 때문이다. 

그 다음에 tray 객체가 생성된 적이 없을 때만 생성하도록 조건절을 다음과 같이 겁니다. 

if(tray == null) {
:
:
}

이 조건절 안에서 트레이 아이콘을 생성하고 트레이 아이콘을 클릭했을때의 처리 함수를 지정합니다. 

tray = new gui.Tray({ icon: 'img/tray.png' });
tray.menu = 트레이메뉴;
tray.on('click', function() {
win.show();
win.focus();
});

트레이 아이콘을 클릭했을때 발생되는 이벤트는 "click" 입니다. 

이것을 tray.on() 에 연결합니다. 

트레이 아이콘을 클릭했을 때 윈도우를 보여 주고 포커스를 가져 옵니다. 

여기서 기억해야 하는 것이 윈도우를 win.show() 함수만 수행한다고 

윈도우가 활성화 되지 않는다는 겁니다. 

반드시 포커스를 가져와야 합니다. 

이제 프로로그램은 트레이 상태가 되었습니다. 

이제 이 트레이는 프로그램이 종료 될때 제거 되어야 하는데 

프로그램 종료와 프로그램 종료 요구 이벤트는 다릅니다. 

윈도우의 타이틀 오른쪽에 종료 버튼이 있는데 

사용자가 이 버튼을 클릭하면 종료 요구 이벤트가 발생합니다. 

만약 이벤트의 처리 함수가 정의되지 않으면 프로그램 종료 처리가 되지만

이 이벤트의 처리를 지정하고 있으면 프로그램 종료가 되지 않습니다. 

그래서 이 이벤트에서는 다음과 같이 하여 종료 처리 하게 됩니다. 

win.on('close', function() {
this.hide();
if(tray != null) {
tray.remove();
tray = null;
}
if (win != null) { 
win.close(true);
}
this.close(true);
});

윈도우를 종료 하는 방법은 

this.hide();
if (win != null) { 
win.close(true);
}
this.close(true);
이런식으로 하게 됩니다. 

윈도우가 종료 요구 될때는 당연히 트레이 객체도 다음과 같이 소멸 시켜 주어야 합니다. 

if(tray != null) {
tray.remove();
tray = null;
}

이제 종료가 진행되어 윈도우 프로그램이 모두 종료 되면 "closed" 이벤트가 발생하게 됩니다. 

이때 win 에 지정된 윈도우 객체를 없애주는 것으로 완전하게 종료되게 됩니다. 

쉽죠?