仮面's profile宇宙仮面の C# 研究室.Live SpacePhotosBlogListsMore Tools Help

Blog


    January 26

    ASP.NET ルーティング 続き on 2003 Server

    この前の ASP.NET ルーティングは、VS2008 + Vista ASP.NET開発サーバーであっさり動きました。

    ところが、2003 Server で試してみると動かない。

    ???ということで調べてみると、

    IIS の Web サイトのプロパティ → ホームディレクトリ タブ → 構成ボタンを押し下げます。

    image

    すると、アプリケーションの構成ダイアログが表示されます。

    image 

    ここで、ワイルドカード アプリケーション マップで、挿入ボンタンを押す。

    image

    c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll を指定し、

    ファイルの存在を確認する チェックボックスを外す。

    これにより該当しないファイル拡張子の場合、aspnet_isapi.dll で、ルーティングが追加されていないかどうか確認するようになりました。

    Culminis : 1/22/2009 Announcing the APAC Regional Board

    シアトルでルームシェアしたインド人の Ashwin からのチャットで、次のお知らせをもらった。

    http://thevoice.culminis.com/APAC/Lists/Posts/Post.aspx?ID=4

    北端さんが DAL (Director-at-Large): で日本代表として参加されているとのこと。

    プロファイルは

    http://new.culminisconnections.com/BOD/APAC.aspx?PageView=Shared

    January 06

    ASP.NET ルーティング

    MSDN を読んでいたら、ASP.NET ルーティングということで、URLの書き換え方法が載っていた。

    http://msdn.microsoft.com/ja-jp/library/cc668201.aspx

    昔調べた方法から、IIS7 対応もあり、だいぶ変わっているようなので調べてみた。そうしたら、ええ~~、こんな簡単にできようになっちゃたんだー!と感動して、ためしに動かしてみようとしました。すると、CategoryRouteHandler がありませんと怒られる。そりゃそうだ、どこにもそんなコードがない。あれ??ということで調べてみると、どっとねっとふぁんBlog の小野さんが

    ASP.NET ルーティングを実装する

    で丁寧に解説してあった。さすが師匠wと感動する一方、やっぱりハンドラ書かないといけないのね。orz

    LinqDataSource によるメモリ内コレクションのデータへの接続

    http://msdn.microsoft.com/ja-jp/library/bb547113.aspx

    Default.aspx.cs にMoviewLibraryクラスを追加。

    using System;
    using System.Collections;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;

    namespace LinqDataSource
    {
        public partial class _Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {

            }
        }

        public class MovieLibrary
        {
            string[] _availableGenres = { "Comedy", "Drama", "Romance" };

            public MovieLibrary()
            {
            }

            public string[] AvailableGenres
            {
                get
                {
                    return _availableGenres;
                }
            }
        }
    }

    GridViewを追加。新しいデータソースを選択。

    image

    LINQを選択。

    image

    データソースの構成ダイアログで、MoviewLibraryを選択。

    image

    データの選択の構成ダイアログで、テーブル、Select, GroupBy, Where, OrderBy を指定可能。

    image

    実行すればこのとおり。

    image

    生成されたWPFコードは、

    <asp:GridView ID="GridView1" runat="server" DataSourceID="LinqDataSource1">
    </asp:GridView>
    <asp:LinqDataSource ID="LinqDataSource1" runat="server"
        ContextTypeName="LinqDataSource.MovieLibrary" TableName="AvailableGenres">
    </asp:LinqDataSource>

    列名までしっかり処理されている。もう少し複雑なテーブルで試してみると、これがずいぶん便利だということに気が付く。

    January 05

    Linqでファイルを作成日順でソート

    MSDNのサンプルそのままだけど、ちょっと便利。
           private void Form1_Load(object sender, EventArgs e)
            {
                string startFolder = @"C:\My Documents\My Pictures\";
    
                // Take a snapshot of the file system.
                IEnumerable fileList = GetFiles(startFolder);
    
                //Create the query
                IEnumerable fileQuery =
                    from file in fileList
                    where file.Extension == ".jpg"
                    orderby file.Name
                    select file;
    
                // Create and execute a new query by using the previous 
                // query as a starting point. fileQuery is not 
                // executed again until the call to Last()
                var files =
                    (from file in fileQuery
                     orderby file.CreationTime
                     select new { file.FullName, file.CreationTime });
            }
    
            // This method assumes that the application has discovery 
            // permissions for all folders under the specified path.
            static IEnumerable GetFiles(string path)
            {
                if (!System.IO.Directory.Exists(path))
                    throw new System.IO.DirectoryNotFoundException();
    
                string[] fileNames = null;
                List files = new List();
    
                fileNames = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
                foreach (string name in fileNames)
                {
                    files.Add(new FileInfo(name));
                }
                return files;
            }
    

    サービス参照の追加(VS2008) と Web参照の追加(VS2005)

    VS2005 では、サービス参照の追加から、次のようなサービスを追加することができる。このダイアログの一番下に、参照設定ボタンがある。

    image 

    この参照設定ボタンをクリックすると、次のようなサービス参照設定の詳細を指定することができる。このダイアログの一番下に、互換性ということで、Web 参照の追加ボタンがある。.NET Framework 2.0 web サービステクノロジーに基づいたコードを生成することができる。

    image

    Web 参照の追加ボタンを押すと、昔懐かしいWeb 参照ダイアログが表示される。

    image

    .NET 2.0とそれ以降では、生成されるコードが若干違ってくるので、注意が必要。

    January 03

    XAML Data Binding

    Expression Blend で TextBlockのプロパティ→共通プロパティ→ Text の右側の小さな四角をクリック

    image

    すると、次のようなメニューが表示されるので、データバインドを選択する。

    image

    データバインドの作成ダイアログが表示されるので、

    要素プロパティタブ→シーン要素から textBox1を選択、プロパティよりTextを選択し、完了。

    image

    生成されるXAMLコード

    <TextBox Name="textBox1" VerticalAlignment="Top" />
    <TextBlock x:Name="textBlock1" Text="{Binding Path=Text, ElementName=textBox1, Mode=Default}"/>

    Path を指定しない場合、既定でオブジェクト全体にバインドされます。

    Mode は、OneWay, TwoWay, OneTime, OneWayToSource, Default

    TwoWay
    ソース プロパティまたはターゲット プロパティのどちらか一方が変更されると、もう一方も自動的に更新されます。この型のバインディングは、編集可能なフォームや完全対話型の UI シナリオに適しています。

    OneWay
    バインディング ソース (ソース) の変更時にバインディング ターゲット (ターゲット) プロパティを更新します。この型のバインディングは、バインドされているコントロールが暗黙的な読み取り専用の場合に適しています。たとえば、株価情報などのソースにバインドする場合です。また、ターゲット プロパティには、データ バインドされたテーブルの背景色などの変更用コントロール インターフェイスがない可能性もあります。ターゲット プロパティの変更を監視する必要がない場合は、OneWay バインディング モードを使うことにより、TwoWay バインディング モードのオーバーヘッドを回避できます。

    OneTime
    アプリケーションの起動時またはデータ コンテキストの変更時にバインディング ターゲットを更新します。この型のバインディングは、現在の状態のスナップショットを使用した方がよい場合や、データが完全に静的である場合に適しています。また、ソース プロパティの値を使用してターゲット プロパティを初期化するときにデータ コンテキストが事前にわからない場合にも、この型のバインディングは便利です。基本的に、この型のバインディングは、ソース値が変わらない場合にパフォーマンスを向上させる OneWay バインディングを簡易化したものです。

    OneWayToSource
    ターゲット プロパティが変更されると、ソース プロパティを更新します。

    Default
    バインディング ターゲットの既定の Mode 値を使用します。ただし、既定値は、各依存関係プロパティによって異なります。一般に、ユーザーが編集できる、テキスト ボックスやチェック ボックスなどのコントロール プロパティは既定で双方向のバインディングであり、それ以外のほとんどのプロパティは既定で一方向のバインドになります。依存関係プロパティが既定で一方向と双方向のいずれであるかをプログラムにより決定する 1 つの方法は、GetMetadata を使用してプロパティのプロパティ メタデータを取得してから、BindsTwoWayByDefault プロパティのブール値を確認することです。

    TwoWay時のソースの更新時期(UpdateSourceTrigger)は、Default, Explicit, LostFocus, PropertyChanged

    <TextBox Name="textBox1" Text="{Binding Path=Text, ElementName=textBox2, Mode=TwoWay, UpdateSourceTrigger=Default}"/>
    <TextBox Name="textBox2" VerticalAlignment="Top" />

    ZAM3Dが生成するXAMLをC#で実装すると ー リソースモデル

    リソースモデルはこんな感じ。

            private void Sample()
            {
                this.viewPort3D1.Name = "ZAM3DViewport3D";
                viewPort3D1.ClipToBounds = true;
                viewPort3D1.Width = 400;
                viewPort3D1.Height = 300;
    
                ResourceDictionary resourceDictionary = new ResourceDictionary();
    
                ////
                
                MaterialGroup materialGroup = new MaterialGroup();
    
                DiffuseMaterial diffuseMaterial = new DiffuseMaterial();
                diffuseMaterial.Brush = new SolidColorBrush(Color.FromRgb(0xd3, 0xc8, 0xad));
                materialGroup.Children.Add(diffuseMaterial);
    
                SpecularMaterial specularMaterial = new SpecularMaterial();
                specularMaterial.SpecularPower = 93f;
                specularMaterial.Brush = new SolidColorBrush(Color.FromRgb(0x33, 0x33, 0x33));
                materialGroup.Children.Add(specularMaterial);
    
                resourceDictionary.Add("ER___Default_MaterialMR1", materialGroup);
    
                ////
    
                Transform3DGroup transform3DGroup = new Transform3DGroup();
    
                TranslateTransform3D translateTransform3D = new TranslateTransform3D(0f, 0f, 0f);
                ScaleTransform3D scaleTransform3D = new ScaleTransform3D(1f, 1f, 1f);
                AxisAngleRotation3D axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(0f, 1f, 0f), 0f);
                RotateTransform3D rotateTransform3D = new RotateTransform3D();
                rotateTransform3D.Rotation = axisAngleRotation3D;
                TranslateTransform3D translateTransform3D2 = new TranslateTransform3D(0f, 0f, 0f);
                
                transform3DGroup.Children.Add(translateTransform3D);
                transform3DGroup.Children.Add(scaleTransform3D);
                transform3DGroup.Children.Add(rotateTransform3D);
                transform3DGroup.Children.Add(translateTransform3D2);
    
                resourceDictionary.Add("SceneTR7", transform3DGroup);
    
                ////
    
                Transform3DGroup transform3DGroupBox = new Transform3DGroup();
    
                TranslateTransform3D translateTransform3DBox = new TranslateTransform3D(0f, 0f, 0f);
                ScaleTransform3D scaleTransform3DBox = new ScaleTransform3D(1f, 1f, 1f);
                AxisAngleRotation3D axisAngleRotation3DBox = new AxisAngleRotation3D(new Vector3D(0f, 1f, 0f), 0f);
                RotateTransform3D rotateTransform3DBox = new RotateTransform3D();
                rotateTransform3DBox.Rotation = axisAngleRotation3DBox;
    
                TranslateTransform3D translateTransform3DBox2 = new TranslateTransform3D(0, 0, 0);
    
                transform3DGroupBox.Children.Add(translateTransform3DBox);
                transform3DGroupBox.Children.Add(scaleTransform3DBox);
                transform3DGroupBox.Children.Add(rotateTransform3DBox);
                transform3DGroupBox.Children.Add(translateTransform3DBox2);
    
                resourceDictionary.Add("BoxOR9TR8", transform3DGroupBox);
    
                ////
    
                MeshGeometry3D meshGeometry3D = new MeshGeometry3D();
    
                TypeConverter i32ColConv = TypeDescriptor.GetConverter(typeof(Int32Collection));
                meshGeometry3D.TriangleIndices = (Int32Collection)i32ColConv.ConvertFromString("0,1,2 2,3,0 4,5,6 6,7,4 8,9,10 10,11,8 12,13,14 14,15,12 16,17,18 18,19,16 20,21,22 22,23,20");
    
                TypeConverter vector3DColConv = TypeDescriptor.GetConverter(typeof(Vector3DCollection));
                meshGeometry3D.Normals = (Vector3DCollection)vector3DColConv.ConvertFromString("0,0,-1 0,0,-1 0,0,-1 0,0,-1 0,0,1 0,0,1 0,0,1 0,0,1 0,-1,0 0,-1,0 0,-1,0 0,-1,0 1,0,0 1,0,0 1,0,0 1,0,0 0,1,0 0,1,0 0,1,0 0,1,0 -1,0,0 -1,0,0 -1,0,0 -1,0,0 ");
    
                TypeConverter point3DColConv = TypeDescriptor.GetConverter(typeof(Point3DCollection));
                meshGeometry3D.Positions = (Point3DCollection)point3DColConv.ConvertFromString("-0.5,-0.5,-0.5 -0.5,0.5,-0.5 0.5,0.5,-0.5 0.5,-0.5,-0.5 -0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,-0.5 0.5,-0.5,-0.5 0.5,-0.5,0.5 -0.5,-0.5,0.5 0.5,-0.5,-0.5 0.5,0.5,-0.5 0.5,0.5,0.5 0.5,-0.5,0.5 0.5,0.5,-0.5 -0.5,0.5,-0.5 -0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,-0.5 -0.5,-0.5,-0.5 -0.5,-0.5,0.5 -0.5,0.5,0.5 ");
    
                resourceDictionary.Add("BoxOR9GR10", meshGeometry3D);
    
                ////
    
                PerspectiveCamera camera = new PerspectiveCamera();
                camera.FarPlaneDistance = 10f;
                camera.LookDirection = new Vector3D(2.05609, -1.21509, -2.52021);
                camera.UpDirection = new Vector3D(0f, 1f, 0f);
                camera.NearPlaneDistance = 2f;
                camera.Position = new Point3D(-2.05609, 1.21509, 2.52021);
                camera.FieldOfView = 39f;
                viewPort3D1.Camera = camera;
    
                ////
    
    
                ModelVisual3D modelVisual3D = new ModelVisual3D();
                Model3DGroup model3DGroup = new Model3DGroup();
                model3DGroup.Transform = (Transform3D)resourceDictionary["SceneTR7"];
    
                //////
                AmbientLight ambientLight = new AmbientLight(Color.FromRgb(0x33, 0x33, 0x33));
                model3DGroup.Children.Add(ambientLight);
                DirectionalLight directionalLight1 = new DirectionalLight(Colors.White, new Vector3D(-0.6f, -0.5f, -0.6f));
                model3DGroup.Children.Add(directionalLight1);
                DirectionalLight directionalLight2 = new DirectionalLight(Colors.White, new Vector3D(0.6f, -0.5f, -0.6f));
                model3DGroup.Children.Add(directionalLight2);
    
                ////
    
                MeshGeometry3D meshGeometry3D2 = (MeshGeometry3D)resourceDictionary["BoxOR9GR10"];
                GeometryModel3D geometryModel3D = new GeometryModel3D();
                geometryModel3D.Geometry = meshGeometry3D2;
                geometryModel3D.Material = resourceDictionary["ER___Default_MaterialMR1"] as Material;
                geometryModel3D.BackMaterial = (Material)resourceDictionary["ER___Default_MaterialMR1"];
    
                model3DGroup.Children.Add(geometryModel3D);
    
    
                modelVisual3D.Content = model3DGroup;
    
                this.viewPort3D1.Children.Add(modelVisual3D);
            }

    ZAM3Dが生成するXAMLをC#で実装すると

    インラインモデルは、こんな感じ。
    image 
            private void Sample2()
            {
                this.viewPort3D1.Name = "ZAM3DViewport3D";
                viewPort3D1.ClipToBounds = true;
                viewPort3D1.Width = 400;
                viewPort3D1.Height = 300;
    
                PerspectiveCamera camera = new PerspectiveCamera();
                camera.FarPlaneDistance = 10f;
                camera.LookDirection = new Vector3D(2.05609, -1.21509, -2.52021);
                camera.UpDirection = new Vector3D(0f, 1f, 0f);
                camera.NearPlaneDistance = 2f;
                camera.Position = new Point3D(-2.05609,1.21509,2.52021);
                camera.FieldOfView = 39f;
                viewPort3D1.Camera = camera;
    
                ModelVisual3D modelVisual3D = new ModelVisual3D();
                Model3DGroup model3DGroup = new Model3DGroup();
                modelVisual3D.Content = model3DGroup;
                Transform3DGroup transform3DGroup = new Transform3DGroup();
    
    
                TranslateTransform3D translateTransform3D = new TranslateTransform3D(0f, 0f, 0f);
                ScaleTransform3D scaleTransform3D = new ScaleTransform3D(1f, 1f, 1f);
                AxisAngleRotation3D axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(0f, 1f, 0f), 0f);
                RotateTransform3D rotateTransform3D = new RotateTransform3D();
                rotateTransform3D.Rotation = axisAngleRotation3D;
    
                transform3DGroup.Children.Add(translateTransform3D);
                transform3DGroup.Children.Add(scaleTransform3D);
                transform3DGroup.Children.Add(rotateTransform3D);
    
                model3DGroup.Transform = transform3DGroup;
                //////
                AmbientLight ambientLight = new AmbientLight(Color.FromRgb(0x33, 0x33, 0x33));
                model3DGroup.Children.Add(ambientLight);
                DirectionalLight directionalLight1 = new DirectionalLight(Colors.White, new Vector3D(-0.6f, -0.5f, -0.6f));
                model3DGroup.Children.Add(directionalLight1);
                DirectionalLight directionalLight2 = new DirectionalLight(Colors.White, new Vector3D(0.6f, -0.5f, -0.6f));
                model3DGroup.Children.Add(directionalLight2);
    
    
                //////
                Model3DGroup model3DGroupBox = new Model3DGroup();
                Transform3DGroup transform3DGroupBox = new Transform3DGroup();
    
                TranslateTransform3D translateTransform3DBox = new TranslateTransform3D(0f, 0f, 0f);
                ScaleTransform3D scaleTransform3DBox = new ScaleTransform3D(1f, 1f, 1f);
                AxisAngleRotation3D axisAngleRotation3DBox = new AxisAngleRotation3D(new Vector3D(0f, 1f, 0f), 0f);
                RotateTransform3D rotateTransform3DBox = new RotateTransform3D();
                rotateTransform3DBox.Rotation = axisAngleRotation3DBox;
    
                TranslateTransform3D translateTransform3DBox2 = new TranslateTransform3D(0,0,0);
    
                transform3DGroupBox.Children.Add(translateTransform3DBox);
                transform3DGroupBox.Children.Add(scaleTransform3DBox);
                transform3DGroupBox.Children.Add(rotateTransform3DBox);
                transform3DGroupBox.Children.Add(translateTransform3DBox2);
    
                model3DGroupBox.Transform = transform3DGroupBox;
    
                /////
    
                GeometryModel3D geometryModel3D = new GeometryModel3D();
                MaterialGroup materialGroup = new MaterialGroup();
    
                DiffuseMaterial diffuseMaterial = new DiffuseMaterial();
                diffuseMaterial.Brush = new SolidColorBrush(Color.FromRgb(0xd3, 0xc8, 0xad));
                materialGroup.Children.Add(diffuseMaterial);
    
                SpecularMaterial specularMaterial = new SpecularMaterial();
                specularMaterial.SpecularPower = 93f;
                specularMaterial.Brush = new SolidColorBrush(Color.FromRgb(0x33, 0x33, 0x33));
                materialGroup.Children.Add(specularMaterial);
    
                geometryModel3D.Material = materialGroup;
    
                ////
    
                GeometryModel3D geometryModel3DBack = new GeometryModel3D();
                MaterialGroup materialGroupBack = new MaterialGroup();
    
                DiffuseMaterial diffuseMaterialBack = new DiffuseMaterial();
                diffuseMaterialBack.Brush = new SolidColorBrush(Color.FromRgb(0xd3, 0xc8, 0xad));
                geometryModel3DBack.Material = materialGroupBack;
                materialGroupBack.Children.Add(diffuseMaterialBack);
    
                SpecularMaterial specularMaterialBack = new SpecularMaterial(); 
                specularMaterialBack.Brush = new SolidColorBrush(Color.FromRgb(0x33, 0x33, 0x33));
                specularMaterialBack.SpecularPower = 93f;
                materialGroupBack.Children.Add(specularMaterialBack);
    
                geometryModel3D.BackMaterial = materialGroupBack;
    
                ////
    
                MeshGeometry3D meshGeometry3D = new MeshGeometry3D();
    
                TypeConverter i32ColConv = TypeDescriptor.GetConverter(typeof(Int32Collection));
                meshGeometry3D.TriangleIndices = (Int32Collection)i32ColConv.ConvertFromString("0,1,2 2,3,0 4,5,6 6,7,4 8,9,10 10,11,8 12,13,14 14,15,12 16,17,18 18,19,16 20,21,22 22,23,20");
    
                TypeConverter vector3DColConv = TypeDescriptor.GetConverter(typeof(Vector3DCollection));
                meshGeometry3D.Normals = (Vector3DCollection)vector3DColConv.ConvertFromString("0,0,-1 0,0,-1 0,0,-1 0,0,-1 0,0,1 0,0,1 0,0,1 0,0,1 0,-1,0 0,-1,0 0,-1,0 0,-1,0 1,0,0 1,0,0 1,0,0 1,0,0 0,1,0 0,1,0 0,1,0 0,1,0 -1,0,0 -1,0,0 -1,0,0 -1,0,0 ");
    
                TypeConverter point3DColConv = TypeDescriptor.GetConverter(typeof(Point3DCollection));
                meshGeometry3D.Positions = (Point3DCollection)point3DColConv.ConvertFromString("-0.5,-0.5,-0.5 -0.5,0.5,-0.5 0.5,0.5,-0.5 0.5,-0.5,-0.5 -0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,-0.5 0.5,-0.5,-0.5 0.5,-0.5,0.5 -0.5,-0.5,0.5 0.5,-0.5,-0.5 0.5,0.5,-0.5 0.5,0.5,0.5 0.5,-0.5,0.5 0.5,0.5,-0.5 -0.5,0.5,-0.5 -0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,-0.5 -0.5,-0.5,-0.5 -0.5,-0.5,0.5 -0.5,0.5,0.5 ");
    
                geometryModel3D.Geometry = meshGeometry3D;
    
                model3DGroupBox.Children.Add(geometryModel3D);
    
                ////
    
                model3DGroup.Children.Add(model3DGroupBox);
                modelVisual3D.Content = model3DGroup;
    
                this.viewPort3D1.Children.Add(modelVisual3D);
            }
    January 01

    リソースのストリーボードをプレイする方法

    久々にWPFを触ったら、こんなことも忘れている・・・

    Storyboard sb = (Storyboard)this.Resources["Storyboard1"];
    sb.Begin();

    か、

    Storyboard sb = (Storyboard )this.FindResource("Storyboard1");
    sb.Begin();

    C++/CLI によるScreen Saver スケルトンコード

    Windows Mobile の Today のプラグインを実装しようと思うと、WnProc を実装する必要があり、C#だけでは実装できない。

    http://msdn.microsoft.com/en-us/library/ms839442.aspx

    に、Creating a Pocket PC Today Screen Plug-in with the .NET Compact Framework という方法も載っているが、これだと共有メモリを使ってHTMLをレンダリングさせる方法なので、かえって見通しが悪そう。これなら、直接C++/CLIで実装して、一部を C#で書いたほうが楽そう。ただ、TodayのプラグインがC++/CLIで実装可能かどうか・・・C++/CLIでも実装可能なら、一部を C# で書くことも可能なので、ちょっと込み入った実装もだいぶ楽になるはず。

    少し調べていたら、

    http://www.atmarkit.co.jp/fdotnet/special/cppcli/cppcli_01.html

    に「いままたC++が熱い!「C++/CLI」として大進化したVisual C++ 2005」の記事があり、C++/CLI によるScreen Saver のサンプルがあったので、試してみた。

    結果はWinProc をC++/CLIで動かすことができる。ということは、おそらく Windows Mobile の Today のプラグインも同様に動くと思われると、思ったが、スマートデバイスのプロジェクトテンプレートでは、C++/CLI がサポートされないみたい orz

    ピーデー 川俣 晶さんがアップしているコードを VS2008用にちょっと修正したので、とりあえずメモ。

    • コンパイル時の設定に、構成プロパティ→全般に 共通言語ランタイムサポート をセット。
    • 構成プロパティ→リンカ→追加の依存ファイルに scrnsavw.lib comctl32.lib をセット。
    • コンパイルしたイメージを /Sで起動。

    #include <stdafx.h>
    #include <windows.h>
    #include <scrnsave.h>

    #using <mscorlib.dll>
    #using <System.dll>
    #using <System.Drawing.dll>
    #using <System.Windows.Forms.dll>

    using namespace System;
    using namespace System::Drawing;
    using namespace System::Windows::Forms; 

    UINT_PTR wTimer;
    WORD wElapse = 1000;
    int xText=0, yText=0;

    #define ID_TIMER 1

    LONG CALLBACK ScreenSaverProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
      switch (msg)
      {
        case WM_CREATE:
          {
            wTimer = SetTimer(hWnd, ID_TIMER, wElapse, NULL);
          }
          break;

        case WM_TIMER:
          {
            HDC hdc = GetDC(hWnd);
            xText = rand() % GetDeviceCaps(hdc,HORZRES);
            yText = rand() % GetDeviceCaps(hdc,VERTRES);
            ReleaseDC(hWnd,hdc);
            InvalidateRect(hWnd,NULL,TRUE);
          }
          break;

        case WM_DESTROY:
          if( wTimer ) KillTimer(hWnd, ID_TIMER);
          break;

        case WM_PAINT:
          {
            PAINTSTRUCT ps;
            HDC hDC = BeginPaint(hWnd, &ps);
    {
    System::Drawing::
    Graphics ^ g = Graphics::FromHdc((IntPtr)hDC);
    Font font("MS ゴシック", 160);
    SolidBrush brush( Color::Blue);
    PointF position( (float)xText, (float)yText );
    g->DrawString( "テスト!",  %font,  %brush, position );
    }
    EndPaint(hWnd, &ps);
          }
          break;

        case WM_ERASEBKGND:
          {
            RECT rc;
            GetClientRect(hWnd,&rc);
            FillRect((HDC)wParam, &rc,
                (HBRUSH)GetStockObject(BLACK_BRUSH));
          }
          return 0L;

        default:
          break;
      }

      return DefScreenSaverProc(hWnd, msg, wParam, lParam);
    }

    BOOL WINAPI RegisterDialogClasses (HANDLE hInst)
    {
      return TRUE;
    }

    BOOL CALLBACK ScreenSaverConfigureDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
    {
      return FALSE;
    }