理解什么是句柄?
對于“句柄”,之前一直停留在一知半解的認識層面,也說不清具體概念,只知道它是一個標(biāo)識符,用來標(biāo)記對象或者說某個東西的。只知其名不知其意。目前學(xué)習(xí)windows編程,對“句柄”做一個完整的認。
現(xiàn)在先看一張圖(這張圖是從其他博主博文扒下來的):
圖1是程序運行到某時刻時的內(nèi)存快照,圖2是程序往后運行到另一時刻時的內(nèi)存快照。紅色部分標(biāo)出了兩次的變化。
【解釋一下:】
windows是一個以虛擬內(nèi)存為基礎(chǔ)的操作系統(tǒng),很多時候,進程的代碼和數(shù)據(jù)并不是全部裝入內(nèi)存,進程某一段裝入內(nèi)存之后,可能會被換出到外存。當(dāng)再次需要時會重新裝入內(nèi)存。兩次裝入內(nèi)存,那么很多時候裝入的地址是不一樣的。也就是說同一個對象在內(nèi)存中的地址會變化。那么程序怎么才能準(zhǔn)確的訪問到對象呢?這時候就引入了句柄。
系統(tǒng)為每個進程在內(nèi)存中分配一定的區(qū)域,用來存放各個句柄,即一個個32位無符號整型值(32位操作系統(tǒng)中)。每個32位無符號整型值相當(dāng)于一個指針,指向內(nèi)存中的另一個區(qū)域(我們不妨稱之為區(qū)域A)。而區(qū)域A中存放的正是對象在內(nèi)存中的地址。當(dāng)對象在內(nèi)存中的位置發(fā)生變化時,區(qū)域A的值被更新,變?yōu)楫?dāng)前時刻對象在內(nèi)存中的地址,而在這個過程中,區(qū)域A的位置以及對應(yīng)句柄的值是不發(fā)生變化的。這種機制,用一種形象的說法可以表述為:有一個固定的地址(句柄),指向一個固定的位置(區(qū)域A),而區(qū)域A中的值可以動態(tài)地變化,它時刻記錄著當(dāng)前時刻對象在內(nèi)存中的地址。這樣,無論對象的位置在內(nèi)存中如何變化,只要我們掌握了句柄的值,就可以找到區(qū)域A,進而找到該對象。而句柄的值在程序本次運行期間是絕對不變的,我們(即系統(tǒng))當(dāng)然可以掌握它。這就是以不變應(yīng)萬變,按圖索驥,順藤摸瓜。
所以,我們可以這樣理解句柄:
- 數(shù)值上:是一個32位的unsigned int;
- 邏輯上:相當(dāng)于一個二級指針。指向?qū)ο笤趦?nèi)存中的地址。(理解上:這個指針的值不可變的,普通指針的值可以變得。)
- 作用上:是windwos使用句柄來標(biāo)識諸多資源或者對象。比如窗口,畫筆,進程,線程等等。
【回到開頭,windows下我們?nèi)绾文玫揭粋€窗口句柄】:
使用FindWindow函數(shù)
可以根據(jù)窗口的類名和窗口名拿到句柄文章來源:http://www.zghlxwxcb.cn/news/detail-737523.html
HWND FindWindow(LPCTSTR IpClassName,LPCTSTR IpWindowName);
//IpClassName :指向一個指定了類名的空結(jié)束字符串
//pWindowName:指向一個指定了窗口名(窗口標(biāo)題)的空結(jié)束字符串。如果該參數(shù)為空,則為所有窗口全匹配。
//返回值:如果函數(shù)成功,返回值為具有指定類名和窗口名的窗口句柄;如果函數(shù)失敗,返回值為NULL。
[那么我們?nèi)绾潍@取到窗口的 類名 和 窗口名呢?]
我們可以使用vs自帶的工具spy++.exe;
通過搜索–>查找窗口,拖到要查詢的窗口就行。
現(xiàn)在,我們寫一個簡單的例子:用記事本打開一個文件。我這里打開的是cfg.ini文件。然后找到記事本窗口,然后通過查找到的記事本窗口句柄將記事本窗口進行移動位置并且改變大小。文章來源地址http://www.zghlxwxcb.cn/news/detail-737523.html
//根據(jù)類名和窗口名查找窗口句柄
HWND GetWindowHandle(std::string className, std::string windowName)
{
HWND hwnd = FindWindowA(className.c_str(), windowName.c_str());
return hwnd;
}
int main()
{
HWND notePadWHND = GetWindowHandle("Notepad", "cfg.ini - 記事本");
if (notePadWHND) {
RECT rect;
GetWindowRect(notePadWHND, &rect); //獲取記事本窗口的位置
MoveWindow(notePadWHND, rect.left + 500, rect.top + 300, 300, 300, TRUE);//移動記事本窗口
}
return 0;
}
到了這里,關(guān)于windows使用FindWindow函數(shù)查找窗口句柄的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!