新聞中心
之前我在一篇文章中曾經(jīng)提過(guò),不應(yīng)該利用 WM_KILLFOCUS 消息中對(duì)表單的字段進(jìn)行有效性校驗(yàn)。 今天的文章,我將介紹另外一個(gè)反面例子,來(lái)表現(xiàn)當(dāng)使用 WM_KILLFOCUS 消息處理焦點(diǎn)相關(guān)的問(wèn)題時(shí)所帶來(lái)的混亂。

創(chuàng)新互聯(lián)是專(zhuān)業(yè)的新北網(wǎng)站建設(shè)公司,新北接單;提供做網(wǎng)站、網(wǎng)站設(shè)計(jì),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專(zhuān)業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行新北網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專(zhuān)業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專(zhuān)業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
假設(shè),有一個(gè)編輯框控件使用了氣球提示來(lái)顯示反饋信息。舉個(gè)例子,對(duì)于一個(gè)密碼輸入控件,當(dāng)鍵盤(pán)上的 CapsLock 按鍵按下時(shí),它會(huì)提示用戶(hù),以防止用戶(hù)輸入錯(cuò)誤的密碼。作為開(kāi)發(fā)者,你可能希望,當(dāng)用戶(hù)將輸入焦點(diǎn)從密碼輸入框移動(dòng)到另外一個(gè)控件時(shí),將氣球提示移除,這是合情合理的。因?yàn)橄蛴脩?hù)給出一個(gè)他完全不會(huì)使用到的控件提示,會(huì)讓用戶(hù)感到莫名其妙??梢酝ㄟ^(guò)對(duì)輸入控件子類(lèi)化來(lái)實(shí)現(xiàn)上述的需求,如下圖所示:
使用上面的代碼進(jìn)行初步測(cè)試,一切如預(yù)期般正常工作,只是有一個(gè)問(wèn)題:當(dāng)用戶(hù)點(diǎn)擊氣球提示時(shí),編輯框的輸入光標(biāo)會(huì)意外的消失,這是為啥?
發(fā)生的事情是,你通過(guò)破壞焦點(diǎn)要去的窗口來(lái)破壞焦點(diǎn)變化過(guò)程!焦點(diǎn)更改過(guò)程如下所示:
- 將焦點(diǎn)移動(dòng)至新的窗口。
- 發(fā)送 WM_KILLFOCUS 消息給丟失焦點(diǎn)的窗口(如果有的話(huà)) 發(fā)送 WM_SETFOCUS 消息給新的焦點(diǎn)窗口(如果有的話(huà))
但是在上面的第二步,我們銷(xiāo)毀了新的窗口。當(dāng)焦點(diǎn)窗口被銷(xiāo)毀后,Windows 窗口管理器會(huì)嘗試找另外一個(gè)焦點(diǎn)窗口,最終它將輸入焦點(diǎn)設(shè)置到了輸入框控件本身。這將啟動(dòng)一個(gè)遞歸式的焦點(diǎn)更改過(guò)程,告知編輯控件它現(xiàn)在再次具有輸入焦點(diǎn)。
讓我們看一下當(dāng)用戶(hù)單擊工具提示窗口時(shí)焦點(diǎn)變化流程。
- > 設(shè)置焦點(diǎn)到工具提示。
- > 發(fā)送 WM_KILLFOCUS 消息到輸入框。
- > EditSubclass 銷(xiāo)毀了工具提示窗口。
- > Windows 窗口管理器將焦點(diǎn)設(shè)置到輸入框。
- > WM_KILLFOCUS 不會(huì)發(fā)送給任何窗口。
- > 發(fā)送 WM_SETFOCUS 給輸入框。
- > EditSubclass 將 WM_SETFOCUS 消息傳遞給原始窗口過(guò)程。
- > EditSubclass 將 WM_KILLFOCUS 傳遞給原始窗口過(guò)程。
你看到這里面的問(wèn)題了嗎?
下面是到達(dá)原始編輯框窗口過(guò)程的消息流程:
WM_SETFOCUS(源自嵌套的焦點(diǎn)變化過(guò)程) WM_KILLFOCUS(源自原始的焦點(diǎn)變化過(guò)程)
就編輯控件而言,它獲得了焦點(diǎn),然后失去了焦點(diǎn)。因此,它不會(huì)顯示輸入光標(biāo),因?yàn)榫庉嬁丶H在具有焦點(diǎn)時(shí)才顯示光標(biāo),并且遞歸焦點(diǎn)變化會(huì)導(dǎo)致編輯控件認(rèn)為它沒(méi)有焦點(diǎn),即使它有焦點(diǎn)。
擺脫這種混亂的方法有很多。
首先,請(qǐng)注意,你不需要對(duì)編輯控件進(jìn)行子類(lèi)化,你可以對(duì) EN_KILLFOCUS 通知做出反應(yīng)。其次,你還可以通過(guò)向自己發(fā)布消息并在收到該發(fā)布消息后銷(xiāo)毀工具提示來(lái)響應(yīng) EN_KILLFOCUS。通過(guò)發(fā)布的消息執(zhí)行此操作,你可以避免遞歸焦點(diǎn)變化,因?yàn)槟愕墓ぷ鳜F(xiàn)在正在焦點(diǎn)更改周期之外完成的。
總結(jié) 請(qǐng)不要忽視這些細(xì)枝末節(jié)的問(wèn)題,資深用戶(hù)會(huì)感受到你的程序里的各種細(xì)節(jié)。 如果是好的細(xì)節(jié),你的程序會(huì)加分,萬(wàn)一是不那么好的細(xì)節(jié),那就不是一件好玩的事兒了,你的用戶(hù)會(huì)慢慢離你而去。
分享標(biāo)題:處理Wm_Killfocus消息時(shí)需要注意的地方
當(dāng)前網(wǎng)址:http://m.fisionsoft.com.cn/article/djjjjeg.html


咨詢(xún)
建站咨詢(xún)
