1、Windows Mobile Team Blog
http://blogs.msdn.com/windowsmobile/

2、Microsoft Technical Forums  –>Smart Device Development —— 强烈推荐
http://forums.microsoft.com/msdn/default.aspx?siteid=1

3、微软中文社区 -> Windows Mobile
 —>Smartphone & Pocket PC 使用交流区
 —>Smartphone & Pocket PC 开发交流区
http://bbs.mscommunity.com/forums/default.aspx

3、VCHelp –> eVC/.NET Compact嵌入式平台
http://www.vchelp.net/cndevforum/subject_list.asp?forum_id=33

4、MSDN 英文网站  –>Mobile
http://msdn.microsoft.com/mobility/

5、MSDN中文网站 –>移动与嵌入式技术
http://www.microsoft.com/china/MSDN/library/Mobility/default.mspx
以及 Webcast 网络讲座
http://www.microsoft.com/china/msdn/events/webcasts/shared/Webcast/MSDNWebCast.aspx

6、移动技术网 –>WinCE开发讨论区
http://www.msale.net/Forum/viewforum.php?f=7

7、天极网 嵌入式开发 版块
http://club.yesky.com/bbs/jsp/list.jsp?forumID=378
以及  天极网软件频道–>移动开发
http://dev.yesky.com/devydkf/

8、CSDN.NET –>移动–>Windows Mobile 资源
http://mobile.csdn.net/List.aspx?Column=80bacd07-4d58-4507-9f32-c142b51c401a

9、CSDN社区 
http://community.csdn.net/
—>硬件/嵌入开发—> 嵌入开发(WinCE)
—>移动平台—>Windows Mobile

10、Smartphone—技术天地—赛迪网
http://tech.ccidnet.com/col/1130/1130.html

11、Pocket PC Developer Network
http://www.pocketpcdn.com/

12、嵌入式世界网
http://www.embedworld.com/forum_list.asp?forum_id=5

13、PocketPC FAQ
http://www.pocketpcfaq.com/

14、MoDaCo » Forum Home » Smartphone » Smartphone Development
http://www.modaco.com/Smartphone_Development-f113.html

15、CodeProject
http://www.codeproject.com/ce/
与该网站类似的有:
CodeGuru
http://www.codeguru.com/

16、移动开发网(资料很多)
http://www.biplip.com/default.aspx
开发论坛—>Windows CE与Pocket PC软件开发讨论区 
http://www.biplip.com/Forums/default.asp?CAT_ID=3

17、嵌入式研究网
http://www.cnemb.com/
—>微软嵌入式开发版
http://www.cnemb.com/index.php?name=PNphpBB2&file=index&c=1

18、MVP Blog
http://blog.csdn.net/aawolf/

19、Smartphone Developer  Network
http://www.smartphonedn.com/

20、PDA 发烧友论坛
http://bbs.pdafans.com
—移动设备软件开发版

21、OpenNETCF.org
http://www.opennetcf.org/CategoryView.aspx?category=Home

22、嵌入者之家论坛
http://www.embeder.com/bbs/index.asp
—WinCE讨论区
—PocketPC讨论区

23、NET Compact Framework Team
http://blogs.msdn.com/netcfteam/

24、中国JAVA手机网
http://www.cnjm.net

25、IOICN 中文数码论坛
http://61.145.126.169/bbs/index.php

26、手机论坛_手机之家
http://bbs.imobile.com.cn/forumdisplay.php?fid=55491

27、Smartphone Thoughts
http://www.smartphonethoughts.com/forums/index.php

28、In the Hand
http://www.inthehand.com/forums/

29、Smartphone Dubai Forums
http://smartphonedubai.com/groupee/forums

30、SourceForge.NET
http://sourceforge.net/

31、新的论坛:
Mobile 应用开发
http://mobile.winfans.net/CCS/Default.aspx
移动开发者
http://www.justmobiler.com/

32、TOM PDA (PDA设备的软硬件交流,并提供PDA新闻订阅)
http://www.tompda.com/bbs/
 ——PocketPC及SmartPhone智能手机讨论区
 ——CE软件讨论区

33、阿YAYA微软智能手机网——Windows Mobile
http://www.aryaya.com/forumdisplay.php?fid=109

34、91mobile
http://91mobile.com/bbs/index.asp
——PocketPC 开发经验交流
——Smartphone 开发经验交流

35、Hi PDA
http://www.hi-pda.com/forum/

36、小胖熊的酷数码乐园
http://www.sosaw.com/

37、数码墟
http://www.01outlet.com/

38、酷派数码
http://www.pxdxa.com/

39、Windows Mobile Developers Wiki
http://channel9.msdn.com/wiki/default.aspx/MobileDeveloper.HomePage

40、  MSDN2(United States) —— 强烈推荐
http://msdn2.microsoft.com/library/default.aspx

The MSDN Library is an essential resource for developers using Microsoft tools, products, and technologies. It contains a bounty of technical programming information, including sample code, documentation, technical articles, and reference guides.

This site, MSDN2, contains the documentation for two new products, Visual Studio 2005 and SQL Server 2005. Use this site to access the latest developer documentation for these tools and technologies and to preview some of the upcoming changes to the MSDN Library interface. In the coming months, the documentation hosted here will be consolidated into the MSDN Library.

41、Visual Studio For Devices
http://blogs.msdn.com/vsdteam/

42、STL For EVC
http://www.syncdata.it/stlce/index.html

43、GotDotNet
http://www.gotdotnet.com
 is a .NET Framework Community Web site providing Visitor with access to code Samples and other resources for Create .NET Solutions.

44、嵌入式开发网络
http://www.embeddedhelp.com/Index.asp

45、翻译《Windows CE 程序设计(3rd版本)》的BLOG
http://blog.csdn.net/tellmenow/category/138980.aspx

46、南方数码掌上软件开发部(留言本)
http://www.lzh.cn/

47、斯普智能手机网
http://www.downpda.com

48、Embedded Development and Research
http://www.buzzdev.net

49、msmobiles.com forums
http://msmobiles.com/f/

50、pdaPhoneHome.com – Pocket PC pdaPhones
http://www.pdaphonehome.com/forums/index.php?s=75bdbcdc0e5a68d010852fac1a0a3e29

51、嵌入式开发网
http://www.palmheart.net/

52、Windows CE Base Team Blog
http://blogs.msdn.com/ce_base/default.aspx

53、Windows Mobile Portal
http://www.winbile.net/

54、Home [PocketMartix >> Mobile Device]
http://www.pocketmatrix.com

55、开发者之家〉移动平台〉Windows Mobile
http://www.vkfz.com/Windows-Mobile-1l216.htm

原文地址:http://www.cnblogs.com/mengshu-lbq/archive/2005/11/16/windows_mobile_develop_resource.html

经测试,在 14483461 条记录中查询第 100000 页,每页 10 条记录按升序和降序第一次时间均为 0.47 秒,第二次时间均为 0.43 秒,测试语法如下:
 exec GetRecordFromPage news,newsid,10,100000
 news 为 表名, newsid 为关键字段, 使用时请先对 newsid 建立索引。
*/

/*
 函数名称: GetRecordFromPage
 函数功能: 获取指定页的数据
 参数说明: @tblName   包含数据的表名
      @fldName   关键字段名
      @PageSize   每页记录数
      @PageIndex  要获取的页码
      @OrderType  排序类型, 0 – 升序, 1 – 降序
      @strWhere   查询条件 (注意: 不要加 where)
 作  者: 铁拳
 邮  箱: [email protected]
 创建时间: 2004-07-04
 修改时间: 2004-07-04
*/
CREATE PROCEDURE GetRecordFromPage
  @tblName   varchar(255),    — 表名
  @fldName   varchar(255),    — 字段名
  @PageSize   int = 10,      — 页尺寸
  @PageIndex  int = 1,      – 页码
  @OrderType  bit = 0,      – 设置排序类型, 非 0 值则降序
  @strWhere   varchar(2000) = "" – 查询条件 (注意: 不要加 where)
AS

declare @strSQL  varchar(6000)    — 主语句
declare @strTmp  varchar(1000)    — 临时变量
declare @strOrder varchar(500)    – 排序类型

if @OrderType != 0
begin
  set @strTmp = "<(select min"
  set @strOrder = " order by [" + @fldName + "] desc"
end
else
begin
  set @strTmp = ">(select max"
  set @strOrder = " order by [" + @fldName +"] asc"
end

set @strSQL = "select top " + str(@PageSize) + " * from ["
  + @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
  + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
  + @fldName + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"
  + @strOrder

if @strWhere != ""
  set @strSQL = "select top " + str(@PageSize) + " * from ["
    + @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
    + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
    + @fldName + "] from [" + @tblName + "] where " + @strWhere + " "
    + @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrder

if @PageIndex = 1
begin
  set @strTmp = ""
  if @strWhere != ""
    set @strTmp = " where (" + @strWhere + ")"

  set @strSQL = "select top " + str(@PageSize) + " * from ["
    + @tblName + "]" + @strTmp + " " + @strOrder
end

exec (@strSQL)

GO

Windows Mobile 开发常见问题集(一)

1、Q:新建项目的时候选择哪个项目类型才能创建智能设备的应用程序?

  A:在Visual Studio的新建项目对话框中选择Visual C#或者Visual Basic项目类型,选择智能设备模板,然后再选择相应的设备SDK,最后选择“Device Application”,就可以创建一个移动设备的应用程序了。

2、Q:托管代码与本地代码有哪些区别?

  A:托管代码是指使用.NET Compact Framework开发的程序代码,可执行文件被编译成IL,执行时需要有.NET的运行时环境。而本地代码指用C++等语言开发的程序代码,可执行文件被编译成与CPU指令集有关的机器码,可以直接运行。

3、Q:能不能简要介绍一下Magneto里面对OTA和MMS的支持?

  A:Magneto对OTA有很好的支持,SDK文档的通讯部分中,有针对OTA的专门介绍。MMS的应用程序基本都是由第三方开发的,因为MMS是基于WAP协议的,而Magneto本身对WAP的支持也很好,具体的协议也可以在SDK文档里找到。

4、Q:请问用Visual Basic .NET开发PDA数据库程序能不能使用ADO.NET?

  A:Visual Basic .NET开发PDA数据库不需要引用System.data.oledb,只需要引用System.Data.SqlServerCe命名空间就可以了。该命名空间中的数据库操作类和ADO.NET是基本一致的。可以用它们来开发针对SQL Server CE的应用程序。

5、Q:在Visual C++2005中,可以使用.Net Compact Framework吗?

  A:不能,现在.NET Compact Framework只支持C#和VB.NET,而不支持C++/CLI。但是在VS.NET 2005中可以用C++来开发Native代码来支持移动设备。

6、Q:从什么地方可以得到Smartphone开发环境?

  A:Smartphone的SDK可以在微软网站上找到,而Visual Studio 2005 Beta 2可以通过参加微软活动的方式获得。MEDC 2005的参加者都获得了VS.NET 2005和Windows Mobile 5 SDK的开发光盘。

7、Q:托管性的代码执行效率怎么样?和使用Visual C++编写的代码相比较。

  A:托管代码的执行效率肯定不如本地代码高,但是托管代码也有一些好处是无法取代的。

8、Q:是否可以使用Visual Studio .NET 2003来开发能够运行在Windows Mobile 2005上的应用程序?

  A:首先更正一下,Windows Mobile最新一代的操作系统叫做Windows Mobile 5,而不是Windows Mobile 2005。是的,使用VS.NET 2003开发的应用程序是可以在Windows Mobile 5上正常运行的,因为Windows Mobile 5 ROM中内置了.NET Compact Framewrok 1.0 SP3。

9、Q:PDA上不能用Pocket Access么?SQL CE太大了。

  A:可以使用Pocket Access来开发Windows Mobile上的应用程序。可以采用C++调用OLEDB或者ADOCE的方式来访问Pocket Access数据库。

10、Q:Visual Studio 2005的新功能是否只在Windows Mobile 5里受到支持,2003是否支持?

  A:新功能分两个部分,一部分是.NET Compact Framework 2.0中提供的的新功能,这部分的功能可以被Windows Mobile 2003支持,但必须安装.NET Compact Framework 2.0;而另一部分是Windows Mobile 5的特有功能。.NET Compact Framework 2.0和Windows Mobile 5开发文档的“What’s New”部分,分别描述了这两方面的新特性。

11、Q:请问如何在模拟器里面配置连接到移动网络?

  A:模拟器如果需要连接移动网络的话,必须有专门的硬件提供支持。可以在开发PC的串口上连一个GPRS的模拟器,SDK文档中对此有专门的说明。

12、Q:SQL CE可以像Pocket Access那样仅使用一个文件就能运行么?是否需要像PC上那样安个服务器才能使用?

  A:不会的,只需要在Windows Mobile上安装SQL Server CE的支持库,也就是就是一些DLL文件。而SQL Server CE的库文件是一个单独的文件,不需要安装一个服务器。

13、Q:开发好的程序通过什么方式部署到手机上?对手机有什么要求?

  A:开发的程序需要打包成cab文件部署到手机上。除了通过ActiveSync安装外,还可以通过网络下载、存储卡运行等方式来安装应用程序。对手机的要求是,必须和开发程序的目标平台相兼容。比如为Windows Mobile 5开发的应用程序,可能就没办法很好地运行在Windows Mobile2003平台上。

14、Q:在模拟器上面开发程序,和真实环境有区别么?需要注意一些什么?

  A:模拟器的仿真度十分高,Windows Mobile 5的模拟器甚至可以支持ARM指令,所以基本不会遇到兼容性的问题。但是对于一些需要连接外部设备的应用场景,比如前边说的无线网络,还有GPS设备等,就需要用到实际设备了。

15、Q:当开发国际化应用程序时,应该特别注意哪些方面?

  A:对于国际化的应用程序,.NET本身就已经提供了非常好的支持。可以把用户界面的文字保存在相应的资源文件中,然后由应用程序判断操作系统的语言版本来调用相应的文字。

16、Q:用.NET开发Pocket PC程序需要考虑设备具体使用的是哪种CPU吗?

  A:不必。无论是在虚拟机上的x86指令集,还是实际设备上的ARM指令集,对.NET Compact Framework程序的运行来说都一样。

17、Q:Windows Mobile 5 是否支持通过语音控制新的开发程序?

  A:现在还不支持。

18、Q:可以在vwd2005 bata2中开发Pocket PC程序吗?Pocket PC是否具有浏览器?

  A:可以,Pocket PC平台是内置浏览器的。

19、Q:Visual Studio 2005的Mobile开发,支持Mobile 2003的设备吗?

  A:支持,VS 2005本身就自带Windows Mobile 2003的SDK。

20、Q:Windows Mobile 5.0 for Smartphone较之前的版本有何明显的区别?对于测试这一领域,我们需要注意些什么?

  A:Windows Mobile 5的Smartphone平台更多的变化是在API层面,比如对数据库的支持、对GPS API的支持等, Windows Mobile 5 SDK文档中对此有详细地说明。

21、Q:对开发来说CDMA和GPRS的数据传输是透明的吗?

  A:对于软件开发来说数据传输是透明的,CDMA和GPRS对于上层应用程序来说,只要支持HTTP协议或者TCP/IP协议就可以进行数据传输的操作。

22、Q:Visual Studio .NET能否支持Nokia的S60系列系统开发?

  A:可以,Visual C++能支持Nokia S60的开发。

23、Q:Pocket PC与Mobile开发的主要区别在哪里?

  A:Window Mobile是微软公司基于Windows CE.NET的一个平台。它包含Pocket PC和Smartphone两个版本。

24、Q:SDE从哪里可以下载?Pocket PC 2005的模拟器可以从哪里下载?

  A:SDE是早期用来开发移动设备程序的VS扩展,目前网上似乎很难找到。其实不用安装它,安装所需版本的Pocket PC或者Smartphone的SDK即可。各个版本的Windows Mobile开发的SDK和模拟器的地址可以从这篇Blog上下载(http://twodays.cnblogs.com/archive/2005/06/30/184107.htm)。

25、Q:.NET Compact Framework 2.0能装在Windows Mobile 2003上吗?

  A:可以。.NET Compact Framework 2.0必须手动安裝到Windows Mobile 2003的机器上。

26、Q:请问有没有好的Windows Mobile编程的网站或者论坛?

  A:OpenNETCF.org、www.devbuzz.com、www.codeproject.com、www.msdn.com/mobility/、www.pocketpcdn.com

27、Q:Windows Mobile 2003上的.NET Compact Framework能升级到.NET Compact Framework 2.0吗?

  A:可以。.NET Compact Framework 2.0必须手动安裝到Windows Mobile 2003的机器上。

28、Q:请问编写WML文件与使用.NET Compact Framework进行开发有什么联系和区别?

  A:WML是能够利用WAP浏览器进行浏览的文件,是一种基于Web的开发方式。.NET Compact Framework是在设备上运行的程序,是基于应用的开发方式。

29、Q:在使用.NET Compact Framework 1.0进行开发时,用EVC直接调用Native代码与使用C#通过P/Invoke在性能上有什么差别?在.NET Compact Framework 2.0上,用C++直接调用和用C#通过P/Invoke又如何呢?

  A:用EVC調用Native API的效率,会比使用.NET Compact Framework通过P/Invoke调用Native API要高,这是.NET Compact Framework本身的特性。在从托管代码中调用Native API时,其内部会进行一些额外的类型转换动作,这会导致效率的降低。

30、Q:有没有支持显示HTML文本的控件?

  A:WebBrowser控件可以用于HTML文本。

31、Q:CAB安装后会在Pocket PC上自动生成“卸载程序”,如何制作安装包,才能不自动产生“卸载程序”?

  A:利用VS 2005建立Smart Device Cab Project,在Solution Explorer的Cab Project上点击鼠标右键选择Property,即可看到有一个选项为NoUninstall,默认为False,改为True就可以了。

32、Q:OpenNETCF能运行在.NET Framework 1.1环境下吗?其中的控件可以与.NET Framework 1.1控件混合使用吗?怎样在Visual Studio .NET 2003中加入OpenNETCF控件?

  A:当初在设计NET Compact Framework 1.0/1.1时,由于考虑到移动设备的资源有限,所以有些原本.NET Framework 1.1中已经提供的类和控件就被删除了,OpenNETCF Smart Device Framework主要是针对.NET Compact Framework 1.0/1.1中没有的功能,开发出来的类似的类型和额外的功能,以弥补.NET Compact Framework 1.0/1.1不足之处。这套Framework主要是供.NET Compact Framework程序开发所用,除了少部份针对PC与Pocket PC的同步功能所编写的类之外,大部分都是在.NET Compact Framework上执行的,一般不支持.NET Framework。OpenNETCF的Smart Device Framework安装完毕之后,可以在VS 2003左侧的工具箱中看到OpenNETCF的控件,可以直接拖放来使用。

Windows Mobile 开发常见问题集(二)

1、Q:请问如何才能保证应用程序能够及时地释放系统资源?
  
  A:由于.NET Compact Framework所运行的移动设备,受限于CPU、内存、电源,因此其中的Garbage Collection时经过调整的,垃圾回收的速度比.NET Framework更快。通过调用Dispose()方法,可以立即释放掉对象所占用的非托管资源。

2、Q:在Visual Studio中可以定义一个所有文件都可以使用的宏吗?比如:#define AA,要求在所有的.cs文件中都可以使用#if AA public class A() #else public class B();

  A:可以。在VS 2005的解决方案资源管理器中,用鼠标右键单击项目,选择其属性。在属性对话框的Build页中,可以找到conditional compilation symbol,在其中输入AA,即可在该项目的所有C#源代码文件中使用这个符号。

3、Q:可以将Smartphone应用程序转换为Pocket PC应用程序吗?

  A:可以。在.NET Compact Framework 2.0中,只要您没有用到某些特殊的API,Pocket PC应用程序与Smartphone程序是可以互相转换的,只需要在控件上做些调整即可。

4、Q:.Net Framework 2.0有没有对Media coder/decoder的支持?开发第三方的媒体播放程序可以不依赖.Net CF2.0吗?

  A:.NET Compact Framework 2.0本身可以开发Direct3D Mobile的应用程序。也可以在VS 2005中以C++开发Native Code的媒体播放程序,而无须依赖.NET Compact Framework 2.0。

5、Q:使用.Net开发的智能设备程序是否比用C语言开发的程序效率低很多?

  A:使用.NET开发的程序会比使用C语言开发的本地程序要慢一些,不过对于一般的应用软件来说,下率不会差太多,除非是需要实时处理硬件或I/O的程序,必须要使用C语言进行开发之外,一般的应用程序用.NET Compact Framework开发即可,因为这样可以获得最好的灵活性和可移植性。

6、Q:用托管C++开发的应用程序执行效率会不会比用C#开发的应用程序高?

  A:不会。由於托管C++与C#源代码在经过编译之后,都将成为IL代码,由.NET Compact Framework来执行,因此在效率上不会有差别。

7、Q:请问.NET Compact Framework 2.0对于使用不同CPU的移动设备支持好吗?.NET Compact Framework 2.0在GSM应用方面有没有增强?
  A:.NET Compact Framework具有Windows Mobile跨平台的特性,因此开发时不需要考虑底层的OS、CPU和其它硬件因素。目前.NET Compact Framework对常见的CPU都能够支持,例如ARM、MIPS、SH、x86等。另外在GSM应用方面,主要针对Smartphone的应用作了加强。
8、Q:请问MFC在Windows Mobile Development中处于什么地位?Douglas Boling写的Programming Microsoft Windows CE .NET一书中好像并不推崇使用MFC开发Windows Mobile应用程序。

  A:MFC还是以本地C++的方式进行开发,其特点是执行效率高,但必须花费更多的心思在資源分配、回收等编程技巧上。如果使用.NET Compact Framework进行开发,虽然执行效率比本地程序略差,但整体而言,可移植性与灵活性都较好,而且不必为回收资源担心,开发者能够专注于真正重要的业务逻辑流程。

9、Q:.NET Compact Framework 2.0与1.0有什么区别?

  A:.NET Compact Framework 2.0主要针对1.0原有的控件及类库进行了改善,提供了更多的支持,并新增了许多类型和控件,.NET Compact Framework 2.0更加接近.NET Framework,同时在效率上也相对1.0有所提升。

10、Q:在制作安装程序的时候,如何在start->program菜单中生成程序的快捷方式?

  A:在VS 2005中建立Smart Device Cab Project,在File System页面中,可以看到Application Folder,这就是Start->Program的位置,可以先建立Primary Output的快捷方式,然后将此快捷方式移到Programs Folder,并构建Cab文件即可。

11、Q:移动设备与WEB网页设计有什么主要区别?

  A:Visual Studio开发环境中移动设备与Web设计是非常类似的 ,可以使用同样的语言进行设计, 不同的只是能够使用的类以及控件有所区别。

12、Q:.NET Compact Framework中可以实现鼠标的双击、右击、中间键单击等用户事件吗?

  A:运行Windows Mobile的设备没有鼠标,所以这些事件也不存在。对于常用的右键弹出上下文相关菜单,在触摸屏上一般用单击并且按住一段时间来实现。

13、Q:Mobile应用程序的界面处理可以使用CSS样式表吗?

  A:不可以。

14、Q:Smartphone上面能够支持横屏幕吗?

  A:不支持。

15、Q:如何在Pocket PC中调整控件的位置使得应用程序可以支持横向屏幕?

  A:可通过设置控件的Anchor和Dock属性来自适应屏幕。

16、Q:界面开发完成后,在移植方面需要注意些什么?

   A:一般来说,要移植到不同平台上必需要重新设计用户界面;可以重用的只是业务逻辑,不是用户界面。
17、Q:我在移动开发过程中用到了很多控件,难以在一页之内显示,如何为它们添加一个滚动条?

  A:可以将这些控件放到一个Panel中,并设置其AutoScroll属性为true即可;如果使用VS2005,拖拽数据源到窗体上时,会自动将所有控件包括在一个Panel里。

18、Q:TableAdapter在.NET Compact Framework 1.0中从未出现过,是新特性吗?

  A:是的,TableAdapter是.NET Compact Framework 2.0中新增加的。

19、Q:SQL Mobile带有像SQL Server那样企业管理器吗?Visual Studio 2005支持在桌面上直接查看SQL Mobile的数据库吗?

  A:您可以通过SQL Server 2005的企业管理器连接到SQL Mobile数据库进行编辑。Visual Studio 2005也支持在桌面上创建或修改SQL Mobile数据库文件。

20、Q:提交成功后如何取消保存?

  A:目前BindingSource尚不支持事务,因此提交成功后是没有办法再undo的。

21、Q:移动设备内存较小,填充DataSet是否有大小限制?

  A:DataSet在逻辑上并没有对大小的限制。但是DataSet的大小必须小于当前前的可用内存,否则会有内存分配不成功的异常出现。

22、Q:如果数据源中的数据在显示前需要处理(例如格式转换),可以使用DataBinging吗?

  A:BindingSource是直接将DataSet与控件进行关联,所以如果需要进行其他操作的话,就不能使用BindingSource。或者,可以在访问数据库后,先在DataSet里对需要转换的数据进行必要的处理之后,再进行显示。

23、Q:DataSet实际上在内存中产生了一套数据副本,如何解决版本控制的问题?

  A:DataSet本身不存在版本控制的问题。在把数据提交回SQL Mobile的时候,的确需要有一些机制来保证修改完成的数据应该是最新的,但是DataSet本身的数据结构是不会发生变化的。

24、Q:能否通过Pocket PC上的程序更新服务器上的数据库信息?

  A:可以。可以使用SQL Mobile中的RDA或者是合并复制的方法和远程SQL Server数据库进行数据同步或更新。具体的实现可以参考SQL Server相关部分的文档。

25、Q:SQL Mobile一定要要安装在移动设备上吗?

  A:是的。SQL Mobile需要安装在Windows Mobile或者Windows CE设备上。

26、Q:SQL Moble支持存储过程吗?

  A:目前还不支持。

27、Q:SQL Mobile必须和应用程序部署在同一台设备上吗?可否远程连接?它是否是一个文本数据库?

  A:是的。SQL Mobile必须和应用程序部署在同一个设备上,现在还不支持远程连接。SQL Mobile是一个文件数据库,但不是一个文本数据库。

28、Q:能不能在一些应用中以XML替代SQL的作用?

  A:可以的。XML的查询效率比SQL Mobile要低,但是在数据比较少的情况下不需要安装更多的组件,这是XML的一个优势。

29、Q: Tableadapter与DataAdapter之间有何区别?DataAdapter是多个TableAdapter的组合吗?

  A:不是的,TableAdapter是对DataAdapter的一个扩展,TableAdapter本身包括了对应数据表的信息。TableAdapter完成从数据库连接、执行SQL语句到将结果填充到DataSet中的一个完整操作,而DataAdapter只支持数据填充的操作。

30、Q:做了SQL Moblie的sdf文件后,Publications后的数据库表中会出现msrepl_tran_version或rowguid字段,这是为什么?

  A:这两个字段是为了保证数据同步,由系统自动添加的,请不要进行修改。

31、Q:网上出了个Reflector反编译工具,可以99%反编译用C#开发的EXE和DLL,怎么才能更好地保护应用程序?

  A:目前大部分应用程序采用混淆和对关键字符串加密的方式,更好的方式可能还要继续探讨。

Windows Mobile 开发常见问题集(三)

1、Q:SQL Mobile的SQL语法和SQL Server的语法有差异么?

  A:SQL Mobile的语法和SQL Server的语法略有差异,可以从SQL Mobile的文档中查找SQL Mobile具体支持哪些SQL语句。总的来说,对绝大部分的开发来说,这些差异不会造成影响。

2、Q:SQL Mobile支持B/S模式吗?

  A:不支持。

3、Q:可以在.NET Compact Framework 1.0上访问由.NET Compact Framework 2.0产生的数据库吗?

  A:SQL Mobile数据库的格式和SQL Server CE 2.0是相同的,因此可以直接在.NET Compact Framework 1.0中进行访问。

4、Q:SQL Mobile数据库文件支持XCOPY吗?可以简单地复制到其他Windows Mobile设备上吗?

  A:是的。SQL Mobile数据库本身是一个文件数据库,直接复制到其他安装了SQL Mobile支持组件的Windows Mobile设备或模拟器上就可以使用了。

5、Q:Visual Studio .NET 2003是否支持Windows Mobile 5.0的开发?

  A:不可以,如果开发基于Windows Mobile 5.0的应用程序请使用Visual Studio 2005。

6、Q:要想从传统的PC程序员转向到移动设备的开发上来,需要在技术上作哪些准备?

  A:移动设备的开发对于基础开发语言和开发技术的要求与PC上是相同的,只需要了解移动设备在哪些方面与PC平台有所不同即可。

7、Q:C#可以开发Windows Moblie应用程序吗?

  A:可以。

8、Q:如果获取.NET Compact Framework 2.0的安装程序并将其安装到Windows Mobile 5.0设备中?

  A:Visual Studio 2005提供了.NET Compact Framework 2.0安装程序,在开发部署时会自动部署到移动设备上。

9、Q:Windows Mobile 5.0中没有集成.NET Compact Framework 2.0,是不是生成的应用程序安装包就应该带上.NET Compact Framework 2.0?

  A:技术上来说是的。但能否在应用程序中提供.NET Compact Framework 2.0取决于微软对此的授权情况。

10、Q:如何把.NET Compact Framework 2.0与应用程序一同打包发布?

  A:.NET Compact Framework 2.0有一个单独的CAB安装包,可以把此文件与应用程序打成一个安装包。

11、Q:用Visual Studio 2003开发可以获得很好的兼容性吗?

  A:用Visual Studio 2003开发的基于.NET Compact Framework 2.0的程序可以在Windows Mobile 5.0的设备上运行。

12、Q:在Windows Mobile上面是否开发COM+或者DLL?

  A:可以开发DLL动态共享库。

13、Q:C#是否支持Windows Mobile 5.0的DirectX开发?

  A:支持。

14、Q:现有的使用Visual Studio开发的Smartphone 2003应用程序,可以移植到Windows CE 5.0平台上吗?

  A:可以。

15、Q:Windows Mobile 5.0内置红外线接口API吗?

  A:Windows Mobile 5.0对红外接口的支持并没有更新,需要采用之前的方法进行红外接口的开发,例如与串口通信等。

16、Q:如何开发手机游戏,特别是能够交互的网络游戏?

  A:Windows Mobile对游戏开发的支持是比较充分的,可以采用DirectX技术进行3D或2D界面的开发;对于网络部分,Windows Mobile可以支持socket通信方式。所以,从技术上来讲,开发网络游戏是完全没有问题的。

17、Q:我们公司目前更多关注的是嵌入式领域,也就是Windows CE,而非Windows Mobile。我们主要是在关注IPTV领域,在这方面有哪些的资源?

  A:Windows CE是一种可自定义的嵌入式操作系统,适用于各种内存很少的设备。OEM可以使用Windows CE设计平台和自定义应用程序,使用户可以获得各种设备的最佳体验,例如手持设备、瘦客户机、逻辑控制器以及各种高级消费类电子产品。 Windows Mobile是基于Windows CE构建的一种完善的软件平台。与Windows CE不同,Windows Mobile Smartphone和Pocket PC操作系统专为要求特殊硬件配置的设备而设计。该软件包括标准化的接口和应用程序,可确保在各种硬件设计中的兼容性。 所以Windows Mobile和Windows CE的资源是通用的,您可以在http://www.microsoft.com/china/mobile、http://www.microsoft.com/windowsmobile/,以及微软社区http://www.microsoft.com/china/windowsmobile/communities/default.mspx获得相应的资源和帮助。

18、Q:我们在Windows Mobile上进行应用开发遇到一些底层的接口问题,如何取得微软的技术支持?

  A:微软将一如既往地对基于Windows Mobile操作系统开发的独立软件开发商和开发人员进行支持,可以直接向800-820-3800全球技术支持中心寻求支持,或者提供具体问题细节,我们将给出相应的解决方案。

19、Q:如何才能将我们的软件放到微软的Mobile2Market项目中去?对MVP有没有什么优惠?

   A:Mobile2Markert项目在中国是非常优惠的,目前对MVP没有特别优惠。另外,如何将软件放到微软的Mobile2Market中请参考http://www.microsoft.com/china/mobile/developer/developerprograms/mobile2market/default.asp。

20、Q:哪些工具可用于Pocket PC 2003开发?

  A:要构建Pocket PC 2003本机C++应用程序,您需要Microsoft eMbedded Visual C++ 4.0、Microsoft eMbedded Visual C++ 4.0 Service Pack 3,以及Pocket PC 2003 SDK。

21、Q:为了支持 Windows Mobile 2003 Second Edition 的增强功能(例如高分辨率或横向屏幕),应该在应用程序中做些什么?

  A:Windows Mobile 2003 Second Edition 提供了全新的屏幕方向和分辨率,包括针对Pocket PC的横向、方形和VGA支持以及针对Smartphone的QVGA支持。这种版本不需要新的SDK。

22、Q:Pocket PC 2002应用程序可以在Pocket PC 2003 设备上工作吗?

  A:使用文档化API且功能良好的Pocket PC 2002 应用程序无需重新编译即可在 Pocket PC 2003 设备上运行。

23、Q:如何从eVB迁移到Visual Basic .NET?

  A:从eVB迁移到Visual Basic .NET并不容易,但迁移的好处远远超过了成本: • 数据类型更丰富:eVB只有16 字节的VARIANT;Visual Basic .NET使用.NET Framework通用类型系统。 • 执行更快:eVB需要解释;Visual Basic .NET在执行前由JIT(实时)编译器编译为本机代码。 • 错误处理更完善:eVB仅支持“On Error”;Visual Basic .NET支持结构化异常处理。 • 支持结构:eVB不支持;Visual Basic .NET支持命名空间、类和结构。 • 面向对象:eVB是面向过程的;Visual Basic .NET支持完全的OOP(面向对象编程)。 • “一等公民”:eVB总是希望迎头赶上MFC;Visual Basic .NET则是.NET的核心。 • 本机XML支持:eVB不支持;Visual Basic .NET支持本机XML和XML Web服务。 • 数据模型更完善:ADO.NET远远超过了ADOCE;它是最好的数据模型。 • 执行更安全、更可靠:eVB是一种脚本语言;Visual Basic .NET为托管代码。 • 还有许许多多! 同时,还有各种各样的资源(从移植实验到技术文章)可以帮助开发人员进行这种过渡。

24、Q:应该使用什么开发工具来编写基于.NET Compact Framework的Pocket PC应用程序?

  A:Microsoft Visual Studio .NET 2003允许Visual Basic .NET或C#编程人员创建Pocket PC 2000、Pocket PC 2002和Pocket PC 2003设备的托管代码应用程序(即那些以.NET公共语言运行库为目标的应用程序)。要开发Pocket PC 2000和Pocket PC 2002设备的托管代码应用程序,您可以使用即装即用的Visual Studio .NET 2003。在开发过程中,Visual Studio .NET 2003将会自动地将.NET Compact Framework安装到这些设备的RAM中。.NET Compact Framework已经在所有Pocket PC 2003设备的ROM 中,而且Visual Studio .NET 2003通过Pocket PC 2003 SDK支持它。

25、Q:有什么资源可以用于进行Windows Mobile 2003 Second Edition的开发?

  A:下载新的Windows Mobile Developer资源包,其中包括白皮书以及新的和更新的代码示例。该版本不需要全新的SDK。可以用新的模拟器软件包对应用程序进行测试。eMbedded Visual C++ 4.0开发人员应当下载eMbedded Visual C++ 4.0 Service Pack 3。

26、Q:什么工具可用于Smartphone 2002开发?

  A:要开始开发Microsoft Smartphone 2002应用程序,您需要eMbedded Visual C++ 3.0和Smartphone 2002 SDK。两者都可以在Windows Mobile Developer获得。

27、Q:MFC或ATL可用于Smartphone 2002开发吗?

  A:不可以,Smartphone 2002不支持MFC与ATL开发。

28、Q:可以使用eMbedded Visual Basic 3.0来构建Smartphone 2002应用程序吗?

  A:不可以,不支持以Smartphone 2002为目标的eVB 开发。

29、Q:哪些工具可用于进行Microsoft Smartphone 2003开发?

  A:对于Smartphone 2003,有两种开发选择,或者通过带有Service Pack 3的eMbedded Visual C++ 4.0开发本机代码,或者通过Visual Studio .NET 2003开发托管代码。这两种情况都需要下载Smartphone 2003 SDK。Windows Mobile 2003 Second Edition模拟器软件包使您可以在Second Edition设备上测试应用程序。eMbedded Visual C++ 4.0和Smartphone 2003 SDK都可以在Windows Mobile Developer获得。

现在很多浏览器都有“弹出窗口过滤功能”,对于一些网站的功能有一定的限制,那么开发人员怎么样才能知道你的窗口是否被浏览器过滤,弹不出你的功能窗口了呢?icech找到了一段代码能够判断是否浏览器阻止了弹出窗口,并提示用户的方法。市一段javascript代码。

先将这段代码放在head里面

下面是一个下拉菜单的效果测试

这样就可以了,效果不错吧!
转载本文请注明来源于:西部E网 www.weste.net,谢谢支持!

问题一:如保加载JDBC驱动程序

正常我们加载驱动程序有三个途径:

1)Class.forName(String)这想当于classLoader一个String指定的类,在装载时把该驱动程序的静态内容都初始化,其实这时驱动程序类调用了DriverManager.registerDriver(driver);方法
2)使用系统属性:System.getProperty().load(new FileInputStream("属性文件"));
在属性文件中指定jdbc.driver=drivername 这样的好处是可以同时加载多个JDBC,换数据库时不用访问JAVA源代码,只是修改属性文件
3)直接registerDriver(driver)这种方法最可靠,可以在任何环境下使用。

1)方法简单,但MS的JVM不能正确初始化。比如使用IE时在APPLET中就不能使用,应该用3)的方法。但3)方法在灵活性方面不如2),可以根据环境综合考虑。

问题二:大对象存储

一般来说,大对象存储是把文件存到数据库中,当然也可以内存中的超大字符串。对于象图片这样的文件当然是用二进制存储,这里有很多误区,网络上的教程99%都是行不通的,连SUN自己的文档都一直错误,虽然错误很小。按说二进制文件应该存为BLOB类型,但JBDC2并不能直接对BLOB存入二进制文件,如果你这样做,会得到一个IO而不是SQL异常,为此花了我近两个小时才弄清楚。

如果要把一个二制文件存入ORACLE,用标准的JDBC你就要用LONG ROW类型:
create table tb_file(name varchar(20),detail long row);
然后
File file = new File("aaa.gif");
int fileLength =(int) file.length();
InputStream fin = new FileInputStream(file);
PreparedStatement pstmt = con.prepareStatement("insert into tb_file values(´aaa.gif´,?)");
pstmt.setBinaryStream (1, fin, fileLength);
pstmt.executeUpdate();

如果你一定要用BLOB存储,你就必须用ORACLE自己的方法:
create table tb_file(name varchar(20),detail BLOB);
con.setAutoCommit(false);
stmt.executeUpdate("insert into tb_file values(´aaa.gif´,empty_blob())");
下面必须SELECT得到BLOB的对象再向里写:
rs = stmt.executeQuery("select detail from tb_file where name=´aaa.gif´ for upfdate" );
if(rs.next())
{
Blob blob = rs.getBlob(1);
BinaryOutputStream out = ((oracle.sql.BLOB)blob).getBinaryOutputStream();
byte[] b = new byte[((oracle.sql.BLOB)blob).getBufferSize];
InputStream fin = new FileInputStream(file);
int len = 0;
while( (len = fin.read(b)) != -1)
out.write(b,0,len);
fin.close();
out.close();
con.commit();
}

同样读取数据你并不能象LONG ROW那样
InputStream in = rs.getBinaryInputStream("detail");
而要
Blob blob = rs.getBlob("detail");
in = blob.getBinaryStream();

问题三:可滚动结果集

ORACLE 明确说明不支持结果集滚动,那么我们用JDBC2得到一个可滚动的结果集就是同JDBC自己支持的,就是说结果集要在内在中高度缓存,很多很多的开发者都错误地认为是数据库支持的。只是他们没有真正查询大量行,如果真的查询大量行的话肯定是死定了!对于超大量行的数据,情愿返回到它的笨方法也不要使用可滚动结果集.

  数据库命令执行时使用Command对象。Command类有三种:SqlCommand、OleDbCommand与OdbcCommand。

  Command对象主要用来运行SELECT、INSERT、UPDATE或DELETE之类的SQL语句。Command对象还可以调用存储过程或从特定表中取得记录。

  DataReader对象主要是用来读取数据结果,使用它读取记录时通常比从DataSet更快。DataReader类有三种:SqlDataReader、OleDbDataReader和OdbcDataReader。DataReader对象用Commmand对象从数据库中读取记录,并且DataReader对象只能向前的读取记录,用于在某些情况下替代DataSet对象(DataSet对象可以存储数据库中的行拷贝,可以在切断数据库的连接时处理这个拷贝,我们将在以后的章节中详细介绍该对象)。

  注意:不能用DataReader修改数据库中的记录,它是采用向前的,只读的方式读取数据库。

  SqlCommand类

  SqlCommand对象用于对Sql Server数据库执行命令。OleDbCommand对象用于对支持OleDb的数据库执行命令,如Oracle与Access。OdbcCommand对象用于对支持Odbc的数据库执行命令。尽管SqlCommand类是针对Sql Server的,但是这个类的许多属性、方法与事件和OleDbCommand及OdbcCommand等类相似。本章将重点讲解SqlCommand特定的属性与方法,其他的Command类你可以参考相应的帮助文档。

  注意:使用不同的Command对象需要导入不同的命名空间。OleDbCommand的命名空间为System.Data.OleDb。SqlCommand的命名空间为System.Data.SqlClient。OdbcCommand的命名空间为System.Data.Odbc。

  SqlCommand属性:

属性 说明
CommandText 其返回类型为string, 获取或设置要对数据源执行的 SQL 语句、存储过程或表。
CommandTimeOut 其返回类型为int,获取或设置在终止执行命令的尝试并生成错误之前的等待时间。
CommandType 其返回类型为CommandType,读取或设置表示CommandText属性将如何被解释的值,其有效的值可以为CommandType.Text、CommandType.StoredProcedur与CommandType.TableDirect,分别表示SQL语句、存储过程调用或要读取的表,默认为Text。
Connection 其返回类型为string, 获取或设置 SqlCommand 的此实例使用的 SqlConnection。
Parameters 其返回类型为SqlParameterCollection,取得提供给命令的参数(如有)。

  SqlCommand方法:

方法 说明
Cancle() 其返回类型为void,取消命令的执行
CreateParameter() 其返回类型为SqlParameter, 用于创建 SqlParameter 对象的新实例。
ExecuteNonQuery() 其返回类型为int,执行不返回结果集的Sql语句,包括INSERT、UPDATE与DELETE语句、DDL语句和不返回结果集的存储过程调用。返回的int值是命令影响的数据库行数。
ExecuteReader() 其返回类型为SqlDataReader, 执行SELECT语句、TableDirect命令或返回结果集的存储过程调用。在SqlDataReader对象中返回结果集。
ExecuteScalar() 其返回类型为object,执行返回单个值的SELECT语句(任何其他的值将被忽略)。这个命令结果作为对象被返回。
ExecuteXmlReader() 其返回类型为XmlReader,执行返回XML数据的SELECT语句,用XmlReader对象返回结果集,只适用于SqlCommand类

 

      生成SqlCommand对象

  我们可以用构造函数生成SqlCommand对象,也可以调用SqlConnection对象的CreateCommand()方法生成SqlCommand对象,下面分别介绍这两种方法。

  用构造函数生成SqlCommand对象

  SqlCommand对象的构造函数如下所示:

SqlCommand()
SqlCommand(string commandText)
SqlCommand(string commandText,SqlConnection mySqlConnection)

  程序代码说明:在上述语法范例的程序代码中,commandText包含SQL语句、存储过程调用或要读取的表。mySqlConnection是对应的SqlConnection对象。

  在使用SqlCommand对象之前,首先要确定一个SqlConnection对象,用于和SQL Server数据库进行数据传递。

mySqlConnection.ConnectionString="server=localhost;database=Northwind;
integrated security=SSPI";

  然后可以用下列语句生成新的SqlCommand对象:

SqlCommand mySqlCommand=new SqlCommand();

  再将mySqlCommand对象的Connection属性设置为mySqlConnection:

mySqlCommand.Connection= mySqlConnection;

  这样mySqlCommand对象就可以使用mySqlConnection与数据库进行数据传递。现在,Command对象的CommandType属性确定要执行的命令类型。可以用System.Data.CommandType枚举值指定CommandType属性。
CommandType的枚举值如下表所示:

数值 说明
Text 表示命令是SQL语句,默认值是Text
StoredProcedure 表示命令是储存过程调用
TableDirect 表示被读取的行和列的表名。注意:SqlCommand对象不支持TableDirect,要使用其他的Command类的对象。

  例如你可以采用如下的形式执行一个SQL查询:

SqlCommand mySqlCommand=new SqlCommand();
mySqlCommand.Connection=mySqlConnection;
mySqlCommand.CommandText=”SELECT * FROM Employees”;
//mySqlCommand.CommandType=CommandType.Text;

  程序代码说明:在上述语法范例的程序代码中,我们设置了mySqlCommand对象的commandText为一个SELECT查询语句,并且指定了mySqlCommand对象的CommandType属性为CommandType.Text,表示命令是SQL语句。由于CommandType.Text是默认的CommandType值,所以我们可以将其注译掉。

  还有一个更具效率的形式,那就是使用SqlCommand对象的其中一种构造函数:

SqlCommand mySqlCommand=new SqlCommand(”SELECT * FROM Employees”,myConnection);

  程序代码说明:在上述语法范例的程序代码中,我们可以直接利用SqlCommand(string commandText,SqlConnection mySqlConnection) 构造函数,从而使得程序代码更加的简练和直观。

  还可以使用储存过程来查询所需要的数据,我们可以采用如下的代码形式:

SqlCommand mySqlCommand=new SqlCommand(”GetEmpolyees”,myConnection);
mySqlCommand.CommandType=CommandType.StoredProcedure;

  程序代码说明:在上述语法范例的程序代码中,GetEmpolyees为一个储存过程名,用来实现所有的雇员信息查询。并且将CommandType值指定为StoredProcedure,表示命令是储存过程调用。

  使用CreateCommand()方法生成SqlCommand对象

  如果不用构造函数,也可以使用SqlConnection对象的CreateCommand()方法生成SqlCommand对象。这个方法返回新的SqlCommand对象。例如:

SqlCommand mySqlCommand=mySqlConnection.CreateCommand();

SqlDataReader类

  可以用SqlDataReader类对象从SQL Server数据库中读取行;用OleDbDataReader类对象从支持OLE DB的数据库中读行,如Oracle与Access;用OdbcDataReader类对象从支持ODBC的数据库中读取行。

  DataReader对象允许你以向前的,只读的方式读取数据,有时候DataReader对象也称为消软管游标。DataReader对象采用了一种简化的数据读取方式,但是提高了性能的同时也牺牲了很多特性。例如在DataSet中支持的排序,分页等功能。这些功能将在以后的章节进行详细的介绍。

  SqlDataReader的属性

属性 说明
Depth 其返回类型为int,取得表示当前行嵌入深度的值
FieldCount 其返回类型为int,取得当前行的列数
IsColsed 其返回类型为bool,取得一个布尔值,表示是否关闭数据读取
RecordsAffected 其返回类型为int, 取得执行SQL语句增加、修改或删除的行数。

  SqlDataReader的方法

方法 说明
Reader() 其返回类型为bool,将数据阅读器移到结果集的下一行并读取该行。这个方法返回的布尔值表示结果集中是否有多行
GetValue() 其返回类型为object, 返回指定列的值
GetValues() 其返回类型为int,将当前行中所有列的值复制到指定对象数组。这个方法返回的int是数组元素的个数
NextResult() 其返回类型为bool,将数据阅读器移到结果集的下一行。这个方法返回的布尔值表示结果集中是否有多行
Close() 关闭 SqlDataReader 对象
GetInt32(),GetChar(),
GateDataTime(),Get×××()
返回指定列的值,并且返回的类型为相应的数据类型。例如GetInt32()返回整型的数值。注意,如果你将返回值赋予一个类型不匹配的变量时,将会抛出一个InvalidCastException异常

   用ExecuteReader()方法执行查询

  下面是一个用ExecuteReader()方法执行SELECT语句的范例。这个方法用DataReader对象返回结果集,然后可以用此对象读取数据库返回的行。

  范例程序代码如下:

01 public partial class _Default : System.Web.UI.Page
02 {
03  protected void Page_Load(object sender, EventArgs e)
04  {
05   string connectionString =
06 ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
07   SqlConnection con = new SqlConnection(connectionString);
08   string sql = "SELECT top 5 CustomerID,CompanyName,ContactName,Address
09          FROM Customers";
10   SqlCommand cmd = new SqlCommand(sql, con);
11   con.Open();
12   SqlDataReader reader = cmd.ExecuteReader();
13   StringBuilder htmlStr = new StringBuilder("");
14   while (reader.Read())
15   {
16    htmlStr.Append("CustomerID:" + reader["CustomerID"] + "<br>");
17    htmlStr.Append("CompanyName:" + reader["CompanyName"] + "<br>");
18    htmlStr.Append("ContactName:" + reader.GetString(2) + "<br>");
19    htmlStr.Append("Address:" + reader.GetString(3) + "<br>");
20    htmlStr.Append("<hr>");
21   }
22   reader.Close();
23   con.Close();
24   HtmlContent.Text = htmlStr.ToString();
25  }
26 }

  程序代码说明:在上述语法范例的程序代码中,第5到12行代码生成所要的对象并执行SELECT语句,从Customers表中读取前5条记录。cmd返回的结果集存放在reader对象中,然后你可以用Reader()方法读取reader对象的记录。这个方法在有另一个可读的行时返回布尔真值,否则返回布尔假值。可以从reader对象中读取一个记录的各个列值,只要在方括号中传入列名即可。如第16和17行所示,我们用reader[“CustomerID”]读取CustomerID列的各项内容。你也可以直接在方括号中传入数字值指定想要列的索引。如第18和19行代码所显示,由于我们在用SELECT进行数据查询的时,ContactName和Address分别位于第3和第4列,而相应的索引值则为2和3,所以我们可以用reader.GetString(2)和reader.GetString(3)读取ContactName和Address列的数据。如第14行代码所示,我们可以在While循环中用Reader()方法一一读取每条记录。

  执行结果:

附件:wrx298kd8j.png(11780 Byte)

      每次程序执行命令时,都要将相应的命令通过网络传递到数据库中,并在数据库进行执行,然后将结果返回到程序中,从而产生大量的网络通信流。我们可以使用ExecuteReader()方法同时执行多条SELECT语句查询减少重复的数据传递。

  下面的实例是使用ExecuteReader()方法同时查询三个表中的数据,并将返回的三个结果集显示在页面上。

  范例程序代码如下:

01 public partial class _Default : System.Web.UI.Page
02 {
03  protected void Page_Load(object sender, EventArgs e)
04  {
05   string connectionString =
06 ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
07   SqlConnection con = new SqlConnection(connectionString);
08   SqlCommand cmd = con.CreateCommand();
09   cmd.CommandText = "SELECT TOP 3 ProductID,ProductName
10   FROM Products ORDER BY ProductID;" +
11    "SELECT TOP 3 CustomerID,CompanyName
12    FROM Customers ORDER BY CustomerID;" +
13     "SELECT TOP 3 OrderID,CustomerID
14     FROM Orders ORDER BY OrderID;";
15   con.Open();
16   SqlDataReader reader = cmd.ExecuteReader();
17   StringBuilder htmStr=new StringBuilder("");
18   int i = 0;
19   do
20   {
21    htmStr.Append("结果集");
22    htmStr.Append(i.ToString());
23    htmStr.Append("<br>");
24    while (reader.Read())
25    {
26     htmStr.Append("reader[0]=" + reader[0]);
27     htmStr.Append("<br>");
28     htmStr.Append("reader[1]=" + reader[1]);
29     htmStr.Append("<br><br>");
30    }
31    htmStr.Append("<hr>");
32    i++;
33   } while (reader.NextResult());
34   reader.Close();
35   con.Close();
36   HtmlContent.Text = htmStr.ToString();
37  }
38 }

  程序代码说明:在上述语法范例的程序代码中,第9行到第14中定义了3个查询语句,各语句之间用分号进行间隔。第16行调用ExecuteReader()方法,并返回SqlDataReader对象,并且对三条不同的SELECT语句各返回一个结果集。要读取第一个结果集的话,可以用SqlDataReader对象的Reader()方法。Reader()方法在没有其他的可读行时将返回一个false值。当一个结果集的所有记录都读取完毕后,可以调用SqlDataReader对象的NextResult()方法,然后在读取下一个结果集,在没有其他的结果集时,也返回一个false值。

  提示:外循环do…while测试结尾的reader. NextResult()的返回值。由于do…while循环末尾检测这个条件,这样就保证了do…while循环至少执行一次。之所以在末尾才调用NextResult()方法,是因为这样可以首先把SqlDataReader对象移到下一个结果集,然后才返回表示是否还有下一个结果集的布尔结果。如果使用while循环中,则有可能直接跳过第一个结果集,从而产生错误。

81d4kg6g51.png

    用ExecuteScalar()方法执行SELECT语句

  用ExecuteScalar()方法执行SELECT语句,返回单个值,并且忽略其他的任何读取的结果。ExecuteScalar()方法返回的结果是一个object对象。ExecuteScalar()主要是用来执行SELECT语句,或者执行包括聚合函数的SQL语句。

  下面我们将使用如下的程序读取Products表中的记录条数,并且在相应的查询语句中使用COUNT()聚合函数。

  范例程序代码如下:

01 public partial class _Default : System.Web.UI.Page
02 {
03  protected void Page_Load(object sender, EventArgs e)
04  {
05   string connectionString =
06    ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
07   SqlConnection con = new SqlConnection(connectionString);
08   SqlCommand cmd = con.CreateCommand();
09   cmd.CommandText = "SELECT COUNT(*) FROM Products";
10   con.Open();
11   int returnValue = (int)cmd.ExecuteScalar();
12   HtmlContent.Text = "Products表中共有" + returnValue.ToString()+"条记录";
13  }
14 }

  程序代码说明:在上述语法范例的程序代码中,第9行即为查询Products表中的记录条数的SQL语句。第11行代码用ExecuteScalar()方法执行SELECT语句。注意,由于ExecuteScalar()方法的结果为object对象,因此我们要将其进行强制类型转换,再赋予相应的变量。

  执行结果:

3iw32u28xs.png

  我们经常会遇到批量上传的问题,也会遇到将某个目录下所有文件都上传到服务器上的问题。那么,如何解决此类问题呢?以前的技术一般采用ActiveX等方式,这里笔者采用SharpZlib来实现,听说VS2005已有压缩和解压缩的解决方案,笔者还没有时间用VS2005,所以就只好使用VS2003 + SharpZlib来解决问题了。

  1、首先从这里下载0.84版本的SharpZlib源码及示例码。
  2、下载下来之后你发现它没有VS2003的解决方案文件,没有关系。你可以自己建立,首先新建一个ZipUnzip的解决方案,然后,将上面经过解压缩之后的所有文件及目录COPY到你的解决方案所在的目录下。
  3、在VS2003解决方案资源管理器(一般是在右上方中部点的位置)中点击显示所有文件按钮,然后可以见到很多“虚”的图标、文件及文件夹等,可以一次选择它们,然后包含进项目中。
  4、编译,最好使用Release选项,编译完成之后你可以在inRelease看到ZipUnzip.dll的类了。如果你编译时报错,说什么AssemblyKeyFile之类的,你可以使用强命名工具新建一个,也可以将AssemblyInfo.cs中[assembly: AssemblyKeyFile("。。。。。")]改成:[assembly: AssemblyKeyFile("")] (不推荐这样做)。
  5、新建一个WEBFORM项目,添加ZipUnzip.dll类的引用,然后添加如下文件及内容:

// ——————————————
// 1. AttachmentUnZip.cs
// ——————————————
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;

namespace WebZipUnzip
{
public class AttachmentUnZip
{
public AttachmentUnZip()
{
}
public static void UpZip(string zipFile)
{
string []FileProperties=new string[2];
FileProperties[0]=zipFile;//待解压的文件
FileProperties[1]=zipFile.Substring(0,zipFile.LastIndexOf("\")+1);//解压后放置的目标目录
UnZipClass UnZc=new UnZipClass();
UnZc.UnZip(FileProperties);
}
}
}

// ———————————————
// 2. UnZipClass.cs
// ———————————————

using System;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;

namespace WebZipUnzip
{
public class UnZipClass
{
///
/// 解压文件
///
/// 包含要解压的文件名和要解压到的目录名数组
public void UnZip(string[] args)
{
ZipInputStream s = new ZipInputStream(File.OpenRead(args[0]));
try
{
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = Path.GetDirectoryName(args[1]);
string fileName = Path.GetFileName(theEntry.Name);

//生成解压目录
Directory.CreateDirectory(directoryName);

if (fileName != String.Empty)
{
//解压文件到指定的目录
FileStream streamWriter = File.Create(args[1]+fileName);

int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}

streamWriter.Close();
}
}
s.Close();
}
catch(Exception eu)
{
throw eu;
}
finally
{
s.Close();
}

}//end UnZip
public static bool UnZipFile(string file, string dir)
{
try
{
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
string fileFullName = Path.Combine(dir,file);
ZipInputStream s = new ZipInputStream(File.OpenRead( fileFullName ));

ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = Path.GetDirectoryName(theEntry.Name);
string fileName = Path.GetFileName(theEntry.Name);

if (directoryName != String.Empty)
Directory.CreateDirectory( Path.Combine(dir, directoryName));

if (fileName != String.Empty)
{
FileStream streamWriter = File.Create( Path.Combine(dir,theEntry.Name) );
int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}

streamWriter.Close();
}
}
s.Close();
return true;
}
catch (Exception)
{
throw;
}
}

}//end UnZipClass
}
// ———————————————-
// 3. ZipClass.cs
// ———————————————-
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;

namespace WebZipUnzip
{
///
/// 压缩文件
///
public class ZipClass
{
public void ZipFile(string FileToZip, string ZipedFile ,int CompressionLevel, int BlockSize,string password)
{
//如果文件没有找到,则报错
if (! System.IO.File.Exists(FileToZip))
{
throw new System.IO.FileNotFoundException("The specified file " + FileToZip + " could not be found. Zipping aborderd");
}

System.IO.FileStream StreamToZip = new System.IO.FileStream(FileToZip,System.IO.FileMode.Open , System.IO.FileAccess.Read);
System.IO.FileStream ZipFile = System.IO.File.Create(ZipedFile);
ZipOutputStream ZipStream = new ZipOutputStream(ZipFile);
ZipEntry ZipEntry = new ZipEntry("ZippedFile");
ZipStream.PutNextEntry(ZipEntry);
ZipStream.SetLevel(CompressionLevel);
byte[] buffer = new byte[BlockSize];
System.Int32 size =StreamToZip.Read(buffer,0,buffer.Length);
ZipStream.Write(buffer,0,size);
try
{
while (size < StreamToZip.Length)
{
int sizeRead =StreamToZip.Read(buffer,0,buffer.Length);
ZipStream.Write(buffer,0,sizeRead);
size += sizeRead;
}
}
catch(System.Exception ex)
{
throw ex;
}
ZipStream.Finish();
ZipStream.Close();
StreamToZip.Close();
}
public void ZipFileMain(string[] args)
{
//string[] filenames = Directory.GetFiles(args[0]);
string[] filenames = new string[]{args[0]};

Crc32 crc = new Crc32();
ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));

s.SetLevel(6); // 0 – store only to 9 – means best compression

foreach (string file in filenames)
{
//打开压缩文件
FileStream fs = File.OpenRead(file);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(file);

entry.DateTime = DateTime.Now;

// set Size and the crc, because the information
// about the size and crc should be stored in the header
// if it is not set it is automatically written in the footer.
// (in this case size == crc == -1 in the header)
// Some ZIP programs have problems with zip files that don‘t store
// the size and crc in the header.
entry.Size = fs.Length;
fs.Close();

crc.Reset();
crc.Update(buffer);

entry.Crc = crc.Value;

s.PutNextEntry(entry);

s.Write(buffer, 0, buffer.Length);

}
s.Finish();
s.Close();
}
}
}
// ———————————————
// 4. WebForm1.aspx
// ———————————————
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="WebZipUnzip.WebForm1" %>&nbsp;
<META content="Microsoft Visual Studio .NET 7.1" name=GENERATOR>
<META content=C# name=CODE_LANGUAGE>
<META content=JavaScript name=vs_defaultClientScript>
<META content=http://schemas.microsoft.com/intellisense/ie5 name=vs_targetSchema>
<FORM id=Form1 method=post runat="server"><?xml:namespace prefix = asp /><asp:Button id=Button1 style="Z-INDEX: 101; LEFT: 56px; POSITION: absolute; TOP: 64px" runat="server" Text="压缩"></asp:Button><asp:Button id=Button2 style="Z-INDEX: 102; LEFT: 112px; POSITION: absolute; TOP: 64px" runat="server" Text="解压"></asp:Button><INPUT id=File1 style="Z-INDEX: 103; LEFT: 32px; POSITION: absolute; TOP: 24px" type=file name=File1 runat="server"> </FORM></BODY></HTML>
//——————————————-
// 5.WebForm1.aspx.cs
//——————————————-

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace WebZipUnzip
{
///
/// Summary description for WebForm1.
///
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;
protected System.Web.UI.HtmlControls.HtmlInputFile File1;
protected System.Web.UI.WebControls.Button Button2;

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

///
/// Required method for Designer support – do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Button2.Click += new System.EventHandler(this.Button2_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion

#region 压缩
private void Button1_Click(object sender, System.EventArgs e)
{
string []FileProperties=new string[2];
string fullName=this.File1.PostedFile.FileName;//C: esta.txt
string destPath=System.IO.Path.GetDirectoryName(fullName);//C: est
//待压缩文件
FileProperties[0]=fullName;

//压缩后的目标文件
FileProperties[1]= destPath +"\"+ System.IO.Path.GetFileNameWithoutExtension(fullName) + ".zip";
ZipClass Zc=new ZipClass();
Zc.ZipFileMain(FileProperties);

//删除压缩前的文件
System.IO.File.Delete(fullName);
}

#endregion

#region 解压
private void Button2_Click(object sender, System.EventArgs e)
{
string fullName=this.File1.PostedFile.FileName;//C: esta.zip
//解压文件
//AttachmentUnZip.UpZip(fullName);

// string[] FileProperties = new string[2];
// FileProperties[0] = fullName;//待解压的文件
// FileProperties[1] = System.IO.Path.GetDirectoryName(fullName);//解压后放置的目标目录
// UnZipClass UnZc=new UnZipClass();
// UnZc.UnZip(FileProperties);
string dir = System.IO.Path.GetDirectoryName(fullName);
string fileName = System.IO.Path.GetFileName(fullName);
UnZipClass.UnZipFile(fileName, dir);
}
#endregion
}
}
  OK! 试试看。

  此方案解决了文件名中文字的问题,目录解压缩问题。
  至于整个文件夹批量上传并压缩成一个WINZIP压缩包的问题,没有时间解决了,各位如有解决方案,不妨共享一下。

如果你想把二进制的数据,比如说图片文件和HTML文件,直接保存在你的MySQL数据库,那么这篇文章就是为你而写的!我将告诉你怎样通过HTML表单来储存这些文件,怎样访问和使用这些文件。
  本文概述: 
  在mysql中建立一个新的数据库 
  一个怎样储存文件的例子程序 
  一个怎样访问文件的例子程序 
  在mysql中建立一个新的database
   首先,你必须在你的mysql中建立一个新的数据库,我们将会把那些二进制文件储存在这个数据库里。在例子中我会使用下列结构,为了建立数据库,你必须做下列步骤: 
  进入MySql控制器 
  输入命令"create database binary_data;" 
  输入命令"use binary_data;" 
  输入命令"CREATE TABLE binary_data ( id INT  (4) NOT NULL AUTO_INCREMENT PRIMARY KEY,
description CHAR(50), bin_data LONGBLOB, filename CHAR(50), filesize CHAR  (50), filetype CHAR(50));" (不能断行) 
  如果没有意外,数据库 和 表 应该建立好了。 
  一个怎样储存文件的例子程序 用这个例子你可以通过Html表单将文件传输到数据库中。.

store.php3

以下为引用的内容:

// store.php3 – by Florian Dittmer 
?>

// 如果提交了表单,代码将被执行:

if ($submit) {

     // 连接到数据库
     // (你可能需要调整主机名,用户名和密码)

    MYSQL_CONNECT( "localhost", "root", "password");
    mysql_select_db( "binary_data");

    $data = addslashes(fread(fopen($form_data,  "r"), filesize($form_data)));

    $result=MYSQL_QUERY( "INSERT INTO binary_data (description,bin_data,filename,filesize,filetype) ".
         "VALUES (’$form_description’,’$data’,’$form_data_name’,’$form_data_size’,’$form_data_type’)");

    $id= mysql_insert_id();
    print  "

This file has the following Database ID: $id";

    MYSQL_CLOSE();

} else {

     // 否则显示储存新数据的表单
?> 
}

?>

  如果你执行了这个程序,你将会看见一个简单的Html表单,单击“浏览”选择一个文件,然后单击提交。
  当文件上传至web服务器之后,程序将会告诉你刚刚上传的文件的ID,记住这个ID,待会要用的。
  一个怎样访问文件的例子程序
  你可以通过这个程序访问你刚才储存的文件

以下为引用的内容:

// getdata.php3 – by Florian Dittmer 
// 调用方法: getdata.php3?id=

if($id) {

     // 你可能需要调整主机名,用户名和密码:
    @MYSQL_CONNECT( "localhost", "root", "password");

    @mysql_select_db( "binary_data");

    $query =  "select bin_data,filetype from binary_data where id=$id";
    $result = @MYSQL_QUERY($query);

    $data = @MYSQL_RESULT($result,0, "bin_data");
    $type = @MYSQL_RESULT($result,0, "filetype");

    Header(  "Content-type: $type");
    echo $data;

};
?>

  程序必须知道要访问那个文件, 你必须将ID作为一个参数。
  例如: 一个文件在数据库中的ID为2. 你可以这样调用它:
                    getdata.php3?id=2如果你将图片储存在数据库里, 你可以向调用图片一样调用它。
  Example: 一个图片文件在数据库中的ID为3. 你可以这样调用它:
                    
  怎样储存大于1MB的文件:
  如果你想储存大于1MB的文件,你必须对你的程序、PHP设置、SQL设置进行许多修改,。
  下面几条也许可以帮助你储存小于24MB的文件:
  修改 store.php3 ,将 MAX_FILE_SIZE 的值改成 24000000。 
  修改你的PHP设置,在一般情况下,PHP只允许小于2MB的文件,你必须将max_filesize(在php.ini中)的值改成24000000

  去掉MYSQL的数据包大小限制,在一般情况下 MYSQL 小于1 MB的数据包. 
  你必须用以下参数重启你的MYSQL
  /usr/local/bin/safe_mysqld -O key_buffer=16M -O table_cache=128 -O sort_buffer=4M -O record_buffer=1M -O max_allowed_packet=24M 

看到了一段防止SQL注入的JavaScript代码,但是似乎在后台解决的话会更好。

[php]
<SCRIPT language="JavaScript">
function Check(theform)
{
if (theform.UserName.value=="")
{
alert("请输入用户名!")
theform.UserName.focus();
return (false);
}
if (theform.Password.value == "")
{
alert("请输入密码!");
theform.Password.focus();
return (false);
}
}
function IsValid( oField )
{
re= /select|update|delete|exec|count|‘|"|=|;|>|<|%/i;
$sMsg = "请您不要在参数中输入特殊字符和SQL关键字!"
if ( re.test(oField.value) )
{
alert( $sMsg );
oField.value = ‘‘;
oField.focus();
return false;
}
}
</SCRIPT>

<input name="UserName" type="text" maxlength="20" id="UserName" onblur="IsValid(this);" style="width:125px;" />
<input name="Password" type="password" maxlength="20" id="Password" onblur="IsValid(this);" style="width:125px;" />
[/php]

JS实现浏览器菜单命令

<object id=min classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"><param name="Command" value="Minimize"></object>

<object id=max classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"><param name="Command" value="Maximize"></object>

<object id=close classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"><PARAM NAME="Command" value="Close"></object>

<input type=button value=最小化 onclick=min.Click()>

<input type=button value=最大化 onclick=max.Click()>

<input type=button value=关闭 onclick=close.Click()></div>

<INPUT type=button onclick="document.execCommand(‘open‘)" value=打开>

<INPUT type=button onclick="document.execCommand(‘saveas‘)" value=保存>

<INPUT type=button onclick="document.execCommand(‘print‘)" value=打印>

<INPUT type=button onclick="document.execCommand(‘selectall‘)" value=全选>

<INPUT type=button onclick="location.replace(‘view-source:‘+location)" value=源文件>

<INPUT type=button onclick="window.external.ShowBrowserUI(‘PrivacySettings‘,null)" value=安全选项>

<input type=button onClick="window.external.ShowBrowserUI(‘LanguageDialog‘, null)" value=语言设置>

<INPUT type=button onclick="window.external.AddFavorite(location.href, document.title)" value=加入收藏夹>

<INPUT type=button onclick="window.external.ShowBrowserUI(‘OrganizeFavorites‘, null)" value=整理收藏夹>

<INPUT onclick=history.go(-1) type=submit value=后退>

<INPUT onclick=history.go(1) type=submit value=前进>

<input type=button value=刷新 name=refresh onclick="window.location.reload()">

<input type="button" value="导入收藏夹" onClick=window.external.ImportExportFavorites(true,‘‘);>

<input type="button" value="导出收藏夹" onClick=window.external.ImportExportFavorites(false,‘‘);>