블로그 이미지
초딩입맛제주아재
하고 싶은 것만 하며 살고 싶다

calendar

1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
2006. 10. 14. 00:11 Programing/ReversEngineering
Disassembler

이미 Assembler와 Linker를 거쳐 생성된 PE파일을 다시 어셈블리어 코드로 바꾸어
주는 프로그램.

W32DASM - 추천
IDA - 초보자게게 다소 어려움.
PVDasm - 9x계열만 지원


Debugger

프로그램에 Break Point를 걸어 원하는 부분을 찾거나,
한줄씩 Step by Step 으로 실행해 가거나 값을 조금씩 바꿔 가며 Input 하여
OutPut 되는 값들을 보는 피드백의 과정을 위해 사용.

SoftIce - 기능은 뛰어나지만 인터페이스가 Orz...
OllyDbg - GUI인터페이스,추천 올리 디버거 1.10 다운로드



리버싱에는 대부분 어셈블러로 작업을 한다.
때문에 어셈블러는 필수다.....에고...

'Programing > ReversEngineering' 카테고리의 다른 글

참고 사이트  (0) 2006.10.13
ReversEngineering이란...  (0) 2006.10.13
posted by 초딩입맛제주아재
2006. 10. 13. 23:42 Programing/ReversEngineering
[ http://ampm.ddns.co.kr/~reverse/ ] 국내 포럼

[ http://openproject.nazzim.net/ ] 정룡옥님 홈페이지
- 오픈캡쳐 개발자. 리버스엔지니어링 기초 자료.

[ http://dualpage.muz.ro/ ]
- 기초강좌

[ http://www.driveronline.org ] 드라이버온라인
- DriverOnline은 Microsoft Windows Driver 개발자를 위한 커뮤니티

[ http://mr-driver.co.kr  ] 미스터 드라이버
- 디바이스 드라이버 개발업체 (대표이사 김훈철)

[ http://www.hajesoft.co.kr ] 하제소프트 
디바이스 드라이버 개발업체, device driver, vxd, ce, usb, pci, system.

[ http://www.zap.pe.kr ] 여리의 작업실
- 선경렬씨가 운영하는 사이트. 관련 최신정보와 프로그램 및 참고자료 링크가 다양함.

[ http://sarangnamu.net ] 사랑나무
- 리버스엔지니어링, 리눅스 커널관련 자료

[ http://www.orgon.com/w2k_internals/ ] Sven Schreiber
- Undocumented Windows 2000 Secrets - A Programmer's Cookbook 저자 홈페이지. 영문.

[ http://www.rootkit.com ] rootkit
- rootkit관련 서적을 출간했으며, Subverting the Windows Kernel이 목적이다. By: Greg Hoglund and Jamie Butler. 영문.

'Programing > ReversEngineering' 카테고리의 다른 글

리버싱에 필요한 툴  (0) 2006.10.14
ReversEngineering이란...  (0) 2006.10.13
posted by 초딩입맛제주아재
2006. 10. 13. 23:36 Programing/ReversEngineering

소프트웨어 공학의 한 분야로 이미 만들어진 시스템을 역으로 추적하여 애초의 문서나 설계기법 등의 자료를 얻어 내는 일.

- 네이버 사전 -


흔히 크랙이라고 표현하고
요즘 유행하는 각종 게임의 '핵'을 만들때 필요한 작업이 바로 리버싱이다.
프로그램 코드의 역추적으로 동작원리를 파악하여
리버서가 원하는 작업을 수행하도록 프로그램을 수정 하는 일련의 작업을
리버스엔지니어링이라고 표현 할 수 있겠다.

요즘 왜이렇게 이것저것 배우고 싶은것이 많아지는지 모르겠다.
일이 별로 없어서 그런건가..
왜 이런 학구열이 이 나이에 불어 닥치는걸까??

'Programing > ReversEngineering' 카테고리의 다른 글

리버싱에 필요한 툴  (0) 2006.10.14
참고 사이트  (0) 2006.10.13
posted by 초딩입맛제주아재
2006. 10. 13. 23:07 Programing/Java

import java.io.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.window.*;
import org.eclipse.swt.*;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.widgets.*;

public class Explorer extends ApplicationWindow {
   public Explorer() { super(null); }

   protected Control createContents(Composite parent){
       SashForm sash_form = new SashForm(parent, SWT.HORIZONTAL | SWT.NULL);
       TreeViewer tv = new TreeViewer(sash_form);
       tv.setContentProvider(new FileTreeContentProvider());
       tv.setLabelProvider(new FileTreeLabelProvider());
       tv.setInput(new File("C:\\"));
       final TableViewer tbv = new TableViewer(sash_form, SWT.BORDER);
       tbv.setContentProvider(new FileTableContentProvider());
       tbv.setLabelProvider(new FileTableLabelProvider());

       TableColumn column=new TableColumn(tbv.getTable(),SWT.LEFT);
       column.setText("Name");
       column.setWidth(200);
       tbv.getTable().setHeaderVisible(true);

       tv.addSelectionChangedListener(new ISelectionChangedListener() {
           public void selectionChanged(SelectionChangedEvent event) {
               IStructuredSelection selection =
                   (IStructuredSelection) event.getSelection();
               Object selected_file = selection.getFirstElement();
               tbv.setInput(selected_file);
           }
       });
       return sash_form;
   }
   public static void main(String[] args) {
       Explorer w = new Explorer();
       w.setBlockOnOpen(true);
       w.open();
       Display.getCurrent().dispose();
   }
}


'Programing > Java' 카테고리의 다른 글

윈도우 Java환경 설정  (0) 2006.12.23
에디트플러스 자바 컴파일/실행 설정  (0) 2006.10.16
SWT Study  (0) 2006.10.13
적당한 크기로 만들어주는 메서드 - Control.pack()  (4) 2006.10.13
SWT 연습...  (0) 2006.10.13
posted by 초딩입맛제주아재
2006. 10. 13. 22:20 Programing/Java

1 소개
1.1 SWT에 대해서
2 SWT 프로그래밍 화경 구축 및 맛보기
2.1 환경 구축
2.2 Hello World를 통해서 익히는 Eclipse+SWT 개발
2.2.1 프로젝트 생성
2.2.2 코드 생성
2.2.3 실행 시키기
3 SWT 프로그래밍 일반
3.1 SWT 애플리케이션의 기본 구조
3.2 SWT 애플리케이션 제작
3.3 SWT 패키지들
3.4 다이얼로그
3.5 Widgets
3.5.1 위젯 이벤트
3.5.2 자주사용하는 위젯
3.5.3 버튼
3.5.4 slider, scale, progressBar 위젯
3.5.5 텍스트 위젯
3.5.6 List 위젯
3.5.7 Sash 위젯
3.6 Composite 위젯
3.6.1 Table 위젯
4 관련 위키

1 소개 #

SmartDic프로젝트를 진행하기 위해서 javaGUI라이브러리인 SWT를 필요로 한다. 아직까지 SWT를 다루어 본적이 없으므로 프로젝트의 원할한 진행을 위해서 SWT에 대한 스터디를 수행하기로 했다.

예제들은 Eclipse를 이용해서 작성하고 테스트하도록 하겠다. Eclipse의 사용방법은 SWT 스터디 위키를 참고하기 바란다.

1.1 SWT에 대해서 #


SWT #

java에서 GUI를 지원하기 위한 도구로 sun에서 개발한 Swing이 널리 사용되고 있었는데, IBM에서 통합개발 플랫폼인 Eclipse를 개발하면서 Swing 대신 자체적으로 개발한 GUI라이브러리를 제작한다. 이게 SWT 이다.

  • Swing : ?J2SE를 위한 GUI 툴킷
  • SWT : IBM의 공개 프로젝트인 Eclipse 플랫폼의 제작을 위해 별도로 개발된 라이브러리
SWT는 Standard Widget Toolkit의 줄임말로 각 운영체제자체에서 제공되는 위젯 툴킷을 통합한 그래픽 라이브러리다. 이는 각 타겟 플렛폼에 꽤나 의존적이 될 수도 있음을 의미하지만, OS독립적인 API를 제공함으로써 이 문제를 해결하고 있다. 이들 API는 목표가 되는 운영체제 시스템의 GUI코드를 wrapper함으로써 개발자 입장에서는 운영체제에 신경쓰지 않고 동일한 코드를 유지할 수 있게 된다.

덧붙여 설명하자면, Swing은 모든 위젯이 운영체제와 별개를 사용하는데(자바의 모토가 One make All use 아니던가) 그렇기때문에 Swing의 GUI는 웬지 눈에 낯설고 어색해 보이는 면이 있어왔다. 그러나 SWT는 가능한한 사용할 수있는 모든 Native Widget은 사용하고, 그러하지 않는 부분만 자바의 자체 위젯을 사용한다. 때문에 최대한 그 OS의 Native GUI와 비슷한 모습을 보여주는것이다.(Native에서 제공하지 않는 자체 위젯까지 포함하므로 때론 더 이쁠수도 있겠다. 물론 반대인 경우도 있겠지만).

그럼 자바가 시스템에 독립적이지 않은게 아닌가? 하고 반문할지 모르지만 위에 설명된 바와같이 공통적인 API를 사용하므로서 (Abstract Layer라고 볼 수 도 있겠다) OS가 다르다고 해서 소스코드의 변경을 필요로 하지 않는것이다. (VM차원에서 Native Widget를 해당 API로 랩핑해주므로)

다음은 현재 java에서 사용중인 GUI라이브러리에 대한 비교다.
Component SWT Swing AWT
Button X X X
Advanced Button X X
Label X X X
List X X X
Progress Bar X X
Sash X X
Scale X X
Sash X X
Slider X X
Text Area X X X
Advanced Text Area X X
Tree X X
Menu X X
Tab Folder X X X
Toolbar X X
Spinner X X
Tabler X X X
Advanced Table X X


2 SWT 프로그래밍 화경 구축 및 맛보기 #

2.1 환경 구축 #

우선은 개발환경을 구축해야 한다. 기본 개발환경은 Linux, ?JDK1.4기반이며 스터디를 위해서 Eclipse를 설치하기로 했다. 아무래도 SWT가 Eclipse의 일부로 개발된 측면이 있기 때문에 자연스러운 학습을 위해서 Eclipse가 필요하다고 판단되었기 때문이다.

Eclipse는 http://www.eclipse.org에서 최신버전 3.0 (04/7/27일 현재)받을 수 있다. 설치는 압축푸는 걸로 끝이다. 이클립스와 함께 SWT개발과 관련된 라이브러리도 받아야 한다. 역시 위 사이트에서 받을 수 있다. SWT라이브러리를 받은다음 이클립스를 설치한 곳에 적당한 디렉토리를 만들어서 압축을 풀도록 하자. 필자의 경우 이클립스 설치디렉토리는 /usr/eclipse에 SWT는 /usr/eclipse/jar에 풀었다.

다음은 이클립스를 통한 개발 모습이다.


2.2 Hello World를 통해서 익히는 Eclipse+SWT 개발 #

자바플렛폼에서의 개발이 그리 익숙치 않은 관계로 우선 SWT버젼의 Hello world출력 애플리케이션을 만들어 보기로 했다.

2.2.1 프로젝트 생성 #
이클립스가 실행되었다면, 새로운 File > New > Project 를 이용해서 새로운 프로젝트를 생성해야 한다. 그러면 아래와 같은 Project 생성 Wizard가 뜨게 된다.


여기에서 java > java project 를 선택하고 Next 버튼을 클릭하도록 한다. 이제 프로젝트의 이름을 선택해 주어야 하는데, ?HelloWorld로 하자. 그다음 Finish 버튼을 누른다. 그럼 아래의 그림과 같이 ?HelloWorld 프로젝트가 생성된걸 확인할 수 있다.


2.2.2 코드 생성 #
프로젝트도 만들어지고 했으니 이제 코드를 생성해 보기로 하자. ?HelloWorld 프로젝트 이름을 마우스로 클릭한후 오른쪽 버튼을 클릭하면 팝업메뉴가 뜨는데 여기에서 New > Class를 선택하도록 한다. 그러면 Java Class 생성화면이 나오는데 Name에 ?HelloWorld를 넣고 Finish버튼을 클릭해서 새로운 클래스를 만들어 내도록 한다.

그러면 아래와 같이 ?HelloWorld.java 에디터 화면이 생성된걸 확인할 수 있다.


이제 코드를 완성하도록 하자. 다음은 ?HelloWorld출력을 위한 코드다.
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;


public class HelloWorld{
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
Label label = new Label(shell, SWT.NONE);
label.setText("Hello World!");
shell.pack();
label.pack();
shell.open();

while(!shell.isDisposed())
if(!display.readAndDispatch())
display.sleep();
display.dispose();
label.dispose();
}
}

그데 몇몇라인을 보면 빨간색 밑줄이 그어져 있는 것을 볼 수 있을 것이다. 이는 코드에 문제가 있다는 건데, 우리가 swt관련 패키지를 지원할 수 있도록 포함시키지 않았기 때문에 발생하는 에러다. C로 말하자면 -l"라이브러리" 를 하여 라이브러리를 링킹하지 않은것과 비슷하다고 볼 수 있겠다.

이문제의 해결을 위해서는 프로젝트에 swt와 관련된 JAR파일을 추가시켜줘야 한다. 추가시키는 방법은 : 프로젝트 이름을 선택하고 마우스 왼쪽 버튼 클릭후 Properties를 클릭하도록 한다. 여기에서 java Build Path > Libraries를 선택하도록 한다. 그다음 Add External Jars를 클릭해서 SWT관련 JAR파일을 추가시켜주면 된다.


2.2.3 실행 시키기 #
이제 실행시키는 일만 남았다. 마찬가지로 우선 ?HelloWorld 프로젝트를 선택한다음 Run > Run 을 선택하도록 하자.

그러면 다음과 Run환경 설정창이 뜬다. 이 화면을 통해서 우리는 각종 실행 인자와 환경변수와 같은 실행환경을 설정할 수 있다. C코드로 부터 실행파일을 만들때 가장 마지막으로 하는 일이 필요한 오브젝트나 라이브러리를 링크하는 작업이 있다. 마찬가지로 java환경에서도 이러한 작업이 필요로 한다. 우리가 만든 Hello World프로그램의 경우 SWT패키지를 사용하고 있으므로 SWT라이브러리를 사용하라고 알려줄 필요가 있다.

이것은 다음과 같이 VM arguments 에 SWT라이브러리의 경로를 명시해줌으로써 알려줄 수 있다. 경로는 자신의 eclipse 설치 디렉토리에 따라 달라질 수 있다.


swt관련 라이브러리의 경로는 리눅스를 기준으로 ./eclipse/plugins/org.eclipse.swt.gtk_3.0.0/os/linux/x86이다. 참고하기 바란다.

이제 Run 버튼을 클릭해서 실행하도록 하자. 다음과 같은 실행결과물을 확인할 수 있을 것이다.


3 SWT 프로그래밍 일반 #

3.1 SWT 애플리케이션의 기본 구조 #

SWT 애플리케이션은 블럭구조를 가지며 Display, Shell, Widget의 기본 블럭들로 이루어진다. Dispalys는 이벤트 loop를 관리하고 UI 쓰레드와 다른 쓰레드들간의 통신을 제어한다. Shell은 OS의 윈도우 메니저에 의해서 생성되는 윈도우 창을 관리한다. 모든 SWT 애플리케이션은 적어도 하나의 Dispaly와 하나 혹은 그 이상의 Shell 인스턴스를 필요로 한다.

http://www.developer.com/img/articles/2004/03/25/figure_01.gif

위 그림은 SWT 애플리케이션의 대략적인 구성을 서로 다른 관점을 통해서 보여주고 있다. 첫번째 다이아 그램은 UI 객체의 상속관계를 나타내고 있다. 두번째 다이아 그램은 UI 객체의 컨태이너 구조체를 보여주고 있다. 세번째 다이아 그램은 만들어진 UI를 보여준다.

만약 애플리케이션이 다중 쓰레드를 이용한다면 각각의 쓰레드는 자신의 Display 인스턴스를 만들게 된다. 프로그래머는 Display.getCurrent()메서드를 이용해서 최근 활성화된 Dispaly의 인스턴스를 가져올 수 있다.

Shell은 운영체제에서 윈도우를 나타내기 위해서 사용된다. shell은 maximized, normail, minimized 형태를 가질수 있다. shell 두가지 타입이 있다. 하나는 top-level shell로 자식을 생성하며 Display의 메인 윈도우가 된다. 다른 하나는 dialog shell로 다른 shell과 독립된다.

shell의 타입은 쉘의 생성자에 의해서 넘겨지는 style bit 값에 의존적이다. 기본적으로 쉘은 ?DialogShell 타입이 된다. 이는 아무런 인자 없이 만들경우 ?DialogShell이 만들어진다는 뜻이다.

몇몇 위젯의 특성(properties)는 반드시 생성시간에 설정되어야 한다. 이러한 위젯 특성을 style bits라고 부른다. Style bits는 SWT 클래스에 상수로 정의되어 있다. 예를들자면 Button button = new Button(shell, <styleBits>)형식으로 사용할 수 있다. sytle bits는 OR연산자 |를 이용할 수 있다. 만약 테두리가 있는 입력버튼을 만들기를 원한다면 SWT.PUSH | SWT.BORDER 해주면 된다.

3.2 SWT 애플리케이션 제작 #

SWT 애플리 케이션은 다음과 같은 순서로 만들어 진다.
  • Display 생성
  • 하나 이상의 shell 생성
  • shell의 레이아웃 설정
  • shell에 포함될 위젯 생성
  • shell windows을 연다.
  • event dispatching loop 작성
  • display의 배치
다음은 SWT 애플리케이션의 일반적인 구성이다.
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class SliderExample {
public static void main(String args[]) {
Display display = new Display();
// 1
Shell shell = new Shell(display);
// 2
shell.setLayout( new RowLayout());
// 3
// -------------------------------
// 여기에 적당한 코드를 넣는다.
// -------------------------------
shell.pack();
shell.open();
// 4
while( !shell.isDisposed())
// 5
{
if(!display.readAndDispatch())
display.sleep();
}
display.dispose();
// 6
}
}

위 예제는 실제 코드가 없기 때문에 비어있는 윈도우를 생성한다. 이를테면 SWT애플리케이션 제작을 위한 템플릿 코드정도로 생각하면 된다.

  1. 모든 SWT애플리케이션은 Dispaly와
  2. 하나 이상의 Shell을 필요로 한다. shell은 객체의 조합이다.
  3. 만약 layout을 잡지 않는다면, 추가된 위젯은 보이지 않게 된다.
  4. 만들어진 shell을 연다.
  5. 이벤트 핸들링 루프를 만들고 GUI 이벤트를 읽는다.
  6. 사용되지 않는 display를 버린다.

3.3 SWT 패키지들 #

SWT는 여러개의 패키지로 구성되어 있다. 이들 패키지에 대한 자세한 내용은 Eclipse API 문서에 정의되어 있다. 여기에서는 중요한 패키지들을 간단하게 설명하도록 하겠다.

  • org.eclipse.swt : SWT 클래스에 의해서 사용되는 상수와 예외값들이 정의되어 있다. SWT패키지는 SWT, ?SWTException, ?SWTError 3개의 클래스로 구성되어 있다. SWT는 keyboard, error, color, layout, text sylte, button등과 같은 가장 자주 사용되는 라이브러리들을 포함하고 있다.
  • org.eclipse.swt.widgets : 핵심 SWT 위젯 컴포넌트들과 위젯을 지원하기 위한 인터페이스와 클래스들을 포함하고 있다.
  • org.eclipse.swt.events: SWT 컴포넌트들에 의해 사용되는 이벤트 타입과, 리스너, 이벤트들을 정의하고 있다. 이 패키지는 Listener interfaces, Adapter class, Event class를 포함하고 있다.
  • org.eclipse.swt.dnd : SWT 위제에서 drag-and-drop을 지원하기 위한 클래스를 포함한다.
  • org.eclipse.swt.layout : SWT위젯의 자동크기변화와 위치지정과 관련된 클래스를 포함한다.
  • org.eclipse.swt.print : 출력을 위한 클래스 포함
  • org.eclipse.swt.graphics : 점, 선, 면, 색, 커서, 폰트, Graphics context등 이미지와 관련된 클래스를 제공한다.

3.4 다이얼로그 #

다이얼로그는 운영체제의 윈도우 환경에서 지원하는 것을 사용한다. 예를들어 리눅스라면 GTK에서 지원하는 다이얼로그를 사용하게 된다. SWT의 다이얼로그는 Dialog 클래스로 부터 파생된다. dialog는 위젯이 아니지만 위젯을 포함할 수 있다.

http://www.developer.com/img/articles/2004/03/25/figure_02.gif

어떤 다이얼로그들은 properties 를 조정할 수 있다. 다이얼로그는 아래와 같이 사용할 수 있다.
MessageBox messageBox = new MessageBox(shell, SWT.OK|SWT.CANCEL);
if (messageBox.open() == SWT.OK) {
System.out.println("Ok is pressed.");
}
각 다이얼로그는 open()메서드를 이용해서 다른 타입을 리턴받을 수 있다. 예를 들어서 ?MessageBox dialog는 open()메서드로 부터 int 값을 리턴받는다. 그러므로 각각의 다이얼로그 마다 리턴되는 타입에 맞도록 처리를 해주어야 한다.

?ColorDialog는 색선택 창을 보여주는데, RGB 객체를 리턴한다.

?DirectoryDialog는 디렉토리 선택을 위한 창을 보여주는데, open()메서드를 사용할 경우 선택된 디렉토리의 이름(문자열)을 리턴한다.

Font dialog는 시스템에서 제공하는 모든폰트에 대한 목록을 제공하고 선택할 수 있도록 한다. ?FontData 객체가 리턴된다.

?FileDialog는 파일선택 창을 띄운다. 여기에 더해서 확장자 필터, 경로 필터, 파일이름 필터등을 적용할 수 있다. 다이얼로그는 다음과 같은 타입을 가지고 있다.

SWT.OPEN Open 버튼을 보여준다. 파일을 열고자 할때 사용한다.
SWT.SAVE Save 버튼을 보여준다. 파일을 저장할때 사용한다.

?PrintDialog는 프린트와 관련된 여러가지 조작을 할 수 있는 창을 보여준다. open()메서드를 호출했을 경우 ?PrintData 객체를 리턴한다.

?MessageBox 다이얼로그는 사용자와 상호작용하기 위해서 사용할 수 있다. 다이얼로그는 목적에 따라서 여러가지 타입을 가질 수 있는데, 아래와 같이 | 연산을 통해서 다양한 타입을 만들어 낼 수 있다.
MessageBox messageBox = new MessageBox(shell,SWT.OK|SWT.CANCEL|SWT.ICON_WARNING);
messageBox.setMessage("www.korayguclu.de"); messageBox.open();
이렇게 해서 만들어진 다이얼로그는 다음과 같이 보일 것이다. 아래 그림은 리눅스에서 실행시킨 경우다. http://www.joinc.co.kr/albums/album01/akl.png ?MessageBox에서 사용할 수 있느 아이콘은 아래에 정리해 두었으니 참고하기 바란다. || SWT.ICON_ERROR || http://www.developer.com/img/articles/2004/03/25/image_01.gif ||
SWT.ICON_INFORMATION http://www.developer.com/img/articles/2004/03/25/image_02.gif
SWT.ICON_QUESTION http://www.developer.com/img/articles/2004/03/25/image_03.gif
SWT.ICON_WARNING http://www.developer.com/img/articles/2004/03/25/image_04.gif
SWT.ICON_WORKING http://www.developer.com/img/articles/2004/03/25/image_02.gif

3.5 Widgets #

위젯은 윈도우를 구성하는 공통 GUI객체다. 버튼, 체크박스, 팝업메뉴, 슬라이드바, 스핀박스, 텍스트 입력창등이 여기에 포함된다.

SWT GUI 객체는 widget과 Control 클래스로 부터 파생된다. 위젯 객체는 모든 공통 GUI클래스를 위한 기본 클래스와 메서드를 정의하고 있다. Control 클래스는 모든 windowed GUI 클래스의 기본 클래스로 윈도우와 다이얼로그의 display와 관련된 제어를 맡는다.

다음은 위젯의 계층구조를 나타낸 그림이다.

http://www.developer.com/img/articles/2004/03/25/figure_04.gif

3.5.1 위젯 이벤트 #
3.5.2 자주사용하는 위젯 #
http://www.developer.com/img/articles/2004/03/25/figure_05.gif

모든 Control 클래스는 border를 가질 수 있다. border는 SWT.BORDER 상수를 이용해서 추가 시킬 수 있다.

3.5.3 버튼 #
버튼은 다양한 스타일을 가지고 있으며 bit값에 의해서 설정할 수 있다. 아래의 테이블은 버튼과 그 스타일을 정리한 테이블이다.

상수 사용예 설명
SWT.ARROW http://www.developer.com/img/articles/2004/03/25/image_05.gif popup메뉴등을 위해서 사용한다.
SWT.CHECK http://www.developer.com/img/articles/2004/03/25/image_06.gif 체크박스
SWT.PUSH http://www.developer.com/img/articles/2004/03/25/image_07.gif 푸쉬버튼
SWT.RADIO http://www.developer.com/img/articles/2004/03/25/image_08.gif 라디오 버튼
SWT.TOGGLE http://www.developer.com/img/articles/2004/03/25/image_06.gif 푸쉬버튼과 비슷하지만 버튼을 누르면 이전의 누름버튼은 원상태로 된다.

3.5.4 slider, scale, progressBar 위젯 #
scale는 연속된 범위내에서 특정한 값을 선택하기 위해서 사용하는 위젯이다. 범위는 Scale 클래스의 setMinimum()과 setMaximum()메서드를 이용해서 정할 수 있다. 선택된 값은 getSelection()메서드를 이용하면 된다. scale는 한번에 하나의 값만을 가져올 수 있다.

http://www.developer.com/img/articles/2004/03/25/figure_06.gif

생성자를 통해서 넘기는 인자를 통하여 다른 모양의 scale와 slider위젯을 생성할 수 있다. slider와 scale를 위해서 사용되는 상수는 아래와 같다.

SWT.HORIZONTAL 수평으로 배치
SWT.VERTICAL 수직으로 배치

옵션으로 SWT.BORDER 상수를 이용해서 scale주변에 테두리를 만들어 줄수 있다.
final Slider slider = new Slider(shell,SWT.VERTICAL);
slider.setMinimum(0);
slider.setMaximum(100);
slider.setIncrement(5);
slider.setPageIncrement(10);
slider.setSelection(25);
slider.addSelectionListener( new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
System.out.println("Selection:"+ slider.getSelection());
}
});

?ProgressBar 위젯은 Slider, Scale 위젯과 비슷하다. 그러나 선택이 불가능하다. 이것은 어떤 작업의 진척정도를 나타내기 위해서 사용한다. SWT.SMOOTH와 SWT.INTERMINATE 상수를 이용해서 ?ProgressBar 위젯을 변경할 수 있다.

3.5.5 텍스트 위젯 #
Text 위젯은 텍스트 편집창을 만들기 위해서 사용한다. 필요에 따라서는 하나의 편집창에서 서로 다른 폰트와 색을 동시에 출력하는 기능을 가진 ?StypleText 위젯을 사용할 수도 있다.. 이 위젯을 사용하면 전경색, 배경색과 폰트를 문자단위로 지정해 줄 수 있다.

http://www.developer.com/img/articles/2004/03/25/figure_07.gif

다음은 text 편집창을 만드는 예제 코드다.
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Slider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Text;
public class SliderExample {
public static void main(String args[]) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout( new RowLayout());
Text text = new Text(shell, SWT.MULTI|SWT.WRAP);
text.setText("Hello world!!");
shell.pack();
shell.open();
while( !shell.isDisposed()) {
if(!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}

3.5.6 List 위젯 #
List widget은 목록중에서 하나의 원소를 선택할 수 있는 인터페이스르 제공한다. 만약에 요소들중 하나를 선택하게 되면 이벤트 리스너에게 신호를 보내게 된다(QT의 슬롯,시그널 개념과 비슷하다.). SWT.SINGLE와 SWT.MULTI를 이용해서 단일 혹은 다중 선택이 가능하다. 리스트 위젯은 기본적으로 스크롤이 가능한 위젯임으로 SWT.H_SCROLL과 SWT.V_SCROLL 상수를 이용할 수 있다.

http://www.developer.com/img/articles/2004/03/25/figure_08.gif

final List list = new List(shell,SWT.MULTI);
for (int i = 1; i < 11; i++) {
list.add(i+".)www.korayguclu.de");
}
list.addSelectionListener( new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
List list = (List) e.getSource();
String[] str = list.getSelection();
for (int i = 0; i < str.length; i++) {
System.out.println("Selection: "+str[i]);
}
}
});

3.5.7 Sash 위젯 #
Sash 위젯은 여러개의 위젯이 포함되었을 때, 서로의 영역을 변경할 수 있도록 만들어 준다. 마우스를 Sash 경계에 가져가면 좌우 화살표 혹은 상하 화살표로 바뀌면서 영역의 크기를 조정할 수 있도록 만들어준다.

http://www.developer.com/img/articles/2004/03/25/figure_09.gif

Button button = new Button(shell,SWT.PUSH);
button.setText("Button0");
Sash sash = new Sash(shell, SWT.VERTICAL);
Button button1 = new Button(shell,SWT.PUSH);
button1.setText("Button1");

3.6 Composite 위젯 #

Composite 위젯은 다른 위젯들을 포함해서 그룹화하고 배열시키기 위한 일종의 Container 위젯이다. 또한 위젯 뿐만 아니라 Composite위젯 클래스 자체를 포함시킬 수도 있다. SWT의 Composite는 Swing의 그것다는 달리 add 메서드를 제공하지 않는다. 대신 생성자를 통해서 필요한 위젯을 배치시켜줘야만 한다.

그리고 아래 그림에서 처럼 Shell 자체를 포함시킬 수도 있다.

http://www.developer.com/img/articles/2004/03/25/figure_10.gif

Composite 위젯은 스크롤 가능한 위젯으로 상수 SWT.H_SCROLL 과 SWT.V_SCROLL을 이용해서 스크롤을 추가시킬 수도 있다.

3.6.1 Table 위젯 #
테이블 위젯은 문자열이나 이미지를 출력하기 위한 위젯이다.

posted by 초딩입맛제주아재
2006. 10. 13. 22:11 Programing/Java
 final Button button = new Button(shell,SWT.BUTTON1);
 button.pack();
 button.setSize(100,30);
 button.setText("눌러봐");
 button.pack();
 
 final Button closebutton = new Button(shell,SWT.BUTTON1);
 closebutton.pack();
 closebutton.setSize(100,30);
 closebutton.setLocation(110, 0);
 closebutton.setText("창닫어");

위 버튼은 다음과 같이 출력된다.


두개의 버튼은 각각 100,30 으로 크기를 지정해 주었다.
오른쪽의 창 크기가 100 * 30으로 지정한 크기대로 출력이 되었다.
왼쪽 창의 크기는 지정해준 크기가 아니다.
두 코드의 다른점을 보면 오른쪽 버튼의 소스에는 Control.pcak()메서드가 없다.

Control.pack()메서드의 역할은 바로 이것이다.
적당한 크기로 바꿔주는것.

일일이 control마다 setSize를 해줄 필요가 없을것 같다.

'Programing > Java' 카테고리의 다른 글

윈도우 Java환경 설정  (0) 2006.12.23
에디트플러스 자바 컴파일/실행 설정  (0) 2006.10.16
SWT 연습 - FileTreeContentProvider  (0) 2006.10.13
SWT Study  (0) 2006.10.13
SWT 연습...  (0) 2006.10.13
posted by 초딩입맛제주아재
2006. 10. 13. 21:54 Programing/Java

import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.*;

public class SWTExample{

  public static void main(String[] args){
    Display display = new Display();
 
Shell shell = new Shell(display);
shell.pack();
// shell.setLayout(new GridLayout());
shell.setSize(450, 400);
shell.setText("This is a window using SWT");


final Button button = new Button(shell,SWT.BUTTON1);
button.pack();
button.setSize(100,30);
button.setText("눌러봐");

final Button closebutton = new Button(shell,SWT.BUTTON1);
closebutton.pack();
closebutton.setSize(100,30);
closebutton.setLocation(110, 0);
closebutton.setText("창닫어");

Listener listener = new Listener(){
  public void handleEvent(Event event){
   if(event.widget == button){
    System.out.println("눌렀네");
   }else if(event.widget == closebutton){
    System.out.println("닫어");
   }
  }
};

button.addListener(SWT.Selection,listener);
closebutton.addListener(SWT.Selection, listener);

shell.open();
 
   
   while(!shell.isDisposed())
       if(!display.readAndDispatch())
     display.sleep();
        
   display.dispose();
}
}



posted by 초딩입맛제주아재
2006. 10. 13. 11:19 Programing/PHP

server.php

set_time_limit(0);

define("_IP",    {IP});
define("_PORT",  {PORT});
define("_TIMEOUT", 10);

$cSock = array();
$cInfo = array();

$sSock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_bind($sSock, _IP, _PORT);
socket_listen($sSock);

while(1)
{
  $sockArr = array_merge(array($sSock), $cSock);

  if(socket_select($sockArr, $tWrite = NULL, $tExcept = NULL, _TIMEOUT) > 0)
  {
       foreach($sockArr as $key => $sock)
       {
           // Listen 하고 있는 서버 소켓일 경우
           // 새로운 클라이언트의 접속을 의미
           echo $sock.'/'.$sSock."\n";

           if($sock == $sSock)
           {
               $tSock = socket_accept($sSock);

               socket_getpeername($tSock, $sockIp, $sockPort);

               $cSock[$tSock] = $tSock;
               $cInfo[$tSock] = array('ip'=>$sockIp, 'port'=>$sockPort);

               msg("client connect : ".$sockIp.":".$sockPort."\n");
           }
           // 클라이언트 접속해 있는 소켓중 하나일경우
           // 해당 클라이언트에서 이벤트가 발생함을 의미
           else
           {
               $buf = socket_read($sock, 4096);

               // 접속 종료
               if(!$buf)
               {
                   exceptSocket($cSock, $cInfo, $sock);
                   msg("client connection broken : ".$sockIp.":".$sockPort."\n");
               }
               // 메시지 수신 이벤트
               else
               {
                   msg("recive data : ".$buf."\n");

                   $thisSockInfo = $cInfo[$sock];
                   //$cmd = substr($buf, 0, 4);
                   $cmd = $buf;

                   switch($cmd)
                   {
                       // 시간전송
                       case "time":
                           msg("client(".$thisSockInfo['port'].") time data request\n");
                           socket_write($sock, date("Y/m/d H:i:s"));
                           break;

                       // 종료
                       case "quit":
                           msg("client(".$thisSockInfo['port'].") quit request\n");
                           socket_write($sock, "quit");
                           socket_close($sock);
                           exceptSocket($cSock, $cInfo, $sock);
                           break;
                       default:
                           if(substr($cmd,0,1) == ':'){
                               msg("client(".$thisSockInfo['port'].") sendmsg : ".substr($cmd,1)."\n");
                               broadCasting($sockArr,$sock,substr($cmd,1));
                           }else{
                               msg("client(".$thisSockInfo['port'].") invalid command $cmd\n");
                           }
                           break;
                   }
               }
           }
       }
  }

  $i++;

}

function exceptSocket(&$sockSet, &$infoSet, $sock)
{
  unset($sockSet[$sock]);
  unset($infoSet[$sock]);
  // array_merge 함수에서 error 발생을 막기위한 처리
  if(count($sockSet)==0)
  {
       $sockSet = array();
       $infoSet = array();
  }
}

function msg($msg)
{
  echo "SERVER >> ".$msg;
}

function broadCasting($socks,$cSock,$msg){
  global $sSock;

  foreach($socks as $key => $sock){
       if($sock != $sSock && $sock != $cSock){
           socket_write($sock,$msg);
       }
  }
}

client.php

define("_IP",    {IP});
define("_PORT",  {PORT});

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_connect($sock, _IP, _PORT);

msg("socket connect to "._IP.":"._PORT."\n");

while(1)
{
  msg("Enter command time or quit : ");

  // 사용자의 명령어를 입력받습니다.
  $stdin = ereg_replace("\n|\r", "", read_data());
  //$stdin = substr($stdin, 0, 4);

  // time 또는 quit 메시지 말고는 무시 합니다.
  if($stdin == "time" || $stdin == "quit")
  {
       msg("Input command : ".$stdin."\n");
  }else{
       if(substr($stdin,0,1) == ':'){
           msg("sendmsg : ".$stdin."\n");
       }else{
           msg("invalid command (not send). If you want said ':' and your message.: ".$stdin."\n");
           continue;
       }
  }

  socket_write($sock, $stdin);
  $sMsg  = socket_read($sock, 4096);

  if(substr($sMsg, 0, 4) == 'quit')
  {
       socket_close($sock);
       exit;
  }else
  {
       msg("recived data : ".$sMsg."\n");
  }
}

// 표준입력을 받아 값을 리턴하는 함수
function read_data()
{
  $in = fopen("php://stdin", "r");
  $in_string = fgets($in, 255);
  fclose($in);
  return $in_string;
}

// 로그 출력
function msg($msg)
{
  echo "CLIENT >> ".$msg;
}

단방향 채팅프로그램이다...-_-;
서버에 지정된 명령어에 의해 클라이언트의 메세지를 처리해주는 정도...
다중 클라이언트 접속이 허용되지만
클라이언트간 메세지 교환은 이루어지지 않고
클라이언트 대 서버의 통신만 가능하다.
서버에서 클라이언트의 메세지를 전체 클라이언트에게 뿌려주는
브로드캐스팅 구현이 안됐다...



TODO:
1.서버의 브로드캐스팅을 구현해야 실질적인 다중채팅이 이루어진다.
2.서버에서 임의의 메세지를 전송 하는 기능을 구현해야 한다.

'Programing > PHP' 카테고리의 다른 글

[OSX] Eclipse에서 PHP 로컬 개발/테스트 환경 구축하기  (4) 2008.08.30
Enabling PHP and Apache in Leopard  (2) 2008.08.19
WAV파일 분석  (0) 2006.11.10
간단한 대화식 프로그램  (0) 2006.07.24
시스템 모니터링 툴  (0) 2006.07.17
posted by 초딩입맛제주아재
2006. 10. 11. 11:00 Programing/Smalltalk
1. Shell 클래스 아래 HouseKeepingBookShell 클래스를 만듭니다.(이것은 MVP에서 P인 Presenter에 해당합니다)

Workspace에서 HouseKeepingBookShell showOn: testBook 을 실행해 봅니다.


창이 새로 열리죠? 그것을 캡쳐해서 올려주세요.






2. Class Browser의 클래스트리에서 HouseKeepingBookShell 의 팝업메뉴 View... / New를 합니다. (이것은 MVP에서 V인 View에 해당합니다) 이름은 그냥 기본으로 있는 Default View로 엔터누릅니다. View Composer가 열렸죠. 1번 문제에서 봤던 창이 있을 겁니다. 이 창을 편집한다는 소리죠. View Composer로 왼쪽에 뷰툴박스를 열어서 ListPresenter.Default View를 찾아 이 창에다 추가해줍니다.(끌어다놓기하면 됩니다) 오른쪽 하단의 속성창에서 name이라는 항목을 찾아 문자열로 book list 라고 이름 지어줍니다. View Composer를 저장하고 닫습니다.


Workspace에서 HouseKeepingBookShell showOn: testBook 을 실행해 봅니다.


창이 새로 열리죠? 그것을 캡쳐해서 올려주세요.


/



3. HouseKeepingBookShell 에 items라는 객체변수를 만듭니다. createComponents라는 매쏘드를 검색(Definitions of...)해 봅니다. 그 매쏘드들을 보고 흉내내서 ListPresenter를 만들어 items변수에 대입하세요. View Composer로 지어줬던 이름을 정확히 문자열로 제공해야 한다는 점을 유의하세요. 작성하신 createComponents 매쏘드를 답으로 제출해 주세요.


createComponents
super createComponents.

items := self add:  ListPresenter new name: 'book list'.


Workspace에서 HouseKeepingBookShell showOn: testBook 해서 다시 창을 열어봅니다. 리스트가 추가 되었나요? 캡쳐해서 답으로 제출하세요.


/



4. 그런데 리스트박스가 비어있군요. 내용을 표시해야 합니다.
HouseKeepingBookShell에 model: 이라는 매쏘드를 추가합니다. 이것도 역시 3번 문제와 마찬가지로 model:의 정의를 참고합니다. model: 매쏘드는 이 GUI객체(Shell)에 모델을 넘길 때, 그것을 받아들이는 매쏘드입니다. 문제 3번에서 추가한 리스트는 Shell의 하위창이었죠? 이 하위창도 역시 MVP구조로 되어있기 때문에 모델을 공급해줘야 제대로 동작합니다. 무엇을 넘겨주면 좋을까요?

items model: ????????????????


HouseKeepingBookShell>>model: 매쏘드를 작성한 것을 답으로 제출하세요.


model: aHouseKeepingBook
items model: aHouseKeepingBook items.


Workspace에서 HouseKeepingBookShell showOn: testBook 를 캡쳐해서 답으로 제출하세요.




5. 이제 하위 창을 하나 더 추가 하겠습니다. 방법은 2번~4번에서 했던 것과 마찬가지로 진행하시면됩니다. 객체변수 pocketMoney를 만듭니다. Class Composer의 클래스트리에서 팝업메뉴 View/Edit···· 해서 View Composer를 엽니다. 뷰툴박스에서 NumberPresenter.Default View를 추가하고 이름을 pocket money로 짓고 저장한다음, HouseKeepingBookShell에서 createComponents매쏘드와 model:매쏘드를 수정해서 새 객체변수 pocketMoney도 items처럼 수정해줍니다.


수정된 createComponents매쏘드와 model:매쏘드를 답으로 제출하세요.


pocketMoney := self add: TextPresenter new name: 'pocket money'.


pocketMoney model: aHouseKeepingBook pocketMoney.



Workspace에서 HouseKeepingBookShell showOn: testBook 를 하여 원금과 가계부 항목이 잘 표시된 모습을 캡쳐해서 답으로 제출하세요.





6. 리스트에 아마 an HouseKeepingBookItem이라고만 표시되고 있을 겁니다. 그것은 리스트에게 받은 객체들을 어떤 형태로 표현할 지 말해주지 않았기 때문에 기본적으로 표시되는 문자열만 뵤여주고 있기 때문입니다. 다시 View Composer를 열어서 book list라는 리스트를 선택하면 오른쪽에서 속성으로 getTextBlock이라고 있습니다. selector에 #displayString이라고 되어 있을 겁니다. 그걸 #stringInTheListBox'라고 고쳐주고 저장한다음 View Composer를 닫습니다. 그런 다음 다시 showOn:해서 창을 열어봅니다. 에러가 날 겁니다. 디버거로 매쏘드를 추가하는 방법 기억하시죠? 그 방법으로 HouseKeepingBookItem에 매쏘드를 만들어줍니다. 방금 만든 그 매쏘드는 리스트가 자신의 아이템들인 HouseKeepingBook객체들에게 표시할 문자열을 요구하는 매쏘드입니다. HouseKeepingBookItem의 name과 value를 문자열로 답하는 매쏘드를 작성해보세요.(숙제하는 사람 마음대로) 다시 showOn:합니다.


HouseKeepingBookItems>>stringInTheListBox 매쏘드를 답으로 제출하세요.


stringInTheListBox
^self name,' : ',self value printString


showOn: 하여 리스트에 항목들이 제대로 표시된 모습을 캡처해서 제출하세요.





7. 합산을 표시하는 작은 창도 만들어 보겠습니다. View Composer를 열어 NumberPresenter.Default View를 추가하여 sum이라고 이름 짓습니다.
HouseKeepingBookShell에 sum이라는 객체변수를 만들고 createComponents와 model: 매쏘드를 다시 수정합니다. 모델인 HouseKeepingBook객체에게 sum을 물어서 그 것을 HouseKeepingBookShell의 sum에게 모델로 넘겨주면 되겠군요.


createComponents, model: 를 답으로 제출하세요.


sum := self add: NumberPresenter new name: 'sum'.

sum model: aHouseKeepingBook sum.


합산이 잘 표시된 창을 캡처해서 답으로 제출하세요.




8. 흑자와 적자를 표시하는 창도 만들어 보겠습니다. View Composer를 열어 TextPresenter.Stati text를 추가하여 status이라고 이름 짓습니다.
HouseKeepingBookShell에 status이라는 객체변수를 만들고 createComponents와 model: 매쏘드를 다시 수정합니다. 모델인 HouseKeepingBook객체에게 흑자인지 적자인지 문자열로 답해주는(그런 매쏘드가 있었지요?) 그것을 HouseKeepingBookShell의 status에게 모델로 넘겨주면 되겠군요.


createComponents, model: 를 답으로 제출하세요.


status := self add: TextPresenter new name: 'status'.

status model: aHouseKeepingBook statusString.



흑자/적자가 잘 표시된 창을 캡처해서 답으로 제출하세요.



posted by 초딩입맛제주아재
2006. 10. 9. 11:08 Programing/HTML/JavaScript/CSS
if(object.addEventListener) {
   object.addEventListener('change',event_listener,false);
}else{
   object.attachEvent('onchange',event_listener);
}

function event_listener(){
   alert('object 의 change 이벤트에 반응하는 리스너');
}

- 이벤트 리스너 추가 메서드
   IE        : attachEvent(event.type,listener)
   Mozila : addEventListener(event.type,listener,useCapture)
   * Mozila 의 event.type 은 IE의 그것과는 달리 접두사 'on'이 붙지 않는다는점에 유의.


- 이벤트 리스너 삭제 메서드
   IE        : object.detachEvent(event.type,listener)
  Mozila : removeEventListener(event.type,listener,useCapture)

posted by 초딩입맛제주아재