WinSight: 窗口偵查(Spying on Windows)
Note
WinSight在Win7下無法正常工作,因此我們在XP環境下介紹下WinSight工具。
WinSight是一個工具,用戶可以使用這個工具來偵查Windows。WinSight顯示正在運行的每一個應用程序及應用程序的每一個窗口(別忘了,控件也是窗口)。同時WinSight也顯示Windows產生的每一條消息(即發送到窗口的每一條消息)。
用戶可選擇查看所有消息或查看發送某個特定窗口的消息。要啟動WinSight,可在Windows資源管理器中先找到WS32.EXE並雙擊該文件(該文件在Delphi7\Bin目錄下)。像Image Editor一樣,WinSight也是一個獨立程序,可以在Delphi IDE以外運行。如下圖,正在偵查Windows資源管理器的WinSight。
從上圖可以看出,WinSight窗口分成兩個窗格,上面的窗格列出了活動的窗口,下面的窗格顯示發送到某個特定窗口或全部窗口的消息。拖動兩個窗格之間的分隔條可以調整窗格的大小。缺省時,WinSight窗口被水平分割成兩部分;單用戶也可以選擇垂直分割。如下圖:
要改變WinSight窗口的布局,可從【View】菜單選擇【Split Horizontal】或【Split Vertical】菜單項。
下面我們先介紹一下Windows消息。
窗口消息接送系統(The Windows Messaging System)
如果對Windows不了解,那么偵查Windows也是徒勞無益的。因此,用戶必須花上一定時間來學習Windows編程,才能真正理解WinSight所顯示的所有信息。
Delphi是一個高級平台,使用戶能在最短的時間內編寫出真正獨立的Windows應用程序。如果要說這個編程環境有缺點的話,那就是用戶沒有機會了解是什么東西真正驅動Windows應用程序運行。
驅動Windows應用給程序運行的是消息,許多許多的消息。Windows發送一條窗口消息來指示窗口的動作或通知窗口某個事件已發生。例如,當一個窗口要刷新時,Windows給它發送一條WM_PAINT消息,這條WM_PANIT消息指示該窗口進行刷新。
當一個窗口被改變大小時,Windows發送一條WM_WINDOWPOSCHANGING 消息通知窗口,其大小或位置正在改變;當修改完窗口的大小和位置后,還要發送WM_WINDOWPOSCHANGED消息和WM_SIZE消息到該窗口。在一個普通Windows環境中,消息發送在一秒內要發生幾十次甚至幾百次。
Windows能發送給應用程序的消息有100多條。在前面的講解中,已經講述過少量Windows消息。Delphi程序響應的許多事件都是Windows消息。OnCreate事件是響應WM_CREATE消息所產生的。還可以繼續舉例下去。Delphi使用戶能在更高層次上處理消息,因而用戶不用編寫應用程序中更重要的部分。
最終,用戶會想知道:是什么驅動Windows運行。Delphi的最大優點是:用戶能很快學會編寫Windows程序,並逐步了解更深層次的內容。
Note
一些非常優秀的Windows程序員可能要說:應該先學習用C語言編寫Windows程序;他們認為,C語言編程基礎對每一個Windows程序員都是必須的,不論他使用何種編程環境。盡管作者也贊同這是一個最佳設想,但仍然認為,今天很少有程序員能花這么多時間來學習C語言編程。
簡要介紹Windows消息后,我們回過頭來看WinSight是如何工作的。
窗口的偵查(Spying on a Window)
WinSight窗口的上窗格稱作窗口樹。窗口樹顯示當前打開的所有窗口;它還顯示有關某個特定窗口的窗口類的一些詳細信息。該信息以如下的形式顯示:
Overlapped 0007013C {CabinetWClass} Explorer.EXE (879,80)-(1679, 680) “E:\HyperSnap 7”
該行第一項指明窗口的窗口類型。此處是一個重疊窗口(WS_OVERLAPPED窗口);其他的窗口類型有子窗口、彈出式窗口等,重疊窗口、子窗口和彈出式窗口是最常用的窗口類型。
第二項指明窗口的窗口手柄(HWND),它與VCL窗口組件的Handle屬性相關。
第三項括在大括號內的是窗口類類名,應用程序使用這個類名來注冊窗口。通常是多個窗口共享一個類名。例如,通用按鈕組件的類名為Button,同一時刻在不同應用程序中可能有幾十個按鈕,但它們是同一個窗口類。當應用程序為Delphi應用程序時,對於窗體和組件,WinSight在此處顯示代表該組件的VCL類。對於一個按鈕組件,WinSight顯示的類名是TButton。如下圖:
Note
在開發Delphi1時,Delphi是工程的代碼名,而產品的名稱打算取作AppBuilder。后來Delphi成了正式的產品名。用WinSight偵查Delphi IDE,會發現Delphi主窗口的類名為TAppBuilder。這也算是對這種說法的一個印證。如下圖:
第四項是創建窗口過程的模塊名,通常該模塊是一個可執行程序。此處,模塊名為Explorer.exe。某塊后面是窗口的大小和位置,最后是窗口正文。對於重疊窗口,窗口正文是指出現在標題欄上的文字,對於其他窗口類型,窗口正文的含義隨窗口類型的不同而不同。例如,按鈕的窗口正文是指按鈕上的文字。
Note
在應用程序中創建隱式窗口來完成具體任務,是商業應用程序的慣用做法。隱式窗口只在模塊后顯示“hidden”,由於窗口是隱藏的,因此既沒有大小和位置信息,也沒有任何窗口正文。如下圖:
窗口樹是分層的,樹的頂層是Windows桌面,下一層是桌面的所有子窗口。例如,可執行文件就位於桌面節點下。每個桌面窗口也可以有自己的子窗口。父窗口、子窗口和同級窗口之間用連線聯接。
看上圖,樹窗口中每個項的左邊有一個菱形。若一個窗口有子窗口,則其左邊的菱形中包含一個“+”號或“-”號;“+”號表示該節點是收縮節點,可將其擴展來顯示子窗口;“-”號表示該節點已經擴展,其子窗口已經顯示。可點擊窗口樹中項目左邊任何部位來擴展或收縮節點。菱形為空時,辨識一個窗口無子窗口。
Note
如果窗口樹中的某個窗口被啟用,則每當該窗口接收一條發自Windows的消息時,其左邊的菱形都會閃爍一下。
消息跟蹤窗口(Message Trace Options)
消息跟蹤窗口顯示Windows產生的單條消息。消息跟蹤項的典型形式如下:
000747:00290220 “h□□“ WM_KEYDOWN Dispatched 48h 72d VK_H Scan 23h Down
沒有必要詳細分析其中的內容,因為隨着消息的不同,其中的內容可以有很大差別。此處是一個Memo組件接收一條帶參數VK_H的WM_KEYDOWN的消息,換句話說,就是當光標在Memo組件上時按下h鍵。正如大家所看到的,消息跟蹤項中某些信息也出現在窗口樹中,例如,窗口句柄和類名。
從主菜單選擇【Start!】菜單項,就可以開始消息跟蹤,窗口接收到的消息就會出現在消息跟蹤窗口中。要終止消息跟蹤,可從主菜單選【Stop!】菜單項。
Note
【Stop!】和【Start!】菜單項在主菜單的菜單條上占用同一個位置,當消息跟蹤處於關閉狀態的時候,該菜單項為【Start!】;當消息跟蹤運行是,該菜單項為【Stop!】。
當消息跟蹤窗口接收消息時,消息可以在窗口中滾動。用戶可以終止消息跟蹤,然后滾動查看消息跟蹤窗口中的任何消息。另一個選項是將消息輸出道一個日志文件。
WinSight使用戶能查看發送到所有窗口的消息或發送到某個特定窗口的消息。要查看所有消息,從主菜單選【Message | All Windows】菜單項;雖然用戶可以選擇查看發送到所有窗口的全部消息,但這樣做通常效率不高;因為窗口中的消息又多又復雜,用戶難以查找想要的消息。
比較好的辦法是選擇一個具體窗口,監視該窗口接收的消息。這樣做可以使消息跟蹤窗口便於管理。要查看某個具體窗口的消息,可先在消息樹中找到該窗口,在其上點擊來選擇它;然后從主菜單選擇【Messages | Selected Windows】,再選【Start!】菜單項,任何發送到所選窗口的消息就會出現在消息跟蹤窗口中。
Note
用戶在使用WinSight時,最好是先想好要查看的內容。因為發送到單個窗口的消息很多,用戶要查看的消息可能很快滾過屏幕。為了發揮WinSight的最大效益,用戶可以選擇要查看消息的窗口,啟動消息跟蹤,根據需要操作窗口,然后關閉消息跟蹤。
消息跟蹤選項
通過“Message Trace Options”對話框,用戶能控制消息跟蹤窗口中消息的顯示,還可以改變消息顯示方式。可從主菜單上選【Messages | Options】菜單項來調出Message Trace Options對話框,用戶能控制消息跟蹤窗口中消息的顯示,還可以改變消息顯示的方式。可從主菜單上選【Messages | Options】菜單項來調出Message Trace Options對話框。
對話框中標有Messages to Trace的區域是該對話框的主體,這個區域的左面有若干個消息組,右面是一個列表框,其中顯示所有Windows消息。當用戶選擇或取消選擇消息組時,列表中對應的消息將被選擇或取消選擇。
Note
列表中所有大寫的消息都是標准Windows消息;小寫消息時未記入文檔的Windows消息;未記入文檔的Windows消息由Windows內部使用,不出現在Windows API幫助文件中。
當選中All Messages復選框時,WinSight跟蹤所有Windows消息。為了減少消息跟蹤窗口的雜亂,用戶可選擇只查看某幾個消息組。例如,用戶只想查看鼠標消息,就可關閉All Messages復選框,而選中Mouse復選框。為了進一步明確要查明的消息,用戶可關閉所有選項,然后從列表中選擇一條具體消息。例如,如果用戶只想查看WM_LBUTTONDOWN消息,就可關閉所有選項,然后從列表框中選取WM_LBUTTONDOWN消息,消息跟蹤窗口就會只顯示WM_LBUTTONDOWN消息。
Message Trace Options對話框上另一組選項控制消息跟蹤窗口中消息的顯示方式。如下圖:
Interpret Values選項通知WinSight,將每條消息的參數分解成可讀性更強的格式。例如,給定一條WM_KEYDOWN消息,用戶在消息跟蹤窗口中看到的顯示如下:
如果勾選中Interpret Values選項,則會看到如下消息:
多數時候,大家還是比較喜歡更詳細的顯示,因此一般都選中Interpret Values選項。
Hex Values選項通知WinSight,以十六進制格式顯示消息跟蹤窗口中的值。當用戶有一定的編程經驗后,會發現這個選項在某些情況下很有用。Show Times選項的用處不大,它顯示系統時間。
Log file選項使用戶能將消息跟蹤結果存儲到磁盤上的文件中。當選中該選項時,消息仍然顯示到消息跟蹤窗口中。當用戶需要對產生的消息做一個備份時,這個選項就很有用了。
Note
創建日志文件有另外一個好處:創建好一個日志文件后,可將它用文本編輯器打開,然后用文本編輯器自帶的查找功能進行查看,查看具體的消息或消息參數。
其他WinSight特性(Other WinSight Features)
WinSight還有一些其他特性,利用這些特性,可使窗口的偵查更靈活方便。
1)、查看窗口細節
WinSight的Detail特性顯示某個特定窗口的全部有關細節。要詳細查看一個窗口,在窗口樹中選取該窗口,然后從主菜單選擇【Spy | Open Detail】菜單項,也可以雙擊窗口樹中的窗口或按Enter鍵。如下圖顯示的是Windows資源管理器的細節。
正如大家所看到的,Detail窗口顯示大量所查看窗口的信息。
2)、Follow Focus
本選項使用戶能選擇應用程序中的一個窗口,並使它成為窗口樹中的活動窗口。窗口樹通常都包含有幾十個窗口,要在其中找到要查看的窗口的確不是件容易的事,因此,Follow Focus確實能給用戶帶來方便。
要使用這一特性,從主菜單選【Spy | Follow Focus】菜單項,然后,切換到包含要偵查窗口的應用程序,並點擊窗口上用戶想要偵查的某個具體控件(如果需要的話);WinSight自動地在窗口樹中選取該窗口。從主菜單上選擇【Start!】菜單項,就可開始窗口偵查。
Tip
一旦打開【Follow Focus】選項,它就會一直開着,直至用戶將它關閉。當用戶在應用程序中找到要偵查的窗口后,如果不再查看程序中的其他窗口或控件,就應該立刻關閉Follow Focus選項。
3)、Find Window(查找窗口)
WinSight的Find Window特性與Follow Focus正好相反:在窗口樹中,找到當前要查看的窗口,然后從主菜單選擇【Spy | Find Window】菜單項,WinSight就會顯示一個環繞該窗口的粗邊框,並閃爍該邊框。
點擊該窗口,或從窗口樹中選擇另外一個窗口,粗邊框就會消失。粗邊框總是顯示在所有的窗口之上,因而用戶可以找到屏幕上的任意一個窗口,即使該窗口隱藏在其他窗口之下。用Find Window找到的窗口不升到最上面,也不得到輸入焦點,它只是被標識出來。
Note
Find Window不能查找隱式窗口或被極小化的窗口。
輸入焦點(focus)一離開窗口樹,Find Window模式就會關閉。如果在另外一個應用程序上點擊,或在WinSight中其他位置點擊,Find Window模式也會關閉。
4)、Switch To(切換到)
Switch To特性使用戶能切換到應用程序中某個特定窗口。要切換到某個窗口,只需在窗口樹中選取該窗口,然后從主菜單上選擇【Spy | Switch To】菜單項,該窗口就會出現在屏幕的最上面,並具有輸入焦點。如果窗口是極小化窗口,則它將恢復到以前的位置。Switch To對隱式窗口不起作用。
要理解WinSight中每一條消息和租用,不是一朝一夕的事情,大家要花一定的事件來實際使用WinSight,從而最終掌握它。