How do I add Components dynamically during runtime in Builder XE6? - delphi

I want to add new panels to my form during runtime, but I have the problem that, when aligning them to the top, they are not displayed in the order that I created them.
I followed the hints from this post with the DisableAlign() and EnableAlign()
How to dynamically create controls aligned to the top but after other aligned controls?
This works for the initial four panels I add.
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TPanel * test;
Panel1->DisableAlign();
for(int i = 0; i<4; i++){
test = new TPanel(Panel1);
test->Caption = i;
test->Parent = Panel1;
test->Align = alTop;
}
Panel1->EnableAlign();
}
But then I want to add another panel when clicking the button:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Panel1->DisableAlign();
TPanel * test;
test = new TPanel(Panel1);
test->Caption = 5;
test->Parent = Panel1;
test->Align = alTop;
Panel1->EnableAlign();
}
and this comes up:
Is there any way to get the alignment to do what I want without messing around with the Top Settings or without rebuilding the whole form?

It's quite simple. You must set Top to an appropriate value before setting Align. Set Top to be the coordinate of the bottom of the bottom panel.

Related

Why the child panel do not assume its color?

Now I am struggling to set the color of a child panel placed on another one.
The goal is to represent fractions of time with certain properties over the whole period, represented by a TPanel on the background(Lime Green).
I do not understand, the code I am using has already worked, but now the child panel keeps the same color of the parent panel.
int IntSize = SecondsBetween( CurrInterrup->TerminoInt, CurrInterrup->InicioInt );
int dura = SecondsBetween( Indisp->DtHoraFim, Indisp->DtHoraIni);
int left = SecondsBetween( Indisp->DtHoraIni, CurrInterrup->InicioInt);
int width = RoundTo(((double)dura /(double) IntSize) *(double) PnGreen->Width, 0);
left = RoundTo(((double)left/(double)IntSize) * (double)PnGreen->Width, 0);
TPanel *pn = new TPanel(this);
pn->ParentColor = false;
pn->BorderStyle = bsSingle;
pn->BevelKind = bkSoft;
pn->Color = clRed;
pn->Left = left;
pn->Width = width;
pn->Height = PnGreen->Height -5;
pn->Parent = PnGreen; // A Panel instantiated at design time of color clLime
pn->Update();
The panel "pn" is shown with the correct properties of left, height and width and position, but the color is clLime instead of clRed.
Is there any error on the code?
Thank you very much.
Kind Regards.
Try setting the panel's ParentBackground property to false.
If ParentBackground is True, the control uses the parent's theme background to draw its own background.
If ParentBackground is False, the control uses its own properties, such as Color, to draw its background.

CBuilder TMenu showing in wrong place

I have a Form that needs to be embedded in another Form. I'm placing on TCard:
EmbeddedForm->Parent = ACard;
EmbeddedForm->BorderStyle = bsNone;
EmbeddedForm->Align = alClient;
EmbeddedForm->Show();
All is working well, except that menus on the EmbeddedForm are offset to where they would be if the form were located in top left of the screen. To be clear, the menu shows up in the proper place on the EmbeddedForm, but when clicked, the sub-menu is in the wrong place.
I've tried modifying the DrawItem event, but so far I can't call the base class DrawItem() as it's protected:
void __fastcall TEmbeddedForm::File1DrawItem(TObject *Sender, TCanvas *ACanvas, TRect &ARect, bool Selected)
{
ARect.Left = MainMenu1.Left; // or some other calculation, not important yet
ARect.Top = MainMenu1.Top;
// ??? how to do normal drawItem from here?
}
I'm thinking, either I have to draw it myself (I don't want to) or somehow explain to TMainMenu where it's actually located (preferred solution).

Why can't I access the width of a THeaderSection

I'm trying to use the width of a headersection in a THeaderControl in C++ Builder XE.
The THeaderControl is called "Header"
The TStringGrid I'm trying to align the widths with is called "Grid".
In the OnResize event handler for the Header, I've got the following code :
void __fastcall TMainForm::HeaderResize(TObject *Sender)
{
for (int col=0; col<Header->Sections->Count; col++)
{
Grid->ColWidths[col]=Header->Sections[0].Width;
}
}
which I thought would be OK, but it won't compile.
Can't seem to find out how to access the widths of the header.
Also, when i stuff something in here just to get it to compile (e.g. Grid->ColWidths[col]=100), the HeaderResize event handler doesn't get called (i.e. if I put a breakpoint in this loop, run the program and resize the header, it doesn't get to the breakpoint).
You are not accessing the individual headers sections correctly. You need to do it like this instead:
void __fastcall TMainForm::HeaderResize(TObject *Sender)
{
for (int col=0; col<Header->Sections->Count; col++)
{
Grid->ColWidths[col] = Header->Sections->Items[col]->Width;
}
}
Notice that Sections[col] is replaced with Sections->Items[col], and that .Width is replaced with ->Width.
As for the OnResize event not being triggered, OnResize is only triggered when the entire THeaderControl is resized. When resizing individual sections, the OnSectionResize event is triggered instead. That event tells you which section was resized, eg:
void __fastcall TMainForm::HeaderSectionResize(TCustomHeaderControl *HeaderControl, THeaderSection *Section)
{
Grid->ColWidths[Section->Index] = Section->Width;
}

Add a combobox in to listview control in c++ builder

I want to create a listview with 2 columns. in the first column it must be the row number and in the second number it should contains a combobox. I write the following code, but second column just show "combo" string. it does not show any combo box. what is the wrong?
for (int i = 0; i < 10; i++) {
TListItem *items;
items= this->ListView1->Items->Add();
items->Caption=IntToStr(i);
items->SubItems->AddObject("combo"+IntToStr(i),(TObject *)this->ComboBox1);
}
It does not show a TComboBox because you have not actually set the TComboBox to be a child control of the TListView. All you have done is store the TComboBox pointer as a user-defined value associated with the TListItem. That has no effect on the UI, so get rid of it:
for (int i = 0; i < 10; i++)
{
TListItem *items = ListView1->Items->Add();
items->Caption = IntToStr(i);
items->SubItems->Add("combo"+IntToStr(i));
}
To actually show a TComboBox inside of the TListView, you have to assign the TListView as the Parent of the TComboBox, and then use the SetBounds() method to position and size the TComboBox whenever you need to show it:
ComboBox1->Parent = ListView1;
...
RECT rect = {0};
ListView_GetSubItemRect(ListView1->Handle, SomeListItem->Index, 1, LVIR_BOUNDS, &rect);
ComboBox1->SetBounds(rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top);
// update ComboBox1->Items as needed...
ComboBox1->Visible = true;
...
ComboBox1->Visible = false;
With that said, what you are attempting to do is better handled using the TValueListEditor component instead. Add items to it as needed, then use its ItemProps property to set each item's TItemProp.EditStyle property to esPickList, and then use the TValueListEditor.OnGetPickList event or the TItemProp.PickList property to manage the ComboBox strings as needed.

Modify the "arrow" with of a split button in TActionToolBar

I have a toolbar using TActionToolBar and TActionManager. A button has sub-buttons that are available clicking the small down arrow placed in the right of the button.
The width of the "arrow down" button is very thin and requires precise mouse control. How can I customize it?
Thank you
A solution is using the OnGetControlClass event of TActionToolBar.
Before, it is necessary to derive a class from TThemedDropDownButton and override the GetDropDownButtonWidth function:
function TThemedDropDownButtonEx.GetDropDownButtonWidth: Integer;
begin
Result := 14; // default drop down button width
end;
Then, in OnGetControlClass function:
void __fastcall TWorkAreaToolBarFrame::ActionToolBarLeftGetControlClass(TCustomActionBar *Sender,
TActionClient *AnItem, TCustomActionControlClass &ControlClass)
{
if(ControlClass == __classid(TThemedDropDownButton))
ControlClass = __classid(TThemedDropDownButtonEx);
}
In few words, in GetControlClass event, the toolbar allows you to define which button class you want to use. We use a custom class with the default width changed.

Resources