GSI

WebBrowser 처리방식.. 참..

WPF 2009. 12. 7. 06:09 |


2일 정도 자료를 찾아 보고 했지만.
WebBrowser 는 왜 WPF의 렌더링 방식과 차이가 있는지 모르겠다.
왜냐하면 WebBrowser 위에 다른걸 그리고 싶었지만.
되지 않더라..

그래서 자료를 보다 보니. BitmapSource 라는걸 사용해서 WPF의 렌더링 방식에
맞출수 있다는걸 알았다.
뭐 용어는 잘 모르겠고 암튼 이런 방식인게다. 쩝..
산넘어 산인거지..

우선 이걸 해결 하고 나니 몇가지 더 테스트 할게 남아 있다.
실제 WebBrowser는 숨겨 놓고 Image 같은데 실시간으로 뿌리면서 드로잉 해야 한다는 것과
숨겨 놓은 웹의 Mouse, Keyboard 등의 접근을 또 어떻게 처리 해야 하느냔데..

암튼 더 고민해봐야 할듯 하다.
아래 자료는 최종 코드...

-- Source --
<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="600" Width="1000" xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration">

    <Grid>
        <WebBrowser x:Name="webbrowser" Source="http://www.naver.com" Margin="0,0,437,199" />
       
        <Button Height="23" HorizontalAlignment="Right" Margin="0,104,307,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click">Button</Button>
        <Image HorizontalAlignment="Right" Margin="0,178,18,21" Name="image1" Stretch="Fill" Width="399" />
    </Grid>

</Window>

..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;


namespace WpfApplication1
{
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window
    {
        BitmapSource bitmapsource = null;

        [DllImport("user32.dll", SetLastError = true)]
        static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);

        [DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);
       
        public Window1()
        {
            InitializeComponent();
        }

        BitmapSource GetScreenInt()
        {
            Bitmap bm = new Bitmap((int)300, (int)300);
            IntPtr hBitmap = bm.GetHbitmap();
            Graphics g = Graphics.FromImage(bm);
            PrintWindow(this.webbrowser.Handle, g.GetHdc(), 0);

            g.ReleaseHdc();

            g.Flush();

            BitmapSource src = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bm.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,
                System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
            src.Freeze();

            bm.Dispose();
            bm = null;
            DeleteObject(hBitmap);

            return src;

        }
       
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            this.image1.Source = null;
            this.image1.Source = GetScreenInt();
        }
    } 
}

Posted by gsi
:


이 오류가 뭔지 처음에는 많이 애매했다.
이게 나온 경우는 아래와 같다.

UnitProject로 사용자 정의 컨트롤을 하나 만들었습니다.
그리고 테스트가 제대로 되서
메인 프로젝트에 해당 Xaml, cs 파일의 내용을 그대로 복사

그렇게 했을때 오류가 발생하더라구요.

오류 CS0103: 'InitializeComponent' 이름이 현재 컨텍스트에 없습니다.

왜 나왔냐.. 찾아 보니까 문제는 네임스페이스였습니다.

xaml 코드에서 x:Class="WpfApplication1.ucStartup" 라는 부분이 있었는데
메인 프로젝트의 네임 스페이스는 WpfApplication1 이게 아니였기 때문입니다.

그렇다 보니 cs 파일의 생성자 부분의 'InitializeComponent'  메소드가 네임스페이가 틀리게 되면
호출되지 않게 됩니다.

그러면 'InitializeComponent'  이 메소드는 어디 있는가?

이건 컴파일 타임에서 생성되며 보통 Xaml 파일이 obj/Debug/**.g.cs 파일로 만들어 지는데요.
그 속에 존재를 하게 됩니다.

뭐.. 잘만 하면 나오지 않는 오류이지만, 어떤 오류인지 알고 나니 더 좋다고나 할까요? ^^
Posted by gsi
:

스토리 보드를 사용할때 에니메이션이 끝나고 다른걸 처리 하는 경우가 많다.
<Storyboard x:Key = "ZoomInImage" Completed = "ZoomFinished">
...

위와 같은 코드가 xaml 파일에 존재 하면
cs 파일에는 Completed의 이벤트 메소드가 선언되어 있어야 한다. (블랜드에서도 자동으로 생성하게 된다.)

private void ZoomFinished(object sender, EventArgs e)
{
Window1 parentWindow = Window.GetWindow(this) as Window1;
parentWindow.UpdateDisplay(FolderPath);
}

위와 같이 sender로 전달되어온 Storyboard 의 부모 윈도우를 얻을때 GetWindow() 를 통해서
가져올 수 있다.
Posted by gsi
:


DB, Webservice, C#, WPF를 통합적으로 공부 하기 위해서.
현재 모니터링 툴을 하나 개발 중이다.

대충 이런 개념이다.

프로그램을 하다 보면 로그를 남겨야 하고,
그 로그로 인한 상태 정보를 파악하고자 할때가 많다.
그래서 그 로그 정보를 해당 DB로 저장하도록 한다.

웹 서비스를 통해서 해당 로그 정보를 DB로 저장하게 된다.

그리고 모니터링 툴은 현재 변경된 정보만을 DB에서 웹 서비스를 통해서
지속적으로 화면에 출력하게 된다.

출력되는 내용에 따라서 에러나 경고 메시지는 창을 통해서 새롭게 출력이 되게 된다.

대충 이런 개념이다.

현재 DB, 웹 서비스 부분은 완료 되었으며,
모니터링 툴의 UI 부분도 대충은 마무리가 되어 가고 있다.

심플하게 구성해 봤지만.
다양한 어플리케이션을 배울 수 있는 아주 좋은 프로젝트인듯 하다.

이후에 다양하게 응용할 부분은 해당 어플리케이션의 시스템 상태 정보를 볼수 있는 경우나,
IDC 센터의 서버를 이용해서 모니터링을 받게 되면, 유지 보수 및 원격지에서도
해당 어플리케이션의 정보를 탐색이 가능할듯 하다.

이후에는 프로그램의 노가다를 최대한 줄이기 위한 나만의 복사코드를 DB화 해서
원격지에서 해당 클립 보드로 전송하고, 그 내용을 바로 적용 가능하도록 하고
더 나아가면, 음성 인식 시스템을 도입해서, 해당 내용을 빠르게 검색하고
내용 전송을 통한 코드 적용을 극대화 하는 것도 연구중이다.

이 부분에서는 음성 인식 패턴을 다양하게 구축할 수 있는 서버가
관건인듯 하지만.. 아직은 자금이나, 아이디어가 많이 부족하기 때문에.
다양한 단위 테스트를 통한 학습을 우선 해야 할듯 하다.

우선 모니터링 툴에 대한 일부 내용들은 내가 WPF용으로 따로 만든 티스토리 페이지에서
지속적으로 업데이트할 생각이다.

WPF 관련된 내용은 여기 페이지가 많아지는 걸 없애기 위해서
그쪽에서 여러가지 테스트를 통한 내용들을 정리할 생각이다.

바쁘지만.. 요즘 같은 시기가 나에게는 다시금 오지 않을 30대 초반의
자유인듯 하다.
Posted by gsi
:

사용자 삽입 이미지

xaml 코드로만 작성해본 폼입니다.

관련코드 :


.
Posted by gsi
:

Kaxaml 1.0 Tool

WPF 2008. 6. 1. 10:45 |

 

http://www.google.co.kr/imgres?imgurl=http://thewpfblog.com/images/yahoo1.jpg&imgrefurl=http://www.snowball.be/CategoryView,category,WPF.aspx&h=473&w=630&sz=261&tbnid=RkGYSUpLU1QJ:&tbnh=103&tbnw=137&prev=/images%3Fq%3Dwpf&hl=ko&sa=X&oi=image_result&resnum=15&ct=image&cd=3

Welcome to Kaxaml!

Kaxaml is a lightweight XAML editor that gives you a "split view" so you can see both your XAML and your rendered content (kind of like XamlPad but without the gigabyte of SDK). Kaxaml is a hobby and was created to be shared, so it's free! Feel free to download and try it out. If you don't like it, it cleans up nicely.

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
:

[WPF] - Angle Gauge 데모

WPF Sample 2008. 3. 10. 18:03 |


사용자 삽입 이미지

Angle Gauge 를 표현해 봤습니다.
원형의 형태에서 AngleArc 같은걸 표현하지 못해서..
조금 다르게 표현해 봤네요.. -.-
Design 에서 그려서 Blend 를 통해서 표현해 봤어요.
TextBox 를 통해서 각도를 입력 받고, Start를 사용해서 에니메이션 구동..

UI만 이쁘게 꾸민다면.. 나름 이쁜 상태 표시용 게이지가 되겠네요.

관련 코드 :
Posted by gsi
:

사용자 삽입 이미지

Wpf Animation( Storyboard ) Demo

Xaml의 Storyboard를 추가 하고 cs 파일을 통해서 처리 해봤습니다.

- Button 을 누르면 해당 값을 설정하고 바로 에니메이션을 동작한다.
- SliderBar 을 누르면 해당 값을 설정하고 바로 에니메이션을 동작한다.

관련코드 :
Posted by gsi
:

사용자 삽입 이미지

Canvas에 사용자 정의 객체를 바인딩 해서 적용해 본 결과.

관련 코드 :
Posted by gsi
:

사용자 삽입 이미지

본 내용은 자료가 좀 많다. -.-
우선 정리는 시간이 걸리기 때문에 차후에 해야 할거 같다.

간단하게 정리 하면...
Employee 라는 직원 정보를 담고 있는 클래스를 하나 제작한다.
Button의 Content의 프로퍼티를 Employee 객체로 설정하여 버튼을 확장하는 예제이다.
여기에서 사용되는 내용은 ContentTemplate, DataTemplate, DataTemplateSelector, DataTemplate.Triggers 등에 대한 내용을 담고 있다.
(이 내용은 WPF 서적의 25장. 템플릿의 내용이다.)

관련소스 :
Posted by gsi
:

사용자 삽입 이미지
  • ControlTemplate 태그 내에는 TargetType 속성을 포함하는 것이 가능하다.
    <ControlTemplate x:Key="btnCustom" TargetType="{x:Type Button}">
    이 경우 TemplateBinding 표현에서 의존 프로퍼티의 클래스 이름을 앞에 붙일 필요는 없다. 바인딩에는 이 프로퍼티를 참조하라는 정보가 들어 있기 때문.
  • 여러개의 컨트롤이 템플릿을 공유할때 리소스로 정의해야 한다.
  • btnCustom이라는 x:Key를 가진 ControlTemplate을 정의한 스탠드 얼론 xaml파일이 있다.
  • ControlTemplate 상에 TargetType 속성을 설정한 이유는 의존 프로퍼티나 이벤트 앞에 반복해서 클래스 이름을 붙이지 않기 위함이다.
  • Posted by gsi
    :

    사용자 삽입 이미지

    Posted by gsi
    :

        public partial class UserControl1 : UserControl
        {
            public static DependencyProperty InputTextProperty;

            public UserControl1()
            {
                InitializeComponent();
           
                //
                InputTextProperty = DependencyProperty.Register("InputText", typeof(string),
                                typeof(UserControl1),
                                new FrameworkPropertyMetadata("none", new PropertyChangedCallback(OnInputTextChanged)));
            }

            public string InputText
            {
                set { SetValue(InputTextProperty, value); }
                get { return (string)GetValue(InputTextProperty); }
            }
             
            private void OnInputTextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
            {
                TextBlock tb = this.FindName("txtShow") as TextBlock;

                tb.Text = InputText;
            }
        }

    관련코드 :

    Posted by gsi
    :