WebBrowser で、innterTextやリンクを取得する方法

環境: Visual Studio 2010 / WPF

インターネット上のHTMLより、リンクや文書を取得するには、単にWebClient でHTMLを取って来て、処理すればいいのですが・・・

とある理由でHTMLをブラウズしながら、ドキュメントに含まれるリンクなどを取得する必要があったので、WebBrowser を使って作ってみました。

WebBrowser は、裏側で mshtml の COMで実装されているので、ちょっと使い方が面倒だったのでメモしておきます。

 

参照の追加より、COM のmshtml.tlb を追加する。

image

 

WebBrowserに対して、Navigate でブラウズする。

Navigated イベントだと、document を完全に取得する前に、Navigated イベントが発生してしまう。

そこで、Document が完全にロードを完了したイベントとして、LoadCompleted を使用する。

 

例1: innterTextを取得する場合

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.webBrowser1.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(webBrowser1_LoadCompleted);
        }

        void webBrowser1_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            if (webBrowser1.Document == null)
                return;

            mshtml.IHTMLDocument2 doc2 = (IHTMLDocument2)webBrowser1.Document;

            this.textBox2.Text = doc2.body.innerText;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            string url = this.textBox1.Text;
            this.webBrowser1.Navigate(url);
        }

例2: リンクの HTML をリストする場合

        void webBrowser1_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            if (webBrowser1.Document == null)
                return;

            mshtml.IHTMLDocument2 doc2 = (IHTMLDocument2)webBrowser1.Document;

            foreach (mshtml.IHTMLElement elem in doc2.links)
            {
                this.textBox2.Text += ((mshtml.IHTMLAnchorElement)elem).href + Environment.NewLine;
            }
        }

実際の実行結果はこんな感じ。

image

スレートPC上でのマルチタッチ開発メモその1

ONKYOのスレートPCを入手した。

tw217_main

http://www.jp.onkyo.com/pc/personalmobile/

さっそく、マルチタッチアプリケーションを作ってみる。

まずは、スレートPC上では開発できないというか、とてもやりにくいので、メインPC上で開発して、スレートPC上で動作させる形。リモートデバッグはできないので、ちょっと厄介かも。

ちょっとイベントがどのように取れているのか確認するプログラムをWPFで作ってみる。

.NET Framework 4.0 がないと動かないので、.NET Framework 4.0をインストール。

TouchEnter, TouchMove, TouchLeave, TouchUp関連は、

private void image1_TouchMove(object sender, TouchEventArgs e)
{
    this.textBoxTouchType.Text = “TouchMove”;

    ShowTouchParams(e);
}

private void ShowTouchParams(TouchEventArgs e)
{
    this.textBoxID.Text = “Touch ID = ” + e.TouchDevice.Id;

    TouchPoint tp = e.GetTouchPoint(this);

    this.textBoxPointX.Text = tp.Position.X.ToString();
    this.textBoxPointY.Text = tp.Position.Y.ToString();
    this.textBoxWidth.Text = tp.Size.Width.ToString(); // 値取れず
    this.textBoxHeight.Text = tp.Size.Height.ToString(); // 値取れず

    this.textBoxBoundsX.Text = tp.Bounds.X.ToString();
    this.textBoxBoundsY.Text = tp.Bounds.Y.ToString();
    this.textBoxBoundsW.Text = tp.Bounds.Width.ToString(); // 値取れず
    this.textBoxBoundsH.Text = tp.Bounds.Height.ToString(); // 値取れず
}

Manipulation系は、

IsManipulationEnabled を trueにセットして、
private void checkBoxManipulationEnabled_Click(object sender, RoutedEventArgs e)
{
    this.image1.IsManipulationEnabled = (bool)checkBoxManipulationEnabled.IsChecked;
    this.textBoxManipulation.Text = this.image1.IsManipulationEnabled.ToString();
}

private void image1_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
    this.textBoxManipulation.Text = “ManipulationDelta”;
    this.textBoxRotationDelta.Text = e.DeltaManipulation.Rotation.ToString();
    this.textBoxManipulationOrigX.Text = e.ManipulationOrigin.X.ToString();
    this.textBoxManipulationOrigY.Text = e.ManipulationOrigin.Y.ToString();
    this.textBoxRotation.Text = e.CumulativeManipulation.Rotation.ToString();
    this.textBoxManTransX.Text = e.CumulativeManipulation.Translation.X.ToString();
    this.textBoxManTransY.Text = e.CumulativeManipulation.Translation.Y.ToString();

    if (e.DeltaManipulation.Rotation != 0)
    {
        Matrix mat = this.image1.RenderTransform.Value;
        mat.RotateAt(e.DeltaManipulation.Rotation, e.ManipulationOrigin.X, e.ManipulationOrigin.Y);
        this.image1.RenderTransform = new MatrixTransform(mat);
    }
    else
    {
        Matrix mat = this.image1.RenderTransform.Value;
        mat.Translate(e.CumulativeManipulation.Translation.X, e.CumulativeManipulation.Translation.Y);
        this.image1.RenderTransform = new MatrixTransform(mat);
    }
}

イナーシャーは、

private void checkBoxInertier_Click(object sender, RoutedEventArgs e)
{
    if(checkBoxInertier.IsChecked == true)
        Manipulation.StartInertia(this.image1);
}

private void image1_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)
{
    this.textBoxManipulation.Text = “ManipulationInertiaStarting”;
    this.textBoxManipulationOrigX.Text = e.ManipulationOrigin.X.ToString();
    this.textBoxManipulationOrigY.Text = e.ManipulationOrigin.Y.ToString();

    e.TranslationBehavior.DesiredDeceleration = 0.001;
    e.RotationBehavior.DesiredDeceleration = 0.001;
}

これで、Delta, Cumulative が取れた。イベントをモニタリングのためにTextBoxに書き出していたら、かなりもっさりした感じになってしまった。

リモートデバッグできないのは、やっかいだな。

移動・ローテーションは、もう少しまともなコードの気がするが、とりあえず機能の説明を忘れないうちにっと。あとでスクリーンショットをもらおう・・・

WPF Shooting Star

[youtube=http://www.youtube.com/watch?v=0l7xTEgUT54&hl=en]

 

This is something like shooting star implemented by WPF/C#. Here is the code. It’s messy, but it is just for my coding memo.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Storyboard  x:Key="OnClick2">
            <!–<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="r1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:11" Value="-120"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="r1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:11" Value="32"/>
            </DoubleAnimationUsingKeyFrames>–>
            <!–<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="r1" Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0"/>
            </DoubleAnimationUsingKeyFrames>–>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button2">
            <BeginStoryboard x:Name="OnClick2_BeginStoryboard" Storyboard="{StaticResource OnClick2}"/>
        </EventTrigger>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
    </Window.Triggers>

    <Grid Background="Black">
        <Canvas Height="100" HorizontalAlignment="Left" Margin="120,87,0,0" Name="canvas1" VerticalAlignment="Top" Width="200">
            <Canvas.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Canvas.RenderTransform>
            <Rectangle Height="4" Name="r" Stroke="Black" Width="1000" Canvas.Left="-50" Canvas.Top="29" >
                <Rectangle.Fill>
                    <LinearGradientBrush MappingMode="RelativeToBoundingBox" EndPoint="0.5,1" StartPoint="0.5,0" >
                        <LinearGradientBrush.RelativeTransform>
                            <TransformGroup>
                                <ScaleTransform CenterX="0.5" CenterY="0.5"/>
                                <SkewTransform CenterX="0.5" CenterY="0.5"/>
                                <RotateTransform Angle="-90" CenterX="0.5" CenterY="0.5"/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </LinearGradientBrush.RelativeTransform>
                        <GradientStop Color="Black" Offset="1"/>
                        <GradientStop Color="Magenta"/>
                    </LinearGradientBrush>
                </Rectangle.Fill>
                <Rectangle.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Rectangle.RenderTransform>
            </Rectangle>
        </Canvas>
        <Button Content="Button" Height="31" HorizontalAlignment="Left" Margin="50,268,0,0" Name="button1" VerticalAlignment="Top" Width="96" Click="button1_Click" />
        <Button Content="Button" Height="31" HorizontalAlignment="Left" Margin="210,268,0,0" Name="button2" VerticalAlignment="Top" Width="96"/>
    </Grid>
</Window>

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            int size = 2;

            Storyboard sb = (Storyboard)this.Resources["OnClick2"];
            SBMoveCanvas(sb, "canvas1");
            SBLength(sb, "r");

            for (int i = 0; i < 200; i++)
            {
                string name = "r" + i.ToString();
                Rectangle r = new Rectangle();
                r.Fill = new SolidColorBrush(Colors.Magenta);
                r.Height = size;
                r.Width = size;

                ScaleTransform st = new ScaleTransform();
                SkewTransform skt = new SkewTransform();
                RotateTransform rt = new RotateTransform();
                TranslateTransform tt = new TranslateTransform();
                TransformGroup tg = new TransformGroup();
                tg.Children.Add(st);
                tg.Children.Add(skt);
                tg.Children.Add(rt);
                tg.Children.Add(tt);

                r.RenderTransform = tg;
                this.RegisterName(name, r);
                Canvas.SetLeft(r, i * size);
                Canvas.SetTop(r, 30);
                SBDissolve(sb, name, i);
                canvas1.Children.Add(r);
            }
        }

        System.Random rnd = new System.Random();

        private void SBDissolve(Storyboard sb, string name, int pos)
        {
            DoubleAnimationUsingKeyFrames daukfX = new DoubleAnimationUsingKeyFrames();

            daukfX.BeginTime = new TimeSpan(0, 0, 0);
            daukfX.Duration = new TimeSpan(0, 0, duration);
            daukfX.KeyFrames.Add(
                 new SplineDoubleKeyFrame(0, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0))));
            daukfX.KeyFrames.Add(
                new SplineDoubleKeyFrame(rnd.Next(6000, 8000), KeyTime.FromTimeSpan(new TimeSpan(0, 0, duration + (200-pos)))));

            Storyboard.SetTargetName(daukfX, name);
            Storyboard.SetTargetProperty(daukfX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"));

            sb.Children.Add(daukfX);

            DoubleAnimationUsingKeyFrames daukfY = new DoubleAnimationUsingKeyFrames();

            daukfY.BeginTime = new TimeSpan(0, 0, 0);
            daukfY.Duration = new TimeSpan(0, 0, duration);
            daukfY.KeyFrames.Add(
                 new SplineDoubleKeyFrame(0, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0))));
            daukfY.KeyFrames.Add(
                new SplineDoubleKeyFrame(rnd.Next(-500, 500), KeyTime.FromTimeSpan(new TimeSpan(0, 0, duration + (200-pos)))));

            Storyboard.SetTargetName(daukfY, name);
            Storyboard.SetTargetProperty(daukfY, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)"));

            sb.Children.Add(daukfY);

            DoubleAnimationUsingKeyFrames daukfOp = new DoubleAnimationUsingKeyFrames();

            daukfOp.BeginTime = new TimeSpan(0, 0, 0);
            daukfOp.Duration = new TimeSpan(0, 0, duration);
            daukfOp.KeyFrames.Add(
                 new SplineDoubleKeyFrame(1.0, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0))));
            daukfOp.KeyFrames.Add(
                new SplineDoubleKeyFrame(0.0, KeyTime.FromTimeSpan(new TimeSpan(0, 0, duration))));

            Storyboard.SetTargetName(daukfOp, name);
            Storyboard.SetTargetProperty(daukfOp, new PropertyPath("(UIElement.Opacity)"));

            sb.Children.Add(daukfOp);
        }

        const int duration = 5;

        private void SBMoveCanvas(Storyboard sb, string name)
        {
            DoubleAnimationUsingKeyFrames daukfX = new DoubleAnimationUsingKeyFrames();

            daukfX.BeginTime = new TimeSpan(0, 0, 0);
            daukfX.Duration = new TimeSpan(0, 0, duration);
            daukfX.KeyFrames.Add(
                 new SplineDoubleKeyFrame(500, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0))));
            daukfX.KeyFrames.Add(
                new SplineDoubleKeyFrame(-500, KeyTime.FromTimeSpan(new TimeSpan(0, 0, duration))));

            Storyboard.SetTargetName(daukfX, name);
            Storyboard.SetTargetProperty(daukfX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"));

            sb.Children.Add(daukfX);

            DoubleAnimationUsingKeyFrames daukfY = new DoubleAnimationUsingKeyFrames();

            daukfY.BeginTime = new TimeSpan(0, 0, 0);
            daukfY.Duration = new TimeSpan(0, 0, duration);
            daukfY.KeyFrames.Add(
                 new SplineDoubleKeyFrame(30, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0))));
            daukfY.KeyFrames.Add(
                new SplineDoubleKeyFrame(30, KeyTime.FromTimeSpan(new TimeSpan(0, 0, duration))));

            Storyboard.SetTargetName(daukfY, name);
            Storyboard.SetTargetProperty(daukfY, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)"));

            sb.Children.Add(daukfY);
        }

        private void SBLength(Storyboard sb, string name)
        {
            DoubleAnimationUsingKeyFrames daukfX = new DoubleAnimationUsingKeyFrames();

            daukfX.BeginTime = new TimeSpan(0, 0, 0);
            daukfX.Duration = new TimeSpan(0, 0, duration);
            daukfX.KeyFrames.Add(
                 new SplineDoubleKeyFrame(1, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0))));
            daukfX.KeyFrames.Add(
                new SplineDoubleKeyFrame(0, KeyTime.FromTimeSpan(new TimeSpan(0, 0, duration))));

            Storyboard.SetTargetName(daukfX, name);
            Storyboard.SetTargetProperty(daukfX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"));

            sb.Children.Add(daukfX);
        }
    }

GeometryModel3D を手書き

             //TriangleIndices="0 1 2  0 2 3 "
             //Positions="0 0 0,  1 0 0, 1 1 0, 0 1 0"
             //TextureCoordinates="0,1 1,1 1,0 0,0 "
             //Normals="0,0,1 0,0,1 0,0,1 0,0,1"

            MeshGeometry3D mg3d = new MeshGeometry3D();
            mg3d.Positions = new Point3DCollection { new Point3D(0, 0, 0), new Point3D(1, 0, 0), new Point3D(1, 1, 0), new Point3D(0, 1, 0) };
            mg3d.TriangleIndices = new Int32Collection { 0,1,2,0,2,3};
            mg3d.TextureCoordinates = new PointCollection{ new Point(0, 1), new Point(1, 1), new Point(1, 0), new Point(0, 0)};
            mg3d.Normals = new Vector3DCollection { new Vector3D(0, 0, 1), new Vector3D(0, 0, 1), new Vector3D(0, 0, 1), new Vector3D(0, 0, 1) };

            GeometryModel3D gm3d = new GeometryModel3D();

            MediaElement me = new MediaElement();
            me.Source = new Uri(@"……….\Wildlife.wmv");

            TextBlock someText = new TextBlock();
            FontSizeConverter myFontSizeConverter = new FontSizeConverter();
            someText.FontSize = (double)myFontSizeConverter.ConvertFrom("30pt");
            someText.Text = "Hello, World!";

            VisualBrush vb = new VisualBrush();
            vb.Visual = someText;
または
            vb.Visual = me;

            gm3d.Material = new DiffuseMaterial(vb);
            gm3d.Geometry = mg3d;

            this.BoxOR9.Children.Add(gm3d);

WPF 3D 上での画像とビデオの表示

イメージ部分を抜き出したもの

image 

<GeometryModel3D.Material>
    <DiffuseMaterial>
        <DiffuseMaterial.Brush>
            <ImageBrush ImageSource="bobsled.jpg"></ImageBrush>
        </DiffuseMaterial.Brush>
    </DiffuseMaterial>
</GeometryModel3D.Material>
<GeometryModel3D.Geometry>
    <MeshGeometry3D
        TriangleIndices="0 1 2  0 2 3 "
        Positions="0 0 0,  1 0 0, 1 1 0, 0 1 0"
        TextureCoordinates="0,1 1,1 1,0 0,0 "
        Normals="0,0,1 0,0,1 0,0,1 0,0,1"
    />
</GeometryModel3D.Geometry>

ビデオ部分を抜き出したもの

image 

<GeometryModel3D.Material>
    <DiffuseMaterial>
        <DiffuseMaterial.Brush>
            <VisualBrush>
                <VisualBrush.Visual>
                    <MediaElement Source="wildlife.wmv" />
                </VisualBrush.Visual>
            </VisualBrush>

        </DiffuseMaterial.Brush>
    </DiffuseMaterial>
</GeometryModel3D.Material>
<GeometryModel3D.Geometry>
    <MeshGeometry3D
        TriangleIndices="0 1 2  0 2 3 "
        Positions="0 0 0,  1 0 0, 1 1 0, 0 1 0"
        TextureCoordinates="0,1 1,1 1,0 0,0 "
        Normals="0,0,1 0,0,1 0,0,1 0,0,1"
    />
</GeometryModel3D.Geometry>

WPF覚書

image

サンプルコード

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    x:Class="WpfApplication2.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640" Height="480" mc:Ignorable="d">

<Viewport3D xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="http://schemas.openxmlformats.org/markup-compatibility/2006" c:Ignorable="d" x:Name="ZAM3DViewport3D" ClipToBounds="true" Width="400" Height="300">
    <Viewport3D.Camera>
        <PerspectiveCamera x:Name="Free_CameraOR6" FarPlaneDistance="10" LookDirection="0,0,-1" UpDirection="0,1,0" NearPlaneDistance="1" Position="0,0.0199925,2.5" FieldOfView="39.5978" />
    </Viewport3D.Camera>

    <ModelVisual3D>
        <ModelVisual3D.Content>
            <Model3DGroup x:Name="Scene"> <!– Scene (XAML Path = ) –>
                <Model3DGroup.Transform>
                    <Transform3DGroup>
                        <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
                        <ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/>
                        <RotateTransform3D d:EulerAngles="0,27.919,0">
                            <RotateTransform3D.Rotation>
                                <AxisAngleRotation3D Angle="27.919" Axis="0,1,0"/>
                            </RotateTransform3D.Rotation>
                        </RotateTransform3D>
                        <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
                        <TranslateTransform3D OffsetY="0.401" OffsetX="-0.446" OffsetZ="0.052"/>
                    </Transform3DGroup>
                </Model3DGroup.Transform>
                <AmbientLight Color="#333333" />
                <DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" />
                <DirectionalLight Color="#FFFFFF" Direction="0.612372,-0.5,-0.612372" />
                <Model3DGroup x:Name="BoxOR9"> <!– Box (XAML Path = (Viewport3D.Children)[0].(ModelVisual3D.Content).(Model3DGroup.Children)[3]) –>
                    <Model3DGroup.Transform>
                        <Transform3DGroup>
                            <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
                            <ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/>
                            <RotateTransform3D>
                                <RotateTransform3D.Rotation>
                                    <AxisAngleRotation3D Angle="65.59121363" Axis="0.1478755617 0.6791817096 0.7189193443"/>
                                </RotateTransform3D.Rotation>
                            </RotateTransform3D>
                            <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
                        </Transform3DGroup>
                    </Model3DGroup.Transform>
                    <GeometryModel3D x:Name="BoxOR9GR10">
                        <GeometryModel3D.Material>
                            <DiffuseMaterial>
                                <DiffuseMaterial.Brush>
                                    <VisualBrush>
                                        <VisualBrush.Visual>
                                            <MediaElement Source="wildlife.wmv" />
                                        </VisualBrush.Visual>
                                    </VisualBrush>
                                </DiffuseMaterial.Brush>
                            </DiffuseMaterial>
                        </GeometryModel3D.Material>
                        <GeometryModel3D.Geometry>
                            <MeshGeometry3D
                                TriangleIndices="0 1 2  0 2 3 "
                                Positions="0 0 0,  1 0 0, 1 1 0, 0 1 0"
                                TextureCoordinates="0,1 1,1 1,0 0,0 "
                                Normals="0,0,1 0,0,1 0,0,1 0,0,1"
                            />
                        </GeometryModel3D.Geometry>
                        <GeometryModel3D.Transform>
                            <Transform3DGroup>
                                <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
                                <ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/>
                                <RotateTransform3D d:EulerAngles="-4.454,-33.326,-46.125">
                                    <RotateTransform3D.Rotation>
                                        <AxisAngleRotation3D Angle="57.575" Axis="-0.304,-0.517,-0.8"/>
                                    </RotateTransform3D.Rotation>
                                </RotateTransform3D>
                                <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
                                <TranslateTransform3D OffsetX="-1.015" OffsetY="-0.317" OffsetZ="0.226"/>
                            </Transform3DGroup>
                        </GeometryModel3D.Transform>
                    </GeometryModel3D>
                </Model3DGroup>
            </Model3DGroup>
        </ModelVisual3D.Content>
    </ModelVisual3D>
</Viewport3D>
</Window>

TMScreensaver V0.6 をアップしました。

V0.5は、XP の場合設定ファイルが機能しないという問題点がありました。これは、8.3ファイル名の制限によるものでした。

修正版V0.6 をアップします。修正点は、ファイル名の変更(TMScreensaver.scr → TMScrs.scr、TMScreensaver.config→ TMScrs.config)です。

古いバージョンをお使いの方は、次の手順でアンインストールしてください。m_ _m

    1.解凍したフォルダーを削除
    2.レジストリの CurrentUser\Software\Uchukamen\TMScreensaver 以下を削除
    PCに格納されたデータは、これで完全に削除されます。  

[1] 名称
	TMScreensaver(x86 32bit 版)
	
[2] 概要
	映画 Matrix のように Twitter のタイムラインを縦に流れるように表示するスクリーンセーバー

[3] バージョン
	0.6

[4]	ダウンロード
    http://cid-7cb203a44bf94940.skydrive.live.com/browse.aspx/TMScreensaver
    より、TMScrs.zip をダウンロードしてください。 

[5] 動作環境
	Windows XP, Windows Vista, Windows 7で動作を確認しました。
     .NET Framework 4.0 が必要です。次のURLから .NET Framework 4.0 をインストールしてください。 http://www.microsoft.com/downloads/details.aspx?FamilyID=9cfb2d51-5ff4-4491-b0e5-b386f32c0992&displaylang=ja グラフィックアクセラレータを搭載していること(CPUでの描画だと苦しいはず) [6] インストール方法 1.古いバージョンをインストールしている人は、古いフォルダーの削除を行ってください。 レジストリはエントリを上書きしますので、削除不要です。
2.TMScrs.zip をダウンロードし、任意の場所(たとえばマイドキュメントフォルダーなど)で、解凍する。 3.エクスプローラで、解凍したフォルダーを開き、TMScrs.scr を右クリックし、[インストール]を選択 4.初めての場合は、TMScreensaver Configurationダイアログが表示されるので、次の情報を入力 Username...twitter のユーザーアカウントを入力 Password...twitter のパスワードを入力 5.OKボタンを押すと、設定情報をレジストリに格納 6.プレビューボタンを押し、プレビューで動作を確認 [7] アンインストール方法 1.解凍したフォルダーを削除 2.レジストリの CurrentUser\Software\Uchukamen\TMScreensaver 以下を削除 PCに格納されたデータは、これで完全に削除されます [8] 注意制限 1.最大タイムラインは200個 2.通信エラー等発生した場合は、赤いメッセージを表示 [9] 各種設定 TMScreensaver.config のXML Configurationファイルを修正する MaxTweets...タイムラインの同時表示数 BackColor...背景色 ForeColor...文字色 FontSize...タイムラインのフォントサイズ Rotation...メッセージの方向(-90...上から下へ、0...左から右へ) ShowImage...プロファイルアイコンの表示(Visible)、非表示(Hide) [10] バグ報告、要望など uchukamen宛に、#TMScreensaver タグでつぶやいてください。

TMScreensaver V0.5 をアップしました。

V0.4は、スクリーンセーバーとして起動しないという致命的な問題点がありました。理由はよくわかりませんが、起動直後にエラー記録用のファイルをクリエートしたとたんに、プロセスから抜けてしまいます。T T

修正版V0.5 をアップします。修正点は、エラー記録用のファイルを作成しないようにした点と、ファイル名の変更(TMScreensaver.exe.scr → TMScreensaver.scr、TMScreensaver.exe.config→ TMScreensaver.config)です。

古いバージョンをお使いの方は、次の手順でアンインストールしてください。m_ _m

    1.解凍したフォルダーを削除
    2.レジストリの CurrentUser\Software\Uchukamen\TMScreensaver 以下を削除
    PCに格納されたデータは、これで完全に削除されます。  

[1] 名称
    TMScreensaver(x86 32bit 版)
[2] 概要
    映画 Matrix のように Twitter のタイムラインを縦に流れるように表示するスクリーンセーバー

[3] バージョン
    0.5

[4]    ダウンロード
http://cid-7cb203a44bf94940.skydrive.live.com/browse.aspx/TMScreensaver
    より、TMScreensaver.zip をダウンロードしてください。

[5] 動作環境
    .NET Framework 4.0 が動く環境
http://www.microsoft.com/downloads/details.aspx?FamilyID=9cfb2d51-5ff4-4491-b0e5-b386f32c0992&displaylang=ja
    グラフィックアクセラレータを搭載していること(CPUでの描画だと苦しいはず)

[6] インストール方法
  1.TMScreensaver.zip をダウンロードし、任意の場所(たとえばマイドキュメントフォルダーなど)で、解凍する。
    2.エクスプローラで、解凍したフォルダーを開き、TMScreensaver.scr を右クリックし、[インストール]を選択
    3.初めての場合は、TMScreensaver Configurationダイアログが表示されるので、次の情報を入力
        Username…twitter のユーザーアカウントを入力
        Password…twitter のパスワードを入力
    5.OKボタンを押すと、設定情報をレジストリに格納
    6.プレビューボタンを押し、プレビューで動作を確認
[7] アンインストール方法
    1.解凍したフォルダーを削除
    2.レジストリの CurrentUser\Software\Uchukamen\TMScreensaver 以下を削除
    PCに格納されたデータは、これで完全に削除されます   

[8] 注意制限
    1.最大タイムラインは200個
    2.通信エラー等発生した場合は、赤いメッセージを表示

[9] 各種設定
    TMScreensaver.config のXML Configurationファイルを修正する

    MaxTweets…タイムラインの同時表示数
    BackColor…背景色
    ForeColor…文字色
    FontSize…タイムラインのフォントサイズ
    Rotation…メッセージの方向(-90…上から下へ、0…左から右へ)
    ShowImage…プロファイルアイコンの表示(Visible)、非表示(Hide)

[10] 要望など
    uchukamen宛に、#TMScreensaver タグでつぶやいてください。

[11] バグ報告
    uchukamen宛に、#TMScreensaver タグでつぶやいてください。

TMScreensaver V0.4

バージョンV0.4 をリリースします。

修正点: Readme の修正、アイコンを非表示、Zip フォルダーを “TMS” から “TMScreensaver 04” に変更

[1] 名称
	TMScreensaver(x86 32bit 版)
	
[2] 概要
	映画 Matrix のように Twitter のタイムラインを縦に流れるように表示するスクリーンセーバー

[3] バージョン
	0.4

[4]	ダウンロード
    http://cid-7cb203a44bf94940.skydrive.live.com/browse.aspx/TMScreensaver
    より、TMS**.zip をダウンロードしてください。 (**は、バージョン番号の数字2ケタ)

[5] 動作環境
	.NET Framework 4.0 が動く環境
	http://www.microsoft.com/downloads/details.aspx?FamilyID=9cfb2d51-5ff4-4491-b0e5-b386f32c0992&displaylang=ja
	グラフィックアクセラレータを搭載していること(CPUでの描画だと苦しいはず)

[6] インストール方法
  1.TMS**.zip をダウンロードし、任意の場所(たとえばマイドキュメントフォルダーなど)で、解凍する。
	2.エクスプローラで、解凍したフォルダーを開き、TMScreensaver.exe.scr を右クリックし、[インストール]を選択
	3.初めての場合は、TMScreensaver Configurationダイアログが表示されるので、次の情報を入力
		Username...twitter のユーザーアカウントを入力
		Password...twitter のパスワードを入力
	5.OKボタンを押すと、設定情報をレジストリに格納
	6.プレビューボタンを押し、プレビューで動作を確認
	
[7] アンインストール方法
	1.解凍したフォルダーを削除
	2.レジストリの CurrentUser\Software\Uchukamen\TMScreensaver 以下を削除
	PCに格納されたデータは、これで完全に削除されます	

[8] 注意制限
	1.最大タイムラインは200個
	2.通信エラー等発生した場合は、赤いメッセージを表示

[9] 各種設定
	TMScreensaver.exe.config のXML COnfigurationファイルを修正する

	MaxTweets...タイムラインの同時表示数
	BackColor...背景色
	ForeColor...文字色
	ErrorColor...エラーメッセージの文字色
	FontSize...タイムラインのフォントサイズ
	Rotation...メッセージの方向(-90...上から下へ、0...左から右へ)
	ShowImage...プロファイルアイコンの表示(Visible)、非表示(Hide)

[10] 要望など
	uchukamen宛に、#TMScreensaver タグでつぶやいてください。

[11] バグ報告
	uchukamen宛に、#TMScreensaver タグでつぶやいてください。
	クラッシュ時には、TMScreensaverLog.txt というログファイルが
	フォルダーに作成されます。