GSI

사용자 삽입 이미지

FormView로 구성된 세부 컨트롤 처리

Color1 + Pick... + CheckButton 은 한줄씩 생성 됩니다.
Add, Delete 로 추가하고 삭제할 수 있습니다.

스크롤로 아래 위로 움직일 수 있습니다.

Add를 하게 되면 하단의 버튼이 아래로 내려 간다.

 int pos = GetScrollPos(SB_VERT);
 GetDlgItem(IDC_EFFECTATTRIB8_CHILD_ADD)->MoveWindow(20, m_NewHeightPos + 10 - pos, 100, 30);
 GetDlgItem(IDC_EFFECTATTRIB8_CHILD_DELETE)->MoveWindow(20, m_NewHeightPos + 42 - pos, 100, 30);
 CSize scrollSize;
 scrollSize.cx = 200;
 scrollSize.cy = m_NewHeightPos + 80;
 SetScrollSizes(MM_TEXT, scrollSize);

위의 코드에서 보듯이 컨트롤을 동적으로 생성할 때
스크롤 성분에 의해서 원하는 위치에 생성되지 않습니다.
이 문제를 해결하기 위해서 GetScrollPos()를 사용해서 스크롤 값을 얻어 오고
그 값을 보정해서 생성하면 되네요..

관련코드 :
Posted by gsi
:

웹의 경로에 위치한 이미지를 가져오는 모듈입니다.
원래 이미지 사이즈를 구하기 위해서 사용했던건데요.
파일 다운로드 쪽으로 활용해도 가능성이 있을듯 하네요.

try
{
    byte[] data = new System.Net.WebClient().DownloadData(url);
    System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
    Image img = Image.FromStream(ms);

    Size size = new Size(img.Width, img.Height);
    return size;
}
catch(Exception ex)
{
    return new Size(-1, -1);
}

msdn 주소 : http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=637975&SiteId=1
키워드 : Image Url

Posted by gsi
:

스마트 포인터를 사용하고,
템플릿을 연동해서 여러가지 단위전략을 세울수 있다.

// CTest //
class CTest
{
public:
 CTest() {}
 ~CTest() }

public:
 int value;
};
typedef SmartPtr<CTest> CDeleteTestPtr;
typedef vector< CDeleteTestPtr > vObject;

// OpNewCreator //
template <class T>
struct OpNewCreator
{
 static T* Crate()
 {
  return new T;
 }
};

// CTestArray //
template < template <class> class CreatePolicy>
class CTestArray
 : public CreatePolicy< CTest >
 , public vObject
{
public:
 CTestArray()
 {
  vObject::clear();
 }
 ~CTestArray() { }

 // Add라는 함수를 하나 제작해 봤다.
 // OpNewCreator를 사용해서 간접적으로 메모리를 생성한다.
 void Add(int idx)
 {
  CDeleteTestPtr ptr = OpNewCreator<CTest>().Crate();
  ptr->value = idx;
  vObject::push_back( ptr );
 }
};
typedef SmartPtr< CTestArray<OpNewCreator> > CTestArrayPtr;

///// 사용법
CTestArrayPtr ar;
for(int i = 0; i < 10; i++)
{
   ar->Add(i);
}

Posted by gsi
:

Smart Ptr

#ifndef SMARTPTR_H
#define SMARTPTR_H

template <class T> class SmartPtr;

// IRefCount 참조 횟수 관리를 위한 인터페이스
// 클래스들은 이것을 직접 구현해도 되고, 아니면
// 내부적으로 IRefCount를 구현하고 있는 SmartPtr을 사용해도 된다.

template <class T> class IRefCount {
    friend class SmartPtr<T>;
protected:
    virtual void AddRef() = 0;
    virtual void Release() = 0;
    virtual T* GetPtr() const = 0;
};

// IRefCountImpl
// IRefCount의 표준적인 구현
// 이것을 상속하기만 하면 참조 횟수 관리 기능이 생긴다.
// class CMyObject : public IrefCountImpl<CMyObjct> { ... };
// 주의: 개별 클래스가 IRefCount를 꼭 구현할 필요는 없지만,
// 직접 구현함으로써 메모리 단편화를 줄일 수도 있다.

template <class T> class IRefCountImpl
: public IRefCount<T>
{
private:
    int m_Count;

protected:
    virtual void AddRef() { m_Count++; }
    virtual void Release();
    {
        assert( m_Count>=0);
        m_Count--;
        if( m_Count<=0 )
        {
            Destroy();
        }
    }
    virtual T* GetPtr() const { return ( (T*)this ); }
    virtual void Destroy() { if(GetPtr()!=NULL) delete GetPtr(); }

    IRefCountImpl() { m_Count = 0; }
};

// SmartPtr

template <class T> class SmartPtr
{
private:
    IRefCount<T> *m_RefCount;
// RefCounter
// IRefCount를 직접 구현하지 않는 클래스를 위한 내부구현.
// SmartPtr은 이 내부 구현과 클래스 T의 IRefCount 구현중
// 적절한 것ㅇ르 자동적으로 선택한다.

    class RefCounter : public IRefCountImpl<T> {
    private:
         T *m_Ptr;
    protected:
         virtual T* GetPtr() const { return m_Ptr; }
         virtual void Destroy() { delete this; }

    public:
       RefCounter( T* ptr ) { m_Ptr = ptr; }
       virtual ~RefCounter() { IRefCountImpl<T>::Destroy(); }
    };
//  T가 IRefCount를 구현하지 않았다면 이 메서드가 호출된다.
    void Assign( void *ptr )
    {
        if( ptr==NULL )
            Assign( (IRefCount<T> *)NULL );
        else
        {
            Assign( new RefCounter( static_cast<T*>(ptr) ) );
        }
    }

     // T가 IRefCount를 구현하고 있다면 Assign(void *ptr) 대신
// 이 메서드가 호출된다.
// 이를 통해서 메모리 사용이 좀더 최적화된다.
    void Assign( IRefCount<T> *refcount )
    {
        if( refcount != NULL )
             refcount->AddRef();
        IRefCount<T> *oldref = m_RefCount;
        m_RefCount = refcount;
        if( oldref!=NULL )
             oldref->Release();
    }
public:

    SmartPtr() { m_RefCount = NULL; }
    SmartPtr( T *ptr ) { m_RefCount = NULL; Assign(ptr); }
    SmartPtr(const SmartPtr &sp) { m_RefCount = NULL; Assign(sp.m_RefCount); }
    virtual ~SmartPtr() { Assign( (IRefCount<T> *)NULL); }

    T* GetPtr() const { return (m_RefCount = NULL ) ? NULL : m_RefCount->GetPtr(); }

    // 배정 연산자들
    SmartPtr& operator = (const SmartPtr &sp) { Assign(sp.m_RefCount); return *this; }
    SmartPtr& operator = (T* ptr) { Assign(ptr); return *this; }

    // T접근 및 const 변환
    T* operator -> () { assert(GetPtr() != NULL); return GetPtr(); }
    operator T* () const { return GetPtr(); }

    // 기타 편의성 연산자들
    bool operator ! () { return GetPtr() == NULL; }
    bool operator == (const SmartPtr &sp) { return GetPtr() == sp.GetPtr(); }
    bool operator != (const SmartPtr &sp) { return GetPtr() != sp.GetPtr(); }
};

#endif

다음은 템플릿 사용 예
SmartPtr.cpp

#include "stdafx.h"
#include "assert.h"
#include "smartptr.h"

class CMyObject
{
   char *name;
public:
   CMyObject(char *aname) { name = aname; printf( "create %s\n", name ); }
   virtual ~CMyObject() { printf("delete %s\n", name ); }
   void print() { printf("print %s\n",name ); }
};

SmartPtr<CMyObject> f1( char *name )
{
    return SmartPtr<CMyObject>(new CMyObject(name));
}

void f2( CMyObject *o )
{
    printf( " (print from a function) ");
    o->print();
}

int main( void )
{
    SmartPtr<CMyObject> ptr1(new CMyObject("1")); // 객체 1을 생성
    SmartPtr<CMyObject> ptr2 = new CMyObject("2"); // 객체 2을 생성

    ptr1 = ptr2; //객체 1을 파괴
    ptr2 = f1("3"); // 반환값으로 쓰이는 경우
    ptr2 = NULL; // 객체 3을 파괴
    f2(ptr1);

    // 잘못된 용례
    //  CMyObject o1;
    // ptr1 = &o1; // o1은 스택에 있으므로 이렇게 하면 안된다.
   
    // CMyObject *o2 = new CMyObject;
    // ptr1 = o2;
    // ptr2 = o2; // CMyObject가 IRefCount를 구현하지 않는 한 이렇게 하면 안된다.
    //     대신 ptr1 = ptr2를 사용할 것, 그것이 항상 안전하다.

    // int에 대해서도 SmartPtr을 사용할수 있다.
    SmartPtr<int> a(new int);
    SmartPtr<int> b(new int);

    *a = 5;
    *b = 6;

    // 명시적으로 파괴하지 않아도 메모리가 새지 않는다.
    return 0;
}

(펌) : http://blog.naver.com/twofree?Redirect=Log&logNo=21484155

Posted by gsi
:

단위 전략 부분의 디자인 패턴 내용을 보고 있다.

template 을 사용해서 다중 상속과 비슷한 구조를 취하기도 하고 메모리 생성 부분을 struct, class 형태로 따로 빼서 관리도 되는거 같다.

예제 1 :

class Ca
{
public:
 Ca() { value = 100; }
 virtual ~Ca() {}

 int value;
protected:
private:
};

template< class T>
class Cb
{
public:
 Cb() {}
 virtual ~Cb() {}

 T b;
protected:
private:
};

template< class T>
class Cc
{
public:
 Cc() {}
 virtual ~Cc() {}

 T c;
protected:
private:
};

template
<
 class T,
 template <class> class CheckingPolicy,
 template <class> class ThreadingModel
>
class SmartPtr
{
public:
 SmartPtr() {}
 ~SmartPtr() {}

public:
 T a;
 CheckingPolicy<T> b;
 ThreadingModel<T> c;
};

typedef SmartPtr<Ca, Cb, Cc> WidgetPtr;

위의 내용에서 보면 typedef를 사용해서 WidgetPtr을 하나 만들고 있다.
여기에 들어가는 내용은 Ca, Cb, Cc 가 있으며,
Cb, CC는 Ca를 포함할 수 있기 때문에 template로 선언되어 있는게 조건인듯 하다.

위와 같이 선언한 후에 아래와 같이 선언해서 사용하게 된다.

TestPtr< OpNewCreator > b;

이렇게 되면 b의 내용을 보면 SmartPtr의 클래스 내부에 b, c가 존재 하는데
이것은 T라는 템플릿 즉, Ca를 가지게 되며, 다른 동작들을 관리할 수 있을거 같다.

예제 2 :

class CTest
{
public:
 CTest() { value = 20; }
 ~CTest() {}

public:
 int value;
};

template <class T>
struct OpNewCreator
{
 static T* Create()
 {
  return new T;
 }
};

template < template <class T> class CreationPolicy>
class TestPtr : public CreationPolicy<CTest>
{
public:
 TestPtr()
 {
  ptr = CreationPolicy<CTest>().Create();
 }
 ~TestPtr()
 {
 }

public:
 CTest* ptr;
};

OpNewCreator 라는 struct를 사용하면서 new를 처리해 준다.
이 곳에서 몇개의 다른 처리를 해서 넘겨 주는 형태를 취해도 될것 같다.

상속 형태로 해서 아래와 같은 코드로 작성 하면,
template < template <class T> class CreationPolicy>
class TestPtr : public CreationPolicy<CTest>
...
이렇게 하고 나서

ptr = CreationPolicy<CTest>().Create();
이런 식으로 생성할 수 있다. 이 코드 참 멋진듯 하다. ^^

생성해서 처리 하는 방법은 아래와 같습니다.

 TestPtr< OpNewCreator > b;
 b.ptr->value = 30;
 printf("%d\n", b.ptr->value);
 TestPtr< OpNewCreator > c;
 b.ptr->value = 50;
 printf("%d\n", b.ptr->value);

아뭍턴.. 템플릿을 구현하는 방법이 복잡하긴 하지만,
제대로 사용하면 정말로 많은 기능을 구사할 수 있다.
Posted by gsi
: