打造属于自己的sample framework(一)

                                                                                     将sample framework 做成用户控件

        可能本文比较适合对 sample framework 有稍微了解的人。

        前段时间研究了一下directx sdk里的sample framework。sample framework是一个非常强大的3d 引擎。这里有些心得体会想和大家一起分享,希望可以得到一些更强大和实际的应用。
        今天我想写一下如何将sample framework做成控件。我里想的不仅仅是将 sample framework 做成用户控件, 而且可以实现动态的load dll.

        首先创建一个类 IFrameWork:
       

public   class  IFrameWork : UserControl, IDeviceCreation, IFrameworkCallback
    
{
        
public  virtual void OnFrameMove(Device device, double totalTime, float elapsedTime)
        
{

        }

        
public virtual void OnFrameRender(Device device, double totalTime, float elapsedTime)
        
{

        }

        
public  virtual bool IsDeviceAcceptable(Caps caps, Format adapterFormat, Format backBufferFormat, bool isWindowed)
        
{
            
return true;
        }

        
public virtual void ModifyDeviceSettings(DeviceSettings settings, Caps caps)
        
{

        }


        
private Framework sampleFramework = null;
        
public virtual Framework Framework
        
{
            
get
            
{
                
return this.sampleFramework;
            }

            
set
            
{
                
this.sampleFramework = value;
            }

        }

  }



这里IFrameWork 继承自 UserControl, IDeviceCreation, IFrameworkCallback.
这里为什么要加一个sampleFramework 属性等下再解释.


对于把sample framework做成控件最关键的地方该在于 mainloop() 函数. 我看www.mdxinfo.com上看过一篇将原来的  main()的函数改成InitializeGraphics();
    而且在方法的最后将 this.sampleFramework.MainLoop();  删掉。
然后在主程序的main() 函数中添加
            Form1 form = new Form1();
            form.Show();
            form.directXWindow.Framework.MainLoop();      
来运行出控件模型。


其实这里有很多值得改进的地方。我们仔细分析一下MainLoop()方法。

  public   void  MainLoop()
        
{
            
            ..

            
//关键就是从这里开始
            using (System.Windows.Forms.Control app = Window)
            
{
                
// Hook the application's idle event
                System.Windows.Forms.Application.Idle += new EventHandler(OnApplicationIdle);
                
// Start the application
                if (app is System.Windows.Forms.Form)
                
{
                    System.Windows.Forms.Application.Run(app 
as System.Windows.Forms.Form);
                }

                
else
                
{
                    
// Show the window
                    app.Show();
                    System.Windows.Forms.Application.Run();
                }

            }

            
            State.IsInsideMainloop 
= false;             
        }

System.Windows.Forms.Application.Idle += new EventHandler(OnApplicationIdle);
是在应用程序空闲的时候调用了绘图的方法。

而   

    if  (app  is  System.Windows.Forms.Form)
                
{
                    System.Windows.Forms.Application.Run(app 
as System.Windows.Forms.Form);
                }

                
else
                
{
                    
// Show the window
                    app.Show();
                    System.Windows.Forms.Application.Run();
                }


是把函数的windows窗体的显示放在了这个方法里,而且占据了主线程。
所以出现上面才会采取将mainloop方法放在主窗体里。

这里面我们其实可以有更好的方法去实现:将上面的一段代码给删除掉。把主线程还给form的main() 函数。


我们添加一个方法:

         public   void  RemoveIdleDelegate()
        
{
            System.Windows.Forms.Application.Idle 
-= new EventHandler(OnApplicationIdle);
        }


这个函数的用法在接下来的使用中就会明白。

 

到了这一步以后我们基本上可以实现把sample framework 做成一个用户控件了。
但是如何实现动态的load dll。

将以下代码: 

  public   class  SampleControl : IFrameWork 
    
{
        
public override void OnFrameMove(Device device, double totalTime, float elapsedTime)
        
{
           
        }

        
public overridevoid OnFrameRender(Device device, double totalTime, float elapsedTime)
        
{
          ..
        }

        
public  overridebool IsDeviceAcceptable(Caps caps, Format adapterFormat, Format backBufferFormat, bool isWindowed)
        
{
          
        }

        
public overridevoid ModifyDeviceSettings(DeviceSettings settings, Caps caps)
        
{
              .
        }


        
private Framework sampleFramework = null;
        
public override Framework Framework
        
{
            
get
            
{
                
return this.sampleFramework;
            }

            
set
            
{
                
this.sampleFramework = value;
            }

        }


        .
    }

编译成dll。

在主窗体里:

 

    private   void  openToolStripMenuItem1_Click( object  sender, EventArgs e)
        
{
            OpenFileDialog dlg 
= new OpenFileDialog();
            dlg.Multiselect 
= true;
            
if (DialogResult.OK == dlg.ShowDialog())
            
{
                
string sFileName = dlg.FileName;
                Type[] types 
= null;
                
try
                
{
                    types 
= Assembly.LoadFile(sFileName).GetTypes();     //动态加载dll


                    
foreach (Type type in types)
                    
{
                        
if (type.IsSubclassOf(typeof(IFrameWork)))
                        
{
                            
//D3dWindow是IFrameWork类型,就是我们的控件 。用于显示3d模型。
                            D3DWindow.Framework.RemoveIdleDelegate();    //  释放掉 System.Windows.Forms.Application.Idle委托。在新的控件实例中才可以重新添加委托,绘制新的图形

                            
this.splitContainer1.Panel1.Controls.Remove(D3DWindow);     //删除掉原来的控件 
                            D3DWindow = (IFrameWork)type.InvokeMember(null, BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, nullnullnull);
        
                            
this.D3DWindow.Dock = System.Windows.Forms.DockStyle.Fill;
                            
this.D3DWindow.Location = new System.Drawing.Point(00);
                            
this.D3DWindow.Name = "D3DWindow";
                            
this.D3DWindow.Size = new System.Drawing.Size(598506);
                            
this.D3DWindow.TabIndex = 1;

                            
this.splitContainer1.Panel1.Controls.Add(D3DWindow);   //加载新的控件。
                            
                        }

                    }

                }

                
catch (Exception ex)
                
{
                    ex.ToString();
                }

            }

        }



到这里所有的工作就完成了。



 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值