您的位置:首页 > 其它

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

2007-05-15 16:45 218 查看
将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, null, null, null);




this.D3DWindow.Dock = System.Windows.Forms.DockStyle.Fill;


this.D3DWindow.Location = new System.Drawing.Point(0, 0);


this.D3DWindow.Name = "D3DWindow";


this.D3DWindow.Size = new System.Drawing.Size(598, 506);


this.D3DWindow.TabIndex = 1;




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




}


}


}


catch (Exception ex)






{


ex.ToString();


}


}


}



到这里所有的工作就完成了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: