태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

달력

1

« 2020/1 »

  •  
  •  
  •  
  • 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
  • 31
  •  

Silverlight Model-View-ViewModel Pattern 1에 이어서.



눈치챘을지도 모르겠지만, 이 코드는 의존성 주입(dependency injection)의 필요성을 외치고 있고, 내가 다음 블로그 포스트에서 다루려고 하는 게 바로 그것이다. 우리는 현재 어플리케이션 개체의 타입을 체크한다. Blend는 그것 스스로의 어플리케이션 개체를 제공하는 반면, 실제로 실행되는 어플리케이션은 우리가 만든 어플리케이션 개체를 우리에게 준다.

리팩토링이 필요한 다음 부분은 메인 사용자 인터페이스이다. 여기서 내가 말하는 것은 카드 주위의 모든 것이다. 어플리케이션은 Twitter 계정을 넣는 텍스트 상자 하나와 새 카드를 추가하기 위한 추가 버튼을 가지고 있다. 클릭 이벤트 핸들러에서 우리는 새 YouCard 사용자 컨트롤의 인스턴스를 만들어서 스택 패널에 넣는다. 또한 YouCard 컨트롤에서 발생하는 클로즈 이벤트를 리스닝하는 이벤트 핸들러를 작성한다. 이런 접근 방법은 몇 가지 이유 때문에 좋지 않은 방법이다. 주요한 문제는 너무 많은 행동(behavior)과 로직을 뷰(XAML 페이지의 코드 비하인드)에 넣는 것이다. 예를들어 디자이너는 코드를 수정하지 않고서는 스택 패널에서 플로우 패널로 바꿀 수가 없다. 또한 어플리케이션 로직의 너무 많은 부분이 특정 UI 컨트롤과 UI 이벤트에 종속되어 있어 코드를 유닛 테스트하기가 어렵다.

이런 문제를 해결하기 위해서 우리는 YouCardData 개체의 옵저버블 컬렉션(Users)을 포함하는 새로운 뷰-모델을 만들 것이다. 이 컬렉션은 YouCard 사용자 컨트롤을 데이터 템플릿으로 사용하는 items presenter control에 바운드된다.


이제 우리는 뷰-모델에 바운드된 UI들을 가지고, 데이터를 어떻게 표시할 것이지 콘트롤하게 되었다. 하지만 이것은 아직 절반 정도밖에 안된다. 아직 사용자가 카드를 추가/삭제할 때 뷰-모델과 인터랙션하게 할 방법이 필요하다.

YouCard 어플리케이션에는 뷰-모델에 영향을 주는 인터랙션 포인트가 두 군데 있는데, 텍스트 상자와 새 사용자 추가 버튼, 목록에서 카드를 제거하는 빨간 버튼이 그것이다. 사용자는 사용자 이름을 입력하고 엔터 키를 누르거나, 추가 버튼을 클릭하여 Users 컬렉션에 새 아이템을 추가한다. 추가 버튼은 입력된 사용자 이름이 올바른 경우에만 활성화되어야 한다. 사용자가 카드에 있는 닫기 버튼을 클릭하면 우리는 뷰-모델에 있는 컬렉션으로부터 그 아이템을 제거해야 한다.

가장 뻔한 해답은 추가 버튼에 클릭 이벤트 리스너를 추가해주고, 새 사용자를 추가하기 위해서 뷰-모델에 있는 메서드를 호출하는 방법일 것이다. 우리는 텍스트 상자의 text changed 이벤트를 받아서 입력을 검증하고 텍스트에 따라서 텍스트 상자를 활성화/비활성화 할 수 있을 것이다. 또한 우리는 빨간 버튼을 클릭했을 때 발생하는 이벤트를 YouCard 컨트롤에 추가할 수도 있을 것이다. 메인 뷰는 이 이벤트를 받아서 해당하는 카드를 뷰-모델로부터 제거할 수 있을 것이다. 이 방법의 문제점은 디자이너가 소유해야만 하는 뷰에 또 다시 로직과 행동(behavior)을 넣게 된다는 것이다. 그렇게 되면 검증 규칙 같은 것들과 추가되거나 제거된 사용자를 로컬 컴퓨터의 isolated storage에 저장하는 것(우리 어플리케이션은 당신이 추가한 카드들을 저장한다) 같은 일들을 유닛 테스트하기가 더 힘들어진다.

뷰와 뷰-모델 간의 인터랙션 문제를 해결하기 위해서 우리는 커맨드 패턴을 적용할 것이다. 커맨드 패턴을 사용하면 액션을 커맨드 개체로 캡슐화할 수 있게 된다. 커맨드 개체는 보통 실행 메서드, 이름과 설명, 커맨드가 활성화되었는지 아닌지에 대한 몇몇 정보를 포함한다. 하나의 커맨드 개체가 여러 UI 엘리먼트에 붙을 수 있다. 당신은 버튼, 키보드 단축키, 메뉴 아이템으로부터 open-file-command를 호출하고 싶을 지도 모르겠다. WPF는 Commands에 대한 지원을 내장하고 있지만 Silverlight 2에는 포함되지 않았다.

Nikhil은 Silverlight behavior를 통해서 어떻게 커맨드 같은 기능을 만들 수 있는지에 대해서 멋진 아이디어를 소개했다. 그것은 ASP.NET 컨트롤을 AJAX behavior로 확장하는 데 사용된 것과 같은 개념이다. 첫번째 ViewModel 포스트에서 Nikhil은 XAML에서 커맨드를 호출하는 데에 다음과 같은 문법을 사용했다.


첨부 속성(attached property)를 이용해서, 뷰-모델에 있는 Search 메서드에 검색 텍스트 상자의 text 속성을 인자로 전달하면서 메서드를 호출하는 행동을 버튼에 추가했다. 이어지는 포스트에서 Nikhil은 Dynamic Language Runtime을 사용하여 더욱 컴팩트한 문법을 사용하는 방법을 보여주었다.

이 접근 방법의 멋진 점은 첨부된 클릭 이벤트에 모든 동적 언어 표현을 사용할 수 있다는 점이다. 메서드 호출이나 페이지에 있는 다른 엘리먼트로부터 파라미터를 얻는 것 등을 사용할 수 있는 것이다. 이 방법으로 뷰를 뷰-모델에 연결하게 되면 놀라운 유연성을 얻게 된다. 이 방법의 문제점은 동적 언어 런타임에 의존성이 생겨서 Silverlight 어플리케이션 크기가 늘어나게 된다는 것이다. 하지만 내가 더 중요하게 생각하는 부분은 이 방법을 쓰게 되면 Blend 2.5에서 제공하는 디자인 타임 지원을 사용할 수 없다는 점이다. 따라서 우리는 다른 접근법을 찾아야 한다.

나는 CodePlex에 있는 "Silverlight Extensions" 프로젝트에서 발견한 좀더 고전적인 커맨드 패턴 구현을 사용하기로 했다. 그 프로젝트는 컨트롤, 헬퍼 클래스, 확장 메서드 등을 포함하고 있다. 우리는 커맨드 패턴 구현에만 관심이 있으므로, 구현 클래스들을 YouCard 프로젝트로 옮기기로 했다. 이제 텍스트 상자와 버튼의 XAML 코드는 아래와 같다.

텍스트 상자는 뷰-모델의 Username 속성에 바운드된다. 두 컨트롤은 모두 뷰-모델의 Username을 파라미터로 사용하여 AddCard 커맨드를 호출한다.

커맨드는 다음과 같이 정의된다.

정적 Commands 클래스는 우리 어플리케이션에서 사용할 수 있는 모든 커맨드에 대한 참조를 유지한다. 새 Command 개체 인스턴스를 만들 때 그것은 Command 개체에 있는 정적 사전(static dictionary)에 추가된다. 어플리케이션에서 만들어진 모든 커맨드 개체는 그 사전에 캐싱된다. XAML에서 CommandService attribute를 사용할 때 CommandService 클래스는 CommandSubscription 클래스를 사용하여 올바른 커맨드를 가진 UI 엘리먼트에 연결된다. 사용자가 사용자 추가 버튼을 클릭했을 때 혹은 텍스트 상자에서 엔터 키를 입력했을 때, CommandSubscription 클래스는 UI 이벤트를 받아서 해당하는 Command 개체의 Executed 이벤트를 발생시킨다. 커맨드가 실행되었을 때 무언가 행동을 취하기를 원하는 클래스는 단순히 Command 개체의 Executed 이벤트를 받기만 하면 된다. 지금같은 경우 우리는 뷰-모델 클래스에서 카드를 추가하고 삭제하는 작업을 처리하기를 원한다.

얘기할만한 가치가 있는 다른 부분으로는 사용자 추가 버튼을 활성화/비활성화하는 부분이 있다. 이 부분은 IsEnabled 버튼의 속성을 뷰-모델의 IsAddEnabled 속성에 데이터 바인딩하는 식으로 되어있다. IsAddEnabled 속성은 이렇게 되어있다.

텍스트 상자는 IsAddEnabled 속성에 대한 PropertyChanged 이벤트를 발생시키는 Username 속성에 바운드되어 있다. 속성의 get 부분에서 우리는 버튼이 활성화되어야 하는지 아닌지에 대한 검증 규칙을 적용한다.

이 포스트가 Model-View-ViewModel 패턴이 어떻게 UI로부터 가능한한 많은 코드를 분리해내는지 당신에게 알려주는 또다른 예제가 되기를 바란다. WPF와 Silverlight의 강력한 데이터 바인딩 지원은 이 패턴을 아주 흥미롭게 만들어준다. 뷰와 뷰-모델 사이의 동기화 코드를 직접 작성하는 부분에 대한 걱정을 하지 않아도 되기 때문이다. 커맨드 패턴을 사용하면 어플리케이션의 액션을 UI 엘리먼트로부터 분리할 수 있다. 이로써 디자이너는 여러가지 액션을 호출하는 데 사용하는 UI 엘리먼트를 선택할 수 있는 자유를 얻는다. 그리고 무엇보다도, 우리는 Blend에서의 디자인 타임 지원을 그대로 유지하면서 이 모든 것을 해냈다. 다음 포스트에서는 의존성 주입(dependency injection)을 도입함으로써 YouCard 어플리케이션의 테스트 가능성을 높이는 작업을 계속할 것이다.


실컷 열심히 번역을 하고 보니 뒷북이란 걸 알게됐다. ㅜ.ㅜ 이미 실버라이트 카페의 boxmile 님께서 번역을 해두셨네. 다음에는 이런 삽질을 하지 말도록 하자.

Posted by wafe

댓글을 달아 주세요

  1. 네오군 2009.01.08 21:54  댓글주소  수정/삭제  댓글쓰기

    헉!!!!!!!!!!!!!!! 저두 님 글 보구 알아챘는데여... 정말 제가 죽고 싶은건.. 님께서 링크해주신 번역글을 제가 전에 읽어봤다는 겁니다.. 그걸 까먹고 있었어여 ㅠㅠ;; 늙으면 죽어야지 ㅠ;

Silverlight의 MVVM 패턴을 소개하고 있는 YouCard Re-visited: Implementing the ViewModel pattern 라는 글을 번역한 글이다. 아직 1/3 정도라서 틈나는 대로 이어서 번역하려고 한다. 실력 부족/시간 부족으로 딱히 좋은 번역이라고 하긴 힘들겠지만.


Model-View-Control (MVC) 패턴은 더 이상 유명할 수가 없을 정도이다. ASP.NET MVC 프레임워크로 Microsoft도 이제 그 대열에 뛰어들었다. Ruby on Rails, Django (Python), Spring MVC (JAVA) 같은 다른 유명한 프레임워크들은 모두 이 유명한 패턴을 구현한 것이다. MVC 패턴은 요청-응답 기반이라는 웹의 본성에 아주 잘 들어맞는다. 요청이 들어오면, controller가 무엇을 해야하는지 결정하여, model에게 알려준다. 그리고 view 엔진에게 렌더링을 시킨다.

반면 Silverlight는 비록 Silverlight가 전통적인 웹 어플리케이션 속에서 실행되기는 하지만, 웹 어플리케이션 보다는 Windows Presentation Foundation 같은 리치 클라이언트 어플리케이션 프레임워크와 공통점이 더 많다. 그러므로 어플리케이션을 설계할 때 다르게 생각할 필요가 있다. 이 포스트에서 나는 View-Model-ViewModel (MVVM) 패턴, 혹은 마틴 파울러가 말한대로 Presentation Model에 대해서 얘기할 것이다. 예제로서 나는 내 YouCard 어플리케이션을 리팩터링하여 이 패턴을 쓰도록 만들 것이다.

Jon GossmanDan CrevierWPF에서의 MVVM 패턴에 대해서 포스팅을 했고, 최근 Nikhil KothariViewModel Pattern in Silverlight using Behaviors라는 제목의 훌륭한 글을 썼다. 마틴 파울러(Martin Fowler)도 이 패턴에 대해서 썼지만 Presentation Model이라는 다른 이름을 사용했다. ViewModel을 Silverlight와 WPF 어플리케이션에서 사용하는 것이 꽤 재미있는 이유는, 이 패턴이 Silverlight와 WPF의 강력한 데이터 바인딩의 장점을 최대한 살려주기 때문이다. MVVM 패턴의 한 가지 중요 컨셉은 특정한 뷰 (사용자 인터페이스)에 딱 맞춘 특정 모델을 정의한다는 것이다. 그 뷰-모델은 당신의 도메인 모델을 형성하는 하나 혹은 그 이상의 필드에 기반한 IsDiscountingEnabled, PageTitle 같은 특별한 필드를 포함할 수도 있다. 당신의 IsDiscoundEnabled 필드는 할인(discount) 권한을 가진 그룹에 소속된 사용자인지 아닌지를 나타내는 것일지도 모른다. 그러나 뷰는 이런 사실을 모를 뿐더러 관심도 없다. 뷰는 뷰-모델의 IsDiscountEnabled 필드에만 신경을 쓰고, 도메인 모델과는 커플링되지 않는다. 뷰와 뷰-모델은 높은 수준으로 동기화된다. 반면, 뷰-모델과 도메인 모델 사이의 동기화는 단지 특정 포인트에서만(사용자가 Apply나 Save 버튼을 클릭했을 때 같은 경우에만) 일어날 뿐이다. 당신이 뷰와 뷰-모델 사이의 동기화를 어떻게 구현할 것인지는 당신이 사용하는 기술에 달려있다. 그러나 마틴 파울러조차도 그 작업이 데이터 바인딩을 통해서 수행되는 것을 추천했다.

아마도 Presentation Model에서 가장 귀찮은 부분은 Presentation Model과 뷰의 동기화이다. 작성하기에 단순한 코드이기는 하지만, 나는 이렇게 지루하게 반복되는 코드를 최소화하는 것이 좋다. Ideally some kind of framework could handle this, which I'm hoping will happen someday with technologies like .NET's data binding.(막 해석 : 이론적으로는 몇몇 프레임워크가 이런 일을 할 수 있지만, 내가 바라는 것은 닷넷의 데이터 바인딩과 같은 기술과 함께 나타날 것이다.) – Martin Fowler

마틴 파울러가 말하는 동기화 코드는, name 텍스트 상자의 값을 Preson 개체의 name 속성으로 옮기는 코드 같은 것이다. 모든 개발자들은 이런 코드들을 작성한 경험이 있고, 우리 모두 그것이 지겹고 반복적인 작업이라는 점에 동의할 것이라고 나는 확신한다! 고맙게도 데이터 바인딩은 .NET 1.1 과 Windows Forms 때부터 많이 개선되었고, 동기화 코드를 작성할 때 WPF와 Silverlight 데이터 바인딩을 선택하는 것은 자연스러운 일이다.


내가 예제로 사용할 어플리케이션은 내가 호주 REMIX에서 만든 YouCard 이다. REMIX에서 나는 디자이너를 위한 Silverlight 2에 대해서 이야기했다. 이야기의 초점은 어플리케이션을 빌드하고 디자인하기 위해서 Blend 2.5를 사용하는 방법에 대한 것이었다. 어플리케이션의 코어는 YouCard 사용자 컨트롤이었다. 그 컨트롤은 YouCardData 클래스에 데이터 바운딩되는 것이다. YouCardData 클래스는 Twitter와 Flickr에서 데이터를 받아오는 기능을 갖고 있고, 어플리케이션에서 모델과 뷰-모델의 역할을 한다. 이 클래스는 Tweet, Name, Bio같이 뷰에 관련된 필드를 갖고 있는데, 이 정보들은 HTTP 요청을 사용해서 Twitter로부터 얻은 Twitter-feed에서 추출한 것이다. YouCardData 클래스는 주어진 시간 간격으로 트위터와 플리커로부터 데이터를 다운로드하는 타이머를 시작시킨다. 단일 책임 원칙 같은 좋은 프로그래밍 원칙을 따르기 위해서 나는 트위터와 플리커 관련 기능을 외부 클래스로 분리시킬 것이다. 이 클래스들이 우리의 Model이 될 것이다. 이 클래스의 책임은 다운로드하고 XML을 분석해서 개체를 만드는 일이 될 것이다. YouCardData 클래스는 우리의 ViewModel이 될 것이고, 트위터와 플리커 서비스를 View의 논리에 맞게 사용하는 책임을 맞게 된다. 또한 UI에 필요한 필드들을 노출시키는 책임도 지게 된다. YouCardData 클래스는 원래 Blend 2.5가 제공하는 강력한 데이터 바인딩과 디자인 타임 지원을 강조하기 위해 설계되었기 때문에, 우리는 리팩토링을 위한 좋은 시작점을 가지고 있는 셈이다. 아래 도표의 왼쪽은 현재의 설계이고, 오른쪽은 리팩토링 후 기대하고 있는 디자인이다.


처음으로 해야 할 일은 외부 서비스를 위한 몇 가지 인터페이스를 정의하는 일이다. ITwitterIFlickr 인터페이스를 만드는대신, 나는 IMicroBlog와 IPhotoService 라는 좀 더 일반적인 이름을 사용하기로 했다. 이 결정은 우리가 FriendFeed, Picasa 또는 Windows Live Photo Gallery를 지원하려고 한다면 좀 더 의미있는 결정일 것이다. 나는 원래의 코드를 리팩토링하여 각각의 인터페이스를 구현하는 두 개의 구상 클래스로 만드려고한다. 하나는 진짜 온라인 서비스를 위한 것이고, 하나는 더미 데이터를 가진 목(mock) 구현이다. 앞에서 언급한대로 이 어플리케이션은 REMIX의 크리에이티브 트랙을 위한 데모로서 작성되었고, Blend에서의 멋진 디자인 타임 사용자 경험을 제공하기 위해서 작성되었기 때문에, 우리는 코드가 디자이너에 의해 사용될 때를 위해 더미 데이터를 생성할 필요가 있다. 만약 당신이 XAML이 가능하게 해주는 디자이너-개발자 업무 흐름으로부터 이익을 얻을 생각이라면, 당신의 코드가 디자인 도구에서 어떻게 동작할 지 생각해보아야 한다. 현재 구현에서 더미 데이터는 YouCardData 클래스 생성자에서 Blend에서 실행되는 것인지 아닌지 체크하는 if 문을 통해 제공된다. 만약 YouCardData 클래스가 Blend에서 실행되면 Twitter와 Flickr 서비스의 목 구현이 사용된다. 브라우저 안에서 실행되면 타이머를 시작시키고 Twitter와 Flickr에서 데이터를 받아오기 시작하는 실제 구현이 사용된다. YouCardData 클래스 생성자의 중요한 부분은 이제 이렇게 보일 것이다.



[Translation] Silverlight Model-View-ViewModel Pattern 2에서 계속.



Posted by wafe

댓글을 달아 주세요

  1. 네오군 2009.01.08 21:53  댓글주소  수정/삭제  댓글쓰기

    노고에 진심으로 감사드립니다. 앞으로도 부탁드려용 ^^;

2008. 11. 10. 00:03

DirectShow 개발자 교육 후기 카테고리 없음2008. 11. 10. 00:03

2주간 매일 3시간씩 저녁 7시부터 10까지 진행되는 동영상 S/W 개발자 교육을 이수했다. 첫 주는 회사에서도 일찍 퇴근하는 등 그나마 할만했지만, 두 번째 주는 예비군 훈련과 겹쳐서 완전 강행군이었다. 덕분에 지금은 약간 감기 기운이 있는 것 같다.


30시간 교육이라고는 하지만 DShow를 처음 배우려고 하는 나같은 사람도 가능한 수준의 교육인데다 워낙 동영상 S/W 개발이라는 범주로 다뤄야 할 것들이 많다보니 기본적인 내용 자체는 그리 특별한 것이 없다고 생각했다. 책에서도 배우려면 배울 수 있지 않을까 하고 말이다. 하지만 같이 교육을 받았고 실제로 개발을 하고 있는 사람 말을 들어보면 그렇지도 않았던 모양이다. 책만으로는 부족했던 내용을 많이 얻을 수 있었다고 한다.

다시 생각해보면 그렇기도 한 것이, 사실 나는 DShow 관련 책을 본 적이 없으니 잘 알지도 못하면서 너무 가볍게 생각한 것이기도 하고, 강의 자료 이외에 강사님이 제공한 예제 소스나 교육생들의 질문에 대한 답변이 양적으로도 풍부하고 질적으로도 좋았기 때문이다. 이쪽 분야로 상당히 경험을 많이 쌓은 분이라 예제 소스나 질문에 대한 답변에 그런 경험이 녹아 있다는 걸 느낄 수 있었다.


마지막 날인 금요일에는 뒤풀이를 가졌다. 2주간이라는 짧은 시간이지만 비슷한 과정을 겪고, 또 다들 비슷한 일을 하고 있거나 경험한 적이 있기에 술자리는 얘깃거리가 넘친다.

주위를 좀만 돌아보면 정말 말도 안되는 상황에서 힘들게 일하는 사람, 혹은 얼마전까지도 그렇게 일하다 상황이 좀더 나은 곳으로 옮긴 사람을 만나는 게 어렵지 않다. 이런 식으로만 보면 개발자의 미래는 참 어둡기만 하다.

하지만 직접 창업할 꿈을 키우고 있는 사람, 창업해서 꿈을 이뤄가고 있는 사람도 어렵지 않게 만날 수 있다. 전반적으로 어려운 요즈음에도 앞으로 계속 나아가는 그분들의 의지를 보면 새삼 감탄스럽고 부럽다.


개인적으로 얻은 것은 과장님과 얘기 할만한 기술적인 교집합이 하나 더 생긴 것. 우리 개발부는 각자 전문 분야를 가지고 독립적으로 작업하는 분위기가 아직 유지되고 있어 의견 교환이나 논의가 쉽지 않았는데, 같이 얘기할 수 있는 거리가 하나 더 생긴다는 것은 좋은 변화의 기회라고 생각한다.

Posted by wafe

댓글을 달아 주세요

  1. 준서아빠 2008.11.10 10:39  댓글주소  수정/삭제  댓글쓰기

    이런 내용의 강좌도 있었군요... 앞으로 종종 뵙겠습니다. :)

    • wafe 2008.11.10 19:38  댓글주소  수정/삭제

      시들어가던 블로그를 다시 살리려고 노력중인데 댓글을 달아주시니 기분이 좋네요.
      찾아와 주셔서 감사합니다. ^^

  2. 2008.11.10 20:19  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • wafe 2008.11.10 19:43  댓글주소  수정/삭제

      하하 안그래도 부담을 많이 느끼길래 연락을 한 번 해봐야하나 싶었는데 먼저 착수하셨군요. 카페에서 뵙겠습니다. =)

  3. hyang082 2008.11.12 15:20  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 이제 막 Direct show 공부를 시작한 사람입니다. 책이 많지 않아서 Direct show가 저한테는 좀 어렵네요 종종 와서 좋은 자료도 얻어가고 가끔씩 여쭈어 봐도 되나요?..;. 수고하세요

    • wafe 2008.11.13 15:15  댓글주소  수정/삭제

      반갑습니다. ^^

      DirectShow 관련해서 질문도 하고 정보공유를 하기 위해서 카페를 만들었으니 와보시면 좋을 것 같습니다. 아직 정보가 많지는 않지만 앞으로 채워나가야죠. =)

      http://cafe.daum.net/dshow

  4. hyang082 2008.12.08 16:39  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 그 동안 잘 지내셨나요? 저.. 여쭈어 볼께 있는데요. 혹시 다이렉트쇼 오디오 변환 필터 만들어 보신 적 있으신가요?.. 예제 소스가 필요한데 혹시 있으신가해서요. 꼭 해야하는 일인데.. 염치불구하고 여쭈어 보고 있습니다. 혹시 해보셨다면 도움을 바랍니다..ㅠ.ㅠ

    • wafe 2009.01.14 02:04  댓글주소  수정/삭제

      에고.. 제가 한참 정신이 없어서 블로그에 신경을 못 썼습니다. 많이 늦었지만 꼭 해결하셨기를 바랍니다.

DirectShow 관련해서는 프로젝트 환경을 깔끔하게 세팅하기가 참 어려운 것 같다. 지난 번에는 Visual Studio 6.0에서 DirectShow 컴파일할 때 했던 삽질 얘기였는데 이번에는 VS 2005다.

DirectShow 필터를 만들려면 샘플 프로젝트 중에서 BaseClasses 프로젝트를 컴파일해서 strmbase.lib 를 만들어야 하는데, 주어진 상황에서 뭔가 쉽게 잘 안되는 문제가 있었다.

주어진 상황은

  1. Visual Studio 2005
  2. Windows Server 2003 SP1 Platform SDK
  3. DirectX SDK 9.0

2003 SP1 Platform SDK 에서는 DirectShow가 PSDK 쪽으로 옮겨졌다. 그리고 BaseClasses 프로젝트가 솔루션 파일을 갖고 있지 않다. 그래서 nmake 를 가지고 컴파일을 해야한다.

어쨌거나 컴파일을 하면 뭔가 잔뜩 에러가 나온다. VC++ 8의 변경 사항 중에, for 문의 시작 조건 부분에서 선언한 변수의 범위가 for 블럭만으로 제한되도록 바뀐 것 때문에 이런 에러가 나는 것으로 확인되었다.

그렇다면 Makefile을 수정하여 컴파일 옵션을 변경해야 한다. 간단히 Makefile을 열고 컴파일 명령이 있는 부분에 /Zc:forScope- 라는 옵션을 추가하면 된다.

한 고비 넘었다. 그리고 다시 컴파일을 하면 에러 갯수가 확 줄어드는 것을 볼 수 있었다. 남은 에러를 보면 대강 '타입이 지정되지 않았는데, 이제는 int 라고 가정해버리는 짓따위는 하지 않아' 정도의 변명이었다.

몇 군데 함수 리턴 타입이 지정되지 않은 곳에서 에러가 발생하는 것인데 이건 별도로 옵션이 있는게 아니라서 소스를 직접 고쳐야 한다. 주변 소스에 맞게 적절히 타입을 선언해주고 다시 컴파일하면 성공!

사실 그냥 다음 버전인 Windows Server 2003 R2 Platform SDK 만 깔아도 문제가 해결된다고 하는데, PSDK를 또 까는게 귀찮아서 이런 삽질을 했다. -_-;

Posted by wafe

댓글을 달아 주세요

익스체인지 서버가 Exchange Server 2003일 때, 아웃룩 2007에서 Cached Exchange Mode 를 쓰는 경우에 Sharepoint 2007의 특정 알림메일(문서 라이브러리 알림 메일 등)을 아웃룩에서 열 수 없는 문제가 있다.

서버에 핫픽스(KB930807)를 설치하거나 Cached Exchange Mode를 사용하지 않도록 Outlook을 설정하는 것으로 이 문제를 피할 수 있다고 한다.

그런데 캐시된 모드가 아니면 정크 메일 필터가 적용되지 않아서 엄청나게 불편하다. 그리고 폴더 이동 시 지연 시간이 생긴다.

특이한 점은, 캐시되지 않는 모드에서 한 번 읽은 알림 메일은 캐시된 모드로 바꾼 후에도 잘 열린다는 점이다.


Posted by wafe

댓글을 달아 주세요

  1. 누리공 2009.08.14 14:51  댓글주소  수정/삭제  댓글쓰기

    예전에 이 문제땜에 무척이나 해맸던 기억이 나네요.
    당시에 해결을 못하고 익스체인지를 2007로 바꾸었답니다.

2008. 10. 22. 23:02

BootCamp의 윈도우 시계 맞추기 카테고리 없음2008. 10. 22. 23:02

Mac에서 BootCamp 안에 설치한 윈도우는 한국의 경우에는 맥에서 설정한 시간과 9시간 차이가 나게 된다. 그렇다고 이쪽에서 시간을 바꿔버리면 이번엔 맥 쪽 시간이 틀어져버리는 것이다.

이런 팁처럼 부팅될 때마다 인터넷으로 시계를 맞추는 방법도 있지만 이럴 경우 정해진 시각에 iMac이 켜지게 하는 기능이 제대로 동작하지 않는 문제가 생겨서, 맥을 알람으로 사용하는 나로서는 쓸 수가 없는 방법이었다.

어차피 맥 쪽을 주로 사용하니까 윈도우 쪽에서 만든 파일 시간은 좀 틀려도 상관없고 해서 비스타 가젯으로 실제 시각과 동일하게 맞춰놓은 시계를 띄워놓고 썼는데 오늘 갑자기 검색해봐야겠다는 생각이 들어서 찾다보니 역시 해결책이 있었다.

알비 포럼의 글 - 맥 레퍼드와 부트캠프의 시계 동기화는 어떻게 해야 하는가?

문제 원인은 이것이라고 한다.

Mac OS는 하드웨어 시각을 GMT(혼은 UTC, 협정 세계시)라고 인식하는데, Windows는 지역 시간대라고 인식한다.

아하, 그래서 9시간 차이가 났던 것이군. 한국 표준시(KST)는 UTC+9 니까 말이다.

이런 동작 방식은 윈도우에서 레지스트리를 수정함으로써 변경할 수 있다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation

이라는 키에 RealTimeIsUniversal 이라는 DWORD 값을 하나 생성하고 1로 설정하면 된다.

Posted by wafe

댓글을 달아 주세요

  1. 호야 2012.01.16 18:37  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사합니다.
    출처 표기하고 퍼가도 될까요?

2008. 9. 19. 00:27

스프링노트 개편 카테고리 없음2008. 9. 19. 00:27

http://ecus-ko.springnote.com/issues/9044

스프링노트가 개편되어서 새로운 기능이 많이 들어갔다. 대시보드에 댓글에 기본적으로 읽기 모드로 들어가는 기능까지 추가되었다.

뭔가 약간 모자라다고 생각했던 기능들이 이번에 다 들어간 듯한 느낌이랄까? 블로그를 위해서 도메인을 얻었는데 어째 블로그의 설자리는 점점 사라지는 듯하다.


Posted by wafe

댓글을 달아 주세요

  1. 흉악곰푸욱 2008.09.19 10:34  댓글주소  수정/삭제  댓글쓰기

    모자란 기능이 다 들어간 느낌이라고 하시니 정말로 다행이네요.

    이 한마디 덕분에 밤샘 고생해서 이번 개편을 준비한 스프링노트팀이 많은 보람을 느낄 수 있을 것 같습니다.^^

    앞으로도 많은 관심 부탁드리겠습니다.^^

  2. merry 2008.09.19 17:57  댓글주소  수정/삭제  댓글쓰기

    안녕하세요, wafe님. 스프링노트 팀 merry입니다.
    어제 새벽에 팀원들과 함께 이 글을 보았는데, 어찌나 뿌듯하던지요.
    계속 성장하는 모습 보여드리겠습니다. 앞으로도 많은 관심 부탁드려요. :)

    • wafe 2008.09.20 00:23  댓글주소  수정/삭제

      쓰다보니 뭔가 디자인이 살짝 바뀐 듯 해서 공지 사항을 찾아보니 개편이 되었더라구요. 딱 아쉽던 부분이 추가된다는 걸 알고는 정말 기뻐서 블로그에 글을 쓴 건데, 제 글 덕분에 기쁘셨다니 저도 또 다시 기쁘네요.
      앞으로도 잘 부탁드리겠습니다. ^^

  3. 도아 2008.10.14 19:03  댓글주소  수정/삭제  댓글쓰기

    그동안 통 사용하지 않았는데 한번 다시 써봐야 겠군요.

2008. 8. 31. 15:26

소설 모방범 카테고리 없음2008. 8. 31. 15:26

요즈음은 이상하게도 시간이 없다. 며칠이면 한 권씩 읽던 책도 읽을 시간이 없고, 매일 읽던 수 백 개의 RSS도 못 읽은지 오래되었다.

오랜만에 일요일이라 생일 선물로 받은 모방범(模倣犯)이라는 소설책을 읽고 있다. 이제 막 2부를 다 읽었다.

읽다보면 지루해서 자꾸만 뒷 부분을 펼쳐보게 만드는 책이다. 등장 인물 한 명 한 명에 대해서 배경 상황과 심리를 자세히 설명하는 부분이 많다. 지루하다고는 했지만 또 그 부분이 재미없다거나 식상한 것은 아니다. 군더더기처럼 붙어 있는건 아니기 때문이다.

왠지 '내 성격은 이랬구나'하고 생각하게 만드는 책이랄까. 나는 한 사람 한 사람이 처한 상황이나 심리 같은 것 보다는 재미있는 스토리를 더 좋아하는 것 같다. 소설에 대해서만 그런 것이 아니라 실제 생활에서도.

그런데 그게 아닌 것 같다. 무슨 일을 하든지 결국 사람이 하는 일이라는 말은 역시 괜히 있는 것이 아닌 것 같다. 같이 하는 사람에 대해서 늘 촉각을 곤두세우고 보살피는 일이 중요하다는 것. 지금의 내게는 그게 스트레스로 다가온다.

그리고 등장 인물을 설명하는데 많은 노력을 들이고 있는 이 소설이 자꾸 그런 부분을 건드려서 불편한 느낌이다.
Posted by wafe

댓글을 달아 주세요

2008. 4. 15. 18:47

PIL로 이미지 DPI 바꾸기 카테고리 없음2008. 4. 15. 18:47

포토샵에서 이미지 DPI를 무조건 72 DPI로 바꾸는 황당한 버그덕분에 PIL도 써본다.

http://mail.python.org/pipermail/python-list/2006-September/403994.html

쓸데없는 걸로 싸우는 거 같이 보이는 메일 쓰레드인데 아무튼 질문자도 원하던 결과를 얻었고 덕분에 나도 좋으니 이 어찌 아니 좋을쏘냐.

결론적으로 DPI는 그냥 이미지에 태그처럼 붙어있는 메타 정보일 뿐인 것 같다.
Posted by wafe

댓글을 달아 주세요

2008. 4. 15. 00:40

불법 복제 부추기는 교육 카테고리 없음2008. 4. 15. 00:40

S/W 불법복제를 부추기는 교육

나는 이런식으로 생각해본 적이 없는데, 이미 불법 복제가 당연시되는 분위기에 익숙해진 탓인가보다. 그나마도 동아리 활동 덕분에 리눅스나 오픈 소스 문화를 조금 접했기에 무료, 공개 소프트웨어를 조금 알고 있고 찾아서 쓰려는 노력을 하지만, 그렇지 않은 사람이라면 어떨까.

적어도 소프트웨어를 만들어내고 그것으로 생활을 유지하고 꿈을 찾는 우리 같은 사람들이라도 소프트웨어의 가치를 인정해야하지 않을까.

Posted by wafe

댓글을 달아 주세요

  1. 도아 2008.04.21 12:58  댓글주소  수정/삭제  댓글쓰기

    인정하는 사람도 많다고 봅니다. 문제는 인정하지 않는 사람이 더 많다는 점이겠죠. 그러나 차츰 나아질 것으로 생각합니다. 한때는 국내에도 소프트웨어를 개발하는 업체가 정말 많았는데 요즘은 정말 손으로 꼽아야 되더군요.

    • wafe 2008.08.29 21:40  댓글주소  수정/삭제

      안녕하세요 도아님 오랜만입니다. 블로그에서는 처음이겠네요. ^^

      차츰 나아지기를 기대해야겠죠? 사실 이글은 저 스스로를 타이르는 글이기도 합니다. 항상 이중적이거든요. ^^;