Icebird

Delphi/C# - My favorite programming language

导航

.NET Windows Form开发心得

第一次用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[0as 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

by the way, CodeRush for VS.NET 和 Refactor! Pro for VS.NET真的很好用,不愧是DevExpress出品

posted on 2006-05-29 11:40  Icebird  阅读(3656)  评论(4编辑  收藏  举报