• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            最近工作中遇到Window Ghosting這個(gè)問(wèn)題, 感覺(jué)挺有意思,這里簡(jiǎn)單記錄下。



            在XP時(shí)代我們的程序沒(méi)有響應(yīng)后只能通過(guò)任務(wù)管理器強(qiáng)制殺掉,但是Vista之后情況變了, 我們?nèi)匀豢梢酝蟿?dòng)失去響應(yīng)的窗口,甚至可以嘗試最小化和關(guān)閉窗口, 我們把這個(gè)特性叫住Window Ghosting。

            首先我們考慮下怎樣判斷一個(gè)窗口是否已經(jīng)失去響應(yīng)?
             
            一般我們想到的是SendMessageTimeout,給窗口發(fā)送WM_NULL消息,判斷返回是否超時(shí)。這當(dāng)然也是一種方法,但是系統(tǒng)有更方便的API  IsHungAppWindow, 該API是判斷窗口是否失去響應(yīng)的標(biāo)準(zhǔn)方法。我們猜測(cè)IsHungAppWindow內(nèi)部是否通過(guò)SendMessageTimeout來(lái)實(shí)現(xiàn)的, 跟蹤下我們會(huì)發(fā)現(xiàn)不是我們想象的那樣, IsHungAppWindow內(nèi)部掉用了未公開(kāi)的API NtUserQueryWindow。

            接下來(lái)考慮下 IsHungAppWindow 是如何鑒定一個(gè)窗口是否在失去響應(yīng)狀態(tài)?

            這是MSDN中的原話: 
            Determines whether the system considers that a specified application is not responding. An application is considered to be not responding if it is not waiting for input, is not in startup processing, and has not calledPeekMessage within the internal timeout period of 5 seconds.
            簡(jiǎn)單來(lái)說(shuō)就是程序在非等待輸入狀態(tài) ,不是在程序啟動(dòng)階段, 并且5秒內(nèi)沒(méi)有從消息隊(duì)列中取消息。 

            下面我們思考系統(tǒng)是如何實(shí)現(xiàn)Window Ghosting的?

            我們知道失去響應(yīng)的窗口一般來(lái)說(shuō)是因?yàn)閁I線程正在做一些繁忙的工作, 或是UI線程死鎖而沒(méi)有在繼續(xù)運(yùn)行了。 那這里就很奇怪了, UI線程都失去響應(yīng)了, 窗口怎么還能響應(yīng)我們的鼠標(biāo)拖動(dòng)消息?我們的鼠標(biāo)拖動(dòng)事件需要運(yùn)行在UI線程中才行 ,該實(shí)現(xiàn)有些顛覆我們現(xiàn)有的計(jì)算機(jī)知識(shí)。

            這里的關(guān)鍵就是我們看到的失去響應(yīng)的窗口是不是還是我們?cè)瓉?lái)的窗口? 實(shí)際上我們真正的窗口已經(jīng)讓系統(tǒng)用Ghosting窗口替代了。
            完整過(guò)程是這樣的, 當(dāng)系統(tǒng)檢測(cè)到我們程序窗口失去響應(yīng)了, 系統(tǒng)進(jìn)程(dwm.exe)會(huì)以相同的Z-order, 位置,大小和Style創(chuàng)建一個(gè)ghosting窗口(可以通過(guò)SPY查看 ,類名是Ghost), 我 們看到的失去響應(yīng)的窗口就是這個(gè)窗口, 該窗口的客戶區(qū)內(nèi)容是從老窗口中拷貝過(guò)來(lái)的。而我們?cè)瓉?lái)真正窗口依舊在那里(style, 位置,大小和z-order都沒(méi)有變 ), 但是dwm.exe合成屏幕內(nèi)容是并不會(huì)把這個(gè)窗口畫出來(lái), 所以我們看起來(lái)就是原來(lái)的窗口給hide了。
             
            這就是Window Ghosting的奧秘, 我們可以在程序中調(diào)用 API DisableProcessWindowsGhosting 來(lái)禁止系統(tǒng)對(duì)我們的程序使用 Window Ghosting.

            Window Ghosting這個(gè)特性很不錯(cuò), 讓失去響應(yīng)的程序也有很好的用戶體驗(yàn), 但是它也帶來(lái)了一些問(wèn)題。

            我遇到的問(wèn)題是我們?cè)诿杜e窗口的過(guò)程中,我們通過(guò)GetWindowRect查詢一個(gè)失去響應(yīng)的程序窗口的位置,但是返回結(jié)果卻和我們屏幕上看到的不一致, 因?yàn)槲覀兛吹降氖潜晃覀兺蟿?dòng)過(guò)的Ghosting window,但是API返回的確是被hide的原窗口的位置。 這種情況下我們需要原窗口和Ghosting窗口的一張映射表, 但是我還沒(méi)有找到他們對(duì)應(yīng)關(guān)系的方法, 不知道系統(tǒng)又沒(méi)有相關(guān)API提供?一種方法是通過(guò)查找類名是"Ghost"的窗口,判斷進(jìn)程是不是dwm.exe, 再通過(guò)標(biāo)題匹配。但是該方法效率低,也不可靠。
            posted on 2014-01-08 21:26 Richard Wei 閱讀(3237) 評(píng)論(3)  編輯 收藏 引用 所屬分類: windows desktop

            FeedBack:
            # re: Window Ghosting
            2014-01-08 21:50 | relax
            挺有意思  回復(fù)  更多評(píng)論
              
            # re: Window Ghosting[未登錄](méi)
            2014-01-08 22:12 | 萬(wàn)連文
            記憶中是Send/PostMessage返回FALSE表示窗口假死,Chromium源碼中有的。Ghosting是很早就知道了,感覺(jué)有遮罩層的意思,方便接管消息做統(tǒng)一的假死處理。  回復(fù)  更多評(píng)論
              
            # re: Window Ghosting
            2014-01-09 10:24 | Richard Wei
            @萬(wàn)連文
            對(duì)假死窗口調(diào)用SendMessage應(yīng)該會(huì)一直等待,不會(huì)返回, 直到窗口有響應(yīng)  回復(fù)  更多評(píng)論
              
            久久综合九色综合欧美就去吻| 久久夜色精品国产亚洲av| 久久久精品午夜免费不卡| 久久棈精品久久久久久噜噜| 亚洲精品高清国产一线久久| 亚洲精品乱码久久久久久蜜桃| 亚洲欧美久久久久9999| 2020最新久久久视精品爱| 99国产欧美精品久久久蜜芽| 久久精品国产99国产精偷 | 浪潮AV色综合久久天堂| 久久成人小视频| 亚洲AV伊人久久青青草原| 99蜜桃臀久久久欧美精品网站| AV无码久久久久不卡蜜桃| 久久国产精品无| 国产精自产拍久久久久久蜜| 久久国产成人| 久久99国产精品久久99| 国产亚州精品女人久久久久久| 国产精品视频久久久| 97香蕉久久夜色精品国产| 亚洲中文字幕无码久久精品1 | 欧美一级久久久久久久大| 99久久成人18免费网站| 国产精品成人99久久久久| 久久人人爽人人爽人人av东京热| 精品多毛少妇人妻AV免费久久 | 色狠狠久久AV五月综合| 色欲久久久天天天综合网精品 | 天天爽天天狠久久久综合麻豆| av色综合久久天堂av色综合在| 2020久久精品亚洲热综合一本 | avtt天堂网久久精品| 91精品国产乱码久久久久久| 久久精品一区二区国产| 国产情侣久久久久aⅴ免费| 成人妇女免费播放久久久| 亚洲乱码中文字幕久久孕妇黑人| 无码人妻久久一区二区三区蜜桃| 精品久久久久久国产三级|