블로그 이미지
차세대 개발 플랫폼인 .NET Framework 4.0 과 Visual Studio 2010 의 정보와 아티클을 제공하는 공식 팀 블로그 입니다. 엄준일(땡초)
« 2010/02 »
  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            


 
 
2010 Microsoft @ Cloud Day 안준석 발표자료
View more presentations from TedAhn.


안녕하세요? 오랜만에 인사드립니다.
클라우드 컴퓨팅 관련해서 블로깅을 하고 있는 Ted 입니다.

이번 마이크로소프트@클라우드 컨퍼런스에서
"클라우드 애플리케이션 개발을 위해 알아야할 MS 기술과 플랫폼"
이라는 긴 제목의 세션 발표를 하게 됐습니다.

일전에 올린 PT자료와 중복되는 부분도 일부 있습니다.
앞으로 몇 차례에 걸쳐 발표 내용을 상세화한 글을 올리겠습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License

Intro
안녕하세요. MFC 카테고리의 꽃집총각 입니다.
우리는 지금 비주얼 스튜디오 2010에서 새롭에 추가되는 MFC 클래스인 CTaskDialog를 알아보고 있습니다.
지난 시간까지는 2회의 연재에 걸쳐서 태스크 대화상자가 무엇인지, 그리고 태스크 대화상자를 기존의 MessageBox 처럼 간단한 용도로 사용하고자 할 때엔 어떻게 해야 하는지를 함께 살펴보았습니다. 앞서 연재된 포스팅은 아래의 링크를 따라가시면 읽어보실 수 있습니다.

이번에는 태스크 대화상자의 세 번째 포스팅으로, 태스크 매니저가 제공하는 다양한 기능들을 본격적으로 활용하기 위한 방법을 알아보기로 하겠습니다.



태스크 대화상자를 띄우는 또다른 방법 - DoModal() 함수.
지난번 포스팅에서 소개했던 단순 출력 방식은 CTaskDialog::ShowDialog 함수 하나만 호출해 주면 바로 태스크 대화상자를 띄울 수 있었습니다. 8개의 인자를 통해 기본적인 기능을 어느 정도 제어할 수는 있었지만 애초부터가 심플한 사용을 위한 방법이었으므로, CTaskDialog의 여러가지 강력한 기능들을 모두 제어하기에는 무리가 있었습니다.
이번에는 CTaskDialog의 객체를 직접 생성하고, CTaskDialog의 멤버함수들을 통해 다양한 기능을 활용하는 방법을 알아보도록 하겠습니다. 이미 우리에게 익숙한 방식인 CDialog의 파생클래스를 출력하던 방식과 유사합니다. 객체를 만들어 DoModal() 함수를 호출하면 창이 뜨고, 창이 떠있는 동안 함수 내부에서 제어를 쥐고 있다가, 사용자가 창을 끄게 되면 리턴값을 내면서 함수의 호출이 종료되는 방식입니다.

// 객체 생성.
CTaskDialog dlg( L"본문", L"머릿글", L"타이틀" );

// TODO : DoModal을 호출하기 전, dlg의 멤버함수를 호출해 원하는 기능들을 설정한다.

INT_PTR iRet = dlg.DoModal();

switch( iRet )
{
case IDOK:        ... break;
case IKCANCEL:    ... break;
    ...
}

기존의 스타일을 그대로 닮아있어서 훨씬 더 친숙하게 느껴집니다 :)
다만 다른점은, DoModal을 부르기 전에 여러가지 기능을 제공하는 CTaskDialog의 멤버함수를 이용해 태스크 대화상자의 동작 및 기능을 런타임에 디자인 한다는 점입니다. 각각의 기능들은 적절한 이름의 함수로 제공되어 있으며, 매우 직관적이므로 별도의 설명 없이도 쉽게 이해하실 수 있습니다.
함수들의 레퍼런스는 아무래도 MSDN 페이지를 직접 보시는 것이 좋을 것 같습니다. ( http://msdn.microsoft.com/en-us/library/dd293651(VS.100).aspx ) 사실은 제가 한글로 설명을 덧붙인 함수 참고표를 정리해 봤는데, 굳이 부가설명이 필요 없을 뿐더러 오히려 MSDN 페이지보다 더 읽기 힘들어지기만 하네요. 대신 눈에 쏙쏙 들어오는 예제 코드를 통해 주요 함수들의 사용 방법에 대한 설명을 갈음하도록 하겠습니다.
예제는 MS VC++ MVP인 Marc Gregoire의 블로그에 공개된 예제 코드를 기반으로 하여, 주석과 인자들을 한글로 수정하고, 강의의 진행에 맞도록 일부 수정한 버전입니다. 원본 코드는 이곳 ( http://www.nuonsoft.com/blog/2009/06/10/ctaskdialog-in-mfc-in-visual-c-2010/ )에서 다운받으실 수 있습니다.

// 태스크 대화상자 객체 생성.
CTaskDialog taskDlg( L"본문", L"머릿글", L"타이틀" );

// 본문, 머릿글, 타이틀 텍스트 별도 지정
taskDlg.SetContent(_T("여기가 본문이 출력되는 위치입니다.\n")
    _T("당연히 여러 줄로 텍스트를 출력할 수 있고,")
    _T("<a href=\"http://vsts2010.net\">하이퍼 링크</a>도 설정할 수 있습니다.") );

taskDlg.SetMainInstruction(_T("여기는 머릿글을 적는 곳입니다.\n")
    _T("머릿글도 여러 줄로 적을 수 있어요."));

taskDlg.SetWindowTitle(_T("이것이 태스크 대화상자 입니다."));

// 3개의 커맨드 버튼 추가. 한 버튼은 권한 승격이 필요한 작업임을 표시.
taskDlg.AddCommandControl(1, _T("커맨드 버튼 1 "));
taskDlg.AddCommandControl(2, _T("커맨드 버튼 2 "));
taskDlg.AddCommandControl(3, _T("커맨드 버튼 3 \n")
    _T("사용자 권한 설정(UAC) 기능의 권한 승격이 필요함을 표시할 수 있습니다."), TRUE, TRUE);


// 2개의 라디오 버튼 추가.
taskDlg.AddRadioButton(4, _T("라디오 버튼 1"));
taskDlg.AddRadioButton(5, _T("라디오 버튼 2"));

// 보이기, 감추기 버튼으로 사용자가 펼치고 접을 수 있는 추가 메세지 설정.
taskDlg.SetExpansionArea(
    _T("이 메세지는 사용자가 하단의 '자세히' 버튼을 누르면 추가로 보여지는 메세지 입니다.\n")
    _T("이곳에도 하이퍼 링크가 적용됩니다. <a href=\"notepad.exe\">메모장 열기</a>."),
    _T("자세히"), _T("감추기"));

// 꼬릿말 부분 설명 & 아이콘 설정.
taskDlg.SetFooterIcon(MAKEINTRESOURCE(IDI_INFORMATION));
taskDlg.SetFooterText(_T("꼬릿말 출력 위치. \n역시 멀티라인 지원됩니다."));

// 대화상자의 메인 아이콘 설정.
taskDlg.SetMainIcon(m_hIcon);

// 태스크 대화상자의 프로그레스바 설정.
taskDlg.SetProgressBarMarquee();
taskDlg.SetProgressBarRange(0, 100);
taskDlg.SetProgressBarPosition(0);

// 대화상자 하단의 체크박스 표시 설정 및 텍스트 셋팅.
taskDlg.SetVerificationCheckboxText(_T("윈도우 시작시 자동 실행"));
taskDlg.SetVerificationCheckbox(TRUE);

// 하이퍼 링크, 타이머 옵션 추가 설정.
int options = taskDlg.GetOptions();
options |= TDF_ENABLE_HYPERLINKS;
options |= TDF_CALLBACK_TIMER;
taskDlg.SetOptions(options);


// 태스크 대화상자 출력.
INT_PTR iRes = taskDlg.DoModal();

// 사용자가 선택한 커맨드 버튼 ID와 라디오 버튼 ID 확인하기.
int iSelectedCommandControlID = taskDlg.GetSelectedCommandControlID();
int iSelectedRadioButtonID = taskDlg.GetSelectedRadioButtonID();

위의 예제 코드로 생성된 태스크 대화상자의 모습은 아래와 같습니다.

(그림 1) 예제 코드로 생성된 태스크 대화상자의 모습.


(그림 2) 예제코드로 생성한 태스크 대화상자. '자세히' 버튼을 눌러 본문이 확장된 상태.


제가 개인적으로 판단하기에는 주요함수 참고 테이블 보다는 위의 예제 코드가 훨씬 더 사용법을 익히기에 좋아 보입니다. 익스플로러 창을 두 개 띄워서 스크린샷과 소스코드를 대조해서 확인해 보세요. 어지간한 기능은 MSDN을 참고하지 않고도 바로 사용법을 이해하실 수 있을겁니다.



CTaskDialog의 프로그레스바 컨트롤.
이 부분까지 포스팅을 유심히 살펴오신 분이시라면 이상한 점을 한 가지 파악하셨을겁니다. 바로 프로그레스바 컨트롤 입니다. 지난 번 포스팅에서도, CTaskDialog::ShowDialog 함수를 이용해 프로그레스바 컨트롤을 억지로 붙여보기만 하고는 제어하는 방법을 오늘로 미루었는데, 오늘의 예제에서도 프로그레스바의 수치 등을 조절하는 함수는 있었지만 여전히 텅 빈 황량한 프로그레스바만 출력되고 있습니다.
DoModal() 함수를 호출하기 전에 SetProgressBarPosition( ... ) 함수로 프로그레스바 컨트롤의 초기값을 정해줄 수는 있지만, 태스트 대화상자가 한 번 뜨고 나면 DoModal() 함수가 제어를 쥐고 있기 때문에 컨트롤의 값을 조작하도록 손쓸 방법도 마땅치가 않습니다.

(그림 3) SetProgressBarPosition(...)으로 초기값은 정할 수 있다고 치지만, 더이상 어떻게 컨트롤 한다는 말인가?

이럴 때 CTaskDialog 클래스의 주요 기능 중의 하나인 타이머를 이용해야 합니다. 프로그레스바 컨트롤을 다루는 방법을 통해 CTaskDialog의 파생 클래스 생성 및 타이머 사용 방법을 알아보도록 하겠습니다.



CTaskDialog::OnTimer 오버로딩하기.
대화상자가 떠있는 동안은 DoModal()이 제어권을 갖고 있기 때문에, 우리가 CTaskDialog 객체의 외부에서 추가적인 조작을 가하기는 어렵습니다. 하지만 프로그레스바 컨트롤의 값을 애니메이션 하려면 대화상자가 출력되어 있는 동안에 처리가 이루어 져야 하겠지요.
이런 경우에는 CTaskDialog를 상속받는 파생 클래스를 제작하고, 가상 함수인 OnTimer를 오버로딩합니다.
OnTimer의 기본형은 다음과 같습니다.

  • virtual HRESULT OnTimer(_In_ long lTime);

예제 코드에 보면 SetOption( ... ) 함수를 이용해 기본적인 옵션에 TDF_CALLBACK_TIMER 를 추가해주어 타이머 기능을 활성화 하는 처리를 확인할 수 있습니다. 이렇게 플래그를 통해 타이머를 활성화 시켜주면 OnTimer 함수가 약 200 밀리초 (=0.2초) 주기로 호출됩니다.

int options = taskDlg.GetOptions(); options |= TDF_CALLBACK_TIMER;   // 타이머 옵션 추가 설정. taskDlg.SetOptions(options);

타이머가 필요한 대표적인 예가 바로 프로그레스바 컨트롤의 애니메이션 이겠지요. 오버로딩한 OnTimer 함수에서 간단하게 프로그레스바의 값을 진행시키는 코드를 넣어보도록 하겠습니다. 값을 조절하는 건 위에서 언급되었던 SetProgressBarPosition 함수만으로 충분합니다 :)

class CMyTaskDialog : public CTaskDialog { // ... virtual HRESULT OnTimer(_In_ long lTime); } HRESULT CMyTaskDialog::OnTimer(_In_ long lTime) { static int iProgressPos = 0; iProgressPos += 2; if (iProgressPos >= 100) iProgressPos = 0; SetProgressBarPosition(iProgressPos); return S_OK; }

위의 코드는 매번 타이머 함수가 호출될 때마다 프로그레스바 컨트롤의 값을 2씩 증가시켜주다가, 컨트롤이 만땅이 되면 꽉 차면 다시 0으로 초기화 해주고 있습니다. 0.2초에 한 번씩 호출이 되는데 2씩 채우니까... 100을 다 채우려면... 그러니까 1초에 다섯번쯤 호출 되는데... 한 번에 2씩이면 초당 10씩인가...... 뭐 아무튼 실행해보면 적당한 속도로 컨트롤이 애니메이션 되는 모습을 확인할 수 있습니다.
(웃자고 적어본 거 아시죠... 저 덧셈 잘합니다...;;)

프로그레스바 컨트롤에 대한 이야기가 나왔으니까 프로그레스바의 스타일에 대해 몇가지만 더 이야기하고 마무리 짓도록 하지요.



Marquee 타입 프로그레스바
태스크 대화상자의 프로그레스바 컨트롤은 기존의 기본적인 프로그레스바 방식보다는 Marquee 타입으로 많이 쓰일것을 예상하고 디자인된 것으로 보입니다. 프로그레스바 컨트롤을 추가하는 함수의 이름부터가 SetProgressBarMarquee(...) 이니 말입니다. 우리 예제에서는 프로그레스바의 영역을 설정하고 값을 지정해 주어 일반 프로그레스바처럼 사용하였지만, SetProgressBarRange(...) 함수와 SetProgressBarPosition(...)을 주석처리하면 프로그레스바는 기본적으로 Marquee 타입으로 설정되고, 자동으로 애니메이션 됩니다.

(그림 4) Marquee 타입 프로그레스바. 지렁이 같은게 계속 스멀스멀...

윈도우 XP의 부팅속도를 가늠하기 위한 암묵적 의사소통 수단이기도 했지요. 지렁이 몇마리...
바로 그런 식입니다. Marquee 타입 프로그레스바 컨트롤은 내부에 초록색 불빛이 좌에서 우로 이동하는 애니메이션을 반복합니다. 내부적으로 무언가 작업을 처리하고 있음을 나타내는 용도로 사용하는데 적합합니다.



CTaskDialog::SetProgressBarState(...)로 프로그레스바 상태 설정하기.
프로그레스바 관련 함수 중에 SetProgressBarState(...)가 있습니다. 이 함수를 이용해 프로그레스바의 상태를 정상 / 일시 정지 / 에러 세가지 상태 중의 하나로 설정할 수가 있습니다. 인자로 아래의 플래그를 주면 됩니다.

  • PBST_NORMAL - 정상. 디폴트값이며, 프로그레스바가 녹색으로 표시됨.
  • PBST_ERROR - 에러. 프로그레스바가 빨강으로 표시됨.
  • PBST_PAUSED - 일시 정지. 프로그레스바가 노랑으로 표시됨.

상황에 따라 적절히 사용하면 좀 더 친절한 인터페이스를 제공할 수 있겠군요. 아래는 각각의 상태에 대한 프로그레스마 컨트롤의 스크린샷 입니다. 스크린샷을 비교하는 김에 위에 붙였던 Marquee 타입의 스크린샷까지 함께 대조해 보도록 하겠습니다.

(그림 5) 위에부터 차례대로, Marquee 타입, 기본형 정상상태 / 에러상태 /일시정지 상태



Outro
이것으로 MFC 10.0의 새로운 클래스인 CTaskDialog 편을 마무리 하도록 하겠습니다. 사용법은 그렇게 어려울 것도 없는데 막상 풀어서 설명하다보니 글이 꽤나 길어졌습니다. 3차례에 걸친 강좌를 마무리하고 보니, 제가 너무 상세한 설명까지 덧붙여 괜히 글이 장황해 진 것은 아닌가 하는 걱정도 드네요. 분명 내용이 어려울 게 없는데 말입니다 ^^; 하하...
제 글이 너무 지루하거나 수준이 낮으신 분들은 매번 포스팅마다 가장 아랫부분에 따로 정리해두는 Reference 링크를 참조하시기 바랍니다. 앞으로도 강의는 가능하면 초보 개발자나 학생들도 어렵다는 느낌 없이 쉽게 접하고 내용을 익힐 수 있는 수준으로 이어나갈 예정입니다.

VisualStudio는 이미 vs2008부터 Native Programmer들을 위한 지원에 많은 노력을 들이고 있다는 점을 확인할 수 있습니다. 그런 부분을 가장 확실하게 보여주는 점이 MFC 라이브러리의 보강 입니다.
vs2010에서도 MFC는 많은 신기능들을 소개하고 있습니다. 다음 강의에도 좀 더 흥미있는 주제로 포스팅을 이어 나가도록 하겠습니다.
그럼 다음 강좌에서 또 뵙도록 하겠습니다.
감사합니다 ^^*


Reference

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

.NET Framework 4.0 에 포함될 MEF(Managed Extensibility Framework) 은 컴포넌트를 조합하는 방식으로 컴포넌트의 재사용성과 보다 컴포넌트를 동적으로 사용할 수 있는 프레임워크입니다.

하 지만 MEF 는 기존에 제네릭 타입(Generic Types) 을 지원하지 않습니다. 이미 C# 2.0 부터 지원하는 Generic Type 을 MEF 에서 지원하지 않는 것도 참 아이러니 합니다. 여기에 대한 내용은 아래의 링크를 참고하십시오.

[.NET/.NET Framework] - MEF 에 Generic Type 을 지원하기 위해서..?
[.NET/.NET Framework] - MEF 는 Generic Type 을 지원하지 않는다!

MEFGeneric 이란?

안타깝게도, MEF 에 Generic Type 을 지원하기 위해 적당한 대안이 아직 전세계적으로도 없다는 것입니다. Microsoft 의 MEF 개발 팀 리더도 MEF V1.0 버전에는 지원하지 못할거라고 합니다. 

http://codebetter.com/blogs/glenn.block/archive/2009/03/21/why-doesn-t-mef-support-open-generics-for-exports-because-mef-is-not-type-based.aspx
http://codebetter.com/blogs/glenn.block/archive/2009/08/20/open-generic-support-in-mef.aspx

MEFGeneric 은 전세계적으로 처음으로 정식으로 Generic Type 을 지원합니다. 세계 최초로 한국에서, 그리고 닷넷엑스퍼트에서, 그리고 나로부터 문제를 해결하니, 로또 맞은 기분이네요.

MEFGeneric 은 기존의 MEF 를 Core(코어) 소스 코드를 수정/확장하여 Generic Type 을 지원하도록 하였습니다. 필자는 이 소스 코드를 codeplex 사이트를 통해 공개하였으니, 아래의 사이트를 참고하세요. ^^

   

MEFGeneric is a framework to support CLR Generic types in MEF (Managed Extensibility Framework).

http://mefgeneric.codeplex.com

 

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

7. System.Object

.NET Framework 4.0/CLR | 2010/02/16 09:00 | Posted by 52
오늘의 주제는 이겁니다.

CLR의 모든 타입은 System.Object로부터 파생된다.

자. 오늘의 공부 끝!


이라고 말하고 싶지만 그러면 안되겠죠;;

그럼 모든 타입의 기본인 System.Object에 대해서 좀 더 공부를 해 봐야겠습니다. System.Object는 Class입니다. Class니까 Method과 Property 들로 구성이 되어 있겠지요.

Object의 Public Method들에 대해서 알아보기로 하죠. IDE 편집창에서 Object를 하나 선언하고 Public Method들이 무엇이 있는지 살펴봅시다.



네 저렇게 4개의 Method가 존재합니다. 이 Method들은 Object의 public Method인 만큼 CLR의 모든 타입들은 저 4개의 Method를 기본적으로 갖고 있게 됩니다. 저 Method들을 알아보기 위해 우선 좀 말이 안되긴 하지만 다음과 같은 클래스들을 만들어 놓습니다.

    class Animal
    {
        Int32 Age;
        string Name;

        public Animal(string name, Int32 age)
        {
            Age = age;
            Name = name;
        }

        public Int32 GetAge()
        {
            return Age;
        }

        public string GetName()
        {
            return Name;
        }

        public virtual string Say()
        {
            return "Can't say";
        }

        public static Int32 GetLegs(Animal animal)
        {
            Int32 legs = 2;

            if (animal.GetType().ToString().Equals("Test04.Animal"))
                legs = 4;

            return legs;

        }
    }

    class Human : Animal
    {
        public Human(string name, Int32 age) : base(name, age)
        {
        }
        public override string Say()
        {
            return "Oh! Yeah!";
        }
    }


Animal 클래스가 있고 Animal에서 상속받은 Human 클래스가 있습니다. Animal의 class 선언에는 생략되어 있지만-

class Animal 은 class Animal : System.Object 와 같이 쓸 수 있습니다. 둘은 같은 의미입니다.


1. Equals

비교 하려는 객체가 같은 값을 가지고 있으면 true 아니면 false를 return 합니다. 같은 값을 가지고 있다는 말은 무슨 의미일까요? 테스트 해 봅시다. 다음과 같은 코드를 작성해 봅니다.

            Animal dog = new Animal("happy", 3);
Human korean = new Human("Park", 33);

            if (dog.Equals(korean))
                Console.WriteLine("dog == korean");
            else
                Console.WriteLine("dog != korean");

dog라는 Animal class의 객체를 선언하고 korean이라는 Human의 객체를 선언하고 이 둘을 비교합니다. 뭐가 찍힐까요? 당연히 dog != korean 이 찍힙니다.

            Animal cat = new Animal("nero", 1);

            if (dog.Equals(cat))
                Console.WriteLine("dog == cat");
            else
                Console.WriteLine("dog != cat");

자 이번엔 어떨까요? 같은 Animal 객체인 cat을 선언해 봅니다. 둘은 같다고 인정될까요? 아닙니다. 역시 dog != cat이 찍힙니다.

            Animal dog2 = new Animal("happy", 3);
            if (dog.Equals(dog2))
                Console.WriteLine("dog == dog2");
            else
                Console.WriteLine("dog != dog2");

아.. 그러면 이번엔 객체 이름은 다르지만 내부의 property값은 같은 dog2라는 객체를 선언하고 둘을 비교해 봅시다. 같다고 인정해 줄까요? 아.. 역시 다르다고 합니다. dog != dog2 라고 찍힙니다.

도대체 그럼 뭐를 어떻게 해야 같은거야? 라고 생각하면서 마지막으로 다음과 같이 테스트 해 봅시다.

            Animal dog3 = dog;

            if (dog.Equals(dog3))
                Console.WriteLine("dog == dog3");
            else
                Console.WriteLine("dog != dog3");

dog 객체를 새로 생성한 dog3에 할당합니다. 여기선 어떤 값이 찍힐까요? 아. 드디어 두 객체가 같다고 인정해 줍니다. dog == dog3 가 찍힙니다!

Object.Equals()의 같다는 의미는 좀 어렵네요. 두 객체가 포함하는 property등의 값이 같다고 equal이 아닙니다. 두 객체가 참조하는 것이(주소값 이라고 해야 할까요? C++적인 의미로 말입니다.) 이 완전히 일치해야지 equal입니다. 

음 개념적으로는 대충 이해가 되는데 좀 더 자세히 알아보고 싶어지는군요.  앞으로 자주 보게 될 ILDASM을 꺼내봐야겠습니다. ILDASM으로 지금까지 작성한 코드들이 어떻게 CLR에 들어가는지 살펴봅시다.




ILDASM을 이용하여 작성한 코드들을 MSIL코드로 볼 수 있습니다. 하나하나씩 따라가보면서 간단하게나마 분석을 해보려고 합니다. 일단 Main 앞 부분입니다. main()함수에서 사용하는 지역변수들을 초기화 하고 알아보기 쉽게 index를 붙여서 태깅해 놓고 시작하네요.

            Animal dog = new Animal("happy", 3);
            Human korean = new Human("Park", 33);

  IL_0001:  ldstr      "happy"
  IL_0006:  ldc.i4.3
  IL_0007:  newobj     instance void Test04.Animal::.ctor(string, int32)
  IL_000c:  stloc.0
  IL_000d:  ldstr      "Park"
  IL_0012:  ldc.i4.s   33
  IL_0014:  newobj     instance void Test04.Human::.ctor(string, int32)
  IL_0019:  stloc.1

1. [IL_0001] ldstr은 스트링 개체를 스택으로 PUSH합니다. "happy"가 스택에 PUSH됩니다. 
2. [IL_0006] ldc.i4.3 은 정수값 3을 역시 스택으로 PUSH합니다. 
3. [IL_0007] newobj는 받아야 할 argument들 갯수만큼 스택에서 POP 한 후 새로운 객체를 생성하고 그 객체를 스택에 PUSH하게 됩니다. 
4. [IL_000c] stloc.0 는 스택에서 값을 POP하여 지역변수 인덱스 0 에 넣습니다. 

IL_0001 부터 IL_000c까지의 내용입니다. 그대로 하면 어떻게 되나요. 위의 C#코드에서 처럼

Animal dog = new Animal("happy", 3); 

을 수행한 결과가 됩니다. 변수 dog는 지역변수 인덱스 0 으로 태깅되어 있지요. IL_000d 부터 IL_0019까지는 korean 객체를 생성하는 과정입니다. IL_0012의 ldc.i4.s 33은 정수값 33을 스택에 PUSH하라는 명령입니다.

            if (dog.Equals(korean))
                Console.WriteLine("dog == korean");
            else
                Console.WriteLine("dog != korean");

  IL_001a:  ldloc.0
  IL_001b:  ldloc.1
  IL_001c:  callvirt   instance bool [mscorlib]System.Object::Equals(object)
  IL_0021:  ldc.i4.0
  IL_0022:  ceq
  IL_0024:  stloc.s    CS$4$0000
  IL_0026:  ldloc.s    CS$4$0000
  IL_0028:  brtrue.s   IL_0037
  IL_002a:  ldstr      "dog == korean"
  IL_002f:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0034:  nop
  IL_0035:  br.s       IL_0042
  IL_0037:  ldstr      "dog != korean"
  IL_003c:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0041:  nop

자 다음은 두 객체를 비교하는 부분입니다. 

1. [IL_001a] ldloc.0 은 0번 지역변수의 값을 스택에 PUSH합니다. 
2. [IL_001b] ldloc.1 은 1번 지역변수의 값을 스택에 PUSH하겠지요.
3. [IL_001c] callvirt 는 런타임에 바인딩된 method를 호출합니다. (call뒤에 virt가 붙은 건 호출 할 method가 virtual로 선언되어 있다는 걸 의미합니다. 실제로 Object.Equals()는 'public virtual bool Equals(object obj);' 로 선언되어 있습니다.) 호출하기 전 method와 관련된 객체와 해당 method의 인수와 관련된 값을 스택에서 POP합니다. 그리고 해당 method의 결과값이 있으면 스택에 PUSH하게 됩니다. 여기서는 equals의 값을 스택에 PUSH하게 되겠네요.
4. [IL_0021] ldc.i4.0 는 정수값 0을 스택에 PUSH하게 됩니다.
5. [IL_0022] ceq 는 비교 명령입니다. 비교에 사용될 값 value0과 value1을 스택에서 POP합니다. 여기서는 4번에서 넣었던 정수값 0과 3번 equals의 결과값이 각각 value0과 value1에 들어가게 되겠지요. 그리고 두 값을 비교해서 같으면 1이 스택으로 PUSH되며 틀리면 0이 스택으로 PUSH됩니다.
6. [IL_0024] stloc.s    CS$4$0000 스택에서 값을 꺼내어 CS$4$0000 이라는 지역변수에 넣습니다. 맨 위에서 보면 알다시피 CS$4$0000은 bool값을 가진 지역변수인데 우리가 직접 선언한 변수는 아니지요. if문에서 비교를 해서 나온 bool값을 저장하기 위해 CLR이 생성한 임시 지역 변수입니다. 결국 ceq로 비교된 값이 CS$40000 이라는 변수에 들어가게 됩니다.
7. [IL_0026] ldloc.s    CS$4$0000 은 지역변수 CS$4$0000의 값을 스택에 PUSH합니다. 아 이거 왜 뺐다가 다시 넣는거야.
8. [IL_0028] brtrue.s  IL_0037 는 스택에서 값을 하나 POP한다음에 이 값이 true거나 null이 아니거나 0이 아닌경우 IL_0037로 점프하게 됩니다. 결국 bool 형식의 CS$4$0000 값이 true면 IL_0037로 점프를 하게 되겠지요. 다시 정리하면 5번에서의 ceq의 값이 같으면 IL_0037로 점프를 하게 되는 것입니다. 또 거슬러가면 ceq의 값이 같기 위해서는 3번의 결과 값이 0이 되어야 하는데 3번의 결과 값이 0이라는 얘기는 equals()의 결과값이 0 그러니까 false라는 이야기죠. 결국 dog != cat 이면 IL_0037로 점프하는겁니다.
9. [IL_002a] ~ [IL_002f] 스택에 스트링값(dog == korean)을 넣고 Console.WriteLine()을 호출합니다.
10. [IL_0034] nop 아무일도 하지 않습니다.
11. [IL_0035] br.s       IL_0042 는 어떠한 조건에 상관없이 IL_0042로 점프하게 됩니다. [IL_0042]는 if문이 모두 끝난 다음의 명령문이 있는 주소입니다.
12. [IL_0037] ~ [IL_003C] 는 dog != korean 을 찍겠지요.

와 길고 복잡합니다. 첨부된 소스를 컴파일 하고 컴파일 된 실행 파일을 ILDASM으로 보면 계속 뒤의 코드를 볼 수 있는데 쭉- false를 리턴했던 dog2까지의 비교는 위와 동일한 패턴의 코드로 진행됩니다. 무엇보다 주시해야 될 부분은 cat이나 dog2의 객체는 쭉- newobj로 새로 생성한다는 점입니다.

            Animal dog3 = dog;

if (dog.Equals(dog3))
                Console.WriteLine("dog == dog3");
            else
                Console.WriteLine("dog != dog3");

  IL_00aa:  ldloc.0
  IL_00ab:  stloc.s    dog3
  IL_00ad:  ldloc.0
  IL_00ae:  ldloc.s    dog3
  IL_00b0:  callvirt   instance bool [mscorlib]System.Object::Equals(object)

이제 true를 반환했던 dog3입니다. IL코드를 읽어보면 알겠지만 dog3의 값은 지역변수 인덱스 0인 dog의 값(주소)를 가져와서 dog3 지역변수에 그대로 넣습니다. 이건 뭘 의미하는건가요?

Animal dog3 = dog;

를 수행한다는 것은 dog3라는 새로운 객체 공간을 생성해서 dog의 값을 복사해 오는 것이 아니라 dog라는 객체가 가리키는 값(주소)를 그대로 dog3와 연결 시킨다는 의미입니다. 결국 dog와 dog3가 가리키는 값(주소)는 같은 값(주소)입니다. equals()는 그래서 같다. 라고 결과를 반환했던 것입니다. equals()가 하는 일은 정말 간단하네요. 내용이고 자시고 간에 그냥 값이 같으면 true입니다. 

간단한 내용을 정말 길게 돌아서 확인했네요.

휴-

Object는 다음에 계속 하기로 하지요. 오늘은 이만!!

참고 소스 : 

크리에이티브 커먼즈 라이선스
Creative Commons License

'.NET Framework 4.0 > CLR' 카테고리의 다른 글

8. System.Object (2)  (0) 2010/03/03
7. System.Object  (0) 2010/02/16
6. Assembly - GAC(Global Assembly Cache)  (2) 2010/02/02
5. Assembly - Strongly named assemblies  (0) 2010/01/26
4. Assembly  (0) 2010/01/15
3. MSCorLib & Metadata  (2) 2010/01/06
TAG CLR

Intro
안녕하세요. MFC 카테고리의 꽃집총각 입니다. 이번에는 지난번 포스팅 [MFC] 태스크 대화상자(Task Dialog) - (1/3) : 기능 소개 편에 이어서, 사용하기 편을 준비했습니다.
이번 포스팅에서 다룰 내용은

  1. 비스타 이전 OS에서 태스크 대화상자 이용에 대한 이슈
  2. 태스크 대화상자의 기본적인 구성
  3. 소스코드 한 줄로 태스크 대화상자 사용하기 - ShowDialog 함수.

이렇게 세 가지 내용을 알아보도록 하겠습니다. 3번 ShowDialog 함수의 소개가 이번 포스팅의 주된 내용입니다. 태스크 대화상자를 사용하기 위해서는 CTaskDialog의 객체를 생성해 DoModal() 함수를 실행하는 방법과, 객체를 생성하지 않고 간단히 CTaskDialog::ShowDialog(...) 함수를 이용하는 방법이 있습니다. 후자는 간편하게 함수호출 한번으로 태스크 대화상자를 이용할 수 있는 장점이 있고, 전자는 보다 디테일한 설정 및 활용이 가능하다는 장점이 있습니다. 오늘은 간단한 사용법인 ShowDialog 함수에 대해 알아보고, CTaskDialog의 객체를 선언하는 방법은 다음 포스팅에서 별도로 다루도록 하겠습니다.



CTaskDialog::IsSupported() - 비스타 이전 OS들을 위한 대비
본격적인 CTaskDialog의 기능들을 알아보기 전에, 먼저 한가지 정리해야 할 점이 있습니다. 이전 포스팅에서 짧게 언급한 바 있지만, 태스크 대화상자는 비스타 이전 OS에서는 제공되지 않습니다. 그래서 만약 개발한 응용프로그램이 윈도우 XP 등에서 실행된다면 태스크 대화상자 출력 시점에 오류를 일으킵니다.  

(그림 1) 윈도우 XP에서 태스크 대화상자 출력을 시도할 때 나오는 오류 화면.


그렇기 때문에 개발한 프로그램이 비스타 이전 OS에서도 실행되어야 한다면 이런 경우를 위한 별도의 처리를 직접 해주어야만 합니다. 이럴 땐 어쩔 수 없이 기존의 메세지 박스나, CDialog를 상속받은 클래스를 직접 제작해 주어야 겠지요.
이런 처리를 찾아볼 수 있는 좋은 예가 바로 인터넷 익스플로러 8.0의 '세션 복구 기능' 입니다. 익스플로러 8.0은 비정상 종료되었다가 실행되는 경우 이전에 열려있던 페이지를 자동 복구할 것인지를 물어보는 창을 띄우는데, 실행중인 윈도우가 비스타 이전 버전이라면 일반 대화상자를, 비스타 이후 버전이라면 태스크 대화상자를 출력합니다.

(그림 2) 인터넷 익스플로러 8.0의 세션복구 기능에서 쓰인 태스크 대화상자.


(그림 3) 비스타 이전 OS에서는 태스크 대화상자 대신 기존의 대화상자를 출력합니다.


이런 식으로 OS 차원의 태스크 대화상자 사용 가능여부를 확인하고자 할 때에는, 직접 OS의 버전을 얻어와서 기능 지원 여부를 판별할 수도 있겠지만 CTaskDialog::IsSupported() 정적 함수를 이용해서 쉽게 확인할 수 있습니다.

if( CTaskDialog::IsSupported() ) // 태스크 대화상자 사용 가능 여부를 확인
{
    // 태스크 대화상자 호출.
    CTaskDialog::ShowDialog(message, emptyString, title, 0, 0, TDCBF_OK_BUTTON);
}
else
{
    // 지원하지 않는 OS인 경우는 예전 방식으로 처리.
    AfxMessageBox(message);
}
(코드 1) CTaskDialog::IsSupported() 함수를 통해 태스크 대화상자 사용 가능 여부를 확인.

참고로 윈도우 서버 2008은 비스타 이전에 나온 OS이므로 태스크 대화상자를 사용할 수 있습니다. 물론 비스타나 윈도우 7 처럼 예쁜 모양은 아니지만요 ^^;

(그림 4) 윈도우 서버 2008에서 출력되는 태스크 대화상자의 모습. 출처 : http://mariusbancila.ro/blog/2009/03/10/task-dialog-in-mfc/

 


태스크 대화상자의 기본적인 구성
태스크 대화상자는 기본적인 구성은 MSDN에 있는 아래의 샘플 스크린샷에 아주 잘 나타나 있습니다.

(그림 5) 태스크 대화상자의 기본적인 구성. (출처 : MSDN)


(그림 5)에서 알 수 있듯이 태스크 대화상자는 다양한 컨트롤들과 기능들을 제공합니다. 오늘은 우선 예전 AfxMessageBox() 수준의 심플한 사용방법을 알아보겠습니다. 간단한 메세지를 사용자에게 노출하거나, 기본적인 버튼을 통해 사용자 입력을 받아오고자 할 때는 오늘 소개하는 ShowDialog 함수를 이용하는 것이 좋습니다.


첫 번째 예제 : 일단 한 번 띄워봅시다
자, 이제 정말로 태스크 대화상자를 사용하기 위한 방법을 알아보죠. 가장 간단하게 태스크 대화상자를 출력하는 방법은 정적 함수인 CTaskDialog::ShowDialog() 를 사용하는 방법입니다. 이 함수를 사용하면 CTaskDialog의 객체를 만들지 않고도 바로 태스크 대화상자를 띄울 수 있습니다.
일단 속 시원하게 코드부터 보겠습니다! ShowDialog 정적 함수를 이용한 코드와, 실제 출력된 태스크 대화상자의 모양입니다.

INT_PTR ret = CTaskDialog::ShowDialog( L"본문 들어가는 곳", L"제목 들어가는 곳", L"타이틀 적는 곳", IDS_STRING102, // 첫 번째 커맨드 버튼. IDS_STRING104 ); // 마지막 커맨드 버튼. if( ret == IDYES ) { // blah blah... }

(코드 2) 드디어 등장했습니다! 태스크 대화상자를 띄우는 첫 번째 코드입니다!

(그림 6) (코드 2)를 통해 출력한 태스크 대화상자의 모습.


태스크 대화상자의 설명을 위해 두 차례나 걸친 포스팅에서 수없이 떠들었던 것에 비해, 너무나도 단순합니다. 그냥 함수 호출 하나 했더니 뜨는군요. 제목, 본문, 타이틀을 설정하는 것은 인자로 직접 문자열을 넣어주고 있으므로 추가 설명이 없이도 쉽게 확인하실 수 있습니다.
스크린샷을 보면 우리의 첫 번째 태스크 대화상자에서는 세 개의 커맨드 버튼을 가지고 있습니다. 커맨드 버튼은 예, 아니요, 확인, 취소 등과 같은 기존 대화상자의 기본적인 버튼 이외에 자유로운 출력 문자열을 설정할 수 있는 의사 입력 버튼 입니다. 태스크 대화상자의 가장 중앙부에 위치하며, 사실상 태스크 대화상자에서 가장 중요한 컨트롤이라고 할 수 있습니다. ShowDialog 함수를 이용할 때 커맨트 버튼을 넣기 위해서는 응용 프로그램의 리소스 파일에 있는 스트링 테이블을 참조합니다. 스트링 테이블에 커맨드 버튼의 설명으로 사용할 문자열들을 차례로 입력하고, 해당 스트링 아이디의 처음과 마지막 값을 ShowDialog의 네 번째, 다섯 번째 인자로 넣어줍니다.

(그림 7) 커맨드 버튼을 추가하기 위해 스트링 테이블을 사용하는 예시.


(그림 6)이 우리의 첫 번째 대화상자 예시에 쓰인 스트링 테이블 입니다. 태스크 대화상자에는 스트링 테이블의 문자열이 출력되고, 사용자가 해당 커맨드 버튼을 선택한 경우 ShowDialog의 리턴값으로 스트링 ID가 반환됩니다. 예제의 세 번째 커맨드 버튼처럼 화면에 여러 줄의 텍스트를 출력하고 싶다면 문자열 안에 개행문자를 이용해 여러 줄의 텍스트를 넣어주면 됩니다.



CTaskDialog::ShowDialog(...) 함수를 좀 더 자세히 알아봅시다.
ShowDialog 함수의 인자는 모두 8개 입니다. 예제에서는 다섯개의 인자만을 사용했고 나머지 인자들은 기본값이 쓰였습니다. 함수의 전체적인 기본형은 아래와 같습니다.  

static INT_PTR CTaskDialog::ShowDialog(
   const CString& strContent,
   const CString& strMainInstruction,
   const CString& strTitle,
   int nIDCommandControlsFirst,
   int nIDCommandControlsLast,
   int nCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON,
   int nTaskDialogOptions = TDF_ENABLE_HYPERLINKS | TDF_USE_COMMAND_LINKS,
   const CString& strFooter = _T("")
);

다섯 번째 인자까지는 설명이 되었으니 나머지 인자를 보자면,
  • nCommonButtons : 태스크 대화상자 오른쪽 하단에 출력되는 기본 버튼들을 설정합니다. 기본값으로 '예', '아니오' 두 개의 버튼이 출력됩니다.
  • nTaskDialogOptions : 태스크 대화상자의 여러가지 옵션을 조절할 수 있는 인자입니다. 옵션에 대한 플래그 값은 아래에서 보다 자세히 설명합니다.
  • strFooter : 태스크 대화상자의 가장 아래쪽에 출력되는 꼬릿말 부분입니다.
기본 버튼으로 설정할 수 있는 플래그는 총 여섯가지이고, CommCtrl.h에 정의되어 있습니다.
  • TDCBF_OK_BUTTON - 확인
  • TDCBF_CANCEL_BUTTON - 취소
  • TDCBF_YES_BUTTON - 예
  • TDCBF_NO_BUTTON - 아니오
  • TDCBF_RETRY_BUTTON - 재시도
  • TDCBF_CLOSE_BUTTON - 닫기
태스크 대화상자의 옵션을 조절할 수 있는 플래그는 총 열 여섯가지이고, 역시 CommCtrl.h 파일에 정의되어 있습니다. 이 중에서, ShowDialog() 함수와 함께 쓰일 수 있을 만한 플래그 몇 가지만을 정리해 보면 아래와 같습니다.
  • TDF_ENABLE_HYPERLINKS
    하이퍼 링크를 활성화 합니다. 텍스트에 하이퍼 링크를 넣고 싶을 때에는 문자열에서 <a href=\"http://vsts2010.net\">하이퍼 링크</a>처럼 HTML 문법으로 설정할 수 있습니다.
  • TDF_ALLOW_DIALOG_CANCELLATION
    태스크 대화상자의 오른쪽 상단에 창 닫기 버튼이 생기고, Esc키나 Alt + F4로도 창을 끌 수 있게 됩니다. 닫기버튼이나 키보드 조작으로 창을 닫은 경우는 IDCANCEL이 리턴됩니다.
  • TDF_USE_COMMAND_LINKS
    커맨드 버튼을 사용하도록 설정합니다. 이 플래그가 설정되지 않으면 커맨드 버튼으로 설정한 버튼들도 기본 버튼들처럼 출력됩니다.
  • TDF_USE_COMMAND_LINKS_NO_ICON
    커맨드 버튼에 아이콘을 출력하지 않고 텍스트만 표시하게 설정합니다.
  • TDF_SHOW_PROGRESS_BAR
    프로그레스바 컨트롤을 표시합니다.
  • TDF_SHOW_MARQUEE_PROGRESS_BAR
    프로그레스바 컨트롤을 Marquee 형식으로 출력합니다.
  • TDF_POSITION_RELATIVE_TO_WINDOW
    태스크 대화상자를 부모 윈도우의 중앙 위치에 나타나도록 합니다. 이 플래그가 설정되지 않으면 바탕화을 기준으로 중앙 위치에 출력됩니다.
  • TDF_RTL_LAYOUT
    태스크 대화상자에 출력되는 텍스트들을 오른쪽에서 왼쪽으로 출력합니다.
  • TDF_CAN_BE_MINIMIZED
    태스크 대화상자의 오른쪽 상단에 최소화 버튼이 생기고, 버튼을 누르면 창이 최소화 됩니다.
위의 아홉가지 플래그 정도가 ShowDialog 함수를 이용한 간단한 사용시에도 유용하게 쓰일만한 기능들 입니다. 이 중에 프로그레스바와 관련된 플래그 같은 경우, TDF_SHOW_PROGRESS_BAR를 넣어주면 실제로 프로그레스바가 표시되지만, 프로그레스바의 값을 조절한다거나, 오류상태를 표시하는 등의 세밀한 처리를 하는 것은 어렵습니다. 이런 경우는 ShowDialog 함수를 통한 호출보다는 직접적으로 CTaskDialog 의 객체 혹은 CTaskDialog 파생클래스의 객체를 만들어서 처리해야 합니다. TDF_SHOW_MARQUEE_PROGRESS_BAR 플래그로 Marquee 형식을 출력할 수도 있지만 이런 경우도 대게는 타이머를 설정하고 자체적으로 동작이 진행중임을 표시하기 위해 주로 사용하므로, 이또한 ShowDialog를 통한 출력에는 생뚱맞습니다.

(그림 8) 예제 대화상자에 꼬릿말과 프로그레스바를 추가한 모습.


위의 (그림 8) 스크린샷을 봅시다. 꼬릿말은 그럭저럭 쓸만 하다고 하지만, 텅 빈 프로그레스바는 보는 이의 마음까지 황량하게 만듭니다. 아무래도 좀 더 추가적인 처리가 필요해 보입니다. ShowDialog 함수를 통해서도 프로그레스바 컨트롤을 출력할 수는 있지만, 이를 세밀하게 제어하는 것은 무리입니다. 이를 포함해 여러가지 컨트롤의 처리에 대한 내용은 다음 포스팅에 설명하도록 하겠습니다.



Outro
이번 포스팅 에서는 태스크 대화상자 미지원 OS를 식별하는 방법과, 태스크 대화상자의 기본적인 구성, 그리고 메시지 박스 수준의 간단한 태스크 대화상자 출력방법을 알아보았습니다. 정적 함수 ShowDialog()를 사용하면 AfxMessageBox()를 이용하는 것보다 좀 더 다양하게 머릿말, 본문, 꼬릿말 등으로 구분에 메세지를 설정할 수 있고, 모던한 디자인의 레이아웃을 갖춘 태스크 대화상자를 출력할 수 있습니다.
다음 포스팅에서는 태스크 대화상자가 제공하는 다양한 컨트롤 들을 활용할 수 있는 방법을 알아보도록 하겠습니다. 리소스 에디터로 직접 다이얼로그를 디자인하던 불편함에서 벗어나 함수호출 몇 줄만으로 다양한 기능을 추가하는 방법들을 정리할 예정입니다. 보다 미리 관련 내용을 확인하고 싶으신 분들은 MSDN(http://msdn.microsoft.com/en-us/library/bb760441(VS.85).aspx)과 다음의 페이지( http://www.nuonsoft.com/blog/2009/06/10/ctaskdialog-in-mfc-in-visual-c-2010/ )를 참고하시기 바랍니다.
그럼 다음 포스팅에서 뵙겠습니다.
감사합니다 ^^*


Reference
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

SharePoint 2010 Server Object Model

SharePoint 2010 | 2010/02/12 09:00 | Posted by 정홍주

SharePoint의 여러 어셈블리를 직접 호출하는 경우로 웹 파트와 관리자 유틸리티, 이벤트 등에서 사용이 가능합니다. 참조할 수 있는 부분은 SDK MSDN을 참고해 볼 수 있습니다.

 

이번 시간에서는 이전 버전에서도 살펴본 SPSite, SPWeb, SPList, SPListItem 등에 대한 내용을 서버 머신에서 돌아가는 WPF 응용 프로그램에서 액세스 해봅니다.

 

WPF 응용 프로그램을 생성합니다. 프로젝트 이름은 ServerOMWPF 라고 생성합니다.


지금은 대상 프레임워크가 4.0으로 되어 있습니다. 리스트 박스와 버튼을 추가해서 사이트의 목록이름을 리스트박스에 표시되게 해봅니다. 디자인 화면은 아래와 같습니다.



프로젝트에 Microsoft.SharePoint.dll

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI 밑에서 참조 추가합니다.


Get Item 버튼을 클릭해서 아래와 같이 코드를 작성합니다.
아래 코드는 SharePoint 사이트의 목록들의 이름을 리스트 박스에 추가하는 내용입니다.

프로젝트를 빌드하면 에러 나는 것을 알 수 있습니다. 특별한 코드가 아닌데도..,

서버 머신위에서 구동하는 Server Object Model의 응용 프로그램은 .NET Framework 3.5에서 구동되면서 X64, Any CPU로 설정되어야만 합니다. 그래서 에러를 만나게 됩니다.

Web Part, Visual Web Part 등은 별도 수정하지 않아도 됩니다.



프로젝트 속성에서 Application 메뉴에서 Target Framework3.5로 지정합니다.



Build 메뉴에서 Plaform Target“Any CPU”로 설정합니다.



프로젝트를 빌드하고 실행해봅니다. 그러면  Server Object Model을 이용한 간단한 WPF 프로그램의 결과를 아래와 같이 확인이 가능합니다.

 

 

 

개체 모델은 SDK MSDN을 참조할 수 있으며 다음 블로그에서 계속 알아보겠으며 위에서 간단하게 Server Object Model을 액세스하는 예와 실행하는 방법을 알아보았습니다.

 

크리에이티브 커먼즈 라이선스
Creative Commons License

'SharePoint 2010' 카테고리의 다른 글

SharePoint 2010 Server Object Model  (0) 2010/02/12
SharePoint 2010 데이터 기술  (0) 2010/02/11
SharePoint 2010 Event Receiver  (0) 2010/02/10
SharePoint 2010 Feature  (0) 2010/02/09
SharePoint 2010 Visual Web Part  (0) 2010/01/21
SharePoint 2010 Web Part 생성  (0) 2010/01/19

SharePoint 2010 데이터 기술

SharePoint 2010 | 2010/02/11 09:05 | Posted by 정홍주

이전 버전에서는 SharePoint 관련 개체와 데이터를 액세스하는 것은 서버 측면에서는 SharePoint Server Object Model CAML 을 사용하고 원격 클라이언트에서는 SharePoint Web Service를 이용했습니다. SharePoint Web Service CAML 의 사용이 쉽지 않았고 개발하기가 불편했습니다.

 

SharePoint 2010에서는 아래 그림처럼 클라이언트 측면에서 Client Object Model 을 제공하고 있으며 REST 기반의 액세스가 가능합니다. 서버 측면에서는 CAML 대신 LINQ를 사용할 수 있게 되었습니다.



이전 버전과 비교해서 생산성이나 접근할 수 있는 부분이 다양해서 아주 유용하게 사용할 수 있습니다.

 

Server Object Model을 알아보면 SharePoint 머신 위에서 구동되는 웹 파트, 이벤트, 관리자 프로그램, 배치 프로그램 등이며 SharePoint 어셈블리를 직접 호출할 수 있다는 것이 Server OM입니다.

 

LINQ는 목록의 수 많은 항목 중에서 조건에 맞는 항목을 가져오고 원하는 정렬을 시키려고 하면 CAML이라는 XML을 직접 구성하고 SPQuery 라는 클래스를 통해 넘겨주어야 했습니다. 그래서 별도로 SharePoint MVP가 만든 CAML Builder 라는 도구가 유용하게 사용되었습니다. 2010 환경에서도 CAML은 사용이 가능합니다만 LINQ는 알고 있는 것처럼 쿼리 식으로 개체를 데이터처럼 액세스 할 수 있습니다. 웹 파트 등에 사용하면 아주 유용하다는 생각이 팍 드실 겁니다.

 

Client OM은 서버 머신 위가 아닌 원격 클라이언트에서 동작되는데 SharePoint 개체나 데이터를 원격 클라이언트에서 접근할 수 있다는 것입니다.

생성할 수 있는 유형은 .NET, Silverlight, Javascript 를 통해 접근할 수 있습니다. SharePoint 2010에서는 Silverlight 환경이 기본적으로 구비되어 있으며 Silverlight 웹 파트도 기본적으로 생성되어 있습니다. Client OM을 사용할 수 있는 내용으로 Silverlight 웹 파트를 생성해서 접근할 수 있습니다.

 

REST 기반 API 는 기존 웹 서비스보다 더 간단하게 사용이 가능하며 개체로 접근을 손쉽게 할 수 있습니다. ADO.NET Data Services 를 이용해서도 SharePoint 개체와 데이터를 액세스 할 수 있습니다.

 

 

SharePoint 2010 데이터 기술을 알아보았고 다음 블로그부터 하나씩 구체적으로 알아보도록 하겠씁니다.

크리에이티브 커먼즈 라이선스
Creative Commons License

'SharePoint 2010' 카테고리의 다른 글

SharePoint 2010 Server Object Model  (0) 2010/02/12
SharePoint 2010 데이터 기술  (0) 2010/02/11
SharePoint 2010 Event Receiver  (0) 2010/02/10
SharePoint 2010 Feature  (0) 2010/02/09
SharePoint 2010 Visual Web Part  (0) 2010/01/21
SharePoint 2010 Web Part 생성  (0) 2010/01/19

[JumpToDX11-11] DirectCompute 를 위한 한걸음!

DirectX 11 | 2010/02/11 09:00 | Posted by 조진현


앞선 시간을 통해서 GPGPU 를 위해서 마이크로소프트가 제공하는 플랫폼이
DirectCompute 라는 것이라고 말씀드렸습니다.
앞으로 DirectX11 을 지원하는 모든 그래픽카드들은 이 DirectCompute 를 지원할 것입니다.
그 이외에도 일부 DirectX10 을 지원하는 그래픽카드들도 지원을 하고 있습니다.


GPGPU 를 위해서 가장 기본적이고 핵심이 되는 기능은 무엇일까요?
저는 GPU 에서 처리된 메모리를 CPU 쪽의 메모리로 보내는 것이라고 생각합니다.
( 이는 개인 의견입니다.^^ )
즉, 그래픽카드에 있는 메모리를 메인메모리로 보내는 작업입니다.
DirectX9 세대까지는 이 작업이 불가능 했습니다.
예를 들면, 그래픽스 파이프라인 중간에 처리된 결과를 다시 가공할 수 있는 방법은
VertexShader 나 PixelShader 같은 쉐이더 스테이지 정도 뿐이였습니다.

하지만 DirectX10 부터는 이들에 대한 중간 결과를 메인메모리로 보내는 기능이 추가되어지면서,
GPGPU 의 시작을 알렸다고 생각합니다.
이 단순한 Copy 작업이 앞으로도 얼마나 유용하게 사용될 수 있을지는 기대가 상당합니다.



< DirectCompute 를 위한 ComputeShader >

DirectCompute 를 위해서 개발자가 할 일은 ComputeShader 를 작성하는 일입니다.
ComputeShader 는 HLSL 이라는 기존 DirectX 의 쉐이더 문법 구조로 작성을 합니다.




HLSL 코드는 DirectX 쉐이더 컴파일러인 FXC 나 API 를 통해서 컴파일 됩니다.
HLSL 은 결국 최적화된 IL 코드를 생성하게 되고,
이 IL 코드를 기반으로 런타임에 각각의 하드웨어에 최적화된 명령어들로 변환
되어져서 실행됩니다.


< GPGPU 에게 실행이란? >

GPGPU 를 활용해서 실행한다는 것은 하드웨어 내부적으로 어떻게 동작하도록 할까요?
앞선 시간에 GPU 는 병렬 처리에 최적화된 많은 SIMD 형태로 구성되어져 있다고 언급했었습니다.
결국 이들은 스레드들의 그룹으로써 실행합니다.
스레드들을 얼마나 많이 생성할 것인지를 개발자가 정해주면, 그에 맞게 연산을 수행합니다.

API 에서는 이들을 큰 그룹으로 나누어 줍니다.
큰 그룹으로 나누어 주는 API 는 ID3D11DeviceContext::Dispatch() 입니다.

ipImmediateContextPtr->Dispatch( 3, 2, 1 );

이렇게 큰 블럭 단위로 나누고 난 후에
ComputeShader HLSL 에서는 이들을 세부적인 스레들로 분할하는 문법을 지정합니다.

[numthreads(4, 4, 1)]
void MainCS( ... )
{
        ....
}




결과적으로 위의 그림처럼 스레드들이 생성되어서 병렬적으로 실행이 됩니다.
위에 나열된 숫자들은 스레드 ID 로써의 역활을 합니다.
즉, 어떤 스레드의 ID 가 MainCS 함수에 파라메터로 넘오오면,
그 ID 를 통해서 해당 버퍼에 값을 작성하게 됩니다.

아래에 간단한 예가 있습니다. 

[numthreads( 256,1,1) ]

void VectorAdd( uint3 id: SV_DispatchThreadID )
{

  gBufOut[id] = gBuf1[id] + gBuf2[id];

}


아무리 스레드들이 복잡하게 동작하더라도, 위와 같이 ID 를 통해서 제어한다면
그 어떤 작업도 문제없이 할 수 있습니다.

일단 먼저 어떻게 DirectCompute 가 실행되어지는지에 대해서 살펴보았습니다.
실행까지 가기 위해서는 일련의 절차를 거쳐야 합니다.
이들에 대해서는 앞으로 차근차근 살펴보겠습니다.



참고 자료
http://microsoftpdc.com/Sessions/P09-16
본 내용은 위의 PDC 를 참고해서 만들었습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License

SharePoint 2010 Event Receiver

SharePoint 2010 | 2010/02/10 09:00 | Posted by 정홍주

항목을 추가하고 삭제하는 경우 이벤트 코드를 작성해야 할 필요가 있습니다. 이전 버전에서도 마찬가지로 클래스를 상속하여 Feature Object Model을 통해 작업을 했지만 수작업이 필요했습니다. Visual Studio 2010을 통해 새로워진 Event Receiver에 대한 부분을 이번 시간에 알아 보도록 하겠습니다.

 

HJ 라는 공지 사항이 있습니다. 간단히 삭제가 안되게 Event 코드를 작성해봅니다.

Visual Studio 2010 SharePoint 프로젝트중 Empty 프로젝트를 생성합니다. 이름은 EventDemo라고 합니다.

EventDemo 프로젝트를 오른쪽 클릭하여 새 항목을 하나 추가합니다. 새 항목은 아래와 같이 Event Receiver를 선택합니다.


Name
은 기본값을 그대로 하고 Add를 선택합니다. 그럼 해당 사이트에 연결하여 어떤 이벤트로 할 것인지와 어떤 목록인지, 어떤 이벤트 인지를 그래픽적으로 선택하게 됩니다.



이벤트 종류는 단순 List Item Event 뿐만 아니라 여러 가지가 나와 있습니다.


List Item Events
Announcements를 선택하고 “A item is being deleted”를 선택합니다.


마침을 선택하면 Feature가 생성되는 것을 확인 할 수 있습니다.

Feature의 활성, 비활성 이벤트를 어떻게 만드냐 하면 Feature1을 오른쪽 클릭하면 아래와 같이 Add Event Receiver를 볼 수 있습니다. 여기서 생성은 하지 않습니다.



EventReceiver1 폴더 아래의 Elements.xml을 살펴봅니다. 다 제대로 구성된 것을 확인할 수 있습니다. (이제부터는 특정 공지사항에만 이벤트를 적용시킬 수 있습니다. ^^)



마침을 선택했을 때의 코드는 아래와 같이 생성되어 있습니다. Deleting만 선택했기 때문에 이벤트 메서드는 하나만 생성되어 있습니다.



간단히 코딩을 해서 HJ 라는 공지사항에 글을 삭제하지 못하도록 해봅니다.



위의 코딩은 이전 버전의 스타일이며 2010에서는 추가로 뒤에서 다룰 Dialog Framework 으로 에러 핸들링을 할 수 있습니다.

 

EventDemo 프로젝트를 오른쪽 클릭하여 Deploy를 선택하고 완료 후 HJ 공지사항의 항목을 새로 추가합니다. 그러면 아래와 같이 결과 페이지를 확인할 수 있습니다.



Visual Studio 2010에서 만든 Event Receiver가 잘 동작되는 것을 확인했으며 Visual Studio 2010을이용해서 보다 더 생산성 있게 작업이 가능하다는 것을 알 수 있습니다.

 

크리에이티브 커먼즈 라이선스
Creative Commons License

'SharePoint 2010' 카테고리의 다른 글

SharePoint 2010 Server Object Model  (0) 2010/02/12
SharePoint 2010 데이터 기술  (0) 2010/02/11
SharePoint 2010 Event Receiver  (0) 2010/02/10
SharePoint 2010 Feature  (0) 2010/02/09
SharePoint 2010 Visual Web Part  (0) 2010/01/21
SharePoint 2010 Web Part 생성  (0) 2010/01/19

Visual Studio 2010 RC 공개

Visual Studio 2010/Visual Studio 2010 | 2010/02/09 11:41 | Posted by 엄준일(땡초)

금일 2010년 2월 9일이 MSDN Subscription 을 통해 공개가 되었습니다. (미국 시간 2월 8일)

Visual Studio 2010 RC(Release Candidate) 공개
http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx

 

이전 Visual Studio 2010 Beta 2 에서 발생하는 가상 메모리와 성능 관련된 문제에 대해서 이번 RC(Release Candidate) 버전에서는 상당히 개선이 되었다는 인터넷 블로거들의 반응이 보입니다.

이미 Visual Studio 2010 RC 버전을 설치한 외국의 블로거의 말에 의하면, Microsoft 는 이런 문제를 해결하는 것에 대해 용기있고 현명함에 칭찬을 아끼지 않고 있네요. 필자 또한 이번 RC 버전에 대해 Microsoft 대한 찬사를 아끼지 않습니다.

일반적으로 RC(Release Candidate) 버전은 더 이상의 기능이나 사용자의 피드백의 반영이 없고, RC 에 안정성을 확보하여 RTM(Release to Manufacture) 버전으로 정식 제품이 공개가 됩니다. 이전의 Beta 버전을 설치하기 꺼려하셨던 분들도 크리티컬한 이슈가 해결된 RC 버전을 설치하셔서 미리 공부하시면 될 것 같습니다.

앞으로 다가오는 4월달 정식 제품이 더욱 기대가 되는 하루입니다. ^^

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License