GSI

C++ 의 변수를 C#의 프로퍼티 처름 사용하기..

말은 거창하지만 다른건 없다. 해당 값을 입력 받을 경우 다른 변수에 값을 추가 하거나 기타 다른 이벤트를 처리 할때 해당 값에 의존적인 클래스에서 처리 할 수 있다는 부분이다.
m_Val = 100 이렇게 입력 받은 후에 다른 이벤트 처리를 의존 프로퍼티 클래스를 상속받은 클래스에서 처리가 가능하게 만들어 본겁니다. ^^..
사용은 해봐야 알겠지만. 괜찮은 확장이 가능해 질거 같네요..

--라이브러리 클래스--

class CGsiDependencyProperty
{
public:
 CGsiDependencyProperty() {}
 virtual ~CGsiDependencyProperty() {}

 //값이 바뀌게 되면 호출할 수 있도록 바인딩 되는 함수
 virtual void PropertyChanged() {
  int iii = 0;
 };
};

template<class T>
class CGsiDataBind
{
public:
 CGsiDataBind() { m_pDependencyProp = NULL; }
 virtual ~CGsiDataBind() { }

 // int a = ?? 이런 코드가 가능합니다.
 operator T() {
  return m_Data;
 }

 // ?? = 100 이런 코드가 가능합니다.
 T operator = (T value) {
  m_Data = value;

  if(m_pDependencyProp)
   m_pDependencyProp->PropertyChanged();

  return m_Data;
 }

 friend class CGsiDependencyProperty;

 void SetDepend(CGsiDependencyProperty* refOper0 = NULL) {
  m_pDependencyProp = refOper0;
 }

protected:
 T      m_Data;
 CGsiDependencyProperty* m_pDependencyProp;
};

-- 사용법--
해당 변수의 값을 입력 할때 특정 클래스의 함수가 호출 되도록 하는 구조를 취할때
사용하면 됩니다.

호출 되는 함수가 있는 클래스 생성할때 CGsiDependencyProperty을 상속 받아서, virtual로된 함수 PropertyChanged() 를 선언해야합니다

class CDependA : public CGsiDependencyProperty
{
 virtual void PropertyChanged() {
  //값이 바뀌면 호출됨
 };
};

이제 변수를 선언하고 프로퍼티 클래스를 선언해서 연결한 후에
변수를 사용하면 됩니다.

 // 의존 프로퍼티 선언
 CDependA    m_Val0Property;

 // 변수 선언
 CGsiDataBind<int>  m_Val0;
 m_Val0.SetDepend(&m_Val0Property);

 m_Val0 = 100;           // 100을 입력하면 m_Val0Property의 클래스 내부 함수가 호출됩니다.
 int value = m_Val0;    // 해당 값을 일반 변수로 리턴받을 수 있습니다.

Posted by gsi
:

잠깐의 휴식..

내 일상 2007. 11. 16. 18:03 |



이번 주말에 시골을 갈려고 합니다.
상황이 이렇게 되서 애기도 시골에 있고 해서..
넘 보고 싶네요 ^^.. 우리딸..

주말을 통해서 재충전 하고 와야 겠어요 ^^..
모두 주말은 활기차게 보내세요 ..
Posted by gsi
:

MFC DLL 사용하기

C++ 2007. 11. 16. 17:58 |

MFC DLL 사용하기

MFC DLL 프로젝트를 하나 생성한다. ( DllLib 라는 이름으로 프로젝트를 생성한다.)

DllLib.cpp 파일에 해당 하는 함수나 클래스 인스턴스를 하나 만듭니다.
이때 AFX_API_EXPORT를 앞에 붙여서 만들면 됩니다.

AFX_API_EXPORT int Plus(int _first, int _second);
AFX_API_EXPORT void DrawTest(CDC* pDC);

AFX_API_EXPORT int Plus(int _first, int _second)
{
 _first += m_Test.value;

    return (_first+_second);
}

AFX_API_EXPORT void DrawTest(CDC* pDC)
{
 pDC->MoveTo(10, 10);
 pDC->LineTo(100, 100);
}

이렇게 만든 후에 MFC Dialog 베이스로 프로그램을 하나 만들어서 테스트를 해봅니다.
(DllTestView 라는 이름으로 프로젝트를 생성한다.)

원하는 코드에서 해당 함수를 호출 하기 위해서 DllLib에서 만들어 놓았던 함수들을
선언해 줍니다.

AFX_API_IMPORT int Plus(int _first, int _second);
AFX_API_IMPORT void DrawTest(CDC* pDC);

이후에 사용은 아래와 같이 하시면 됩니다.

void CDllTestViewDlg::OnPaint()
{
......
 {
  CPaintDC dc(this);
  DrawTest(&dc);        // DC를 넘겨서 라인을 찍는 함수 테스트
  CDialog::OnPaint();
 }
}

// 두개의 에디터 박스에서 값을 int 형으로 받아서 합계를 내주는 함수 사용
void CDllTestViewDlg::OnBnClickedButton1()
{
 UpdateData(TRUE);
 m_Sum = Plus(m_Left, m_Right);
 UpdateData(FALSE);
}

요즘은 프로젝트가 대형화 되고, 한사람이 짜는 프로젝트가 많이 없다 보니
슬슬 DLL을 써야 할거 같다.

Posted by gsi
:

데이터 바인딩#1 - 기본
데이터 바인딩#2 - Binding Mode
데이터바인딩#3 - DataContext
▶데이터 바인딩#4 - TextBox vs Run
데이터 바인딩#5 - FrameWorkElement Demo
데이터 바인딩#6 - IValueConverter


소스 정보를 사용해서 타겟에 적용할때 텍스트로 원하는 형태의 문자열로 만들어서 하고 싶을때가 있다.
아래의 예제를 보자.

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" Name="window">

    <StackPanel Orientation="Horizontal"
                HorizontalAlignment="Center" VerticalAlignment="Center"
                DataContext="{Binding ElementName=scroll}" Name="stackpanel">
        <TextBlock Text="{Binding ElementName=window, Path=ActualWidth}" />
        <TextBlock Text=" &#x00D7;" />
        <TextBlock Text="{Binding ElementName=window, Path=ActualHeight}" />
        <TextBlock Text=" Device independent units"/>
    </StackPanel>

</Window>

실행해 보면 300 x 300 device independent units 라는 글자를 볼 수 있다.
TextBlock를 여러개 써서 하는거 자체가 조금 어울리지 않아 보인다. 그래서 Run 을 사용하는 코드를 적용하게 되면 조금더 코드가 깔끔해지게 된다.

아래의 코드는 TextBlock로 이루어진 부분을 Run으로 처리한 내용이다.

        <TextBlock>
            <Run Text="{Binding ElementName=window, Path=ActualWidth}" />
            <Run Text=" &#x00D7;" />
            <Run Text="{Binding ElementName=window, Path=ActualHeight}" />
            <Run Text=" Device independent units" />
        </TextBlock>

하지만 이 코드를 쓰게 되면 아래와 같은 에러 코드를 보게 된다.
Error 1 A 'Binding' cannot be set on the 'Text' property of type 'Run'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject. D:\temp4\WpfApplication1\WpfApplication1\Window1.xaml 15 24 WpfApplication1

이 에러가 나는 이유는 TextBlock에 정의된 Text 프로퍼티는 TextProperty라는 의존 프로퍼티에 의해 지원되지만 Run에는 정의 되어 있지 않아서 있다.
즉, 이 이유는 데이터 바인딩의 타깃은 반드시 의존 프로퍼티가 되어야 하는 것이 이유이다.

의존 프로퍼티를 적용한 가장큰 이점은 데이터 바인딩이며, 의존 프로퍼티 시스템은 내부에 통보 장치가 구현되어 있다는 것이다. 바인딩 소스가 의존 프로퍼티가 될 필요는 없지만 의존 프로퍼티일 경우에 유리한 상황이 되는 것이다.

FrameworkElement를 상속 받아서 작성한 clr 객체가 DependencyProperty를 정의 하게 되면서 데이터 바인딩 통지 메시지를 받는 예제를 보여 드리겠습니다.

참고 ^^
본 내용은 "찰스페졸드의 WPF"의 내용을 이해 하고 나름 생각과 같이 정리한 겁니다.
제제가 가해질 경우 바로 삭제하도록 하겠습니다. ^^;
Posted by gsi
:

가끔 요즘 나오는 기술들을 보다 보면 데이터 바인딩에 대한 내용이 잘 구현되어있는거 같다. 물론 이해는 100% 되지 않지만 말이다.

그래서 C++에서 나름대로 사용하면 이런 형태는 어떨까 해서 하나 만들어 봤다. ^^
조금더 다듬어서 일부 기능은 이것을 사용해도 될거 같다.

사용되는 구조는 데이터를 가지고 있는 객체를 CContain 클래스 처름 구헌한다고
가정을 해보면 CDataBind 클래스와 연결후에 CDataBind의 객체만 SetValue 하면 된다.
이때 CContain 인스턴서의 PropertyChanged()가 자동으로호출 될 수도 있다.

이것과 다르게 함수포인터를 연동하는 부분도 추가를 해봤다. 클래스 내부의 함수가
함수 포인터로 하기에는 조금 몇가지 제약사항이 있기 때문에 전역 함수를 포인터와
연동하고 값이 바뀌게 되면 해당 함수가 호출 되는 구조를 취하게 된다.

혹.. 필요하신분 있으시면 요청시 설명해드릴게요 ^^
혹.. 좋은 의견 있음 코멘트 부탁 해요. ^^

Posted by gsi
: