Tech/Silverlight2011. 6. 21. 15:04

Silverlight 5(Beta) 동영상 재생 속도 조절 기능이 추가되었습니다.

MediaElement PlaybackRate 속성을 설정함으로써 쉽게 재생 속도를 조절할 있습니다.


PlaybackRate
의 값은 배속을 나타내며, 값이 2이면 2배속(2x), 0.5면 0.5배속(0.5x)으로 동작합니다.

이를 이용해서 배속 조절이 가능한 간단한 동영상 재생기를 만들어 보겠습니다.
 


위와
같이 동영상을 재생할 MediaElement 하나와 재생 속도를 조절할 Slider 하나를 만들고

MediaElement PlaybackRate 속성에 Slider Value 바인드하고 실행하면,


슬라이더를 이용해 동영상 재생 속도를 조절할 있는 동영상 재생기가 완성됩니다!

'Tech > Silverlight' 카테고리의 다른 글

[Silverlight 5] 3D 그래픽  (1) 2011.06.22
[Silverlight 5] GPU 가속 동영상 재생  (0) 2011.06.22
[Silverlight MEF - Export UserControl]  (2) 2010.06.02
[Silverlight MEF - Dynamic XAP Loading]  (1) 2010.05.12
Posted by 알 수 없는 사용자
Tech/WPF2011. 5. 3. 17:26

WPF에서 GDI를 이용하여 이미지를 생성할 수 있다.
Graphics객체를 통해, 도형이나 선, 텍스트, 이미지 등을 그릴 수 있다.

참고 (http://msdn.microsoft.com/ko-kr/library/system.drawing.graphics.aspx)

아래의 예제는 파일목록들을 얻어와서 1000*1000크기의 Bitmap객체에 이미지들을 추가하여 이미지를 생성하는 코드이다.

 private void Button_Click(object sender, RoutedEventArgs e)
         {
            Bitmap bitmap = new Bitmap(1000, 1000);
             Graphics g = Graphics.FromImage(bitmap);

            float x = 0;
            float y = 0;
            DateTime start = System.DateTime.Now;
            for(int i = 0; i< this.imageList.Count; i++)
             {
                try
                {
                    System.Drawing.Image image = System.Drawing.Image.FromFile(this.imageList[i]);

                    g.DrawImage(image, x, y, 100, 100);
                     x += 20;
                    y += 20;
                    bitmap.Save(System.IO.Path.Combine(this.outputFolderPath, "test" + i.ToString() + ".png"));
                 }
                catch (Exception)
                {
                    //파일 경로중 이미지가 아닌 파일의 경우 Image객체를 생성할 때, 예외가 발생한다.
                     continue;
                }
            }
            
            System.Diagnostics.Debug.WriteLine("elapsed :" + System.DateTime.Now.Subtract(start).TotalSeconds.ToString());
}

 

'Tech > WPF' 카테고리의 다른 글

WPF 화면에 보여지는 이미지 삭제하기  (1) 2010.10.29
[WPF 3D UI 구현하기 - 3]  (1) 2009.11.12
[WPF 3D UI 구현하기 - 2]  (0) 2009.11.12
[WPF 3D UI 구현하기 - 1]  (2) 2009.11.11
Posted by 알 수 없는 사용자
Tech/Android 개발2011. 4. 15. 12:21

Android 개발환경 설정

 

자 이제 우리도 안드로이드 개발을 해봅시다.

안드로이드 개발에 앞서 필요한 환경은 일단 세가지 입니다.

 

제일 먼저, 안드로이드는 JAVA를 기반으로 구현된 플랫폼 입니다.

그러니 JAVA개발환경부터 세팅을 해야하지요.

자 일단, JDK를 설치해 봅시다.

1. JAVA개발환경 설정

1.1  JAVA SDK설치

JDK에는 세가지 버전이 있는데, 가장 보편적인 SE(Standard Edition)을 사용하도록 합시다.

https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=jdk-6u24-oth-JPR@CDS-CDS_Developer

이 링크를 따라가서 자신의 OS환경에 맞춰 다운을 받으시면 됩니다.

대략 80MB정도의 용량입니다.

다운받고 설치를 하시면, 이제 JAVA를 개발할 수 있습니다!

 


1.2
환경변수 설정

하지만, JAVA의 컴파일은 커맨드 기반으로 진행되기 때문에, 편의를 위해서 환경변수 등록을 해줍시다.

왜 환경변수 설정을 하느냐?

일단, JAVA개발에 있어서 가장 자주 사용하는 커맨드는 두개, 컴파일하는 javac, 실행하는 java 입니다.

이것을 환경변수를 설정하지 않고, 사용하려고 하면

 

 

이런 오류가 나옵니다.

커맨드를 사용하려면 실행파일이 있는 폴더까지 가서 실행해야 하는 불편함이 있지요.

현재 위치에 상관없이 어느 위치에서나 커맨드를 사용 가능하도록 하기 위해 환경변수를 설정하는 것입니다.

그럼 어디가서 환경변수를 설정하느냐?


시스템 속성창을 여시면 고급탭 하단에 환경변수 버튼이 보입니다.

버튼을 클릭하게 되면,



이런 창이 뜹니다.

여기서 아래 시스템 변수 영역에서 path변수에 JAVA의 실행파일들이 위치한 폴더를 추가해줍시다.


경로는 JDK가 설치된 폴더 하위의 bin폴더 입니다.

이렇게 환경변수를 설정하고 나서 다시 커맨드를 실행해봅시다.

 

 

아까와는 다르게 실행방법에 대한 설명이 주루루룩 나옵니다.

이제 JAVA개발환경은 준비가 되었습니다.


 

2.     Android SDK설치하기

이제 기반이 되는 JAVA는 설치를 마쳤으니, Android도 설치를 해봅시다.

http://developer.android.com/sdk/index.html

JDK와 마찬가지로 자신의 OS에 맞춰 Android SDK를 다운 받아봅시다.

현재 설치형 버전과 압축형 버전 두가지가 제공되고 있는데, 별 차이는 없습니다.
다만 설치형이 조금더 편하기에 설치형을 사용해 봅시다.

40MB가 조금 못되는 용량입니다. 다운을 받고 설치를 진행하게 되면 다음과 같은 창이 뜹니다.


여기서 Android OS버전별 업데이트를 진행할 수 있습니다.

필수적으로 해야하는 업데이트는 Android SDK Tools, Android SDK Platform-tools 입니다.

업데이트까지 진행하고 나면, Android SDK설치는 완료되었습니다.

 

3. Eclipse 설치하기

3.1 Eclipse
설치


자 그럼 Android개발에 사용할 툴을 설치해봅시다.
Android
가 지원하는 개발툴은 Eclipse입니다.
그럼 이것도 설치를 해봅시다.

http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/helios/SR2/eclipse-jee-helios-SR2-win32.zip

대략 300MB정도 됩니다. 가장 크죠.

 

Eclipse는 설치가 필요없이 다운받아서 압축만 풀어서 사용할 수 있습니다.

다운받은 파일의 압축을 풀어봅시다.

압축을 풀게되면, 다음과 같은 파일들을 보실 수 있습니다.

 


이중에서 딱 봐도 아이콘이 있는 eclipse.exe를 실행해 봅시다.

 


처음 실행하게 되면, 위와 같은 창이 뜹니다. 프로젝트를 저장할 작업 폴더를 설정해줘야 합니다.
사용할 작업 폴더 경로를 입력하고 OK를 클릭합시다.

 


자 그러면 Eclipse는 설치가 완료되었습니다.

 

3.2 Toolkit설치

하지만, Android개발을 위해서는 또, 설정을 해줘야합니다.

뭐가 참 많죠? ㅠㅠ

일단 Android SDK와 연결을 위한 Toolkit을 설치해야 합니다.

 

메뉴의 Help -> Install New Software를 선택합니다.



그리고 화면 상단의 ADD버튼을 클릭하여, Toolkit을 다운 받을 경로를 설정해줍시다.


 

경로를 설정하게 되면, 설치가능한 툴킷목록이 주루룩 나옵니다.

  


일단 네가지 다 설치합니다.

 

다 설치하고 나면, 프로그램을 재시작하라는 다이얼로그가 뜹니다.

재시작!


 

3.3 Android SDK 경로 설정


다시 실행된 Eclipse를 보면 뭔가 Android스러운 아이콘들이 몇 개 보이기 시작합니다.

하지만 아직 끝나지 않았습니다.

이제 마지막 입니다.

Eclipse 2번에서 설치한 Android SDK를 연결하기 위해서 Android SDK가 설치된 폴더경로를 지정해 주어야 합니다.

메뉴의 Window -> preferences 를 클릭해보시면

 


이런 창이 뜹니다.

목록중에 Android가 보이시죠?

저기에서 설정하면 됩니다.

 


이렇게 SDK가 설치된 폴더경로를 설정해주고, Apply를 클릭하면 설치된 Android버전들이 주루룩 나타납니다.
OK
를 누르시면 종료!

자 이제 Android개발을 위한 환경 설정을 마쳤습니다.

 

4. Hello! World!

4.1 프로젝트 생성하기

자 그럼 다 설치했으니, 설레는 마음으로 Hello! World!를 해봅시다.

먼저 프로젝트를 생성합니다.


좌측의 Package Explorer에서 우클릭을 통해 메뉴를 열거나 상단 메뉴의 File -> New 에 보시면 Android Project가 보입니다! (보이지 않는 경우에는 맨 아래의 Other를 클릭하시면 Android -> Android Project를 찾으실 수 있습니다) 꾹 눌러주시죠.

나타나는 창에서 어플리케이션에 대한 대략적인 설정을 해줘야 합니다.
OS
버젼, 어플리케이션 이름, 패키지 명, Activity(Main 역할을 합니다.)등을 작성하고 Finish를 클릭합니다.

프로젝트를 생성하면 기본적으로 Hello World가 템플릿 형식으로 구현되어 있습니다.
그래서 바로 실행을 해보도록 합시다.

Package Explorer영역의 프로젝트에서 우클릭후 Run As-> Android Application을 클릭합니다.

 


4.2 Virtual Device
생성하기

 

 


실행하려고 하면 위와 같이 다이얼로그가 뜹니다.
아직 만들어진 에뮬레이터가 없어서 만들라는 얘기지요. Yes를 클릭해서 한번 만들어봅시다.

  


우측 상단의 New를 클릭합니다.

에뮬레이터의 이름과 대상OS버젼, SD카드 사이즈를 설정하고 Create AVD를 클릭합시다.


이제 에뮬레이터가 만들어졌습니다.

 


4.3 Hello! World!


자 이제 준비는 끝났습니다. 좀 전과 같이 프로젝트를 실행하면


짜잔 에뮬레이터가 실행됩니다. (대략 시간이 좀 걸립니다 -_-)

 


Hello World!!
이렇게 대략적으로 Android 개발 준비를 마쳤습니다!!

이제 다함께 삽질의 세계로~


Posted by 알 수 없는 사용자
Tech/iOS 개발2011. 3. 12. 09:38
EXC_BAD_ACCESS 오류가 나면서 프로그램이 종료되는 현상은 이미 소멸된 개체의 포인터에 메시지를 보낸 것이 원인입니다.

문제는 이렇게 종료되었을 때 코드의 어느 부분에서 그러한 메시지 전달이 시도되었는지 알려주지 않아서 디버깅이 정말 힘들다는거죠.

이럴 때 NSZombie를 사용해야 합니다.

XCode 왼편 목록에서 Executables 중 디버깅하려는 항목의 Get Info로 들어갑니다. 거기서 Arguments에 NSZombieEnabled 를 YES로 성장하는 항목을 추가해줍니다. 그리고 디버깅을 하면 됩니다.

이렇게 설정하면 개체가 소멸된 그자리에 좀비가 남아서 잘못된 메시지 전달 시도라는 것을 알려줍니다.

문제에 대한 디버깅을 마치면 위에서 추가한 NSZombieEnabled Argument를 지우거나 체크 해제해줍니다.

iPhone 에서 작성된 글입니다.
Posted by wafe
Tech/Objective-C 언어2011. 1. 20. 23:22

Objective-C 에서 여러 개의 인자를 받는 메소드는 다음과 같은 모양으로 선언됩니다.

- (void)setWidth:(float)width height:(float)height;

파라미터마다 반드시 하나씩 이름이 붙는 것처럼 보이기는 하지만, 이것은 Python이나 C# 에서 제공되는 Named Parameter 와는 달리 순서를 바꿔 쓸 수 없습니다. 아래와 같이 세 개의 인자를 받는 인스턴스 메소드가 있을 때,

- (void)setCoordinatesX:(float)x y:(float)y z:(float)z; 

다음과 같은 메시지 표현식은 위에 있는 메소드와 대응되지 않습니다. (y: 와 z: 의 순서가 바뀌었지요)

[myCoordinates setCoordinatesX:1.0 z:2.0 y:3.0]

즉,    (void)setCoordinatesX:(float)x y:(float)y z:(float)z  라는 메서드와 (void)setCoordinatesX:(float)x z:(float)z y:(float)y  라는 메서드는 서로 다른 메서드이며, 한 클래스 안에 같이 정의될 수 있습니다.


여러 개의 인자를 받는 메소드에서 재미있는 부분이 또 하나 있는데, 동일한 파라미터 이름을 반복해서 쓸 수도 있습니다. 아래와 같은 메서드 선언이 가능한 것이지요.

- (void)setValue:(int)v1 val:(int)v2 val:(int)v3; 

어차피 Objective-C 에서는 메소드의 파라미터 순서를 바꿔서 호출하거나, C++ 에서처럼 선언시에 파라미터 기본값을 설정해서 호출시에는 생략할 수 있는 기능이 제공되지 않기 때문에 위에서와 같은 메소드를 정의해도 별 문제가 없겠지요. 


'Tech > Objective-C 언어' 카테고리의 다른 글

메시지, 메소드, 셀렉터에 대해서  (0) 2011.01.17
Posted by wafe
Tech/iOS 개발2011. 1. 18. 18:39

XCode의 디버거에서는 변수의 retain count를 볼 수가 없어서 불편한데요, 디버깅 중에 볼 수 있는 방법이 없지는 않습니다. gdb의 디버깅 콘솔을 띄워서 다음과 같이 입력하면 theObj의 retain count 가 출력됩니다.

print (unsigned int)[theObj retainCount]


참고로, 재미삼아 위의 문장에서 (unsigned int) 부분을 지우고 실행해보면 '리턴 타입 정보가 없어서 "objc_msgSend" 함수를 호출할 수 없다'는 오류 메시지가 표시됩니다. Objective-C 에서 메시지 표현식이 내부적으로 어떻게 구현되는지 엿볼 수 있는 부분이겠네요. ^^

Posted by wafe
Tech/iOS 개발2011. 1. 18. 16:03


오랜만에 글을 쓰네요. 연말 중에는 정신 없어서 방치했던 개발부 블로그님...

요즘 Xcode를 뚝딱거리느라 -_-; iOS에서 svn을 사용하는 방법을 wafe 과장님께서 알려주셨습니다.
iOS에서 Tortoise SVN처럼 폴더 메뉴를 이용하여 svn에서 업데이트하고, 커밋할 수 있는 놈이 있더군요.
바로 SCPlugin인인데요.

설치 방법과 사용법은 굉장히 간단합니다.

SCPlugin 사이트에서 Download 탭을 누르신 뒤, 가장 최신 설치 파일을 다운로드 받으셔서 설치하시면 됩니다.

설치를 마쳤으면, Application(응용 프로그램)폴더로 이동하여 SCToolbarButton을 마우스로 클릭한 채로 Finder 윈도우 상단으로 드래그 하여 이동시킵니다.



svn에서 체크아웃 받을 폴더로 이동하여, SCToolbarButton을 클릭하면, svn 관련하여 익숙한 메뉴들이 나열됩니다.

여기서 당연히 Checkout을 클릭하시면 되겠죠? ' ㅅ')/
Checkout을 클릭하면, 저장소 주소(Repository URL), 본인 계정(Username, Password), Checkout받을 프로젝트 폴더 경로(Checkout to)를 설정해주시면 됩니다.



모든 설정을 완료한 뒤, Checkout 버튼을 클릭하면 끝!
간단하죠잉 ' ㅅ')/
이후부터는, SCToolbarButton을 통해 업데이트, 커밋을 사용하시면 됨돠.

그럼 저는 이만 뿅!
Posted by 알 수 없는 사용자
Tech/Objective-C 언어2011. 1. 17. 23:55

Objective-C 에 구현된 개체 중심(Object-Oriented, 보통은 객체 지향이라고 하죠) 패러다임 관점은 Smalltalk 언어에서 영향을 받았습니다. 그래서 프로그램이란 개체들과 그 개체들 사이에서 일어나는 메시지 교환으로 바라보는 것이 Objective-C 에서의 OOP 관점입니다.  클래스 조차도 개체로 생각하기 때문에, 클래스에도 메시지를 보낼 수 있게 되어 있습니다. C++의 static method 와 대응되는 개념이라고 볼 수도 있죠. 특정 클래스의 인스턴스를 생성할 때 사용하는 alloc이나 init 같은 것이 대표적입니다.

C++의 메소드 호출과 대응된다고 볼 수 있는 Objective-C의 메시지 표현식은 아래와 같은 형태입니다.

[receiver message]

수신자를 정해서 메시지를 보내는 것이지요. 

클래스에 정의된 함수들을 Objective-C 에서도 동일하게 메소드(method)라고 부릅니다. 개체들이 동작하는 방식을 결정하기 때문에 method(방식)이라고 부르는 것입니다.

[myRectangle display];

[myRectangle setWidth:20.0];

[myRectangle setOriginX: 30.0 y:50.0]

위의 세 가지 메시지 표현식은 인자(argument)를 지정하지 않았거나, 하나 지정했거나, 두 개 지정한 메시지 표현식을 보여주고 있습니다. 각각의 메시지 표현식에서 인자를 뺀 부분, 즉 display, setWidth:, setOriginX:y: 는 개체에 있을 메소드를 선택하는 역할을 하고 있으므로 선택자(selector)라고 합니다. 

참고로, Objective-C 에는 메시지 포워딩이라는 개념이 있는데, 특정 개체에 구현되지 않은 메시지를 받았을 때 다른 개체에게 메시지를 보내서 처리를 위임하는 개념을 의미합니다. COM에도 비슷한 개념이 있는데, 메시지를 주고 받는다는 개념에서 출발한 '메시지 포워딩'이라는 말이 좀 더 이해하기 좋다는 생각이 듭니다. 


'Tech > Objective-C 언어' 카테고리의 다른 글

여러 개의 인자를 받는 메소드  (0) 2011.01.20
Posted by wafe
Tech/WPF2010. 10. 29. 17:06
WPF에서 이미지를 보여줄 때 Image 태그의 Source를 설정해서 보여주는 방식을 사용한다.

이때 로딩된 이미지 파일을 삭제하려고 하면, Exception이 발생한다.
이것은 이미지의 Source를 null로 설정하여도 동일하게 발생하는데 
이를 해결하기 위해서 이미지 Source의 Cache 옵션을 설정하여 해결할 수 있다.

1
2
3
4
string filepath = @"c:\test.jpg";
this.img.Source = new BitmapImage(new Uri(filepath, UriKind.RelativeOrAbsolute));
this.img.Source = null;
File.Delete(filepath);
!!!Exception 발생


1
2
3
4
5
6
7
8
9
10
11
string filepath = @"c:\test.jpg";

BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
bi.UriSource = new Uri(filepath);
bi.EndInit();
img.Source = bi;

File.Delete(filepath);
정상적으로 파일이 삭제됨

'Tech > WPF' 카테고리의 다른 글

WPF에서 그래픽을 이용하여 이미지 생성하기.  (0) 2011.05.03
[WPF 3D UI 구현하기 - 3]  (1) 2009.11.12
[WPF 3D UI 구현하기 - 2]  (0) 2009.11.12
[WPF 3D UI 구현하기 - 1]  (2) 2009.11.11
Posted by 알 수 없는 사용자
Tech/닷넷 일반2010. 9. 19. 20:28

Visual C++로 데스크톱용 제품을 만들 때에는 주로 MFC 기반으로 작업을 하게 됩니다. 이 때는 모듈화를 할 때 MFC ActiveX를 주로 사용합니다. 이것은 Visual C++ 6.0 시절부터 개발해왔던 습관 때문이라고 볼 수 있겠습니다. MFC 응용프로그램에서든, Internet Explorer에서든 모듈을 사용하는 면에서든 COM 모듈을 쓰는 것과 차이가 없고 만들기는 더 편하니까요.

그런데 서비스는 UI가 제공되지 않는 세션(Session 0)에서 실행됩니다. 따라서 ActiveX 같이 윈도우가 없이는 생성조차 되지 않는 모듈은 사용할 수 없습니다. 서비스가 실행되는 세션에서는 데스크톱 윈도우도 없기 때문에 데스크톱 DC를 이용해서 이미지를 조작한다거나 하는 것도 불가능할 정도이거든요.

하지만 이미 만들어져 있는 수많은 ActiveX 모듈을 생각하면 그냥 그렇구나하며 넘어갈 수는 없죠. 일단 검색을 좀 해보니 윈폼을 쓰면 될 거라는 얘기가 있습니다. 이 정보 하나를 가지고 1차 시도를 해봅니다.

예제로 사용할 ActiveX 모듈은 GDI+를 이용해서 이미지를 JPEG 형식으로 저장해주는 간단한 모듈입니다. TheActiveOne이라는 예제 모듈에는 SaveAsJpg 라는 메서드가 하나 있는데, 아래와 같이 이미지를 저장하는 단순한 메서드입니다. from은 원본 이미지 파일 경로이고, to는 새로 생성될 jpg 이미지 파일의 경로입니다. 

InitializeGdiPlus();

 

Image image(from);

CLSID jpegClsid;

GetEncoderClsid(_T("image/jpeg"), &jpegClsid);

 

image.Save(to, &jpegClsid, NULL);

 

FinalizeGdiPlus();

이제 서비스 프로젝트를 하나 만듭니다. 이름은 TheAxService라고 지었습니다. 서비스를 만드는 방법은 이전의 포스트를 참고하시기 바랍니다. 윈폼을 쓰면 될 것이라 했으니, TheActiveOneForm이라는 윈폼을 하나만들고 TheActiveOne 모듈을 넣습니다. 그리고 서비스 클래스 쪽에서 이미지 저장 기능을 사용할 수 있도록 메서드를 하나 추가 했습니다.

public long SaveAsJPG(string srcImgPath, string outJpgPath)

{

    return this.axTheActiveOne1.SaveAsJpg(srcImgPath, outJpgPath);

}

서비스 진입점에서 윈폼을 만듭니다. 그리고 UI는 Single Thread Apartment에서 생성되어야 할 것이므로 서비스 진입점에 STAThread Attribute를 붙여줬습니다. 그 결과 Program.cs 의 Main 메서드 내용은 아래와 같이 바뀌었습니다.

[STAThread]

static void Main()

{

    //System.Diagnostics.Debugger.Launch();

 

    ServiceBase[] ServicesToRun;

    ServicesToRun = new ServiceBase[]

       {

             new TheAxService(new TheActiveOneForm())

       };

    ServiceBase.Run(ServicesToRun);

}

TheAxService 클래스의 생성자에 폼을 생성해서 넘겨주고 있는 것을 위의 코드에서 볼 수 있습니다.

자, 그러면 핵심인 TheAxService 클래스의 코드를 보겠습니다.

public partial class TheAxService : ServiceBase

{

    TheActiveOneForm axForm;

 

    public TheAxService(TheActiveOneForm form)

    {

        InitializeComponent();

 

        this.axForm = form;

    }

 

    protected override void OnStart(string[] args)

    {

        this.axForm.Load += new EventHandler(axForm_Load);

        this.axForm.Show();

    }

 

    void axForm_Load(object sender, EventArgs e)

    {

        this.axForm.SaveAsJPG(@"C:\Users\wafe\Pictures\office live 2.PNG", @"C:\Users\wafe\Pictures\office live 2.jpg");

    }

}

OnStart 메서드에서 폼을 Show 하고 있고, Load 이벤트 핸들러에서 이미지 파일을 저장하는 기능을 호출하고 있습니다.

이제 서비스를 빌드해서 설치하고 실행시키면!

네, 잘 안됩니다. Windows 7에서 개발하고 있는 제 경우에는 윈도우 관리자가 이상해져서 Windows Server 2008 처럼 클래식 테마로 바뀌는 등 난리도 아닙니다. -_-;;

지금까지 만든 코드에는 제대로 동작하지 않을만한 문제가 있습니다. 디버거를 통해서 확인해보면, Main 메서드가 호출되는 메인 쓰레드와 OnStart 메서드가 호출되는 쓰레드는 서로 다른 쓰레드입니다. ActiveX를 생성하지 않은 쓰레드에서 ActiveX의 메서드를 호출하는 것은 문제가 있죠.

그렇다고 OnStart 메서드에서 ActiveX를 포함하는 윈폼을 생성하도록 하는 것은 불가능합니다. STA 쓰레드가 되도록 제어할 수 없는 쓰레드에서 OnStart 메서드가 호출되기 때문입니다.

그렇다면 별도의 쓰레드를 생성해서 윈폼을 만들고 이미지 저장을 하도록 하면 어떨까 하는 생각을 하게 되었습니다. 그 내용은 다음 포스트에서 다뤄보도록 하겠습니다.

 

Posted by wafe