【誤區(qū)分析】TB-創(chuàng)新互聯(lián)

一、基本原理

專注于為中小企業(yè)提供做網(wǎng)站、成都做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)左權(quán)免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了近千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

使用SendMessage函數(shù)發(fā)送TB_BUTTONCOUNT消息到指定窗口,可以檢索工具欄中當(dāng)前按鈕的計(jì)數(shù)。但這個(gè)值可能并不是最新的,個(gè)數(shù)僅僅是當(dāng)前個(gè)數(shù),而且并非是顯示的個(gè)數(shù),也非有效按鈕窗口的個(gè)數(shù)。

使用SendMessage函數(shù)發(fā)送TB_GETBUTTON消息到指定窗口獲取指針,然后向指定進(jìn)程申請(qǐng)?jiān)L問(wèn)內(nèi)存,獲取TBBUTTON結(jié)構(gòu)體中dwData字段數(shù)據(jù),可以獲得遠(yuǎn)線程的工具欄窗口中當(dāng)前所有按鈕的句柄、標(biāo)題、進(jìn)程路徑信息。但該信息可能包含舊的內(nèi)容。

任務(wù)欄的通知區(qū)域分為四個(gè)部分:用戶提示的通知區(qū)域、系統(tǒng)升級(jí)的通知區(qū)域,溢出角通知區(qū)域、DUI彈出式通知區(qū)域(部分圖標(biāo)如:電源電量、音量等的注冊(cè)記錄在溢出通知區(qū)域窗口,但是并不是在溢出窗口內(nèi)顯示的,所以單獨(dú)歸類)。通知區(qū)域是外殼處理器Shell控件:ToolBarWindow32.

首先我們需要明白任務(wù)欄的ToolBarWindow(工具欄視圖)的一些特征:

1)除系統(tǒng)升級(jí)的通知區(qū)域以外的通知區(qū)域圖標(biāo)不會(huì)自動(dòng)刷新,需要接收到鼠標(biāo)移動(dòng)消息、模擬點(diǎn)擊消息才會(huì)逐個(gè)刷新。

2)如果一個(gè)窗口多次在通知區(qū)域注冊(cè)通知圖標(biāo),即使它是由同一個(gè)窗口發(fā)出的,也會(huì)被記錄為獨(dú)立的窗口,但他們具有相同的信息,在外殼程序內(nèi)存中相應(yīng)位置按序排列。

二、案例如何發(fā)生?

當(dāng)開(kāi)發(fā)者嘗試使用如下代碼獲取任務(wù)欄圖標(biāo)個(gè)數(shù)時(shí)可能得不到準(zhǔn)確的個(gè)數(shù):

LRESULT ButtonCount = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0);// 獲取hWnd窗口的圖標(biāo)個(gè)數(shù)

警告:以下談到的案例并不局限于任務(wù)管理器,其他第三方軟件都如此,這和資源管理器外殼Shell的處理邏輯有關(guān)系。

誤區(qū)1:忽略系統(tǒng)升級(jí)的通知區(qū)域,盡管這個(gè)區(qū)域經(jīng)常沒(méi)有顯示,但它位于溢出角按鈕和用戶通知區(qū)之間,當(dāng)有程序首次創(chuàng)建通知區(qū)圖標(biāo)的時(shí)候,提供短暫突出顯示的時(shí)間,這些圖標(biāo)臨時(shí)顯示在該區(qū)域,不在用戶區(qū)和溢出區(qū),當(dāng)超時(shí)完成時(shí)(最長(zhǎng)60秒)這些圖標(biāo)被放入溢出區(qū)(前提是沒(méi)有被標(biāo)記為始終顯示)。在超時(shí)完成前通知統(tǒng)計(jì)的用戶區(qū)和溢出區(qū)圖標(biāo)數(shù)據(jù)中跳過(guò)了這些圖標(biāo)。

誤區(qū)2:忽略重復(fù)注冊(cè)的圖標(biāo)窗口,盡管這在我們看來(lái)是相當(dāng)荒誕的,但它確實(shí)發(fā)生過(guò),也應(yīng)該引起相關(guān)開(kāi)發(fā)者的注意。

這張圖片展示了當(dāng)任務(wù)管理器打開(kāi)時(shí)(等待超時(shí)完成后記錄的結(jié)果),在使用TB_BUTTONCOUNT獲取個(gè)數(shù)時(shí)將多次記錄到任務(wù)管理器窗口,顯示為他創(chuàng)建了13個(gè)圖標(biāo)按鈕,隨后通過(guò)在外殼進(jìn)程內(nèi)存中讀取TBBUTTON結(jié)構(gòu)中的dwData數(shù)據(jù),得到窗口的標(biāo)題、句柄、以及目錄路徑(類名、矩形等其他信息是根據(jù)窗口句柄通過(guò)相關(guān)API遍歷枚舉的,不是直接獲得的結(jié)果),不難發(fā)現(xiàn)同樣的句柄有多條記錄,然而我們不需要多余的信息。這是TB類消息得到錯(cuò)誤結(jié)果的重要原因。

誤區(qū)3:(對(duì)于誤區(qū)2而言)任務(wù)管理器等剛剛注冊(cè)通知圖標(biāo)的窗口,圖標(biāo)會(huì)顯示在系統(tǒng)升級(jí)通知區(qū),此時(shí)記錄的個(gè)數(shù)是真確的(唯一的)。因?yàn)樗灰邮障⒘?,就?huì)被移除到溢出區(qū)。否則他只允許靜默一段時(shí)間。

誤區(qū)4:線程異常退出,而沒(méi)有注銷相應(yīng)圖標(biāo)。這時(shí)候我們把它稱作僵尸圖標(biāo),空有軀殼而沒(méi)有靈魂。但是這段內(nèi)存區(qū)域中相關(guān)信息不會(huì)被立即清除。導(dǎo)致獲得的計(jì)數(shù)以及句柄都是無(wú)效的。

通過(guò)檢查窗口的矩形,API調(diào)用返回“Error:1400”無(wú)效的窗口句柄即可排除該錯(cuò)誤帶來(lái)的影響。

Notice:請(qǐng)觀察下圖數(shù)據(jù)

再看下圖數(shù)據(jù):

以上結(jié)果發(fā)生在一個(gè)已經(jīng)注冊(cè)通知圖標(biāo)的程序意外終止時(shí)(沒(méi)有來(lái)得及注銷圖標(biāo)),外殼程序內(nèi)存中不會(huì)及時(shí)刪除這些內(nèi)容,這些內(nèi)容可能位于錯(cuò)誤的內(nèi)存位置,訪問(wèn)這些位置會(huì)帶來(lái)意外的結(jié)果。即使用戶已經(jīng)刷新了視圖區(qū)域,這些內(nèi)容依然不會(huì)被清除,直到重啟資源管理器。

并且對(duì)無(wú)效的句柄使用GetClassName()返回值為0,但是不會(huì)向遍歷時(shí)候的字符串指針更新數(shù)據(jù),所以需要注意變量的作用域或者記得及時(shí)檢查錯(cuò)誤原因,比如此時(shí)的LastError為1400,以及最后要記得將內(nèi)容重新初始化為{0}。一面這些垃圾數(shù)據(jù)影響用戶體驗(yàn)。(顯然圖中沒(méi)有考慮到這些問(wèn)題)

-----------------------------------------------

希望通過(guò)我的分析,能夠給遇到相關(guān)問(wèn)題的友人一點(diǎn)微薄的解答。文章如果有誤,歡迎各位斧正,謝謝!

轉(zhuǎn)載請(qǐng)注明博客來(lái)源:@漣幽516(http://t.csdn.cn/CpBeJ)

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

文章名稱:【誤區(qū)分析】TB-創(chuàng)新互聯(lián)
標(biāo)題鏈接:http://bm7419.com/article6/dihhig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開(kāi)發(fā)、服務(wù)器托管、微信小程序電子商務(wù)、面包屑導(dǎo)航全網(wǎng)營(yíng)銷推廣

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開(kāi)發(fā)公司