Window/WPF2010. 1. 24. 10:14

이미지의 픽셀 값을 얻어 오기 위해서는 Bitmap으로 불러 들어와 GetPixel 함수를 호출하는 방법도 있지만

BitmapSource를 이용해 얻어오는 방법에 대해 InkCanvas를 사용해 다음과 같은 간단한 예제를 만들어 보았습니다.

 

        

 

소스는 매우 간략하기 때문에 이해가 쉬울 겁니다.

중요한 부분은 픽셀 포맷에 따라 Stride의 값을 달리하여 읽어 들어와야 하는 부분입니다.

 

비트맵의 Stride는 픽셀 데이타의 한 행의 폭으로 바이트 수를 나타냅니다.

이미지 포맷에 따라 오프셋을 구하는 효율을 위해 4의 배수로 부수적으로 의미없는 바이트가 추가 되는 경우가 있습니다.

 

예로 24Bit에서 Width가 17Pixel인 경우 51바이트(3 * 17)가 필요하지만 Stride값은 4배의 배수인 52바이트로 의미없는 1바이트가 추가됩니다.

자세한 자료는 다음 사이트를 참고 하시기 바랍니다.

http://www.bobpowell.net/lockingbits.htm

 

     9 class ImagePixelColor : Image

   10 {

   11     private static readonly DependencyProperty CurrentColorProperty =

   12         DependencyProperty.Register("CurrentColor", typeof(Color), typeof(ImagePixelColor),

   13         new FrameworkPropertyMetadata(Colors.Black,

   14             FrameworkPropertyMetadataOptions.AffectsRender));

   15 

   16     public Color CurrentColor

   17     {

   18         get

   19         {

   20             return (Color)GetValue(CurrentColorProperty);

   21         }

   22     }

   23 

   24     byte[] Pixels = new byte[4];

   25 

   26     protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)

   27     {

   28         SetValue(CurrentColorProperty, GetPixelColor(e.GetPosition(this)));

   29     }

   30 

   31     protected override void OnMouseMove(MouseEventArgs e)

   32     {

   33         if (e.LeftButton == MouseButtonState.Pressed || e.RightButton == MouseButtonState.Pressed)

   34         {

   35             SetValue(CurrentColorProperty, GetPixelColor(e.GetPosition(this)));

   36         }

   37     }

   38 

   39     private Color GetPixelColor(Point CurrentPoint)

   40     {

   41         BitmapSource CurrentSource = this.Source as BitmapSource;

   42 

   43         // 비트맵 내의 좌표 값 계산

   44         CurrentPoint.X *= CurrentSource.PixelWidth / this.ActualWidth;

   45         CurrentPoint.Y *= CurrentSource.PixelHeight / this.ActualHeight;

   46 

   47         if (CurrentSource.Format == PixelFormats.Bgra32 || CurrentSource.Format == PixelFormats.Bgr32)

   48         {

   49             // 32bit stride = (width * bpp + 7) /8

   50             int Stride = (CurrentSource.PixelWidth * CurrentSource.Format.BitsPerPixel + 7) / 8;

   51             // 한 픽셀 복사

   52             CurrentSource.CopyPixels(

   53                 new Int32Rect((int)CurrentPoint.X, (int)CurrentPoint.Y, 1, 1), Pixels, Stride, 0);

   54 

   55             // 컬러로 변환 후 리턴

   56             return Color.FromArgb(Pixels[3], Pixels[2], Pixels[1], Pixels[0]);

   57         }

   58         else

   59         {

   60             MessageBox.Show("지원되지 않는 포맷형식");

   61         }

   62         // TODO: 다른 포맷 형식 추가

   63 

   64         return Color.FromArgb(Pixels[3], Pixels[2], Pixels[1], Pixels[0]);

   65     }

   66 }

 

Ink의 색상과 선택한 픽셀값을 보여주는 Rectangle의 색상을 변경하기 위해 다음과 같은 컨버트와 바인딩 시켰습니다.

IvalueConverter 인터페이스는 바인딩 엔진을 통과할 때 데이터 수정을 가능하게 하는 메소드를 가지고 있습니다.

다음의 두 함수를 통해 전달되는 데이터를 값을 변경할 수 있습니다.

 

Convert : 소스 데이터를 UI에 표시하기 위해 대상에 전달하기 전에 수정합니다.

ConvertBack : 대상 데이터를 소스 개체에 전달하기 전에 수정합니다. TwoWay 바인딩에서만 호출됩니다.

 value  대상으로 전달되는 소스 데이터
 targetType  대상 종속성 속성에 필요한 데이터 타입
 parameter  변환기 논리에 사용 될 선택적 매개 변수
 culture  변환의 문화권

 

 

    50 [ValueConversion(typeof(Color), typeof(Brush))]

   51 public class ColorBrushConverter : IValueConverter

   52 {

   53     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

   54     {

   55         return new SolidColorBrush((Color)value);

   56     }

   57 

   58     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

   59     {

   60         return null;

   61     }

   62 }

   63 

   64 [ValueConversion(typeof(Color), typeof(DrawingAttributes))]

   65 public class InkColorConverter : IValueConverter

   66 {

   67     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

   68     {

   69         DrawingAttributes attribute = new DrawingAttributes();

   70         attribute.Color = (Color)value;

   71         return attribute;

   72     }

   73 

   74     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

   75     {

   76         return null;

   77     }

   78 }

 

[ Rectangle ]

 Fill="{Binding ElementName=Palette, Path=CurrentColor, Converter={StaticResource ColorConverter}}"

 

[ InkCanvas ]

 DefaultDrawingAttributes="{Binding ElementName=Palette, Path=CurrentColor, Converter={StaticResource InkColorConverter}}"

 

 

'Window > WPF' 카테고리의 다른 글

[ WPF ] Window 사이즈 변경 시 컨트롤 크기 변경하기  (3) 2010.02.08
[WPF] Object Capture  (0) 2010.01.29
[WPF] 시계 만들기  (0) 2010.01.26
[WPF] Drag, Scale, Rotate  (1) 2010.01.24
[ WPF ] Drag  (0) 2009.09.27
Posted by 열ㅇl
Window/WPF2010. 1. 24. 00:57

 

 

멀티터치는 기본적으로 위와 같은 세 가지의 제스쳐를 사용하여 컨트롤 하게 됩니다.

이를 간단하게 마우스로 동작할 수 있도록 구현해 보았습니다.

멀티터치와 같이 여러 점에 반응하는 것이 아닌 마우스의 두 버튼 만으로 동작하는 점이 다르지만

객체에 전해지는 두 좌표만을 사용하는 원리에는 비슷하지 않나 싶습니다.

 

이전 Drag 예제에선 부모 컨트롤이 Canvas에 제약이 되었기 때문에

이번 예제에서는 RenderTransform 값을 변경함으로써 부모 컨트롤의 제약을 없앴습니다.

 

가지 동작 모두 처음 값과 현재 값의 차이를 구한다는 점에서 공통점이 있습니다.

드래그는 현재 좌표값에서 처음 좌표 값의 차이만큼 현재 객체의 좌표값에 더해 줌으로써 이동시킵니다.

크기 조절은 현재 비율과 처음 비율을 나누어줌으로 변경시킬 비율을 구합니다.

회전은 처음각에서 현재각의 차이를 통해 회전 각을 구합니다.

 

이론은 간단하지만 수식으로 옮기기엔 수학적인 부분이 부족하여 많은 소스들을 참고하였습니다.

수학을 잘 하시는 분이라면 쉽게 하셨을 테지만 말이죠. ^^;;

 

소스의 내용은 길지 않기 때문에 이해가 빠르실겁니다.

크기 조절과 회전 시 현재 클릭 점 위치를 기준으로 변경하여야 하기 때문에 마지막 부분에 드래그를 해주었습니다.

 

< Drag > 

   121 private void Drag(Point point)

  122 {

  123     if (!IsDragging)

  124     {

  125         // 윈도우상의 처음 좌표값의 역변환

  126         FirstCoordinate = Element.TransformToVisual(Window).Inverse.Transform(FirstPoint);

  127         IsDragging = true;

  128     }

  129 

  130     // 객체를 기준으로 역변환 값을 윈도우상의 좌표값으로 변환합니다.

  131     Point Translate = Element.TranslatePoint(FirstCoordinate, Window);

  132 

  133     // 현재 좌표값과의 차이

  134     Point Difference = new Point(point.X - Translate.X, point.Y - Translate.Y);

  135 

  136     // 좌표를 변경합니다.

  137     TranslateTrans.X += Difference.X;

  138     TranslateTrans.Y += Difference.Y;

  139 

  140     Element.RenderTransform = TransGroup;

  141 }

 

< Scale &  Rotate  >

    61 private void TransformationeEvent(object sender, MouseEventArgs e)

   62 {

   63     if (e.LeftButton == MouseButtonState.Pressed || e.RightButton == MouseButtonState.Pressed)

   64     {

   65         Point CurrentPoint = e.GetPosition(Window);

   66         Point DistanceVector = new Point((CurrentPoint.X - FirstPoint.X), (FirstPoint.Y - CurrentPoint.Y));

   67 

   68         double CurrentLength = Math.Sqrt(DistanceVector.X * DistanceVector.X

   69                                                   + DistanceVector.Y * DistanceVector.Y);

   70         double CurrentAngle = Math.Atan2(DistanceVector.Y, DistanceVector.X) * 180 / Math.PI;

   71 

   72         // 포인터 위치 표시

   73         if (ShowPosition)

   74         {

   75             ChangePosition(SecondPosition, CurrentPoint);

   76         }

   77 

   78         // 크기 변경

   79         if (CanBeScaled)

   80         {

   81             if (!IsScaling)

   82             {

   83                 // 처음 비율

   84                 FirstLength = CurrentLength / ScaleTrans.ScaleX;

   85                 IsScaling = true;

   86             }

   87 

   88             if (FirstLength > 0)

   89             {

   90                 // 현재 비율

   91                 double Scale = CurrentLength / FirstLength;

   92                 ScaleTrans.ScaleX = Scale;

   93                 ScaleTrans.ScaleY = Scale;

   94             }

   95         }

   96 

   97         // 회전

   98         if (CanBeRotated)

   99         {

  100             if (!IsRotating)

  101             {

  102                 // 처음 각도

  103                 FirstAngle = CurrentAngle + RotateTrans.Angle;

  104                 IsRotating = true;

  105             }

  106 

  107             // 현재 각도

  108             double AngleDiff = (FirstAngle - CurrentAngle + 360) % 360;

  109             RotateTrans.Angle = AngleDiff;

  110         }

  111 

  112         Drag(FirstPoint);

  113     }

  114 }

 

사용은 다음과 같이 하시면 됩니다.

Transform의 첫 인자는 변경 시킬 객체, 두 번째 인자는 해당 윈도우입니다.

CanBeDragged : 드래그 여부

CanBeScaled : 크기 조절 여부

CanBeRotated : 회전 여부

ShowPosition : 클릭 점을 표시 할지 여부

 

    38 transform = new Transform(grid, this);

   39 transform.CanBeDragged = true;

   40 transform.CanBeScaled = true;

   41 transform.CanBeRotated = true;

   42 transform.ShowPosition = true;

 

전체 소스코드는 첨부파일을 받으시길 바랍니다.

※ 프로토타입 형식으로 좀 더 유연하게 코드를 수정할 필요가 있습니다.

 

조작방법

드래그 : 왼쪽 or 오른쪽 버튼 클릭 후 이동

크기 조절 / 회전 : 왼쪽과 오른쪽 버튼을 누른 후

                         왼쪽 or 오른쪽 버튼 클릭 후 이동

                         왼쪽과 오른쪽 버튼을 한번 더 누르면 해제

 

마우스가 객체나 윈도우 창을 벗어나면 모두 해제 됩니다.

 

< 시연 영상 >
화면이 끊기네요 ㅡㅡ;;


'Window > WPF' 카테고리의 다른 글

[ WPF ] Window 사이즈 변경 시 컨트롤 크기 변경하기  (3) 2010.02.08
[WPF] Object Capture  (0) 2010.01.29
[WPF] 시계 만들기  (0) 2010.01.26
[WPF] Image Pixel  (0) 2010.01.24
[ WPF ] Drag  (0) 2009.09.27
Posted by 열ㅇl
Window/WPF2009. 9. 27. 20:41

프로그램 작성 중 Drag 기능을 사용해야 할 때가 있습니다.

일반적으로 Window는 DragMove라는 함수를 호출하여 사용할 수 있지만

나머지는 구현을 하여야 하는 일이 생깁니다.

 

TranslateTransformDependencyProperty   이용한 간단한 예제를 만들어 보았습니다.

 

TranslateTransform은 RenderTransform의 현재 오프셋을 변경시킬 수가 있습니다.

 

DependencyProperty (의존 속성)클래스 를 이용하면 여러 객체에 대해 기능을 부여 할 수 있습니다.

의존 속성의 값을 변경하면 자동적으로 객체를 변경 시킬 수가 있습니다..

 

선언은 다음과 같습니다.

    15 private static readonly DependencyProperty DragProperty =

   16     DependencyProperty.RegisterAttached("Drag",

   17     typeof(bool),

   18     typeof(Drag),

   19     new UIPropertyMetadata(false, ChangeDragProperty));

 

4개의 파라미터는 다음과 같습니다.

 Name  등록 속성의 이름
 Property type  속성 타입
 Owner type  부모 타입
 Type metadata  메타데이터 지정

 

UIPropertyMetadata

코어 수준에서 렌더링/사용자 인터페이스에 영향을 주는 프레임워크가 아닌 속성에 대해 속성 메타데이터를 제공합니다.

 defaultValue  속성의 기본값, 일반적으로 특정 형식의 값으로 제공.
 propertyChangedCallback  속성의 유효 값이 변경될 때마다 호출되는 함수

 

[ 함수 내용 ]

 

- 프로퍼티 값 변경 시 이벤트 설정을 변경합니다.

   39 private static void ChangeDragProperty(DependencyObject d, DependencyPropertyChangedEventArgs e)

   40 {

   41     FrameworkElement element = d as FrameworkElement;

   42 

   43     if (element != null)

   44     {

   45         if ((bool)e.NewValue)

   46         {

   47             // 오프셋 변경을 위해 생성합니다.

   48             element.RenderTransform = new TranslateTransform(0, 0);

   49 

   50             element.PreviewMouseDown += element_PreviewMouseDown;

   51             element.PreviewMouseUp += element_PreviewMouseUp;

   52         }

   53         else

   54         {

   55             element.PreviewMouseDown -= element_PreviewMouseDown;

   56             element.PreviewMouseUp -= element_PreviewMouseUp;

   57         }

   58     }

   59 }

 

 

- 드래그 시 객체를 놓치지 않기 위해 윈도우의 MouseMove를 사용했습니다.

  간단한 방법으로 객체 내의 처음 포인터 값과 현재 포인터 값의 차이만큼 오프셋을 변경합니다.

  ZIndex를 변경하여 선택한 객체를 상위로 올립니다.

   61 static void window_PreviewMouseMove(object sender, MouseEventArgs e)

   62 {

   63     if (CurrentElement != null &&

   64         e.LeftButton == MouseButtonState.Pressed || e.RightButton == MouseButtonState.Pressed)

   65     {

   66         Point CurrentPoint = e.GetPosition(CurrentElement);

   67 

   68         TranslateTransform Translate = CurrentElement.RenderTransform as TranslateTransform;

   69 

   70         if (Translate != null)

   71         {

   72             CurrentElement.LayoutTransform = Translate;

   73             Translate.X += CurrentPoint.X - FirstPoint.X;

   74             Translate.Y += CurrentPoint.Y - FirstPoint.Y;

   75         }

   76     }         

   77 }

   78 

   79 static void element_PreviewMouseDown(object sender, MouseButtonEventArgs e)

   80 {

   81     CurrentElement = sender as FrameworkElement;

   82 

   83     OldzIndex = Canvas.GetZIndex(CurrentElement);

   84     Canvas.SetZIndex(CurrentElement, 100);

   85 

   86     FirstPoint = e.GetPosition(CurrentElement);

   87 

   88     window.PreviewMouseMove += window_PreviewMouseMove;

   89 }

   90 

   91 private static void element_PreviewMouseUp(object sender, MouseButtonEventArgs e)

   92 {

   93     FrameworkElement element = sender as FrameworkElement;

   94 

   95     Canvas.SetZIndex(element, OldzIndex);

   96 

   97     CurrentElement = window;

   98     window.MouseMove -= window_PreviewMouseMove;

   99 }

 

 

- 다음과 같이 사용하면 됩니다.

   Drag.SetWindow(this);

    

  Drag.SetDrag(sample_btn, true);

  Drag.SetDrag(sample_image1, true);

  Drag.SetDrag(sample_image2, true);

  Drag.SetDrag(sample_text, true);

  Drag.SetDrag(title, true);

 

 

[ 시연 영상 ]

 

 

 

'Window > WPF' 카테고리의 다른 글

[ WPF ] Window 사이즈 변경 시 컨트롤 크기 변경하기  (3) 2010.02.08
[WPF] Object Capture  (0) 2010.01.29
[WPF] 시계 만들기  (0) 2010.01.26
[WPF] Image Pixel  (0) 2010.01.24
[WPF] Drag, Scale, Rotate  (1) 2010.01.24
Posted by 열ㅇl
Window/Win32 API, MFC2009. 9. 27. 13:50

 

MFC 학습 목적으로 이스트소프트의 알씨 프로그램을 모티브로 해서 만든 이미지 뷰어 프로그램입니다.

CxImage를 사용하여 이미지 처리를 하였습니다.

파일 탐색기를 만드느라 매우 고생한 기억이 나네요..

 

[ 시연 영상 ]

 

 

'Window > Win32 API, MFC' 카테고리의 다른 글

고급반 - [ MFC ] 그림판  (18) 2009.09.19
[MFC] 클래스들 간 상호참조  (1) 2009.09.10
[MFC] CFileDialog 다중 파일 선택하기  (1) 2009.06.12
예비반 실습 - API  (0) 2009.03.05
Posted by 열ㅇl
Window/Win32 API, MFC2009. 9. 19. 13:33

BIT 고급반과정 시절 MFC로 기초적인 기능을 갖는 그림판을 제작.
어설프지만 MFC와 소켓통신에 대한 이해와 학습을 할 수 있었습니다.

 


[ 시연 영상 ]

 

[ 소켓 통신 ]
 

[ UPDATE ] 2011. 07. 12

소스 요청하시는 분들이 많아서 분할 압축하여 첨부 하였습니다.

 

 

'Window > Win32 API, MFC' 카테고리의 다른 글

[ 고급반 - MFC ] 이미지 뷰어  (0) 2009.09.27
[MFC] 클래스들 간 상호참조  (1) 2009.09.10
[MFC] CFileDialog 다중 파일 선택하기  (1) 2009.06.12
예비반 실습 - API  (0) 2009.03.05
Posted by 열ㅇl
Window/Win32 API, MFC2009. 9. 10. 01:32

MFC에서는 클래스들 간 서로를 참조하는 기능들이 마련되어 있습니다.

상호 참조를 위한 함수들은 다음과 같습니다.

 

 

 

이제부터는 프로젝트명을  Example이라 가정 후 설명하겠습니다.

 

 CExampleApp  CWinApp 클래스 상속, 프로그램 초기화 클래스
 CMainFrame  CFrameWnd 클래스 상속, 전체 윈도우 관련 클래스
 CExampleDoc  CDocument 클래스 상속, 문서 관련 클래스
 CExampleView  CView 클래스 상속, 사용자 화면 클래스
 CAboutDlg  CDialog 클래스 상속, 도움말 대화 상자 클래스


1. 메인 프레임 윈도우( CExampleAPP ) 참조

CWinApp* AfxGetApp();

- CWinApp 파생클래스의 인스턴스 포인터를 반환해 줍니다.

 

ex)

#include Example.h

CExampleApp* pApp = (CExampleApp*)AfxGetApp();

 

2. 메인 프레임 윈도우( CMainFrame ) 참조

CWnd* AfxGetMainWnd();

- 메인 프레임 클래스의 인스턴스 포인터를 반환해 줍니다.

 

ex)

#include "MainFrm.h"

CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();

 

① 프레임 윈도우에서 뷰( CExampleView ) 참조

CView* CFrameWnd::GetActiveView();

- 프레임 윈도우에서 뷰를 참조합니다.

  현재 프레임 윈도우와 연결된 뷰 중 활성화 된 것의 포인터를 반환합니다.

 

ex)

CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();

CExampleView* pView = (CExampleView*)pFrame->GetActiveView();

 

② 프레임 윈도우에서 도큐먼트 ( CExampleDoc ) 참조

virtual CDocument* CFrameWnd::GetActiveDocument();

- 프레임 윈도우 클래스에서 도큐먼트 클래스를 참조합니다.

  현재 프레임 윈도우와 연결된 도큐먼트 중 활성화 된 것의 포인터를 반환합니다.

 

ex)

CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();

CExampleDoc* pDoc = (CExampleDoc*)pFrame->GetActiveDocument();

 

대화 상자에서도 동일합니다.

 

3. 뷰에서 프레임 윈도우/도큐먼트( CExampleDoc ) 참조

① 도큐먼트 참조

CDocument* CView::GetDocument();

- 뷰 클래스와 연결된 도큐먼트 클래스를 참조합니다.

  CView클래스의 멤버 함수로써 CView클래스에서만 사용할 수 있습니다.

  어떤 뷰와 연결된 도큐먼트는 오직 하나만 존재하기 때문입니다.

 

ex)

CExampleDoc* pDocument = (CExampleDoc*)GetDocument();

 

MFC로 프로젝트 생성 시 기본적으로 생성되는 함수이지만,

    만약 직접 만든 클래스라면 GetDocument()함수를 직접 만들어 주거나

    CExampleView 클래스의 멤버인 m_pDocument 를 사용해도 됩니다.

 

① 자식 프레임 윈도우 참조

CFrameWnd* CWnd::GetParentFrame();

- 뷰를 둘러싸고 있는 프레임을 참조합니다.

   프레임 윈도우는 뷰 뿐 아니라, 일반적인 윈도우를 둘러싸는 틀로써 사용될 수 있기 때문에,

   CWnd 클래스의 멤버 함수로 되어 있습니다.

   물론 CView에서도 사용할 수 있습니다.

   단일 도큐먼트 프로그램에선 AfxGetMainWnd함수와 GetParentFrame 함수의 반환 값이 같습니다.

   하지만 다중 도큐먼트 프로그램에선 함수가 서로 구별됩니다.

 

ex)

CMainFrame* pFrame = (CMainFrame*)GetParentFrame();

 

4. 도큐먼트에서 뷰/프레임 윈도우 참조

① 뷰 참조

하나의 도큐먼트에 여러 개의 뷰가 결합되어 리스트로 관리되고 있습니다.

GetFirstViewPosition 함수와 GetNextView 함수를 조합하여 사용합니다.

 

ex)

POSITION pos = GetFirstViewPosition(); // 첫번째 뷰가 매달려 있는 포인터

 

while ( pos != NULL )

{

        CView * pView = GetNextView( pos ); // 다음 뷰들의 포인터

        // to do

}

 

- 뷰가 하나인 경우

m_viewList: CDocument 클래스의 멤버 변수로 뷰를 관리하는 연결 리스트.

ex)

CView* pView = m_viewList.GetHead();

 

5. 도큐먼트 템플릿에서 도큐먼트/뷰/자식 프레임 윈도우 참조

다중 도큐먼트 프로그램에는 여러 개의 도큐먼트/뷰/자식 프레임이 있을 수 있습니다.

같은 타입의 클래스의 인스턴스가 두 개 이상 존재하는 것들은 연결리스트로 이루어져 있습니다.

노드를 참조하는 함수는 모두 다음과 같은 형식입니다.

 

POSITION pos = GetFirstXXXPosition();

while( !pos != NULL )

{

        XXX xx = ( XXX* )GetNextXXX(pos);

        // to do

}

 

ex)

CWinApp *App = AfxGetApp();

POSITION posTemplate = pApp-> GetFirstDocTemplatePosition();

     // POSITION CWinApp::GetFirstDocTemplatePosition();

 

while( posTemplate )

{

        CDocTemplate * pTemplate = pApp-> GetNextDocTemplatePosition( posTemplate );

        // CDocTemplate* CWinApp::GetNextDocTemplatePosition( POSITION& pos );

 

        POSITION posDoc = pTemplate-> GetFirstDocPosition();
       // virtual POSITION CDocTemplate::GetFirstDocPosition();


        while( posDoc )

        {

                   CDocument *pDoc = pTemplate->GetNextDoc( posDoc );

                   // virtual CDocument* CDocTemplate::GetNextDoc( POSITION& rPos );

                  

                   POSITION posView = pDoc-> GetFirstViewPosition();

                   // virtual POSITION CDoccument::GetFirstViewPosition();

                   while( posView )

                   {

                                CView *pView = pDoc->GetNextView( posView );

                                // virtual CView* CDocument::GetNextView( POSITION& rPosition );

                                // to do

                   }

        }

}

 

6. 분할 뷰에서의 참조

위의 방법과 같이 포인터를 얻어 올 수 있거나 다음과 같은 방법으로 얻어 올 수 있습니다.

 

CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();

CExampleView* pView1 = (CExampleView*)pFrame->m_wndSplitter.GetPane(0,0);  

CXXXView* pView2 = (CXXXView*)pFrame->m_wndSplitter.GetPane(0,1);  


뷰 포인터의 좌표는 다음과 같습니다.

 

 GetPane( 0, 0 )

 GetPane( 0, 1 )

 GetPane( 1, 0 )

 GetPane( 1, 1 )

 GetPane( 2, 0 )

 GetPane( 2, 1)

 

[ 메시지를 이용한 통신 ]

 - 포인터를 얻어 직접 서로의 함수를 호출할 수도 있지만 메시지를 보내어 간접적으로 함수가 호출되도록 할 수도 있습니다.
 
방법은 다음의 두 가지 방법이 있습니다.

① SendMessage 함수
LRESULT SendMessage( UINT message, WPARAM wParam=0, LPARAM lParam=0 );
- 윈도우에 메시지를 보내는 함수 입니다.
  wParam, lParam은 추가적인 정보를 담기 위한 인자입니다.
  CWnd 클래스의 멤버 함수 입니다.
  CWnd 클래스에서 상속받지 않은 클래스는 호출할 수 없습니다.
  메인 프레임 클래스 밖에서 메인 프레임 윈도우로 메시지를 보낼시 다음과 같이 하면 됩니다.
  AfxGetMainWnd()-> SendMessage( ..., ..., ...);
 
ex)
AfxGetMainWnd()-> SendMessage( WM_COMMAND, ID_FILE_OPEN );
 
① PostMessage 함수
BOOL PostMessage( UINT message, WPARAM wParam=0, LPARAM lParam=0 );
- SendMessage 함수와 비슷하게 메시지를 보냅니다.
  차이점은 메시지 큐를 거치느냐 아니냐 하는 것입니다.
  SendMessage 함수는 메시지를 보내면 메시지 큐를 거치지 않고 직접 메시지 처리기를 호출합니다.
  따라서, 호출과 동시에 해당하는 메시지 처리기가 호출됩니다.
  반면, PostMessage 함수는 메시지를 메시지 큐에 넣어 주는 일만 합니다.
  따라서, 메시지를 보내주면 현재 수행되고 있는 함수가 완전히 끝나고, 메시지 큐에 쌓여 있던 메시지들의 처리기가
  다 수행되고 난후에야 PostMessage함수로 보낸 메시지의 처리기가 호출됩니다.
 
☞ 헤더파일 포함 순서.
#include "stdafx.h"
#include "Example.h"
#include "MainFrm.h"
#include "ExampleDoc.h"
#include "ExampleView.h"

'Window > Win32 API, MFC' 카테고리의 다른 글

[ 고급반 - MFC ] 이미지 뷰어  (0) 2009.09.27
고급반 - [ MFC ] 그림판  (18) 2009.09.19
[MFC] CFileDialog 다중 파일 선택하기  (1) 2009.06.12
예비반 실습 - API  (0) 2009.03.05
Posted by 열ㅇl
Window/Win32 API, MFC2009. 6. 12. 18:22

프로그램 도중 여러 파일을 선택해야 할 때가 있습니다.

 

CFileDialog 클래스의 플래그 값을 설정하시면 됩니다. (OFN_ALLOWMULTISELECT)

예제 화면은 다음과 같습니다.

 

 

fileBuffer 값은 다중 선택한 파일명들을 모두 저장할 버퍼이기 때문에 충분한 값으로 설정하였습니다.

 

CFileDialog 클래스의 인자는 다음과 같습니다.

 

CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt=NULL

                         LPCTSTR lpszFileName=NULL,

                         DWORD dwFlags=  OFN_HEDEREADONLY | OFN_OVERWRITEPROMPT,

                         LPCRSTR lpszFilter= NULL, CWnd* pParentWnd=NULL);

 

인자 값

bOpenFileDialog 

대화상자 타이틀 바 문자 설정

TRUE: 열기’

FALSE: "다른 이름으로 저장"

lpszDefExt         

기본 확장자 설정

lpszFileName  

대화상자가 처음 출력 되었을 때 "파일이름" 에디트 컨트롤에 입력될 파일명 출력

dwFlags      

파일 대화 상자의 속성 플래그

or(|)연산자로 조합

lpszFilter          

대화 상자에 출력될 파일들을 확장자에 의해서 걸러지도록 하기 위한 필터를 지정

pParentWnd        

대화 상자의 부모 윈도우를 지정

 

플래그

OFN_EXPLORER

 윈도우 탐색기 스타일

OFN_EXPLORER          

 다중 파일 선택

OFN_CREATEPROMPT         

 새 파일명을 입력 시 메시지 박스 출력 

OFN_FILEMUSTEXIST          

 존재 하지 않는 파일명 입력 불가

OFN_HIDEREADONLY          

 읽기 전용파일 출력 불가

OFN_LONGNAMES              

 긴 파일이름 포맷 지원

OFN_OVERWRITEPROMPT      

 존재하는 파일명 입력 시 메시지 박스 출력

OFN_PATHMUSTEXIST        

 존재 하는 디렉터리명만 입력

 

 함수

CString GetPathName()

선택된 파일의 절대 경로

CString GetFileName()

선택된 파일의 파일명과 확장자

CString GetFileExt()

선택된 파일의 확장자

CString GetFileTitle()

선택된 파일의 파일명

BOOL GetReadOnlyPref()

읽기 전용 여부

POSITION GetStartPosition()

다중 선택의 경우

CString GetNextPathName()

'Window > Win32 API, MFC' 카테고리의 다른 글

[ 고급반 - MFC ] 이미지 뷰어  (0) 2009.09.27
고급반 - [ MFC ] 그림판  (18) 2009.09.19
[MFC] 클래스들 간 상호참조  (1) 2009.09.10
예비반 실습 - API  (0) 2009.03.05
Posted by 열ㅇl
Window/Win32 API, MFC2009. 3. 5. 21:38

공튀기기

 

 

 

 

 

학생관리_트리뷰

 

'Window > Win32 API, MFC' 카테고리의 다른 글

[ 고급반 - MFC ] 이미지 뷰어  (0) 2009.09.27
고급반 - [ MFC ] 그림판  (18) 2009.09.19
[MFC] 클래스들 간 상호참조  (1) 2009.09.10
[MFC] CFileDialog 다중 파일 선택하기  (1) 2009.06.12
Posted by 열ㅇl