發信人: starsky (星星), 信區: programming
標 題: 螢幕抓字揭密(轉寄)
發信站: 煙雨漓江 (tue may 9 21:46:50 2000), 轉信
(本文**自華南木棉站)
螢幕抓字技術揭密
----------深入windows內部探險手記
鄭州 馬飛濤
一 公開它!
四通利方和金山詞霸的使用者都曾見識過螢幕抓字技術,滑鼠指哪就翻譯哪個單
詞,這個技術看似簡單,其實在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系統了解的深入,我逐漸明白了在向螢幕輸出文字時,windows
系統僅僅只是對某個應用程式傳送wm_paint訊息,告訴該應用程式視窗使用者區已經
「無效」而需要重畫。具體的「繪製」工作(選擇字型,顏色,文字)由應用程式
完成。應用程式在處理wm_paint訊息時,呼叫beginpaint和endpaint來獲得和釋放設
備描述表,呼叫drawtext、exttextout、 textout等函式在裝置描述表中「繪製」
文字。應用程式「繪製」文字, 就象學生(應用程式)奉命(獲得 wm_paint訊息)
用老師(windows)提供的畫筆(drawtext exttextout textout等) 在黑板上畫畫
一樣,雖然大家能看到畫的是什麼字,但是畫筆作為繪圖工具並不知道畫的是什麼。
老師(windows)不知道學生(應用程式)到底用什麼字型,顏色,畫哪些文字。
總之 ,windows並不知道應用程式「繪製」的是什麼。「文字」對 windows
來說只是畫筆留在黑板(螢幕)上的 郾視。 只是繪畫的 奐!! 文字」只存在於
應用程式的模組中,對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 系統中的
任意乙個函式按我們的設想工作,就可構造自己的外掛程式漢字平台,設計改變字型的
放大鏡、改變顏色的變色鏡,保護視力的軟體視保屏等等。
九 後記
希望此文能拋磚引玉,為大家程式設計時能找到捷徑,開拓出新的思路;
對攔截、跟蹤感興趣的朋友也請來信交流切磋,如需dll 或「抓字」的源代
碼,敬請
與 [email protected] 聯絡;
如能得到「四通利方」、「金山詞霸」、「英漢通」等公司的教導與指正,
筆者不勝感激。
----------------------------
email: [email protected]
金山詞霸」螢幕取詞技術揭密 討論稿
這篇文章最早是發在北極星論壇的一系列帖子,那時候聞怡洋 好像他也是mvp 也在那裡混 原始的帖子我已經沒有了,但不知道是誰幫我收集整理了下來 非常感謝 我用google找到了 這是我進金山之前寫的,應該不算洩露公司技術秘密吧 而且這些現在看來似乎已經有些過時了 那時討論的只是win31和win9x下...
揭密顯示螢幕背後高畫質晰電視技術
摘要 為了最優化整個數碼電視的成本和效能,當針對數碼電視中的任何模組作出設計決策時,要從整個系統的要求出發來考慮。較低端的電源方案會把雜訊留在訊號路徑中,然後,由模擬前端 afe 來補償。同樣地,附加在高解析度顯示器上的效能較弱的afe就不能完全發揮所選擇的顯示技術的優勢。數碼電視基礎 即使目前在貨...
《C 技術揭密》手記
2007 12 26 19.5,這個例子。把commprotocol及其子類都放在乙個專案中,然後單獨生成幾個類的dll檔案,然後編譯專案,編譯成功。執行時卻總會報乙個commprotocol同時存在於和中,省略號為guid,看起來感覺這個類應該同時存在於兩個dll中,可是dll就這麼幾個,還有別的...