GSI

MFC 에서 ListBox 에 내용을 추가 하는 코드로 테스트 해본겁니다.

void UTRACE(char* fmt...)
{
 //CString output;
 CTime time = CTime::GetCurrentTime();

 std::ostringstream outstream;
 outstream << "[" << time.GetHour() << ":" << time.GetMinute() << ":" << time.GetSecond() << "] ";

 va_list ap;            //argument pointer

 char*p; int ival; double dval;
 char pBuf[256];  // 버퍼용

 va_start(ap, fmt);        //make ap point to the final named arg
 for(p=fmt; *p; p++) {
  if(*p !='%'){
   outstream << *p;
   //putchar(*p);
   continue;
  }

  switch(*++p){
    case 'd':
     ival = va_arg(ap, int);        //get the argument and move on to the next
     outstream << ival;
     /*itoa(ival, pBuf, 10);
     for(int i=0 ; i < (int)strlen(pBuf) ; i++)
     {
      putchar(pBuf[i]);
     }*/
     break;

    case 'f':
     dval = va_arg(ap, double);        //get the argument and move on to the next
     outstream << dval;
     /*dval = atof( pBuf );
     for(int i=0 ; i < (float)strlen(pBuf) ; i++)
     {
      putchar(pBuf[i]);
     }*/
     break;

    case 's':
     sarg = va_arg(ap, const char *);        //get the argument and move on to the next
     outstream << sarg;
     break;
    case 't':
     outstream << "\t";
     break;

    default:
     outstream << *p;
     break;

  }
 }
 va_end(ap);

 g_pDebugListBox->AddString( outstream.str().c_str() );
 g_pDebugListBox->SetCurSel( g_pDebugListBox->GetCount()-1 );

// 여기에서 콘솔 모드면 아래 코드를 적용하면 될듯 하다.
 memset( pBuf, 0, sizeof(char) * 256 );
 strcpy( pBuf, outstream.str().c_str() );
 //p = pBuf;
 printf( pBuf );
}

Posted by gsi
:

사용자 삽입 이미지

기본 UI만 구현해 봤어요.

UserControl의 기능을 처리 하기 위해서 의존 프로퍼티도 있어야 할거 같은데요. Click 버튼을 누르면 UserControl의 시작 스토리 보드 객체를 Begin() 하면 될듯, 더 내용을 추가 하고 몇가지 테스트를 해보면서 조금씩 기본기를 익혀야 할거 같다.

관련 코드
Posted by gsi
:

사용자 삽입 이미지

Win Form 에서 WPF 를 추가 해서 사용할때는 ElementHost를 사용합니다.
자세한 내용은 Win Form 에 WPF 컨트롤 붙이기 를 참고 하시구요.

그렇다면 이제 반대로 WPF 에서 Win Form을 추가 해서 쓰고 싶을때는 어떻게 할까 고민해보니.
WindowsFormsHost 라는 객체를 이용하면 처리가 되네요.

<Grid>
    <my:WindowsFormsHost ... />
</Grid>

이렇게 xaml 코드를 추가한 후에 cs 파일에서 추가를 아래와 같이 합니다.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    WindowsFormsControlLibrary1.UserControl1 uc =
        new WindowsFormsControlLibrary1.UserControl1();

    windowsFormsHost1.Child = uc;
}

중점 사항

  • UserControl 클래스를 추가 해서 사용해야 합니다. 즉, userControl 의 dll 파일을 참조 추가 해서
    사용해야 한다는 말이죠.
  • WPF 에서 Win Form의 UserControl의 객체를 접근하기 위해서는 노출이 되어 있지 않기 때문에 게터 메소드를 하나 만들어서 해야 합니다.
    예)  public string TextValue { get { return textBox1.Text; } }
  • 위의 게터 메소드가 노출되어 있다면 아래와 같이 WPF를 통해서 값을 참조할 수 있네요.
    예) WindowsFormsControlLibrary1.UserControl1 uc =
            (WindowsFormsControlLibrary1.UserControl1)windowsFormsHost1.Child;
         textBox1.Text = uc.TextValue;

다른 몇가지 사항에 대해서는 더 테스트를 해보지 않았습니다.
우선 자세한 코드는 아래 파일을 보세요.
더 자세한 사항이나 기타 의논하고 싶으신 부분 있으시면 언제든 연락 부탁 해요.

관련 파일:


Posted by gsi
:

Iterator 는 반복자로 알고 있는데요.

헤더 퍼스트 책을 보니
한개 이상의 다른 클래스들을 Iterator를 통해서 출력 부분을 동일화 해준다.
실제 데이터 클래스에 반복자 부분을 넣지 않고, Iterator를 직접 생성해서 관리 한다..
이정도로 생각하면 될까요?.

자바 클래스로 샘플 자료가 인터넷에 있던걸 C++로 처리를 해봤는데요.
코드는 아래에 위치 합니다.

여기서 몇가지 궁금증이 발생 합니다.
1. PersonIterator* personiter = (PersonIterator*)persons.CreatIterator(); 를 통해서
   객체를 Iterator로 보내기 위해서요. 내부에 new 를 사용했습니다.
   이때 C++에서는 삭제를 해줘야 하는 번거로움이 발생을 하게 됩니다.
   그래서 참조 형태로 함수에서 인자로 넘기는 것도 고려를 해봤지만. 코드가 깔끔하지 않더라구요.
   다르게 PersonIterator 쪽에 operator=()를 사용해서 Persons 객체를 PersonIterator로 대입하도록 처리도 해봤지만.
   UML의 그림이 조금 이상하게 나와서 ^^..
   자바나 C# 같은 경우는 가비지가 있어서 그런지 모르겠지만 포인터라는 개념 자체가 조금 다르게 되다 보니
   넘길때도 new 해서 객체를 생성해서 넘기게 되니 C++의 형태와 같다는 생각도 들구요.

2. UML을 표현하는데 있어서 아래와 같이 작성을 해봤습니다.
   헤더 파일만 리버스 해서 StarUML에 적용해 봤습니다. 그런데 리버스 할때 상속 구조는 화살표가 생기는데요.
   vector<>를 사용한 부분에서는 제대로 표현이 안되네요.

3. Iterator 패턴을 사용함에 있어서 반복해서 출력해 주거나, 특정 객체를 찾아 주거나, 기타 다른 작업들을
   데이터가 들어가 있는 클래스에 계속 구현하는게 아니라 Iterator를 상속 받아서 여러개를 만들어서 관리를 하는게
   더 좋다고 생각하면 될까요?.. 기존에는 작업을 하나의 데이터 포멧이 있다면 그곳에 드로잉, 탐색, 기타 위치 조정 등에
   대한 코든 코드를 다 넣다 보니 비대해 지고 관리가 힘들어져서 Iterator를 사용해서 분리를 시켜서 적용하면
   더 좋을거 같다는 생각은 드네요.

제가 아직 경험이 부족하니 아래 코드를 보고 잘못 된 점이 있다면 지적 많이 부탁 드려요 ^^..

[코드를 UML로 표현]

사용자 삽입 이미지

/** 코드 구현부 시작  **/

// 헤더 파일///////////////////////////////////////////////////////////////
#pragma once

class Person;
class Persons;

/************************************************************************/
/*                                                                      */
/************************************************************************/
class Iterator
{
public:
 Iterator() {}
 ~Iterator() {}

 virtual bool hasNext() = 0;
 virtual Person* Next() = 0;
};


/************************************************************************/
/*                                                                      */
/************************************************************************/
class PersonIterator : public Iterator
{
public:
 PersonIterator() {}
 PersonIterator( Persons* p );
 ~PersonIterator();

 PersonIterator& operator = ( Persons* p );

 bool  hasNext();
 Person*  Next();

protected:
 Persons*     m_pPersons;
// vector< Person >*   vperson;
// vector< Person >::iterator vpersoniter;
 int       number;
};


/************************************************************************/
/*                                                                      */
/************************************************************************/
class Person
{
public:
 Person( string name );
 ~Person();

 void  Print();
 string&  getName();

public:
 string m_name;
};


/************************************************************************/
/*                                                                      */
/************************************************************************/
class Aggregate
{
public:
 Aggregate() {}
 ~Aggregate() {}

 virtual void iterator( Iterator* iter ) {}
};


/************************************************************************/
/*                                                                      */
/************************************************************************/
class Persons : public Aggregate
{
public:
 Persons();
 ~Persons();

 void  AddPerson( Person& p );
 Iterator* CreatIterator();
public:
 int     m_Number;
 vector< Person > m_Array;
};

// 소스 파일///////////////////////////////////////////////////////////////

// IteratorPattern.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"
#include "IteratorPattern.h"

/************************************************************************/
/*                                                                      */
/************************************************************************/
Person::Person( string name )
{
 m_name = name;
}

Person::~Person()
{
}

string& Person::getName()
{
 return m_name;
}

void Person::Print()
{
 cout << "이름:" << m_name.c_str() << endl;
}


/************************************************************************/
/*                                                                      */
/************************************************************************/
PersonIterator::PersonIterator( Persons* p )
{
 m_pPersons  = p;
 number   = 0;
}

PersonIterator::~PersonIterator()
{
}

PersonIterator& PersonIterator::operator = ( Persons* p )
{
 m_pPersons  = p;
// vperson   = &rhs.m_Array;
// vpersoniter  = vperson->begin();
 number   = 0;
 return *this;
}

bool PersonIterator::hasNext()
{
 if( number < (int)m_pPersons->m_Array.size() )
  return true;
 else
  return false;
}

Person* PersonIterator::Next()
{
 vector< Person >::iterator iter = m_pPersons->m_Array.begin();
 iter += number++;
 return (Person*)&(*iter);
}


/************************************************************************/
/*                                                                      */
/************************************************************************/
Persons::Persons()
{
 m_Number = 0;
 m_Array.clear();
}

Persons::~Persons()
{
}

void Persons::AddPerson( Person& p )
{
 m_Array.push_back( p );
}

Iterator* Persons::CreatIterator()
{
 PersonIterator* pi = new PersonIterator( this );
 return pi;
}

/** 코드 구현부 끝 **/

/** 메인 시작 **/
int _tmain(int argc, _TCHAR* argv[])
{
    Persons persons;

    persons.AddPerson( Person( "손병욱" ) );
    persons.AddPerson( Person( "천성구" ) );
    persons.AddPerson( Person( "박창준" ) );

    PersonIterator* personiter = (PersonIterator*)persons.CreatIterator();

    while( personiter->hasNext() )
    {
        Person* pp = personiter->Next();
        if( pp )
        {
            pp->Print();
        }
    }
    delete personiter;

    return 0;
}
/** 메인 끝 **/

Posted by gsi
:

Google
 
UML을 사용하다 보면 아직까지 익숙하지 않아서 화살표의 의미 자체가 조금 힘들게 받아 들여 진다.
아래의 이미지는 Iterator 패턴을 사용해서 화살표가 의미 하는 것을 적어 보았다.

사용자 삽입 이미지
Posted by gsi
: