Q:我的 Form 上面有多個 Edit 元件,我在 Edit1 的 OnExit 事件中秀
訊息之後,游標即消失不見,以下為問題重現的步驟:
1.在 Form1 上面放兩個 TEdit(使用標準元件,不要用 Ez 元件)。
2.在 Edit1 的 OnExit 事件中加入以下命令:
Application.MessageBox(PChar('Hello'), '訊息', MB_OK);
3.執行程式。
當輸入焦點從 Edit1 離開時會顯示訊息視窗,關閉該訊息視窗之後就
會發生游標消失的情形。應如何解決?
A:OnExit 事件發生時,Windows 已經準備將輸入焦點轉移到下一個元件
,但是轉移動作並未完成。因此如果在 Edit 元件的 OnExit 事件中執
行任何會移動輸入焦點的動作,例如 MessageBox 或開啟其他對話盒,
都會讓 Windows 的輸入焦點不正常。此時輸入焦點雖然已經切到下一
個 control, 但是游標卻不見了。解決方法為使用 PostMessage 自行
送一個 WM_SETFOCUS 訊息給下一個元件(不可以用 SendMessage):
procedure TForm1.Edit1Exit(Sender: TObject);
begin
if not IsValid(Edit1.Text) then
begin
MessageBox(Application.Handle, 'Hello', '訊息', MB_OK);
PostMessage(GetFocus, WM_SETFOCUS, TWinControl(Sender).Handle, 0);
end;
end;
以下是網友提供的方法:
Adding the following to your form:
const
WM_FOCUSFIX = WM_USER + $400;
....
private
procedure WMFocusFix (var Message: TMessage); Message WM_FOCUSFIX;
....
{ Works a bug when a Messagebox is displayed just as
focus is shifting from one control to another. }
procedure TForm1.WMFocusFix(var Message: TMessage);
var
Ctrl: TWinCtrl;
begin
if ActiveControl = nil then Exit;
Ctrl := ActiveControl;
ActiveControl := nil;
Application.ProcessMessages;
ActiveControl := Ctrl;
end;
Then calling:
PostMessage(Self.Handle, WM_FOCUSFIX, 0, 0);
in your OnExit handler should solve your problem.
Damien
============================
對於 UI 設計的一點建議
如果可能的話,盡量不要在輸入焦點離開元件時顯示任何警告訊息,
這個顯示訊息的動作可以只放在〔儲存〕或〔確認〕之類的按鈕事件裡面
,因為:
1.即使在元件輸入完資料就立刻檢查資料是否正確,最後存檔前還是應該
再檢查一次比較保險吧(檢查的程式碼可寫成函數)。
2.使用者可能會想先輸入其他欄位,然後再回來輸入這個欄位。如果覺得
這個理由太牽強,請看第三個理由,情況有點類似。
3.如果現在游標(輸入焦點)停留在 Edit1 上面,而且 OnExit 事件裡
面會檢查資料如果是空白就秀出錯誤訊息,如果使用者後悔了(或選錯
功能了),按一下〔離開〕鈕欲結束程式,這時候會觸發 Edit1 的
OnExit事件,秀出錯誤訊息,然後....無法離開程式!
因為這時候 Windows 的輸入焦點已經亂了(OS 本身的行為),〔離開
〕鈕的 click 動作並沒有完成。這時候 user 得再按一次〔離開〕鈕
才能結束程式。
如果你在 Edit1 的 OnClick 事件裡除了秀訊息之外,還把輸入焦點再
切回 Edit1 來強迫 user 一定要輸入正確資料才能離開元件的話,情
況會更糟,〔離開〕鈕的 OnClick 事件將永遠不會觸發。
不過很多情況我們還是希望在 user 輸入完一個欄位時立刻提醒 user 資
料輸入錯了,如果不能在 OnExit 中秀訊息,該如何處理?
其中一種可能的解決方法,是在離開元件時,如果檢查到資料不正確,就
把元件的字型顏色設成紅色,並且在視窗下方的狀態列中顯示警示訊息(
顏色可以醒目一些)。在資料儲存之前的檢查才秀出訊息視窗。
               (
geocities.com/huanlin_tsai)