GSI

vector 라는 컨테이너 다른 경우도 포함이 되지만. 컨테이너는 지능적이기는 하지만 메모리에 대해서는 신경을 쓰지 않습니다. 즉 new로 선언한 객체의 delete가 행해 지지 않는 다는 거죠.

보통 아래의 일반적인 경우로 메모리를 처리 할수 있습니다.

//헤더 선언

#include <vector>
#include <functional> -> 아래쪽 디파인 잡을때 사용되는거
#include <algorithm> -> 아래쪽 디파인 잡을때 사용되는거
#include <iostream>

using namespace std;

//선언

 vector< int* > m_List;

//추가

 m_List.clear();

 for(int i = 0; i < 2; i++) {
  int* p = new int;
  *p = 10;
  m_List.push_back(p);
 }

//삭제

 for(vector< int* >::iterator i = m_List.begin(); i != m_List.end(); ++i)
 {
  delete (*i);
 }

// 조금 편한 삭제 방법

//디파인

class DeleteObj
{
public:
 template<typename T>
 void operator()(const T* ptr) const
 {
  delete ptr;
 }
};

//삭제

for_each(m_List.begin(), m_List.end(), DeleteObj());

위의 클래스로 템플릿을 만들어 놨기 때문에.
대부분의 객체에 삭제 함수로 적용할 수 있다.
for_each를 통해서 조금더 코드량을 줄이고 가독성을 높일수 있을거 같다.

Posted by gsi
:

vector과 string의 용법

STL 2007. 9. 6. 14:37 |

//vector

void doSomething(const int* pInts, size_t numInts) {}

int의 배열정보를 가져 올때 아래와 같이

doSomething(&v[0], v.size());

v가 빈 디렉토리일때 &v[0]가 잘못된 값을 가져 올수 있기
때문에 아래 표기가 맞습니다.

if(!v.empty()) {
   doSomething(&v[0], v.size());
}

** &v[0] == &*v.begin()

//string

void doSomething(const char *pString) {}

string로 부터 char*를 가져 올때 아래와 같이

doSomething(s.c_str());

C API : 이 함수는 최대 arraySize 만큼의 double을 가진 배열에 대한 포인터를 받아 그 배열에 데이터를 기록 합니다. 동작이 끝나고 나면 데이터가 기록된 double의 개수를 반환하는데, 이 값은 maxNumDoubles를 넘지 않습니다.

size_t fillArray(double *pArray, size_t arraySize);

크기가 maxNumDoubles인 벡터를 생성합니다.

vector<double> vd(maxNumDoubles);

fillArray를 써서 vd에 데이터를 기록하고, resize를 써서 vd의 크기를 fillArray가 반환한 수치로 맞춥니다.

vd.resize(fillArray(&vd[0], vd.size());

C API : 이 함수는 최대 arraySize 만큼의  char를 가진 배열에 대한 포인터를 받아 그 배열에 데이터를 기록합니다. 동작이 끝나고 나면 데이터가 기록된 char의 개수를 반환하는데, 이 값은 maxNumChars를 넘지 않습니다.

size_t fillString(char *pArray, size_t arraySize);

maxNumCahrs 만큼의 크기를 가진 벡터를 생성합니다.

vector<char> vc(maxNumChars);

fillString을 써서 vc에 데이터를 기록합니다.

Size_t charsWritten = fillString(&vc[0], vc.size());

vc에 s로 데이터를 복사하는데, 이때 범위 생성자를 사용합니다.

stirng s(vc.begin(), vc.begin() + charsWritten);

쓸데 없이 남은 용량 없애기 (vector)

vector가 100,000개인 데이터를 추가한 후에 10개의 데이터만을 남기가 모두 erase로 했다고 가정해 봅시다. 이때 vector는 10개의 데이터를 가지고 있지만 내부적으로는 100,000개의 데이터 공간이 존재 하게 됩니다. 즉, 불필요한 용량이 존재 하게 됩니다.

이때 swap를 사용해서 용량을 현재 크기에 맞게 설정할 수 있습니다.

vector<Contestant>(contestant).swap(contestant);

vector< Contestant>( contestant) 이 표현식은 contestant의 사본인 임시 벡터 객체를 만듭니다. 즉, vector의 복사 생성자가 contestant의 상수 참조자를 매게변수로 받아 동작하는 거죠, 단, 이 복사 생성자는 요소가 복사되는데 필요한 만큼의 메모리만을 할당하기 때문에, 이렇게 만들어지는 객체는 contestant와 달리 딱 맞는 용량이 잡혀 있게 됩니다.

그 다음 swap 문이 이어 지는데요. 이 함수에 의해서 임시 벡터 안의 데이터와 contestant안의 데이터가 완전히 싹 바뀝니다.

이렇게 되면 용량이 현재 사이즈에 맞게 수축됩니다.

swap를 거치게 되면서 데이터의 반복자, 포인터, 참조자는 그대로 유지됩니다.

Posted by gsi
:

stl vector sort

STL 2007. 9. 6. 14:36 |

#include <vector>
#include <algorithm>

using namespace std;

bool compare(type a,type b)
{
  return a>b(비교);  
}

void function()
{
  vector<type> v;
  sort(v.begin(),v.end(),compare) ;
}

Posted by gsi
:

for_each 에 대해서...(이펙티브 STL 내용 발췌.. 243 페이지)

이 알고리즘은 범위 내의 데이터를 요약할 수 있는 또 하나의 알고리즘이면서 accumulate가 가진 이상한 제한도 받지 않습니다. for_each는 범위와 그 범위 내의 요소에 대해 호출할 함수(대개 함수 객체)를 받아 들이는데, 이 알고리즘에 넘겨지는 함수는 자신이 처리할 단 하나의 요소만을 받아들이며, for_each는 자신의 수행을 마칠 때 이 함수를 반환합니다(엄밀히 말하면 그 함수의 사본(copy) 입니다.  항목 38에서 더 자세히 공부하세요). 가장 중요한 포인트는 for_each에 넘겨지는 (그리고 반환되는) 함수는 부가적 효과를 가져도 된다는 것입니다.

부가적 효과에 대한 사항을 차지하고라도, for_each는 두 가지 면에서 accumulate와 다릅니다. 우선 accumulate라는 이름 자체에서 "범위를 요약한다"는 느낌이 강하게 풍겨집니다. for_each는 "범위 내의 모든 요소에 어떤 일을 한다"라는 냄새가 나죠. 물론 이 알고리즘들의 일차적인 목적이 그것이겠지만요. 어쨌든 for_each를 써서도 범위를 요약할 수 있습니다. 하지만 accumulate처럼 확실하지 않다는 것 뿐이죠.

두번째, accumulate는 우리가 원하는 요약 결과를 바로 반환하지만, for_each는 자신이 매게 변수로 받은 함수 객체를 반환하기 때문에 이 객체에서 요약 정보를 뽑아내야 합니다. C++ 업에 용어로 말하면 for_each에 넘기는 함수자 객체에다가 요약 정보를 얻어 낼 수 있는 멤버 함수를 추가해야 한다는 의미이지요.

.. 이상..

대부분 vector의 예를 보면 간단하게 아래와 같이 서술할 겁니다.

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

private:
  ... 내용...
};

void Test(CTest& e) { ... 내용... }

vector<CTest> m_vTest;

//배열의 정보를 사용해서 Test() 함수를 실행할려고 할때.

vector<CTest>::iterator iter;
for(iter = m_vTest.Begin(); iter != m_vTest.End(); iter++) {
  Test((*iter));
}

//이런 형태로 구성하게 되지요.
//하지만 for_each를 구성하면 한줄로 심플하게 구성됩니다.

std::for_each(m_vTest.Begin(), m_vTest.End(), &Test);

//이렇게 한줄로 요약이 되는군요.
//여기서 조금더 확장해서  Test() 함수에 템플릿을 연동하면
//비슷한 형태의 다른 타입의 vector로 선언된 변수들을 연동할수 있습니다.

template < class T >
void Test(T& e) { ... 내용 ... }
std::for_each(m_vTest.Begin(), m_vTest.End(), &Test);

//이렇게만 구성하면 컴파일 오류가 납니다.
//아래와 같이 구성하시면 됩니다.

std::for_each(m_vTest.Begin(), m_vTest.End(), &Test<CTest>);

위의 코드는 오류가 있을지도 모릅니다. 제 나름대로 정리해본겁니다.
하지만 위의 코드가 더 다양한 방법으로 전환되기도 하더군요.
예를 들어서 CTest 클래스 내부에 Test() 함수를 넣고 그것을 for_each에 연동할 수 있더라구요.
Exceptional C++ Style 책에 보니 내용이 있더라구요.
아래와 같은 코드로 사용하면 되는듯 합니다.

std::for_each(m_vTest.Begin(), m_vTest.End(), std::mem_fun_ref( &CTest::Test));

이렇게 구성하시면 됩니다.
아 그리고 for_each는 Test가 반환되는 값이 있다면 앞쪽에 붙여서 받으면 되요.

Posted by gsi
:

화면에 보여지는 객체로 여기지 않고 Resource로 처리 하면서
화면의 다른 객체에 표현 가능하게 할려면 아래와 같은 코드로 변형 하면 됩니다.
이때 Grid의 x:Key 가 부여 되어야 합니다. ^^

 <Window.Resources>
  <Grid x:Key="KTestGrid" HorizontalAlignment="Left" Margin="38.857,8,0,0" x:Name="TestGrid" VerticalAlignment="Top" Width="151.786" Height="126.286">
   <Rectangle Margin="19.643,20.929,28.572,30.357" Stroke="#FF000000">
    <Rectangle.Fill>
     <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
      <GradientStop Color="#FFFF3838" Offset="0"/>
      <GradientStop Color="#FFFFFFFF" Offset="1"/>
     </LinearGradientBrush>
    </Rectangle.Fill>
   </Rectangle>
  </Grid>
 </Window.Resources>
Posted by gsi
:

VisualBrush 사용한 Grid 객체 렌더링 하기.


2D 형태의 객체를 3D 화면에 렌더링 하는 방법을 적을려고 합니다.
이때 사용하게 되는게 VisualBrush가 있는데요.
아래의 사용법을 가지고 처리해줄 수가 있습니다.


Window.Resource에 등록해서 할수도 있을듯 한데요.
이번 예제는 화면에 그려지고 있는 Grid를 3D 화면에 그려 보는것으로 마치겠습니다.

Start!!!

프로젝트를 생성합니다.
아래와 같이 WPF Application(*.exe)를 선택 합니다.
Name는 VisualBrushTest로 입력하고 Ok를 누릅니다.
사용자 삽입 이미지

Window를 선택하고 배경색은 검정 계통으로 보이게 합니다.
흰색일때는 왠지 테스트 하기가 불편한듯 해서 ^^.
사용자 삽입 이미지

VisualBrush로 사용할 Grid 객체를 선택하고 생성합니다.
사용자 삽입 이미지
아래와 같이 테스트를 위해서 간단한 사각형을 Grid에 추가 하고 Grid의 이름을 부여 합니다.
사용자 삽입 이미지

Viewport3D 객체를 추가 해야 하는데요.
사실 이게 직접 xaml을 코딩 하기도 좀 번거롭고 해서 Tools에 있는 Make Image 3D
를 사용해 보겠습니다.
"TestGrid"를 선택하고 Make Image 3D를 바로 하면 좋겠지만. 이게 되지를 않습니다.
사용자 삽입 이미지

그래서 아래와 같이 우측의 Project 탭을 선택하고 VisualBrushTest를 선택한 후에
마우스 오른쪽 버튼을 클릭해서 컨텍스트 메뉴를 뛰우게 됩니다.
그리고 나서 Add Existing Item...를 선택 하게 됩니다.
선택후에 나오는 Add Existing Item 창에서 샘플로 사용할 이미지를 선택 합니다.
이 이미지는 나중에 지워도 괜찮은거니 아무거나 해주심 됩니다. ^^
사용자 삽입 이미지

그림 샘플에 있는 이미지를 추가 해봤습니다. 아래와 같이 이미지가 추가 되었죠.
사용자 삽입 이미지

이 이미지를 선택한 후에 컨텍스트 메뉴에서 Insert를 해주면 화면에 표시가 되게 됩니다.
사용자 삽입 이미지

이제 Viewport3D를 만들어 보겠습니다.
Image 객체는 이 메뉴가 활성화 되어서 보이게 됩니다.
Tools>Make Image 3D...를 선택 합니다. 이제 Objects and Timeline 화면에 보시면
Image 가 Viewport3D로 되어 있는 것을 볼 수 있습니다.
중앙의 윈도우 화면의 이미지는 그대로 보이게 되죠.
트랜스폼이나 기타 조작을 해주지 않았으니 당연하겠죠 ^^.
사용자 삽입 이미지

화면을 3차원인거 처름 보이게 하기 위해서 조금 트랜스폼을 조작해 보겠습니다.
여기서는 방법이 몇가지 될수 있겠죠.
좌측의 메뉴를 이용해서 하는 방법을 우선 보겠습니다.
Camera Orbit 메뉴를 선택 하고 좌측의 Viewport3D를 선택하고 객체를 3차원으로
변형할 수 있습니다.
사용자 삽입 이미지
[참고] 위에서 보시는 이미지를 보면 Viewport3D의 화면 영역 안에서 clip되는걸
볼수 있습니다. 이것을 없애고 싶다면 아래의 체크 박스를 없애면 됩니다.
사용자 삽입 이미지

이제 샘플로 사용한 이미지를 없애고 위에서 작업한 Grid를 추가해 보겠습니다.
Design에서 XAML 페이지로 이동하고 나면 좀 많은 코드가 생기게 됩니다.
아까 "푸른언덕.jpg"를 추가 했으니 그쪽으로 가면 되겠죠...
사용자 삽입 이미지
위에서 보는 것과 같이 DiffuseMaterial.Brush에 VisualBrush를 붙여 보겠습니다.
사실 DiffuseMaterial 말고도 몇개 더 있다는 것을 3D를 해보신 분이라면 아실겁니다. ^^
자. 이제 아래와 같이 이 부분을 수정하게 됩니다. 우리가 아까 Grid의 이름을
TestGrid로 한거 기억 나시죠?. 아래와 같이 입력합니다.
사용자 삽입 이미지
아래와 같이 화면이 Grid와 같이 나오게 됩니다.
사용자 삽입 이미지

Blend 툴에서 Grid의 내용을 수정하거나 하면 동적으로 Viewport3D의 화면도
바뀌게 되어 있습니다.
보통 이게 동영상이나 기타반사 효과 또는 젖은 효과라고도 하던데요.
이런 트낌을 줄때 많이들 하게 되는거 같아요.

여기까지 해보신 분이라면 많은 생각이 될게 될거 같아요.
몇가지 개선 사항을 적어 볼까 합니다.

1. TestGrid를 Window.Resource에 추가 해서 화면에 보이지는 않지만 내부 데이터를
   접근하고 하면서 화면에는 Viewport3D 의 형태로 표현도 가능하죠.
2. 그리고 3DTools 라이브러리를 사용 하게 되면 Window Form도 여기에 붙여서
    3D 상에서의 윈도우 컨트롤이 가능하게 됩니다.

이거 말고도 다양한 효과를 줄 수 있을거 같아요.
이번 강좌는 여기까지 하고 3DTools를 이용한 외국 사이트의 내용을 나름대로
정리 해서 올릴까 합니다. 어쩔지 ^^.. 많은 의견 주세요.

Posted by gsi
:

MessageBox 사용하기

C# 2007. 9. 2. 13:24 |

//그냥 해당 글을 출력할때
MessageBox.Show("Closing called");

//해당 결과를 받아서 처리 하고 싶을때
string msg = "Data is dirty. Close without saving?";
MessageBoxResult result =
    MessageBox.Show(
        msg,
        "Data App",
        MessageBoxButton.YesNo,
        MessageBoxImage.Warning);
if (result == MessageBoxResult.No)
{
    // If user doesn't want to close, cancel closure
    e.Cancel = true;
}
Posted by gsi
:

DB는 초급이라.. 아무래도 다 생소하다 ^^..

우선 로그인 페이지를 만들어 볼까 하는데.
필요한게 ID, Pass, LoginButton 이 필요할거 같다.

ID와 Pass를 입력한 후에 LoginButton을 클릭 하면,
해당 ID를 where 절에 포함해서 ID, Pass를 받아 오면 될거 같다.

OleDbDataAdapter 구문에 쿼리를 넣어서 받아 오는 코드이다.

OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT ID, Pass FROM Login WHERE ID='aaa';", conn);
위에서 보는 것과 같이 aaa라는 사용자의 ID, Pass 내용을 가져 오는 구문이다.
Posted by gsi
:

DB명 : member.mdb
테이블 이름 : BookTable
테이블 내용 : ID(일련번호), Title(텍스트)

cs 파일 내용

네임 스페이스

using System.Data.OleDb;
(이것만 선언 해서 안되는거 같네욤, References 에 "System.Data"를
추가해주어야 합니다.)

OleDbConnection, OleDbDataAdapter 처리
string mdbFile = Path.Combine(AppDataPath, "d:\\member.mdb");
string connString = string.Format(
                "Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}", mdbFile);
OleDbConnection conn = new OleDbConnection(connString);
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM BookTable;", conn);

DataSet 연결 (전역으로 만들어 놓는다.)

DataSet myDataSet;
adapter.Fill(myDataSet, "BookTable");

활용

ListBox에 연결시...

myListBox.DataContext = myDataSet;

... 나머지는 xaml에서 처리가능...

<StackPanel>
        <StackPanel.Resources>
            <c:IntColorConverter x:Key="MyConverter"/>

            <DataTemplate x:Key="BookItemTemplate">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="250" />
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Path=Title}" Grid.Column="0"
            FontWeight="Bold" />
                </Grid>
            </DataTemplate>
        </StackPanel.Resources>

        <ListBox Name="myListBox" Height="200"
      ItemsSource="{Binding Path=BookTable}"
      ItemTemplate  ="{StaticResource BookItemTemplate}"/>
        <Button Click="OnClick">Add Record</Button>
    </StackPanel>

foreach 문을 사용해서 비교 할때...

DataTable dt = myDataSet.Tables["BookTable"];
foreach (DataRow row in dt.Rows)
{
    string ss = row["Title"].ToString();
}
- "BookTable" 테이블 명이다.
- "Title" 컬럼 번호. (0, 1, 2, 인덱스도 가능하다.)

DataRow를 사용해서 Row 추가 할때...

DataTable myDataTable = myDataSet.Tables["BookTable"];
DataRow row = myDataTable.NewRow();
row["Title"] = "손병욱";
myDataTable.Rows.Add(row);  //<--이것은 DB랑은 상관없다.


위의 내용을 토대로 해서 기본 테이블에서 내용을 가져 와서 검색 하고
하는 등의 내용을 해결할 수 있을거 같다.
위의 내용을 토대로 로그인 페이지를 만들어 볼려고 한다.






 

Posted by gsi
:

Storyboard 를 사용한 TransformGroup를 C#에서 처리 하는 방법


Blend에서 Timeline을 생성하고 오브젝트를 움직이면 에니메이션 처리를 할수 있다.
가장 간단하게 하면서도 효과적인 에니메이션을 구현할 수 있다.

에니메이션 쪽을 보면 Transform에 여러개의 객체가 붙을수 있다.

만약 Button 의 이름이 btn이라고 하고 예로 들어 보겠다.

btn.RenderTransform 에 붙을수 있는 것은 아래와 같을 것이다.

btn.RenderTransform = new RotateTransform(0);
btn.RenderTransform = new ScaleTransform(1, 1);
btn.RenderTransform = new SkewTransform(0, 0);
btn.RenderTransform = new TranslateTransform(10, 10);



그리고 위의 4개를 통합해서 사용할 수 있는것으로 TransformGroup를 들수 있다.

...
btn.RenderTransform = tGroup;



위에서 보는 것과 같이 5개의 속성을 연결 시킬 수가 있다.

몇가지 테스트를 해봤고,
RenderTransform에 TransformGroup를 붙이지 않고 개별적인
속성을 붙이게 되면 Animation할때도 그 속성에 대한 정보만 제어 할 수 있다.
즉, 이동만을 하고 싶은 것이라면 TranslateTransform만 연결해서 사용하면 될듯 하다.

구체적인 예제를 만들지는 않았지만.
궁금하면 질문 해주기 바랍니다.

아래의 코드는 4개의 속성 정보를 다 연동하고 난 후에 제어 하는
아주 심플한 예제 입니다.
물론 자료형을 사용해서 배열로 정보들을 저장하고 조금더
깔끔하고 효과적으로 처리 할 수도 있을거 같다.
그리고 현재 코드는 2D의 처리만 가능한 것이다.

-------------------------------------------------------------------------
전제조건 :
Blend에서 기본 오브젝트를 우선 제작한다.
1. 버튼 두개를 제작한다.
2. 텍스트 박스를 하나 만든다. 이름은 TextBox2로 지정한다.

자.. 프로그램 코드는 *.cs 파일에서만 구동되므로 바로 설명 하겠다.

제어에 필요한 변수를 아래와 같이 만들었습니다.

//에니메이션 이름에 사용할 것을 지정
private string aniTrans = "_aniTrans";
private string aniSkew = "_aniSkew";
private string aniScale = "_aniScale";
private string aniRotate = "_aniRotate";

//트랜스폼을 제어 하기 위해서 변수를 설정
private TransformGroup group;
private RotateTransform rotate;
private ScaleTransform scale;
private SkewTransform skew;
private TranslateTransform trans;

//스토리 보드의 속성정보를 저장할 변수 설정
private Storyboard transStoryX;
private Storyboard transStoryY;
private Storyboard RotateStory;

//에니메이션 변수 설정
private DoubleAnimation myTransX;
private DoubleAnimation myTransY;
private DoubleAnimation myRotate;

public Window1()
{
    ...
    group = new TransformGroup();
    rotate = new RotateTransform(0);
    scale = new ScaleTransform(1, 1);
    skew = new SkewTransform(0, 0);
    trans = new TranslateTransform(50, 50);

    group.Children.Add(rotate);
    group.Children.Add(scale);
    group.Children.Add(skew);
    group.Children.Add(trans);

    this.RegisterName(aniTrans, trans);
    this.RegisterName(aniSkew, skew);
    this.RegisterName(aniScale, scale);
    this.RegisterName(aniRotate, rotate);

    TextBox2.RenderTransform = group;
}

private void OnLoaded(object sender, RoutedEventArgs e)
{
    myTransX = new DoubleAnimation();
    myTransY = new DoubleAnimation();
    myRotate = new DoubleAnimation();

    Storyboard.SetTargetName(myTransX, aniTrans);
    Storyboard.SetTargetProperty(myTransX, new PropertyPath(TranslateTransform.XProperty));
    Storyboard.SetTargetName(myTransY, aniTrans);
    Storyboard.SetTargetProperty(myTransY, new PropertyPath(TranslateTransform.YProperty));
    Storyboard.SetTargetName(myRotate, aniRotate);
    Storyboard.SetTargetProperty(myRotate, new PropertyPath(RotateTransform.AngleProperty));

    transStoryX = new Storyboard();
    transStoryX.Children.Add(myTransX);
    transStoryY = new Storyboard();
    transStoryY.Children.Add(myTransY);
    RotateStory = new Storyboard();
    RotateStory.Children.Add(myRotate);
}

private void OnClick(object sender, RoutedEventArgs e)
{
    myTransX.To = -50;
    myTransX.Duration = new Duration(TimeSpan.FromMilliseconds(800));
    myTransY.To = -50;
    myTransY.Duration = new Duration(TimeSpan.FromMilliseconds(800));
    myRotate.To = -50;
    myRotate.Duration = new Duration(TimeSpan.FromMilliseconds(800));

    transStoryX.Begin(this);
    transStoryY.Begin(this);
    RotateStory.Begin(this);
}

private void OnClick2(object sender, RoutedEventArgs e)
{
    myTransX.To = 120;
    myTransX.Duration = new Duration(TimeSpan.FromMilliseconds(800));
    myTransY.To = 150;
    myTransY.Duration = new Duration(TimeSpan.FromMilliseconds(800));
    myRotate.To = 270;
    myRotate.Duration = new Duration(TimeSpan.FromMilliseconds(800));

    transStoryX.Begin(this);
    transStoryY.Begin(this);
    RotateStory.Begin(this);
}


아.. 내용이 많아 지네욤..

우선 한번만 지정하는 부분과 매번 동작상황에 맞게 값을 입력해줘야 하는것으로
세분화를 해봤습니다.
Windows1()에 있는 내용은 기본적으로 설정할 부분이며,

OnClick(), OnClick1() 에는 버튼에 대한 이벤트 입니다.
아무래서 여기서 From, To, Duration을 설정해 줘야 할듯 합니다.

아. 참고로 From을 설정하지 않으면 현재 위치에서 To까지의 진행을
하게 됩니다. 처음에 이게 궁금했는데 아주 편한듯 합니다. ^^

그리고 Storyboard 여기 설정하는 부분이 솔직이 아직 다 이해가 가질 않습니다.
위의 코드 처름 하나하나의 속성을 처리 하는 부분에서는 별다른
문제가 없지만 path 형태의 처리는 아직 공부 중입니다. ^^

음.. 대충 설명은 이것으로 마치겠습니다.
샘플 받아서 실행해 보시고 분석해 보시면 더 도움 될거 같아욤.
아무쪼록 좋지 않은 내용을 봐주셔서 감사 ^^

Posted by gsi
:

여러개의 블로그 들을 보여 준다.
대표적으로 MSDN에서 여러가지 자료들을 올려 주고 계신 고마운 분들이당 ^^
http://blogs.msdn.com/tims/archive/2005/06/10/427565.aspx
Posted by gsi
:

개발자는 항상 새로운걸 추구 하고 그속에서 관계를 맺어 가는거 같네요.

저도 열심히 해야 겠습니다.
제가 하고 있다는 것은 바로 다른 사람들이 나보다 더 달려 가고 있다고
생각이 되니.. 무지 열심히 해야 겠네요 ^^.

http://www.gisdeveloper.co.kr/guestbook
Posted by gsi
:

Cube3D - WPF 3D

WPF 2007. 8. 30. 17:57 |

본 내용은 인터넷에서 받은 자료를 사용해서 작성한 것입니다.
영어권이 아닌 다른 곳이지만. 코드만 봐도 알수 있을 정도로 잘 정리 되어 있네요.

사각형 큐브를 3차원으로 구성하고 3D의 페이스에 동영상이나 2D 컨트롤 패널을
추가 할 수가 있습니다.

사용자 삽입 이미지

관련 자료 링크 : http://www.unitedstatesof.net/stuff/2007-03-19_WPF_Tutorial/WPF.pdf

Posted by gsi
:

Overview

A collection of tools to help developers using the 3D features in the Windows Presentation Foundation.

Some of things you will find inside:
  • Code to interact with 2D content placed on 3D
  • Trackball class to Rotate the camera using the mouse
  • ScreenSpaceLines3D to draw fixed width lines in a 3D scene
  • Texture coordinate generators

Current status: Released - please go to the "Releases" tab to download the latest source and binaries.
Audience: Beginner, Intermediate, Advanced
Language: C#
관련 주소 : http://www.codeplex.com/3DTools

내용.
해당 라이브러리를 사용하게 되면 3D의 표면에 Grid와 같은 패널의 내용을 맵핑 할 수가 있습니다. 3차원의 화면에 2차원의 각종 컨트롤을 처리 할 수가 있습니다.
그리고 트랙볼 구현도 쉽게 되니 활용하기 좋은 자료인듯 합니다.
Posted by gsi
:

가끔 mfc로 작업을 하다 보면 Dialog에 Bitmap를 배경에 깔고 싶을때가 있다.
그래서 배경에 까는건 아니지만 Picture Control을 사용해서 적용해보았다.

1. 리소스에 비트맵을 추가하고 아이디는 IDB_STATUSMGR_BACKGROUND로 지정
    (실제 파일을 불러 오는것도 가능하지만 지금 내가 한것은 리소스를 통해서 한것이기에...)

2. Dialog에 Picture Control을 생성한다.
3. Alt + D를 사용해서 레이어를 하단으로 옮겨 주는것도 좋다.
4. Type를 Bitmap로 맞춰 준다.
    (처음에 기본이 frame로 되어 있다.)
5. IDC_STATIC로 되어 있는 이름을 다른 것으로 바꾼다.

6. 코드를 추가한다.
BOOL CDlgStatusMgr::OnInitDialog()
{
   ...
    CStatic* m_pPicture = (CStatic*)GetDlgItem(IDC_STATIC_BACKGROUND);
    assert(m_pPicture && "포인터가 구해지지 않았네욤.");

    //HBITMAP를 생성한다.
    HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
     MAKEINTRESOURCE(IDB_STATUSMGR_BACKGROUND),
     IMAGE_BITMAP,
     0,0,
     LR_LOADMAP3DCOLORS);

    //Picture Control에 이미지를 연결시킨다.
    m_pPicture->SetBitmap(hBmp);
   ...
}

위와 같이 진행 하면. 픽쳐 컨트롤에 이미지를 부여 할 수 있다.

Posted by gsi
: