如何用C語言寫一個獲取視窗控制程式碼和其他資訊的小程式.
博主是一個SDK程式設計的初學者,始終堅持學技術要任務驅動的觀念,在學習了有關Windows程式,核心物件,程式管理和控制的知識之後,就迫不及待地想要設計一個記憶體修改器練練手,然而在獲取當前執行的各視窗的控制程式碼這一步就卡住了,經過一番查閱和鑽研,終於寫出瞭如下的CUI小程式,解決了獲取視窗及子視窗控制程式碼,獲取ClassName,獲取WindowText的問題。
不知道這個小程式能不能替代SPY++的部分功能……
//CUI:相對於GUI(Graphical User Interface)圖形使用者介面而言的Command User Interface命令列使用者介面。
PS:博主才疏學淺,程式中如有錯誤,歡迎各位指正!
該程式基於下列四個API實現
EnumWindows()
EnumWindows()
//BOOL EnumWindows(WNDENUMPROC,LPARAM)
//WNDENUMPROC 為回撥函式的地址
//LPARAM為你自已定義的引數,將會傳遞給回撥函式.
EnumChildWindows()
函式原型:
BOOL EnumChildWindows(HWND hWndParent,WNDENUMPROC lpEnumFunc, LPARAM lParam);
//HWND hWndParent 父視窗控制程式碼
//WNDENUMPROC lpEnumFunc 回撥函式的地址
//LPARAM lParam 自定義的引數
//注意:回撥函式的返回值將會影響到這個API函式的行為。如果回撥函式返回true,則列舉繼續直到列舉完成;如果返回false,則將會中止列舉。
GetClassName()
GetClassName(hwnd,classname,256);
//GetClassName();hwnd是需要傳入的控制程式碼/classname是需要傳入的LPTSTR緩衝區,用於接收類名/256是int,指定classname的大小,單位位元組.
//獲取成功將返回返回值為拷貝到指定緩衝區的字元個數,如果函式失敗,返回值為0.
GetWindowText()
//與GetClassName引數完全一致,不再贅述。
//關於它們的引數列表和解釋會在下面的程式碼註釋中體現,想要了解以上四個函式的使用方法的話也可以作為參考。
基本思路比較簡單,先呼叫EnumWindows,遍歷所有父窗體,在遍歷時再呼叫EnumChildWindows,在每一個父窗體下遍歷其子窗體,如果有的話即輸出。
以下為原始碼:
/*
程式名稱: 簡易Windows窗體檢視器
程式功能: 檢視當前狀態下所有窗體的classname,windowtext,hwnd(窗體控制程式碼).
程式類別: CUI WIN32應用程式
作者: 北赤道逆流
聯絡方式: zhangjunshuo_sdu@outlook.com
注意: 本程式編譯環境為 WindowsXP x86 Dev-C++ 5.4.2
Windows10 x64 Dev-C++ 5.9.2
經測試64位版本與32位版本狀態均良好,其餘環境未經測試.
*/
#define Primary false //關閉初級使用者模式 //使用者可以在此處選擇開啟(true)或是關閉初級使用者模式
//在初級使用者模式下,程式將不會顯示子窗體的資訊,同時也會隱藏沒有WindowText的窗體。
#include<stdio.h>
#include<windows.h>
#include<string.h>
//EnumWindows()和EnumChildWindows()需要回撥函式.
//先寫EnumChildWindows()的回撥函式enumchildwindows_callback(),因為在enumwindows_callback()裡面要用它.
BOOL CALLBACK enumchildwindows_callback(HWND hwnd, LPARAM lParam)
//關於函式引數等的具體解釋見下面的enumwindows_callback()!
//因為enumwindows_callback()函式寫的比較完整,所以在它裡面加了詳細註釋,就不在這裡加了.
//如果閱讀該函式有困難,建議先閱讀下面的enumwindows_callback();
{
TCHAR classname[256];
TCHAR windowtext[256];
int cn = GetClassName(hwnd,classname,256);
int wt = GetWindowText(hwnd,windowtext,256);
if(cn==0)
{
if(wt==0)
{
printf(" Error in EnumChildWindows_CALLBACK\n");
return FALSE;
}
else if(wt!=0)
{
printf(" NULL ||| %18s ||| %d\n",windowtext,hwnd); //%18s表示該字串最少佔用18個個字元空間,printf格式控制符。
return TRUE;
}
}
else if(cn!=0)
{
if(wt==0)
{
printf(" %-18s ||| NULL ||| %d\n",classname,hwnd); //-是格式控制字元,表示左對齊。
return TRUE;
}
else if(wt!=0)
{
printf(" %-18s ||| %s ||| %d\n",classname,windowtext,hwnd);
return TRUE;
}
}
}
BOOL CALLBACK enumwindows_callback(HWND hwnd, LPARAM lParam)
//hwnd就是系統傳遞給該回撥函式的窗體控制程式碼,lParam是控制引數,將會由呼叫函式(EnumWindows)傳入,以控制回撥函式的行為,預設值為0;
{
TCHAR classname[256];//此處務必事先指定變數的記憶體大小!如果使用LPTSTR指標形式,也務必立即使用malloc分配合適的記憶體,避免野指標.
TCHAR windowtext[256];
int cn = GetClassName(hwnd,classname,256);
//GetClassName();hwnd是需要傳入的控制程式碼/classname是需要傳入的LPTSTR緩衝區,用於接收類名/256是int,指定classname的大小,單位位元組.
//獲取成功將返回返回值為拷貝到指定緩衝區的字元個數,如果函式失敗,返回值為0.
int wt = GetWindowText(hwnd,windowtext,256);
//解釋同GetClassName();
if(cn==0)
{
if(wt==0)
{
printf("Error in EnumWindows_CALLBACK\n");
return FALSE; //理論上不會存在既沒有類名又沒有標題名的窗體
}
else if(wt!=0)
{
printf("NULL ||| %18s ||| %d\n",windowtext,hwnd);
return TRUE; //這種情況至今沒有見到過!
}
}
else if(cn!=0)
{
if(wt==0)
{
if(Primary==true)return TRUE;//隱藏輸出,以面向初級使用者,而且不顯示子窗體資訊.
else if(Primary==false)
{
printf("------------------------------------------------------------\n");//父窗體與父窗體之間的分割線.
printf("%-18s ||| NULL ||| %d\n",classname,hwnd);
int check=EnumChildWindows(hwnd,(WNDENUMPROC)enumchildwindows_callback,0);//在此處呼叫顯示子窗體的EnumChildWindows.
if(check == 0) printf(" ->NoneChildWindow\n");//如果沒有子窗體我們要這樣回顯.
return TRUE;
}
}
else if(wt!=0)
{
if(Primary==true)
{
printf("%-18s ||| %s ||| %d\n",classname,windowtext,hwnd);
return TRUE;
}
else if(Primary==false)
{
printf("------------------------------------------------------------\n");//父窗體與父窗體之間的分割線.
printf("%-18s ||| %s ||| %d\n",classname,windowtext,hwnd);
int check=EnumChildWindows(hwnd,(WNDENUMPROC)enumchildwindows_callback,0);
if(check == 0) printf(" ->NoneChildWindow\n");
return TRUE;
}
}
}
}
int main()
{
//先建立一個標題欄
printf("WINDOWS_EXPLORER\n");
if(Primary==true)printf("PRIMARY_MODE\n\n");
else if(Primary==false)printf("ADVANCED_MODE\n\n");
printf("CLASSNAME----WINDOWTEXT----(int)HWND\n\n");
int check = EnumWindows((WNDENUMPROC)enumwindows_callback,0);
//BOOL EnumWindows(WNDENUMPROC,LPARAM)
//WNDENUMPROC 為回撥函式的地址
//LPARAM為你自已定義的引數,將會傳遞給回撥函式.
if(check == 0)printf("Error in EnumWindows\n");
system("pause");
return 0;
}
最後附上該原始碼的Github地址
https://github.com/ZhangJunshuo/WindowsInformationExplorer.git
相關文章
- C語言建立空白Windows視窗程式碼C語言Windows
- 新手的第一個c語言小程式C語言
- 小程式獲取帶有分享者資訊的小程式碼
- 聊聊C語言/C++—程式和程式語言C語言C++
- 用 PHP 寫一個"程式語言"PHP
- Linux c程式中獲取shell指令碼輸出(如獲取system命令輸出)LinuxC程式指令碼
- 廣告彈窗/小視窗程式碼
- PHP獲取小程式openid,10行程式碼快速獲取小程式openidPHP行程
- c語言實用小程式C語言
- C語言爬蟲程式編寫的爬取APP通用模板C語言爬蟲APP
- 小程式播放當前視訊關閉其他視訊
- C語言簡單程式碼程式C語言
- 02-第一個C語言程式C語言
- 節操,程式碼,修養,妹子和其他(Go語言版)Go
- 獲取小程式二維碼
- 使用C語言編寫貪食蛇程式原始碼C語言原始碼
- Python:如何用一行程式碼獲取上個月是幾月Python行程
- 微信小程式 獲取使用者資訊微信小程式
- 哈嘍C!蘇小紅-C語言程式設計(第3版)程式碼C語言程式設計
- C 語言程式碼總結
- C語言:一種高效、易學的程式語言C語言
- 小程式音訊和視訊音訊
- 通訊錄的c語言程式編輯C語言
- 微信小程式獲取使用者資訊方法微信小程式
- 微信小程式 getUserProfile 獲取使用者資訊微信小程式
- 教你C語言實現通訊錄的詳細程式碼C語言
- Python和其他流行的程式語言有什麼區別?Python
- 支付寶小程式(後臺)---獲取授權和使用者資訊
- 使用Java語言寫的一個簡單的撲克牌發牌程式碼Java
- 微信小程式—— 獲取資料微信小程式
- 如何用GO語言編寫快取服務?Go快取
- C++程式語言的四個準則C++
- C語言判斷輸入小寫字母的個數C語言
- 兩步快速獲取小程式原始碼原始碼
- 有哪一種程式語言比其他的更安全嗎?
- uniapp微信小程式獲取手機號 位置資訊APP微信小程式
- 微信小程式三種獲取使用者資訊的方式微信小程式
- [轉]如何用React寫小程式-2React