微軟.NET精簡框架(NETCF)最常見問題

2010-08-28 10:50:01來源:西部e網(wǎng)作者:

此FAQ的內(nèi)容,一部分來自 net精簡框架新聞組 (microsoft.public.dotnet.framework.compactframework)張貼和回答的問題。.net精簡框架開發(fā)小組感謝每一位參與新聞組的人事,感謝他們對FAQ編寫的積極參與和對FAQ的投稿。

要申請?zhí)砑覨AQ項目,請發(fā)郵件到 netcffaq@microsoft.com.

1. 開發(fā)

1.1. 什么是微軟 .net精簡框架?
1.2. 我需要什么工具才能開發(fā).net精簡框架的應(yīng)用?
1.3. 哪里可以下載最新的工具和相關(guān)軟件?
1.4. .net精簡框架支持些什么設(shè)備?
1.5. .net精簡框架以后將支持什么設(shè)備?
1.6. 調(diào)試程序時為什么會出現(xiàn)“與模擬器建立連接失敗”的錯誤(剛開始執(zhí)行程序的時候)?
1.7. .net框架和.net精簡框架之間有什么區(qū)別?
1.8. .net精簡框架的補(bǔ)丁有什么改進(jìn)?
1.9. Poclet PC上的.net精簡框架開發(fā)和Windows CE .NET上的.net精簡框架開發(fā)有什么不同?
1.10. 哪里有更多的關(guān)于建立.net精簡框架上的應(yīng)用程序的信息?
1.11. .net精簡框架的文檔在哪里?
1.12. 怎樣設(shè)置才不會在每次調(diào)試的時候把所涉及的文件都拷貝到設(shè)備上?
1.13. 怎樣設(shè)置模擬器的屬性?
1.14. 怎么調(diào)試.net精簡框架的應(yīng)用程序?
1.15. 怎樣開始使用Visual Basic .NET開發(fā).net精簡框架的程序?
1.16. 怎樣才能把.net精簡框架安裝到裝配集中(GAC)?
1.17. 當(dāng)從Visual Studio .NET 2003中發(fā)布程序到設(shè)備上的時候,怎樣處理"Sharing Violation"?
1.18. 什么是common language runtime (CLR)?
1.19. 什么是Global Assembly Cache (GAC)?
1.20. 在.net精簡框架下內(nèi)存管理是怎樣的?
1.21. 當(dāng)我的網(wǎng)絡(luò)協(xié)議數(shù)超過50個的時候,為什么不能向發(fā)布程序?
1.22. 為什么會有跨平臺代碼?
1.23. 這些ARM指令代表什么?
1.24. 怎樣寫注冊表?
1.25. How can I prevent .CAB files from being deleted after installation?
1.26. How can I determine the version of the .NET Compact Framework that is installed on a device?
1.27. How do I copy files to the emulator?
1.28. Why does installation of the PocketPC 2002 SDK fail?
1.29. How do I debug a Web service consumed by a Smart Device application?
1.30. What is the footprint of the .NET Compact Framework?
1.31. How do I include imgdecmp.dll in an emulator image?
1.32. How do I programmatically replace Assemblies in the Global Assembly Cache (GAC)?
1.33. How can I display Pocket PC applications on my desktop or laptop without needing any device side configuration?
1.34. How can I allow Activesync to connect to an Emulator session from Visual Studio .NET 2003?
1.35. How can I copy files to the device currently connected to desktop ActiveSync?
1.36. How can I stress test user input?
1.37. Where can I get a UI version of the Platform Builder Target Control Window?
1.38. Where can I get a Command shell for Pocket PC 2003 devices?
1.39. How can I get detailed information about currently running processes?
1.40. How can I remotely start an application on a Pocket PC from my desktop?
1.41. Why can't I load different assemblies with the same name?
1.42. How can I force Visual Studio .NET 2003 to connect to newer versions of the Pocket PC 2003 emulator?
1.43. Why don't my custom controls show up properly in the toolbox?
2. 圖形
2.1. 怎樣建立一個圖形對象?
2.2. 怎樣優(yōu)化GDI+?
2.3. 怎樣在窗體上畫一個圖案?
2.4. 怎樣畫一個帶有透明色的圖案?
2.5. 為什么從TextBox上調(diào)用CreateGraphics會失敗?
2.6. 怎樣獲得屏幕上文字的大?
2.7. Can I set the width of a pen?
2.8. How do I zoom an image?
2.9. Why can't I load an image?
3. 發(fā)布
3.1. 怎樣建立一個PocketPC的設(shè)置程序?
3.2. 哪個發(fā)布包可以包括在我的安裝程序中?
3.3. 怎樣可以建立一個不需要.net框架的安裝程序?
3.4. 怎樣建立不受PocketPC系統(tǒng)約束的CAB安裝文件?
3.5. 為什么不同的處理器會有不同的CAB安裝文件?
3.6. How do I create a desktop installer that detects the presence of the .NET Compact Framework on the target device and installs it if necessary?
3.7. How do I deploy a .NET Compact Framework Service Pack to the emulator?
3.8. How do I include SQL Server CE with my application installation?
3.9. How do I use GAPI to create a graphics engine?
4. 圖形用戶界面(GUI): 窗體
4.1. 怎樣建立一個全屏的窗體?
4.2. 什么時候用窗體的構(gòu)造器?什么時候用窗體的Load事件?
4.3. 怎樣把最小化按鈕換成關(guān)閉按鈕?
4.4. 怎樣在.net精簡框架上建立多窗體系統(tǒng)結(jié)構(gòu)?
4.5. 怎樣提高.net精簡框架應(yīng)用程序的載入速度?
4.6. 運(yùn)行時怎樣修改窗體的風(fēng)格?
4.7. 怎樣滾動窗體的內(nèi)容?
4.8. 怎樣制作一個浮動的窗體?好象所有的窗體總是全屏狀態(tài)的。
4.9. 怎樣強(qiáng)迫一個窗體變成最小化?
4.10. 我有一個包含很多控件的智能設(shè)備窗體,為什么運(yùn)行的時候出現(xiàn)"NotSupportedException"錯誤?
4.11. 哪個是正確關(guān)閉窗體的方法:Appplication.Exit 還是 Form.Close ?
4.12. Why does showing a MessageBox on Windows Mobile 2003 for Smartphone with the Abort, Retry, and Fail set of buttons or the Yes, No, Cancel set of buttons, or the third button as the default button result in a NotSupportedException?
4.13 How do I get an icon in the Pocket PC Start Menu Most Recently Used (MRU) List?
4.14 How do I center a Form on the screen?
4.15 Why can't I show a Form that has been closed?
4.16 How can I enable multiple instances of an application?
5. 圖形用戶界面 (GUI): 通用
5.1. 怎樣建立一個帶有圖形或支持多行的按鈕?
5.2. TextBox.AcceptsReturn在.net精簡框架下是怎樣工作的?
5.3. 當(dāng)數(shù)據(jù)載入ComboBox的時候,為什么SelectedIndexChanged事件沒有被觸發(fā)?
5.4. Show和ShowDialog有什么不同?
5.5. 為什么我不能建立右鍵菜單分離器?(separator)
5.6. 運(yùn)行時把ImageList賦給ToolBar時,為什么圖象不出現(xiàn)?
5.7. 怎樣把光標(biāo)設(shè)置成等待狀態(tài)?
5.8. 如何在菜單項中顯示符號:&?
5.9. 如何制作基于.net精簡框架的動畫控件?
5.10. 如何在.net精簡框架上制作自定義控件?
5.11. 如何制作基于.net精簡框架的帶圖片的按鈕?
5.12. 如何使用.net精簡框架下的MessageWindow類庫?
5.13. 如何向DataGrid中添加行和列?
5.14. 如何實現(xiàn)DataGrid的編輯?
5.15. 怎樣設(shè)置DataGrid的DataSource?
5.16. 怎樣對DataGrid的列排序?
5.17. 怎樣對ListView中的內(nèi)容排序?
5.18. 如何使用 輸入板(SIP)控件?
5.19. 如何自定義事件?
5.20. 如何做一個 owner-drawn List Box?
5.21. 如何做一個多選框判斷真假?
5.22. 設(shè)置InputPanel.Enabled = true的時候為什么出現(xiàn)異常?
5.23. 為什么自定義控件不會自動繼承父類的字體?
5.24. 為什么當(dāng)輸入字符時,NumericUpDown 和 DomainUpDown 控件不會引發(fā) ValueChanged 和 SelectedItemChanged 事件?
5.25. 為什么NumericUpDown控件增長的值不是設(shè)置好的值?
5.26. 為什么StatusBar不能放在窗體的任意位置?一定要在底部?
5.27. 為什么我的控件自動繼承了父控件的背景色?
5.28. 為什么NumericUpDown控件能接受decimal類型的值,但不會顯示大于2^16的值?
5.29. 為什么不能在DomainUpDown 中輸入文字,而要選擇?
5.30. 為什么OpenFileDialog被限制在"My Documents" 文件夾中?
5.31. How can I activate the SIP (InputPanel) without a menu?
5.32. How do I add a subnode to every node in a TreeView?
5.33. How do I determine the number of rows or columns in a DataGrid?
5.34. How do I create a owner drawn Listbox?
5.35. How can I implement Control.GetNextControl under the .NET Compact Framework?
5.36. How do I get notified when the user clicks on a treeview node?
5.37. How do I set the title of a fullscreen multiline edit control window?
5.38. Why don' I see the validItem selected when I set ComboBox.SelectedValue to validItemInCollection?
5.39. How do I detect the location where a 'tap & hold' occurred to bring up a context menu on my custom control?
5.40. Why doesn't the scrollbar value ever get set to the maximum value?
5.41. How do I tab out of a custom control to the previous control?
5.42. How do I add Toolbar buttons with Transparency? 
6. 與本地代碼(Native Code)協(xié)同工作
6.1. 如何調(diào)用本地寫的DLL中的函數(shù)?
6.2. 如何使用dumpbin.exe幫助描述 P/Invokes?
6.3. 如何為微軟.net精簡框架寫非托管代碼?
6.4. 如何調(diào)用 P/Invoke GetTickCount?
6.5. 如何獲得系統(tǒng)還有多少可用內(nèi)存?
6.6. 如何是窗口一直保持最小化?
6.7. 在微軟.net精簡框架上調(diào)用系統(tǒng)函數(shù)時,如何裝配數(shù)據(jù)類型?
6.8. 如何得到一個窗體或控件的句柄 (HWND) ?
6.9. 如何使用性能計數(shù)器功能?
6.10. 調(diào)用本地代碼時,數(shù)據(jù)類型有什么限制?What are the limitations on marshalling types via P/Invoke?
6.11. 調(diào)用GetLastError時,總是獲得不定的代碼?
6.12. 調(diào)用本地代碼時,有沒有參數(shù)數(shù)量的限制?
6.13. 調(diào)用本地代碼時,為什么得到"NotSupportedException"異常?
6.14. 如何把 byte[] 轉(zhuǎn)換成 IntPtr?
6.15. Why do I get a MissingMethodException when I call a function from a native DLL?
6.16. How do I set the system time?
6.17. How do I programmatically soft reset the device?
6.18. How can I put an icon on the title bar regardless of the which form is active?
6.19. How do I disable and capture hardware buttons?
6.20. How do I hide the start icon?
6.21. How do I enumerate, create, and terminate processes?
6.22. Where can I find a centralized library of P/Invoke samples?
6.23. How do I play and record .WAV audio files with the Waveform Audio Inteface? 
7. 通用
7.1. 如何確定應(yīng)用程序的主目錄?
7.2. 如何計算精確的時間間隔?
7.3. 如何把嵌入式資源當(dāng)作一個流(Stream)?
7.4. 為什么得到一個"An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in System.dll"的錯誤?
7.5. 如何使用性能監(jiān)視器?
7.6. 如何取消一個程序的關(guān)閉?
7.7. 如何在我的程序中調(diào)用另一個應(yīng)用程序?
7.8. .net精簡框架的應(yīng)用程序會建立什么線程?
7.9. 如何把byte數(shù)組轉(zhuǎn)換成結(jié)構(gòu)體?
7.10. 我可以建立一個委托(delegate)交給Invoke嗎?
7.11. 如何在微軟.net精簡框架上使用電話API?
7.12. 如何在Pocket Pc上生成GUID?
7.13. 如何讓我的.net精簡框架程序和Pocket Outlook的數(shù)據(jù)結(jié)合?
7.14. 我可以判斷.net精簡框架中一個文件的版本嗎?
7.15. 微軟.net精簡框架的后臺處理有什么相關(guān)技術(shù)?
7.16. 在微軟.net精簡框架上使用多線程有什么技巧?
7.17. 如何在 智能設(shè)備應(yīng)用 中使用混淆器?
7.18. 如何使用密碼服務(wù)對數(shù)據(jù)進(jìn)行加密或解密?
7.19. 如何在微軟.net精簡框架上獲得Windows CE設(shè)備的唯一號碼?
7.20. 如何在微軟.net精簡框架的應(yīng)用程序上發(fā)送短消息?
7.21. 不使用Control.Name,可以判斷事件的發(fā)送者嗎?
7.22. 如何在線程中調(diào)用方法的參數(shù)?
7.23. 如何建立提醒程序和定時程序?
7.24. 如何播放聲音?
7.25. 如何使用命令行參數(shù)?
7.26. 當(dāng)使用已經(jīng)釋放的對象的方法或?qū)傩缘臅r候,為什么得到一個異常?
7.27. 如何獲得"Enter", "TAB", 和 "Arrow"按鍵的事件?
7.28. 如何刪除一個只讀文件?
7.29. How do I determine if a member exists at runtime?
7.30. How do I determine the device name programatically?
7.31. How do I build a C# Smart Device project from the command line?
7.32. How do I abort an executing thread?
7.33. Why can't I play a movie on the Pocket PC emulator?
7.34. How do I suppress Form titles from showing in the active applications list?
7.35. How do I access a Control from its instance name?
7.36. How do I detect the hardware directional pad buttons?
7.37. How do I get a double click event when only the Click event is supported?
7.38. How do I get onenter/onleave style notifications?
7.39. How do I use threading in a modal dialog that doesn't hang my app?
7.40. How do I round floating point numbers efficiently?
7.41. Why does Control.Invoke take so long when a modal dialog is displayed?
7.42. Is there a way to retrieve the culture information of an Assembly?
8. 通訊和Web服務(wù)
8.1. 如何通過TCP Socket向桌面機(jī)發(fā)送數(shù)據(jù)?
8.2. 為什么不能訪問本機(jī)上的Web服務(wù)?
8.3. 如何在微軟.net精簡框架上調(diào)用Web服務(wù)
8.4. 如何通過代理服務(wù)器提交HTTP GET申請?
8.5. 如何使用Web服務(wù)?
8.6. 如何使用MapPoint3.0得到地圖?
8.7. 如何使用MapPoint3.0獲得地圖和方向?
8.8. Is NTLM authentication supported by the .NET Compact Framework?
8.9. When using blocking Sockets, why does Send throw an InvalidOperationException when blocking is set to false?
8.10. How do I create an http-server?
8.11. Why do I get an exception when calling SetSocketOption with ReuseAddress set?
8.12. Why do I get a socket error using SSL to communicate with a server via the WebRequest namespace?
9. SQL CE 和 數(shù)據(jù)
9.1. 使用.net精簡框架、SQL Server CE 和 復(fù)制 開發(fā)應(yīng)用程序時,要注意些什么?
9.2. 如何在微軟.net精簡框架上使用合并復(fù)制(Merge Replication)?
9.3. 如何將ADO.NET數(shù)據(jù)和XML綁定?
9.4. 如何建立SQL Server CE的數(shù)據(jù)庫?
9.5. 如何向SQL Server CE提交一個帶參數(shù)的查詢?
9.6. Why does using RDA and the push method fail with error 27750?
10. 其他信息
10.1. Pocket TaskVision 程序
10.2. 建立基于微軟.net精簡框架的進(jìn)程管理器
10.3. 使用微軟.net精簡框架開發(fā)移動游戲
10.4. 制作一個微軟.net精簡框架的DateTimePicker控件
10.5. 寫一個捕捉Pocket PC簽名的程序
10.6. 有沒有非微軟的網(wǎng)站提供在.net精簡框架上開發(fā)應(yīng)用的信息?
11. 連通性
11.1. 為什么不同通過ActiveSync把程序部署到Windows CE的設(shè)備上?
11.2. 為什么不能通過ActiveSync調(diào)試 CEPC 或其他 x86 的Windows CE設(shè)備?
11.3. 為什么當(dāng)設(shè)備上的Toolhelp.dll文件丟失后,調(diào)試就會失?
11.4. 為什么當(dāng)網(wǎng)絡(luò)協(xié)議數(shù)超過50個的時候,就不能向設(shè)備發(fā)布程序?
11.5. 為什么卸載ActiveSync后,不能通過ActiveSync向設(shè)備發(fā)布?
11.6. 為什么本地化的機(jī)器名或用戶名或?qū)е孪蛟O(shè)備發(fā)布程序的失。
11.7. 為什么當(dāng)前用戶不屬于Administrators組的時候,不能向設(shè)備發(fā)布程序?
11.8. 為什么向Pocket PC或模擬器發(fā)布的時候出現(xiàn) sharing violation 的錯誤?
11.9. 為什么在.NET Server的計算機(jī)上第一次使用模擬器的時候,得到一個安全警告消息?
11.10. 為什么在模擬器剛開始運(yùn)行的時候出現(xiàn)關(guān)于找不到文件的錯誤信息?
11.11. 為什么第一次用模擬器發(fā)布時,會出現(xiàn)偶爾的錯誤?
11.12. 為什么第一次用Connect按鈕連接模擬器并發(fā)布程序的時候失敗了?
11.13. 為什么當(dāng)計算機(jī)沒有網(wǎng)絡(luò)連接的時候,用模擬器調(diào)試程序會出現(xiàn)錯誤?
11.14. 為什么當(dāng)模擬器使用了一個COM端口的時候不啟動不了(黑屏)?
11.15. 為什么Visual Studio .NET 2003的模擬器不能和eMbedded Visual Tools的模擬器同時使用?
11.16. 為什么沒有ActiveSync連接的時候不能通過TCP連接向設(shè)備發(fā)布程序?
11.17. How can I allow Activesync to connect to an Emulator session from Visual Studio .NET 2003?
11.18. How can I copy files to the device currently connected to desktop ActiveSync?
11.19. Why does the Visual Studio debugger fail to connect to an ARMV4I device?
12. Smartphone
12.1. Where can I get the latest Smartphone SDK?
12.2. What are the rules for Smartphone menus?
12.3. Why are there disabled controls in the toolbox when creating a Smartphone project?
12.4. Does Smartphone support RAM installs of the .NET Compact Framework?
12.5. How do I set the title of a fullscreen multiline edit control window?
12.6. How can I generate Smartphone CABWizSP XML docs from existing Pocket PC CAB files?
12.7. How can I send characters and strings to the Smartphone 2003 Emulator via ActiveSync?
12.8. How do I programmatically set the Smartphone input mode?

1. 開發(fā)

1.1. 什么是微軟 .net精簡框架?

微軟.net精簡框架是.net框架為智能設(shè)備開發(fā)的平臺,是實現(xiàn)微軟的目標(biāo):“為用戶提供精彩的體驗--任何時間、任何地點(diǎn)、任何設(shè)備” 的關(guān)鍵部分。.net精簡框架把托管代碼的世界從web服務(wù)帶到了智能設(shè)備上, 允許在個人數(shù)字助理(PDA)、移動電話、機(jī)頂盒設(shè)備上的 安全的、可下載的應(yīng)用。

http://msdn.microsoft.com/mobility/prodtechinfo/devtools/netcf/overview/default.aspx

1.2. 我需要什么工具才能開發(fā).net精簡框架的應(yīng)用?

Visual Studio .NET 2003 是在Pocket PC 2000、Pocket PC 2002和Windows CE.NET 4.1上開發(fā).net精簡框架所需要的, .net精簡框架與Visual Studio .NET 2003一同發(fā)售.
http://msdn.microsoft.com/mobility/prodtechinfo/devtools/vstudio/default.aspx

其他Windows移動平臺開發(fā)包可以在以下地方獲得:

Windows Mobile 2003 Pocket PC SDK:
http://www.microsoft.com/downloads/details.aspx?familyid=9996b314-0364-4623-9ede-0b5fbb133652&displaylang=en

Windows Mobile 2003 Smartphone SDK:
http://www.microsoft.com/downloads/details.aspx?familyid=a6c4f799-ec5c-427c-807c-4c0f96765a81&displaylang=en

這篇文章將介紹如何使用.net精簡框架和Visual Studio .NET 2003下開發(fā)健壯的智能設(shè)備應(yīng)用程序.
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfgetstarted.asp

1.3. 哪里可以下載最新的工具和相關(guān)軟件?

Visual Studio .NET 2003試用版可以在這里獲得:
http://msdn.microsoft.com/vstudio/productinfo/trial/default.aspx

最新的.net精簡框架和補(bǔ)丁集可以在這里獲得:
http://msdn.microsoft.com/mobility/downloads/default.aspx

1.4. .net精簡框架支持些什么設(shè)備?

.net精簡框架可以在Pocket PC 2000, Pocket PC 2002, Windows Mobile 2003的Pocket PC 和 基于Windows CE.NET 4.1嵌入式系統(tǒng)的Pocket PC、智能手機(jī) 上運(yùn)行。

1.5. .net精簡框架以后將支持什么設(shè)備?

.net精簡框架將被集成到微軟系統(tǒng)中并成為一部分,包括未來的Pocket PC設(shè)備,Pocket PC電話版,智能手機(jī),車載Windows CE系統(tǒng),MSTV。 各種設(shè)備的發(fā)布時間待定。

.net精簡框架將作為Windows CE .NET 4.1系統(tǒng)組件的一部分,因此允許OEM廠商使用PlatformBuilder把.net精簡框架集成到新的Windows CE設(shè)備中。

1.6. 調(diào)試程序時為什么會出現(xiàn)“與模擬器建立連接失敗”的錯誤(剛開始執(zhí)行程序的時候)?

下面這個連接將告訴你如何設(shè)置調(diào)試和排錯。
http://download.microsoft.com/download/c/d/b/cdbff573-73fb-4f9f-a464-c5adc890e1ae/Readme.htm

1.7. .net框架和.net精簡框架之間有什么區(qū)別?

.NET框架 和 .net精簡框架 的關(guān)系:
http://msdn.microsoft.com/library/en-us/dv_evtuv/html/etconComparisonsWithNETFramework.asp

在線查看.net精簡框架類庫關(guān)系工具:
http://msdn.microsoft.com/library/en-us/dv_spchk/html/NET_Compact_Framework.htm

1.8. .net精簡框架的補(bǔ)丁有什么改進(jìn)?

.net精簡框架 SP1 修正了許多漏洞,查看修正項目列表:
http://www.microsoft.com/downloads/details.aspx?familyid=1f62a2a3-7282-4ba9-b26b-2267e972501d&displaylang=en

1.9. Poclet PC上的.net精簡框架開發(fā)和Windows CE .NET上的.net精簡框架開發(fā)有什么不同?

這篇文章將描述在Pocket PC和Windows CE.NET平臺上開發(fā)基于.net 精簡框架的應(yīng)用程序的區(qū)別之處。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfPPCtoCE.asp

1.10. 哪里有更多的關(guān)于建立.net精簡框架上的應(yīng)用程序的信息?

以下資源能教會您怎樣建立.net精簡框架應(yīng)用程序:

  • .net精簡框架  快速入門
    http://samples.gotdotnet.com/quickstart/compactframework/
  • .net精簡框架白皮書 MSDN移動和嵌入式開發(fā)中心:
    http://msdn.microsoft.com/mobility/understanding/articles/default.aspx

    1.11. .net精簡框架的文檔在哪里?

    http://msdn.microsoft.com/library/en-us/dv_evtuv/html/etconNETCompactFramework.asp

    1.12. 怎樣設(shè)置才不會在每次調(diào)試的時候把所涉及的文件都拷貝到設(shè)備上?

    在Visual Studio .NET 2003, 右鍵點(diǎn)擊文件并選擇屬性,把Build的屬性設(shè)置為None.文件將不再被拷貝.如果文件修改過了,需要重新拷貝,把Build屬性改為Content即可.

    1.13. 怎樣設(shè)置模擬器的屬性?

    在Visual Studio .NET 2003菜單中,選擇 Tools->Options. 打開 Device Tools 文件夾,并選擇 Devices. 您應(yīng)該看到一個顯示設(shè)備列表的對話框.選擇您想修改的設(shè)備,按Configuration按鈕.
    現(xiàn)在您應(yīng)該看到一個包含多個TAB并可以修改設(shè)置的對話框,如設(shè)置內(nèi)存和屏幕大小等.

    1.14. 怎么調(diào)試.net精簡框架的應(yīng)用程序?

    微軟.net精簡框架完全集成在Visual Studio .NET 2003中,在Visual Studio .NET 2003下調(diào)試.net精簡框架的應(yīng)用和在Visual Studio .NET 2003下調(diào)試其他應(yīng)用一樣。在一個單獨(dú)的設(shè)備上調(diào)試程序和在模擬器中調(diào)試程序需要注意不同的地方。查看下面文章可以獲得更多調(diào)試.net精簡框架的經(jīng)驗。
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/CompactFXDebug.asp

    1.15. 怎樣開始使用Visual Basic .NET開發(fā).net精簡框架的程序?

    了解怎樣使用Smart Device Extensions (SDE)編寫只能設(shè)備的應(yīng)用。這篇文章詳細(xì)介紹了在.net精簡框架上開發(fā)、調(diào)試、發(fā)布的完整過程,并描述了和在.net框架上開發(fā)的區(qū)別。
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/sdeforvb.asp

    1.16. 怎樣才能把.net精簡框架安裝到裝配集中(GAC)?

    http://msdn.microsoft.com/library/en-us/dncfhowto/html/HOWTOGAC.asp

    1.17. 當(dāng)從Visual Studio .NET 2003中發(fā)布程序到設(shè)備上的時候,怎樣處理"Sharing Violation"?

    This article illustrates the cause of a sharing violation that prevents the deployment of your application from Visual Studio .NET 2003, and gives instructions on how to work around it.
    http://msdn.microsoft.com/library/en-us/dncfhowto/html/HOWTOSharingviolation.asp

    1.18. 什么是common language runtime (CLR)?

    .net精簡框架提供的運(yùn)行環(huán)境叫做CLR,它使程序運(yùn)行,并且是開發(fā)更加容易。以下文章將使您了解更多關(guān)于CLR:
    http://msdn.microsoft.com/library/en-us/cpguide/html/cpconcommonlanguageruntimeoverview.asp

    1.19. 什么是Global Assembly Cache (GAC)?

    每一臺裝了.net環(huán)境的機(jī)器都會有一個本機(jī)器范圍內(nèi)的緩沖,這就是GAC。GAC中存放的裝配會被這臺計算機(jī)上的一些應(yīng)用程序共享 。這篇文章將告訴你更多關(guān)于GAC的信息:
    http://msdn.microsoft.com/library/en-us/cpguide/html/cpconglobalassemblycache.asp

    1.20. 在.net精簡框架下內(nèi)存管理是怎樣的?

    自動內(nèi)存管理是CLR提供的一項服務(wù)。CLR的垃圾回收器會管理應(yīng)用程序內(nèi)存的分派和回收,以下文章將為您解釋:
    http://msdn.microsoft.com/library/en-us/cpguide/html/cpconautomaticmemorymanagement.asp

    1.21. 當(dāng)我的網(wǎng)絡(luò)協(xié)議數(shù)超過50個的時候,為什么不能向發(fā)布程序?

    請查看本文章的  "11.4. 為什么當(dāng)網(wǎng)絡(luò)協(xié)議數(shù)超過50個的時候,就不能向設(shè)備發(fā)布程序?"  部分。

    1.22. 為什么會有跨平臺代碼?

    .net精簡框架和它的執(zhí)行引擎是.net框架和CLR的子集。缺省的強(qiáng)名稱策略,針對.net精簡框架編譯的程序同樣可以在完整的.NET框架上運(yùn)行,但會有一些重要的異常信息:
    • .net精簡框架裝配使用和.net框架不用的強(qiáng)名稱簽名,所以CLR可以區(qū)分它們。
    • 在未來發(fā)布的.NET框架和CLR的綁定策略中將使用.NET框架裝配代替兼容.NET精簡框架參考。這樣,在普通情況下,不需要重新連接就能重用組件。 例如:如果您的組件只引用了.net精簡框架的 System 和 System.NET 類庫,它則不需要重新連接就適合在.net精簡框架和完整的.NET框架下運(yùn)行。
    • 如果你引用了.net精簡框架特有的功能,如PocketPC特有的用戶界面,程序?qū)⒉荒茉谕暾?net框架上運(yùn)行。
    • 如跨平臺的中間組件的開發(fā)和發(fā)布,微軟認(rèn)為豐富的客戶端應(yīng)用應(yīng)該利用智能設(shè)備特有的功能為用戶帶來更好的體驗。這一味著好的圖形用戶界面基本上是客戶端特有的。
    • 盡管微軟花費(fèi)很大精力為不同設(shè)備和功能劃分了不同的命名空間和裝配以避免裝配沖突,但在1.0的版本里還是會有不能處理的兼容性問題。在這種情況下,在. net框架上不經(jīng)意地使用了設(shè)備專有的功能將會導(dǎo)致程序在運(yùn)行時的異常,而不是載入時的異常。

    1.23. 這些ARM指令代表什么?

    XScale支持ARM v5指令集,同時也向下兼容ARM v4指令集。這里有三種情況:
    • ARMv4 -> 只支持32位ARMv4指令
    • ARMv4T -> 'T' 表示 Thumb. Thumb 是ARM16位指令模式
    • ARMv4I -> 'I' 表示 Interworking. 允許32位和16位指令共存

    對于其他ARM處理器:
    • StrongARM (SA1110) -> 只支持ARMv4指令
    • ARM920T, etc -> 支持所有三種情況

    .net精簡框架支持三種ARM代碼
    • ARMv4 for PocketPC 2000 and Pocket PC 2002. 支持所有ARM設(shè)備,包括XScale。發(fā)布到設(shè)備的CAB文件名包含有"arm"字符。
    • ARMv4 for Windows CE.NET. 支持由PlatformBuilder使用ARMv4核心編譯的Windows CE.NET設(shè)備。Pocket PC 2003支持這種代碼。發(fā)布到設(shè)備的CAB文件名包含有"armv4"字符。
    • ARMv4T or ARMv4I for Windows CE.NET. 支持由PlatformBuilder使用ARMv4T 或 ARMv4I核心編譯的Windows CE.NET設(shè)備。發(fā)布到設(shè)備的CAB文件名包含有"armv4T"字符。

    1.24. 怎樣寫注冊表?

    Visual Studio .NET 的發(fā)布中沒有包括Windows CE的遠(yuǎn)程注冊表編輯器。要修改注冊鍵值,可以采用以下方法:
    • Microsoft Embedded Visual Tools Remote Registry Editor
    • Microsoft Windows CE Platform Builder Remote Registry Editor
    • PHM Pocket PC Registry Editor (共享軟件,很容易在網(wǎng)上找到)
    1.25. How can I prevent .CAB files from being deleted after installation?

    Automatic deletion of .CAB files can be prevented by setting the property of the .CAB file(s) to Read Only.

    1.26. How can I determine the version of the .NET Compact Framework that is installed on a device?

    Each version of the .NET Compact Framework is released with a different Win32 File Version number (this is a separate version number from the Assembly Version, which should be the same across all releases of the Version 1 .NET Compact Framework, including Service Packs).

    In order to see what version is installed, use File Explorer to navigate to the \Windows directory on the device, and click the file called CGACUTIL. You will get a message box showing you the Win32 File Version of the .NET Compact Framework installed on the device.

    RTM = 1.0.2268.0
    SP1 = 1.0.3111.0
    SP2 Recall = 1.0.3226.0
    SP2 Beta = 1.0.3227.0
    SP2 Final = 1.0.3316.0

    To determine the version programmatically you can use System.Environment.Version.ToString().

    1.27. How do I copy files to the emulator?

    One approach would be to create a file share on your development PC, and then connect to that share via File Explorer in the emulator. You may then copy and paste the files from the share to the emulator's local file system. Another approach would be to add the file(s) to a smart device project and set their Build Action(s) property to "Content". See the Visual Studio .NET online documentation for more information on "File Properties":

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vbconfileproperties.asp

    Step by step instructions for adding a "Content" file to a smart device project:
    1. Open or create a smart device project,
    2. On the View menu, click Solution Explorer,
    3. In Solution Explorer, right-click on your project, point to Add, and click Add Existing Item. Browse to and add the desired file to the project.
    4. Right-click on the file that you added, in solution explorer, and click Properties,
    5. Set the Build Action property to "Content", if it is not already set.
    1.28. Why does installation of the PocketPC 2002 SDK fail?

    Symptom: The Pocket PC 2002 SDK installer hangs while "registering components."

    Cause: An unregestered component causes the installation to hang while attempting to run the emulator.

    Workaround: From a console window prompt:
    cd \WINNT\system32
    regsvr32 atl.dll

    1.29. How do I debug a Web service consumed by a Smart Device application?

    You need to attach the debugger to the ASP.NET worker process.

    Refer to the following link for more information:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsdebug/html/vxtskdebugginganaspdeployedwebapplication.asp

    1.30. What is the footprint of the .NET Compact Framework?

    .NET Compact Framework storage size:
    • 1.55MB (ROM) on Pocket PC 2000/2002
    • 1.35MB (ROM) on Windows Mobile for Pocket PC 2003 or Windows CE .NET Devices
    Running RAM requirements:
    • .5 MB+ (depends on application)
    Typical application sizes:
    • 5 - 100 KB
    1.31. How do I include imgdecmp.dll in an emulator image?

    You must ask the OEM to include it in the device's image. If you are the OEM and you are using Platform Builder 4.2, then including the OS Dependencies for the .NET item automatically causes imgdecmp.dll to be part of the emulator image - if that is not working then refer to cesysgen.bat. Another method is to set the environment variable "__SYSGEN_IMGDECMP=1" to explicitly force the DLL into the image.

    1.32. How do I programmatically replace Assemblies in the Global Assembly Cache (GAC)?

    One can install and remove Assemblies directly to and from the GAC by programmatically launching cgacutil.
    • Remove assemblies from the GAC using the -u option
    • Install assemblies to the GAC using the -i option
    It is typically safest to remove the Assembly before reinstalling it.

    1.33. How can I display Pocket PC applications on my desktop or laptop without needing any device side configuration?

    Download the ActiveSync Remote Display from Windows Mobile Developer Power Toys:
    http://www.microsoft.com/downloads/details.aspx?FamilyId=74473FD6-1DCC-47AA-AB28-6A2B006EDFE9&displaylang=en

    1.34. How can I allow Activesync to connect to an Emulator session from Visual Studio .NET 2003?

    See the entry titled "11.17. How can I allow Activesync to connect to an Emulator session from Visual Studio .NET 2003?" of this FAQ.

    1.35. How can I copy files to the device currently connected to desktop ActiveSync?

    See the entry titled "11.18. How can I copy files to the device currently connected to desktop ActiveSync?" of this FAQ.

    1.36. How can I stress test user input?

    Download Hopper from Windows Mobile Developer Power Toys:
    http://www.microsoft.com/downloads/details.aspx?FamilyId=74473FD6-1DCC-47AA-AB28-6A2B006EDFE9&displaylang=en

    1.37. Where can I get a UI version of the Platform Builder Target Control Window?

    Download JShell from Windows Mobile Developer Power Toys:
    http://www.microsoft.com/downloads/details.aspx?FamilyId=74473FD6-1DCC-47AA-AB28-6A2B006EDFE9&displaylang=en

    1.38. Where can I get a Command shell for Pocket PC 2003 devices?

    Download PPC Command Shell from Windows Mobile Developer Power Toys:
    http://www.microsoft.com/downloads/details.aspx?FamilyId=74473FD6-1DCC-47AA-AB28-6A2B006EDFE9&displaylang=en

    1.39. How can I get detailed information about currently running processes?

    Download RAPI Debug from Windows Mobile Developer Power Toys:
    http://www.microsoft.com/downloads/details.aspx?FamilyId=74473FD6-1DCC-47AA-AB28-6A2B006EDFE9&displaylang=en

    1.40. How can I remotely start an application on a Pocket PC from my desktop?

    Download RAPI Start from Windows Mobile Developer Power Toys:
    http://www.microsoft.com/downloads/details.aspx?FamilyId=74473FD6-1DCC-47AA-AB28-6A2B006EDFE9&displaylang=en

    1.41. Why can't I load different assemblies with the same name?

    This is by design. You must either change the names of the DLLs, or if the DLLs are strong named, place them in the GAC and use Assembly.Load with a full strong name.

    1.42. How can I force Visual Studio .NET 2003 to connect to newer versions of the Pocket PC 2003 emulator?

    Download the Emulator ActiveSync Connection Tool from Windows Mobile Developer Power Toys:
    http://www.microsoft.com/downloads/details.aspx?familyid=74473FD6-1DCC-47AA-AB28-6A2B006EDFE9&displaylang=en

    This allows ActiveSync to connect to your Emulator session from Visual Studio .NET 2003. Create an ActiveSync session to the 4.2 emulator, this will allow Visual Studio 2003 to consider it a real device (Choose PPC device as the deployment target).

    1.43. Why don't my custom controls show up properly in the toolbox?

    While adding designer support in Visual Studio .NET 2003 for Smart Device custom controls, you may run into the following issues:
    • Unable to associate an Icon to the Control for showing it in the toolbox at design time
    • The component, when added to the toolbox, becomes greyed out
    Causes
    • Using a design project separate from the control project. Visual Studio .NET automatically prepends the project default namespace to the bitmap name. The "default namespace" defaults to the project name. This may be a problem because the design project has a slightly different name than the runtime project.
    • Not setting the correct ToolBoxItemFilterAttribute values
    Resolutions

    Given the following example:
    Runtime VS.NET Project: MyProject
    Class Name: MyProject.MyClass
    Design VS.NET Project Name: MyProject.Design
    BitMap name in VS.NET Design Project: Foo.bmp
    Bitmap name in design assembly: MyProject.Design.MyClass.bmp
    -- This creates a problem because the bitmap needs the name: MyProject.MyClass.bmp

    In the above example, setting the design project's default namespace to "MyProject" rather then "MyProject.Design" should fix the problem.

    The easiest way to check the name of the bitmap within the assembly is to run ILDASM and open the Manifest. The embedded resources are listed at the end of the manifest.

    If you create a custom component derived from the Component class, your code must include the following statements so that your component appears in the Toolbox:
    ToolBoxItemFilterAttribute("NETCF",ToolBoxItemFilterType.Require)
    ToolBoxItemFilterAttribute("System.CF.Windows.Forms", ToolBoxITemFilterType.Custom)

    2. 圖形


     2.1. 怎樣建立一個圖形對象?

    有很多種方法可以建立圖形對象,看你怎么用:

    在OnPaint中,使用object參數(shù)提供的PaintEventArgs參數(shù):
    //C#
    protected override void OnPaint(PaintEventArgs e)
    {
    e.Graphics.DrawLine(...);
    }

    'VB
    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    e.Graphics.DrawLine(...)
    End Sub 'OnPaint
    在程序的其他部分,利用控件的一個方法,可以用來建立任意控件的圖形對象:
    //C#
    using System.Drawing;

    Graphics g = this.CreateGraphics();

    'VB
    Imports System.Drawing

    Dim g As Graphics = Me.CreateGraphics()
    直接畫到bitmap位圖文件中:
    //C#
    using System.Drawing;

    Bitmap bm = new Bitmap(10,10);
    Graphics g = Graphics.FromImage(bm);

    'VB
    Imports System.Drawing

    Dim bm As New Bitmap(10, 10)
    Dim g As Graphics = Graphics.FromImage(bm)
    2.2. 怎樣優(yōu)化GDI+?

    以下編碼方式有助提高使用Graphics的繪圖速度:
    • 只建立一個圖形對象 (或只使用OnPaint中的 PaintEventArgs)。
    • 把所有繪圖工作先畫到不顯示的位圖上,再一次性把位圖顯示出來。
    • 只重畫變化的部分圖象。
    • 盡可能在相同的區(qū)域上畫相同大小的圖象。
    主要思路:最小化地重畫圖象。例如,當(dāng)光標(biāo)拖過圖象時,不需要把整個圖重新畫一遍。只需要重畫光標(biāo)之前經(jīng)過的地方。

    2.3. 怎樣在窗體上畫一個圖案?

    這里有個例子,告訴你怎樣把圖片畫到窗體的背景上:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/bkgndimage.aspx

    2.4. 怎樣畫一個帶有透明色的圖案?

    畫一個帶有透明色的圖象,需要設(shè)置ImageAttributes對象的透明色。目前.net精簡框架支持單種顏色的透明色。雖然SetColorKey 功能可以設(shè)置顏色范圍,但顏色的最大值和最小值必須相同,不然在運(yùn)行時會出現(xiàn)ArgumentException的錯誤:
    //C#
    using System.Drawing.Imaging;

    ImageAttributes attr = new ImageAttributes();

    'VB
    Imports System.Drawing.Imaging

    Dim attr As New ImageAttributes()
    以下代碼描述了如何根據(jù)圖象左上角的顏色設(shè)置透明色。
    //C#
    attr.SetColorKey(bmp.GetPixel(0,0), bmp.GetPixel(0,0));

    'VB
    attr.SetColorKey(bmp.GetPixel(0,0), bmp.GetPixel(0,0))
    以下方法可以準(zhǔn)確的設(shè)置顏色:
    //C#
    attr.SetColorKey(Color.FromArgb(255,0,255),Color.FromArgb(255,0,255));
    attr.SetColorKey(Color.Fuchsia, Color.Fuchsia);

    'VB
    attr.SetColorKey(Color.FromArgb(255,0,255),Color.FromArgb(255,0,255))
    attr.SetColorKey(Color.Fuchsia, Color.Fuchsia)
    圖象會被重載的Graphics.DrawImage方法重畫,并且使用ImageAttributes對象作為一個參數(shù)parameter:
    //C#
    g.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height,GraphicsUnit.Pixel, attr);

    'VB
    g.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height,GraphicsUnit.Pixel, attr)
    2.5. 為什么從TextBox上調(diào)用CreateGraphics會失敗?

    只有Form類才支持Control.CreateGraphics().

    2.6. 怎樣獲得屏幕上文字的大。

    使用Graphics的MeasureString方法。以下代碼說明如何在文字周圍畫一個方框:
    //C#
    using System.Drawing;

    protected override void OnPaint(PaintEventArgs e)
    {
    string s = "Hello World"

    Pen pen = new Pen(Color.Fuchsia);
    Font font = new Font("Arial", 18, FontStyle.Regular);
    Brush brush = new SolidBrush(Color.Black);

    SizeF sSize = e.Graphics.MeasureString(s, font);

    Rectangle r = new Rectangle(9, 199,(int)sSize.Width + 1, (int)sSize.Height + 1);

    e.Graphics.DrawRectangle(pen, r);
    e.Graphics.DrawString(s, font, brush, 10.0f, 200.0f);

    base.OnPaint (e);
    }

    'VB
    Imports System.Drawing

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
    Dim s As String = "Hello World"

    Dim pen As New Pen(Color.Fuchsia)
    Dim font As New Font("Arial", 18, FontStyle.Regular)
    Dim brush = New SolidBrush(Color.Black)

    Dim sSize As SizeF = e.Graphics.MeasureString(s, font)

    Dim r As New Rectangle(9, 199, Fix(sSize.Width) + 1, Fix(sSize.Height) + 1)

    e.Graphics.DrawRectangle(pen, r)
    e.Graphics.DrawString(s, font, brush, 10F, 200F)

    MyBase.OnPaint(e)

    End Sub 'OnPaint
    2.7. Can I set the width of a pen?

    Setting the pen width is not available in the .NET Compact Framework. Some alternate solutions include:

    • Drawing filled rectangles with the Graphics.FillRectangle method
    • Drawing multiple lines next to each other
    • Writing a custom graphics routine with GAPI
    2.8. How do I zoom an image?

    While there is no inherent support for zooming or stretching a single image, these effects can be achieved quite easily by creating a new Bitmap object with an associated Graphics object and copying the desired portion of the original Bitmap into it. The following sample creates two bitmaps of the same size, where the second contains a zoomed center section of the first, provided the project has an embedded resource named MyImage.bmp. This same technique could be used to stretch images by modifying the source and destination rectangles such that they do not maintain their original aspect ratio.
    //C#
    using System.Drawing;
    using System.Reflection;

    Bitmap m_bmpOriginal;
    Bitmap m_bmpZoom;

    private void Form1_Load(object sender, System.EventArgs e)
    {
    Assembly asm = Assembly.GetExecutingAssembly();
    m_bmpOriginal = new Bitmap(asm.GetManifestResourceStream(asm.GetName().Name
    + ".MyImage.bmp"));

    // Take the center quarter of m_bmpOriginal
    // and create stetch it into m_bmpZoom of the same size
    m_bmpZoom = new Bitmap(m_bmpOriginal.Width, m_bmpOriginal.Height);
    Graphics gZoom = Graphics.FromImage(m_bmpZoom);

    Rectangle srcRect = new Rectangle(m_bmpOriginal.Width / 4, m_bmpOriginal.Height / 4,
    m_bmpOriginal.Width / 2, m_bmpOriginal.Height / 2);
    Rectangle dstRect = new Rectangle(0, 0, m_bmpZoom.Width, m_bmpZoom.Height);
    gZoom.DrawImage(m_bmpOriginal, dstRect, srcRect, GraphicsUnit.Pixel);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
    e.Graphics.DrawImage(m_bmpOriginal, 0, 0);
    e.Graphics.DrawImage(m_bmpZoom, 125, 0);
    base.OnPaint (e);
    }

    'VB
    Imports System.Drawing
    Imports System.Reflection

    Private m_bmpOriginal As Bitmap
    Private m_bmpZoom As Bitmap

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim asm As [Assembly] = [Assembly].GetExecutingAssembly()
    m_bmpOriginal = New Bitmap(asm.GetManifestResourceStream((asm.GetName().Name _
    + ".MyImage.bmp")))

    ' Take the center quarter of m_bmpOriginal
    ' and create stetch it into m_bmpZoom of the same size
    m_bmpZoom = New Bitmap(m_bmpOriginal.Width, m_bmpOriginal.Height)
    Dim gZoom As Graphics = Graphics.FromImage(m_bmpZoom)

    Dim srcRect As New Rectangle(m_bmpOriginal.Width / 4, m_bmpOriginal.Height / 4, _
    m_bmpOriginal.Width / 2, m_bmpOriginal.Height / 2)
    Dim dstRect As New Rectangle(0, 0, m_bmpZoom.Width, m_bmpZoom.Height)
    gZoom.DrawImage(m_bmpOriginal, dstRect, srcRect, GraphicsUnit.Pixel)
    End Sub 'Form1_Load

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    e.Graphics.DrawImage(m_bmpOriginal, 0, 0)
    e.Graphics.DrawImage(m_bmpZoom, 125, 0)
    MyBase.OnPaint(e)
    End Sub 'OnPaint
    2.9. Why can't I load an image?

    Ensure that imgdecmp.dll is in the device's Windows directory.

    For more information, see the topic "1.31. How do include imgdemp.dll in an emulator image?" of this FAQ.



    3. 發(fā)布

    3.1. 怎樣建立一個PocketPC的設(shè)置程序?

    這篇文章告訴您如何建立一個單獨(dú)的.msi文件,可以運(yùn)行并把應(yīng)用安裝到不同的Pocket PC設(shè)備上。整個過程都是自動的,所以很容易把所有需要的組件都打包到.msi文件中。包含C#和Microsoft Visual Basic .NET代碼。
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfdeployment.asp

    3.2. 哪個發(fā)布包可以包括在我的安裝程序中?

    您可以為您的用戶提供一個最終的發(fā)布包,以幫助他們升級設(shè)備。您不能拆開這個發(fā)布包把內(nèi)容給您的用戶。但是,您可以拆開開發(fā)人員的發(fā)布包把內(nèi)容給您的用戶。

    3.3. 怎樣可以建立一個不需要.net框架的安裝程序?

    這篇文章討論了如何成功的安裝一個Pocket PC的應(yīng)用:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnppc2k/html/ppc_allation.asp

    3.4. 怎樣建立不受PocketPC系統(tǒng)約束的CAB安裝文件?

    您可以建立一個.inf文件生成一個適合任何Pocket PC設(shè)備的應(yīng)用程序安裝文件。查看示例代碼:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/cabfile.aspx

    3.5. 為什么不同的處理器會有不同的CAB安裝文件?

    每一個CAB文件都包含一小段檢測智能設(shè)備上的.net精簡框架版本的代碼。這個功能是處理器/平臺特有的,不同的CAB文件根據(jù)處理器類型綁定不同的代碼。

    3.6. How do I create a desktop installer that detects the presence of the .NET Compact Framework on the target device and installs it if necessary?


    The article titled "Creating an MSI Package that Detects and Updates the .NET Compact Framework" in the MSDN Library describes a technique that may be used:
    http://msdn.microsoft.com/mobility/understanding/articles/default.aspx?pull=/library/en-us/dnnetcomp/html/netcfdepl.asp

    3.7. How do I deploy a .NET Compact Framework Service Pack to the emulator?

    Download and install to your desktop development PC a "Developer" version of the service pack (the download title will read something like: "Microsoft?? .NET Compact Framework 1.0 SPx Developer Redistributable") from:
    http://msdn.microsoft.com/mobility/downloads/updates/default.aspx

    The next step is to copy the appropriate .NET Compact Framework cab file (as per next paragraph) to the emulator. From within the emulator point File Explorer to a share on your PC and then copy and paste the cab to somewhere on the emulator's file system. Now launch the cab file from File Explorer and answer "Yes" if asked to overwrite anything.

     

    Emulator

    CAB File

    Pocket PC 2002 netcf.core.ppc3.x86.cab
    Windows Mobile 2003 for Pocket PC netcf.core.wce4.x86.cab
    Windows Mobile 2003 for Smartphone RAM installs not supported

    3.8. How do I include SQL Server CE with my application installation?

    To install SQL Server CE with an application, simply install the proper SQL Server CE CAB files as part of the application's installation. There are two sets of cabs associated with SQL Server CE.

    The developer CAB includes Query Analyzer, and error strings. This CAB should not be included with application deployment. It comes in two actual files, one for Pocket PC and one for Windows CE 4.x devices:

    sqlce.dev.ppc3.<processor>.cab
    sqlce.dev.wce4.<processor>.cab

    The SQL Server CE CAB, which includes the engine, client agent, and managed extensions for the client agent is required by applications utilizing System.Data.SqlServerCe components. This CAB also comes in two actual files, one for Pocket PC and one for Windows CE 4.x devices:

    sqlce.ppc3.<processor>.cab
    sqlce.wce4.<processor>.cab

    Applications that access SQL Server, ie applications utilizing System.Data.SqlClient components should deploy the 'sql' CAB. This CAB also comes in two actual files, one for Pocket PC and one for Windows CE 4.x devices:

    sql.ppc3.<processor>.cab
    sql.wce4.<processor>.cab

    All of these CABs are included in the Visual Studio .NET 2003 Professional Edtion install. The default location is:

    \Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\...

    3.9. How do I use GAPI to create a graphics engine?

    This article describes how to create a DLL that wraps GAPI (Game API), such that it is .NET Compact Framework compliant, and use it to create and optimize a basic graphics library in managed code.
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/WrapGAPI1.asp

    This article expands upon the "Dancing Rectangles" sample by implementing loading and displaying of bitmaps. It also implements some more advanced features such as animated bitmaps, source and destination key transparency, and alpha blending, i.e., translucency.
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/WrapGAPI2.asp

    This article expands upon the "Dancing Zombies" sample by implementing drawing of points, lines, and custom 1 bit fonts converted from 8 bit bitmaps. It also implements an input system that overrides the functionality of the hardware buttons and tracks button states.
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/WrapGAPI3.asp  

    4. 圖形用戶界面(GUI): 窗體

    4.1. 怎樣建立一個全屏的窗體?

    您必須把WindowState屬性設(shè)置為最大化。做一個看不見的窗體,如把全屏的圖片放到窗體中,您需要把FormBorderStyle設(shè)置為None,關(guān)掉ControlBox刪掉窗體中所有的菜單。

    //C#
    this.WindowState = FormWindowState.Maximized;
    this.FormBorderStyle = FormBorderStyle.None;
    this.ControlBox = false;
    this.Menu = null;

    'VB
    Me.WindowState = FormWindowState.Maximized
    Me.FormBorderStyle = FormBorderStyle.None
    Me.ControlBox = False
    Me.Menu = Nothing
    4.2. 什么時候用窗體的構(gòu)造器?什么時候用窗體的Load事件?

    窗體的load功能是做界面操作的最好方法。典型又安全的做法是在構(gòu)造器中創(chuàng)建數(shù)據(jù)和控件的實例。任何包含用戶界面的控件或窗體的初始化,都應(yīng)該在 load功能中完成。例如:在窗體的構(gòu)造器中完成控件對象的建立,然后在load功能中設(shè)置控件的位置等 是安全的做法。

    4.3. 怎樣把最小化按鈕換成關(guān)閉按鈕?

    通過開發(fā)環(huán)境的設(shè)計器,可以把窗體的自動最小化模式轉(zhuǎn)變成關(guān)閉模式,或者通過變成實現(xiàn)。(x)按鈕自動最小化應(yīng)用程序,(ok)按鈕回關(guān)閉程序。

    在設(shè)計器中轉(zhuǎn)化窗體的風(fēng)格
    打開Visual Studio環(huán)境的窗體設(shè)計器,查看屬性。在窗體上右鍵并選擇Properties,Window Style 部分把MinimizeBox設(shè)置為 False。

    在代碼中轉(zhuǎn)變窗體風(fēng)格
    簡單的在窗體的load功能中添加以下一行代碼:
    //C#
    this.MinimizeBox = false;

    'VB
    Me.MinimizeBox = False
    4.4. 怎樣在.net精簡框架上建立多窗體系統(tǒng)結(jié)構(gòu)?

    這篇文章討論了如何在.net精簡框架上為應(yīng)用程序有效的建立用戶界面:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfuiframework.asp

    4.5. 怎樣提高.net精簡框架應(yīng)用程序的載入速度?

    通過下面文章中的優(yōu)化技巧,減少.net精簡框架應(yīng)用程序的載如時間:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfimproveformloadperf.asp

    4.6. 運(yùn)行時怎樣修改窗體的風(fēng)格?

    這篇快速入門教程描述了在pocket pc應(yīng)用程序中使用代碼改變窗體界面:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/ppcformproperties.aspx

    4.7. 怎樣滾動窗體的內(nèi)容?

    這篇快速入門教程演示了如何使用縱向和橫向滾動條 還有如何在窗體中繪制一個圖象:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/scrolling.aspx

    4.8. 怎樣制作一個浮動的窗體?好象所有的窗體總是全屏狀態(tài)的。

    有邊界的最頂端的窗體總是全屏的,不能移動或改變大小。沒有邊界或子窗體可以移動和改變大小。

    使用: Form.BorderStyle = BorderStyle.None;  //來設(shè)置有無邊界

    4.9. 怎樣強(qiáng)迫一個窗體變成最小化?

    請查看本問 "6.6. 如何是窗口一直保持最小化? " 部分。

    4.10. 我有一個包含很多控件的智能設(shè)備窗體,為什么運(yùn)行的時候出現(xiàn)"NotSupportedException"錯誤?

    如果你的窗體中包含了很多控件,當(dāng)你運(yùn)行的時候可能會有NotSupportedException的錯誤。如果你是在Debug模式下運(yùn)行的話,你會發(fā)現(xiàn)異常是來自于窗體的InitializeComponent部分。這種情況是由于精簡框架CLR在編譯類的方法時,會有64kb的限制造成的。這意味著 CLR把方法(如,InitializeComponent)翻譯成中間語言時,返回的機(jī)器碼不能超過64KB。如果超過了64KB, NotSupportedException將被拋出。這也是為什么容易在Debug模式(F5)下導(dǎo)致錯誤,而非Debug模式(Ctrl+F5)卻不容易出錯。因為Debug模式運(yùn)行時會生成更多容量的調(diào)試代碼。

    除了模擬器,您也可能在智能設(shè)備上遇到這個錯誤,因為即時編譯代碼根據(jù)因CPU類型而異的(如,PocketPC使用的是ARM指令,而模擬器上使用的x86指令)

    沒有一個準(zhǔn)確的數(shù)字說明,一個窗體中到底可以包含多少個控件。因為不同控件的產(chǎn)生的代碼量不一樣。如,一個Button控件,比TabControl控件產(chǎn)生的代碼要少。還會因由設(shè)置了多少屬性而異。包含集合的控件,象ListBox或TreeView,如果在設(shè)計時向?qū)傩钥蛑刑钊肓撕芏嘀担幾g時將產(chǎn)生大量代碼。同樣,設(shè)置了Localized的窗體(Localizable屬性為true),會比沒設(shè)置localize的窗體產(chǎn)生更多代碼。因為 localize需要從資源文件中讀取屬性值,放在InitializeComponent方法中。

    果你遇到這種情況,下面有一些技巧幫助你避免它的發(fā)生:
    • 把一個窗體的代碼分成多個窗體。過多控件的窗體,會影響程序開始時載入的性能。盡可能把用戶界面分成兩個或多個窗體。
    • 不要在設(shè)計時填充大的、內(nèi)部的、帶集合的控件。如果你把很多節(jié)點(diǎn)集合加到TreeView控件中,這樣會在InitializeComponent方法中加入大量代碼。盡可能把加入集合的代碼移到Form.Load事件中。這樣做的缺點(diǎn)是,要在設(shè)計時編輯這些集合將變得不容易,但它有助于分割代碼。
    • 不要把自己的代碼添加到InitializeComponent方法中,這對通常的編碼都有用,不建議添加、修改設(shè)計起生成的代碼。這樣做會造成設(shè)計器不可知的錯誤。如果你想添加自己的啟動代碼,你應(yīng)該在Form.Load事件中做。
    • 運(yùn)行時初始化類似的控件。比如,有12個Button控件,只是文字和位置不同,你應(yīng)該考慮使用循環(huán)來設(shè)置屬性,而不是在設(shè)計時設(shè)置屬性。在次,如果你自己寫代碼來實現(xiàn)它,不要把代碼放在InitializeComponent方法中。

    編輯InitializeComponent方法的缺點(diǎn)是,在InitializeComponent代碼外建立對象實例的代碼,將不能在設(shè)計器重被設(shè)計。同樣,如果你手動修改了InitializeComponent中的代碼,你會發(fā)現(xiàn),設(shè)計器可能不再識別你修改的代碼。所以以上技巧的前提是,不要修改InitializeComponent中的代碼。

    4.11. 哪個是正確關(guān)閉窗體的方法:Appplication.Exit 還是 Form.Close ?

    Application.Exit是類似Win32平臺下的PostQuitMessage()硬性退出。收回所有彈出的信息,釋放呼叫堆棧,把執(zhí)行權(quán)返回給系統(tǒng)。

    在windows平臺(Win32或.NET)下正確關(guān)閉應(yīng)用程序的方法是關(guān)閉主窗體(如:Form.Close)。所有主窗體結(jié)束時仍存在的窗體需要手工關(guān)閉。Any window that's still present after the main message pump ends needs to be manually closed. 好的方法就是在應(yīng)用程序調(diào)用Form.Close或Form.Dispose退出之前,關(guān)閉所有窗體。需要記住.NET框架的OnClosing()就是Win32平臺下WM_CLOSE的托管版本,而不是WM_DESTROY。

    另外,使用form.Close()的話,你的程序可以在OnClosing或OnClosed事件中處理釋放資源、關(guān)閉文件等操作。如果使用Application.Exit退出,這些事件將不會被觸發(fā)。


    4.12. Why does showing a MessageBox on Windows Mobile 2003 for Smartphone with the Abort, Retry, and Fail set of buttons or the Yes, No, Cancel set of buttons, or the third button as the default button result in a NotSupportedException?

    Windows Mobile 2003 for Smartphone only supports 1 or 2 button MessageBoxes.

    4.13 How do I get an icon in the Pocket PC Start Menu Most Recently Used (MRU) List?

    Create a shortcut to your application somewhere under \windows\start menu\programs. When your application is launched from this shortcut an icon for your applications will appear the MRU list.



    4.14 How do I center a Form on the screen?

    In order to display a non-full screen Form, ensure that the Form's FormBorderStyle property is set to FormBorderStyle.None. To center the form add the following code to the Form's FormLoad event handler: Set FormBorderStyle to FormBorderStyle.None then:
    //c#
    Rectangle screen = Screen.PrimaryScreen.Bounds;
    this.Location = new Point((screen.Width - this.Width) / 2,
    (screen.Height - this.Height ) / 2);

    'VB
    Dim theScreen As Rectangle
    theScreen = Screen.PrimaryScreen.Bounds()
    Me.Location = New Point((theScreen.Width - Me.Width) / 2, _
    (theScreen.Height - Me.Height) / 2)
    4.15 Why can't I show a Form that has been closed?

    Once a Form is closed, it is disposed and therefore may be garbage collected by the system so it is not safe to attempt to show a closed Form. An alternative solution is to use Form.Hide and Form.Show to hide and display Forms respectively.

    4.16 How can I enable multiple instances of an application?

    Multi-instancing is not supported by the .NET Compact Framework. The following code sample provides a solution that allows applications to be instanced rather than maximized when an application is launched but a running instance already exists.

    Note: The following code is not supported and is not guaranteed to work on all versions of the OS, including future versions.
    // C#
    using System.Runtime.InteropServices;
    using System.Reflection;

    private void Form1_Load(object sender, System.EventArgs e)
    {
    this.Text = string.Format("Form {0}", new Random().Next());
    }

    [DllImport("CoreDll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("CoreDll")]
    public static extern int SetWindowText(IntPtr hWnd, string lpString);

    protected override void OnResize(EventArgs e)
    {
    Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
    IntPtr hWnd = FindWindow("#NETCF_AGL_PARK_",
    asm.GetModules()[0].FullyQualifiedName);

    if (hWnd != IntPtr.Zero)
    SetWindowText(hWnd, "#42");

    base.OnResize (e);
    }

    'VB
    Imports System.Runtime.InteropServices
    Imports System.Reflection

    Private Sub Form1_Load(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
    Me.Text = String.Format("Form {0}", New Random().Next())
    End Sub 'Form1_Load

    <DllImport("CoreDll")> _
    Public Shared Function FindWindow(ByVal lpClassName As String, _
    ByVal lpWindowName As String) As IntPtr
    End Function

    <DllImport("CoreDll")> _
    Public Shared Function SetWindowText(ByVal hWnd As IntPtr, _
    ByVal lpString As String) As Integer
    End Function

    Protected Overrides Sub OnResize(ByVal e As EventArgs)
    Dim asm As [Assembly] = System.Reflection.Assembly.GetExecutingAssembly()
    Dim hWnd As IntPtr = FindWindow("#NETCF_AGL_PARK_", _
    asm.GetModules()(0).FullyQualifiedName)
    If hWnd.ToInt32() <> IntPtr.Zero.ToInt32() Then
    SetWindowText(hWnd, "#42")
    End If
    MyBase.OnResize(e)
    End Sub 'OnResize

     


    5. 圖形用戶界面 (GUI): 通用


    5.1. 怎樣建立一個帶有圖形或支持多行的按鈕?

    建立一個帶有圖形或支持多行的按鈕需要使用自定義控件。自定義控件能繼承button的paint方法,以及其他任何需要的自定義數(shù)據(jù)。參考以下連接獲得更多關(guān)于自定義控件的信息:

    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/customctrlscompactfx.asp

    快速入門教程告訴你如何建立一個帶圖像的按鈕:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/picturebutton.aspx

    5.2. TextBox.AcceptsReturn在.net精簡框架下是怎樣工作的?

    雖然設(shè)置了AcceptsReturn為false,但它還是按true的方式來操作。你可以寫一個繼承TextBox的類,在KeyPress事件中實現(xiàn)對Enter的處理。

    5.3. 當(dāng)數(shù)據(jù)載入ComboBox的時候,為什么SelectedIndexChanged事件沒有被觸發(fā)?

    這是一個已經(jīng)知道的問題,將在以后的.net精簡框架中發(fā)布。

    5.4. Show和ShowDialog有什么不同?

    ShowDialog會把一個窗體以 模式 方式顯示,這是一種獨(dú)占調(diào)用方式,知道窗體關(guān)閉才會返回。這個方法將返回一個DialogResult枚舉,表示關(guān)閉的條件。
    Show是一種非獨(dú)占的調(diào)用方式,和顯示一個控件一樣,可以立刻返回,沒有返回參數(shù)。顯示一個控件意味著Visible屬性被設(shè)置為true,直到Hide方法被調(diào)用,Visible方法才會變?yōu)閒alse。

    5.5. 為什么我不能建立右鍵菜單分離器?(separator)

    這是一個已經(jīng)知道的BUG,把右鍵菜單設(shè)置為分割線,將拋出NotSupportedException錯誤。這個問題是由于WinCE系統(tǒng)有個限制,不允許在已經(jīng)加入右鍵菜單的菜單項設(shè)置為分隔符,并且菜單的父類是一個控件。在Visual Studio 2003種,設(shè)計器分割移動應(yīng)用代碼的方式和PC上的應(yīng)用程序類似。這是導(dǎo)致此問題的原因。解決的方法是,把右鍵菜單單獨(dú)放在InitilizeComponent方法外的地方。

    5.6. 運(yùn)行時把ImageList賦給ToolBar時,為什么圖象不出現(xiàn)?

    你可以在窗體載入的時候把ImageList分配給ToolBar,但重新應(yīng)用圖像在ToolBar上的順序。在設(shè)置ToolBar的ImageList之前 設(shè)置ToolBar按鈕的圖像順序是不被支持的。

    5.7. 怎樣把光標(biāo)設(shè)置成等待狀態(tài)?

    這段代碼可以把光標(biāo)設(shè)置成等待光標(biāo):

  • //C#
    Cursor.Current = Cursors.WaitCursor;

    'VB
    Cursor.Current = Cursors.WaitCursor
    這段代碼可以把光標(biāo)設(shè)置為默認(rèn):
    //C#
    Cursor.Current = Cursors.Default;

    'VB
    Cursor.Current = Cursors.Default
    5.8. 如何在菜單項中顯示符號:&?

    這項功能還不被.net精簡框架支持。使用"&&"不會在菜單項的文字中顯示"&"符號。

    5.9. 如何制作基于.net精簡框架的動畫控件?

    這篇文章將告訴你如何制作基于.net精簡框架的動畫控件:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/animationcontrol.asp

    5.10. 如何在.net精簡框架上制作自定義控件?

    學(xué)習(xí)制作.net精簡框架控件,提高您的技巧。(文章附帶了自定義控件的示例代碼):
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/customctrlscompactfx.asp

    5.11. 如何制作基于.net精簡框架的帶圖片的按鈕?

    這篇文章討論了建立基于.net精簡框架的帶圖片的按鈕:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/ImageButton.asp

    5.12. 如何使用.net精簡框架下的MessageWindow類庫?

    學(xué)習(xí)如何使用.net精簡框架 MessageWindow 類建立一個提示圖標(biāo):
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/messagewindow.asp

    這篇快速入門實現(xiàn)了,當(dāng)鼠標(biāo)點(diǎn)擊矩形自定義控件或點(diǎn)擊Panel控件時,使用MessageWindow把消息發(fā)送給發(fā)送窗體:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/messagewindow.aspx

    5.13. 如何向DataGrid中添加行和列?

    這篇快速入門教程解釋了如何在運(yùn)行時向DataGrid控件添加或刪除行、列:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/datagridadding.aspx

    5.14. 如何實現(xiàn)DataGrid的編輯?

    .net精簡框架中的DataGrid控件提供了幾乎.net框架中的DataGrid控件的所有功能。一個主要的區(qū)別是.net精簡框架中的DataGrid不能在運(yùn)行時編輯單元。這篇快速入門教程演示了如何通過程序?qū)崿F(xiàn)編輯單元格的一種方法:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/datagridediting.aspx

    5.15. 怎樣設(shè)置DataGrid的DataSource?

    與.net框架的DataGrid的另一個區(qū)別是,.net精簡框架的DataGrid不支持把DataSource設(shè)置為DataSet。
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/datagrid.aspx

    5.16. 怎樣對DataGrid的列排序?

    與.net框架的DataGrid的另一個區(qū)別是,.net精簡框架的DataGrid不支持在運(yùn)行時按照列進(jìn)行排序。
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/datagridsorting.aspx

    5.17. 怎樣對ListView中的內(nèi)容排序?

    .net精簡框架不支持ListView.Sort方法,但任然可以排序。這篇快速入門教程定義了一個繼承ArrayList.Sort的IComparable接口的方法:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/listviewsort.aspx

    5.18. 如何使用 輸入板(SIP)控件?

    這篇快速入門教程演示了在PocketPC上打開和關(guān)閉軟輸入板(SIP),以及當(dāng)SIP顯示時,tab控件大小也跟隨變化:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/inputpanel.aspx

    多個窗體應(yīng)該共享一個輸入板對象?梢酝ㄟ^先在主窗體中建立SIP對象,然后把它傳給子窗體或暴露SIP對象的一些方法、屬性給其他需要使用SIP的窗體。

    5.19. 如何自定義事件?

    這篇快速入門教程描述了如何繼承Button類、重載方法來事現(xiàn)雙擊事件。這個自定義事件會在按鈕被雙擊時觸發(fā),兩次點(diǎn)擊的間隔時間是SystemInformation.DoubleClickTime 屬性的值,以毫秒為單位。
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/btndclick.aspx

    .net精簡框架的控件不支持OnEnter和OnLeave方法,包括Windows.Forms.Control基類。但是,因為支持Control.OnMouseMove方法,您可以通過它和Control.Capture 屬性判斷鼠標(biāo)什么時候進(jìn)入和離開控件。
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/enterleave.aspx

    5.20. 如何做一個 owner-drawn List Box?

    您可以制作一個.net精簡框架的owner drawn list box。.net精簡框架的ListBox或其他控件不支持DrawMode、DrawItem, 或其他drawing方法,但您可以編程實現(xiàn)。這篇快速入門教程提供一個自定義控件類,建立一個owner-drawn list box,并實現(xiàn)了選擇字體的控件的功能。
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/ownerdrawnlistbox.aspx

    5.21. 如何做一個多選框判斷真假?

    這篇快速入門教程提供了在Windows.Forms.CheckBox控件上建立真/假多選框:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/tfcheckbox.aspx

    5.22. 設(shè)置InputPanel.Enabled = true的時候為什么出現(xiàn)異常?

    InputPanel組件需要窗體包含MainMenu控件,而且那個窗體是顯示在屏幕上的。

    5.23. 為什么自定義控件不會自動繼承父類的字體?

    這個功能不被.net精簡框架所支持。

    5.24. 為什么當(dāng)輸入字符時,NumericUpDown 和 DomainUpDown 控件不會引發(fā) ValueChanged 和 SelectedItemChanged 事件?

    在代碼中改變控件的值 或 按下了上、下箭頭才會觸發(fā)ValueChanged和SelectedItemChanged事件。當(dāng)用戶往控件中輸入字符的時候時不會觸發(fā)的。

    5.25. 為什么NumericUpDown控件增長的值不是設(shè)置好的值?

    當(dāng)您按了上、下后出現(xiàn)的值,不是增長值的倍數(shù),它將向著那個方向(上或下)直到下一個增長值的倍數(shù)的值。

    5.26. 為什么StatusBar不能放在窗體的任意位置?一定要在底部?

    StatusBar控件只能?吭诖绑w的底部,它的大小不能改變。

    5.27. 為什么我的控件自動繼承了父控件的背景色?

    這個功能不被.net精簡框架所支持?梢圆扇〉姆椒ㄊ抢^承OnParentChanged方法手動設(shè)置顏色:
    //C#
    protected override void OnParentChanged(EventArgs e)
    {
    base.OnParentChanged(e);
    this.BackColor = Parent.BackColor;
    }

    'VB
    Protected Overrides Sub OnParentChanged(ByVal e As EventArgs)
    MyBase.OnParentChanged(e)
    Me.BackColor = Parent.BackColor
    End Sub 'OnParentChanged
    5.28. 為什么NumericUpDown控件能接受decimal類型的值,但不會顯示大于2^16的值?

    雖然NumericUpDown控件接受decimal類型的值,但.net精簡框架把這個控件的值當(dāng)作int類型來處理。如,10.23當(dāng)作10。同樣此控件在PocketPC上不接受大于帶符號的16位整型。

    5.29. 為什么不能在DomainUpDown 中輸入文字,而要選擇?

    DomainUpDown控件不會對輸入的文字進(jìn)行確認(rèn)(不象完整的.net框架)。如果您先輸入了一些文字,再按上、下箭頭,它會顯示內(nèi)容改變前的值的下一個值。

    5.30. 為什么OpenFileDialog被限制在"My Documents" 文件夾中?

    OpenFileDialog的初始化目錄被限制在"My Documents"文件夾或它的子文件夾中。這個限制是由PocketPC系統(tǒng)強(qiáng)加的,為了幫助用戶在標(biāo)準(zhǔn)目錄下管理自己的文檔。
      5.31. How can I activate the SIP (InputPanel) without a menu?

    The SIP can be activated by P/Invoking the function "SipShowIM" as follows.
    //C#
    using System.Runtime.InteropServices;

    const uint SIPF_OFF = 0x0;
    const uint SIPF_ON = 0x1;

    [DllImport("coredll.dll")]
    private extern static void SipShowIM(uint dwFlag);

    'VB
    Imports System.Runtime.InteropServices

    Const SIPF_OFF As Integer = &H0
    Const SIPF_ON As Integer = &H1

    <DllImport("coredll.dll")> _
    Private Shared Function SipShowIM(ByVal dwFlag As Integer) As Integer
    End Function
    5.32. How do I add a subnode to every node in a TreeView?

    Adding subnodes to all nodes is accomplished by iterating through all of the nodes in the TreeView and adding a new node to each.
    //C#
    foreach (TreeNode node in treeView1.Nodes)
    {
        node.Nodes.Add(new TreeNode("SubNode"));
    }

    'VB
    Dim node As TreeNode
    For Each node In  treeView1.Nodes
        node.Nodes.Add(New TreeNode("SubNode"))
    Next node
    5.33. How do I determine the number of rows or columns in a DataGrid?

    The number of rows and columns in a DataGrid can be determined from the data source itself. For example:
    //C#
    DataSet ds = new DataSet();

    int numRows = ds.Tables[0].Rows.Count;
    int numCols = ds.Tables[0].Columns.Count;

    'VB
    Dim ds As New DataSet()

    Dim numRows As Integer = ds.Tables(0).Rows.Count
    Dim numCols As Integer = ds.Tables(0).Columns.Count
    If the DataGrid is bound to the DataView you can also use DataView.Count.

    5.34. How do I create a owner drawn Listbox?

    See the .NET Compact Framework QuickStarts, Implementing Events topic:

    http://samples.gotdotnet.com/quickstart/compactframework/doc/btndclick.aspx

    5.35. How can I implement Control.GetNextControl under the .NET Compact Framework?

    The tab order of the controls in the .NET Compact Framework correspond directly to the order of the Controls in the Form.Controls collection. Therefore, GetNextControl can be implemented by determining the index of the specified Control and determing its neighbors in the collection.
    //C#
    public Control GetNextControl(Control ctl, bool forward)
    {
    int curIndex = this.Controls.IndexOf(ctl);

    if (forward)
    {
    if (curIndex < this.Controls.Count)
    curIndex++;
    else
    curIndex = 0;
    }
    else
    {
    if (curIndex > 0)
    curIndex--;
    else
    curIndex = this.Controls.Count - 1;
    }

    return this.Controls[curIndex];
    }

    'VB
    Public Function GetNextControl(ByVal ctl As Control, _
    ByVal forward As Boolean) As Control
    Dim curIndex As Integer = Me.Controls.IndexOf(ctl)

    If forward Then
    If curIndex < Me.Controls.Count Then
    curIndex += 1
    Else
    curIndex = 0
    End If
    Else
    If curIndex > 0 Then
    curIndex -= 1
    Else
    curIndex = Me.Controls.Count - 1
    End If
    End If

    Return Me.Controls(curIndex)

    End Function 'GetNextControl
    5.36. How do I get notified when the user clicks on a treeview node?

    TreeView does not support the Click event, however, a workaround is to use the AfterSelect event instead.

    5.37. How do I set the title of a fullscreen multiline edit control window?

    This is not supported by the current version of the .NET Compact Framework.

    5.38. Why don' I see the validItem selected when I set ComboBox.SelectedValue to validItemInCollection?

    Setting the SelectedValue property only works if the control is databound.

    5.39. How do I detect the location where a 'tap & hold' occurred to bring up a context menu on my custom control?

    Handle the ContextMenu.Popup event, and then query the current mouse coordinates using 'Control.MousePosition'.

    5.40. Why doesn't the scrollbar value ever get set to the maximum value?

    Similar to the NumericUpDown control, the maximum achievable value is the first empty row above the thumb. More specifically, from the editor properties, this equates to:

    Maximum - (LargeChange + 1).

    5.41. How do I tab out of a custom control to the previous control?

    Call this.Parent.Controls(this.Parent.GetChildIndex(customcontrol) - 1).Focus() in the KeyDown event handler when a Keys.Up key is detected.

    5.42. How do I add Toolbar buttons with transparency?

    Icons support transparency, however, there is a known bug in Visual Studio .NET 2003 designer that creates incorrect code and makes icons non-transparent. A work around is to add an icon file to the ImageList outside of InitializeComponent and add the icon files to the project as content or embedded resources. The following code demonstrates this:
    //C#
    using System.Drawing;
    using System.IO;
    using System.Reflection;

    // Loaded as content example
    private void Form1_Load(object sender, System.EventArgs e)
    {
    this.imageList1.Images.Add(new Icon(File.Open("fullFileName.ico",
    FileMode.Open)));

    this.toolBar1.Buttons[0].ImageIndex = 0;
    }

    // Loaded as a resource example
    private void Form1_Load(object sender, System.EventArgs e)
    {
    this.imageList1.Images.Add(new
    Icon(Assembly.GetExecutingAssembly().GetManifestResourceStream(
    ".filename.ico")));

    this.toolBar1.Buttons[0].ImageIndex = 0;
    }

    'VB
    Imports System.Drawing
    Imports System.IO
    Imports System.Reflection

    ' Loaded as content example
    Private Sub Form1_Load1(ByVal sender As Object, ByVal e As System.EventArgs)

    Me.imageList1.Images.Add(New Icon(File.Open("fullFileName.ico", _
    FileMode.Open)))

    Me.toolBar1.Buttons(0).ImageIndex = 0

    End Sub 'Form1_Load1

    ' Loaded as a resource example
    Private Sub Form1_Load2(ByVal sender As Object, ByVal e As System.EventArgs)

    Me.imageList1.Images.Add(New _
    Icon([Assembly].GetExecutingAssembly().GetManifestResourceStream( _
    ".filename.ico")))

    Me.toolBar1.Buttons(0).ImageIndex = 0

    End Sub 'Form1_Load2
     

    6. 與本地代碼(Native Code)互用

    6.1. 如何調(diào)用本地代碼寫的DLL中的函數(shù)?

    本地DLL代碼可以通過系統(tǒng)的Invoke (P/Invoke)方法調(diào)用。這些文章提供了如何實現(xiàn)調(diào)用和更多的調(diào)用技巧:

    6.2. 如何使用dumpbin.exe幫助描述 P/Invokes?

    見本問答的 "6.1. 如何調(diào)用本地寫的DLL中的函數(shù)? " 章節(jié)。

    6.3. 如何為微軟.net精簡框架寫非托管代碼?

    見本問答的 "6.1. 如何調(diào)用本地寫的DLL中的函數(shù)? " 章節(jié)。

    6.4. 如何調(diào)用 P/Invoke GetTickCount?

    不需要使用P/Invoke調(diào)用GetTickCount功能,因為Environment.TickCount就提供了這個功能。
    見本問答的 " 7.2. 如何計算精確的時間間隔?" 章節(jié)。

    6.5. 如何獲得系統(tǒng)還有多少可用內(nèi)存?

    您可以調(diào)用GetSystemMemoryDivision和GlobalMemorySystem函,數(shù)獲得程序和存儲器間有多少內(nèi)存是隔離的和已經(jīng)分配的。

    參數(shù)的說明可以在API參考文檔中找到。
    //C#
    using System.Runtime.InteropServices;

    public class MEMORYSTATUS
    {
    public uint dwLength;
    public uint dwMemoryLoad;
    public uint dwTotalPhys;
    public uint dwAvailPhys;
    public uint dwTotalPageFile;
    public uint dwAvailPageFile;
    public uint dwTotalVirtual;
    public uint dwAvailVirtual;
    }

    [DllImport("CoreDll.dll")]
    public static extern void GlobalMemoryStatus
    (
    MEMORYSTATUS lpBuffer
    );

    [DllImport("CoreDll.dll")]
    public static extern int GetSystemMemoryDivision
    (
    ref uint lpdwStorePages,
    ref uint lpdwRamPages,
    ref uint lpdwPageSize
    );

    public void Test()
    {
    uint storePages = 0;
    uint ramPages = 0;
    uint pageSize = 0;
    int res = GetSystemMemoryDivision(ref storePages, ref ramPages, ref pageSize);

    MEMORYSTATUS memStatus = new MEMORYSTATUS();
    GlobalMemoryStatus(memStatus);
    }

    'VB
    Imports System.Runtime.InteropServices

    Public Structure MEMORYSTATUS
    Public dwLength As UInt32
    Public dwMemoryLoad As UInt32
    Public dwTotalPhys As UInt32
    Public dwAvailPhys As UInt32
    Public dwTotalPageFile As UInt32
    Public dwAvailPageFile As UInt32
    Public dwTotalVirtual As UInt32
    Public dwAvailVirtual As UInt32
    End Structure 'MEMORYSTATUS

    <DllImport("coredll.dll")> _
    Private Shared Sub GlobalMemoryStatus(ByRef ms As MEMORYSTATUS)
    End Sub

    <DllImport("CoreDll.dll")> _
    Public Shared Function GetSystemMemoryDivision( _
    ByRef lpdwStorePages As UInt32, _
    ByRef lpdwRamPages As UInt32, _
    ByRef lpdwPageSize As UInt32) As Integer
    End Function

    Public Shared Sub Test()
    Dim storePages As UInt32
    Dim ramPages As UInt32
    Dim pageSize As UInt32
    Dim res As Integer = GetSystemMemoryDivision(storePages, ramPages, pageSize)

    Dim memStatus As New MEMORYSTATUS
    GlobalMemoryStatus(memStatus)
    End Sub 'Test
    6.6. 如何是窗口一直保持最小化?
    1. 繼承窗體的OnGotFocus方法。
    2. 找到窗體的窗口句柄。
    3. 調(diào)用ShowWindow(hwnd, SW_MINIMIZE)強(qiáng)制窗體最小化。
    //C#
    using System.Runtime.InteropServices;

    [DllImport("CoreDll")]
    public static extern IntPtr FindWindow(string className,string WindowsName);

    [DllImport("CoreDll")]
    public static extern bool ShowWindow(IntPtr hwnd,int nCmdShow);

    const int SW_MINIMIZE = 6;

    protected override void OnGotFocus(EventArgs e)
    {
    IntPtr hwnd = FindWindow(null, this.Text);
    ShowWindow(hwnd, SW_MINIMIZE);
    base.OnGotFocus(e);
    }

    'VB
    Imports System.Runtime.InteropServices

    <DllImport("CoreDll")> _
    Public Shared Function FindWindow(ByVal className As String, ByVal WindowsName As String) As IntPtr
    End Function

    <DllImport("CoreDll")> _
    Public Shared Function ShowWindow(ByVal hwnd As IntPtr,ByVal nCmdShow As Integer) As Boolean
    End Function

    Private Const SW_MINIMIZE As Integer = 6

    Protected Overrides Sub OnGotFocus(ByVal e As EventArgs)
    Dim hwnd As IntPtr = FindWindow(Nothing, Me.Text)
    ShowWindow(hwnd, SW_MINIMIZE)
    MyBase.OnGotFocus(e)
    End Sub 'OnGotFocus
    6.7. 在微軟.net精簡框架上調(diào)用系統(tǒng)函數(shù)時,如何裝配數(shù)據(jù)類型?

    見本問答的 "6.1. 如何調(diào)用本地寫的DLL中的函數(shù)? " 章節(jié)。

    6.8. 如何得到一個窗體或控件的句柄 (HWND) ?

    其實有一些使用調(diào)用本地代碼的方法可以獲得控件的句柄HWND。下面列出其中兩種,一種使用GetCapture,另一個使用FindWindow。
    //C#
    [DllImport("coredll.dll"]
    public static extern IntPtr GetCapture();

    [DllImport("coredll.dll")]
    public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);

    this.Text = "FindMe";
    IntPtr hwnd1 = FindWindow(null, "FindMe");

    this.Capture = true;
    IntPtr hwnd2 = GetCapture();
    this.Capture = false;

    'VB
    <DllImport("coredll.dll", SetLastError:=True)> _
    Public Shared Function GetCapture() As IntPtr
    End Function

    <DllImport("coredll.dll", SetLastError:=True)> _
    Public Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function

    Me.Text = "FindMe"
    Dim deskWin As IntPtr = FindWindow(Nothing, "FindMe")

    Me.Capture = True
    Dim hwnd As IntPtr = GetCapture()
    Me.Capture = False
    6.9. 如何使用性能計數(shù)器功能?

    使用QueryPerformanceFrequency函數(shù)和QueryPerformanceCounter函數(shù)可以建立精確的計時程序。這些功能是和設(shè)備提供商相關(guān)的,如果他們不能執(zhí)行,那么只能和GetTickCount功能得到一樣的結(jié)果。如果能執(zhí)行這些函數(shù),就能保證計時器最準(zhǔn)確的運(yùn)行,比GetTickCounter或Environment.TickCount準(zhǔn)確得多。TickCount其實是調(diào)用 GetTickCounter的。

    如果性能計數(shù)器是GetTickCount的一個實例,QueryPerformanceFrequency將把1000作為計時頻率。如果這些函數(shù)不能執(zhí)行,將得到返回值為0。以下代碼演示了如何使用這些函數(shù)。
    //C#
    [DllImport("CoreDll.dll")]
    public static extern int QueryPerformanceFrequency(ref Int64 lpFrequency);

    [DllImport("CoreDll.dll")]
    public static extern int QueryPerformanceCounter(ref Int64 lpPerformanceCount);

    private void TestTimer()
    {
    System.Int64 freq = 0;
    if (QueryPerformanceFrequency(ref freq) != 0)
    {
    System.Int64 count1 = 0;
    System.Int64 count2 = 0;

    if (QueryPerformanceCounter(ref count1) != 0)
    {
    System.Threading.Thread.Sleep(1200);
    QueryPerformanceCounter(ref count2);
    System.Int64 time_ms = (count2 - count1) * 1000 / freq;
    }
    }
    }

    'VB
    <DllImport("CoreDll.dll")> _
    Public Shared Function QueryPerformanceFrequency(ByRef lpFrequency As Int64) As Integer
    End Function

    <DllImport("coredll.dll")> _
    Public Shared Function QueryPerformanceCounter(ByRef lpPerformanceCount As Int64) As Integer
    End Function

    Private Sub TestTimer()
    Dim freq As System.Int64 = 0

    If QueryPerformanceFrequency(freq) <> 0 Then
    Dim count1 As System.Int64 = 0
    Dim count2 As System.Int64 = 0

    If QueryPerformanceCounter(count1) <> 0 Then
    System.Threading.Thread.Sleep(1200)
    QueryPerformanceCounter(count2)
    Dim time_ms As System.Int64 = (count2 - count1) * 1000 / freq
    End If
    End If
    End Sub 'TestTimer

    6.10. 調(diào)用本地代碼時,數(shù)據(jù)類型有什么限制?What are the limitations on marshalling types via P/Invoke?

    • 返回值
      • 只能是長度小于等于32位的類型
      • 非浮點(diǎn)型not floating point
    • 參數(shù)
      • Only support marshaling blittable types
        • blittable types -> same representation in memory in both managed and native
        • non-blittable -> memory transformation required
        • Since only blittable types, all objects are pinned and never copied
          • Exception: passing String ByVal in VB.NET
        • Implies that you can't marshal nested objects since this requires a memory transformation (non-blittable)
      • 只能是長度小于等于32位的類型
        • 值通過堆棧傳遞
        • 例外:float32
      • 參考(References)
        • Pass blittable reference types
        • 把參考傳遞到值類型變量
        • 這就是如何傳遞float32類型的值
      • 可以傳遞值類型的數(shù)組
        • 在本地代碼中,您可以使用指針指向第一個對象,然后一個接一個地訪問其他對象
      • String是特殊的,傳遞char數(shù)組 -> 不變的
      • StringBuilder是特殊的,傳遞char數(shù)組 -> 易變的 (需要單獨(dú)傳遞長度)
      • 注意:C# bool是8個比特位的,并且不等于Win32的BOOL
      • 隊列:編譯器默認(rèn)的隊列 (4字節(jié))
      • Marshal.GetLastWin32Error 支持 GetLastError() 語義
      • 未支持的:
        • MarshalAs: no support for non-blittable types
        • StructLayout: 不能改變外觀
        • Delegates(委托)
        • DateTime
        • Only support default calling convention

    6.11. 調(diào)用GetLastError時,總是獲得不定的代碼?

    盡量不要嘗試調(diào)用Windows GetLastError() API,因為CLR調(diào)用本地代碼時可能會改變last error的代碼。取而代之的是,使用調(diào)用的返回值標(biāo)記錯誤代碼,再調(diào)用System.Runtime.InteropServices.Marshal.GetLastWin32Error()方法來獲得錯誤代碼。
    using System.Runtime.InteropServices;

    [DllImport("coredll.dll", SetLastError=true)]
    int myFoo(...);

    Foo(...)
    {
    int rc = myFoo(...);

    if (rc == false)
    {
    throw new Win32Exception(Marshal.GetLastWin32Error(), "Foo failed");
    }
    }

    6.12. 調(diào)用本地代碼時,有沒有參數(shù)數(shù)量的限制?

    有限制。.net精簡框架版本1.0的限制為12個。

    6.13. 調(diào)用本地代碼時,為什么得到"NotSupportedException"異常?

    通常有三種可能性:
    • 在托管代碼中的申明不正確
    • .net精簡框架不支持你想做的操作
    • dll的名稱在暴露過程中損壞了

    檢查以下項目: 
    • 有沒有違反.net精簡框架 P/Invoke(調(diào)用)的限制?
    • 有沒有參數(shù)需要預(yù)先分配內(nèi)存(如,是不是指針)? 如果是的,您應(yīng)該傳遞已經(jīng)存在的變量的參考。
    • 暴露的函數(shù)名是否正確? 可以用DUMPBIN.EXE工具來驗證
    • 是不是想嘗試太多的參數(shù)?

    例如,針對上面的第二點(diǎn),RegOpenKey API的最后一個參數(shù)HKEY的指針。您應(yīng)該這樣申明和調(diào)用:
    //C#
    [DllImport("coredll.dll", SetLastError=true)]
    public static extern long RegOpenKey(
    IntPtr hkey,
    string lpSubKey,
    ref IntPtr hkeyResult
    );

    public long OpenMySubKey()
    {
    IntPtr hkey = IntPtr.Zero;
    return RegOpenKey(HKEY_CLASSES_ROOT, "MySubKey", ref hkey);
    }

    'VB
    <DllImport("coredll.dll", SetLastError:=True)> _
    Public Shared Function RegOpenKey(ByVal hkey As IntPtr, ByVal lpSubKey As String, ByRef hkeyResult As IntPtr) As Long
    End Function

    Public Function OpenMySubKey() As Long
    Dim hkey As IntPtr = IntPtr.Zero
    Return RegOpenKey(HKEY_CLASSES_ROOT, "MySubKey", hkey)
    End Function 'OpenMySubKey

    6.14. 如何把 byte[] 轉(zhuǎn)換成 IntPtr?

    有不止一種的方法訪問IntPtr。

    第一種方法,使用非安全代碼,直接用指針指向byte數(shù)組。
    //C#
    unsafe
    {
    byte[] test = new byte[5];
    fixed (byte* p = &test[0])
    {
    *p = 0xff;
    }
    }
    也可以使用GCHandle指向?qū)ο蟆?
    //C#
    using System.Runtime.InteropServices;

    byte[] test = new byte[5];
    GCHandle hObject = GCHandle.Alloc(test, GCHandleType.Pinned);
    IntPtr pObject = hObject.AddrOfPinnedObject();

    if(hObject.IsAllocated)
    hObject.Free();

    'VB
    Imports System.Runtime.InteropServices

    Dim test(4) As Byte
    Dim hObject As GCHandle = GCHandle.Alloc(test, GCHandleType.Pinned)
    Dim pObject As IntPtr = hObject.AddrOfPinnedObject()
    If hObject.IsAllocated Then
    hObject.Free()
    End If
    最后,可以使用LocalAlloc和Marshalling函數(shù)復(fù)制內(nèi)存塊得到數(shù)據(jù)塊。
    //C#
    [DllImport("coredll.dll",SetLastError=true)]
    public static extern IntPtr LocalAlloc(uint uFlags, uint uBytes);

    [DllImport("coredll.dll",SetLastError=true)]
    public static extern IntPtr LocalFree(IntPtr hMem);

    [DllImport("coredll.dll",SetLastError=true)]
    public static extern IntPtr LocalReAlloc(IntPtr hMem, uint uBytes, uint fuFlags);

    public const uint LMEM_FIXED = 0;
    public const uint LMEM_MOVEABLE = 2;
    public const uint LMEM_ZEROINIT = 0x0040;

    byte[] test = new byte[5];
    IntPtr p = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, (uint)test.Length);

    if (p == IntPtr.Zero)
    {
    throw new OutOfMemoryException();
    }
    else
    {
    Marshal.Copy(test, 0, p, test.Length);
    }

    'VB
    <DllImport("coredll.dll", SetLastError:=True)> _
    Public Shared Function LocalAlloc(ByVal uFlags As UInt32, ByVal uBytes As UInt32) As IntPtr
    End Function

    <DllImport("coredll.dll", SetLastError:=True)> _
    Public Shared Function LocalFree(ByVal hMem As IntPtr) As IntPtr
    End Function

    <DllImport("coredll.dll", SetLastError:=True)> _
    Public Shared Function LocalReAlloc(ByVal hMem As IntPtr, ByVal uBytes As UInt32, ByVal fuFlags As UInt32) As IntPtr
    End Function

    Public Const LMEM_FIXED As Integer = 0
    Public Const LMEM_MOVEABLE As Integer = 2
    Public Const LMEM_ZEROINIT As Integer = &H40

    Dim test(4) As Byte
    Dim p As IntPtr = LocalAlloc(Convert.ToUInt32(LMEM_FIXED Or LMEM_ZEROINIT), Convert.ToUInt32(test.Length))
    If p.Equals(IntPtr.Zero) Then
    Throw New OutOfMemoryException
    Else
    Marshal.Copy(test, 0, p, test.Length)
    End If

    6.15. Why do I get a MissingMethodException when I call a function from a native DLL?

    There are several issues to consider when determining the case of a MissingMethodException. When this exception occurs you should verify the following:

    For the latest Microsoft eMbedded Visual Tools and SDK downloads, visit the MSDN Mobile and Embedded Developer Center "Products & Updates" download page at:
    http://msdn.microsoft.com/mobility/downloads/updates/default.aspx

    6.16. How do I set the system time?
    You can set the system time by P/Invoking the SetSystemTime function.
    //C#
    using System.Runtime.InteropServices;

    public struct SYSTEMTIME
    {
    public ushort wYear;
    public ushort wMonth;
    public ushort wDayOfWeek;
    public ushort wDay;
    public ushort wHour;
    public ushort wMinute;
    public ushort wSecond;
    public ushort wMilliseconds;
    }

    [DllImport("coredll.dll")]
    public extern static void GetSystemTime(ref SYSTEMTIME lpSystemTime);

    [DllImport("coredll.dll")]
    public extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);

    // Set the clock ahead one hour
    SYSTEMTIME st = new SYSTEMTIME();
    GetSystemTime(ref st);
    st.wHour = (ushort)(st.wHour + 1 % 24);
    SetSystemTime(ref st);

    'VB
    Imports System.Runtime.InteropServices

    Public Structure SYSTEMTIME
    Public wYear As UInt16
    Public wMonth As UInt16
    Public wDayOfWeek As UInt16
    Public wDay As UInt16
    Public wHour As UInt16
    Public wMinute As UInt16
    Public wSecond As UInt16
    Public wMilliseconds As UInt16
    End Structure

    <DllImport("coredll.dll")> _
    Public Shared Sub GetSystemTime(ByRef lpSystemTime As SYSTEMTIME)
    End Sub

    <DllImport("coredll.dll")> _
    Public Shared Function SetSystemTime(ByRef lpSystemTime As SYSTEMTIME) As UInt32
    End Function

    'Set the clock ahead one hour
    Dim st As New SYSTEMTIME
    GetSystemTime(st)
    st.wHour = Convert.ToUInt16(((Convert.ToInt32(st.wHour) + 1)) Mod 24)
    SetSystemTime(st)
    6.17. How do I programmatically soft reset the device?

    The device can be soft reset through P/Invoking of the KernelIoControl function, as demonstrated in the code below. For more information on how to use the function and extend the functionality of this sample, refer to Visual Studio .NET Help.

    Note: On Smartphone devices, this will only work if you are signed with a privileged certificate.
    //C#
    using System.Runtime.InteropServices;

    public const uint FILE_DEVICE_HAL = 0x00000101;
    public const uint METHOD_BUFFERED = 0;
    public const uint FILE_ANY_ACCESS = 0;

    public uint CTL_CODE(uint DeviceType, uint Function, uint Method, uint Access)
    {
    return ((DeviceType << 16) | (Access << 14) | (Function << 2) | Method);
    }

    [DllImport("Coredll.dll")]
    public extern static uint KernelIoControl
    (
    uint dwIoControlCode,
    IntPtr lpInBuf,
    uint nInBufSize,
    IntPtr lpOutBuf,
    uint nOutBufSize,
    ref uint lpBytesReturned
    );

    uint ResetPocketPC()
    {
    uint bytesReturned = 0;
    uint IOCTL_HAL_REBOOT = CTL_CODE(FILE_DEVICE_HAL, 15,
    METHOD_BUFFERED, FILE_ANY_ACCESS);
    return KernelIoControl(IOCTL_HAL_REBOOT, IntPtr.Zero, 0,
    IntPtr.Zero, 0, ref bytesReturned);
    }

    private void Form1_Load(object sender, System.EventArgs e)
    {
    DialogResult r = MessageBox.Show
    (
    "Are you sure you want to reset?",
    "Test",
    MessageBoxButtons.YesNo,
    MessageBoxIcon.Question,
    MessageBoxDefaultButton.Button2
    );

    if (r == DialogResult.Yes)
    {
    ResetPocketPC();
    }
    }

    'VB
    Public Const FILE_DEVICE_HAL As Integer = &H101
    Public Const METHOD_BUFFERED As Integer = 0
    Public Const FILE_ANY_ACCESS As Integer = 0

    Public Function CTL_CODE( _
    ByVal DeviceType As Integer, _
    ByVal Func As Integer, _
    ByVal Method As Integer, _
    ByVal Access As Integer) As Integer

    Return (DeviceType << 16) Or (Access << 14) Or (Func << 2) Or Method

    End Function 'CTL_CODE

    <DllImport("Coredll.dll")> _
    Public Shared Function KernelIoControl _
    ( _
    ByVal dwIoControlCode As Integer, _
    ByVal lpInBuf As IntPtr, _
    ByVal nInBufSize As Integer, _
    ByVal lpOutBuf As IntPtr, _
    ByVal nOutBufSize As Integer, _
    ByRef lpBytesReturned As Integer _
    ) As Integer
    End Function

    Function ResetPocketPC() As Integer
    Dim bytesReturned As Integer = 0
    Dim IOCTL_HAL_REBOOT As Integer = CTL_CODE(FILE_DEVICE_HAL, _
    15, METHOD_BUFFERED, FILE_ANY_ACCESS)
    Return KernelIoControl(IOCTL_HAL_REBOOT, IntPtr.Zero, 0, _
    IntPtr.Zero, 0, bytesReturned)
    End Function 'ResetPocketPC

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles MyBase.Load
    Dim r As DialogResult = MessageBox.Show( _
    "Are you sure you want to reset?", _
    "Test", _
    MessageBoxButtons.YesNo, _
    MessageBoxIcon.Question, _
    MessageBoxDefaultButton.Button2)

    If r = DialogResult.Yes Then
    ResetPocketPC()
    End If

    End Sub 'Form1_Load
    6.18. How can I put an icon on the title bar regardless of the which form is active?

    This is not supported with the current version of the .NET Compact Framework. You can, however, P/Invoke Pocket PC's notificaiton system to do this. Refer to the following for more information:

    Sample Code:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnppc2k2/html/ppc_fications.asp

    AYGShell APIs:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceui40/html/_cerefaygshellfunctions.asp

    The native Notification APIs are: SHNotificationAdd, SHNotificationRemove, SHNotificationGetData, and SHNotificationUpdate.

    6.19. How do I disable and capture hardware buttons?

    Refer to the sample in the P/Invoke library.
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/PInvokeLib.asp#PInvokeLib_Topic03

    6.20. How do I hide the start icon?

    The Start icon can be hidden using the SHFullScreen API.
    //C#
    const uint SHFS_SHOWTASKBAR = 0x0001;
    const uint SHFS_HIDETASKBAR = 0x0002;
    const uint SHFS_SHOWSIPBUTTON = 0x0004;
    const uint SHFS_HIDESIPBUTTON = 0x0008;
    const uint SHFS_SHOWSTARTICON = 0x0010;
    const uint SHFS_HIDESTARTICON = 0x0020;

    [DllImport("aygshell.dll")]
    static extern uint SHFullScreen(IntPtr hwndRequester, uint dwState);

    [DllImport("coredll.dll")]
    public static extern IntPtr GetCapture();

    private void Form1_Load(object sender, System.EventArgs e)
    {
    Capture = true;
    IntPtr hwnd = GetCapture();
    Capture = false;
    SHFullScreen(hwnd, SHFS_HIDESTARTICON);
    }

    'VB
    Const SHFS_SHOWTASKBAR As Integer = &H1
    Const SHFS_HIDETASKBAR As Integer = &H2
    Const SHFS_SHOWSIPBUTTON As Integer = &H4
    Const SHFS_HIDESIPBUTTON As Integer = &H8
    Const SHFS_SHOWSTARTICON As Integer = &H10
    Const SHFS_HIDESTARTICON As Integer = &H20

    <DllImport("aygshell.dll")> _
    Shared Function SHFullScreen(ByVal hwndRequester As IntPtr, ByVal dwState As Integer) As Integer
    End Function

    <DllImport("coredll.dll")> _
    Public Shared Function GetCapture() As IntPtr
    End Function

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs)

    Capture = True
    Dim hwnd As IntPtr = GetCapture()
    Capture = False

    SHFullScreen(hwnd, SHFS_HIDESTARTICON)

    End Sub 'Form1_Load
    6.21. How do I enumerate, create, and terminate processes?

    Refer to the sample:
    http://msdn.microsoft.com/mobility/understanding/articles/default.aspx?pull=/library/en-us/dnnetcomp/html/processmanager.asp

    6.22. Where can I find a centralized library of P/Invoke samples?

    This sample demonstrates how to P/Invoke numerous useful native functions that are not directly available through the .NET Compact Framework. A test Form is provided that enumerates all available test procedures and allows the user to select and run them:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/PInvokeLib.asp

    6.23. How do I play and record .WAV audio files with the Waveform Audio Inteface?

    Learn how to use the Waveform Audio Interface to record and play ".wav" files:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/WaveInOut.asp

     

    7. 通用


    7.1. 如何確定應(yīng)用程序的主目錄?

    使用Reflection,應(yīng)用程序可以確定自己是從哪個目錄啟動的,也可以使用IO.Path命名空間來修改它。

    //C#
    using System.Reflection;
    using System.IO;

    // This is the full directory and exe name
    String fullAppName = Assembly.GetExecutingAssembly().GetName().CodeBase;

    // This strips off the exe name
    String fullAppPath = Path.GetDirectoryName(fullAppName);

    // This adds a file name to the path
    String splashImageName = Path.Combine(fullAppPath, "myfile.txt");

    'VB
    Imports System.IO
    Imports System.Reflection

    ' This is the full directory and exe name
    Dim fullAppName As String = [Assembly].GetExecutingAssembly().GetName().CodeBase

    ' This strips off the exe name
    Dim fullAppPath As String = Path.GetDirectoryName(fullAppName)

    ' This adds a file name to the path
    Dim splashImageName As String = Path.Combine(fullAppPath, "myfile.txt")
    學(xué)習(xí)如何獲得程序執(zhí)行的當(dāng)前目錄。在Embedded Visual Basic中,程序執(zhí)行的當(dāng)前目錄可以通過App.Path屬性獲得。執(zhí)行程序的目錄可以通過程序集的AssemblyName對象的獲得,AssemblyName對象包含了程序集的所有描述:
    http://msdn.microsoft.com/library/en-us/dncfhowto/html/HOWTOExecutingAppPath.asp

    這篇快速入門教程告訴您如何獲得您的程序集和數(shù)據(jù)文件所在的目錄。Windows CE .NET本身不支持應(yīng)用程序的當(dāng)前目錄的設(shè)置:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/getappdir.aspx

    7.2. 如何計算精確的時間間隔?

    一個應(yīng)用程序有四種方法得到時間間隔:
    • System.Environment.TickCount
      獲得一個帶符號的整型值,表示從機(jī)器啟動到調(diào)用時經(jīng)過的豪秒數(shù)。在.NET精簡框架下,這個值的誤差在0.5秒內(nèi),大多情況下會比0.5秒小。
    • GetTickCount()
      屬性Environment.TickCount就是調(diào)用GetTickCount函數(shù)的,所以沒有必要再調(diào)用本地代碼中的這個方法。
    • Performance Monitor
      可以作為壓力測試用途,但不是為最終使用的應(yīng)用程序而設(shè)計的。如需更多信息,請查看本問答的 "7.5. 如何使用性能監(jiān)視器? " 章節(jié)
    • Timers
      使用System.Threading.Timer類,可以在線程內(nèi)設(shè)定計時器,用委托(delegate)指向應(yīng)用程序 。
    • Performance Counter
      如果OEM廠商支持的話,QueryPerformanceCounter函數(shù)能提供最高精度的計時功能。
      請查看本問答的"6.9. 如何使用性能計數(shù)器功能? "章節(jié)。

    7.3. 如何把嵌入式資源當(dāng)作一個流(Stream)?

    為了能夠訪問嵌入資源,應(yīng)用程序只須簡單地引用相關(guān)的程序集(assembly)并調(diào)用GetManifestResourceStream方法。下面這個例子巖石了如何從嵌入資源中建立一個位圖:
    //C#
    using System.Reflection;

    Assembly asm = Assembly.GetExecutingAssembly();
    Bitmap bmpSprite = new Bitmap(asm.GetManifestResourceStream("AssemblyName.FileName"));

    'VB
    Imports System.Reflection

    Dim asm As [Assembly] = [Assembly].GetExecutingAssembly()
    Dim bmpSprite As New Bitmap(asm.GetManifestResourceStream("AssemblyName.FileName"))
    上面代碼中, 字符串AssemblyName部分可以在運(yùn)行時通過調(diào)用asm.GetName().Name得到。

    注意:如果AssemblyName中有空格,它將被下劃線代替,而且必須這樣訪問。

    7.4. 為什么得到一個"An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in System.dll"的錯誤?

    這是.net精簡框架的BUG。這是由于Windows CE底層的Secure Sockets Layer (SSL)的限制造成的。但是,也偶避免的方法,如果設(shè)置 req.AllowWriteStreamBuffering為true,不要設(shè)置req.ContentLength屬性,那就不會在發(fā)生這個錯誤了。

    7.5. 如何使用性能監(jiān)視器?

    性能計數(shù)器通過編輯設(shè)備注冊表建立:
    1. 建立注冊表鍵:"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETCompactFramework\PerfMonitor"
    2. 新建雙字節(jié)項,值就是計數(shù)器的名字。
    3. 把Counters的值設(shè)置為1表示允許計數(shù)器,設(shè)置為0表示禁止使用。
    設(shè)置了性能計數(shù)器后,當(dāng)程序關(guān)閉時,會建立一個文本文件"mscoree.stat"。這個文件會存放在設(shè)備的根目錄。這是一個文件每行的長度是固定的,所以導(dǎo)入Excel是非常方便的。

    注意: 計數(shù)器只能被一個運(yùn)行著的托管的程序使用。
    注意: 使用性能計數(shù)器時,會導(dǎo)致30%的性能下降。

    7.6. 如何取消一個程序的關(guān)閉?

    程序可以重載OnClosing方法,設(shè)置CancelEventArgs.Cancel為true就可以取消關(guān)閉。
    //C#
    protected override void OnClosing(CancelEventArgs e)
    {
    e.Cancel = true;
    }

    'VB
    Protected Overrides Sub OnClosing(ByVal e As CancelEventArgs)
    e.Cancel = True
    End Sub 'OnClosing
    7.7. 如何在我的程序中調(diào)用另一個應(yīng)用程序?

    您可以調(diào)用本地代碼的CreateProcess函數(shù)開始運(yùn)行第二個程序。然后調(diào)用本地代碼的WaitForSingleObject函數(shù)暫停調(diào)用的程序,直到第二個程序運(yùn)行結(jié)束。以下快速入門演示了通過PocketPC模擬器來實現(xiàn)這一操作:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/waitforsingleobject.aspx

    7.8. .net精簡框架的應(yīng)用程序會建立什么線程?

    一個.net精簡框架程序最多會產(chǎn)生4個線程:
    • 一個主應(yīng)用程序線程。
    • 一個線程控制各種時間間隔,時間間隔是供系統(tǒng)和其他應(yīng)用程序使用的。
    • 一個線程跟蹤活動的TCP/IP接口的變化(模擬Windows XP上的媒體動作,Windows CE上是沒有這些操作的)。
    • 一個執(zhí)行終止對象的線程。當(dāng)?shù)谝粋被垃圾回收的對象回收時,就被建立了。
    7.9. 如何把byte數(shù)組轉(zhuǎn)換成結(jié)構(gòu)體?

    在C++中,通過建造類型(typecasting)可以很方便和有效的保存一個類或結(jié)構(gòu)體到文件,并直接從文件中重構(gòu)出來。但托管代碼的本性決定了它不能這樣實現(xiàn)。但還是有辦法實現(xiàn)的,建立一個類,把內(nèi)存中的數(shù)據(jù)作為它的屬性讓其他類訪問。例如:
    //C#
    public class MyClass
    {
    protected byte[] m_data = null;
    // uint uiDummy
    // short sDummy

    // This is a bit unsafe so you should throw an
    // exception or assert if the byte array length is
    // not 6. A safer but less memory efficient approach
    // would be to set m_data = new byte[6] and then copy
    //bytes to m_data.
    public MyClass(byte[] bytes) {m_data = bytes;}

    // Get/Set the uint
    public uint uiDummy
    {
    get {return BitConverter.ToUInt32(m_data, 0);}
    set
    {
    Buffer.BlockCopy(BitConverter.GetBytes(value),0,m_data,0,BitConverter.GetBytes(value).Length);
    }
    }

    // Get/Set the short
    public short sDummy
    {
    get {return BitConverter.ToInt16(m_data, 4);}
    set
    {
    Buffer.BlockCopy(BitConverter.GetBytes(value),0,m_data,4,BitConverter.GetBytes(value).Length);
    }
    }
    }

    byte[] fromFile = {1,1,1,1,2,2};
    MyClass myClass = new MyClass(fromFile);

    uint test1 = myClass.uiDummy; // 0x1010101
    short test2 = myClass.sDummy; // 0x202

    myClass.sDummy = 0x0505; // Test setting the short
    uint test4 = myClass.uiDummy; // 0x1010101
    short test5 = myClass.sDummy; // 0x505

    'VB
    Public Class ByteClass
    Protected m_data As Byte() = Nothing

    ' uint uiDummy
    ' short sDummy
    ' This is a bit unsafe so you should throw an exception
    ' or assert if the byte array length is not 6. A safer
    ' but less memory efficient approach would be to set
    ' m_data = new byte[6] and then copy bytes to m_data.
    Public Sub New(ByVal bytes() As Byte)
    m_data = bytes
    End Sub 'New

    ' Get/Set the uint
    Public Property uiDummy() As UInt32
    Get
    Return BitConverter.ToUInt32(m_data, 0)
    End Get
    Set(ByVal Value As System.UInt32)
    Buffer.BlockCopy(BitConverter.GetBytes(Value),0,m_data,0,BitConverter.GetBytes(Value).Length)
    End Set
    End Property

    ' Get/Set the short
    Public Property sDummy() As Short
    Get
    Return BitConverter.ToInt16(m_data, 4)
    End Get
    Set(ByVal Value As Short)
    Buffer.BlockCopy(BitConverter.GetBytes(Value),0,m_data,4,BitConverter.GetBytes(Value).Length)
    End Set
    End Property
    End Class 'ByteClass

    Dim fromFile As Byte() = {1, 1, 1, 1, 2, 2}
    Dim testClass As New ByteClass(fromFile)

    Dim test1 As System.UInt32 = testClass.uiDummy ' 0x1010101
    Dim test2 As Short = testClass.sDummy ' 0x202
    testClass.sDummy = &H505 ' Test short
    Dim test4 As System.UInt32 = testClass.uiDummy ' 0x1010101
    Dim test5 As Short = testClass.sDummy ' 0x505
    7.10. 我可以建立一個委托(delegate)交給Invoke嗎?

    不可以。在.net精簡框架中,只有EventHandler方法可以被調(diào)用。以下代碼說明啊如何正確使用此方法:
    //C#
    public void HandleMe(object o, EventArgs e) {...}
    form.Invoke(new EventHandler(form.HandleMe));

    'VB
    Public Sub HandleMe(o As Object, e As EventArgs)
    End Sub 'HandleMe
    form.Invoke(New EventHandler(AddressOf form.HandleMe))
    Although the following will compile, it will not work properly:
    //C#
    public delegate void MyHandler();
    public void HandleMeBadly() {...}
    form.Invoke(new MyHandler(form.HandleMeBadly));

    'VB
    Delegate Sub MyHandler()
    Public Sub HandleMeBadly()
    End Sub 'HandleMeBadly
    form.Invoke(New MyHandler(form.HandleMeBadly))
    7.11. 如何在微軟.net精簡框架上使用電話API?

    查看這篇文章,學(xué)習(xí)如何在基于.net精簡框架的應(yīng)用程序中訪問電話API:

    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfphoneapi.asp

    7.12. 如何在Pocket Pc上生成GUID?

    Guid.NewGuid方法可以生成新的GUID,但在.net精簡框架中沒有此方法。閱讀這篇文章,學(xué)習(xí)如何根據(jù)GUID規(guī)范在PocketPC應(yīng)用程序中建立GUID對象:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/PPCGuidGen.asp

    7.13. 如何讓我的.net精簡框架程序和Pocket Outlook的數(shù)據(jù)結(jié)合?

    這篇文章討論了如何使用InTheHand公司的Pocket Outlook .NET組件:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/inthehandpoom.asp

    7.14. 我可以判斷.net精簡框架中一個文件的版本嗎?

    Visual Studio .NET 2003幫助中的C# Programmer's Reference提供了在.net精簡框架下使用不安全代碼調(diào)用GetFileVersionInfo函數(shù)。 這個例子帶來的問題是,這個函數(shù)是由OEM廠商決定的,并且不保證能返回正確結(jié)果。

    使用Reflection可以獲得程序集(Assembly)的版本:
    //C#
    using System.Reflection;

    String ver = Assembly.GetExecutingAssembly().GetName().Version.ToString();

    'VB
    Imports System.Reflection;

    Dim ver As String = [Assembly].GetExecutingAssembly().GetName().Version.ToString()
    7.15. 微軟.net精簡框架的后臺處理有什么相關(guān)技術(shù)?

    使用后臺處理,需要注意相關(guān)細(xì)節(jié)并小心設(shè)計。這篇文章提供一些關(guān)于后臺處理最有用的建議,文中介紹的很多觀點(diǎn)是必須說明的:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/BackgroundProcess.asp

    7.16. 在微軟.net精簡框架上使用多線程有什么技巧?

    學(xué)習(xí)如何在基于.net精簡框架的Windows窗體應(yīng)用程序中使用多線程。
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfmultithreadedapp.asp

    7.17. 如何在 智能設(shè)備應(yīng)用 中使用混淆器?

    學(xué)習(xí)如何使用PreEmptive Dotfuscator混淆器保護(hù)你的代碼。
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfobfuscation.asp

    7.18. 如何使用密碼服務(wù)對數(shù)據(jù)進(jìn)行加密或解密?

    請參考本問答的 "10.5. 寫一個捕捉Pocket PC簽名的程序n ." 部分。

    7.19. 如何在微軟.net精簡框架上獲得Windows CE設(shè)備的唯一號碼?

    學(xué)習(xí)如何使用.net精簡框架獲得Windows CE設(shè)備的設(shè)備號。
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/retrievedeviceid.asp

    你可以調(diào)用本地代碼的函數(shù)來獲得PocketPC的設(shè)備號,也就是序列號。這篇快速入門教程,演示了用MessageBox來顯示設(shè)備號。
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/deviceid.aspx

    7.20. 如何在微軟.net精簡框架的應(yīng)用程序上發(fā)送短消息?

    這篇文章演示了如何從基于.net精簡框架的應(yīng)用程序中發(fā)送短消息:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfsendsms.asp

    7.21. 不使用Control.Name,可以判斷事件的發(fā)送者嗎?

    這篇文章討論了在.net精簡框架下如何判斷事件的發(fā)送者,.net精簡框架中的控件不支持name屬性:
    http://msdn.microsoft.com/library/en-us/dncfhowto/html/HOWTOsenderevent.asp

    7.22. 如何在線程中調(diào)用方法的參數(shù)?

    在應(yīng)用程序中使用多線程,可以提高用戶界面的性能;怌ontrol提供Invoke、BeginInvoke和EndInvoke方法在控件中來建立線程。.net精簡框架不支持異步的BeginInvoke和EndInvoke調(diào)用。到現(xiàn)在,也還不支持向同步Invoke調(diào)用傳遞參數(shù)。這篇快速入門教程提供一個自定義類ControlInvoker,可以實現(xiàn)向Invoke方法中傳遞參數(shù):
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/controlinvoker.aspx

    7.23. 如何建立提醒程序和定時程序?

    這篇快速入門文章描述了使用P/Invoke定義一個用戶提醒和訂時的應(yīng)用。您可以計劃提醒窗口彈出的時間。您也可以設(shè)置一個應(yīng)用程序在特定的時間運(yùn)行或響應(yīng)某個事件。
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/notifications.aspx

    7.24. 如何播放聲音?

    這篇快速入門教程演示了使用P/Invoke播放個短WAV文件,一個是作為嵌入式資源,另一個作為一個內(nèi)容。這個窗體包含了兩個按鈕,一個播放嵌入資源的Chimes.wav,另一個按單獨(dú)的文件播放Chord.wav。
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/playsounds.aspx

    7.25. 如何使用命令行參數(shù)?

    在代碼中使用命令行參數(shù),只須簡單的定義main方法接受參數(shù)并正確處理。以下代碼演示了這個方法:
    //C#
    static void Main(string[] args)
    {
    // Do your thing here
    }

    'VB
    Shared Sub Main(ByVal args() As String)
    'Do your thing here
    End Sub
    在Visual Studio 2003中測試的時候,可以通過繼承開發(fā)環(huán)境設(shè)置命令行的參數(shù)。主菜單,選擇 Project->Project Name Properties.Property Pages對話框中,選擇 Configuration Properties->Debugging。Command Line Arguments 中輸入字符串:text box.

    7.26. 當(dāng)使用已經(jīng)釋放的對象的方法或?qū)傩缘臅r候,為什么得到一個異常?

    完整的.net框架不保證,在訪問一個已經(jīng)釋放的對象的屬性或方法時能成功。在完整的.net框架下,雖然訪問某些屬性(像Text),經(jīng)常能成功。根據(jù).net框架和.net精簡框架執(zhí)行上的區(qū)別,在.net精簡框架上訪問已經(jīng)釋放了的對象的方法或?qū)傩詴?jīng)常失敗。

    7.27. 如何獲得"Enter", "TAB", 和 "Arrow"按鍵的事件?

    使用KeyDown和KeyUp事件,可以獲得無字符的鍵(像tab)。

    現(xiàn)在,只有一些特定的控件支持key的事件(如,form, panel, textbox 和自定義控件)。在.net精簡框架SP2版本中,所有控件都將支持key事件。

    已經(jīng)知道的問題,在使用模擬器時,從鍵盤按下tab鍵將不被支持,但從軟鍵盤(SIP)上按下tab時,會有效果。

    這是VS帶的模擬器的原因造成,而不是.net精簡框架的問題。.net精簡框架觸發(fā)Key事件當(dāng)它收到系統(tǒng)傳來的WM_KEY*消息。當(dāng)您在模擬器中運(yùn)行本地代碼程序時,從鍵盤按下tab鍵并不會讓系統(tǒng)觸發(fā)WM_KEYDOWN事件。若是通過模擬器的軟鍵盤(SIP),或真正的設(shè)備,則不會有這個問題。

    7.28. 如何刪除一個只讀文件?

    使用System.IO.FileInfo類訪問文件的屬性。
    //C#
    System.IO.FileInfo fi = new System.IO.FileInfo("filename");
    // remove readonly attribute
    fi.Attributes -= System.IO.FileAttributes.ReadOnly;
    System.IO.File.Delete("filename");

    'VB
    Dim fi As New System.IO.FileInfo("filename")
    'remove readonly attribute
    fi.Attributes -= IO.FileAttributes.ReadOnly
    System.IO.File.Delete("filename")

    7.29. How do I determine if a member exists at runtime?

    The existence of a member can be determined at runtime using Reflection. The code below demonstrates how to use Reflection to access the "Width" property and the "GetPixel" method of a Bitmap object. In the case of the "Width" property, the code enumerates all "public" properties with a "get" component and then searches for one named "Width". The "GetPixel" sample demonstrates how one might use Reflection to call a known function where the parameter order is unknown. This sample is set up as if the author knows there is a method named "GetPixel" which takes a pixel location of x,y but does not know the order in which they appear in the parameter list. The sample enumerates the methods and searches for one named "GetPixel" and then enumerates the parameter list to determine whether the first or second parameter is named "X". Keep in mind that, due to the differences in hardware pixel formats, the value returned by GetPixel may be different from that set by SetPixel in this sample.

    Reflection provides many powerful tools for determing functionality at runtime so for information, refer to the documentation regarding System.Type and the namespace System.Reflection.
    //C#
    using System.Reflection;
    using System.Drawing;

    Bitmap bm = new Bitmap(200, 100);
    int width = 0;

    // Explicitly set one pixel for testing
    int x = 199;
    int y = 20;
    Color pixColor = Color.Black;
    bm.SetPixel(x,y,Color.Magenta);

    // Get the "Width" property
    PropertyInfo[] propInfo =
      bm.GetType().GetProperties(BindingFlags.GetProperty |
    BindingFlags.Public | BindingFlags.Instance);

    for (int i = 0; i < propInfo.Length; i++)
    {
        if (propInfo[i].Name == "Width")
        {
            width = (int)propInfo[i].GetValue(bm, null);
            break;
        }
    }

    // Call the GetPixel method
    MethodInfo[] methInfo = bm.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance);
    for (int i = 0; i < methInfo.Length; i++)
    {
        if (methInfo[i].Name == "GetPixel")
        {
            ParameterInfo[] paramInfo = methInfo[i].GetParameters();
            if (paramInfo.Length == 2)
        {

        object[] xy = new object[2];
        if (paramInfo[0].Name == "x")
        {
            xy[0] = x;
            xy[1] = y;
        }
        else
        {
            xy[1] = x;
            xy[0] = y;
        }

        pixColor = (Color)methInfo[i].Invoke(bm, xy);
        break;
    }

    'VB
    Imports System.Reflection
    Imports System.Drawing

    Dim bm As New Bitmap(200, 100)
    Dim width As Integer = 0

    ' Explicitly set one pixel for testing
    Dim x As Integer = 199
    Dim y As Integer = 20
    Dim pixColor As Color = Color.Black
    bm.SetPixel(x, y, Color.Magenta)

    ' Get the "Width" property
    Dim propInfo As PropertyInfo() = _
      bm.GetType().GetProperties((BindingFlags.GetProperty Or _
    BindingFlags.Public Or BindingFlags.Instance))

    Dim i As Integer
    For i = 0 To propInfo.Length - 1
        If propInfo(i).Name = "Width" Then
            width = Fix(propInfo(i).GetValue(bm, Nothing))
            Exit For
        End If
    Next i

    ' Call the SetPixel method
    Dim methInfo As MethodInfo() = bm.GetType().GetMethods((BindingFlags.Public _
    Or BindingFlags.Instance))
    For i = 0 To methInfo.Length - 1
        If methInfo(i).Name = "GetPixel" Then
            Dim paramInfo As ParameterInfo() = methInfo(i).GetParameters()
            If paramInfo.Length = 2 Then
                Dim xy(1) As Object

                If paramInfo(0).Name = "x" Then
                    xy(0) = x
                    xy(1) = y
                Else
                    xy(1) = x
                    xy(0) = y
                End If

                pixColor = CType(methInfo(i).Invoke(bm, xy), Color)
                Exit For
            End If
        End If
    Next i

    7.30. How do I determine the device name programatically?

    The device name can be accessed through the System.Net namespace, as demonstrated by the following code.
    //C#
    String devName = System.Net.Dns.GetHostName();

    'VB
    Dim devName As String = System.Net.Dns.GetHostName()

    7.31. How do I build a C# Smart Device project from the command line?

    Enter the following commands as single lines (each is broken into two lines for clarity):
    set CFPath=%SystemDrive%\Program Files\Microsoft Visual Studio .NET 2003\
    CompactFrameworkSDK\v1.0.5000\Windows CE
    csc Form1.cs /noconfig /nostdlib /lib:"%CFPath%"  /r:"%CFPath%\system.dll";"%CFPath%\
    system.drawing.dll";"%CFPath%\system.windows.forms.dll";"%CFPath%\mscorlib.dll"

    7.32. How do I abort an executing thread??

    There is no Abort method to the Thread class in the .NET Compact Framework so a thread must be aborted by returning from the executing procedure. Typically, an application will notify threads of a closing event by setting a global variable. The main thread will then wait for worker threads to finish processing before closing the application. The following HOWTO article demonstrates how to accomplish this.

    http://msdn.microsoft.com/library/en-us/dncfhowto/html/stopmt.asp


    7.33. Why can't I play a movie on the Pocket PC emulator?

    Windows Media Player is only available on the Pocket PC 2003 emulator. The Windows Media Player install package is for installation on a hardware device connected through ActiveSync and will not install to the emulator.

    7.34. How do I suppress Form titles from showing in the active applications list?

    The Active Programs list on the Pocket PC enumerates all open Forms. To stop a Form from being displayed in the list, simply set the Form's caption to be an empty string. The following example shows how to keep only the application name in the list while a Form is displayed from within another Form:
    //C#
    string AppName = "MyApp";

    Form1 form1 = new Form1();
    this.Text = "";
    form1.Text = AppName;
    form1.ShowDialog();
    this.Text = AppName;

    'VB
    Dim AppName As String = "MyApp"

    Dim form1 As New Form1()
    Me.Text = ""
    form1.Text = AppName
    form1.ShowDialog()
    Me.Text = AppName

    7.35. How do I access a Control from its instance name?

    You can use Reflection to look up a control instance by its name. Here is some sample code:
    //C#
    private void Form1_Load(object sender, System.EventArgs e)
    {
        ComboBox c = (ComboBox)this.ControlFromName("combobox1");
        c.Items.Add("1");
        this.GetControls();
    }

    private Control ControlFromName(string name)
    {
    object o = this.GetType().GetField(name,
    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance |
    System.Reflection.BindingFlags.IgnoreCase).GetValue(this);

        return((Control)o);
    }

    private void GetControls()
    {
        System.Reflection.FieldInfo[] fis = this.GetType().GetFields
        (
            System.Reflection.BindingFlags.NonPublic | 
            System.Reflection.BindingFlags.Instance |
            System.Reflection.BindingFlags.IgnoreCase
        );

        foreach(System.Reflection.FieldInfo fi in fis)
        {
            if (fi.GetValue(this) is Control)
                MessageBox.Show(fi.Name);
        }
    }
    'VB
    Private Function ControlFromName(ByVal name As String) As Control
        Dim o As ObjectDim o As Object
        o = Me.GetType().GetField(name, Reflection.BindingFlags.NonPublic Or _
          Reflection.BindingFlags.Instance Or _
          Reflection.BindingFlags.IgnoreCase).GetValue(Me)
       
        Return (CType(o, Control))
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
        Dim c As ComboBox
        c = CType(ControlFromName("_combobox1"), ComboBox)
        c.Items.Add("1")
        Me.GetControls()e.GetControls()
    End Sub

    Private Sub GetControls()
        Dim fis As System.Reflection.FieldInfo()

        fis = Me.GetType().GetFields(Reflection.BindingFlags.NonPublic Or _
          Reflection.BindingFlags.Instance Or _
          Reflection.BindingFlags.IgnoreCase)

        For Each fi As Reflection.FieldInfo In fis
            If TypeOf (fi.GetValue(Me)) Is Control Then
                MessageBox.Show(fi.Name)
            End Ifnd If
        Next
    End Sub

    7.36. How do I detect the hardware directional pad buttons?

    The hardware directional pad buttons can be detected through the standard key events by comparing the KeyCode from the KeyEventArgs parameter.
    //C#
    protected override void OnKeyDown(KeyEventArgs e)
    {
        switch (e.KeyCode)
        {
            case Keys.Up:
                MessageBox.Show("Up Key Pressed");
                break;
            case Keys.Down:
                MessageBox.Show("Down Key Pressed");
                break;
            case Keys.Left:
                MessageBox.Show("Left Key Pressed");
                break;
            case Keys.Right:
                MessageBox.Show("Right Key Pressed");
                break;
        }
        base.OnKeyDown (e);
    }
    'VB
    Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
        Select Case e.KeyCode
            Case Keys.Up
                MessageBox.Show("Up Key Pressed")
            Case Keys.Down
                MessageBox.Show("Down Key Pressed")
            Case Keys.Left
                MessageBox.Show("Left Key Pressed")
            Case Keys.Right
                MessageBox.Show("Right Key Pressed")
        End Select
         
        MyBase.OnKeyDown(e)

    End Sub 'OnKeyDown

    7.37. How do I get a double click event when only the Click event is supported?

    See the .NET Compact Framework QuickStarts, Implementing Events topic:

    http://samples.gotdotnet.com/quickstart/compactframework/doc/btndclick.aspx

    7.38. How do I get onenter/onleave style notifications?

    See the .NET Compact Framework QuickStarts, OnEnter/OnLeave Functionality:

    http://samples.gotdotnet.com/quickstart/compactframework/doc/enterleave.aspx

    7.39. How do I use threading in a modal dialog that doesn't hang my app?

    Create a modeless dialog that behaves like a model dialog.
    //C#
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Collections;
    using System.ComponentModel;

    public interface IModelessDialogCallback
    {
    void DialogResultCallback(DialogResult result);
    }

    public class Test : System.Windows.Forms.Form, IModelessDialogCallback
    {
    ModelessDialog dlg;
    Button bShow;
    int counter = 0;

    protected override void OnLoad(EventArgs e)
    {
    this.Text = "Modal(less) Dialog Example";

    this.bShow = new Button();
    this.bShow.Parent = this;
    this.bShow.Bounds = new Rectangle (10, 10, 150, 30);
    this.bShow.Text = "Show Dialog";
    this.bShow.Click += new EventHandler(this._Click);

    this.dlg = new ModelessDialog(this);
    }


    private void _Click(object o, EventArgs e)
    {
    this.Enabled = false;
    this.bShow.Text = "waiting for dlg";
    dlg.Show();
    }

    public void DialogResultCallback(DialogResult result)
    {
    MessageBox.Show("dialog returned: " + (result == DialogResult.OK ? "OK" : "Cancel"));
    this.Enabled = true;
    this.bShow.Text = "Show Dialog:" + ++counter;
    }

    public static void Main()
    {
    Application.Run(new Test());
    }
    }

    public class ModelessDialog : Form
    {
    IModelessDialogCallback parent;
    Button bOK, bCancel;

    public ModelessDialog(IModelessDialogCallback parent)
    {
    this.parent = parent;
    this.Text = "Modeless Dialog";

    this.bOK = new Button();
    this.bOK.Parent = this;
    this.bOK.Bounds = new Rectangle (10, 10, 150, 30);
    this.bOK.Text = "OK";
    this.bOK.Click += new EventHandler(this._Click);

    this.bCancel = new Button();
    this.bCancel.Parent = this;
    this.bCancel.Bounds = new Rectangle (10, 50, 150, 30);
    this.bCancel.Text = "Cancel";
    this.bCancel.Click += new EventHandler(this._Click);
    }

    private void _Click(object o, EventArgs e)
    {
    this.Hide();
    this.parent.DialogResultCallback(o == this.bOK ? DialogResult.OK : DialogResult.Cancel);
    }

    protected override void OnClosing(CancelEventArgs e)
    {
    e.Cancel = true;
    this.Hide();
    this.parent.DialogResultCallback(DialogResult.Cancel);
    }
    }

    'VB
    Imports System
    Imports System.Drawing
    Imports System.Windows.Forms
    Imports System.Collections
    Imports System.ComponentModel

    Public Interface IModelessDialogCallback
    Sub DialogResultCallback(result As DialogResult)
    End Interface IModelessDialogCallback'


    Public Class Test
    Inherits System.Windows.Forms.Form
    Implements IModelessDialogCallback
    Private dlg As ModelessDialog
    Private bShow As Button
    Private counter As Integer = 0

    Protected Overrides Sub OnLoad(e As EventArgs)
    Me.Text = "Modal(less) Dialog Example"

    Me.bShow = New Button()
    Me.bShow.Parent = Me
    Me.bShow.Bounds = New Rectangle(10, 10, 150, 30)
    Me.bShow.Text = "Show Dialog"
    AddHandler Me.bShow.Click, AddressOf Me._Click

    Me.dlg = New ModelessDialog(Me)
    End Sub 'OnLoad

    Private Sub _Click(o As Object, e As EventArgs)
    Me.Enabled = False
    Me.bShow.Text = "waiting for dlg"
    dlg.Show()
    End Sub '_Click

    Public Sub DialogResultCallback(ByVal result As DialogResult) Implements _
    IModelessDialogCallback.DialogResultCallback
    MessageBox.Show(("dialog returned: " + IIf(result = DialogResult.OK, "OK", "Cancel")))
    Me.Enabled = True
    counter += 1
    Me.bShow.Text = String.Format("Show Dialog: {0}", counter)
    End Sub 'DialogResultCallback

    Public Shared Sub Main()
    Application.Run(New Test)
    End Sub 'Main
    End Class 'Test

    Public Class ModelessDialog
    Inherits Form
    Private myParent As IModelessDialogCallback
    Private bOK, bCancel As Button

    Public Sub New(parent As IModelessDialogCallback)
    Me.myParent = parent
    Me.Text = "Modeless Dialog"

    Me.bOK = New Button()
    Me.bOK.Parent = Me
    Me.bOK.Bounds = New Rectangle(10, 10, 150, 30)
    Me.bOK.Text = "OK"
    AddHandler Me.bOK.Click, AddressOf Me._Click

    Me.bCancel = New Button()
    Me.bCancel.Parent = Me
    Me.bCancel.Bounds = New Rectangle(10, 50, 150, 30)
    Me.bCancel.Text = "Cancel"
    AddHandler Me.bCancel.Click, AddressOf Me._Click
    End Sub 'New

    Private Sub _Click(o As Object, e As EventArgs)
    Me.Hide()
    Me.myParent.DialogResultCallback(IIf(o Is Me.bOK, DialogResult.OK, DialogResult.Cancel))
    End Sub '_Click

    Protected Overrides Sub OnClosing(e As CancelEventArgs)
    e.Cancel = True
    Me.Hide()
    Me.myParent.DialogResultCallback(DialogResult.Cancel)
    End Sub 'OnClosing
    End Class 'ModelessDialog
    7.40. How do I round floating point numbers efficiently?

    There are two primary methods for rounding numbers:
    • Convert.ToInt32
    • Cast or Fix (C# or VB)
    Convert.ToInt32 automatically handles rounding, where remainders of .5 and greater cause the number to be rounded up. Casting or using Fix requires adding .5 to the number to ensure that it will round properly, as these methods simply remove the remainder.

    Profiling on the emulator and a Compaq iPAQ H3600 series device yielded the following results for 1 million operations of each method, where num is a float set to 3.6F:

    Emulator
    iPAQ
    Operation Debug (ms) Release (ms) Debug (ms) Release (ms)
    C#: Convert.ToInt32(num) 1321 1109 6264 6283
    C#: (int)(num + .5F) 170 49 1479 59
    VB: Convert.ToInt32(num) 1218 1232 6531 6517
    VB: Fix(num + .5F) 3873 3677 18144 17955

    Thus, by examining the release build results for the device, it can be concluded that on the current generation of devices it is most efficient to use casting in C# and Convert.ToInt32 in VB. In C#, casting proved to be over 106 times faster, whereas in VB, Convert.ToInt32 was nearly 3 times faster.
    //C#
    float temp = 3.6f;
    int rounded1 = (int)(temp + .5f);
    int rounded2 = Convert.ToInt32(temp);

    'VB
    Dim temp As Single = 3.6F
    Dim rounded1 As Integer = Fix(temp + .5F)
    Dim rounded2 As Integer = Convert.ToInt32(temp)
    7.41. Why does Control.Invoke take so long when a modal dialog is displayed?

    There is a known bug with using Control.Invoke while a modal dialog is displayed through ShowDialog. Download the latest .NET Compact Framework Service Pack to fix this:

    The latest platform updates and .NET Compact Framework service packs are available at:
    http://msdn.microsoft.com/mobility/downloads/default.aspx


    7.42. Is there a way to retrieve the culture information of an Assembly?

    Culture information can be retrieved through Reflection:
    //C#
    using System.Reflection;
    using System.Globalization;

    Assembly asm = Assembly.GetExecutingAssembly();
    CultureInfo ci = asm.GetName().CultureInfo;

    'VB
    Imports System.Reflection
    Imports System.Globalization

    Dim asm As Assembly = Assembly.GetExecutingAssembly()
    Dim ci As CultureInfo = asm.GetName().CultureInfo
     

    8.通訊和Web服務(wù)


    8.1. 如何通過TCP Socket向桌面機(jī)發(fā)送數(shù)據(jù)?

    請查看本問答的"10.5. 寫一個捕捉Pocket PC簽名的程序. " 部分。

    8.2. 為什么不能訪問本機(jī)上的Web服務(wù)?

    不要在設(shè)備上使用localhost來引用Web服務(wù),因為對于設(shè)備來說localhost就是運(yùn)行應(yīng)用程序所在的設(shè)備,就是設(shè)備它本身。您應(yīng)該使用機(jī)器名或IP地址來引用Web服務(wù)。

    8.3. 如何在微軟.net精簡框架上調(diào)用Web服務(wù)

    這篇文章向您演示了如何從智能設(shè)備上,通過.net精簡框架同步和異步調(diào)用Web服務(wù):

    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfwebservices.asp

    8.4. 如何通過代理服務(wù)器提交HTTP GET申請?

    通過或不通過特定的代理服務(wù)器提交HTTP GET請求。
    使用StreamReader讀取返回的HTML,并轉(zhuǎn)成字符數(shù)組。然后把返回的值顯示在ListBox中,如以下的屏幕截圖所示:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/httpgetwithproxy.aspx

    8.5. 如何使用Web服務(wù)?

    這篇快速入門教程,描述了如何使用提供了簡單數(shù)學(xué)計算的Web服務(wù)(這個數(shù)學(xué)計算的Web服務(wù)在.net框架的快速入門中有說明,標(biāo)題是"Write a Simple Web service,")。這個快速入門教程提供了一個Web服務(wù)的客戶端應(yīng)用:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/xmlwebservice.aspx

    8.6. 如何使用MapPoint3.0得到地圖?

    這篇快速入門描述了如何使用MapPoint的Web服務(wù),編程實現(xiàn)在PocketPC上獲得特定位置的程序,如以下屏幕截圖所示:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/mappointfindmap.aspx

    8.7. 如何使用MapPoint3.0獲得地圖和方向?

    這篇快速入門教程描述了如何使用MapPoint的Web服務(wù),在PocketPC上獲得特定位置的地圖方向,如以下屏幕截圖所示:
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/mappointdirections.aspx

    8.8. Is NTLM authentication supported by the .NET Compact Framework?

    Using Digest authentication instead of Basic or NTLM authentication is the recommended solution. Digest authentication is supported by the .NET Compact Framework.

    8.9. When using blocking Sockets, why does Send throw an InvalidOperationException when blocking is set to false?

    There is a known issue with setting Blocking to false on a blocking socket. There are three paradigms when programming with sockets (both managed and native) and it is strongly recommended that developers use asynchronous I/O functions as a solution to this problem. Select is very inefficient in managed code, and the cost of the regular case exception is also high. The three paradigms are detailed below, with the last being the preferred method.

    • Use blocking calls on blocking sockets (i.e. send(), recv(), etc). This is the simplest method, and probably the most commonly used. The functions perform their operation synchronously, tying up the currently executing thread. This is most acceptable for clients, and multithreaded servers (Microsoft does not recommend using one thread per client because threads are very expensive on Windows). Note that though the operations may block for an unspecified period of time (i.e. until the operation can be completed), they will most often complete immediately.
    • Use non-blocking sockets in conjunction with select or poll. Use the same "blocking" functions, but put the socket in a special mode that prohibits it from blocking. In the cases when the function would block, it returns an error code (in managed code, this throws an exception). You can then use poll or select to wait until a point in time at which an operation would complete (select allows you to manage more than one socket, so you can handle multiple clients on only one thread), and then perform the operation. At the time these calls were created, there were no threads in operating systems, so this was the only way to do things. Using this mechanism has by far the absolute worst performance you could possibly get from socket programming. This problem is exacerbated in managed code, since you now expect an exception to be thrown, which is an even bigger performance hit.
    • Use asynchronous I/O functions on the socket. This is your best all around solution. It allows you to perform operations asynchronously, and you get notified by callbacks. In general, the performance is better than using non-blocking I/O with select, and this is the recommendation for how to do things (at least, in native code).


    8.10. How do I create an http-server?

    Get technical insight on the implementation of Mobile Web Server architecture. Understand use cases, the web server framework and future developments in the architecture:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/NETCFMA.asp

    8.11. Why do I get an exception when calling SetSocketOption with ReuseAddress set?

    This is a known issue in the version 1 of the .NET Compact Framework. To work around the issue, you can P/Invoke setsockopt with SO_REUSEADDR set to true.

    8.12. Why do I get a socket error using SSL to communicate with a server via the WebRequest namespace?

    There is a known issue in the .NET Compact Framework. You can work around this by setting HttpWebRequest.AllowStreamWriteBuffering to True and commenting out your setting of the ContentLength.

     


    9. SQL CE 和 數(shù)據(jù)


    9.1. 使用.net精簡框架、SQL Server CE 和 復(fù)制 開發(fā)應(yīng)用程序時,要注意些什么?

    這篇文章詳細(xì)討論了這個問題:
    http://msdn.microsoft.com/msdnmag/issues/03/09/datapoints/toc.asp

    9.2. 如何在微軟.net精簡框架上使用合并復(fù)制(Merge Replication)?

    這篇文章討論了如何通過程序在.net精簡框架的應(yīng)用程序中調(diào)用合并、復(fù)制:
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfmergereplication.asp

    SQL Server CE是非常好的在設(shè)備上管理數(shù)據(jù)的工具,但在未復(fù)制到桌面機(jī)的SQL Server之前,它必須保留數(shù)據(jù)。使用合并、復(fù)制在設(shè)備上管理數(shù)據(jù),然后當(dāng)設(shè)備連接到桌面機(jī)時,再合并到桌面機(jī)的SQL Server的實例中。.net精簡框架提供SqlCeReplication對象,可以通過程序?qū)崿F(xiàn)數(shù)據(jù)的合并與復(fù)制。
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/sqlcemergereplication.aspx

    9.3. 如何將ADO.NET數(shù)據(jù)和XML綁定?

    以下三個步驟:

    1. 根據(jù)提供的XML文件,建立一個XML Schema文件(.xsd)。
    2. 讀取XML數(shù)據(jù)和它的schema,以便操作。
    3. 將XML保存會文件。
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/adonetdatabinding.aspx

    9.4. 如何建立SQL Server CE的數(shù)據(jù)庫?

    您可以使用.net精簡框架在Windows CE.NET的設(shè)備上建立、管理SQL Server CE的數(shù)據(jù)庫。這篇快速入門教程演示了如何實現(xiàn)它:
    • 建立一個SQL CE數(shù)據(jù)庫。
    • 連接到SQL CE數(shù)據(jù)庫。
    • 在SQL CE的數(shù)據(jù)庫中建立一個表。
    • 插入一行數(shù)據(jù)到SQL CE數(shù)據(jù)庫中。

    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/sqlcedbcreate.aspx

    9.5. 如何向SQL Server CE提交一個帶參數(shù)的查詢?

    您可以使用.net精簡框架在用戶輸入時,向SQL Server CE的數(shù)據(jù)庫中插入值。以下教程向您展示了如何實現(xiàn)此操作:
    • 設(shè)計一個用戶可以設(shè)置查詢值的界面。
    • 連接到SQL CE的數(shù)據(jù)庫。
    • 把用戶輸入的值插入到SQL CE的數(shù)據(jù)庫中
    http://samples.gotdotnet.com/quickstart/CompactFramework/doc/sqlceparameterizedquery.aspx

    9.6. Why does using RDA and the push method fail with error 27750?

    Symptom
    When calling:
    rda = new SqlCeRemoteDataAccess();
    An error of type SQLCeException with a Native Error Code of 27750 occurs. This error corresponds to "Cannot load sscemw20.dll or ssceca20.dll is missing or not registered."

    Resolution
    Load the library at the start of the application, even if you do nothing with it. To load the library, you can load the SqlCeEngine object.
    SqlCeEngine eng = new SqlCeEngine();
       

    10. 其他信息


    10.1. Pocket TaskVision 程序

    This document provides an overview of the development tasks that were unique to the Pocket TaskVision sample application. Pocket PC devices have much lower storage capacities, memory and lower-end processors than desktop systems—storage and performance considerations are mentioned throughout the document.
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/wnf_pkttaskvision.asp

    10.2. 建立基于微軟.net精簡框架的進(jìn)程管理器

    In this article, learn how to marshal structures as byte arrays.
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/ProcessManager.asp

    10.3. 使用微軟.net精簡框架開發(fā)移動游戲

    Learn how to create .NET Compact Framework-based games. Learn the key requirements for writing games targeting small devices and see that the .NET Compact Framework can handle them with ease. Include advanced performance-tuning techniques that you can use to push the limits of your game.
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfgaming.asp

    10.4. 制作一個微軟.net精簡框架的DateTimePicker控件

    Learn how to use a managed DateTimePicker class in your Pocket PC projects. The .net精簡框架 provides managed classes for most controls but the DateTimePicker class is not supported. Wrapper classes that P/Invoke the native control can be found on the Web, but this sample provides a purely managed DateTimePicker class that you can use in your Pocket PC projects. The class and sample application are provided in C# and Visual Basic .NET.
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfdatetimepicker.asp

    10.5. 寫一個捕捉Pocket PC簽名的程序.

    This article discusses the Pocket PC Signature sample application. The sample includes a client that runs on the Pocket PC that sends signature data over TCP sockets to a server that is running on the desktop. Data is encrypted and decrypted using the cryptography services.
    http://msdn.microsoft.com/library/en-us/dnnetcomp/html/PPCSignatureApp.asp

    10.6. 有沒有非微軟的網(wǎng)站提供在.net精簡框架上開發(fā)應(yīng)用的信息?

    See the "Related Sites" section of the MSDN Mobile and Embedded Developer Center:
    http://msdn.microsoft.com/mobility/Community/related/default.aspx



    11. 連通性


    11.1. 為什么不同通過ActiveSync把程序部署到Windows CE的設(shè)備上?

    Symptom: When a Windows CE device is connected through ActiveSync, deployment and debugging (F5 and Ctrl-F5) fail with the typical error message "There were deployment errors. Continue?"

    Cause: Due to the fact that ActiveSync 3.5 and 3.6 do not provide accurate information about the device instruction set, ConMan (Visual Studio .NET 2003 component for device connectivity) cannot use the information returned by ActiveSync to map a Windows CE device to the right .NET Compact Framework target (MIPSII, ARMV4 etc).

    Workaround: Install and run the separately provided Windows CE Configuration Add-In. For ARMV4 devices, an alternative is to select Pocket PC Device at the beginning of the deployment.

    11.2. 為什么不能通過ActiveSync調(diào)試 CEPC 或其他 x86 的Windows CE設(shè)備?

    Symptom: After running the Windows CE Device Configuration Add-In, the user can deploy without debugging (Ctrl-F5) to an ActiveSync connected CEPC (or any x86 based Windows CE device) but cannot debug (F5). Non-x86 based Windows CE devices do not have this problem.

    Cause: Debugging Windows CE Emulators (also x86 based) uses a TCP port that conflicts with the one used by ActiveSync for debugging x86 based devices. To support Emulator debugging, it is necessary to disable debugging for CEPC and other x86 devices by default.

    Workaround: The following workaround will allow debugging of x86 devices but disable debugging with the Windows CE Emulator. The workaround requires the files WinCEx86Device.reg, and ProxyPorts.reg which can be found in the SDK utilities directory: "<VSROOT>\CompactFrameworkSDK\WinCE Utilities\WinCE Proxy Ports Reg".

    If you do not have these files they can be downloaded from the following link:
    http://www.microsoft.com/downloads/details.aspx?FamilyID=7ec99ca6-2095-4086-b0cc-7c6c39b28762&DisplayLang=en#filelist

    • Import WinCEx86Device.reg to the registry. Now you will be able to debug x86 devices, but debugging with the Windows CE Emulator will fail.
    • To restore Emulator debugging, remove the registry key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\ProxyPorts" and then import ProxyPorts.reg.

    11.3. 為什么當(dāng)設(shè)備上的Toolhelp.dll文件丟失后,調(diào)試就會失?

    Symptom: After F5, all the files including the application executables and .net精簡框架 cab files are copied to the device, and the IDE reports success on launching the application, but nothing is launched on the device. If you check the \windows folder of the device, toolhelp.dll does not exist.

    Cause: Some device images may not include toolhelp.dll which is required by SDE debugging.

    Workaround: Copy toolhelp.dll from Windows CE SDK to the \windows folder of the device. This file can be found in the corresponding target directory for each device.

    For example, for an ARM device: "<VSROOT>\CompactFrameworkSDK\WinCE Utilities\ToolHelp\WinCE4\armv4".

    If you do not have this file it can be downloaded from the following link:
    http://www.microsoft.com/downloads/details.aspx?FamilyID=7ec99ca6-2095-4086-b0cc-7c6c39b28762&DisplayLang=en#filelist

    11.4. 為什么當(dāng)網(wǎng)絡(luò)協(xié)議數(shù)超過50個的時候,就不能向設(shè)備發(fā)布程序?

    Symptom: The "deployment error" message box occurs on Ctrl-F5 or F5. Running EnumProtocols.exe lists more than 50 protocols. (EnumProtocols.exe can be found in the WinCE utilites directory: "<VSROOT>\CompactFrameworkSDK\WinCE Utilities\EnumProtocols"). If you do not have this file it can be downloaded from the following link:
    http://www.microsoft.com/downloads/details.aspx?FamilyID=7ec99ca6-2095-4086-b0cc-7c6c39b28762&DisplayLang=en#filelist

    Cause: It is a known issue that the .NET Framework method System.Net.Dns.GetHostName throws an exception when there are more than 50 network protocols installed on the current machine. The method is called by ConMan and the exception causes failure of the ConMan transport initialization.

    Workaround: Uninstall the network protocols that are not actually needed. One way to do this is to go to Device Manager (Right-click on "My Computer", select Properties->Hardware and press the "Device Manager" button) and remove unused entries under "Network adapters". Another way is to uninstall applications that have installed protocols. Those applications can be found from the output of EnumProtocles.exe.

    11.5. 為什么卸載ActiveSync后,不能通過ActiveSync向設(shè)備發(fā)布?

    Symptom: The "deployment error" message box occurs on Ctrl-F5 or F5 after ActiveSync has been uninstalled. Uninstalling ActiveSync typically happens when the user upgrades ActiveSync, e.g. from version 3.5 to 3.6.

    Cause: ConMan relies on some registry values under "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\ProxyPorts" for deployment and debugging through ActiveSync. These registry values are removed when ActiveSync is uninstalled.

    Workaround: Reinstall or repair Visual Studio .NET 2003.
    A simpler fix is to import ProxyPorts.reg which can be found in the WinCE utilities folder: "<VSROOT>\CompactFrameworkSDK\WinCE Utilities\WinCE Proxy Ports Reg" . If you do not have this file it can be downloaded from the following link:
    http://www.microsoft.com/downloads/details.aspx?FamilyID=7ec99ca6-2095-4086-b0cc-7c6c39b28762&DisplayLang=en#filelist

    The device may need to be un-cradled/re-cradled or soft rebooted to make the fix take effect.
    It is recommended that users never uninstall ActiveSync. To upgrade ActiveSync, you should directly install the new version which will correctly override the old one.

    11.6. 為什么本地化的機(jī)器名或用戶名或?qū)е孪蛟O(shè)備發(fā)布程序的失。

    Symptom: When the machine name or the logon user name contains any character that is not on the current code page or below ASCII value 0x20, deployment to devices fails while deployment to the Emulator works fine.

    Cause: ConMan security authentication internally uses the machine name and user name in the ASCII form which is not able to handle characters in the categories described above.

    Workaround: Do not use characters described above in the machine name or the user name. If the user is not clear what characters belong to those categories, it is always safe to use just English alphabetic letters and numbers.

    11.7. 為什么當(dāng)前用戶不屬于Administrators組的時候,不能向設(shè)備發(fā)布程序?

    Symptom: If the current logon user is not in the Administrators group, deployment to devices always fails even though the user is in the Visual Studio Developers group and the Debugger Users group. On the other hand deployment/debugging to the Emulator works fine.

    Cause: During device deployment, the ConMan code internally opens a file in a mode that requires administrator privileges.

    Workaround: Add the current user to the Administrators group or limit the deployment target to the Emulator only.

    11.8. 為什么向Pocket PC或模擬器發(fā)布的時候出現(xiàn) sharing violation 的錯誤?

    Symptom: When deploying an application to a Pocket PC 2002/2003 device or Emulator, the deployment fails with an output message similar to "Could not write to output file 'SmartDeviceApplication1.exe' - Sharing violation". This usually happens after the same application has previously deployed to the same device or Emulator.

    Cause: By default the X button on an application for Pocket PC 2002 or 2003 (not 2000) does not close the process. It only "minimizes" the application window. When the user tries to deploy the application again, the "minimized" instance will cause the sharing violation and fail the deployment.
    Another possible cause is that the user has forcibly terminated a debug session in the middle.

    Workaround: Make sure the application is really closed on the device or Emulator when deploying it again. To see running processes, go to Start->Settings->Memory->Running Programs on the Pocket PC. In case it is intended to have a button to really close an application, create such a button explicitly or set Windows Form's property Minimize Box to False so that the X button will become an OK button for closing the application. If the cause was the manual termination of a debug session, the device or the Emulator may need to be soft rebooted.

    11.9. 為什么在.NET Server的計算機(jī)上第一次使用模擬器的時候,得到一個安全警告消息?

    Symptom: When the Emulator is used for the first time after the installation of Visual Studio .NET 2003 on a .NET Server machine, a message box pops up titled "Security Alert a
關(guān)鍵詞:NETCF