欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
從 eMbedded Visual Basic 遷移到 Visual Basic .NET

從 eMbedded Visual Basic 遷移到 Visual Basic .NET

Microsoft Corporation

2003 年 8 月

適用于:
   Microsoft® Windows® Pocket PC 2002
   Microsoft® eMbedded Visual Basic®
   Microsoft® .NET Framework
   Microsoft® Visual Basic® .NET
   Microsoft® .NET Compact Framework
   Microsoft® Visual Studio® .NET

摘要:了解如何將 Microsoft Windows Pocket PC 2002 軟件開(kāi)發(fā)從 Microsoft eMbedded Visual Basic 遷移到 Microsoft .NET Framework 和 Visual Basic .NET。發(fā)布 .NET Compact Framework 之后,在服務(wù)器和臺式機應用程序開(kāi)發(fā)中使用的語(yǔ)言和工具也可以用于開(kāi)發(fā)移動(dòng)應用程序。(本文包含一些指向英文站點(diǎn)的鏈接。)

目錄

簡(jiǎn)介
基本變化
開(kāi)發(fā)變化及改進(jìn)概述
用戶(hù)界面和應用程序導航
Pocket PC 和 Smartphone 的開(kāi)發(fā)
應用程序集成
使用數據庫
部署和分布
小結

簡(jiǎn)介

本白皮書(shū)探討如何將 Microsoft® Windows® Pocket PC 2002 的軟件開(kāi)發(fā)從 Microsoft® eMbedded Visual Basic® 遷移到 Microsoft® .NET Framework 和 Visual Basic® .NET。發(fā)布 Microsoft® .NET Compact Framework 之后,在服務(wù)器和臺式機應用程序開(kāi)發(fā)中使用的語(yǔ)言和工具也可以用于開(kāi)發(fā)移動(dòng)應用程序。

.NET Compact Framework 包含 .NET Framework 類(lèi)型和命名空間的子集。Microsoft® Visual Studio® .NET 環(huán)境中還包含一個(gè)名為 Smart Device Programmability 的集成部件,它包括窗體設計器、設備仿真器等支持功能,從而允許用戶(hù)使用 .NET Compact Framework 進(jìn)行開(kāi)發(fā)。從本質(zhì)上講,新的平臺以及工具、語(yǔ)言的改進(jìn)有助于提高移動(dòng)應用程序在開(kāi)發(fā)、代碼、執行和部署方面的質(zhì)量。下圖簡(jiǎn)要描述了不同的開(kāi)發(fā)構造塊之間的關(guān)系。

圖 1:如何配套使用

基本變化

Microsoft eMbedded Visual Basic 在問(wèn)世之后就成為了主流的應用程序開(kāi)發(fā)環(huán)境。由于它與 Microsoft Visual Basic 6.0 極其相似,而且簡(jiǎn)單易用,因此吸引了許多開(kāi)發(fā)人員。但是,它在語(yǔ)言和平臺相關(guān)性方面還存在一些固有的局限性,因此還需要妥善的解決方法、第三方產(chǎn)品,以及調用底層 Windows CE API。這些局限中的大多數在新的環(huán)境中都已得到解決,但是有些仍需要您自己解決。最基本的變化就是 Visual Basic .NET 是一種面向對象的現代語(yǔ)言,構建代碼要使用公共的 .NET Compact Framework 類(lèi)庫,如用于 Windows 窗體的 System.Windows.Forms 和用于數據庫管理的 System.Data,以及它們的公共方法、屬性和事件。它本身支持許多常見(jiàn)的任務(wù),如嚴格類(lèi)型、使用類(lèi)、調用 XML Web Service、實(shí)現結構化的異常處理等,而這些任務(wù)以前在 eMbedded Visual Basic 中需要開(kāi)發(fā)人員花費很多精力才能完成。

移植您的應用程序

對于現有的 eMbedded Visual Basic 代碼,并沒(méi)有自動(dòng)的升級方法,由于平臺和語(yǔ)言的差別較大,因此要成功、有效地設計和實(shí)現這種支持比較困難。移植工作主要包括以下幾個(gè)方面:

  • 語(yǔ)言的語(yǔ)法:eMbedded Visual Basic 是一種 Visual Basic Script 語(yǔ)言,因此語(yǔ)法區別有的很小,有的很大。
  • 公共代碼庫的實(shí)現:需要將現有的 eMbedded Visual Basic 公共代碼庫導出。由于現在支持使用類(lèi),因此在代碼庫的使用和實(shí)現上可能有所不同。而 .NET Compact Framework 是 .NET Framework 的子集,所以在 Pocket PC 的開(kāi)發(fā)中,可以使用現有的 Visual Basic .NET 類(lèi)庫。
  • 應用程序導航和控制流:窗體的管理和應用程序導航通過(guò) System.Windows.Forms 中的類(lèi)型來(lái)處理,其實(shí)現方式與 eMbedded Visual Basic 中的實(shí)現方式不同。
  • 數據庫:通過(guò) ADO.NET 的子集處理數據訪(fǎng)問(wèn)。Microsoft 為 Microsoft SQL Server™ 2000 Windows CE Edition 2.0 (SQL Server CE 2.0) 提供了一個(gè)托管數據提供程序。.NET Compact Framework 不包括用于訪(fǎng)問(wèn)本地數據庫(有時(shí)稱(chēng)為 CEDB 或 Pocket Access)的托管類(lèi)型,而 eMbedded Visual Basic 開(kāi)發(fā)人員卻經(jīng)常會(huì )用到。
  • XML Web Service:eMbedded Visual Basic 本身不支持調用遠程組件,調用和使用遠程組件需要第三方的支持。對 Web 服務(wù)的支持是 .NET Compact Framework 的核心類(lèi)型之一,被認為是整個(gè) .NET Framework 中的主要集成機制。大多數開(kāi)發(fā)項目中有關(guān)系統集成的工作量很大,因此,系統集成代碼極有可能要重寫(xiě)。
  • 異常處理:eMbedded Visual Basic 中的錯誤處理體現在四個(gè)詞上:“On Error Resume Next”,以及“沒(méi)完沒(méi)了”的 If Err.Number <> 0 Then 語(yǔ)句。而使用 Try ... Catch ... Finally 語(yǔ)句塊的有效的結構化異常處理,可以增強代碼的健壯性和容錯能力。

其他概要信息請參閱以下頁(yè)面:

Microsoft .NET Compact Framework
(http://msdn.microsoft.com/vstudio/device/compact.asp)

Frequently Asked Questions About Microsoft .NET Compact Framework
(http://msdn.microsoft.com/vstudio/device/compactfaq.asp)

Microsoft .NET Framework
(http://msdn.microsoft.com/netframework/)

GotDotNet .NET Smart Device Development
(http://www.gotdotnet.com/team/netcf/default.aspx)

開(kāi)發(fā)變化及改進(jìn)概述

平臺的改進(jìn)

eMbedded Visual Basic 中的開(kāi)發(fā)在獨立的環(huán)境中進(jìn)行,并使用 eMbedded Visual Basic 專(zhuān)用的運行時(shí)。用 .NET Compact Framework 代替 Visual Basic 運行時(shí)環(huán)境,意味著(zhù)開(kāi)發(fā)人員要重新學(xué)習新的平臺、語(yǔ)言和工具技能。大部分變化所帶來(lái)的主要益處來(lái)自于“公共”這個(gè)詞。.NET Compact Framework 與完整的 .NET Framework 有許多共同點(diǎn),包括:

  • 公共語(yǔ)言運行庫 (CLR):所有移動(dòng)應用程序開(kāi)發(fā)均使用相同的可執行程序運行時(shí)環(huán)境。CLR 提供程序加載、內存管理和其他的核心操作系統功能(圖 2)。
  • 公共類(lèi)型系統 (CTS):CTS 定義如何在運行時(shí)中聲明、使用和管理類(lèi)型,可以通過(guò)所有 .NET Framework 語(yǔ)言進(jìn)行訪(fǎng)問(wèn)。
  • 公共中間語(yǔ)言 (CIL):也稱(chēng)為 Microsoft Intermediate Language (MSIL),CIL 是一套獨立于 CPU 的指令集,這些指令集可以有效地轉換為本機代碼。

圖 2:“公共”之一:公共語(yǔ)言運行庫

實(shí)際的核心框架是操作系統和硬件。但是,這種平臺交叉方法并不表示編程工作的各個(gè)方面都具備了共同的基礎。平臺調用(圖 3)就是一種可以使托管代碼調用動(dòng)態(tài)鏈接庫 (DLL) 中實(shí)現的非托管函數的服務(wù),如 Windows CE API 中的非托管函數。幸運的是,Visual Studio .NET 開(kāi)發(fā)環(huán)境隱藏了這些復雜內容,只為開(kāi)發(fā)人員提供了合適的元素。開(kāi)發(fā)人員可以在開(kāi)始新項目時(shí)選擇目標平臺來(lái)實(shí)現此目的。

圖 3:在 Visual Studio .NET 中選擇目標平臺

開(kāi)發(fā)出的應用程序是實(shí)時(shí) (JIT) 編譯的,CLR 負責管理內存維護進(jìn)程 - 內存回收。對于使用 CreateObject 語(yǔ)句并由此可能導致內存泄漏的 eMbedded Visual Basic 開(kāi)發(fā)人員來(lái)說(shuō),這種內存維護進(jìn)程或者缺少工作進(jìn)程已經(jīng)成為一大問(wèn)題。從移動(dòng)解決方案的角度來(lái)看,最重要的平臺改進(jìn)體現在連接性。.NET Compact Framework 本身就支持主要的 Internet 協(xié)議(TCP IP、HTTP 等)和文檔標準(XML、SOAP 等),這就為連接的移動(dòng)應用程序奠定了基礎。

開(kāi)發(fā)環(huán)境的改進(jìn)

eMbedded Visual Basic 編程是在獨立的開(kāi)發(fā)環(huán)境中完成的。.NET Compact Framework 的開(kāi)發(fā)則是在 Visual Studio .NET 2003 中進(jìn)行的,這樣就可以共享完整的 .NET Framework 開(kāi)發(fā)環(huán)境。eMbedded Visual Basic 開(kāi)發(fā)人員可以看到與 Visual Studio 元素類(lèi)似的元素,注意到編輯器中的 IntelliSense、用戶(hù)界面設計器、強壯調試,以及直觀(guān)的編譯、部署及調試步驟等。對使用遠程 Web 服務(wù)和其他 .NET Framework 組件進(jìn)行的開(kāi)發(fā),提供了內置的支持,并且無(wú)縫地集成到了工具和語(yǔ)言中。

重要的語(yǔ)言改進(jìn)

從概念上講,eMbedded Visual Basic 和 Visual Basic .NET 有相同的起源,都是從普通的 Basic 語(yǔ)言進(jìn)化而來(lái)。對現代的 Visual Basic 開(kāi)發(fā)者來(lái)說(shuō),關(guān)鍵的語(yǔ)言結構和元素并沒(méi)有改變,重要的是引入了許多新特點(diǎn)。語(yǔ)言方面的改進(jìn)主要包括:

  • 基于 .NET Compact Framework 類(lèi)庫的開(kāi)發(fā)
  • 支持真正的面向對象設計
  • 結構化的異常處理
  • 多線(xiàn)程功能
  • 與其他語(yǔ)言的集成

但是,.NET Compact Framework 不支持與 COM 的互操作,這就意味著(zhù)必須重新開(kāi)發(fā)現有 COM 和 ActiveX 組件的包裝,并使用平臺調用 (P/Invoke) 來(lái)調用這些包裝。但如果使用 Odyssey Software 提供的第三方解決方案,開(kāi)發(fā)人員則可以在托管代碼中無(wú)縫地使用 COM 和 ActiveX 組件。

有關(guān)不同之處及改進(jìn)的詳細信息,請參閱
Ten Code Conversions for Visual Basics for Applications, Visual Basic .NET , and C# (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnoxpta/html/odc_tencodeconverts.asp)。

用戶(hù)界面和應用程序導航

這種新的開(kāi)發(fā)工具 (Visual Basic .NET) 將為您帶來(lái)前所未有的編碼體驗。由于該開(kāi)發(fā)環(huán)境繼承了 Visual Basic 和 eMbedded Visual Basic 開(kāi)發(fā)人員所熟悉的很多功能,因此過(guò)渡并不十分困難。許多熟悉的功能在新環(huán)境中仍然有效,例如雙擊按鈕,然后輸入“Click”事件的代碼。但從本質(zhì)來(lái)看,改變還是很大的。

在 eMbedded Visual Basic 中,許多步驟是開(kāi)發(fā)人員看不到的,如設計時(shí)屬性和事件的定義。另外,由于不是真正的面向對象環(huán)境,有些類(lèi)(窗體、控件)在首次使用時(shí)會(huì )自動(dòng)實(shí)例化。而在 Visual Basic .NET 中,在設計器中對窗體進(jìn)行的所有處理都反映在代碼中。窗體和控件是必須進(jìn)行聲明的對象,并且要在代碼中實(shí)例化。

窗體的基本知識

現在,讓我們來(lái)看一個(gè)設計器中的窗體示例(圖 4)。(請注意,圖中只顯示了窗體的上半部分。)

圖 4:示例窗體

使用窗體設計器創(chuàng )建窗體之后,用來(lái)聲明窗體中控件的生成代碼如下所示:

Friend WithEvents Label1 As System.Windows.Forms.LabelFriend WithEvents TextBox1 As System.Windows.Forms.TextBoxFriend WithEvents Button1 As System.Windows.Forms.Button

用來(lái)創(chuàng )建控件的生成代碼如下所示:

Me.Label1 = New System.Windows.Forms.LabelMe.TextBox1 = New System.Windows.Forms.TextBoxMe.Button1 = New System.Windows.Forms.Button

最后,設置這些控件的屬性的生成代碼如下所示:

Me.Label1.Location = New System.Drawing.Point(8,11)Me.Label1.Size = New System.Drawing.Size(48,16)Me.Label1.Text = "Label1"Me.TextBox1.Location = New System.Drawing.Point(56,8)Me.TextBox1.Size = New System.Drawing.Size(104,22)Me.TextBox1.Text = "TextBox1"Me.Button1.Location = New System.Drawing.Point(168,8)Me.Button1.Size = New System.Drawing.Size(64,24)Me.Button1.Text = "Button1"Me.Controls.Add(Me.Button1)Me.Controls.Add(Me.TextBox1)Me.Controls.Add(Me.Label1)Me.Text = "Form1"

每個(gè)控件的位置、大小和內容(Text 屬性)均被設定,請注意,生成的代碼實(shí)際上將控件添加到了窗體中。一個(gè)很重要的細節是,現在所有的控件都具有 Text 屬性(窗體和標簽沒(méi)有 Caption 屬性)。

還需要一些控件來(lái)保存額外的元數據(像設計時(shí)的控件屬性和其他資源,如圖片),這些數據保存在與窗體同名的資源文件(在以上的示例中為 Form1.resx)中。

為窗體生成的其余代碼則創(chuàng )建窗體的基本結構。首先,像聲明其他類(lèi)一樣聲明窗體,并從 .NET Compact Framework 提供的基本 Windows 類(lèi)中繼承窗體:

Public Class Form1 : Inherits System.Windows.Forms.Form

以上的代碼實(shí)際是兩行,為了便于閱讀,將這兩個(gè)語(yǔ)句放在了一行。創(chuàng )建窗體后,調用構造函數,代碼如下所示:

Public Sub New()MyBase.New()InitializeComponent()End Sub

構造函數按要求調用基類(lèi)構造函數,然后又按要求調用生成的私有函數 (Sub InitializeComponent),該函數的代碼用于創(chuàng )建控件并設置屬性,如上所示。窗體設計器需要 InitializeComponent 函數,而該函數的代碼需要謹慎處理。

開(kāi)始編寫(xiě)應用程序時(shí),在“Project Properties”(項目屬性)對話(huà)框中將窗體 Form1 定義為“Startup object”(右擊“Solution Explorer”[解決方案資源管理器] 中的項目,選擇“Properties”[屬性]),定義方法與 eMbedded Visual Basic 中的方法類(lèi)似。

Pocket PC 和 Smartphone 的開(kāi)發(fā)

事件

設計應用程序中的窗體時(shí),應該為控件創(chuàng )建事件處理程序。與在 eMbedded Visual Basic 中一樣,可以雙擊控件以創(chuàng )建默認的事件處理程序。如果我們繼續上面的示例,雙擊其中的按鈕,將生成 Click 事件的事件處理程序:

Private Sub Button1_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles Button1.ClickMessageBox.Show("Text on button is: " & Button1.Text)End Sub

事件過(guò)程的各個(gè)參數總是一樣的。參數“sender”是對觸發(fā)事件的對象的引用,參數“e”針對不同的事件類(lèi)型。它通常包含有關(guān)所觸發(fā)事件的數據,這些數據在 eMbedded Visual Basic 中是獨立的事件參數。請注意,聲明的結尾有一個(gè)特殊的關(guān)鍵字 (Handles),它用于指明使用該事件的控件。一個(gè)需要注意的地方是,關(guān)鍵字 Handles 接受多個(gè)參數,也就是說(shuō),可以利用這一點(diǎn)讓同一個(gè)事件處理程序來(lái)處理多個(gè)控件的事件。讓我們向窗體再添加一個(gè)按鈕 (Button2),并修改事件處理程序的代碼:

Private Sub Button1_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles Button1.Click,Button2.ClickMessageBox.Show("Text on button is: " & CType(sender,Button).Text)End Sub

現在,事件處理程序可以處理兩個(gè)按鈕的 Click 事件。請注意,“sender”參數用于獲取觸發(fā)事件的按鈕對象。

添加和刪除事件的方法與在 eMbedded Visual Basic 中的方法非常相似。要添加其他事件處理程序,只需在代碼窗口右上角的方法名稱(chēng)下拉列表中選擇即可。要刪除事件處理程序,只需刪除事件處理代碼即可。另外,與在 eMbedded Visual Basic 一樣,當把控件從一個(gè)窗體復制到另一窗體時(shí),必須手動(dòng)復制事件處理程序代碼。

外觀(guān)

要遷移到 Visual Basic .NET 的 eMbedded Visual Basic 開(kāi)發(fā)人員經(jīng)常會(huì )問(wèn)這樣一個(gè)問(wèn)題:如何控制任務(wù)欄右上角的按鈕?創(chuàng )建新窗體時(shí),默認設置將顯示一個(gè)智能最小化按鈕(看起來(lái)象一個(gè) X),這個(gè)按鈕不會(huì )關(guān)閉窗口,但會(huì )將窗口放在后臺(不可見(jiàn),但仍在運行)。這是因為默認情況下窗體的 Minimize 屬性設置為 True。由于 ControlBox 屬性默認也設置為 True,要顯示 OK 按鈕,只需將 Minimize 屬性設置為 False。如果希望在點(diǎn)擊 OK 按鈕后、關(guān)閉窗體前添加事件(例如驗證),可以向窗體添加一個(gè) Closing 事件處理程序。繼續以該示例為例,窗體的 Minimize 屬性設置為 False,并添加以下的事件處理程序:

Private Sub Form1_Closing(ByVal sender As Object, _ByVal e As System.ComponentModel.CancelEventArgs) _Handles MyBase.ClosingIf TextBox1.Text <> "TextBox1" ThenMessageBox.Show("Text in TextBox cannot be changed!")e.Cancel = TrueEnd IfEnd Sub

該示例顯示了如何在 TextBox 中的文字被改變時(shí)防止窗體關(guān)閉。請注意,示例是如何使用第二個(gè)參數 (e) 來(lái)處理事件特定的值(屬性)的。

另一個(gè)需要特別注意的地方是,需要向窗體添加一個(gè)菜單(實(shí)際上是 MainMenu)控件,以使底部的菜單欄和 SIP (軟輸入面板)可見(jiàn)。創(chuàng )建新項目時(shí),會(huì )在生成的第一個(gè)窗體中添加一個(gè)菜單控件,但是在添加新窗體時(shí),必須手動(dòng)添加菜單。

要使您的應用程序看起來(lái)與其他 Pocket PC 應用程序一樣,還要遵循以下原則:

  • 一定要將應用程序名稱(chēng)放到所有窗體的標題中(窗體的 Text 屬性)。
  • 在子窗體中,在窗體的左上角(最好在 X=8,Y=5 的位置)添加一個(gè) Label 控件,其名稱(chēng)與對話(huà)框的名稱(chēng)相同。在該標簽下面,添加一條單點(diǎn)線(xiàn),長(cháng)度等于窗體的寬度。建議使用 Panel 控件,將其高度設置為 1,寬度設置為 240(最好在 X=0,Y=23 的位置)。
  • 要將 Label 控件與 TextBox 控件中的文字對齊,Label 的位置要低于 TextBox 3 個(gè)像素(TextBox 的 Y 值加 3)。

有關(guān)用戶(hù)界面的其他注意事項,請參閱 Visual Basic .NET 的幫助文件和通用的 Pocket PC 設計原則 (http://www.microsoft.com/mobile/assets/Design_PocketPC.pdf)。

窗體導航和互操作

只包含一個(gè)窗體的應用程序很少見(jiàn),所以,讓我們來(lái)看一下如何在不同的窗體間導航,這是很常用的。我們仍使用以上示例,再添加另一個(gè)窗體(選擇菜單選項“Project”[項目],“Add Windows Form”[添加 Windows 窗體],接受默認名稱(chēng) Form2)。第一步是添加一個(gè) MainMenu 控件,以使底部菜單欄可見(jiàn),然后也將窗體的 Minimize 屬性改變?yōu)?False,以使右上角的 OK 按鈕可見(jiàn)。創(chuàng )建子窗體時(shí)最好也這樣做,這種習慣有助于節省調試時(shí)間。

生成新窗體的最簡(jiǎn)單的方法是將這段代碼添加到第一個(gè)窗體的按鈕上:

Dim secondForm As Form2secondForm = New Form2secondForm.ShowDialog()

如前所述,與在 eMbedded Visual Basic 中相反,必須先創(chuàng )建所有類(lèi)的實(shí)例,然后才能使用它們,包括窗體。

根據所加載的窗體的大小,您可能希望在加載窗體的過(guò)程中看到等待光標,您可以將下面一行代碼放到調用 ShowDialog 的代碼之前:

Cursor.Current = Cursors.WaitCursor

然后,應該在窗體加載完畢時(shí)刪除等待光標。為此,可以在第二個(gè)窗體的構造函數中添加以下代碼:

Public Sub New()MyBase.New()InitializeComponent()Cursor.Current = Cursors.DefaultEnd Sub

但是,如果第二個(gè)窗體 (Form2_Load) 的 Load 事件處理程序包含大量初始化過(guò)程,例如加載控件的值,則最好在 Load 事件處理程序的結尾恢復光標。

一個(gè)常會(huì )遇到的問(wèn)題是不同窗體間的通信。調用 ShowDialog 可以提供最簡(jiǎn)單的通信形式。ShowDialog 可以返回任意預定義的結果代碼(OK、Cancel、Yes、No、Abort、Retry、Ignore 和 None)。在第一個(gè)窗體中,可以將代碼更改為:

MessageBox.Show ("You selected: " +secondForm.ShowDialog().ToString())

這將顯示第二個(gè)窗體返回的結果代碼。有兩種方法可以從第二個(gè)窗體返回該值:設置按鈕的 DialogResult 屬性,或者設置窗體本身的 DialogResult 屬性。如果在第二個(gè)窗體中添加了按鈕(名為 btnCancel),可以在構造函數中添加以下代碼來(lái)設置該屬性:

btnCancel.DialogResult = DialogResult.Cancel

請注意,設計器中未提供該屬性,只能用代碼來(lái)設置。如果將第二個(gè)窗體的 Minimize 屬性改為 False,則將從窗體返回兩組結果代碼:按右上角的 OK 按鈕返回 OK,按 btnCancel 按鈕返回 Cancel。

根據通用的 Pocket PC 用戶(hù)界面設計原則(參閱上文),應用程序應該在“Running Programs”(正在運行的程序)列表(“Memory Setting”[內存設置] 中的選項卡)中只顯示一個(gè)實(shí)例。但是,如果在第一個(gè)窗體可見(jiàn)(在第二個(gè)下面)的情況下打開(kāi)第二個(gè)窗體,則“Running Programs”(正在運行的程序)列表中將顯示這兩個(gè)窗體。因此,需要在第二個(gè)窗體可見(jiàn)時(shí)隱藏第一個(gè)窗體。在第一個(gè)窗體中調用 Hide 方法可以隱藏窗體,方法是在第一個(gè)窗體中調用 Me.Hide(),然后調用 ShowDialog 和 Me.Show()。但是,這樣做也存在一些問(wèn)題。如果第二個(gè)窗體的加載時(shí)間過(guò)長(cháng),則在窗體的轉換過(guò)程中將看不到任何窗體(這對應用程序用戶(hù)來(lái)說(shuō)有些不方便),在上面的例子中,“You selected ... ”消息框就是在不顯示任何窗體的情況下顯示的。更為可行的處理方法是讓第二個(gè)窗體隱藏第一個(gè)窗體。為此,第二個(gè)窗體需要以某種方式接收第一個(gè)窗體的實(shí)例。要傳遞此信息,最明顯的方法是使用第二個(gè)窗體的構造函數。在第二個(gè)窗體中,添加一個(gè)私有類(lèi)變量以保存第一個(gè)窗體的實(shí)例:

Private firstForm As Form1

用新參數更新構造函數,并使用以下代碼將該參數保存到私有變量:

Public Sub New(ByVal firstForm As Form1)Me.firstForm = firstForm‘ 其他代碼...End Sub

現在,第一個(gè)窗體中用來(lái)實(shí)例化第二個(gè)窗體的代碼行變?yōu)椋?/p>

secondForm = New Form2(Me)

這樣,第二個(gè)窗體現在就“了解”了第一個(gè)窗體,并且可以調用它:

firstForm.Hide()

最好在窗體的 Load 事件 (Form2_Load) 結束后再使用它。在窗體的 Closing 事件 (Form2_Closing) 中,可以使用以下代碼再次顯示第一個(gè)窗體:

firstForm.Show()

這樣一來(lái),窗體間的過(guò)渡就比較平滑,而且過(guò)渡不會(huì )造成任何性能問(wèn)題,如不會(huì )影響加載或關(guān)閉第二個(gè)窗體所用的時(shí)間。這是一種在窗體間通信的好方法。向第二個(gè)窗體的構造函數添加多少個(gè)參數都不會(huì )出現問(wèn)題,因此,可以從第一個(gè)窗體向第二個(gè)窗體傳遞任意的數據。但是,如何將數據從第二個(gè)窗體傳遞回第一個(gè)窗體呢? 我們知道,可以用結果代碼通知第一個(gè)窗體(如上所述),但是,要傳遞回數據還需要其他方法。在上面的代碼中,您可能已經(jīng)注意到了變量 firstForm(及其參數)被聲明為 Form1,而不是基類(lèi)型 Form??梢赃@樣做是由于 Hide 和 Show 方法都是基類(lèi)型 Form 的一部分。但是,如果變量 firstForm 被聲明為類(lèi)型 Form1,則 Form1 類(lèi)就可以實(shí)現一個(gè)公共(或相當友好的)方法,能夠被第二個(gè)窗體調用,以將數據傳遞回第一個(gè)窗體。

我們還以上面的示例為例,將以下方法添加到第一個(gè)窗體:

Friend Sub Form2Data(ByVal text As String)textFromForm2 = textEnd Sub

textFromForm2 是 Form1 中被私自聲明的類(lèi)變量。以下是修改后的按鈕 Click 事件的代碼,此按鈕用來(lái)加載第二個(gè)窗體:

Dim secondForm As Form2Dim result As DialogResultCursor.Current = Cursors.WaitCursorsecondForm = New Form2(Me)result = secondForm.ShowDialog()MessageBox.Show("You selected: " + result.ToString())If result = DialogResult.OK ThentxtFromForm2.Text = textFromForm2End If

用來(lái)顯示第二個(gè)窗體中的數據的 TextBox 控件名為 txtFromForm2。

在第二個(gè)窗體中,將以下代碼添加到 Closing 事件 (Form2_Closing):

firstForm.Form2Data(TextBox1.Text)

該方法允許將任何數據從第二個(gè)窗體傳遞到第一個(gè)窗體。

應用程序導航對于增加應用程序的可用性十分重要。通過(guò)學(xué)習以上內容,您現在應該了解了在窗體間高效導航和傳遞數據的方法。

大多數企業(yè)移動(dòng)解決方案是對現有系統的擴展。因此,這種解決方案體系結構面臨的主要問(wèn)題是它如何與現有的 IT 系統集成。

應用程序集成

集成策略

集成包括兩個(gè)方面:集成模式(如何集成)和連接頻率(每隔多久連接一次)。

集成模式

目前,許多商用 Pocket PC 應用程序根本沒(méi)有實(shí)現連接。因此稱(chēng)之為“獨立式”應用程序,它們不具備集成能力。但是,隨著(zhù)連接的設備日益增多,集成就成了一個(gè)關(guān)鍵問(wèn)題。隨之而來(lái)的另一個(gè)問(wèn)題就是“如何集成?”。最常見(jiàn)的集成體系結構模式包括:

  • 設備數據到服務(wù)器數據:設備上的數據庫直接與服務(wù)器數據庫同步。如果數據同步所涉及的邏輯較少,可以采用這種模式,因為這樣做可以獲得很好的性能。
  • 設備邏輯到服務(wù)器邏輯:設備應用程序連接到服務(wù)器的組件。這是最常用的方法,因為大多數同步都會(huì )涉及業(yè)務(wù)邏輯。
  • 設備邏輯到服務(wù)器數據:設備直接連接到服務(wù)器數據庫。如果涉及的邏輯不太多而且帶寬足夠用時(shí),可以考慮使用這種方法。
  • 僅服務(wù)器:使用設備瀏覽器連接到服務(wù)器端的 Web 應用程序。由于所有基于客戶(hù)端 (Web) 的應用程序都比較小,因此這也是一種不錯的選擇,但是很顯然,這樣做需要設備與服務(wù)器始終保持連接。

最后一種方法并不是真正的集成方法,我們將其作為集成方法,是想說(shuō)明有時(shí)侯可用的帶寬對始終聯(lián)機的應用程序來(lái)說(shuō)是足夠的。坦率地講,這種方法不是最佳方法。這些模式用到的技術(shù)包括:

  • 設備數據到服務(wù)器數據:SQL Server CE .NET 的 Remote Data Access 和 Merge Replication
  • 設備邏輯到服務(wù)器邏輯:Web 服務(wù)
  • 設備邏輯到服務(wù)器數據:SQL Server .NET Provider
  • 僅服務(wù)器:Visual Studio .NET 2003 中的 Mobile Device Programmability

如上所述,使用這些模式實(shí)現應用程序所需的大多數技術(shù)都是現成的。

連接頻率

另一個(gè)關(guān)鍵問(wèn)題是解決方案要求的網(wǎng)絡(luò )相關(guān)性。傳統的選項是或者選擇脫機,或者選擇聯(lián)機,現在,這種方式已經(jīng)不能滿(mǎn)足要求了。根據不同的使用環(huán)境,更傾向于選擇脫機和聯(lián)機之間的某種狀態(tài)。

最重要的連接頻率包括:

  • 很少:大多數時(shí)間,應用程序都可以脫機工作,只有當并發(fā)(許多用戶(hù)使用相同的數據)很少或根本沒(méi)有時(shí)需要以一定的間隔進(jìn)行同步,因此需要的帶寬較少,只在一定的時(shí)間段才要求很高的帶寬(如在辦公室時(shí))。
  • 自動(dòng):它與“很少”(參閱前一項)很相似,但是應用程序中包括用于確定何時(shí)需要同步的邏輯。
  • 經(jīng)常:應用程序頻繁向服務(wù)器發(fā)出調用以發(fā)送或接收數據。由于應用程序只是來(lái)回傳輸數據,因此不需要連續的連接,需要的帶寬也就相對較低。如果帶寬的使用成本與發(fā)送的字節數有關(guān),那么這是一個(gè)不錯的選擇。
  • 始終:這適用于需要保持連接才能工作的聯(lián)機(大多數是 Web)應用程序。

不同時(shí)間段內可用的帶寬對于確定方案中要傳輸的數據量也很重要。最常見(jiàn)的選項包括:

  • 高(WLAN/Wi-Fi = 11 Mb 或更高)
  • 低 (WAN/GPRS = 43.2 Kb)
  • 最低(WAN/CDMA = 4.8 Kb 或 WAN/GSM = 9.6 Kb)

做出選擇

以上選項的任一組合不可能滿(mǎn)足所有方案,但是在評價(jià)各種方案時(shí),都需要將這些選項作為考慮的因素。對 eMbedded Visual Basic 開(kāi)發(fā)人員來(lái)說(shuō),可以完成上面提到的大多數同步選項(大多數時(shí)候要使用一些中間件)。使用 SQL Server for Windows CE 的 Remote Data Access 或 Merge Replication 進(jìn)行的數據庫同步與使用 Visual Basic .NET 進(jìn)行的同步非常相似。到服務(wù)器數據庫的直接連接與在臺式機中使用 Visual Basic .NET 的方法也非常相似,實(shí)際上,創(chuàng )建聯(lián)機 (Web) 應用程序與 eMbedded Visual Basic 的關(guān)系不大。因此,最需要考慮的選項是使用 Web 服務(wù)來(lái)連接服務(wù)器組件。

基于 XML 的 Web 服務(wù)

簡(jiǎn)言之,Web 服務(wù)是一種使用可擴展標記語(yǔ)言 (XML) 以及超文本傳輸協(xié)議 (HTTP)(大多數情況下)調用(請求/響應)方法的方法。Web 服務(wù)的總體目標是應用程序集成,它可以在公司內部應用程序中使用,也提供了連接到不同公司的系統的方法。Web 服務(wù)會(huì )取得成功有兩大原因:一是它構建的基礎是一些公認的標準(HTTP、XML、SOAP、WSDL、UDDI 等),二是大多數大公司(IBM、Microsoft、Sun、Oracle 等等)都在使用它。

為擴展 Web 服務(wù)簡(jiǎn)單對象訪(fǎng)問(wèn)協(xié)議 (SOAP) 的功能而做的大量工作稱(chēng)為全局 XML 體系結構 (Global XML Architecture [GXA])。GXA 不是產(chǎn)品,而是一系列應用程序規范的統稱(chēng),包括 Web 服務(wù)發(fā)現 (WS-Inspection)、安全調用 (WS-Security)、定義消息和備用路徑 (WS-Routing/WS-Referral)、支持事務(wù)處理 (WS-Transaction) 以及發(fā)送二進(jìn)制附件 (WS-Attachments)。GXA 的基石是 Web Services Enhancements (http://msdn.microsoft.com/webservices/building/wse/),它包括這些規范的 .NET Framework 實(shí)現。

連接到服務(wù)器組件

eMbedded Visual Basic 未提供本機方法來(lái)輕松地連接到服務(wù)器組件,開(kāi)發(fā)人員必須依賴(lài)第三方的中間件組件以實(shí)現此功能。這樣的中間件產(chǎn)品有很多,其中效果最好的是那些使用組件類(lèi)似于使用本機方法的產(chǎn)品。例如使用 Odyssey Software 公司的 CEfusion,eMbedded Visual Basic 開(kāi)發(fā)人員可以在服務(wù)器上創(chuàng )建對象,然后就像在臺式機上使用 DCOM(分布式組件對象模型)一樣來(lái)使用它們。在 CEfusion 中,傳輸數據時(shí)要使用 Recordset,與臺式機中的 Recordset 幾乎完全相同。而 Visual Basic .NET 就提供了使用 Web 服務(wù)集成應用程序的本機方法。服務(wù)器上的組件可以使用簡(jiǎn)單協(xié)議(如 XML 和 HTTP)來(lái)發(fā)布它們的功能。Visual Basic .NET 和 .NET Compact Framework 都內置了對 Web 服務(wù)的支持,我們從下文可以看出,這種支持不僅使應用程序集成成為可能,而且集成方法簡(jiǎn)單、有效。

發(fā)布 Web 服務(wù)

在服務(wù)器上使用 Visual Studio .NET 創(chuàng )建 Web 服務(wù)的過(guò)程很簡(jiǎn)單,Web 服務(wù)也可用來(lái)發(fā)布 .NET Framework 和組件對象模型 (COM) 組件。有現成的模板可以創(chuàng )建 Active Server Page (ASP) .NET Framework Web 服務(wù)項目。MSDN (http://msdn.microsoft.com/) 中提供了很多好的資源,可以創(chuàng )建 Web 服務(wù)。

有關(guān)在 .NET Framework 中創(chuàng )建 Web 服務(wù)的最佳指南,請參閱 Getting Started with XML Web Services in Visual Basic.NET and Visual C# (http://msdn.microsoft.com/library/en-us/dv_vstechart/html/vbtchGetting StartedWithXMLWebServicesInVisualStudioNET.asp),有關(guān)在 .NET 中使用 COM 組件的內容,請參閱 Visual Basic .NET documentation (http://msdn.microsoft.com/library/en-us/vbcn7/html/vaconIntroductionToCOMInteroperability.asp)。

由于 .NET Framework 對 COM 互操作提供了非常有效的支持,封裝 COM 組件的效率要比將現有組件記錄到本機 .NET Framework 組件的效率高出許多倍。

即使服務(wù)器沒(méi)有提供 .NET Framework,借助 Microsoft SOAP Toolkit (http://www.microsoft.com/downloads/details.aspx?FamilyID=ba611554-5943-444c-b53c-c0a450b7013c&DisplayLang=en),您也可以將 COM 組件發(fā)布為 Web 服務(wù)。

許多其他服務(wù)器平臺允許將服務(wù)器組件發(fā)布為 Web 服務(wù),因此,您可以將移動(dòng)解決方案與運行在各種平臺上的大多數現有系統相集成。

客戶(hù)端基礎知識

讓我們從一個(gè)非常簡(jiǎn)單的 Web 服務(wù)開(kāi)始,即一個(gè)使用 Visual Basic .NET 在客戶(hù)端實(shí)現的 Web 服務(wù)。為了說(shuō)明該示例現有的功能,示例中使用了一個(gè)公共的(免費)Web 服務(wù)。在新項目中,添加一個(gè) Web 引用(菜單項“Project”[項目] 和“Add Web Reference”[添加 Add Web 引用]),該示例使用一個(gè)免費的公共 Web 服務(wù)來(lái)檢查信用卡號的有效性。圖 5 顯示了窗體的外觀(guān)。(請注意,圖中只顯示了窗體的上半部分。)

圖 5:Web 服務(wù)示例窗體

創(chuàng )建新的 Visual Basic .NET 項目后,只需要改變窗體和控件的 Name 和 Text 屬性。改變這些屬性是為了反映更恰當的值。要創(chuàng )建對 Web 服務(wù)的引用,請選擇菜單項“Project”(項目)、“Add Web Reference”(添加 Web 引用),然后添加 Web 服務(wù)的 URL(本示例使用的 URL 為 http://secure.cdyne.com/creditcardverify/luhnchecker.asmx)。

在按鈕的 Click 事件中,添加以下代碼:

Dim CreditCardWS As New cdyne.LUHNCheckerDim Result As cdyne.ReturnIndicatorResult = CreditCardWS.CheckCC(txtCreditCardNumber.Text)MessageBox.Show("Card type: " & Result.CardType & _Microsoft.VisualBasic.vbCrLf & _"Card valid:" & IIf(Result.CardValid, "Yes", "No"))

請注意,Web 引用的名稱(chēng)改為“cdyne”(建議的名稱(chēng),實(shí)際上是域 URL 的反向,但這樣不太方便)。當設定對 Web 服務(wù)的引用后,就可以將 Web 服務(wù)類(lèi)型當作應用程序中的任意類(lèi)型來(lái)看待。

Web 服務(wù)可能返回一個(gè)基本類(lèi)型(String、Integer 等),但也可能如本示例所示,返回一個(gè)可以轉換為 Visual Basic .NET 類(lèi)的復雜類(lèi)型。在本示例中,這個(gè)類(lèi)是有兩個(gè)成員(CardType 和 CardValid)的 ReturnIndicator。

如果您想看一下該應用程序的具體內容,請單擊“Solution Explorer”(解決方案資源管理器)中的“Show All Files”(顯示所有文件),然后找到 Reference.vb 文件(在 Reference.map 文件下面)。找到該文件的代碼之后,您就可以看到 Web 服務(wù)和此復雜類(lèi)型是如何聲明為真正的 .NET Framework 類(lèi)的。

“吵鬧的”交互與“臃腫的”交互

該示例還說(shuō)明了在使用 Web 服務(wù)時(shí)會(huì )遇到的一個(gè)有趣情況。由于返回值是一個(gè)復雜類(lèi)型,因此在一次調用中可以返回多個(gè)值。如果需要使用多個(gè)調用以獲取各個(gè)值,從性能上考慮,這種解決方案通常是首選方案。但是,如果一次調用中返回的數據量非常大,則僅通過(guò)一次調用來(lái)返回所有數據可能會(huì )出現問(wèn)題。這種問(wèn)題一般稱(chēng)為“吵鬧的”交互與“臃腫的”交互。“吵鬧的”交互是指為完成一項任務(wù)而執行過(guò)多的調用,“臃腫的”交互是指每次調用都包含大量數據。而在許多移動(dòng)應用程序中,帶寬一般是有限制的,所以,如果帶寬較低,必須特別注意,謹慎選擇最優(yōu)的解決方案。

DataSet 集成

在 eMbedded Visual Basic 中處理數據的最方便結構是 ActiveX Data Objects (ADO) Recordset。Visual Basic .NET 中與之相對應但又完全不同的結構是 DataSet(有關(guān) Recordset 和 DataSet 之間的區別的詳細信息,請參閱后面的“使用數據庫”一節)。簡(jiǎn)言之,DataSet 是一種不連接的數據容器,可將其數據提取為 XML,這在與 Web 服務(wù)結合使用時(shí)十分有用。

要了解如何使用 Web 服務(wù)和 DataSet 來(lái)集成服務(wù)器組件,讓我們使用 .NET Framework 工具創(chuàng )建一個(gè) Web 服務(wù)。在 Visual Studio .NET 中,創(chuàng )建一個(gè)類(lèi)型為“ASP.NET Web Service”、名稱(chēng)為“DataSetWS”的新項目。為了說(shuō)明在 .NET Framework 中集成與所用的語(yǔ)言無(wú)關(guān),此 Web 服務(wù)被創(chuàng )建為 C# 項目。但愿這段代碼不是很難,即便是沒(méi)有 C# 使用經(jīng)驗的讀者也可以理解。創(chuàng )建新項目后,添加以下代碼:

[WebMethod]public DataSet GetEmployees(int EmployeeID){SqlConnection con;SqlDataAdapter da;DataSet ds;con = new SqlConnection("data source=(local);initialcatalog=Northwind;" +"uid=sa;pwd=");con.Open();if (EmployeeID > 0)da = new SqlDataAdapter("SELECT EmployeeID,LastName,FirstName, " +"HomePhone FROM Employees WHERE EmployeeID="+EmployeeID.ToString(),con);elseda = new SqlDataAdapter("SELECT EmployeeID,LastName,FirstName, " +"HomePhone FROM Employees",con);ds = new DataSet("Employees");da.Fill(ds,"Employees");return ds;}

這個(gè)示例中使用的數據庫是 SQL Server 中的示例數據庫:Northwind。Web 服務(wù)方法 (GetEmployees) 接受一個(gè)參數 (EmployeeID),并返回一個(gè) DataSet。創(chuàng )建連接并打開(kāi)后,需要進(jìn)行檢查以確定所提供的員工身份是否有效(大于零)。如果有效,將從數據庫中選出一名特定的員工;如果無(wú)效,則檢索所有員工。查詢(xún)結果保存在 DataSet 的表中(DataSet 和表的名稱(chēng)都為“Employees”),而 DataSet 則返回調用者。請注意,只有必要的字段從數據庫查詢(xún)返回,以盡量減少數據量。構建項目時(shí),您可以利用 Web 服務(wù)從您的“服務(wù)器”(可能是您開(kāi)發(fā)所使用的計算機)獲取員工信息。

現在,讓我們進(jìn)一步擴展上面的示例,向窗體添加一些項目,完成后的情形如下所示(圖 6):

圖 6:DataSet Web 服務(wù)示例窗體

新項目包括一個(gè)標簽和一個(gè)文本框(名為“txtEmployeeID”),用于輸入員工身份;一個(gè)按鈕,用于調用 Web 服務(wù);一個(gè)列表視圖(名為“lvwEmployees”),用于保存返回員工的數據。如果文本框中未輸入員工身份,將返回所有員工的數據。列表視圖中包含三列(姓名、電話(huà)、ID),最后一列是隱藏的(寬度為 0)。

添加 Web 引用后(使用新創(chuàng )建的 Web 服務(wù)的 URL 進(jìn)行添加),將以下代碼添加到 Get 按鈕的 Click 事件:

Dim DataSetWS As New server.NETCFDim ds As DataSetDim iEmployeeID As Integer = 0Dim dr As DataRowDim lvi As ListViewItemIf IsNumeric(txtEmployeeID.Text) TheniEmployeeID = Convert.ToInt32(txtEmployeeID.Text)End Ifds = DataSetWS.GetEmployees(iEmployeeID)If ds.Tables(0).Rows.Count < 1 ThenMessageBox.Show("No Employee(s)found!")ElselvwEmployees.Items.Clear()For Each dr In ds.Tables(0).Rowslvi = New ListViewItem(dr("FirstName").ToString() & " " & _dr("LastName").ToString())lvi.SubItems.Add(dr("HomePhone").ToString())lvi.SubItems.Add(dr("EmployeeID").ToString())lvwEmployees.Items.Add(lvi)NextEnd If

首先,創(chuàng )建 Web 服務(wù)(在本例中,Web 服務(wù)被引用為“server”,服務(wù)器中 Web 服務(wù)類(lèi)的名稱(chēng)為“NETCF”),完成其他聲明后,檢查是否在文本框 (txtEmployeeID) 中添加了員工身份。如果未提供身份,則在調用 Web 服務(wù)時(shí)使用默認值 (0)。檢查返回的 DataSet (ds) 是否包含行,如果包含,將這些行添加到列表視圖中。需要注意的是,第三列用于檢索員工的身份,如果要從列表視圖的某一行獲取更多的員工信息,可以利用這一列。

這種方法對于在服務(wù)器和客戶(hù)端之間傳輸關(guān)系型數據十分方便,如果考慮完成這種任務(wù)所需的代碼量,最好的選擇就是利用 .NET Framework 中提供的支持。檢查傳輸的數據之后,您會(huì )發(fā)現,不僅傳輸了數據,還傳輸了元數據(字段類(lèi)型、長(cháng)度等)。

異步 Web 服務(wù)調用

根據上文有關(guān)“吵鬧”和“臃腫”的論述,很顯然,XML 格式的數據會(huì )很容易變得非常“臃腫”。因此,應該盡可能地減少發(fā)送的數據量(如以上示例中只選擇需要的列)。有時(shí)需要在不鎖定設備的情況下傳輸大量數據,這時(shí),就需要使用異步 Web 服務(wù)調用。

仍然以上面的示例代碼為例,再添加一個(gè)按鈕(名為“btnGetAsync”),然后向該按鈕的 Click 事件添加以下代碼:

Dim DataSetWS As server.NETCF = New server.NETCFDim iEmployeeID As Integer = 0aDim cb As AsyncCallbackbtnGetAsync.Enabled = FalselvwEmployees.Items.Clear()If IsNumeric(txtEmployeeID.Text) TheniEmployeeID = Convert.ToInt32(txtEmployeeID.Text)End Ifcb = New AsyncCallback(AddressOf GetAsyncReturn)DataSetWS.BeginGetEmployees(iEmployeeID,cb,DataSetWS)

大部分代碼都與上文介紹的同步調用代碼相同,但這一次在調用過(guò)程中禁用了按鈕。這是通知用戶(hù)操作處于激活狀態(tài)的最方便的方法。最重要的區別是,在對 Web 服務(wù) (BeginGetEmployees) 的異步調用中使用了異步回調變量 (cb)。

這個(gè)回調變量 (cb) 其實(shí)是一個(gè)指向公共函數的函數指針,其代碼如下:

Public Sub GetAsyncReturn(ByVal ar As IAsyncResult)Dim DataSetWS As server.NETCFDim ds As DataSetDim i As Integer = 0Dim dr As DataRowDim lvi As ListViewItemDataSetWS = ar.AsyncStateds = DataSetWS.EndGetEmployees(ar)If ds.Tables(0).Rows.Count < 1 ThenMessageBox.Show("No Employee(s) found!")ElseFor Each dr In ds.Tables(0).Rowslvi = New ListViewItem(dr("FirstName").ToString() & " "& _dr("LastName").ToString())lvi.SubItems.Add(dr("HomePhone").ToString())lvi.SubItems.Add(dr("EmployeeID").ToString())lvwEmployees.Items.Add(lvi)NextEnd IfbtnGetAsync.Enabled = TrueEnd Sub

大部分聲明與同步調用中的相同,但是需要注意的是,Web 服務(wù) (DataSetWS) 并沒(méi)有在聲明中進(jìn)行實(shí)例化,而是從異步狀態(tài)參數 (ar) 中檢索實(shí)例。通過(guò)最后調用 Web 服務(wù) (EndGetEmployees) 來(lái)檢索返回的 DataSet (ds)。按照以前的方法填充列表視圖后,重新啟用按鈕。

有意思的是,在調用按鈕 Click 事件的執行和調用 GetAsyncReturn 的過(guò)程中,用戶(hù)可以與應用程序正常交互。盡管檢索得到的數據相同,但是這會(huì )給用戶(hù)帶來(lái)新的體驗。

集成優(yōu)化

盡管能夠異步調用 Web 服務(wù),還能給用戶(hù)帶來(lái)更為愉悅的使用體驗,但傳輸的數據量對可用的帶寬(或資金)來(lái)說(shuō)可能仍然太大。除了從設計角度采取一些措施外(比如將傳輸的數據分成較小的部分),還應該考慮壓縮數據的可能性。但這方面的內容很多,需要單獨撰文論述。

有關(guān)詳細信息,請參閱以下頁(yè)面:

XML Web Services Developer Center
(http://msdn.microsoft.com/webservices/)

SOAP
(http://msdn.microsoft.com/soap/)

使用數據庫

本節詳細介紹前面提到的“設備數據到服務(wù)器數據”集成模式。大多數移動(dòng)應用程序對從遠程數據庫檢索數據、在本地保存收集的數據以及將數據傳輸回遠程數據庫,都有著(zhù)相同的要求。eMbedded Visual Basic 提供了一個(gè)基于 ADOCE 的編程模型,它是一個(gè)服務(wù)器端 ADO 對象模型的“同胞”。與之類(lèi)似,.NET Compact Framework 通過(guò) System.Data 命名空間提供了一個(gè) ADO.NET 的子集。表面看來(lái),新的編程模型與 ADOCE 沒(méi)什么區別,一些基本任務(wù),如進(jìn)行連接、使用記錄和字段集合、通過(guò)連接對象使用事務(wù)處理等,工作方式大致相同。

但是,在數據訪(fǎng)問(wèn)方面有兩個(gè)明顯的變化。首先,沒(méi)有用于本地數據庫(有時(shí)稱(chēng)為 CEDB 或 Pocket Access)的托管提供程序。相反,Microsoft 為 SQL Server CE 2.0 及到服務(wù)器端 SQL Server 的遠程連接提供了托管提供程序。其次,當數據量較小時(shí),可以將保存為本地文件的 XML 作為數據庫,換句話(huà)說(shuō),就是可以不使用 SQL Server CE 2.0。但在這兩種情況下都要使用 ADOCE Recordset 的對等對象 - DataSet。表 1 概括了三種可用的數據庫策略。

表 1:三種可用的數據庫策略

   作為本地文件中 XML 的 DataSet本地 SQL Server
CE 數據庫
遠程 SQL
Server 數據庫
數據量數據量較小數據量中等遠程數據量很大,設備使用小結果集
查詢(xún)簡(jiǎn)單,脫機豐富,脫機豐富,(始終)脫機
主要優(yōu)勢成本低最健壯的本地數據解決方案,帶寬的利用率高實(shí)時(shí),沒(méi)有復制問(wèn)題

從 eMbedded Visual Basic 和 SQL Server CE 1.0/1.1 遷移到 Visual Basic .NET 和 SQL Server CE 2.0 時(shí),兩種數據庫版本的文件格式是相同的,它們可以在同一設備中和平共存,了解這一點(diǎn)是很有幫助的。

System.Data 命名空間中的許多類(lèi)型都與 DataSet 類(lèi)相關(guān)。下圖說(shuō)明了 DataSet 如何實(shí)現讀、寫(xiě) XML,以及本地和遠程 SQL Server 的用法。

圖 7:System.Data 的核心

DataSet

DataSet 類(lèi)代替了 ADOCE Recordset,除此之外,還添加了許多功能。一個(gè) DataSet 可以包含多個(gè)名為 DataTable 對象的結果集,這些結果集又與 DataRelation 和 DataRelationCollection 對象關(guān)聯(lián)。

以下代碼使用 eMbedded Visual Basic 從 SQL Server CE 數據庫打開(kāi)連接和記錄集:

‘ 變量Dim provider As StringDim datasource As StringDim rs As ADOCE.RecordsetDim cn As ADOCE.Connection‘ 創(chuàng  )建 ADOCE 對象Set cn = CreateObject("ADOCE.Connection.3.1")Set rs = CreateObject("ADOCE.Recordset.3.1")‘ 設置 provider 和 datasource 字符串provider = "Provider=Microsoft.SQLSERVER.OLEDB.CE.2.0"datasource = "Data Source=\SQL\sample.sdf"‘ 打開(kāi)連接cn.Open provider & "; " & datasource‘ 打開(kāi)記錄集rs.Open "SELECT SupplierID, CompanyName FROM Suppliers ORDERBY CompanyName",cn,adOpenDynamic,adLockOptimistic

以下是 Visual Basic .NET 中與之相對應的代碼:

‘ 變量Dim cn As New SqlServerCe.SqlCeConnectionDim ds As New DataSetDim da As New SqlServerCe.SqlCeDataAdapterDim cmd As New SqlServerCe.SqlCeCommand‘ 設置 connectionstring,打開(kāi)連接cn.ConnectionString = "Data Source=\SQL\sample.sdf"cn.Open()‘ 設置命令屬性cmd.CommandText = "SELECT SupplierID,CompanyName FROMSuppliers ORDER BY CompanyName"cmd.Connection = cn‘ 設置數據適配器命令da.SelectCommand = cmd‘ 使用適配器的數據表填充 Datasetda.Fill(ds,"Suppliers")

Visual Basic .NET 代碼還可以再簡(jiǎn)潔一些,即在實(shí)例化類(lèi)時(shí)通過(guò)構造函數的參數設置屬性值,而這在 eMbedded Visual Basic 中是無(wú)法做到的。以下就是具體方法:

‘ 變量Dim cn As New SqlServerCe.SqlCeConnection("DataSource=\SQL\sample.sdf")Dim ds As New DataSetDim da As New SqlServerCe.SqlCeDataAdapter("SELECT SupplierID,CompanyName FROM Suppliers", cn)‘ 打開(kāi)連接cn.Open()‘ 使用適配器的數據表填充 DataSetda.Fill(ds, "Suppliers")

DataAdapter 用于向數據庫插入數據、更新其中的數據以及從中刪除數據。要創(chuàng )建所需的命令,最簡(jiǎn)單的方法是構建一個(gè)桌面 Windows Forms 應用程序,并使用“Data Adapter Configuration Wizard”(數據適配器配置向導)創(chuàng )建一個(gè)數據適配器。向導將創(chuàng )建相應的代碼和命令。

DataSet 將數據和架構作為 XML 文檔來(lái)管理,并實(shí)現方法(WriteXml、ReadXml、WriteXmlSchema 和 ReadXmlSchema)以讀、寫(xiě)數據和架構。因此,DataSet 本身在數據量較低時(shí),就可以實(shí)現本地數據庫的具體實(shí)現。

以下兩行代碼根據 DataSet 編寫(xiě) XML 架構和數據:

ds.WriteXmlSchema("\SuppliersSchema.xsd")ds.WriteXml("\Suppliers.xml")

XML 架構的代碼如下所示:

<?xml version="1.0" standalone="yes" ?>- <xs:schema id="NewDataSet" xmlns=""xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">- <xs:element name="NewDataSet" msdata:IsDataSet="true"msdata:Locale="sv-SE">- <xs:complexType>- <xs:choice maxOccurs="unbounded">- <xs:element name="Suppliers">- <xs:complexType>- <xs:sequence><xs:element name="SupplierID" type="xs:int" minOccurs="0" /><xs:element name="CompanyName" type="xs:string"minOccurs="0" /></xs:sequence></xs:complexType></xs:element></xs:choice></xs:complexType></xs:element></xs:schema>

數據文件中的前幾行 XML:

<?xml version="1.0" standalone="yes" ?>- <NewDataSet>- <Suppliers><SupplierID>1</SupplierID><CompanyName>Aux joyeux eccl???©siastiques</CompanyName></Suppliers>- <Suppliers><SupplierID>2</SupplierID><CompanyName>New Orleans Cajun Delights</CompanyName></Suppliers>- <Suppliers><SupplierID>3</SupplierID><CompanyName>Grandma Kelly‘s Homestead</CompanyName></Suppliers>- <Suppliers><SupplierID>4</SupplierID><CompanyName>Tokyo Traders</CompanyName></Suppliers></NewDataSet>

DataSet 的 XML 功能很好地體現了對 eMbedded Visual Basic 的超越。使用 DataSet 將數據從數據庫傳輸到用戶(hù)界面將十分簡(jiǎn)單。以下代碼說(shuō)明了如何使用 DataSet 清除組合框的內容,然后再填充組合框:

‘ 將 DataSet 綁定到組合框并選擇第一個(gè)項目With cboSuppliers.Items.Clear().DataSource = ds.Tables("Suppliers").ValueMember = "SupplierID".DisplayMember = "CompanyName".SelectedIndex = 0End With

DataReader

DataSet 會(huì )生成一個(gè)不連接的結果集,而 DataReader 則是一個(gè)連接的、可讀的、游標只能向前的結果集,可以提供更好的性能。從本質(zhì)上講,DataReader 的行為與使用以下 eMbedded Visual Basic 代碼創(chuàng )建的 ADOCE Recordset 的行為相似:

rs.CursorType = adOpenForwardOnlyrs.LockType = adLockReadOnlyrs.ActiveConnection = cnrs.Open "SELECT SupplierID, CompanyName FROM Suppliers ORDERBY CompanyName"

請注意,變量“cn”是一個(gè) ADOCE Connection 對象。Visual Basic .NET 中的與之相對應代碼如下所示(包括 Connection 對象的實(shí)例化):

Dim cn As New SqlServerCe.SqlCeConnection("DataSource=\SQL\sample.sdf")cn.Open()Dim dc As New SqlServerCe.SqlCeCommand("SELECT SupplierID,CompanyName FROM Suppliers ORDER BY CompanyName", cn)Dim dr As SqlServerCe.SqlCeDataReader = dc.ExecuteReader()

以下代碼說(shuō)明了如何對 DataReader 數據進(jìn)行循環(huán),并填充組合框。代碼實(shí)現了一個(gè)接受兩個(gè)參數的通用過(guò)程,這兩個(gè)參數一個(gè)是 ComboBox 引用,一個(gè)是 SQL 字符串。該過(guò)程假設有一個(gè)開(kāi)放的連接 (cn) 可用,并且使用 ArrayList(一個(gè) .NET Compact Framework 中新提供的類(lèi))來(lái)解決一個(gè)常見(jiàn)的問(wèn)題:填充每個(gè)項目都有隱藏的唯一 ID 和一個(gè)描述性可見(jiàn)名稱(chēng)的組合框。

Private Sub PopulateComboBox(ByRef ComboBox As ComboBox, ByValSQL As String)‘ 填充具有 ID/Name 的組合框的通用子程序‘ 聲明Dim IDNameArray As ArrayList = New ArrayList‘ 清除組合框With ComboBox.Visible = False.DataSource = Nothing.Items.Clear()End WithTryDim dc As New SqlServerCe.SqlCeCommand(SQL, cn)Dim dr As SqlServerCe.SqlCeDataReader = dc.ExecuteReader()‘ 循環(huán)讀取程序While dr.Read()IDNameArray.Add(New IDName(Trim(dr("ID")),Trim(dr("Name"))))End While‘ 設置組合框屬性With ComboBox.DataSource = IDNameArray.DisplayMember = "Name".ValueMember = "ID".SelectedIndex = 0End WithCatch ex As ExceptionMessageBox.Show(ex.Message)FinallyComboBox.Visible = TrueEnd TryEnd Sub

組合框由 ArrayList 填充,ArrayList 是由自定義類(lèi)中的項目數據構建的,這個(gè)自定義類(lèi)實(shí)現兩個(gè)通用屬性:ID 和 Name。類(lèi)的代碼如下所示:

Class IDNamePrivate _ID As StringPrivate _Name As StringPublic Sub New(ByVal ID As String, ByVal Name As String)MyBase.New()_ID = ID_Name = NameEnd SubPublic ReadOnly Property ID() As StringGetReturn (_ID)End GetEnd PropertyPublic ReadOnly Property Name() As StringGetReturn _NameEnd GetEnd PropertyPublic Overrides Function ToString() As StringReturn _ID + " - " + _NameEnd FunctionEnd Class

管理本地數據庫

有兩種方法可以將 SQL Server CE 數據庫植入設備:

  • 安裝時(shí)發(fā)布數據庫文件
  • 運行時(shí)創(chuàng )建數據庫

要使用 eMbedded Visual Basic 創(chuàng )建新數據庫:

‘ 變量Dim provider As StringDim datasource As StringDim ct As ADOXCE.Catalog‘ 處理錯誤On Error Resume Next‘ 創(chuàng  )建 ADOXCE 種類(lèi)Set ct = CreateObject("ADOXCE.Catalog.3.1")‘ 設置 provider 和 datasource 字符串provider = "Provider=Microsoft.SQLSERVER.OLEDB.CE.2.0"datasource = "Data Source=\SQL\sample.sdf"‘ 創(chuàng  )建數據庫ct.Create provider & "; " & datasource‘ 檢查錯誤If Err.Number <> 0 Then‘ 將處理代碼放到此處!End If

很顯然,在運行時(shí)創(chuàng )建的數據庫可能已經(jīng)存在。有兩種方法可以處理這種情況。第一,代碼可以檢查數據庫文件是否存在。如果確實(shí)存在,代碼就不創(chuàng )建新文件。第二,代碼可以處理當它試圖創(chuàng )建已經(jīng)存在的數據庫時(shí)出現的錯誤。在 eMbedded Visual Basic 代碼中,這是在 Create 方法之后,通過(guò)使用前置的“On Error Resume Next”并檢查 Err 對象的 Number 屬性 (Err.Number) 實(shí)現的。要在 Visual Basic .NET 中實(shí)現相同的目的,可以使用更加結構化的 Try ... Catch ... Finally 異常處理:

‘ 變量Dim db As String = "\sample2.sdf"Dim sqlEngine As New SqlServerCe.SqlCeEngine("Data Source=" +db)Try‘ 創(chuàng  )建數據庫sqlEngine.CreateDatabase()Catch ex As SqlServerCe.SqlCeException‘ 將處理代碼放到此處!Finally‘ 無(wú)論 CreateDatabase 運行或失敗,都將執行代碼放到此處!cn.Open()End Try

首先檢查現有數據庫,然后使用 Visual Basic .NET 創(chuàng )建新數據庫:

‘ 變量Dim db As String = "\sample.sdf"Dim sqlEngine As New SqlServerCe.SqlCeEngine("Data Source=" +db)‘ 如果數據庫已經(jīng)存在,則刪除它If File.Exists(db) ThenFile.Delete(db)End If0‘ 創(chuàng  )建數據庫sqlEngine.CreateDatabase()

創(chuàng )建數據庫之后,接著(zhù)創(chuàng )建表格并開(kāi)始處理數據。

以下代碼:

  • 創(chuàng )建表格供應程序
  • 插入兩條記錄
  • 更新一條記錄,刪除一條記錄
  • 管理事務(wù)中的數據更改
‘ 變量Dim db As String = "\sample.sdf"Dim sqlEngine As New SqlServerCe.SqlCeEngine("Data Source=" +db)Dim cn As New SqlServerCe.SqlCeConnection("Data Source=" + db)Dim cmd As New SqlServerCe.SqlCeCommand‘ 如果數據庫已經(jīng)存在,則刪除它If File.Exists(db) ThenFile.Delete (db)End IfTry‘ 創(chuàng  )建數據庫sqlEngine.CreateDatabase()Catch‘ 將處理代碼放到此處!Finally‘ 無(wú)論 CreateDatabase 運行或失敗,都將執行代碼放到此處!cn.Open()End Try‘ 使用 Command 對象創(chuàng  )建表格cmd.Connection = cncmd.CommandText = "CREATE TABLE Suppliers(SupplierID intPRIMARY KEY, CompanyName nvarchar(50))"cmd.ExecuteNonQuery()Try‘ 填充表格cmd.CommandText = "INSERT INTO Suppliers(SupplierID,CompanyName) VALUES (1, ‘Best Foods‘)"cmd.ExecuteNonQuery()cmd.CommandText = "INSERT INTO Suppliers(SupplierID,CompanyName) VALUES (2, ‘Best Clothes‘)"cmd.ExecuteNonQuery()Catch ex As SqlServerCe.SqlCeExceptioncn.Close()MsgBox("Could not insert data!" + ex.Message)Exit SubFinallyEnd TryTry‘ 更新和刪除!cmd.CommandText = "UPDATE Suppliers SET CompanyName = ‘GoodFoods‘ WHERE SupplierID = 1"cmd.ExecuteNonQuery()cmd.CommandText = "DELETE FROM Suppliers WHERE SupplierID =2"cmd.ExecuteNonQuery()Catch ex As SqlServerCe.SqlCeExceptionMsgBox("Could not modify data!" + ex.Message)Finallycn.Close()End Try

使用遠程數據庫

.NET Compact Framework 提供了兩種方法用來(lái)從 Pocket PC 訪(fǎng)問(wèn)遠程數據庫:

  • 多層 Web 服務(wù)應用程序:您可以將 DataSet (XML) 傳遞到服務(wù)器端 Web 服務(wù),而服務(wù)器端 Web 服務(wù)又連接到遠程數據庫?;蛘?,可以通過(guò)服務(wù)器端的 SQLXML 托管類(lèi) (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sqlxml3/htm/dotnet_9n03.asp) 利用 SQL Server 2000 內置的 XML 支持。
  • 遠程數據庫應用程序:開(kāi)發(fā)遠程數據庫應用程序。方法有兩種,一是在 .NET Compact Framework 中使用 SQL 托管提供程序,從而可以對數據庫進(jìn)行直接查詢(xún),這在 eMbedded Visual Basic 中是做不到的;二是在 .NET Compact Framework 中使用 SQL Server CE 托管提供程序,以啟用對數據庫表格的推、拉和合并復制。數據庫與數據庫的緊密集成可以提供更好的性能,但是很難或者根本無(wú)法使用經(jīng)常要在 Web 服務(wù)中實(shí)現的業(yè)務(wù)邏輯。

以下兩篇 MSDN 文章探討了如何安全地配置遠程服務(wù)器:

Security Models and Scenarios for SQL Server 2000 Windows CE Edition 2.0
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsqlce/html/sqlce_secmodelscen20.asp)

Troubleshooting SQL Server CE Connectivity Issues
(http://www.microsoft.com/sql/techinfo/administration/2000/CEconnectivitywp.asp)

配置過(guò) SQL Server CE 1.x 連接的 eMbedded Visual Basic 開(kāi)發(fā)人員會(huì )很高興地發(fā)現,現在他們可以使用 SQL Server CE Connectivity Management 控制臺和 SQL Server CE Virtual Directory Creation Wizard(圖 8)。

圖 8:SQL Server CE 虛擬目錄創(chuàng )建向導

直接數據庫查詢(xún)

System.Data.SqlClient 命名空間 (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sqlce/htm/_lce_sqlclient_705.asp) 中的組件用于連接到遠程 SQL Server、在其中執行命令并從中檢索結果。以下代碼顯示了如何使用 DataReader 實(shí)現此目的。示例代碼要求用戶(hù)輸入公司名稱(chēng),該名稱(chēng)將在對 Northwind 數據庫的 Suppliers 表進(jìn)行查詢(xún)時(shí)用到。請注意,SqlCommand 對象引用一個(gè)駐留在遠程 SQL Server 的存儲過(guò)程。

‘ 變量Dim cmd As SqlClient.SqlCommandDim dr As SqlClient.SqlDataReaderDim cn As New System.Data.SqlClient.SqlConnection("userid=sa;password=;initialcatalog=northwind;server=192.168.100.100")Dim CompanyName As String‘ 獲取要搜索的公司名稱(chēng)CompanyName = txtCompanyName.TextTry‘ 打開(kāi)到遠程服務(wù)器的連接cn.Open()‘ 獲取供應商cmd = New System.Data.SqlClient.SqlCommand("getSuppliers " +CompanyName, cn)dr = cmd.ExecuteReader()‘ 填充組合框cboSuppliers.Items.Clear()While dr.Read()cboSuppliers.Items.Add(dr("CompanyName"))End While‘ 顯示第一個(gè)供應商cboSuppliers.SelectedIndex = 0Catch ex As SqlClient.SqlExceptionMsgBox(ex.Message)Finallydr.Close()cn.Close()End Try

存儲過(guò)程 getSuppliers 的代碼如下所示:

CREATE PROCEDURE getSuppliers@CompanyName NVARCHAR(50)ASSELECT SupplierID, CompanyNameFROM SuppliersWHERE CompanyName LIKE ‘%‘ + @CompanyName + ‘%‘

許多使用 eMbedded Visual Basic 構建的應用程序都利用 SQL Server CE 的 COM 組件 Remote Data Access (RDA) 和 Merge Replication (MR) 以同步設備與遠程服務(wù)器之間的數據。.NET Compact Framework 的 SqlCeRemoteDataAccess 和 SqlCeReplication 命名空間也可以實(shí)現相同的功能。

有關(guān)這些命名空間的詳細信息,請參閱 SQL Server 2000 Windows CE Edition and the .NET Compact Framework
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsqlce/html/sqlwince.asp)。

有關(guān)詳細信息,請參閱以下頁(yè)面:

.NET Compact Framework Data Providers (http://msdn.microsoft.com/library/default.asp?url=/library/enus/sqlce/htm/_lce_sql_server_ce_manage_provider.asp)

Microsoft SQL Server 2000 Windows® CE Edition Home
(http://www.microsoft.com/sql/CE/default.asp)

Converting an eMbedded Visual Basic 3.0 Application from SQL Server CE 1.x to SQL Server CE 2.0
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsqlce/html/sqlce_convertssce10to20_.asp)

部署和分布

構建應用程序之后,需要用一種方便的方法來(lái)部署和發(fā)布應用程序。在 eMbedded Visual Basic 中,有一個(gè)“Application Install Wizard”(應用程序安裝向導),它可以將項目和所需的資源打包到安裝可執行文件中 (setup.exe)。而在 Visual Basic .NET 中,則不像這樣簡(jiǎn)單明了。

創(chuàng )建壓縮文件 (Cabinet)

當“Application Installation Wizard”(應用程序安裝向導,包含在 eMbedded Visual Basic 中)創(chuàng )建安裝程序之后,安裝程序中總會(huì )包含一個(gè)壓縮 (.cab) 文件,該文件在設備上運行,以執行實(shí)際的安裝過(guò)程。生成的文件(Setup.exe、Setup.ini 和壓縮文件)位于名為 CD1 的文件夾中。在 Visual Basic .NET 中,無(wú)法創(chuàng )建完整的計算機安裝,但它本身支持創(chuàng )建壓縮文件。在 Visual Basic .NET 中加載并構建(可能使用“Release”配置)項目后,選擇菜單選項“Build”(構建)和子菜單項“Build Cab File”(構建 Cab 文件),就會(huì )生成適合多種處理器類(lèi)型的壓縮文件。生成的壓縮文件位于項目文件夾(<項目路徑>/cab/Release)下的一個(gè)文件夾中。

要在 Pocket PC 上進(jìn)行安裝,請使用后綴為“_PPC.ARM.CAB”的壓縮文件。這是一個(gè) Pocket PC 安裝程序,將此文件復制到設備上,并從“File Explorer”(文件資源管理器,設備上的)中打開(kāi),就可以開(kāi)始安裝應用程序。這個(gè)文件也可以放置在 Web 頁(yè)面中,已連接的 Pocket PC 用戶(hù)可以直接從 Pocket PC 的 IE 啟動(dòng)安裝過(guò)程。

但是,如果將生成的壓縮文件安裝到設備上,您將會(huì )發(fā)現應用程序的名稱(chēng)與 Visual Basic .NET 中使用的項目名稱(chēng)是相同的。另外,公司名稱(chēng)被設置為“My Company”,這可能不符合您公司的要求。要自定義壓縮文件的創(chuàng )建,必須用到項目文件夾(位于 <項目路徑>/obj/Release)下面的另一個(gè)文件夾。您可以在其中找到創(chuàng )建壓縮文件所需的安裝信息文件 (.inf)。在該文件中,有應用程序條目和公司名稱(chēng)條目。以下示例是此文件的節選(不包括用句點(diǎn)標記的小節):

[Version]Signature="$Windows NT$"Provider="CompanyName"CESignature="$Windows CE$"[CEStrings]AppName="ApplicationName"InstallDir=%CE1%\%AppName%..[DefaultInstall]CEShortcuts=ShortcutsCopyFiles=Files.Common..[SourceDisksFiles]ProjectName.exe=1..[Files.Common]ProjectName.exe,,,0..[Shortcuts]ApplicationName,0,ProjectName.exe,%CE11%

生成此文件的 Visual Basic .NET 項目名稱(chēng)是“ProjectName”,在生成的文件中,Version 小節中的 Provider 值從“My Company”變?yōu)?#8220;CompanyName”。同樣,CEStrings 小節的 AppName 值從“ProjectName”變?yōu)?#8220;ApplicationName”。Shortcuts 小節中也有類(lèi)似的改變(列表中的第一個(gè)值是生成的快捷鍵名)。以上只是簡(jiǎn)單介紹,因為 .inf 文件涉及的內容很多(詳細信息,請參閱 Visual Basic .NET 幫助文件的索引主題“設備項目的 inf 文件”)。

更新 .inf 文件時(shí),您可以運行與 .inf 文件在同一文件夾中的批處理文件 (BuildCab.bat) 來(lái)生成一套新的壓縮文件。

有關(guān)詳細信息,請參閱以下頁(yè)面:

Microsoft Windows CE 3.0 Installation and Configuration Guide
(http://msdn.microsoft.com/library/en-us/wcesetup/htm/_wcesdk_installation_and_configuration_guide.asp)

ActiveSync 安裝

如前所述,eMbedded Visual Basic 中包含的“Application Installation Wizard”(應用程序安裝向導)可以創(chuàng )建一個(gè)文件夾 (CD1),其中包含了安裝文件。這些文件包括在計算機上運行的安裝應用程序 (Setup.exe) 和一個(gè)配置設置文件 (Setup.ini)。要從 Visual Basic .NET 項目創(chuàng )建計算機安裝,您可以使用這兩個(gè)文件,前提是您已經(jīng)安裝了 eMbedded Visual Basic。仍以以上示例為例,setup.ini 文件的結構和內容如下所示:

[General]Component=ProjectNameDefaultDirectory=ApplicationNameCabCount=1Cab0=ProjectName_PPC.ARM.CABDescription=CompanyName ApplicationName

對于 Pocket PC 安裝,只需要后綴為“_PPC.ARM.CAB”的壓縮文件。您需要將三個(gè)文件(Setup.exe、Setup.ini 和 ProjectName_PPC.ARM.CAB)發(fā)送給您的用戶(hù),以便通過(guò) ActiveSync 從計算機來(lái)安裝應用程序。為了方便最終用戶(hù),您甚至可以將這三個(gè)文件壓縮到自解壓的壓縮文件中,當用戶(hù)解壓縮時(shí)即可啟動(dòng)安裝應用程序 (Setup.exe)。大多數的商用壓縮工具(如 WinZip 和 WinRAR)都可以實(shí)現此目的。

小結

從 eMbedded Visual Basic 到 Visual Basic .NET,對于 Pocket PC 的開(kāi)發(fā)來(lái)說(shuō)是一大進(jìn)步。許多開(kāi)發(fā)工作,如用戶(hù)界面的開(kāi)發(fā)、應用程序導航、系統集成、數據庫管理和解決方案部署等,都有重大改進(jìn)。環(huán)境、語(yǔ)言和平臺得到徹底重新構建,從而提供了更為健壯的功能,也提高了編寫(xiě)代碼的效率,開(kāi)發(fā)工作由此變得更為輕松,移動(dòng)應用程序的連接性也得到改善。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
基于 Windows Mobile 的 Pocket PC 和 Smartphone 的開(kāi)發(fā)工具簡(jiǎn)介
從 C 向 C# 遷移
.NET 與 Win32 相比的優(yōu)勢
Visual Basic 2005新功能——My命名空間
VB.NET Sub過(guò)程簡(jiǎn)單分析
VB如何編寫(xiě)定時(shí)器代碼
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久