第一次用VS.NET 2003做Windows Form 开发, 总结一下 1. 把所有的资源放在一个或多个DLL里, 就象游戏软件把所有的图片做一个资源包, 所有的音效做一个资源包的做法类似, 好处是可以减少主程序的大小, 另外把业务代码根据需要放在一个或多个DLL里, 最终是能够提升软件自动升级的效率, 避免无意义的下载流量, 当然, 为了避免出现DLL Hell, 最好是把所有的DLL加上Strong Name
/**/
/// <summary> /// 从资源DLL中取得需要的资源 /// </summary>
public
static
Stream GetResource(
string
fileName)
{ Stream stream = null ; Type resourceType = typeof (ResourceManager); // ResourceManager是资源DLL中定义的一个DummyClass string resourceName = resourceType.Namespace + " . " + fileName.Replace( " // " , " . " ); System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(resourceType); if (assembly == null ) throw new Exception( " 无法装载资源文件: " + resourceType.Namespace + " .dll " ); stream = System.Reflection.Assembly.GetAssembly(resourceType).GetManifestResourceStream(resourceName); if (stream == null ) throw new Exception( " 无法取得资源: " + fileName); return stream; }
2. 把应用程序的主入口点的代码放到一个新单元的启动类里, 好处是与主窗体的代码分开, 流程更加清晰 3. 用执行文件的版本号作为系统的版本号,避免出现多个定义的地方
Assembly assembly
=
Assembly.GetExecutingAssembly();
object
[] assemblyTitleAttributes
=
assembly.GetCustomAttributes(
typeof
(AssemblyTitleAttribute),
false
);
if
(assemblyTitleAttributes.Length
>
0
) title
=
(assemblyTitleAttributes[
0
]
as
AssemblyTitleAttribute).Title; version
=
assembly.GetName().Version.ToString();
4.有时需要统一设置窗体上控件的属性,作界面上的运行期绑定,下面提供一个返回所有控件的函数
/**/
/// <summary> /// 取得指定容器上的全部子控件 /// </summary>
public
static
Control[] GetAllControls(Control ctrl)
{ ArrayList allControls = new ArrayList(); Queue queue = new Queue(); queue.Enqueue(ctrl.Controls); while ( queue.Count > 0 ) { Control.ControlCollection controls = (Control.ControlCollection)queue.Dequeue(); if ( controls == null || controls.Count == 0 ) continue ; foreach ( Control control in controls ) { allControls.Add(control); queue.Enqueue(control.Controls); } } return (Control[])allControls.ToArray( typeof (Control)); }
5.消息机制,写Windows程序,很有可能需要自定义消息加以处理
protected
override
void
DefWndProc(
ref
System.Windows.Forms.Message m)
{ switch (m.Msg) { case CM_MYMESSAGE: // Do My Business break ; default : base .DefWndProc( ref m); break ; } }
private
const
int
CM_CUSTOMMESSAGE
=
0x1600
;
/**/
/// <summary> /// 自定义消息 /// </summary>
public
const
int
CM_MYMESSAGE
=
CM_CUSTOMMESSAGE
+
1
; [DllImport(
"
User32.dll
"
,EntryPoint
=
"
SendMessage
"
)]
public
static
extern
int
SendMessage(IntPtr hWnd,
int
Msg,
int
wParam,
int
lParam); [DllImport(
"
User32.dll
"
,EntryPoint
=
"
PostMessage
"
)]
public
static
extern
int
PostMessage(IntPtr hWnd,
int
Msg,
int
wParam,
int
lParam);
6. 调用Jet Engine压缩Access数据库
/**/
/// <summary> /// 压缩数据库 /// </summary> /// <param name="fileName"> 文件名 </param> /// <param name="newFileName"> 文件名 </param>
public
static
bool
CompactDatabase(
string
fileName,
string
newFileName)
{ bool result = false ; // 如果要压缩的数据库打开的话,先关闭之 string TempFile; if (newFileName == String.Empty) TempFile = Path.GetTempFileName(); else TempFile = newFileName; try { object [] oParams; object objJRO = Activator.CreateInstance(Type.GetTypeFromProgID( " JRO.JetEngine " )); oParams = new object [] {TConnection.ConnectionString(fileName), " Provider=Microsoft.Jet.OLEDB.4.0;Data " + " Source= " + TempFile + " ;Jet OLEDB:Engine Type=5 " } ; objJRO.GetType().InvokeMember( " CompactDatabase " , System.Reflection.BindingFlags.InvokeMethod, null , objJRO, oParams); if (newFileName == String.Empty) { File.Delete(fileName); File.Move(TempFile, fileName); } System.Runtime.InteropServices.Marshal.ReleaseComObject(objJRO); objJRO = null ; result = true ; } finally { // 如果有必要的话,恢复数据库连接 } return result; }
7. 程序中嵌入WebBrowser, .NET封装的AxWebBrowser的功能实在是够弱的,下面2篇文章基本上包括了设置WebBrowser的方方面面http://icebird.cnblogs.com/articles/403056.html http://icebird.cnblogs.com/articles/403031.html