How to create label on bevel line in Inno Setup - label

Yesterday I found a new setup. It has a label on a bevel line. So, how to create and setting label on bevel line like this in Inno Setup?

That looks like a group box control (known as the TGroupBox in Delphi/VCL), not the bevel.
But the group box control is not exposed in Inno Setup.
As an alternative, just place a TLabel on top of the TBevel. Make sure you set label's Transparent property to False.
On Windows Vista and newer, you can also add a hair space around for a padding. You need Unicode version of Inno Setup for that (the only version as of Inno Setup 6).
procedure InitializeWizard;
var
Page: TWizardPage;
Bevel: TBevel;
Caption: TLabel;
begin
Page := CreateCustomPage(wpWelcome, '', '');
Bevel := TBevel.Create(WizardForm);
with Bevel do
begin
Parent := Page.Surface;
Shape := bsFrame;
Left := ScaleX(0);
Top := ScaleY(8);
Width := ScaleX(417);
Height := ScaleY(220);
end;
Caption := TLabel.Create(WizardForm);
with Caption do
begin
Parent := Page.Surface;
Left := Bevel.Left + ScaleX(8);
Top := Bevel.Top - ScaleY(6);
Transparent := False;
Caption := 'Caption';
{ On Vista and newer, add padding using a hair space }
if GetWindowsVersion >= $06000000 then
Caption := #$200A + Caption + #$200A;
end;
end;

Related

Change background color of TListView header in older Delphi

An old app using Delphi 7, but should be similar code in older Delphi versions up to perhaps 2010. I need to change the background color of a TListView header so I can offer a dark theme. I can change the colors of everything else. I found the thread below which apparently works for changing the font color on a column header, but I need to adjust the background color of the entire header as well.
Delphi: ListView (vsReport) single column header caption with custom font color?
Can someone please help as I am lost. Windows message notifications are beyond my comprehension.
Many thanks.
I'm fairly proud of myself and somehow found bits and pieces of code that all went together to make it all work. Something like this...
procedure TTntListView.WMNotify(var AMessage: TWMNotify);
const
DT_ALIGN: array[TAlignment] of integer = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
NMCustomDraw: TNMCustomDraw;
i: Integer;
r: TRect;
begin
if (AMessage.NMHdr.hwndFrom = FHeaderHandle) and
(AMessage.NMHdr.code = NM_CUSTOMDRAW) then
begin
NMCustomDraw := PNMCustomDraw(TMessage(AMessage).LParam)^;
case NMCustomDraw.dwDrawStage of
CDDS_PREPAINT: AMessage.Result := CDRF_NOTIFYITEMDRAW;
CDDS_ITEMPREPAINT: begin
i := NMCustomDraw.dwItemSpec;
r := NMCustomDraw.rc;
FillRect(NMCustomDraw.hdc, r, Sender.Canvas.Brush.Handle);
SetBkColor(NMCustomDraw.hdc, ColorToRGB(Sender.Canvas.Brush.Color));
SetTextColor(NMCustomDraw.hdc, ColorToRGB(Sender.Canvas.Font.Color));
DrawEdge(NMCustomDraw.hdc,r,EDGE_SUNKEN,BF_LEFT);
Inc(r.Left,2);
Dec(r.Right,2);
if Sender.Column[i].Alignment = taLeftJustify then Inc(r.Left,3)
else Dec(r.Right,3);
DrawTextW(NMCustomDraw.hdc,
pWideChar(Sender.Column[i].Caption),
length(Sender.Column[i].Caption),
r,
DT_SINGLELINE or DT_ALIGN[Sender.Column[i].Alignment] or
DT_VCENTER or DT_END_ELLIPSIS);
Message.Result := CDRF_SKIPDEFAULT;
end;
else AMessage.Result := CDRF_DODEFAULT;
end;
end
else inherited;
end;

How to make Inno Setup RunList checklist box transparent?

My installer has a custom finish page with an image on it. I referred this Custom Welcome and Finished page with stretched image in Inno Setup solution for it. But the issue is with the check box at finish page, it is coming on top of the finish page image with a white background. If I removed postinstall flag, then it will automatically launch my app. But I want the user to be able to choose like how checkbox does. So is there any way to transparent the check box launch message on top of my image? Would TNewCheckBox help here?
[Run]
Filename: "app\My program.exe"; Description: "{cm:LaunchProgram}"; #
Flags: nowait postinstall skipifsilent
In standard Inno Setup, I do not think you can make WizardForm.RunList (TNewCheckListBox) transparent. But as the simple TNewCheckListBox is transparent, you can replace the WizardForm.RunList with TNewCheckListBox.
[Code]
procedure RunCheckBoxClick(Sender: TObject);
begin
WizardForm.RunList.Checked[0] := TNewCheckBox(Sender).Checked;
end;
procedure CurPageChanged(CurPageID: Integer);
var
RunCheckBox: TNewCheckBox;
begin
if CurPageID = wpFinished then
begin
if (not WizardForm.RunList.Visible) or
(WizardForm.RunList.Items.Count < 1) then
begin
Log('No items to run');
end
else
if WizardForm.RunList.Items.Count > 1 then
begin
Log('More than one item to run, keeping the standard non-transparent run list');
end
else
begin
Log('Replacing the one item in the run list with a simple transparent checkbox');
RunCheckBox := TNewCheckBox.Create(WizardForm);
RunCheckBox.Parent := WizardForm.RunList.Parent;
RunCheckBox.Left := WizardForm.RunList.Left + ScaleX(4);
RunCheckBox.Top := WizardForm.RunList.Top + ScaleY(4);
RunCheckBox.Width := WizardForm.RunList.Width;
RunCheckBox.Height := ScaleY(RunCheckBox.Height);
RunCheckBox.Checked := WizardForm.RunList.Checked[0];
RunCheckBox.Caption := WizardForm.RunList.ItemCaption[0];
RunCheckBox.OnClick := #RunCheckBoxClick;
WizardForm.RunList.Visible := False;
end
end;
end;

Why doesn't the radio button on custom page checked in Inno Setup?

Why don't rbStandardInstallType and rbCustomInstallType radio buttons get checked even though I set the Checked property of one of those to True? On the other hand, rbDefaultMSSQLInstance and rbNamedMSSQLInstance radio buttons do get checked.
I create radio buttons like this:
function CreateRadioButton(
AParent: TNewNotebookPage; AChecked: Boolean; AWidth, ALeft, ATop, AFontSize: Integer;
AFontStyle: TFontStyles; const ACaption: String): TNewRadioButton;
begin
Result := TNewRadioButton.Create(WizardForm);
with Result do
begin
Parent := AParent;
Checked := AChecked;
Width := AWidth;
Left := ALeft;
Top := ATop;
Font.Size := AFontSize;
Font.Style := AFontStyle;
Caption := ACaption;
end;
end;
I have 2 custom pages where I must show my image on the left and some text and radio buttons on the right (2 radio buttons per page).
So, in my InitializeWizard procedure I've written this:
wpSelectInstallTypePage := CreateCustomPage(wpSelectDir, 'Caption', 'Description');
rbStandardInstallType := CreateRadioButton(WizardForm.InnerPage, True, WizardForm.InnerPage.Width, ScaleX(15), WizardForm.MainPanel.Top + ScaleY(30), 9, [fsBold], 'Standard');
rbCustomInstallType := CreateRadioButton(WizardForm.InnerPage, False, rbStandardInstallType.Width, rbStandardInstallType.Left, rbStandardInstallType.Top + rbStandardInstallType .Height + ScaleY(16), 9, [fsBold], 'Custom');
wpMSSQLInstallTypePage := CreateCustomPage(wpSelectInstallTypePage.ID, 'Caption2', 'Description2');
rbDefaultMSSQLInstance := CreateRadioButton(WizardForm.InnerPage, True, WizardForm.InnerPage.Width, ScaleX(15), WizardForm.MainPanel.Top + ScaleY(30), 9, [fsBold], 'DefaultInstance');
rbNamedMSSQLInstance := CreateRadioButton(WizardForm.InnerPage, False, rbDefaultMSSQLInstance.Width, rbDefaultMSSQLInstance.Left, rbDefaultMSSQLInstance.Top + rbDefaultMSSQLInstance.Height + ScaleY(10), 9, [fsBold], 'NamedInstance');
And finally, here's my CurPageChanged code in order to display all the controls properly:
procedure CurPageChanged(CurPageID: Integer);
begin
case CurPageID of
wpSelectInstallTypePage.ID, wpMSSQLInstallTypePage.ID:
WizardForm.InnerNotebook.Visible := False;
else
WizardForm.InnerNotebook.Visible := True;
end;
rbDefaultMSSQLInstance.Visible := CurPageID = wpMSSQLInstallTypePage.ID;
rbNamedMSSQLInstance.Visible := CurPageID = wpMSSQLInstallTypePage.ID;
rbStandardInstallType.Visible := CurPageID = wpSelectInstallTypePage.ID;
rbCustomInstallType.Visible := CurPageID = wpSelectInstallTypePage.ID;
end
You are adding the radio buttons to a wrong parent control (WizardForm.InnerPage). Not to the custom pages you are creating. And you then workaround that flaw by explicitly hiding/showing the radio buttons in CurPageChanged.
As all four radio buttons have the same parent (WizardForm.InnerPage), only one of them can be checked. So when you check the rbDefaultMSSQLInstance, the rbStandardInstallType is implicitly unchecked.
For the correct code, see:
Inno Setup Placing image/control on custom page
(make sure you remove your redundant CurPageChanged code)
You should also consider using CreateInputOptionPage instead of manually adding the radio buttons to a generic custom page.

Lazarus find control under cursor

I am using the following code from this posting.
Code from Checked Answer
I need to get the Control (Label.Caption) under the mouse cursor from one of several TLabel and it worked fine when the Label was on the Main From. I put the Labels on a Panel on the Main form and now this only finds the Panel. I only want this to work on a select few of the Labels of the many that are on the Panel.
I tried changing the Z-Order for the Labels as "Bring To Front" but it made no difference, still got the Panel. How can I again find a Label under the cursor now that they are on the Panel?
Lazarus does not appear to have FindVCLWindow or ObjectAtPoint.
procedure TForm1.Button1Click(Sender: TObject);
var
ctrl : TControl;
point : TPoint;
begin
point := Mouse.CursorPos; // Mouse pos at screen
Dec(point.X, Left); // Adjust for window.
Dec(point.Y, Top);
Dec(point.Y, GetSystemMetrics(SM_CYCAPTION)); // Adjust to client area.
ctrl := ControlAtPos(point, True, True, True);
// I added the following
tStr:=ctrl.Name; // DEBUG: This now shows "Panel2"
aStr:=(ctrl as TLabel).Caption; // This used to work
end;
Try:
procedure TForm1.Button1Click(Sender: TObject);
var
ctrl: TControl;
pt: TPoint;
begin
pt := ScreenToClient(Mouse.CursorPos);
ctrl := ControlAtPos(pt, [capfRecursive, capfAllowWinControls]);
if Assigned(ctrl) then
Caption := ctrl.Name
else
Caption := Format('%d, %d', [pt.x, pt.y]);
end;

How to get images to show up on TExtButton in ExtPascal?

I've been trying for hours in Lazarus following from the sample code in the
AdvancedTabs unit, to make am image appear on a button.
The sample code has this:
constructor TAdvancedTabs.Create;
var
I : integer;
begin
inherited;
with SelfSession do begin
SetCodePress;
SetStyle('.new-tab{background-image:url(' + ExtPath + '/examples/feed-viewer/images/new_tab.gif) !important}');
SetStyle('.tabs{background:url(' + ExtPath + '/examples/desktop/images/tabs.gif)}');
end;
with TExtButton.Create do begin
RenderTo := 'body';
Text := 'Add Tab using AJAX!';
IconCls := 'new-tab';
Handler := Ajax(AddTab);
OnClick := HandleExtButtonClick; // Delphi style event handler
end;
...
I have this:
extPath := (CurrentFCGIThread as TExtThread).ExtPath;
(CurrentFCGIThread as TExtThread).SetStyle('.backbtn{background-image:url(' + ExtPath + '/basxv2/back.png) !important}');
btnClose := TV2ExtButton.Create;
with btnClose.AddTo(Items) do
begin
Id := 'frmManualOrder_btnClose';
X := MarginLeft;
Height := ButtonHeight;
Y := ScreenHeight-12*MarginLeft;
Width := ButtonWidth-10;
RenderTo := 'body';
IconCls := 'backbtn';
...
I have tried a number of different things, converting the image to a
gif, for example, and in most cases the button is either blank (if I
don't set the Text property) or shows the text nudged to the right a
few pixels as if making room for an invisible image. A few times the image appears with the top and bottom clipped.
Can anyone see what I am doing wrong?
TIA
Mark

Resources