0

I am struggling to right align a column in a TStringGrid populated after data binding at runtime in C++builder 10.4. I followed the Delphi snippets found here and there , but without any success. As result of the code below, the grid rows are drawn, but without text. Scrolling can be done in empty rows.

// .h
class fLinkGridToDataSource : public TLinkGridToDataSource
{protected:
  virtual void __fastcall Reactivate() {};
  virtual bool __fastcall RequiresControlHandler() {return true;};

 public:
   __fastcall virtual fLinkGridToDataSource(System::Classes::TComponent* AOwner) override : TLinkGridToDataSource(AOwner) {};
   __fastcall virtual ~fLinkGridToDataSource()override {};
};
//---------------------------------------------------------------------------
class TForm1 : public TForm
{/* ... */
 public:        // Déclarations utilisateur
    __fastcall TForm1(TComponent* Owner);

     TRESTClient *RESTClient1;
     TRESTRequest *RESTRequest1;
     TRESTResponse *RESTResponse1;
     TBindSourceDB *BindSourceDB1;
     TClientDataSet *ClientDataSet1;
     TRESTResponseDataSetAdapter *RESTResponseDataSetAdapter1;
     fLinkGridToDataSource *LinkGridToDataSource1;
};
//---------------------------------------------------------------------------
class fThread : public TThread
{private:
 protected:
    void __fastcall Execute();
 public:
    __fastcall fThread(bool CreateSuspended);
};
//---------------------------------------------------------------------------
//===========================================================================

// .cpp
void __fastcall TForm1::FormShow(TObject *Sender)
{AniIndicator1->Enabled = false;
 AniIndicator1->Visible = false;

 StringGrid1->DefaultDrawing = false;

 RESTClient1 = new TRESTClient(this);
 RESTRequest1 = new TRESTRequest(this);
 RESTResponse1 = new TRESTResponse(this);
 BindSourceDB1 = new TBindSourceDB(this);
 ClientDataSet1 = new TClientDataSet(this);
 LinkGridToDataSource1 = new fLinkGridToDataSource(this);
 RESTResponseDataSetAdapter1 = new TRESTResponseDataSetAdapter(this);

 fThread *Thread1 = new fThread(true); Thread1->Start();
}
//---------------------------------------------------------------------------
__fastcall fThread::fThread(bool CreateSuspended)
    : TThread(CreateSuspended)
{FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall fThread::Execute()
{Synchronize([this](){Form1->AniIndicator1->Align = TAlignLayout::Contents;
                      Form1->AniIndicator1->Enabled = true;
                      Form1->AniIndicator1->Visible = true;
                     }
            );

 Form1->RESTClient1->BaseURL = "my.URL.php";
 Form1->RESTRequest1->AddParameter("ID", "3");
 Form1->RESTRequest1->Client = Form1->RESTClient1;
 Form1->RESTRequest1->Response = Form1->RESTResponse1;

 Form1->RESTResponse1->ContentType = "application/json";
 Form1->RESTResponseDataSetAdapter1->Dataset = Form1->ClientDataSet1;
 Form1->RESTResponseDataSetAdapter1->Response = Form1->RESTResponse1;
 Form1->RESTResponseDataSetAdapter1->Active = true;
 Form1->RESTRequest1->Execute();

 Form1->BindSourceDB1->DataSet = Form1->ClientDataSet1;
 Form1->LinkGridToDataSource1->DataSource = Form1->BindSourceDB1;

 Synchronize([this](){Form1->LinkGridToDataSource1->GridControl = Form1->StringGrid1;
                      if(Form1->StringGrid1->ColumnCount == 2)
                        {Form1->StringGrid1->Columns[0]->Width = (Form1->StringGrid1->Width/4)*3;
                         Form1->StringGrid1->Columns[1]->Width = (Form1->StringGrid1->Width/4)*1;
                        }                    }
            );

 Synchronize([this](){Form1->AniIndicator1->Enabled = false;
                      Form1->AniIndicator1->Visible = false;
                     }
            );

 Terminate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1DrawColumnCell(TObject *Sender, TCanvas * const Canvas,
          TColumn * const Column, const TRectF &Bounds, const int Row,
          const TValue &Value, const TGridDrawStates State)
{TTextLayout *TextLayout1 = TTextLayoutManager::TextLayoutForClass(TTextLayoutManager::DefaultTextLayout);
  try{TextLayout1->BeginUpdate();
      try{if(Column->Index == 0) {TextLayout1->HorizontalAlign = TTextAlign::Leading; /*Column->DefaultDrawCell(Canvas, Bounds, Row, Value, State);*/}
          if(Column->Index == 1) {TextLayout1->HorizontalAlign = TTextAlign::Trailing; /*Column->DefaultDrawCell(Canvas, Bounds, Row, Value, State);*/}
         }
      __finally {TextLayout1->EndUpdate();}
      TextLayout1->RenderLayout(Canvas);
     }
  __finally {FreeAndNil(TextLayout1);}

}
//---------------------------------------------------------------------------

Uncommenting Column->DefaultDrawCell(Canvas, Bounds, Row, Value, State); just leads again to the default left alignment. This is the case also when DefaultDrawing is set to true. Any idea to fix the issue?

ibouka
  • 13
  • 1
  • 5
  • Sorry, I can't test myself with C++ Builder, but in Delphi, with `DefaultDrawing := True;` I can do `StringGrid1.Columns[1].HorzAlign := TTextAlign.Trailing;`, but I also need to call `StringGrid1.Repaint;` to force an immediate repaint. The `HorzAlign` property can also be set already in the designer. – Tom Brunberg Nov 04 '22 at 18:41
  • @Tom, thank you so much. It works. This is the snippet I placed in the onDrawColumnCell handler of the TStringrid : `StringGrid1->Columns[1]->HorzAlign = TTextAlign::Trailing; StringGrid1->Repaint();` – ibouka Nov 04 '22 at 21:03

0 Answers0