Search code examples
delphidelphi-xe2vcl-styles

Right to left ComboBox in Delphi XE2 with styles


I have problems when I use ComboBox in Delphi XE2 with Custom styles(Emerald Light Slate) and this property:

BiDiMode := bdRightToLeft;
Style := csDropDownList;

That ComboBox without Custom style:

enter image description here

And with Custom styles(Emerald Light Slate):

enter image description here

How i can fix it?


Solution

  • The issue it seems located in the DrawItem method of the TComboBoxStyleHook (the vcl style hook of the TComboBox), you can fix this overriding this method.

    Try this sample code (this solution is far from being perfect but is a start)

    type
      TComboBoxStyleHookFix = class(TComboBoxStyleHook)
      protected
        procedure DrawItem(Canvas: TCanvas; Index: Integer;
          const R: TRect; Selected: Boolean); override;
      end;
    
    { TComboBoxStyleHookFix }
    
    procedure TComboBoxStyleHookFix.DrawItem(Canvas: TCanvas; Index: Integer;
      const R: TRect; Selected: Boolean);
    var
      DIS  : TDrawItemStruct;
      Text : string;
    begin
      if Control.BiDiMode<>bdRightToLeft then
       inherited
      else
      begin
        FillChar(DIS, SizeOf(DIS), 0);
        DIS.CtlType := ODT_COMBOBOX;
        DIS.CtlID := GetDlgCtrlID(Handle);
        DIS.itemAction := ODA_DRAWENTIRE;
        DIS.hDC := Canvas.Handle;
        DIS.hwndItem := Handle;
        DIS.rcItem := R;
        Text:=TComboBox(Control).Items[Index];    
        DIS.rcItem.Left:=DIS.rcItem.Left+ (DIS.rcItem.Width-Canvas.TextWidth(Text)-5);    
        DIS.itemID := Index;
        DIS.itemData := SendMessage(ListHandle, LB_GETITEMDATA, 0, 0);
        if Selected then
          DIS.itemState := DIS.itemState {or ODS_FOCUS} or ODS_SELECTED;
        SendMessage(Handle, WM_DRAWITEM, Handle, LPARAM(@DIS));
      end;
    end;
    

    and use in this way

     TStyleManager.Engine.RegisterStyleHook(TComboBox, TComboBoxStyleHookFix);
    

    enter image description here

    Don't forget report this bug in the QC page of Embarcadero.