how can I lock and hide a FastReport object inspector? - delphi

I am using a fastreport report to create a label and then print it. but I need to show the user the TfrxDesigner from code so that they can drag and resize the components in the report's page.
with that being said, I need to lock and hide all the menus and toolbars so that users don't use them.
I don't want to show or let the user use the menus in the red shape on the picture, also the data tree and all those tool bars, only the green ones.
has anyone been there? any help is appreciated, thanks!

You can create a TfrxDesigner instance:
FDesigner := TfrxDesigner.Create(nil);
FDesigner.OnShow := DesignerShow;
with an OnShow handler like this:
procedure TFRHelper.DesignerShow(Sender: TObject);
begin
Assert(Sender is TfrxDesignerForm);
// Change the TfrxDesignerForm as you wish, e.g.:
TfrxDesignerForm(Sender).BorderIcons := TfrxDesignerForm(Sender).BorderIcons - [biMinimize];
TfrxDesignerForm(Sender).OnMouseWheel := DesignerFormMouseWheel;
end;

Related

Changing font color using TColorBox

Delphi v7
I have yet another remedial question.
Using a TColorBox I would like to change the font color in each of 4 RichEdit controls. I am using an OnClick event of the color box.
This procedure works fine for one rich edit control.
procedure TForm1.cmbFColorClick(Sender: TObject);
begin
reProc.SelAttributes.Color := cmbFColor.Selected;
end;
If I try to write the same code for each of the richedit controls it will change the font color in all of the richedit control at the same time.
Example: I select and change the text color on one richedit control, then I change the text color on a different control the text color on both richedit controls is changed at the same time.
Example
procedure TForm1.cmbFColorClick(Sender: TObject);
begin
reProc.SelAttributes.Color := cmbFColor.Selected;
reApp.SelAttributes.Color := cmbFColor.Selected;
reServ.SelAttributes.Color := cmbFColor.Selected;
end;
This procedure does not work at all
procedure TForm1.cmbFColorClick(Sender: TObject);
begin
if ActiveControl is TDBRichEdit then
with ActiveControl as TDBRichEdit do
SelAttributes.Color := cmbFColor.Selected;
end;
Is there a way I can change the text color on all of the richedit controls without affecting any of the other controls?
i think the active control is your TColorBox not the richeditboxes, because only one control can be the active control. If i remember right, this control which have the focus.
So you have to implement a procedure like this.
and you have remember by code, which was the last, active richedit.
procedure changeColor(edit : Trichedit) ;
begin
procedure changeColor(edit:Trichedit);
begin
edit.SelAttributes.Color := cmbFColor.Selected;
end;
Kind Regards
Problem solved. In a PageControl OnChange event I set the RichEdit SelLength to "0" for each rich edit control.
Thank you for your help. It gave me the idea.
I'm piecing things together from this question, your last question, the comments to those questions, and your answers to those questions.
What you are trying to do is modify SelAttributes.Color for a single rich edit control. The problem is working out which rich edit control to operate on.
Let us suppose you had the following function available:
function ActiveRichEdit: TRichEdit;
Then you could simply write:
ActiveRichEdit.SelAttributes.Color := NewColor;
Or, if there was a possibility that there was no rich edit control active:
if ActiveRichEdit<>nil then
ActiveRichEdit.SelAttributes.Color := NewColor;
So, how do we implement ActiveRichEdit? Well, it seems that you have a control with multiple pages, each containing a distinct rich edit. That sounds very much like a page control to me.
I'm going to assume that your page control is called PageControl, and the tab sheets called TabSheet1, TabSheet2 etc., and rich edit controls are named RichEdit1, RichEdit2 etc. But if your names are different then you'll need to adapt this code.
function TForm1.ActiveRichEdit: TRichEdit;
begin
if PageControl.ActivePage=TabSheet1 then
Result := RichEdit1
else if PageControl.ActivePage=TabSheet2 then
Result := RichEdit2
else if PageControl.ActivePage=TabSheet3 then
Result := RichEdit3
// etc. etc.
else
Result := nil;
end;
Now, there are other ways to do this. You could make an array of rich edit references that could be indexed by PageControl.ActivePageIndex. And there are indeed yet more possible solutions.
But the key is to use the ActivePage or ActivePageIndex properties of the page control to work out which rich edit control to operate on.

Live update of StringGrid when horizontal scroll bar is moving?

In Delphi 2010, I need to display a grid that has a horizontal scroll bar with about 15 columns x 5 rows.
I chose to use a StringGrid.
However, while the mouse button is down dragging the horizontal scroll bar, I want the grid to scroll live.
The StringGrid component, it appears, does not scroll live. It waits until the mouse button is released before updating the column and scrolling if necessary.
Also, the horizontal scroll bar button (is that what it's called) is not proportional to the number of columns. And for a down-arrow when on the bottom row to move to the top of the next column to the right...
These seem like common needs, so I was surprised not to find them in TStringGrid.
Any suggestions on a way around these two problems? I can use a DbGrid or other standard component, but my preference is to not use a commercial grid if I can avoid it. And I'm not going to use shareware or freeware...
TIA
For the first question, you can set goThumbTracking in the StringGrid's Options at design-time, or at run-time: StringGrid1.Options := StringGrid1.Options + [goThumbTracking];
For the third question, you can provide the functionality you need by using keyboard event handlers of the control. An example;
procedure TForm1.StringGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
StringGrid: TStringGrid;
begin
StringGrid := Sender as TStringGrid;
case Key of
VK_DOWN:
if StringGrid.Row = StringGrid.RowCount - 1 then begin
Key := 0;
StringGrid.Row := StringGrid.FixedRows;
if StringGrid.Col = StringGrid.ColCount - 1 then
StringGrid.Col := StringGrid.FixedCols
else
StringGrid.Col := StringGrid.Col + 1;
end;
VK_UP: //...;
VK_RIGHT: //;
VK_LEFT: //;
end;
end;
For the second question, the scrolling code seems to be buried in private methods of TCustomGrid. I have no clue how to achieve that..
If noticed you are not interested in third party components - Freeware, I am not fond of these either, but we all must make sacrifices sometimes if we want to get the problems solved. This is one of these sacrifices! This component is to good to be ignored. You will not create something like it yourself if you don't have a couple of years of free time.
Either write a new component based on TStringGrid (I would not - it is not the best tool in the box to begin with)
But take some time and learn TVirtualStringTree. The component is years ahead of TStrignGrid. The source is available and there are many who uses it.
And there are events already implemented to react on scrollbar changes
OnScroll, OnShowScrollbar
http://www.delphi-gems.com/index.php?option=com_content&task=view&id=12&Itemid=38
Search on stackoverflow and you can read much more about tvirtualstringtree
Second the suggestion to use TVirtualStringTree. Working with the TStringGrid component is like stabbing yourself in the belly with a rusty scissor.

Delphi How to force Main form scrollbars to be visible

What options/properties should use to show a main from scrolbars when I want to?
or always visible in Delphi 2010
The help is as too often useless
thanks
Pw
#Philippe, you can use the ShowScrollBar function and the HorzScrollBar, VertScrollBar propeties to do this.
check this code
procedure TForm1.FormCreate(Sender: TObject);
begin
HorzScrollBar.Range := 10000; // set the range to an higher number
VertScrollBar.Range := 10000; // set the range to an higher number
ShowScrollBar(Handle, SB_BOTH, True);
end;
If you set AutoScroll = true, they should show up if needed. That is, if any visual component is placed outside of the visible client area.
If you do not have any components 'off-screen', why would you need the scrollbar showing?
Anyway, you can set Horz-/VertScrollBar.Range to anything larger than the clientheight/width, and they will show up.
If you need the scrollbar for something else, you can always drop a TScrollBar component on the form.

Making a TPageControl flat in Delphi 7

I don't know whether this question can be answered here, but I hope it will.
I wrote a simple text editor in Delphi 7 that serves as my primary IDE for writing C code under Windows. I run Windows in a VM and I needed something light.
In any case, it uses a TpageControl that gets a new tab whenever you open or create a new file. Pretty standard.
Now, the TPageControl under Delphi has no flat property.
NO I don't mean setting the tab style to tsButtons or tsFlatButtons
the borders cannot be set to "none" and it looks pretty bad when you add a text editor into the tab control.
Is there any way to make a TpageControl flat?
EDIT:
On an open source PageControl that supports flat here's what I found:
procedure TCustomTabExtControl.WndProc(var Message: TMessage);
begin
if(Message.Msg=TCM_ADJUSTRECT) and (FFlat) then
begin
Inherited WndProc(Message);
Case TAbPosition of
tpTop : begin
PRect(Message.LParam)^.Left:=0;
PRect(Message.LParam)^.Right:=ClientWidth;
PRect(Message.LParam)^.Top:=PRect(Message.LParam)^.Top-4;
PRect(Message.LParam)^.Bottom:=ClientHeight;
end;
tpLeft : begin
PRect(Message.LParam)^.Top:=0;
PRect(Message.LParam)^.Right:=ClientWidth;
PRect(Message.LParam)^.Left:=PRect(Message.LParam)^.Left-4;
PRect(Message.LParam)^.Bottom:=ClientHeight;
end;
tpBottom : begin
PRect(Message.LParam)^.Left:=0;
PRect(Message.LParam)^.Right:=ClientWidth;
PRect(Message.LParam)^.Bottom:=PRect(Message.LParam)^.Bottom-4;
PRect(Message.LParam)^.Top:=0;
end;
tpRight : begin
PRect(Message.LParam)^.Top:=0;
PRect(Message.LParam)^.Left:=0;
PRect(Message.LParam)^.Right:=PRect(Message.LParam)^.Right-4;
PRect(Message.LParam)^.Bottom:=ClientHeight;
end;
end;
end else Inherited WndProc(Message);
end;
The thing is when I tried something similar on the main application it won't work. It won't even compile.
When the tabs are drawn as buttons, no border is drawn around the display area, so set the Style property to tsButtons or tsFlatButtons. (For non-VCL programmers, this is equivalent to including the tcs_Buttons window style on the tab control.)
An alternative is to use a TNotebook. It holds pages, but it doesn't do any painting at all. You'd have to provide the tabs yourself, such as by setting the tab control's height equal to the height of the tabs, or by using a TTabSet. (TTabSet is available in Delphi 2005; I'm not sure about Delphi 7.)
Regarding the code you found, it would be helpful if you indicated why it doesn't compile, or if you gave a link to where you found it, since I suppose the compilation error was because it refers to fields or properties of the custom class rather than the stock one. Here's what you can try to put it in your own code, without having to write a custom control.
Make two new declarations in your form like this:
FOldTabProc: TWndMethod;
procedure TabWndProc(var Msg: TMessage);
In the form's OnCreate event handler, assign that method to the page control's WindowProc property:
FOldTabProc := PageControl1.WindowProc;
PageControl1.WindowProc := TabWndProc;
Now implement that method and handle the tcm_AdjustRect messsage:
procedure TForm1.TabWndProc(var Msg: TMessage);
begin
FOldTabProc(Msg);
if Msg.Msg = tcm_AdjustRect then begin
case PageControl1.TabPosition of
tpTop: begin
PRect(Msg.LParam)^.Left := 0;
PRect(Msg.LParam)^.Right := PageControl1.ClientWidth;
Dec(PRect(Msg.LParam)^.Top, 4);
PRect(Msg.LParam)^.Bottom := PageControl1.ClientHeight;
end;
end;
end;
end;
You can fill in the other three cases if you need them. Tcm_AdjustRect is a message identifier declared in the CommCtrl unit. If you don't have that message in that unit, declare it yourself; its value is 4904.
I suspect this doesn't stop the control from drawing its borders. Rather, it causes the contained TTabSheet to grow a little bigger and cover up the borders.
I'm using Delphi XE8 and the following seems to do the trick:
ATabControl.Tabs.Clear;
ATabControl.Style := TTabStyle.tsFlatButtons;
ATabControl.Brush.Color := clWhite;
You could always use a commercial solution. I would strongly recommend Raize components, which support flat TPageControls with tabs. The component set is very easy to work with, and supports numerous visual enhancements which in my opinion give a better feel to any application.
(source: raize.com)
Drop two TPageControls, one with tabs as Tabs, with a global height equal to the tabs, and one with flatbuttons and Tabvisible properties set to false, which would be aligned under the first one. Then make sure the tab change on the first TPagecontrol makes the tabs also change in the second one.

Image Preview in a Listbox

How can I display a preview (almost like a hint) of an image when I hover the mouse over an item in a listbox of filenames? I've tried showing a form and loading the image, but when the preview form shows, I lose focus for the listbox which means that when I move the mouse, the preview image does not change when I go to the next item in the list.
Thanks, Pieter.
I have, based on the answer from TOndrej, tried to implement a custom THintWindow, but the Canvas.StretchDraw does not draw the bitmap sent as a parameter. Any ideas why not? Text is displayed normally.
procedure TFormMain.DisplayPreview(HintImage: TBitmap);
var
CustomHint: THintWindow;
Rect: TRect;
MousePoint: TPoint;
begin
*{
Based on Source: http://www.chami.com/tips/delphi/112996D.html
}*
GetCursorPos(MousePoint);
with Rect do
begin
// set the position and size of the hint window
Left := MousePoint.X;
Top := MousePoint.Y;
Right := Left + 50;
Bottom := Top + 25;
end;
CustomHint := THintWindow.Create(Self);
try
with CustomHint do
begin
// set the background color
//Color := clNone;
**Canvas.StretchDraw(Rect, HintImage);**
ActivateHint(Rect, 'Hint');
Application.ProcessMessages;
//
// perform your tasks here
// before closing the hint window
//
Sleep(500);
ReleaseHandle;
end;
finally
if Assigned(CustomHint) then
CustomHint.Free;
end;
end;
To me it seems you want a custom hint window. To do this you should write a new THintWindow descendant and either set it globally to the whole application by assigning your new class to the HintWindowClass global variable in Forms unit, or write your own listbox descendant in which you will handle CM_HINTSHOW message and assign your new hint window class to HintInfo.HintWindowClass. (HintInfo points to a record passed to your control in the CM_HINTSHOW message by the VCL.)
1) Are you displaying your preview form like a dialog (Modal Window) if yes then change it to non modal window.
2) Remember to set focus back to your parent window once the preview form shows up, that way your parent form that has the listbox has the focus and it will pass the mouse move events to the listbox.
Best Regards.

Resources