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_SETTEXTat 字体更改以及在禁用自动完成时它如何知道第二项文本匹配?

到目前为止,我可以在安装了最新更新的 Windows 7 Home Premium 64 位上的 Delphi 2009 和 Delphi XE3 中重现这一点。

4

3 回答 3

4

只需启用 Debug DCU,然后进入Font.Color属性设置器,您就可以在几秒钟内自行追踪到这一点。

当由于Font任何原因更改时,将TFont.OnChange触发事件。 TControl有一个事件处理程序分配给它,即使它可以向自己发送一条CM_FONTCHANGED消息以允许后代类对更改做出反应。当TWinControl收到该消息时,它会向WM_SETFONT自己发送一条消息,然后触发 ComCtl32 发送WM_SETTEXT您正在查看的消息。

于 2012-10-09T21:16:53.713 回答
2

我不认为这是 VCL 问题,查看调用堆栈,似乎消息似乎是通过 comctl32.dll 处理的。您可以通过在设置文本之前设置字体颜色来解决问题:

procedure TForm1.Button1Click(Sender: TObject);
begin
  ComboBox1.Font.Color := clRed;
  ComboBox1.Text := 'B';
  ShowMessage(IntToStr(ComboBox1.ItemIndex));
end;
于 2012-10-09T20:59:00.923 回答
0

我对 Delphi XE8 的实验似乎表明,只要您第一次开始使用 TComboBox 并且在您第一次编写文本之前,强制更改字体请求(例如,只需将颜色设置为 clBlack,即使它已经是)就足够了给它。我认为 WM_SETTEXT 选择错误的文本只会在第一次写入字体颜色(或其他字体属性)时发生。之后,一切正常。无论是 Windows 还是 Delphi 中的错误,我都懒得去发现,因为这个技巧为我解决了问题。:) 但是,我怀疑这是“初始化前的操作”的另一种情况 因为当您为用户提供大量构建后的配置属性(例如更改尚未使用的 TCombobox 中的字体和文本)时,编码人员没有考虑到事情并不总是以方便的顺序被调用。如果这确实是“万灵药”,那么也许我们应该说服 Delphi 团队为我们将其放入 TCombobox(或祖先)构造函数中。顺便说一句,这个相同的“错误”导致 SelLength 从零变化 - 非常烦人,因为它最终将文本框着色为蓝色,暗示焦点,当焦点不是!因此,如果您的表单上有很多组合框都显示为蓝色并声称有焦点 - 这也是特别令人头疼的根源!那么也许我们应该说服 Delphi 团队为我们将其放入 TCombobox(或祖先)构造函数中。顺便说一句,这个相同的“错误”导致 SelLength 从零变化 - 非常烦人,因为它最终将文本框着色为蓝色,暗示焦点,当焦点不是!因此,如果您的表单上有很多组合框都显示为蓝色并声称有焦点 - 这也是特别令人头疼的根源!那么也许我们应该说服 Delphi 团队为我们将其放入 TCombobox(或祖先)构造函数中。顺便说一句,这个相同的“错误”导致 SelLength 从零变化 - 非常烦人,因为它最终将文本框着色为蓝色,暗示焦点,当焦点不是!因此,如果您的表单上有很多组合框都显示为蓝色并声称有焦点 - 这也是特别令人头疼的根源!

顺便说一句,我已经向 Embarcadero 提出了这个问题,并提出了一个解决方案,将上述技巧合并到基本构造函数中。他们将其传递给编码人员,但新版本的 Delphi 是否会包含必要的修复还有待观察。

于 2016-08-28T08:46:02.427 回答