这些年微软相关的技术总结, Javascript在客户端的使用
http://antkillerfarm.github.io/
C#相關
1.XmlReader
XmlReader是.NET中處理XML的類。之前的W3C已經提出了DOM和SAX兩種模型。作為最早的模型,這兩種模型在各種語言中都有相應的實現,關于它們的討論也有很多,在此不再贅述。
XmlReader是一種快速、無緩沖、向前并只讀的輕量級XML引擎,在這一點上它和SAX是相同的。它和SAX的主要區別在于它們的設計模式是不同的。SAX是push模式的XML引擎,它會在讀到相應的節點時,觸發消息并將之發送給調用程序。而XmlReader則是pull式的XML引擎,它更符合人們的通常的對文件順序處理的習慣。當然除此之外,它還有其他的好處。參看MSDN的相關章節。
通常情況下,pull模型比push模型的效率高,但push模型的靈活性要高些。例如,Dos下的編程主要是一種順序執行的pull模型結構,而Windows下的編程則是一種基于消息的push模型結構。所以,讀取特定標簽內容的XML文檔,采用XmlReader比較好,而對于那些結構不固定或需要遍歷的XML文檔用SAX較好。
PS: XmlReader提出的pull方案,后來被libxml2采用,成為了GTK+的一部分。
2.Microsoft.WindowsCE.Forms
這是一個Wince的類。由于.NET CF中的System.Windows.Forms.Form沒有DefWndProc參數,所以要想接收窗體消息就要用到它。不過它的dll需要自己添(在.NET CF的安裝路徑下可以找到這個Microsoft.WindowsCE.Forms.dll),接收C++編程時的那些WM_開頭的消息時需要用到這個模塊中的MessageWindow類。
代碼示例如下:
public class MsgWindow : MessageWindow {public const int WM_CUSTOMMSG = 0x0400+3333;private Form1 msgform;//Form1是用于接收消息的那個窗體Form。public MsgWindow(Form1 msgform){this.msgform = msgform;}protected override void WndProc(ref Message msg){switch (msg.Msg){case WM_CUSTOMMSG://do sthbreak;}base.WndProc(ref msg);} }3.C#中的發布功能
C#項目屬性中有個publish標簽是關于發布程序的功能的。用過Java的人都知道,Java的可移植性是很不錯的,但Java程序的部署相對于一般 的本地程序來說就顯得比較麻煩了。至少在本人的程序生涯中,就多次經歷拿著JAR文件興沖沖的跑去,卻發現目標機沒有JRE的情況。
C#中的發布功能除了能打包程序和.NET Framework之外,還有網絡發布的功能。這里我主要討論單機程序的打包。如果只有程序文件的話,情況比較簡單,沒什么難度。如果還有數據文件的話就 要注意了。在程序文件(Application Files)對話框中,每個文件有一個發布狀態(Publish Status)的屬性,如果你希望數據文件和程序文件在同一個文件夾下的話,最好選擇包含(Include)而不是數據文件(Data File),后者會把你的數據文件部署到一個專門的數據文件夾下,這個文件夾可用 System.Deployment.Application.DataDirectory獲得。
VS2005
1.選擇CPU的類型
使用過EVC的朋友都知道,EVC支持諸如ARMV4、ARMV4I、MIPS、X86等多種CPU類型。但是除了STANDARD SDK之外,其他的SDK通常都是限定了CPU類型的。例如PPC2003是ARMV4的,而Mobile5是ARMV4I的。
大家都知道,ARMV4、ARMV4I是兩套頗有淵源的指令集,前者編的程序可以運行在支持后者的機器上,但反過來則不行。這就帶來了一個新的問題。
最近我負責向一個PPC2003的程序添加新功能,該功能是由第三方以靜態庫的方式提供的,那個庫是ARMV4I的。在默認情況下,是不能鏈接到PPC2003程序中的。由于這個程序比較復雜,用Mobile5重新編過,需要對代碼作較大修改。所以可以考慮修改鏈接器的CPU類型。當然這種方法只是一種偷懶的方法,常會產生一些深層次的鏈接錯誤,并不推薦。
方法:
1)EVC
Project->Settings->Link->General->Project Options,將/MACHINE:ARM改為/MACHINE:THUMB。
2)VS2005
Project->Properties->Linker->Command Line->Additional options,將/MACHINE:ARM改為/MACHINE:THUMB。
類似的我們還可以修改鏈接內核版本,例如我們用Windows Mobile 5 SDK編譯程序,如果想讓它的行為與PPC 2003相同的話,可以將/subsystem:windowsce,5.01改為/subsystem:windowsce,4.20
這個方法在VGA編程時是很有用的,PPC 2003下VGA是320 * 240的分辨率,而WM5下是640 * 480的分辨率。有時可能需要用這個方法移植一些老程序。
2.LNK2005問題
http://www.cnblogs.com/hyamw/archive/2007/01/11/618021.html
http://topic.csdn.net/t/20050525/17/4035191.html
當然還有終極大招——命令行的/FORCE選項,不過這是不得已而為之。明知有問題,卻采用此暴力流,鏈接是沒問題了,但鏈接后的東西是否可用,那就只有天知道了。
3.
最近做一個嵌入式的項目,需要做一個全屏的MFC對話框。剛接到手時,著實沒怎么在意這個小東西。豈料剛開始做,問題就出來了。VC的對話框編輯器使用DLU作為長度單位,而我的項目需要以像素為單位。經過無數實踐和查找資料后,我終于找到了一個方法。
1)創建一個Bitmap資源,圖片的大小與你所需大小一致。
2)在對話框中添加該圖片,按照圖片的大小調整對話框的大小即可。
在EVC4下我試過該方法,但不成功。網上有的人說VC 6和VC 2005下,同樣的字體、大小,DLU和像素之間的換算值是不同的,估計這也是微軟在新形勢下對工具的一種調整。DLU這種東西,問世的年代比較久遠,它主要解決的是在分辨率較小的年代,如何清晰顯示字體的問題。在當時這是個首要問題,但現在UI設計的關鍵已經轉移到窗口的貼圖上,對于圖片而言,像素才是標準單位。
這里需要注意的是1 DLU在橫向和縱向上對應的像素值,隨設備不同而不同,在我實驗的幾款設備中,用上面的方法基本橫向都沒問題,但縱向就不一定正確了。
最后再提一下控件的Z值問題。雖然在對話框編輯器中,沒有明顯的地方設置Z值(Z值決定當兩個控件重疊時,誰在上面),但其實是可以修改的,調整一下控件的TAB值即可。
4.
自繪按鈕時,發現即使使用了DT_VCENTER來繪制字體,字體在按鈕上的位置也不居中,后來發現還需要添加DT_SINGLELINE才行。
5.
在MFC中要實現換行效果,除了要在字符串中添加\n之外,還需要將DrawText設置成~DT_SINGLELINE。
6.
執行.bat文件時,如果不想讓它運行完后直接關閉窗口,可以為該文件創建快捷方式,右鍵點擊該快捷方式,在“屬性”的“快捷方式”頁的“目標”欄的最前面添加%comspec% /k。
7.工程向導
某些SDK可能比較古老,沒有匹配VS2005的向導文件,可以采用以下辦法試試:找到向導對應的.vsz文件,將Wizard所在行改為Wizard=VsWizard.VsWizardEngine.8.0,但不同版本的向導之間,還是有差別的,因此這一招在某些情況下,可能無效。
8.
win32控制臺工程,如果在運行時,不希望有控制臺窗口,只要在程序中加上:
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
反過來如果某個win32控制臺工程運行過快,以至于看不清控制臺窗口的輸出時,可以在主程序的末尾加上:
system("pause");
Windows Mobile
1.自動打開微軟藍牙
使用BthUtil.dll中的BthSetMode函數。
2.改變音量
使用waveOutSetVolume函數。
3.設置震動、靜音
使用aygshell.dll中的SndSetSound函數。
4.關閉輸入法
使用SipShowIM函數。
5.隱藏/顯示 輸入法、任務欄
使用SHFullScreen函數。如果是MFC對話框的話,還需要添加以下代碼才能實現輸入法的隱藏:
m_bFullScreen = FALSE;
6.在VS2005下創建MFC工程
EVC下將MFC的工程分為PPC和wince兩種,而VS2005下,不再區分這兩者。但通常情況下PPC的程序在wince設備上并不能運行。這時可以采用以下方法:
1)有SDK時,在建立工程時,選擇Platform即可。
2)無SDK時,在工程設置的預定義宏中,去掉WIN32_PLATFORM_WFSP或WIN32_PLATFORM_PSPC宏,前者表示Smartphone,后者表示Pocket PC。這個宏有時會定義在$PLATFORMDEFINES中。
7.設置全屏
// 隱藏任務欄HWND hWndTaskBar = ::FindWindow(TEXT("HHTaskBar"), NULL);if (NULL != hWndTaskBar){::ShowWindow(hWndTaskBar, SW_HIDE);}// 如果需要的話,隱藏輸入法窗口SIPINFO sipInfo;memset(&sipInfo, 0, sizeof(SIPINFO));sipInfo.cbSize = sizeof(SIPINFO);::SipGetInfo(&sipInfo);if ((sipInfo.fdwFlags & SIPF_ON) == SIPF_ON){::SipShowIM(SIPF_OFF);}// 隱藏“拼”按鈕HWND hWndSipButton = ::FindWindow(TEXT("MS_SIPBUTTON"), NULL);if (NULL != hWndSipButton){::ShowWindow(hWndSipButton, SW_HIDE); }8.打電話
使用tapiRequestMakeCall函數。
Javascript在客戶端的使用
Javascript在服務器前端的成功,促使人們思考其在客戶端的使用。
最早的嘗試,是MS提供的web broswer控件(例如MFC的CHtmlView類)。然而,當時的目的,并不是美化應用程序外觀,而只是給程序提供一個訪問互聯網的機會。其最常見的用處,就是給About添加一個網站鏈接。這種方式不光用途簡陋,更關鍵的是從外觀來看,網頁和應用程序完全是兩種風格。
網站的外觀在隨后的幾年中進化的很快,由于CSS和Javascript的出現,網頁前端不再是一成不變的靜態網頁,而是具有了一定的動畫和交互能力。強大的功能促進了分工的發展,網站設計逐漸分成了前端和后端兩大工種。這種分工又促進了網頁交互技術的進步。
反觀普通的應用程序,由于受限于編程的復雜度,前端人員一直難于介入,很多年都處于停滯階段。這期間一些不甘平庸的公司,在UI技術方面也做了一些嘗試。
首先是DirectUI。這個是MS對于Win32窗口模型的一個重大改進。
在原始的Win32窗口模型中,每個控件都是一個窗口,擁有一個窗口句柄(相當于窗口資源的描述符)。窗口事件的處理和資源管理都在OS層面進行,開銷比較大。(比如包含10000個按鈕的窗口怎么處理的問題)窗口之間的交互,比如透明、動畫,也由于需要跨窗口句柄,而變得非常復雜。
DirectUI的思路,是將控件降級為貼圖,并接管整體窗口事件的處理,以模擬的方式實現控件的行為。開銷和擴展性得到了很大的提升。
DirectUI技術最早出現在Windows XP中。比如,“我的電腦”左側的控制面板。由于它的HWND的名字叫做DirectUI,故名。GTK項目實際上也采用了類似的方案。
DirectUI技術國內做的比較好的有:
https://www.douban.com/group/topic/27583755/
各種DirectUI技術,普遍引入了UI配置文件的概念,而且UI配置文件的功能也越來越強。比如,GTK的設計器Glade,早期的時候是根據UI設計,導出代碼,但現在已經改為導出UI配置文件了。
然而,由于低層實現的限制,這些UI配置文件語法各異,雖然有設計器來簡化設計難度,但注定不能做的太復雜。因此,功能上無論如何都無法與網頁相比,更不必說和HTML 5相比了。
2012年以后,以CEF(Chromium Embedded Framework)和XULRunner為代表的瀏覽器派,開始逐漸嶄露頭角。從此,開發桌面應用程序,不再是Javascript的禁區。桌面應用UI和網頁前端開始呈現融合的局面。
總結
以上是生活随笔為你收集整理的这些年微软相关的技术总结, Javascript在客户端的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 入行以来涉及的技术简史
- 下一篇: Jpeglib使用指南, 各种压缩包的压