2012-10-09 44 views
4

這顯然是一個錯誤,但我無法追查爲什麼發生。這是一個簡單的代碼來重現。剛落窗體上的組合框和按鈕,並寫了以下事件處理程序:爲什麼組合框在更改字體時將其文本更改爲項目文本?

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    ComboBox1.Items.Add('A Item'); 
    ComboBox1.Items.Add('B Item'); 
    ComboBox1.Items.Add('C Item'); 
    ComboBox1.Style := csDropDown; 
    ComboBox1.AutoComplete := False; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ComboBox1.Text := 'B'; 
    ComboBox1.Font.Color := clRed; 
    ShowMessage(IntToStr(ComboBox1.ItemIndex)); 
end; 

當你點擊按鈕的第一次,你會在充分選擇的第二項的文字組合編輯看到,但消息框會顯示項目索引等於-1。當你放下它時,第二個項目似乎被選中。第二次點擊將設置適當的文本,但其餘的將與第一次點擊相同。所以,在這種情況下,組合框的行爲就像是如果啓用一些奇怪的自動完成。

我已經跟蹤到EditWndProc,在收到字體更改後WM_SETTEXT消息與第二項的文本,但我不知道它來自哪裏,爲什麼與第二項的文本。

所以,我的問題是非常具體 - 什麼(哪種方法)發送WM_SETTEXT在字體更改和它是如何知道關於第二項文本匹配時禁用自動完成?

到目前爲止,我可以在Delphi 2009和Delphi XE3上重新安裝Windows 7 Home Premium 64位並安裝最新的更新。

+0

在delphi 2007中確認的相同行爲認爲這可能是一個Windows API錯誤,你在哪個版本的Windows中測試? – MikeT

+0

我將它包含到問題中,在Windows 7上。 – TLama

+1

已經添加了標籤:) – whosrdaddy

回答

2

我不認爲這是一個VCL問題,看着調用堆棧,似乎這個消息似乎是通過comctl32.dll處理的。 您可以通過設置文本之前設置字體顏色解決的問題:

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ComboBox1.Font.Color := clRed; 
    ComboBox1.Text := 'B'; 
    ShowMessage(IntToStr(ComboBox1.ItemIndex)); 
end; 
+0

我也在悄悄地懷疑Windows。我只有Windows 7可用,所以我無法在其他版本上驗證此問題,您在哪裏嘗試過? – TLama

+0

Delphi XE/W7。如果你想要的話,我可以在明天在XP上試試這個 – whosrdaddy

+0

那太棒了,謝謝你! – TLama

4

你可以在幾秒鐘內通過簡單地啓用調試的DCU,然後步入Font.Color屬性setter已追蹤下來自己。

Font因任何原因而更改時,會觸發TFont.OnChange事件。 TControl有一個事件處理程序分配給它,即使它可以發送一個CM_FONTCHANGED消息允許後代類對變化作出反應。當TWinControl收到該消息時,它會發送WM_SETFONT消息給自己,然後觸發ComCtl32發送您看到的WM_SETTEXT消息。

+0

剛剛發現這一點,所以它第二次點擊正確的原因是字體已經是紅色。 – MikeT

+1

當然,我用調試dcus;我無法跟蹤到這個「EditWndProc」方法和導致更改的消息。更多我一直對此發件人如何瞭解匹配項目感興趣,但即使您的回答意味着它是發送此消息的comctl32。 – TLama

+3

我不明白這是怎麼回答爲什麼文本更改爲項目文本。 –

0

我對Delphi XE8的實驗似乎表明,只要您第一次開始使用TComboBox並且之前強制進行字體更改請求(例如,只需將顏色設置爲clBlack,即使它已經存在)你先寫文本吧。回答WM_SETTEXT選擇錯誤的文本僅在第一次寫入字體顏色(或其他字體屬性)時發生。之後,一切都正常。無論是Windows還是Delphi的一個bug,我都無法找到答案,因爲這個技巧爲我解決了這個問題。 :)然而,我懷疑這是另一種「初始化之前的操作」的情況,因爲編碼器沒有考慮到事件並不總是以方便的順序被調用,當你向用戶提供大量的構建後配置屬性(如更改尚未使用的TCombobox中的字體和文本)。如果這確實是一個「萬能藥」,那麼也許我們應該說服德爾菲團隊把它放進我們的TCombobox(或祖先)構造器。順便說一句,這個相同的「錯誤」會導致SelLength從零變成 - 非常煩人,因爲它最終會將文本框着色爲藍色,意味着焦點不集中!所以如果你的表格上有很多組合框都顯示藍色,並聲稱有焦點 - 這也是特定頭痛的根源!

順便提一句,我已經提出了Embarcadero的這個問題,並提出了一種解決方案,將上述技巧結合到基礎構造函數中。他們將其傳遞給編碼人員,但是新版本的Delphi是否包含必要的修補程序還有待觀察。

相關問題