螢幕取字原理

2021-04-02 17:23:26 字數 3947 閱讀 3515

一   公開它!  

四通利方和金山詞霸的使用者都曾見識過螢幕抓字技術,滑鼠指哪就翻譯哪個單  

詞,這個技術看似簡單,其實在windows系統中實現卻是非常複雜和有趣的。   經  

過半年多的艱辛探索,筆者終於破解了其中的秘密,並在今天決定公開它,這個  

人人   都曾見過但是卻鮮有人知的秘密,這個只被幾家軟體公司壟斷從未在公開的報刊   資   料披露過只言片語的秘密!  

回想這半年多的探索,其中浸潤了多少筆者的苦悶與歡樂,絕望與興奮,挫   折  

與收穫,現在都終於有了結果:將螢幕抓字技術的秘密公開,獻給孜孜不倦辛勤  

工   作的程式設計師們。如果這樣做能為國產軟體事業的發展效微薄之力,對筆者來說,也   是一樁快事!  

二   初識螢幕抓字  

最初知道螢幕抓字,   是在購買了〖英漢通〗軟體之後。   當時筆者還只是一   個  

visual   basic   的初學者,   對   windows   系統內部的知識了解並不多,   認為   在  

windows系統中螢幕抓字的實現應該和dos系統中的一樣,呼叫乙個dos   中斷取屏  

幕   上的字元或直接讀顯示記憶體的內容就可以了。  

三   看似很簡單,其實不然  

隨著對windows系統的認識不斷深入,才發現問題並不象想得那麼簡單。首先,  

翻閱了winodws應用程式介面(api)中的上千個函式,並沒有發現有乙個現成的  

類   似於getwordfrompoint()的函式;根據使用經驗,經過判斷發現螢幕抓字採用的   也   不是影象識別技術;翻閱了sdk的聯機文件中沒有,ddk的聯機文件中也沒有;顯示   卡程式設計介面的資料則很難獲得,有的也只是cga到vga視訊記憶體的基本知識。回想當時   坐   在機子前,面對一屏屏的聯機資料(如果是紙,將堆積如山),感覺就是在黑暗   中   的大海浬航行,沒有方向,沒有燈光,但強烈的興趣緊抓著我,一定要把這個謎   解   開。  

四   選擇合適的程式設計工具  

突然又有了一些新的想法:  

可否試著截獲windows中關於字元的訊息呢?  

dc(裝置描述表)到底是什麼?  

windows的textout函式是否將text放在dc的某個單元中?  

顯然,用visual   basic就力不從心了。在dos中用turbo   c程式設計筆者還算熟練  

,  

因此先嘗試用visual   c++,但是奇慢的編譯速度使人難以忍受,   高度抽象的類  

讓   人一頭霧水,開發商務軟體可能還行,但開發這樣乙個深入windows   內部的系統     件,望著一堆纏繞不清的類和訊息,真有點牛刀宰雞、刺刀耕田的感覺。  

最後選擇了delphi,第一印象是編譯速度真快,在我的祖父型386   機子上   編  

譯乙個windows程式,速度和用turbo   c的速度感覺差不多,真讓人興奮得愛不釋手。   隨著不斷使用,發覺delphi真是乙個好的快速開發工具,(快速並不意味著簡單   粗   糙,而是和windows系統有混然一體良好介面的表現)讓初學者也很容易上手。   調   用各種windows   函式(包括很多未公開的函式)都非常直接迅速,用它來作開發   工   具,大有刺刀見紅、一劍封喉的痛快感覺。  

五   山窮水盡疑無路  

隨著對windows系統了解的深入,我逐漸明白了在向螢幕輸出文字時,windo  

ws   系統僅僅只是對某個應用程式傳送wm_paint訊息,告訴該應用程式視窗使用者區已   經  

「無效」而需要重畫。具體的「繪製」工作(選擇字型,顏色,文字)由應用程  

序   完成。   應用程式在處理wm_paint訊息時,呼叫beginpaint和endpaint來獲得和釋放   設   備描述表,呼叫drawtext、exttextout、   textout等函式在裝置描述表中「繪製   」   文字。   應用程式「繪製」文字,   就象學生(應用程式)奉命(獲得   wm_paint訊息   )   用老師(windows)提供的畫筆(drawtext   exttextout   textout等)   在黑板上畫   畫   一樣,雖然大家能看到畫的是什麼字,但是畫筆作為繪圖工具並不知道畫的是什   麼。  

老師(windows)不知道學生(應用程式)到底用什麼字型,顏色,畫哪些文字。  

總之   ,windows並不知道應用程式「繪製」的是什麼。「文字」對   windo  

ws  

來說只是畫筆留在黑板(螢幕)上的粉筆印,只是繪畫的痕跡。「文字」只存在  

於  

應用程式的模組中,對windows系統是「不可見」的。  

到處走投無路,真想掂5000塊錢,跑到「英漢通」公司買回這個秘密。仔細  

一  

想,錢太少,就是多掂10倍,人家也不一定說。  

六   柳暗花明又一村  

經過再三考慮,我聯想到在dos系統中程式設計,會採取改變中斷向量位址,   設  

置  

新的中斷向量的技術:如果系統呼叫這個中斷,就會先進入新的中斷服務程式,  

然  

後再呼叫原來的中斷服務程式。  

那末,在windows系統中也採取這種技術,使系統如果呼叫某個函式,   先進  

入  

乙個跟蹤函式,取得原函式的引數,再呼叫原來的函式。聽起來是否象病毒傳染  

和  

發作?其實很多程式都採用過類似技術。大學畢業設計音效卡時我就用過。  

至此,   我認識到應該放棄常規的思路,   採取一些技巧,   截獲   textout  

、  

exttextout等函式,使之轉向我的跟蹤函式,在此檢視應用程式(學生)的堆疊  

中  

傳遞給畫筆(textout、exttextout等函式)的引數,   從而獲得應用程式要在屏  

幕  

上寫的「文字」。  

七 「   螢幕抓字」的實現  

1   用setwindowshookex()安裝滑鼠鉤子mouseproc;  

2   在螢幕上移動滑鼠時,系統就會呼叫滑鼠鉤子mouseproc;  

3   進入mouseproc,獲得滑鼠的座標(x,y),  

設定對textout()、exttextout()等的跟蹤程式,  

用invalidaterect()告訴系統該點(x,y)「失效」;  

4  

系統發出wm_paint訊息,指示該點(x,y)處的應用程式重繪「失效」的區域。  

5   負責繪製該點()的應用程式在受到   wm_paint   訊息後,   就有機會呼叫  

textout()、   exttextout()等函式。  

6   呼叫的函式被攔截進入跟蹤程式:設定好了的跟蹤程式截獲了該次呼叫,  

從  

應用程式的堆疊中取出   該點(x,y)「文字」的指標;  

7   從應用程式的資料段中將「文字」指標的內容取出,即完成了一次「螢幕  

抓  

字」;  

8   退出跟蹤程式,返回到滑鼠鉤子mouseproc;  

9   在mouseproc中解除對textout()   exttextout()的跟蹤;  

10   退出mouseproc滑鼠鉤子程式,控制權交給系統。  

11   在螢幕上移動滑鼠,開始下一次「螢幕抓字」,返回步驟2。  

八   前景展望  

掌握了「螢幕抓字」的技術秘密,稍加改變,我們就可對windows   系統中  

的  

任意乙個函式呼叫進行動態地攔截、跟蹤、修改和恢復,就可讓windows   系統中  

的  

任意乙個函式按我們的設想工作,就可構造自己的外掛程式漢字平台,設計改變字型  

的  

放大鏡、改變顏色的變色鏡,保護視力的軟體視保屏等等。  

螢幕適配原理

為什麼需要螢幕適配?android機型碎片化嚴重 各種機型解析度的手機都有 解析度太多,為了ui美觀,良好的使用者體驗 所以螢幕適配 布局適配 布局適配 1.dp,px,sp,相對布局,權重,matchparent,dp dip 在螢幕密度是160ppi的時候 1dp 1px px 畫素 構成影象的...

android螢幕適配原理

android裝置碎片化非常嚴重,如圖,每個小色塊代表一種裝置解析度 各種解析度的裝置要想全部完美適配是不可能的,那麼就可以理解,如上幾個資料夾劃分了一部分區間,拿過來乙個機器,它的畫素密度引數接近哪個就用哪個資料夾的 做測試 heightpixels widthpixels density den...

ApiCloud螢幕適配原理及實現

螢幕尺寸 嚴格來說,螢幕尺寸實際被物理尺寸和顯示解析度兩個部分定義。而我們今天對各類手機 pad 裝置所說的螢幕尺寸,只指物理尺寸。如果一塊手機螢幕的物理尺寸是 5.5 英吋,即是指該手機螢幕對角線的長度。螢幕解析度 螢幕解析度是指螢幕影象的精密度,是顯示器所能顯示的畫素的具體數值。如乙個手機標稱解...