<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          記一次有教益的焦點(diǎn)窗口查找過(guò)程—— 一定注意 spy++ 的這個(gè)坑

          共 2611字,需瀏覽 6分鐘

           ·

          2022-09-22 22:14

          緣起

          前一陣子,同事遇到了一個(gè)詭異的 bug,新版本發(fā)出來(lái)后之前運(yùn)行好好的功能不好使了。原來(lái)的邏輯是:點(diǎn)擊板上某個(gè)埋件的時(shí)候,會(huì)彈出四個(gè)定位編輯框,其中的一個(gè)編輯框需要獲得焦點(diǎn),方便用戶直接修改,按 tab 會(huì)切換到下一個(gè)編輯框。但是新程序的行為發(fā)生了變化——點(diǎn)擊埋件的時(shí)候,四個(gè)編輯框沒(méi)有一個(gè)獲得焦點(diǎn)。本文記錄了使用 spyxxaccevent.exe 定位此問(wèn)題的過(guò)程。

          初步調(diào)查

          同事演示了一下現(xiàn)象,大概現(xiàn)象如下:

          e30a5d7fa336de3a82b839f2293c0a83.webp搶焦點(diǎn)

          可以發(fā)現(xiàn),左側(cè)的編輯框先是獲得了焦點(diǎn)(獲得焦點(diǎn)的時(shí)候會(huì)選中全部文字),然后很快被搶走了。

          因?yàn)橹霸陂_發(fā)其它功能時(shí)也遇到過(guò)焦點(diǎn)被命令編輯框(軟件底部中央的編輯框)搶走的情況,所以經(jīng)過(guò)一定的觀察后,斷定跟上次是一樣的問(wèn)題。由于之前遇到的那個(gè)問(wèn)題是通過(guò)其它方式解決的,這次的問(wèn)題不能用相同的方式解決,于是建議同事跟客戶反饋一下,讓平臺(tái)同事幫忙處理一下?lián)尳裹c(diǎn)的問(wèn)題。

          再次調(diào)查

          過(guò)了一天,客戶那邊反饋可以使用某個(gè)命令禁止命令編輯框搶焦點(diǎn)。執(zhí)行這個(gè)命令后,發(fā)現(xiàn)命令編輯框確實(shí)不搶焦點(diǎn)了,但是焦點(diǎn)還是會(huì)被搶走。

          跟同事了解完相關(guān)代碼邏輯后,找到了被搶走焦點(diǎn)的編輯框類。該類中包含一個(gè)響應(yīng)函數(shù) OnKillFocus(CWnd* pNewWnd)。從名字可以看出,該函數(shù)是處理失去焦點(diǎn)事件的,該函數(shù)只有一個(gè)參數(shù),從名字看該參數(shù)是新獲得焦點(diǎn)的窗口對(duì)象指針。于是,果斷在這里設(shè)置斷點(diǎn),并且設(shè)置中斷時(shí)輸出調(diào)試信息后繼續(xù)執(zhí)行代碼。經(jīng)過(guò)幾次觀察,可以發(fā)現(xiàn),焦點(diǎn)總是被某個(gè)固定的窗口搶走。

          e483c30b56c6b9c938520914ce2224f1.webpOnKillFocus

          既然焦點(diǎn)總被固定的窗口搶走,說(shuō)明這個(gè)窗口是固定存在的,不是臨時(shí)窗口。既然是固定存在的窗口,就可以通過(guò) spyxx ?查看到底是哪個(gè)窗口。但是當(dāng)我在 spyxx 中輸入這個(gè)窗口句柄時(shí),卻怎么也找不到這個(gè)句柄對(duì)應(yīng)的窗口!真是怪事!

          da9117eabb46b4a7260e31efbebaf08f.webpcan-not-find-this-window

          保存調(diào)用棧

          雖然沒(méi)能通過(guò) spyxx 找到對(duì)應(yīng)的窗口,但是卻發(fā)現(xiàn)了一條非常有用的信息 —— 每次焦點(diǎn)都會(huì)被同一個(gè)窗口搶走。那么可以在 OnKillFocus() 函數(shù)內(nèi)部設(shè)置條件斷點(diǎn),當(dāng) pNewWnd 是特定值時(shí)才中斷。這樣就可以在目標(biāo)編輯框失去焦點(diǎn)時(shí)中斷下來(lái)。中斷下來(lái)后,簡(jiǎn)單查看調(diào)用棧,由于缺少調(diào)試符號(hào),沒(méi)有發(fā)現(xiàn)什么有用信息。保存一份完整轉(zhuǎn)儲(chǔ)文件,后面可以發(fā)給平臺(tái)同事,讓他們幫忙查看具體原因。

          提示: 轉(zhuǎn)儲(chǔ)文件是程序某個(gè)時(shí)刻的快照。調(diào)試時(shí)保存轉(zhuǎn)儲(chǔ)文件個(gè)非常好的習(xí)慣,尤其是那種不輕易重現(xiàn)的問(wèn)題。好不容易抓到一次,一定要先拍個(gè)照。防止調(diào)試器意外退出,追悔莫及。都懂,對(duì)吧。

          其實(shí),這個(gè)問(wèn)題調(diào)查到這一步已經(jīng)夠了。因?yàn)檫@個(gè)問(wèn)題已經(jīng)很明確了(焦點(diǎn)被其它窗口搶走了),而且外網(wǎng)沒(méi)有相關(guān)代碼,只能等平臺(tái)同事處理。但是,我特別好奇到底是哪個(gè)窗口把焦點(diǎn)搶走了,為什么在調(diào)試輸出中看到焦點(diǎn)每次都被同一個(gè)窗口搶走,但是在 spyxx 中卻查不到這個(gè)窗口。

          繼續(xù)折騰

          之前做讀屏軟件開發(fā)的時(shí)候了解到,除了 spyxx,還有其它工具可以查看窗口信息。比如,可以通過(guò) Inspect, UISpy, accevent 等工具以追蹤焦點(diǎn)的方式自動(dòng)獲取當(dāng)前獲得焦點(diǎn)的窗口。但是,這次在使用這幾個(gè)工具的過(guò)程中,發(fā)現(xiàn)很大概率會(huì)導(dǎo)致主程序發(fā)生 StackOverflow 異常(在這里浪費(fèi)了很長(zhǎng)時(shí)間)。最后發(fā)現(xiàn),使用 accevent32,并且只監(jiān)聽 OBJ_FOCUS 事件的時(shí)候,不會(huì)發(fā)生異常。

          59ff8a07e1ca7f7dab8cc69f399e645b.webpaccevent32-setting

          按上圖設(shè)置好之后,點(diǎn)擊 OK 按鈕,即可監(jiān)聽焦點(diǎn)變化事件。終于抓到了這個(gè)偷搶焦點(diǎn)的窗口。

          9c83acb010b3b0fb752133352d144904.webpaccevent-watch-focused-window

          好像搶焦點(diǎn)的是主窗口?趕緊用 spyxx 查看主窗口句柄,果然主窗口的句柄是 00541376,與使用 accevent 捕獲到的窗口句柄是一樣的。0474dea256507ffda07c8677fbb486b8.webp

          這次,終于知道是哪個(gè)窗口搶走了焦點(diǎn),但是為什么主窗口會(huì)搶焦點(diǎn),還是需要平臺(tái)同事幫忙調(diào)查原因了。

          為什么 spyxx 找不到窗口

          為什么之前在 spyxx 里輸入窗口句柄,但是卻找不到對(duì)應(yīng)的窗口呢?在 vs 輸出窗口中顯示的窗口句柄是 0x0000000000541376,在 spyxx 中輸入的也是 0x0000000000541376,沒(méi)道理找不到。但是在 accevent 里看到的窗口句柄是 00541376,難道在spyxx 中輸入 00541376 就可以查找到了?趕緊試試。

          6f4d300f4e3e65d24433b9b520d5e56c.webpfind-window-by-spyxx

          果然,輸入 00541376 是可以找到對(duì)應(yīng)的窗口的。但是當(dāng)我嘗試使用 0x00541376 查找窗口時(shí),卻無(wú)法找到匹配的窗口。看來(lái),在 spyxx 中通過(guò)輸入句柄查找窗口時(shí)不能輸入 0x 前綴。

          反思

          在整個(gè)過(guò)程中有一點(diǎn)做的特別不好:本來(lái)可以修改 OnKillFocus() 函數(shù)中的代碼,多打印一些信息,比如獲取窗口范圍,窗口類名等信息。這樣就可以直接在代碼里定位到是哪個(gè)窗口搶走了焦點(diǎn)。但是根據(jù)之前的經(jīng)驗(yàn),編譯一次比較耗時(shí),所以潛意識(shí)里不想修改代碼,只是想著通過(guò)為斷點(diǎn)設(shè)置輸出信息的方式打印了一些輔助信息。

          總結(jié)

          • Inspect, UISpy, accevent ?等工具也是一種可以查看窗口信息的工具,在某些情況下可能非常有用。

          • spyxx 中通過(guò)輸入窗口句柄查找窗口時(shí)不能輸入 0x 前綴,否則會(huì)出現(xiàn)找不到窗口的情況。


          瀏覽 95
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操逼视频手机播放 | 亚洲娱乐成人网 | 青草青青精品视频在线观看 | 色综合天| 亚洲色情在线观看 |