C#でツールを作る その3.1 -ApplicationContextを使ってみる-

前回C#でツールを作る その3-デザインの変更- - while( c++ );のMain()は以下のようになっていますが、

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    using( Hoge hoge = new Hoge() )
    using( UserControl1 main_panel = new UserControl1( hoge ) )
    using( Form1 form = new Form1( main_panel ) )
    {
        hoge.Init( main_panel );
        Application.Run( form );
    }
}

正直、何か気持ち悪いというか、しっくりきませんね。

いろいろ調べるとApplicationContextというクラスが使えそうだったので、早速修正してみます。

参考サイト

PACパターンは初めて知りました。。。MVCと同様に有名なパターン(アーキテクチャ?)なんですね。


以下ソースです。

Program.cs

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            using( Hoge hoge = new Hoge() )
            {
                if( hoge.Init() )
                {
                    Application.Run( hoge );
                }
            }
        }
    }
}

Hoge.cs

namespace WindowsFormsApplication1
{
    public class Hoge : ApplicationContext
    {
        /// <summary>
        /// 描画対象
        /// </summary>
        private UserControl1 view = null;

        /// <summary>
        /// 
        /// </summary>
        private Device device = null;

        /// <summary>
        /// 
        /// </summary>
        private Microsoft.DirectX.Direct3D.Font font = null;


        /// <summary>
        /// コンストラクタ。
        /// 
        /// </summary>
        public Hoge()
        {
            view = new UserControl1();
            view.Paint += new PaintEventHandler( Paint );

            MainForm = new Form1( view );
            MainForm.Disposed += new EventHandler( ReleaseDevice );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Paint( object sender, PaintEventArgs e )
        {
            Render();
        }

        /// <summary>
        /// Direct3Dの初期化
        /// </summary>
        public bool Init()
        {
            try
            {
                CreateDevice();
                CreateDeviceObject();
            }
            catch( Direct3DXException )
            {
                MessageBox.Show( "Direct3Dの初期化に失敗しました" );
                return false;
            }
            return true;
        }

        /// <summary>
        /// 描画
        /// </summary>
        private void Render()
        {
            device.Clear(ClearFlags.Target, Color.FromArgb(0x333333), 1.0f, 0);

            device.BeginScene();

            font.DrawText(null, "hoge", 0, 0, Color.White);

            device.EndScene();

            device.Present();
        }

        /// <summary>
        /// 
        /// </summary>
        private void CreateDevice()
        {
            PresentParameters pp = new PresentParameters();
            pp.Windowed = true;
            pp.SwapEffect = SwapEffect.Discard;

            device = new Device(
                0,
                DeviceType.Hardware,
                view,
                CreateFlags.HardwareVertexProcessing,
                pp
                );
            device.Disposing += new EventHandler( ReleaseDeviceObject );
        }

        /// <summary>
        /// 
        /// </summary>
        private void CreateDeviceObject()
        {
            //FontDescription desc = FontDescriptoin();//error?
            font = new Microsoft.DirectX.Direct3D.Font(
                device,
                16, 0,
                FontWeight.Normal,
                0,
                false,
                CharacterSet.ShiftJIS,
                Precision.Default,
                FontQuality.AntiAliased,
                PitchAndFamily.DefaultPitch,
                "MS ゴシック"
                );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReleaseDevice( object sender, EventArgs e )
        {
            if (device != null)
            {
                device.Dispose();
                device = null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReleaseDeviceObject( object sender, EventArgs e )
        {
            if (font != null)
            {
                font.Dispose();
                font = null;
            }
        }
    }
}

Form1.cs

  • メインフォーム
  • splitContainer.Panel1にViewを追加
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1( UserControl1 view )
        {
            InitializeComponent();
            splitContainer1.Panel1.Controls.Add( view );
        }
    }
}

UserControl1.cs

  • OnPaintBackgroundのoverride
namespace WindowsFormsApplication1
{
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();

        }

        private void UserControl1_Load(object sender, EventArgs e)
        {
            Dock = DockStyle.Fill;
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            //サイズ変更時にちらつかないようにする
            //base.OnPaintBackground(e);
        }

    }
}