WinSpy涉及的windows api
WinSpy是仿造微軟Spy++的開源項目,但只涉及Spy++的窗口句柄、窗口的屬性、styles、類名子窗口、進程線程信息等查找功能。功能雖然不算強大,但涉及到很多windows api,是了解windows api的一個有用工具。WinSpy界面截圖如下:
1:拖拽瞄准鏡圖標獲取窗口的HWND
核心api:ClientToScreen、WindowFromPoint、EnumChildWindows、GetParent、GetWindowLong、SetWindowLong
1.1 WindowFromPoint

HWND WindowFromPoint(POINT Point);
根據桌面坐標獲取到window的HWND。返回NULL表示沒有窗口在該point下。
1.2 ClientToScreen

BOOL ClientToScreen( HWND hWnd, // handle to window LPPOINT lpPoint // screen coordinates);
將客戶端相對坐標轉換為桌面坐標,是WindowFromPoint的前提。函數調用成功,返回非0值。否則,返回0.
1.3 GetParent

HWND GetParent( HWND hWnd );
返回當前HWND的父窗口HWND。如果該窗口無父窗口或者函數調用失敗,返回NULL。
1.4 GetWindowLong

LONG GetWindowLong( HWND hWnd, int nIndex);
該函數獲得有關指定窗口的信息,函數也獲得在額外窗口內存中指定偏移位地址的32位度整型值(該整形值也可用於傳入的函數指針或窗口過程地址)。調用成功返回32位整形值,失敗返回0.可用GetLastError獲取失敗信息。可獲取的窗口信息的類型如下:
GWL_EXSTYLE;獲得擴展窗口風格。
GWL_STYLE:獲得窗口風格。
GWL_WNDPROC:獲得窗口過程的地址,或代表窗口過程的地址的句柄。必須使用CallWindowProc函數調用窗口過程,CallWindowProc函數用於給指定窗口的窗口過程發消息。原型如下:

1 LRESULT CallWindowProc( 2 WNDPROC lpPrevWndFunc, 3 HWND hWnd, 4 UINT Msg, 5 WPARAM wParam, 6 LPARAM lParam );
GWL_HINSTANCE:獲得應用事例的句柄。
GWL_HWNDPAAENT:如果父窗口存在,獲得父窗口句柄。
GWL_ID:獲得窗口標識。
GWL_USERDATA:獲得與窗口有關的32位值。每一個窗口均有一個由創建該窗口的應用程序使用的32位值。
在hWnd參數標識了一個對話框時也可用下列值:
DWL_DLGPROC:獲得對話框過程的地址,或一個代表對話框過程的地址的句柄。必須使用函數CallWindowProc來調用對話框過程。
DWL_MSGRESULT:獲得在對話框過程中一個消息處理的返回值。
DWL_USER:獲得應用程序私有的額外信息,例如一個句柄或指針。
1.5 SetWindowLong

1 LONG SetWindowLong( 2 HWND hWnd, 3 int nIndex, 4 LONG dwNewLong);
與GetWindowLong對應,用於修改窗口的屬性。屬性類型與GetWindowLong一樣。返回值0表示調用失敗,用GetLastError查詢錯誤信息。
1.6 EnumChildWindows

1 BOOL EnumChildWindows( 2 HWND hWndParent, 3 WNDENUMPROC lpEnumFunc, 4 LPARAM lParam 5 );
用於枚舉父窗口下所有的子窗口,通過回掉函數WNDENUMPROC lpEnumFunc處理子窗口。函數將堵塞直至所用子窗口被枚舉,或者回掉函數返回FALSE。回掉函數的格式為:

1 BOOL CALLBACK EnumChildProc( 2 HWND hwnd, 3 LPARAM lParam 4 );
2:General頁相關api
general頁包含了窗口的一些基本信息,核心api有GetClassName、IsWindowUnicode、GetWindowRect、GetClientRect、OffsetRect、MapWindowPoints、GetClassLong。
2.1 GetClassName

1 int GetClassName( 2 HWND hWnd, 3 LPTSTR lpClassName, 4 int nMaxCount);
獲得指定窗口所屬的類的類名。第二個參數傳入待接收類名的緩沖區,第三個參數為緩沖區長度。返回值為返回字符串的長度,返回值為0表示調用失敗。
2.2 IsWindowUnicode

BOOL IsWindowUnicode( HWND hWnd);
判斷window的字符集是否是unicode。一個窗口的字符集是由函數RegisterClass決定的。如果窗口類是以ANSI版的RegisterClass ( RegjsterClassA)注冊的,則窗口字符集是ANSI的;如果窗口類是以Unicode版的Registerclass( RegisterClassW)注冊的,則窗口字符集是Unicode。
2.3 GetWindowRect

BOOL GetWindowRect( HWND hWnd, LPRECT lpRect );
返回指定窗口的邊框矩形的窗口的左上角和右下角的屏幕坐標。屏幕坐標坐標系。
2.4 GetClientRect

BOOL GetClientRect( HWND hWnd, LPRECT lpRect );
返回指定窗口的邊框矩形的窗口的左上角和右下角的客戶區坐標。客戶區坐標系。
2.5 OffsetRect

1 BOOL OffsetRect( 2 LPRECT lprc, // rectangle 3 int dx, // horizontal offset 4 int dy // vertical offset);
指定的矩形移動到指定的位置,返回值非0成功,0失敗。
2.6 MapWindowPoints

1 int MapWindowPoints( 2 HWND hWndFrom, // handle to source window 3 HWND hWndTo, // handle to destination window 4 LPPOINT lpPoints, // array of points to map 5 UINT cPoints // number of points in array);
把相對於一個窗口的坐標空間的一組點映射成相對於另一窗口的坐標空間的一組點。如果函數調用成功,返回值的低位字是每一個源點的水平坐標的像素數目,以便計算每個目標點的水平坐標;高位字是每一個源點的垂直坐標的像素的數目,以便計算每個目標點的垂直坐標,如果函數調用失敗,返回值為零。
hWndFrom或To參數為NULL或HWND_DESKTOP,則假定這些點在屏幕坐標上。可代替ScreenToClient或ClientToScreen使用。
2.7 GetClassLong

DWORD GetClassLong( HWND hWnd, int nIndex );
返回與指定窗口相關的WNDCLASSEX結構的指定32位值。
3:Styles頁相關api
4:Properities頁相關api
核心api:EnumPropsEx
4.1 EnumPropsEx

int EnumPropsEx( HWND hWnd, PROPENUMPROCEX lpEnumFunc, LPARAM lParam);
將窗口屬性表中的所有項列舉出來,依次傳送給指定的回調函數,直到列舉到最后一項,或者回調函數返回FALSE為止。該函數提供了COM組件OLE相關的屬性。
5:Class頁相關api
核心api:GetClassLong、GetClassInfoEx
5.1 GetClassInfoEx

BOOL GetClassInfoEx(
HINSTANCE hinst,
LPCTSTR lpszClass,
LPWNDCLASSEX lpwcx
);
查找窗口類的相關信息。第二個參數傳入窗口類的名稱,該類必須由RegisterClass或RegisterClassEx注冊過。第三個參數用於接收類信息。
6:Windows頁相關api
核心api:EnumChildWindows、GetParent
7:Process頁相關api
核心api:OpenProcess、GetWindowThreadProcessId、GetModuleBaseName 、GetModuleFileNameEx、EnumProcessModules
7.1 OpenProcess

HANDLE OpenProcess( DWORD fdwAccess, BOOL fInherit, DWORD IDProcess);
OpenProcess 函數用來打開一個已存在的進程對象,並返回進程的句柄。參數如下取值:
dwDesiredAccess:想擁有的該進程訪問權限
PROCESS_ALL_ACCESS //所有能獲得的權限
PROCESS_CREATE_PROCESS //需要創建一個進程
PROCESS_CREATE_THREAD //需要創建一個線程
PROCESS_DUP_HANDLE //重復使用DuplicateHandle句柄
PROCESS_QUERY_INFORMATION //獲得進程信息的權限,如它的退出代碼、優先級
PROCESS_QUERY_LIMITED_INFORMATION /*獲得某些信息的權限,如果獲得了PROCESS_QUERY_INFORMATION,也擁有PROCESS_QUERY_LIMITED_INFORMATION權限*/
PROCESS_SET_INFORMATION //設置某些信息的權限,如進程優先級
PROCESS_SET_QUOTA //設置內存限制的權限,使用SetProcessWorkingSetSize
PROCESS_SUSPEND_RESUME //暫停或恢復進程的權限
PROCESS_TERMINATE //終止一個進程的權限,使用TerminateProcess
PROCESS_VM_OPERATION //操作進程內存空間的權限(可用VirtualProtectEx和WriteProcessMemory)
PROCESS_VM_READ //讀取進程內存空間的權限,可使用ReadProcessMemory
PROCESS_VM_WRITE //讀取進程內存空間的權限,可使用WriteProcessMemory
SYNCHRONIZE //等待進程終止
bInheritHandle:表示所得到的進程句柄是否可以被繼承
dwProcessId:被打開進程的PID
返回值為指定進程的句柄。如失敗,返回值為NULL,可調用GetLastError()獲得錯誤代碼。
7.2 GetWindowThreadProcessId

DWORD GetWindowThreadProcessId( HWND hWnd, LPDWORD lpdwProcessId );
找出某個窗口的創建者(線程或進程),返回創建者的進程ID和線程ID。返回值是線程ID,第二個參數返回進程ID。
7.3 GetModuleBaseName

DWORD WINAPI GetModuleBaseName(
__in HANDLE hProcess,
__in HMODULE hModule,
__out LPTSTR lpBaseName,
__in DWORD nSize
);
第三個參數返回模塊的名稱。第二個參數如果是NULL,函數返回文件名。返回值表示寫入緩沖區字符串的長度,0表示調用失敗。
7.4 GetModuleFileNameEx

DWORD WINAPI GetModuleFileNameEx(
__in HANDLE hProcess,
__in HMODULE hModule,
__out LPTSTR lpFilename,
__in DWORD nSize
);
獲取模塊的全路徑。返回值表示寫入緩沖區字符串的長度,0表示調用失敗。
7.5 EnumProcessModules

BOOL WINAPI EnumProcessModules( __in HANDLE hProcess, __out HMODULE* lphModule, __in DWORD cb, __out LPDWORD lpcbNeeded );
枚舉進程下所有的模塊,用第二個參數接收。返回0表示調用失敗。