I'd like to highlight my toolbar icons when their associated action has it's "checked" property set to true. I'd like to do it in a manner similar to how Microsoft Office 2003 did it, e.g. see the Bold and Align Left icons in this image:
The image is drawn with a box around it and the background has been changed to orange.
How could I implement this using Delphi 2009?
As a bonus, is there also a way to do the same thing with the icon in the menu for the associated item? e.g. as below with the Ruler and Markup entries:
Followup:
Thank you Andreas, for what is a simple and correct answer to my question. As a Delphi 4 programmer converted to Delphi 2009, I was not familiar enough with the VCL additions of Delphi 5 to 7, so the TActionManager, TActionToolbar and their workings were not in my Delphi vocabulary. And this is based on Delphi's ability to use a style that is akin to a Microsoft O/S's theme.
However, with your answer, and a bit of research using it, I confirm that I do not want to do this in this manner. An illuminating Embarcadero thread re: Popup menus: "Checked" items with icon no longer shown as sunken? with Peter Below contributing his expertise, made me realize that I don't want to change to the XP theme at all, since that will do baaaaad things to Vista and Windows 7 users, taking them back to the Bronze Age.
The true culprit here is that there are certain things that the O/S themes want you to respect. Delphi tries to follow the rules. I can go back to XP, the XP style/theme, and the XP Color Map. In this mode, checked items will be hilighted. And this is really all I wanted - to highlight the checked items. I used Office 2003 as an example, because it was the sort of hilighting I wanted. But I really didn't want to entirely change themes and force an entire new look on my program. It would especially make things look unnatural for Vista and Windows 7 users.
What would be ideal is if I could have another set of Images that would apply when the object is Checked ... but there is not a "CheckedImages" property. Or a way of programmatically or automatically modifying the image if it is checked (e.g. like disabled images get a grayscale version of their enabled image).
I still wouldn't mind hearing from anyone if there are any ways to implement this or something else that might work equally well, without changing the entire look of my program.
Add a TActionManager to the form, and create some actions (e.g., bold, italic, and underline). Make sure to set the AutoCheck property to true for each action. Then add a TActionToolbar. Double-click the action manager, and drag the three actions to the toolbar. Now add a TXPColorMap to the form, and assign it to the action manager. Also add a TImageList and add icons for bold, italic, and underline (from C:\Program Files (x86)\Common Files\CodeGear Shared\Images\GlyFX\Icons\BMP\16x16). Assign the image list to the action manager.
Set the toolbar icons to show only the glyph and not the caption. Finally, set the ActionManager's Style property to XP Style. The end result is what you seek.
One can also use an ordinary TToolBar, with DrawingStyle set to dsGradient, I just found out.
Without changing the entire theme, I think this is something that might work half decently:
Add extra images to the ImageList, so that for a given action, there are two (or more) images to choose from.
Instead of changing the "checked" property to true or false, change the ImageIndex to the alternative image, e.g.:
if WS = 1 then begin
ElTree.Align := alTop;
// TileTopBottomAction.Checked := true; --- take this out
// TileLeftRightAction.Checked := false; --- take this out
TileTopBottomAction.ImageIndex := 47; { hilighted image }
TileLeftRightAction.ImageIndex := 14; { regular image }
end
else begin
ElTree.Align := alLeft;
// TileTopBottomAction.Checked := false; --- take this out
// TileLeftRightAction.Checked := true; --- take this out
TileTopBottomAction.ImageIndex := 13; { regular image }
TileLeftRightAction.ImageIndex := 48; { hilighted image }
end;
Now the images will look like this on the toolbar:
and like this on the menu:
The nice things about this method is that it also works on the menu, and you can have multiple images to represent what you want. Also, it will not wreck the theme (XP, Vista, Windows 7, etc) that the program has taken on.
The disadvantage of this method is: You are limited to 16x16 image area to play with and cannot draw a box around it that are outside those limits as happens when you set the "checked" property to true.
Related
The following was found in Embarcardero RAD Studio 10.2. I have not looked at other versions.
If you have a TRichEdit on your form that contains existing text (more than 1021 characters), and change the WordWrap (or any other recreate window) property, then the component will sometimes insert additional blank lines in the middle of your existing text. It appears to depend on where the CR/LF characters land.
To demonstrate the problem, paste the following text into the Lines property of a TRichEdit on a form in Delphi:
01xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx78
02xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
03xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
04xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
05xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
06xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
07xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
08xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
09xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
10xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
11x456789012345678901234567890123456789012345678901234567890123456789012345678
12xxxxxxx1xxxxxxxxx2xxxxxxxxx3xxxxxxxxx4xxxxxxxxx5xxxxxxxxx6xxxxxxxxx7xxxxxxxx
13x4567890123456789012345678901234567890123456789012345678901
x
The purpose of the sample text above is to have 1024 characters (counting the CR/LF at the end of the preceding lines) when you get to the last line (the 'x' on its own). What comes after does not matter.
Now, with the above text in your TRichEdit, and still in design mode, toggle the WordWrap property a few times. (The same thing should happen if you set up your form to do it at runtime.) If your Delphi does the same as mine, the last line (the 'x' on its own) will start to separate from the earlier lines as new lines are inserted.
If you change the length of the 13th line - add or remove just one character - the problem seems to go away.
I say "seems to go away" because the 1022/1023 position for CR/LF is not the only sensitive positions. I found more further on (when playing with larger text), but not always on the 1k borders (I think, not studied in detail).
I found the problem with WordWrap, but it happens with any of the properties that recreate the window handle (I think) - certainly BorderStyle does the same thing.
Has anyone else seen this? Is it too much to ask if someone could try the above test in Delphi 10.3 to see if it's fixed?
Probably the only reliable fix (if 10.3 doesn't fix it) is to avoid using TRichEdit, or - and this is my next step for testing the problem - to create and use a derivation that inserts code to save and restore content during handle recreation. Any other ideas?
UPDATE At runtime the problem only happens if the PlainText property is true. At designtime it happens whether that property is true or not.
I want to set the background color (and foreground color) of the status bar in my freshly created Delphi XE8 Firemonkey app. With the status bar I mean the top bar with the time and wifi widgets.
I just cannot find it. I need some help :-)
Thanks,
Edward
The Fill.Color of the form controls the color of the toolbar, and the average luminance of this color controls wether the text is white or black
Borderstyle must be <> None, or else the toolbar will be hidden.
If you have multiple forms, it is a bit unclear what form is used, but it seems like it is the last form being auto-created in your project file.
Here is some relevant sourcecode from FMX.Platform.iOS.pas that documents the color of the text:
procedure TPlatformCocoaTouch.UpdateStatusBarColor(const AForm: TCommonCustomForm);
...
AppDelegate.MainWindow.RootViewController.SetStatusBarBackgroundColor((AForm as TCustomForm).Fill.Color);
...
procedure TFMXViewController.SetStatusBarBackgroundColor(const ABackgroundColor: TAlphaColor);
...
FStatusBarLuminance := Luminance(ABackgroundColor);
...
function TFMXViewController.preferredStatusBarStyle: UIStatusBarStyle;
begin
if FStatusBarLuminance < 0.5 then
Result := UIStatusBarStyleLightContent
else
Result := UIStatusBarStyleDefault;
end;
PS. I have another unanswered SO question about how to make the statusbar transparent, which is native iOS 7+ behavior.
Recomendation from book "Cross-Platform Development with Delphi XE7 and FireMonkey for Windows & MAC OS X" by Harry Stahl
TStatusbar (a way to compensate the missing “Panels”)
In the VCL
status bar you can display a text either on the property “Panels” or
via the “SimpleText” property. In the FireMonkey status bar there is
nothing of the sort, no text property. So you could use the status bar
as container and there, for example, insert Labels .
Better solution:
Just take a TGrid! As you can see in the screenshot shown below, I
have included in the StatusBar a TGrid. In the TGrid I have 2
TStringColumns, a TImageColumn, again a TStringColumn and a
TProgressColumn added. In the Objectinspector, I have set for the
TGrid:
I am using the code below to create a messagebox in Delphi 7. However I also have another form on screen who's FormStyle is set to fsStayOnTop and the messagebox appears behind this form.
Is there any way to force the messagebox to appear in front?
if Application.MessageBox('Amessage here','Title', +MB_APPLMODAL + MB_ICONQUESTION + MB_YESNO) = IDNO then
Call NormalizeTopMosts prior to showing the message box.
Use NormalizeTopMosts to allow a message box or dialog box that is
displayed using the Windows API functions (such as MessageBox and
MessageDlg) directly, appear on top of a topmost form. Otherwise the
topmost form remains on top, and may obscure the message box.
(Hope it's available in Delphi 7.)
Edit: Not sure about the downvote. If it hints in the direction that OP should use the native MessageBox function and set its parent HWND to the topmost window - I would agree. But maybe this is not possible for some reason.
In Windows.pas you can find more flags to MessageBox():
MB_APPLMODAL = $00000000;
MB_SYSTEMMODAL = $00001000;
MB_TASKMODAL = $00002000;
Read about them in MessageBox documentation
You can even use MB_TOPMOST flag.
Try MB_TASKMODAL flag instead of MB_APPLMODAL.
I would like to increase the font size of the standard (D2009) Ribbon controls, but I din't find a property to do it.
Is it possible to change the font at all? When yes, how?
thanks
TRibbon has a published Font property, I'd use that?
Just make sure you do not have any subcomponent of the ribbon selected, or when you do, press escape until the Object Inspector show the properties for the TRibbon itself.
Update (in response to comment)
It works for me, just tried it to make sure. I used a FontSelector from a component library (TMS Software), and setting Ribbon1.Font.Name to any valid font name (retrieved from the system by the font selector) such as "Verdana" or "Comic Sans MS" had an immediate visible effect on all text displayed on the Ribbon.
So:
Ribbon1.Font.Name = 'Comic Sans MS';
should do the trick, though to test it I would probably select a font (such as "Modern") for which the difference with Tahoma (the standard system font on most systems) is a bit more obvious.
Note: Haven't checked this, but I wouldn't be surprised if you can only use True Type fonts with the Ribbon.
Update
Andreas Rejbrand just pointed out that in my previous update I overlooked the fact that the OP wanted to change the size of the Font, not the font face (as identified by its name). Unfortunately, as it turns out, while of course the Font property has a size, changing that has indeed no effect at all... hmmm, why ever not?
Some investigation turned up the following
The Size of the Font does get changed
The Ribbon finally receives a CMFONTCHANGED message
Processing that messages makes the Ribbon change the font of all the ActionBars connected to the Ribbon
Then it starts a RebuildRibbonMetrics
It then proceeds to set Tabs[I].Page.Canvas.Font.Size := GetRibbonMetric(rmFontSize);
And GetRibbonMetric - lo and behold - returns 8, unconditionally, hard coded, not even a constant, just an integer literal.
Well, there is the reason why you can change the Ribbon's font size to your hearts content but it will never have any effect.
Why it was coded that way? Dunno. May have to ask Borcadero that through Quality Central. I have skimmed through the MS Ribbon Control Guidelines and can't remember seeing anything that says the Ribbon's font size should always be 8...
I've got an app that runs a long set of operations, and I'm trying to use a TProgressBar to keep track of what's going on. I set a number of steps, and call .StepIt to increment the progress bar.
Problem is, it doesn't keep up very well. Instead of jumping directly to the correct position, it seems to like to slide gradually up to it. That's all well and good if it's eye candy you're after, but when I'm trying to get an accurate representation of my routine's progress, this makes it appear to be constantly lagging behind the true status. How can I turn that "feature" off?
I only notice this happening under Windows Vista. Not sure if it's also going on on XP or not, because when I test it on XP, the process goes a lot faster and it's over too quickly. :P But this may or may not be Vista-specific. Either way, it's driving me nuts. Does anyone know how to fix it?
I have a quick but partial and inelegant solution, if you don't mind having the progressbar yellow instead of green:
ProgressBar1.SmoothReverse := True;
ProgressBar1.State := pbsPaused; // for yellow or pbsError for red
Or if you don't mind loosing the vista/theme look and go back to a flat blue one:
UxTheme.SetWindowTheme(ProgressBar1.Handle, ' ', ' ');
The real "problem" according to Microsoft is that you try to "pervert" a ProgressBar into a Meter which they claim it is not.
You could also try to draw it yourself ;-)
Same problem on Windows7 !!
But the answer was already in one of the older posts:
If tou make the progressbar step backwards there will NO delay !!!
So I implemented this..... (and get instant updates)
if(progress < ProgressBar.Max)
then
begin
ProgressBar.Position := progress+1;
ProgressBar.Position := progress; //This will set Progress backwards and give an instant update....
end
else
begin //cannot set position beyond max...
ProgressBar.Max := progress + 1;
ProgressBar.Position := progress + 1;
ProgressBar.Max := progress; //This will also set Progress backwards also so instant update........
end;
I ran into exactly the same problem a while ago. After searching Google for a long time, I found that it is a Vista-specific problem. It seems to boil down to this: Microsoft added fancy animations to the progress bar control in Vista (i.e., the moving 'highlight'). To make updates more smooth, they implemented some sort of 'lagging' in the repaint of the control --- and this basically screws the whole progress bar control. Rather annoying, I'd say, especially since there doesn't seem to be a decent solution.
See for more details the replies by Arvid Winkelsdorf to this Embarcadero Discussion Forum post:
It's the same for VB, C++ and C#
somehow as the problem lies in the
Vista drawing of the new animated
ProgressBars. To provide a smoother
visual feedback drawing is delayed
when moving forward. Your application
cannot be sure that 100% will be
reached at any given time.
By setting the position back to a
smaller value, the ProgressBar drawing
is forced to jump back. No delay in
getting to a position smaller than the
current. So you'll have nearly 100%
immediately. Afterwards set to the
maximum and you'll have exactly 100%.
[...]
There is a similar glitch when using
the new Vista ProgressBar Styles like
PB Paused or PB Error. If the bar is
still moving (MS part) and your app
sets the color to paused by
SendMessage (like in D2009) the
message will be ignored by the
ProgressBar.
Maybe you can try to set the position of the ProgressBar directly instead of using the StepIt procedure. I'm on XP with Delphi 7 here, so I can't test it, but looking at the code of TProgressBar it uses a different message (PBM_SETPOS instead of PBM_STEPIT). So maybe it sets the position of the progressbar without an animation.
Additionally there are several 3rd party components which provide better Progress bar implementations that still render nice on Vista. Personally, I prefer the one from Raize components which works quite well. It doesn't "lag" like the windows control does and works independent of any theming.
If you don't really want anything fancy, then you can always build one yourself using a panel and a tshape aligned left inside the panel. Resize the tshape to be a % of the panel it sets on.
I had the same problem, my solution was to switch to another control available in the VCL :
I choose to use the Range of TTrackBar to display the progression.
(with slider off and control resized to hide the range marks).
Not the same visual (particulary if themed), but it fit well my need (no lag).
Here is a simple solution:
ProgressBar.max := ProgressBar.max +1;
ProgressBar.StepBy(2);
ProgressBar.StepBy(-1);
ProgressBar.max := ProgressBar.max -1;