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;

ボタンを初めてクリックすると、コンボ編集で 2 番目のアイテムの完全に選択されたテキストが表示されますが、メッセージ ボックスにはアイテム インデックスが -1 と表示されます。ドロップダウンすると、2番目の項目が選択されているようです。2 回目のクリックで適切なテキストが設定されますが、残りは最初のクリックと同じになります。したがって、この場合のコンボ ボックスは、変なオートコンプリートが有効になっているかのように動作します。

EditWndProcこれを、2 番目の項目のテキストでフォントの変更が受信されたメッセージの場所まで追跡しましたWM_SETTEXTが、2 番目の項目のテキストがどこから来て、その理由がわかりません。

だから、私の質問は非常に具体的です - 何 (どのメソッド) がWM_SETTEXTat font change を送信し、オートコンプリートが無効になっているときに 2 番目の項目テキストの一致をどのように知るのですか?

これまでのところ、最新の更新プログラムがインストールされた Windows 7 Home Premium 64 ビット上の Delphi 2009 および Delphi XE3 でこれを再現できました。

4

3 に答える 3

4

Font.ColorDCU のデバッグを有効にしてからプロパティ セッターにステップインするだけで、数秒でこれを追跡できたはずです。

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 が 0 から変更されます。フォーカスされていないときに、テキスト ボックスがフォーカスを意味する青色に着色されるため、非常に厄介です。したがって、フォームに多くのコンボボックスが表示され、すべてが青く表示され、フォーカスがあると主張している場合、これもその特定の頭痛の原因です! それなら、Delphi チームを説得して、TCombobox (または祖先) コンストラクターに入れるように説得する必要があります。ちなみに、この同じ「バグ」により、SelLength が 0 から変更されます。フォーカスされていないときに、テキスト ボックスがフォーカスを意味する青色に着色されるため、非常に厄介です。したがって、フォームに多くのコンボボックスが表示され、すべてが青く表示され、フォーカスがあると主張している場合、これもその特定の頭痛の原因です! それなら、Delphi チームを説得して、TCombobox (または祖先) コンストラクターに入れるように説得する必要があります。ちなみに、この同じ「バグ」により、SelLength が 0 から変更されます。フォーカスされていないときに、テキスト ボックスがフォーカスを意味する青色に着色されるため、非常に厄介です。したがって、フォームに多くのコンボボックスが表示され、すべてが青く表示され、フォーカスがあると主張している場合、これもその特定の頭痛の原因です!

ちなみに、私は Embarcadero でこの問題を提起し、上記のトリックを基本コンストラクターに組み込むことで解決策を提案しました。彼らはそれをコーダーに伝えましたが、Delphi の新しいバージョンに必要な修正が含まれるかどうかはまだわかりません。

于 2016-08-28T08:46:02.427 に答える