FastReport 4 and VCL Styles bugs
delphi, delphi-xe5, fastreport, vcl-styles
Solution
Effectively both issues it seems VCL Styles bugs.
1) Q: The toolbar gets a white border around it.
A: The `TToolBarStyleHook` Style hook in not handling the BorderWidth property. so you must create a new style hook and override the `PaintNC` to overcome this issue.
type
TToolBarStyleHookEx = class(TToolBarStyleHook)
protected
procedure PaintNC(Canvas: TCanvas); override;
end;
{ TToolBarStyleHookEx }
procedure TToolBarStyleHookEx.PaintNC(Canvas: TCanvas);
var
Details: TThemedElementDetails;
LStyle: TCustomStyleServices;
R: TRect;
begin
if TToolBar(Control).BorderWidth>0 then
begin
LStyle := StyleServices;
R := Rect(0, 0, Control.Width, Control.Height);
Details.Element := teToolBar;
Details.Part := 0;
Details.State := 0;
if LStyle.HasTransparentParts(Details) then
LStyle.DrawParentBackground(Handle, Canvas.Handle, Details, False);
LStyle.DrawElement(Canvas.Handle, Details, R);
end;
inherited;
end;
and register like so
initialization
TCustomStyleEngine.RegisterStyleHook(TToolBar, TToolBarStyleHookEx);
2) Q : Controls in the print dialog and others are misaligned or wrongly positioned
A: It seems a issue related with the `TFormStyleHook`, you had 3 alternatives.
1) you can edit the frxPrintDialog unit and increase the width of the form.
2) you can patch the form style hook.
3) You can change the width of the print dialog in run-time.
Check this code which changes the width of the dialog in run-time using a `HCBT_ACTIVATE` hook
var
hhk: HHOOK;
function CBT_FUNC(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
const
ClassNameBufferSize = 1024;
var
hWindow: HWND;
RetVal : Integer;
ClassNameBuffer: Array[0..ClassNameBufferSize-1] of Char;
i : integer;
begin
Result := CallNextHookEx(hhk, nCode, wParam, lParam);
if nCode<0 then exit;
case nCode of
HCBT_ACTIVATE:
begin
hWindow := HWND(wParam);
if (hWindow>0) then
begin
RetVal := GetClassName(wParam, ClassNameBuffer, SizeOf(ClassNameBuffer));
if (RetVal>0) and SameText(ClassNameBuffer, 'TfrxPrintDialog') then
for i:= 0 to Screen.FormCount-1 do
if (SameText(Screen.Forms[i].ClassName, 'TfrxPrintDialog')) and (Screen.Forms[i].Width<=563) then
Screen.Forms[i].Width:=Screen.Forms[i].Width+8;
end;
end;
end;
end;
Procedure InitHook();
var
dwThreadID : DWORD;
begin
dwThreadID := GetCurrentThreadId;
hhk := SetWindowsHookEx(WH_CBT, @CBT_FUNC, hInstance, dwThreadID);
if hhk=0 then RaiseLastOSError;
end;
Procedure KillHook();
begin
if (hhk <> 0) then
UnhookWindowsHookEx(hhk);
end;
initialization
InitHook();
finalization
KillHook();
After of apply both fixes this will be the result
Note: please report these issues to the QC page of Embarcadero.
Problem
Some background info. I work at a very small company who has recently upgraded Delphi from version 6 (!!!) to Rad Studio XE5 and things have certainly changed a lot in 10+ years. Most things seems to have been improved in the IDE and framework, but we're having big problems with the new VCL Styles feature. It's just very buggy and not up to par with the quality we were used to from Borland back in the day. We have done lots of tweaks and work arounds to get things working but one issue is really bugging me at the moment and it has to do with the preview form in FastReport 4. - The toolbar gets a white border around it. - Controls in the print dialog and others are misaligned or wrongly positioned We really want to use VCL Styles to give our software a new fresh look, so we hope there is a solution to these problems. Steps to reproduce the issues: - Create a new VCL Forms Application - Check a VCL Style in Project > Options > Application > Appearance, e.g. Sapphire Kamri. - Add a TfrxReport report Component to the form - Double click the component frxReport1 and add a Page Header band just to have some content - Add a TButton and in OnClick event, call frxReport1.ShowReport(); - Run the program and click on the button. In the preview form you now see that the toolbar is surrounded by a white border which looks weird. - Click the leftmost print button to bring up the print dialog and you can see how the group boxes and cancel button is positioned outside of the client area. Do you have any solutions or suggestions to solve the issues? Edit: RRUZ gave a good answer, but there were some side effects to his solution to problem #1 so I decided to simplify the code and just paint the border around the toolbar manually. Like this: ``` procedure TToolBarStyleHookEx.PaintNC(Canvas: TCanvas); begin if TToolBar(Control).BorderWidth>0 then begin Canvas.Pen.Width := 4; Canvas.Pen.Color := StyleServices.GetStyleColor(scWindow); Canvas.Brush.Style := bsClear; Canvas.Rectangle(2,2,Control.Width-2,Control.Height-1); end; inherited; end; ```