谷歌瀏覽器源碼分析
《谷歌瀏覽器源碼分析》由會(huì)員分享,可在線閱讀,更多相關(guān)《谷歌瀏覽器源碼分析(94頁珍藏版)》請?jiān)谘b配圖網(wǎng)上搜索。
1、隨著網(wǎng)絡(luò)技?術(shù)的發(fā)展,越來越多應(yīng)? 用都已經(jīng)離?不開網(wǎng)絡(luò),特別像人類?大腦一樣的?知識(shí)庫的搜?索引擎,更加是離不?開功能強(qiáng)大?的云計(jì)算。不過,即便云計(jì)算?非常強(qiáng)大,但它還不能?直接地把結(jié)?果呈現(xiàn)給用? 戶,這樣就需要?一個(gè)客戶端?來呈現(xiàn)出來?,這個(gè)客戶端?就是瀏覽器??,F(xiàn)在越來越?多人上網(wǎng),他們每一次?上網(wǎng),都離不開瀏?覽的使用,這已經(jīng)是一?個(gè)不可缺少?的軟件了。 這里介紹和?分析谷歌推?出有創(chuàng)新的?瀏覽器,它的速度比?其它瀏覽器?快很多,那么它是怎?么實(shí)現(xiàn)的呢??又采用了什?么樣的技術(shù)?能達(dá)到這樣?呢?又比如它的?標(biāo)簽頁是每?一 個(gè)進(jìn)程進(jìn)行?顯示的,這到底又是?怎么樣實(shí)現(xiàn)?的呢?下面來通過?
2、分析它的源?碼,一一地解開?這種高新技?術(shù)的使用,以及這種高?效算法的奧?秘。 谷歌瀏覽器?的英語名稱?為Chro?me,它的意義是?鉻。鉻是一種有?光澤的、藍(lán)灰色的堅(jiān)?硬金屬元素?。不失光澤,抗腐蝕,最早在鉻鐵?礦中發(fā)現(xiàn)。用作催化劑?,可加強(qiáng)鋼合?金的強(qiáng)度和?生產(chǎn)不銹鋼?,可以做防腐?鍍層和玻璃?制品中的顏?料。原子序數(shù)2?4;原子量51?.996;比重7.18;化合價(jià)2,3,6。谷歌起這個(gè)?名稱,可能是想讓?這個(gè)瀏覽器?永遠(yuǎn)不失去?光澤,永遠(yuǎn)那么吸?引人。鉻是無毒,化學(xué)性質(zhì)很?穩(wěn)定,有延展性,含雜質(zhì)時(shí)硬?而脆。熔點(diǎn)185?7C,沸點(diǎn)267?2C,密度單晶為?7.22克/厘米3,多晶
3、為7.14克/厘米3;鉻,原子序數(shù)2?4,原子量51?.9961。鉻的名稱來?自希臘文C?hroma?,意為顏色。因?yàn)檫@種元?素以多種不?同顏色的化?合物存在,故被稱為“多彩的元素?”。可用于制不?銹鋼,汽車零件,工具,磁帶和錄像?帶等。鉻鍍在金屬?上可以防銹?,也叫可多米?,堅(jiān)固美觀。紅、綠寶石的色?彩也來自于?鉻。作為現(xiàn)代科?技中最重要?的金屬,以不同百分?比熔合的鉻?鎳鋼千變?nèi)f?化,種類繁多,令人難以置?信。 谷歌的開發(fā)?人員稱,雖然網(wǎng)絡(luò)的?發(fā)展日新月?異,但作為網(wǎng)絡(luò)?平臺(tái)的瀏覽?器,卻沒有跟上?網(wǎng)絡(luò)發(fā)展的?步伐。谷歌傾心打?造的免費(fèi)瀏?覽器就是希?望能跟隨著?網(wǎng)絡(luò)的發(fā)展?而不斷升
4、級?換代,完美的切合?網(wǎng)絡(luò)時(shí)代的?潮流。 據(jù)了解,谷歌員工每?天使用的最?多的應(yīng)用程?序就是瀏覽?器,通過瀏覽器?,查看新聞資?訊,觀看視頻聊?天,玩網(wǎng)絡(luò)游戲?。谷歌的員工?說,如果能夠開?發(fā)出一種全?新的瀏覽器?,才能夠滿足?人們使用應(yīng)?用程序和網(wǎng)?站管理員的?要求。谷歌希望能?夠提供一種?速度更快,穩(wěn)定性更高?,安全性更強(qiáng)?的瀏覽器。因此Goo?gle Chrom?e誕生了! 為了學(xué)習(xí)這?個(gè)瀏覽器,需要通過網(wǎng)?絡(luò)把這份達(dá)?到1G以上?的代碼下載?下來,需要的時(shí)間?就需要好幾?個(gè)小時(shí),然后再把硬?盤空間清空?為10G左?右大小,最后配置好?VC 2005,就可以編譯?這個(gè)“可多米
5、”了。在我的電腦?上編譯,共需要兩個(gè)?小時(shí)左右,才完全編譯?完成,最后生成下?面的可多米?,如下圖: 缺省編譯出?來的可多米?是英語版本?的,從關(guān)于對話?框里就可以?看到。下面是編譯?出來的目錄?圖片,如下: 上面是調(diào)試?版本的輸出?文件,所以程序大?小都比較大?,沒有經(jīng)過優(yōu)?化的處理。整個(gè)程序的?大小,需要編譯1?37個(gè)工程?,共1G多的?源碼大小,這是一個(gè)非?常旁大的一?個(gè)工程。 這么大的工?程,我從哪里開?始呢?我認(rèn)為從界?面開始,這樣才可以?快速地深入?研究。下面就可以?先嘗試修改?一個(gè)chr?ome的關(guān)?于對話框,上一次看到?它是英語的?,那么我就來?把它改
6、成中?文的吧,這樣有目標(biāo)?了。從chro?me的工程?里可以看到?它是支持多?種語言的,在Wind?ows平臺(tái)?上支持多語?言的標(biāo)準(zhǔn)做?法,就是寫多個(gè)?語言的DL?L。因此,chrom?e也不例外?,從app工?程集里,就可以看到?如下圖所示?: 上面顯示了?多種語言的?動(dòng)態(tài)連接庫?資源,其中zh-CN是簡體?中文的。 接著打開資?源文件的字?符串編輯,如下圖: 把上面的字?符串修改為? “關(guān)于 可多米”,然后把這個(gè)?工程重新編?譯一下,就會(huì)生成下?面的文件: 然后運(yùn)行自?己編譯的可?多米,就會(huì)顯示出?修改的成果?,如下圖: 可以看
7、到關(guān)?于對話框的?標(biāo)題,就變成我上?面修改的了?。這樣學(xué)習(xí)它?的修改,就是幾分鐘?的事情,哈哈...... 這樣就學(xué)習(xí)?了可多米開?發(fā)漢化的工?作,這是本地化?的重要做的?一件事情,也學(xué)習(xí)到怎?么樣支持多?語言的實(shí)現(xiàn)?方式。那么它的關(guān)?于對話框是?從那里顯示?出來的呢?怎么樣把字?符串更新到?上面的呢?下一次再告?訴你。 前面修改了?chrom?e關(guān)于對話?框,并且編譯顯?示出來了,那么它是在?那里調(diào)用顯?示的呢?現(xiàn)在就帶你?去了解它。由于它是界?面顯示,那么不用想?,直接到界面?的工程里查?找它,也就是到目?錄src\chrom?e\brows?er\views?里查看到文?件abo
8、u?t_chr?ome_v?iew.cc。 這個(gè)文件里?聲明了一個(gè)?類Abou?tChro?meVie?w,它就是主要?負(fù)責(zé)初始化?對話框、布局、顯示字符串?等等,比如顯示“關(guān)于可樂米?”的字符串,就是這樣實(shí)?現(xiàn)的,先調(diào)用函數(shù)?: #001 std::wstri?ng About?Chrom?eView?::GetWi?ndowT?itle() const? { retur?n l10n_?util::GetSt?ring(IDS_A?BOUT_?CHROM?E_TIT?LE); } 獲取資源里?的對話框標(biāo)?題,接著: 在上面的斷?點(diǎn)里就是響?應(yīng)菜單,然后創(chuàng)建關(guān)?于對
9、話框,主要調(diào)用函?數(shù)Crea?teChr?omeWi?ndow來?創(chuàng)建窗口,把Abou?tChro?meVie?w窗口綁定?到這個(gè)窗口?類型里。由于可多米?都是統(tǒng)一的?窗口樣式,那么它是通?過創(chuàng)建一樣?的窗口類C?ustom?Frame?Windo?w來實(shí)現(xiàn)的?。 為了顯示窗?口的標(biāo)題,是通過下面?的函數(shù)關(guān)系?調(diào)用: 1. Brows?er::Execu?teCom?mand 瀏覽器執(zhí)行?菜單命令。 2. Chrom?eView?s::Windo?w::Creat?eChro?meWin?dow 創(chuàng)建窗口。 3. Chrom?eView?s::Custo?mFram?eWind?o
10、w::Init 初始化窗口?。 4. Chrom?eView?s::Windo?w::Init 初始化窗口?標(biāo)題。 5. About?Chrom?eView?::GetWi?ndowT?itle 從關(guān)于對話?框獲取標(biāo)題?。 理解上面的?函數(shù)關(guān)系調(diào)?用就知道怎?么樣顯示標(biāo)?題了,因此也知道?關(guān)于對話框?所有內(nèi)容是?由類Abo?utChr?omeVi?ew來管理?的,但窗口的樣?式是由Cu?stomF?rameW?indow?類來管理的?。 通過上面的?分析,了解了關(guān)于?對話框的標(biāo)?題顯示過程?,你想修改成?什么樣的內(nèi)?容,就要看你的?需要了。下一次再仔?細(xì)地分析有?關(guān)于對話框?怎
11、么樣組織?其它信息,比如重要的?升級功能。 關(guān)于對話框?,主要實(shí)現(xiàn)了?讓用戶查看?當(dāng)前軟件的?版本、軟件信息和?檢查升級的?功能。因此這個(gè)類?主要繼續(xù)C?hrome?Views?::View類?、Chrom?eView?s::Dialo?gDele?gate和?Googl?eUpda?teSta?tusLi?stene?r。其中Chr?omeVi?ews::View實(shí)?現(xiàn)窗口的布?局和顯示問?題,Chrom?eView?s::Dialo?gDele?gate實(shí)?現(xiàn)了事件響?應(yīng),或者窗口某?時(shí)是否可以?顯示按鈕的?問題,Googl?eUpda?teSta?tusLi?stene?r是用來實(shí)
12、?現(xiàn)接收更新?程序狀態(tài)信?息。 這個(gè)類的聲?明如下: class? About?Chrom?eView? : publi?c Chrom?eView?s::View, publi?c Chrom?eView?s::Dialo?gDele?gate, publi?c Googl?eUpda?teSta?tusLi?stene?r { publi?c: expli?cit About?Chrom?eView?(Profi?le* profi?le); virtu?al ~About?Chrom?eView?(); // Initi?alize? the contr
13、?ols on the dialo?g. void Init(); // Overr?idden? from Chrom?eView?s::View: virtu?al void GetPr?eferr?edSiz?e(CSize? *out); virtu?al void Layou?t(); virtu?al void ViewH?ierar?chyCh?anged?(bool is_ad?d, Chrom?eView?s::View* paren?t, Chrom?eView?s::View* child?); // Overr?idden? fr
14、om Chrom?eView?s::Dialo?gDele?gate: virtu?al int GetDi?alogB?utton?s() const?; virtu?al std::wstri?ng GetDi?alogB?utton?Label?(Dialo?gButt?on butto?n) const?; virtu?al bool IsDia?logBu?ttonE?nable?d(Dialo?gButt?on butto?n) const?; virtu?al bool IsDia?logBu?ttonV?isibl?e(Dialo?gButt?on butto?n
15、) const?; virtu?al bool CanRe?size() const?; virtu?al bool CanMa?ximiz?e() const?; virtu?al bool IsAlw?aysOn?Top() const?; virtu?al bool HasAl?waysO?nTopM?enu() const?; virtu?al bool IsMod?al() const?; virtu?al std::wstri?ng GetWi?ndowT?itle() const?; virtu?al bool Accep?t(); virtu?a
16、l Chrom?eView?s::View* GetCo?ntent?sView?(); // Overr?idden? from Googl?eUpda?teSta?tusLi?stene?r: virtu?al void OnRep?ortRe?sults?(Googl?eUpda?teUpg?radeR?esult? resul?t, Googl?eUpda?teErr?orCod?e error?_code?, const? std::wstri?ng& versi?on); priva?te: // The visib?le state? of the
17、Check? For Updat?es butto?n. enum Check?Butto?nStat?us { CHECK?BUTTO?N_HID?DEN = 0, CHECK?BUTTO?N_DIS?ABLED?, CHECK?BUTTO?N_ENA?BLED, }; // Updat?e the UI to show the statu?s of the upgra?de. void Updat?eStat?us(Googl?eUpda?teUpg?radeR?esult? resul?t, Googl?eUpda?teErr?orCod?e erro
18、r?_code?); Profi?le* profi?le_; // UI eleme?nts on the dialo?g. Chrom?eView?s::Image?View* about?_dlg_?backg?round?_; Chrom?eView?s::Label?* about?_titl?e_lab?el_; Chrom?eView?s::TextF?ield* versi?on_la?bel_; Chrom?eView?s::TextF?ield* main_?text_?label?_; // UI eleme?nts we add to
19、 the paren?t view.
scope?d_ptr?
20、 the visib?le state? of the Check? For Updat?es butto?n. Check?Butto?nStat?us check?_butt?on_st?atus_?; // The class? that commu?nicat?es with Googl?e Updat?e to find out if an updat?e is // avail?able and asks it to start? an upgra?de. Googl?eUpda?te* googl?e_upd?ater_?; // Our curre?
21、nt versi?on. std::wstri?ng curre?nt_ve?rsion?_; // The versi?on Googl?e Updat?e repor?ts is avail?able to us. std::wstri?ng new_v?ersio?n_ava?ilabl?e_; DISAL?LOW_E?VIL_C?ONSTR?UCTOR?S(About?Chrom?eView?); }; 通過關(guān)于對?話框的分析?,可以理解到?chrom?e瀏覽器窗?口基本組成?,以及窗口繼?承關(guān)系,還有事件的?響應(yīng)方式。前面三次分?析,主要是入門?的分析
22、,也是了解這?么一個(gè)大工?程的一種手?段。比如測試整?個(gè)工程是否?可以編譯,是否可以修?改代碼等等?。后面的分析?會(huì)以瀏覽器?輸入HTT?P連接開始?,直到打開網(wǎng)?頁顯示為一?個(gè)主線,做一個(gè)基本?的分析。 當(dāng)用戶打開?瀏覽器之后?,最希望輸入?的地方,是瀏覽器的?連接框。目前谷歌瀏?覽器把輸入?連接框與搜?索引擎輸入?合并到一起?,可以說完美?的組合,讓界面更加?簡潔,方便實(shí)用,并且它自動(dòng)?完成的功能?更加強(qiáng)勁,如下圖所示?: 上面輸入了?www.c時(shí),它就會(huì)自動(dòng)?地在后面添?加智能選擇?的連接,并且可以G?OOGLE?里搜索輸入?的內(nèi)容,又如下面:
23、 上面在輸入?框里輸入我?的名字,就會(huì)自動(dòng)彈?出查找的內(nèi)?容,或者可能搜?索的連接。這些功能都?比較完美的?實(shí)現(xiàn),這可以說是?史無前例的?輸入創(chuàng)新,真正人性化?的體現(xiàn),那么它又是?怎么樣實(shí)現(xiàn)?的呢?其主要功能?是在文件s?rc\chrom?e\brows?er\autoc?omple?te\autoc?omple?te_ed?it.cc里實(shí)現(xiàn)?,具體的實(shí)現(xiàn)?方式內(nèi)容等?下一次再去?分析。 前面已經(jīng)介?紹了這么引?人的輸入自?動(dòng)完成功能?,并且可以在?輸入超級連?接框里直接?通過GOO?GLE搜索?所有的內(nèi)容?,這是比較大?的創(chuàng)新,不但可以節(jié)?省界面的占?用面積,還很方便大?家查
24、詢的需?要,比如記不住?的連接,根本不需要?去記了,只要你記住?需要的內(nèi)容?就行了。這樣既不需?要到什么門?戶網(wǎng)站去找?連接,也不需要去?記住眾多的?網(wǎng)站,這個(gè)功能是?非常方便的?。 這個(gè)輸入框?的自動(dòng)完成?的功能,是比較智能?化的。因?yàn)樗鼤?huì)根?據(jù)以往的輸?入自動(dòng)完成?,或者智能提?示所需要的?連接或者內(nèi)?容。 下面就來先?看這個(gè)類的?定義: #001 // Provi?des the imple?menta?tion of an edit contr?ol with a drop-down #002 // autoc?omple?te box. The box itsel?f is
25、 imple?mente?d in autoc?omple?te_po?pup.cc #003 // This file imple?ments? the edit box and manag?ement? for the popup?. #004 // #005 // This imple?menta?tion is curre?ntly appro?priat?e for the URL bar, where? the #006 // autoc?omple?te dropd?own is alway?s displ?ayed becau?se there? is alway?s
26、a
#007 // defau?lt item. For web page autof?ill and other? appli?catio?ns, this is
#008 // proba?bly not appro?priat?e. We may want to add a flag to deter?mine which?
#009 // of these? modes? were in.
#010 class? Autoc?omple?teEdi?t
#011 : publi?c CWind?owImp?l 27、EditC?trl,
#013 CWinT?raits? 28、窗?口,它是WTL?里的窗口模?板類,主要用來創(chuàng)?建窗口界面?類,并且使用類?CRich?EditC?trl作為?基類,類CRic?hEdit?Ctrl主?要調(diào)用Wi?ndows?里的編輯類?。類CRic?hEdit?Comma?nds實(shí)現(xiàn)?RichE?dit的命?令功能。Menu::Deleg?ate類是?實(shí)現(xiàn)智能下?拉式菜單的?提示界面。因此,要學(xué)習(xí)開發(fā)?chrom?e,需要先學(xué)習(xí)?WTL的開?發(fā),它是一套基?于模板的窗?口框架。下一次再仔?細(xì)地分析自?動(dòng)完成的實(shí)?現(xiàn)過程。
當(dāng)我們鍵入?字母或者文?字開始時(shí),那么類Au?tocom?plete?Edit就?會(huì)從窗口消?息里獲取到?相應(yīng)的字 29、母?或者文字,然后根據(jù)輸?入的信息到?本地或者網(wǎng)?絡(luò)上保存的?信息庫里查?找相應(yīng)的輸?入提示,這就是自動(dòng)?完成的實(shí)現(xiàn)?。下面就來先?分析輸入的?函數(shù):
#001 void Autoc?omple?teEdi?t::OnCha?r(TCHAR? ch, UINT repea?t_cou?nt, UINT flags?) {
#002 // Dont let alt-enter? beep. Not sure this is neces?sary, as the stand?ard
#003 // alt-enter? will hit Disca?rdWMS?ysCha?r() and g 30、et throw?n away, and
#004 // ctrl-alt-enter? doesn?t seem to reach? here for some reaso?n? At least? not on
#005 // my syste?m... still?, this is harml?ess and maybe? neces?sary in other? local?es.
下面把a(bǔ)l?t-enter?組合鍵消息?過濾掉。
#006 if (ch == VK_RE?TURN && (flags? & KF_AL?TDOWN?))
#007 retur?n;
# 31、008
#009 // Escap?e is proce?ssed in OnKey?Down. Dont let any WM_CH?AR messa?ges propa?gate
#010 // as we dont want the RichE?dit to do anyth?ing funky?.
下面把ES?C鍵的消息?過濾掉。
#011 if (ch == VK_ES?CAPE && !(flags? & KF_AL?TDOWN?))
#012 retur?n;
#013
下面把TA?B鍵的消息?過濾掉。
#014 if (ch == VK_TA?B) 32、{
#015 // Dont add tabs to the input?.
#016 retur?n;
#017 }
#018
這里處理其?它有用的按?鍵消息。
#019 Handl?eKeys?troke?(GetCu?rrent?Messa?ge()->messa?ge, ch, repea?t_cou?nt, flags?);
#020 }
Autoc?omple?teEdi?t::OnCha?r函數(shù)是W?TL里的W?M_CHA?R消息處理?,當(dāng)用戶鍵入?字母時(shí)就會(huì)?觸發(fā)這個(gè)消?息。這個(gè)函數(shù)先?跳過幾個(gè)不?要處理的消?息,最后調(diào)用函?數(shù)Hand?leKey?s 33、trok?e來處理,如下:
#001 void Autoc?omple?teEdi?t::Handl?eKeys?troke?(UINT messa?ge, TCHAR? key,
#002 UINT repea?t_cou?nt, UINT flags?) {
凍結(jié)Ric?hEdit?的更新。
#003 Scope?dFree?ze freez?e(this, GetTe?xtObj?ectMo?del());
處理消息變?化前的動(dòng)作?。
#004 OnBef?orePo?ssibl?eChan?ge();
處理消息
#005 DefWi?ndowP?roc(me 34、ssa?ge, key, MAKEL?PARAM?(repea?t_cou?nt, flags?));
處理消息變?化后的動(dòng)作?。
#006 OnAft?erPos?sible?Chang?e();
#007 }
在這里為什?么要進(jìn)行窗?口的消息凍?結(jié)呢?又為什么需?要進(jìn)行消息?處理和消息?變化后處理?呢?下一次再告?訴你。
上一次說到?處理WM_?CHAR消?息,當(dāng)用戶每鍵?入一個(gè)字符?時(shí),萬能連接框?就會(huì)去進(jìn)行?一次查找的?過程,然后把智能?提示信息顯?示出來。說到Aut?ocomp?leteE?dit::Handl?eKeys?troke?函數(shù)的操作?,那么它為什?么需 35、要凍結(jié)?這個(gè)函數(shù)的?使用呢?現(xiàn)在就來分?析這部份的?內(nèi)容。如下:
Scope?dFree?ze freez?e(this, GetTe?xtObj?ectMo?del());
在這行代碼?里,首先會(huì)調(diào)用?函數(shù)Get?TextO?bject?Model?()來獲取一個(gè)?文檔ITe?xtDoc?ument?接口,然后再使用?它的功能。這個(gè)函數(shù)的?代碼如下:
#001 IText?Docum?ent* Autoc?omple?teEdi?t::GetTe?xtObj?ectMo?del() const? {
先判斷這個(gè)?接口是否獲?取到,如果已經(jīng)獲?取到就不再?去重復(fù)獲取?了。
#00 36、2 if (!text_?objec?t_mod?el_) {
#003 // This is lazil?y initi?alize?d, inste?ad of being? initi?alize?d in the
#004 // const?ructo?r, in order? to avoid? hurti?ng start?up perfo?rmanc?e.
這里使用了?智能指針來?獲取IRi?chEdi?tOle接?口。
#005 CComP?tr 37、到智能指針?里。
#006 ole_i?nterf?ace.Attac?h(GetOl?eInte?rface?());
下面通過=操作符獲取?IText?Docum?ent接口?,如果你深入?去分析這個(gè)?賦值操作符?,會(huì)看到它自?動(dòng)去調(diào)用I?RichE?ditOl?e的接口I?Unkno?wn::Query?Inter?face來?查詢到IT?extDo?cumen?t接口,這個(gè)過程對?于程序員來?說是完全不?用關(guān)心的,這就是使用?mutab?le CComQ?IPtr 38、ext_?objec?t_mod?el_ = ole_i?nterf?ace;
#008 }
#009 retur?n text_?objec?t_mod?el_;
#010 }
通過上面的?分析,可見使用C?ComQI?Ptr 39、部對?象在棧里生?命周期的特?性應(yīng)用。如下面的代?碼:
#001 Autoc?omple?teEdi?t::Scope?dFree?ze::Scope?dFree?ze(Autoc?omple?teEdi?t* edit,
#002 IText?Docum?ent* text_?objec?t_mod?el)
#003 : edit_?(edit),
#004 text_?objec?t_mod?el_(text_?objec?t_mod?el) {
#005 // Freez?e the scree?n.
#006 if (text_?objec?t_mod?el_) {
40、#007 long count?;
#008 text_?objec?t_mod?el_->Freez?e(&count?);
#009 }
#010 }
#011
#012 Autoc?omple?teEdi?t::Scope?dFree?ze::~Scope?dFree?ze() {
#013 // Unfre?eze the scree?n.
#014 // NOTE: If this destr?uctor? is reach?ed while? the edit is being? destr?oyed (for
#015 // examp?le, becau?se 41、 we doubl?e-click?ed the edit of a popup? and cause?d it to
#016 // trans?form to an uncon?strai?ned windo?w), it will no longe?r have an HWND, and
#017 // text_?objec?t_mod?el_ may point? to a destr?oyed objec?t, so do nothi?ng here.
#018 if (edit_?->IsWin?dow() && text_?objec?t_mod?el_) {
#019 42、 long count?;
#020 text_?objec?t_mod?el_->Unfre?eze(&count?);
#021 if (count? == 0) {
這里需要手?動(dòng)地更新窗?口的顯示。
#022 // We need to Updat?eWind?ow() here inste?ad of Inval?idate?Rect() becau?se, as
#023 // far as I can tell, the edit likes? to synch?ronou?sly erase? its backg?round?
#024 // when unfr 43、e?ezing?, thus requi?ring us to synch?ronou?sly redra?w if we dont
#025 // want flick?er.
#026 edit_?->Updat?eWind?ow();
#027 }
#028 }
#029 }
從上面的代?碼可以看到?構(gòu)造函數(shù)里?凍結(jié),析構(gòu)造函數(shù)?里解凍結(jié),如果需要就?會(huì)自動(dòng)更新?窗口的顯示?。
通過上面的?分析,學(xué)會(huì)使用R?ichEd?it的凍結(jié)?窗口的輸入?,并且解凍結(jié)?和更新窗口?的顯示,也同時(shí)學(xué)會(huì)?使用智能指?針來操作C?OM接口的?方便性,最后還學(xué)會(huì)?了使用棧對?象的生命周 44、?期來方便對?加鎖和解鎖?的操作,以便降低代?碼的出錯(cuò)率?。
為了處理字?符消息實(shí)現(xiàn)?自動(dòng)完成的?功能,這是怎么樣?實(shí)現(xiàn)的呢?其實(shí)是先記?錄字符消息?響應(yīng)前的字?符串以及選?中狀態(tài),接著再處理?消息,最后才查詢?可能的輸入?,做出智能提?示。
#001 void Autoc?omple?teEdi?t::OnBef?orePo?ssibl?eChan?ge() {
#002 // Recor?d our state?.
記錄當(dāng)前已?經(jīng)輸入的字?符串。
#003 text_?befor?e_cha?nge_ = GetTe?xt();
記錄當(dāng)前選?中的字符位?置。
#004 45、 GetSe?lecti?on(sel_b?efore?_chan?ge_);
#005 selec?t_all?_befo?re_ch?ange_? = IsSel?ectAl?l(sel_b?efore?_chan?ge_);
#006 }
上面就保存?字符消息響?應(yīng)前的狀態(tài)?,接著下來就?是消息響應(yīng)?后的處理了?,如下:
#001 bool Autoc?omple?teEdi?t::OnAft?erPos?sible?Chang?e() {
#002 // Preve?nt the user from selec?ting the "phant?om newli?ne" a 46、t the end of the
#003 // edit. If they try, we just silen?tly move the end of the selec?tion back to
#004 // the end of the real text.
判斷用戶新?選中狀態(tài)。
#005 CHARR?ANGE new_s?el;
#006 GetSe?lecti?on(new_s?el);
#007 const? int lengt?h = GetTe?xtLen?gth();
#008 if ((new_s?el.cpMin? > lengt?h) || (n 47、ew_s?el.cpMax? > lengt?h)) {
#009 if (new_s?el.cpMin? > lengt?h)
#010 new_s?el.cpMin? = lengt?h;
#011 if (new_s?el.cpMax? > lengt?h)
#012 new_s?el.cpMax? = lengt?h;
#013 SetSe?lecti?onRan?ge(new_s?el);
#014 }
判斷用戶是?否輸入字符?有變化。
#015 const? bool selec?tion_?diffe?rs = (new_s?el.cpMin? != sel_ 48、b?efore?_chan?ge_.cpMin?) ||
#016 (new_s?el.cpMax? != sel_b?efore?_chan?ge_.cpMax?);
#017
#018 // See if the text or selec?tion have chang?ed since? OnBef?orePo?ssibl?eChan?ge().
#019 const? std::wstri?ng new_t?ext(GetTe?xt());
#020 const? bool text_?diffe?rs = (new_t?ext != text_?befor?e_cha? 49、nge_);
#021
#022 // Updat?e the paste? state? as appro?priat?e: if were just finis?hing a paste?
#023 // that repla?ced all the text, prese?rve that infor?matio?n; other?wise, if weve
#024 // made some other? edit, clear? paste? track?ing.
#025 if (paste?_stat?e_ == REPLA?CING_?ALL)
#026 past 50、e?_stat?e_ = REPLA?CED_A?LL;
#027 else if (text_?diffe?rs)
#028 paste?_stat?e_ = NONE;
#029
如果輸入沒?有任何變化?,就返回去。
#030 // If somet?hing has chang?ed while? the contr?ol key is down, preve?nt
#031 // "ctrl-enter?" until? the contr?ol key is relea?sed. When we do this, we need
#032 // to updat? 51、e the popup? if its open, since? the desir?ed_tl?d will have chang?ed.
#033 if ((text_?diffe?rs || selec?tion_?diffe?rs) &&
#034 (contr?ol_ke?y_sta?te_ == DOWN_?WITHO?UT_CH?ANGE)) {
#035 contr?ol_ke?y_sta?te_ = DOWN_?WITH_?CHANG?E;
#036 if (!text_?diffe?rs && !popup?_->is_op?en())
#037 retur?n 52、false?; // Dont open the popup? for no reaso?n.
#038 } else if (!text_?diffe?rs &&
#039 (inlin?e_aut?ocomp?lete_?text_?.empty?() || !selec?tion_?diffe?rs)) {
#040 retur?n false?;
#041 }
#042
#043 const? bool had_k?eywor?d = !is_ke?yword?_hint?_ && !keywo?rd_.empty?();
#044
下面開始設(shè)?置新的顯示?字符 53、串。
#045 // Modif?ying the selec?tion count?s as accep?ting the autoc?omple?ted text.
#046 Inter?nalSe?tUser?Text(UserT?extFr?omDis?playT?ext(new_t?ext));
#047 has_t?empor?ary_t?ext_ = false?;
#048
#049 if (text_?diffe?rs) {
#050 // When the user has delet?ed text, dont allow? inlin?e autoc?om 54、ple?te. Make
#051 // sure to not flag cases? like selec?ting part of the text and then pasti?ng
#052 // (or typin?g) the prefi?x of that selec?tion. (We detec?t these? by makin?g
#053 // sure the caret?, which? shoul?d be after? any inser?tion, hasnt moved?
#054 // forwa?rd of the old selec?tion 55、 start?.)
#055 just_?delet?ed_te?xt_ = (text_?befor?e_cha?nge_.lengt?h() > new_t?ext.lengt?h()) &&
#056 (new_s?el.cpMin? <= std::min(sel_b?efore?_chan?ge_.cpMin?,
#057 sel_b?efore?_chan?ge_.cpMax?));
#058
#059 // When the user doesn?t have a selec?ted keywo?rd, delet?ing text or repla?cing
#0 56、60 // all of it with somet?hing else shoul?d reset? the provi?der affin?ity. The
#061 // typic?al use case for delet?ing is that the user start?s typin?g, sees that
#062 // some entry? is close? to what he wants?, arrow?s to it, and then delet?es some
#063 // unnec?essar?y bit from the end of the 57、 strin?g. In this case the user didnt
#064 // actua?lly want "provi?der X", he wante?d the strin?g from that entry? for
#065 // editi?ng purpo?ses, and hes no longe?r looki?ng at the popup? to notic?e that,
#066 // despi?te delet?ing some text, the actio?n well take on enter? hasnt chang?ed
#067 58、 // at all.
這里刪除已?經(jīng)選擇的提?示。
#068 if (!had_k?eywor?d && (just_?delet?ed_te?xt_ || selec?t_all?_befo?re_ch?ange_?)) {
#069 popup?_->manua?lly_s?elect?ed_ma?tch_.Clear?();
#070 }
#071 }
#072
#073 // Disab?le the fancy? keywo?rd UI if the user didnt alrea?dy have a visib?le
#074 // keywo?rd an 59、d is not at the end of the edit. This preve?nts us from showi?ng
#075 // the fancy? UI (and inter?rupti?ng the users editi?ng) if the user happe?ns to
#076 // have a keywo?rd for a, types? ab then puts a space? betwe?en the a and
#077 // the b.
#078 disab?le_ke?yword?_ui_ = (is_ke?yword?_hint?_ 60、|| keywo?rd_.empty?()) &&
#079 ((new_s?el.cpMax? != lengt?h) || (new_s?el.cpMin? != lengt?h));
#080
更新智能提?示菜單。
#081 Updat?ePopu?p();
#082
#083 if (!had_k?eywor?d && !is_ke?yword?_hint?_ && !keywo?rd_.empty?()) {
#084 // Went from no selec?ted keywo?rd to a selec?ted keywo?rd. Set the affi 61、n?ity to
#085 // the keywo?rd provi?der. This force?s the selec?ted keywo?rd to persi?st even
#086 // if the user delet?es all the text.
#087 popup?_->manua?lly_s?elect?ed_ma?tch_.Clear?();
#088 popup?_->manua?lly_s?elect?ed_ma?tch_.provi?der_a?ffini?ty =
#089 popup?_->autoc?omple?te_co?ntrol?l 62、er()->keywo?rd_pr?ovide?r();
#090 }
#091
當(dāng)自動(dòng)完成?框字符串發(fā)?生變化,就需要更新?URL重點(diǎn)?顯示。
#092 if (text_?diffe?rs)
#093 TextC?hange?d();
#094
#095 retur?n true;
#096 }
在這個(gè)函數(shù)?里,先判斷字符?串是否發(fā)生?變化,然后根據(jù)變?化來決定是?否更新編輯?框的顯示,同時(shí)還需要?Updat?ePopu?p更新智能?提示菜單,最后判斷是?否有一個(gè)U?RL地址,如果有就重?點(diǎn)顯示出來?。
其實(shí)這里最?關(guān)鍵的問題?就是智能菜?單的數(shù)據(jù)從?那里來的呢??怎么樣根據(jù)?用戶的輸入?查找到最合?適的提示呢??下一次我們?再來分析這?方面的問題?。
上一次已經(jīng)?分析到輸入?字符后,就需要把這?些關(guān)鍵字去?查找歷史的?連接,或者相關(guān)的?內(nèi)容,那么可多米?的瀏覽器又?是從那里去?找到這些數(shù)?據(jù)呢?現(xiàn)在就來分?析這方面相?關(guān)的內(nèi)容。它主要通下?面的函數(shù)來?實(shí)現(xiàn):
#001 void Autoc?omple?
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 市教育局冬季運(yùn)動(dòng)會(huì)安全工作預(yù)案
- 2024年秋季《思想道德與法治》大作業(yè)及答案3套試卷
- 2024年教師年度考核表個(gè)人工作總結(jié)(可編輯)
- 2024年xx村兩委涉案資金退還保證書
- 2024年憲法宣傳周活動(dòng)總結(jié)+在機(jī)關(guān)“弘揚(yáng)憲法精神推動(dòng)發(fā)改工作高質(zhì)量發(fā)展”專題宣講報(bào)告會(huì)上的講話
- 2024年XX村合作社年報(bào)總結(jié)
- 2024-2025年秋季第一學(xué)期初中歷史上冊教研組工作總結(jié)
- 2024年小學(xué)高級教師年終工作總結(jié)匯報(bào)
- 2024-2025年秋季第一學(xué)期初中物理上冊教研組工作總結(jié)
- 2024年xx鎮(zhèn)交通年度總結(jié)
- 2024-2025年秋季第一學(xué)期小學(xué)語文教師工作總結(jié)
- 2024年XX村陳規(guī)陋習(xí)整治報(bào)告
- 2025年學(xué)校元旦迎新盛典活動(dòng)策劃方案
- 2024年學(xué)校周邊安全隱患自查報(bào)告
- 2024年XX鎮(zhèn)農(nóng)村規(guī)劃管控述職報(bào)告