When I set the imageindex and images property of a Button (from a imagelist component/pngs), start the program and click the button, the image is blinking slowly/ fading in and out. How to prevent this and what seems to be the problem?
Reviving an old topic...
After searching for a solution on internet and found nothing, I took a look in the TCustomButton code.
It happens that, internaly, a button control on Windows has an imagelist with 6 images, as follows:
index 0: normal image
index 1: hot image (when mouse is moving over button)
index 2: pressed image (while you hold the mouse button d own)
index 3: disabled image
index 4: selected image (when the button has focus, but is not pressed nor with mouse over it)
index 5: (the one that we need and can't be specified in TButton control; we'll talk about it)
In the TButton control in Delphi, you can set an ImageList to the "Images" property, and you can set "ImageIndex", "HotImageIndex", "PressedImageIndex", "DisabledImageIndex" and "SelectedImageIndex".
With this properties set, the TButton control creates ANOTHER image list, and copy the indexes you specified in the properties from the image list in the "Images" property to that new created image list, in the order I specified above.
The problem is, when you focus the control, Win 7 Aero has that effect that it fades in and out the highlight color (a little animation), and it used the 6th image from it's internal image list to fade in and out to also, but it is IMPOSSIBLE to supply that "FADE" image index to TButton control, so I have created a simple solution that is working for myself, but I have to call in RunTime. (you could derive a new class from TCustomButton and create a new control that you can set a new SelectedFadeImageIndex for example, but I didnt).
I created this procedure:
procedure MakeButtonImageStopBlinking(AButton: TCustomButton);
var
ButtonImageList: TButtonImageList;
Icon: HICON;
begin
SendMessage(AButton.Handle, BCM_GETIMAGELIST, 0, LPARAM(#ButtonImageList));
Icon := ImageList_GetIcon(ButtonImageList.himl, 0, ILD_NORMAL);
ImageList_AddIcon(ButtonImageLIst.himl, Icon);
DestroyIcon(Icon);
end;
so, when the window is created (on OnCreate event), i just call MakeButtonImageStopBlinking suppling each button that has image as it's parameter, and it all now works.
Sry for revving such an old topic, but it seems to be no answer for that anyware (or I wasn't able to search properly).
Edit: Setting DoubleBufferd to True will work, but it will stop the little animation from the button with focus. With the solution above, you can leave DoubleBuffered to False and you'll get it all (animation from aero and no fading out image).
It appears to be a doubleBuffered property of a Tbutton. When set to false, the image blinks, when set to true it's working. This occurs on Win 7 with aero enabled.
Related
I have met a bug in applying of StyleLookup in TTabControl nested in FMX Frame. The appearance of the control does not accept the style if the frame with the control is nested in a HorzScrollBox and at form creation the position of the frame is outside the visible area of the form. In other words if the control is visible when the form is shown the control is painted with necessary style appearance otherwise - not.
To reproduce the bug:
Create a new grid metropolis application.
Create a Frame and put a TTabControl on it. Set Align of the TabControl to alClient. Add, say, 4 TTabItems.
Open detail form, and set its width to a value > your Screen.Width (for me 2500 was enough).
Copy-paste any of the Columns (Layouts), say, 2 times and use the most right layout to nest a frame in it. You will see normal presentation of tabitems at designtime. Set style settings. You will get the following picture:
Done. Run the project. You will get the bug.
At runtime the appearance of TabItem is like this:
If you set the StyleLookup manually at runtime the appearance might either not change either be set to every other item (for example 1st, 3rd and not set to 2nd and 4th though you assign the same StyleLookup to all TabItems). The other interesting finding. If you have other forms containing TabControls with TabItems (nested without frames and closer to left border of the form) for example Form2, you get the following. If you show the faulty Form1 at runtime first you will see the bug, but if you close this form and show Form2 you see proper TabControl. Closing Form2 and showing Form1 (faulty) afterwards will give you a proper appearance of TabControl in a faulty form.
It has something in common with the bug reported by me earlier: Incorrect selection of items in an FMX TListbox (Grid Metropolis UI). It is still not fully solved.
There was also a question yesterday but it is about an exact problem with VCL Frames and the solution is not suitable for FMX.
Appended.
The way is to partially set the style is to set OnPainting event handler for TTabControl in the parent form unit (it does not work being set in frame unit) and write something like this:
procedure TPatientsScrollF.HMDiagnosisFr1TabControl2Painting(Sender: TObject;
Canvas: TCanvas; const ARect: TRectF);
var
i: byte;
begin
(Sender as TTabControl).StyleLookup := 'tabcontrolstyle';
for i := 0 to (Sender as TTabControl).TabCount-1 do
(Sender as TTabControl).Tabs[i].StyleLookup := 'tabitemstyle';
end;
But than you still get a problem - the Tabs are not drawn properly - see the lower edge of inactive Tabs.
Or even like this:
Appended 2
I have just met the bug appearing even at design-time after placing a frame in a form and assigning style to TabItems. The TabControl looks like in fig. 3.
Nearly every application will highlight a comboboxes' item at the current mouse position.
In Firemonkey Embarcadero changed this behavior.
Image1:
In this case ListBoxItem3 should be highlighted - but it isn't.
I then selected ListBoxItem2 and opened the combobox again.
Image2:
ListBoxItem2 keeps being selected even tho ListboxItem4 should be.
As you can see I was using TListBox Items in this example.
In the StyleBook I added a new StyleObject (a blue rectangle) with a TFloatAnimation so i could add a "fake" selection.
But it sadly didn't work.
Image3:
So here i am after spending quite some time trying to figure out how to select a comboboxes' item on mouse over movements.
Someone know a way to achieve this?
This is a new behaviour introduced by new versions (from X3 onwards), you can set DropDownKind = ddkCustom (default value ddkNative) for emulate old behavior.
Note that using Custom as DropDownKind you obtain a behaviour that it's slightly different from the previous one, since it sets the itemIndex property value immediately, but it shouldn't be a big problem ...
I am new to FireMonkey (drawn by its new ability to work with Android). I am trying to animate selection of an item with animation of the list box to reveal underlying content (a frequent pattern). However, I am having trouble getting the list box to manage the deselection of the previously-selected item when I animate the disappearance of the list box. Strangely, this only seems to happen on the Windows platform, and not on Android or iPad devices (or the iPad simulator).
To reproduce the problem (in RAD Studio XE5):
1) Create a new FireMonkey Mobile Application, selecting Tablet Master-Detail to use as a starting layout
2) Right-click on Target Platforms, and select 32-bit Windows, to simplify debugging, and select it.
3) Add a new TListBox object, and drop it on the left portion of the window.
4) Use the Structure browser to move it to LeftLayout, making it's parent the LeftLayout.
5) Click on the ListBox1 object
6) Change the Align property to alClient, to fill the LeftLayout
7) In the ObjectInspector, select the Position Property, and the X Sub Property, and select Create New TFloatAnimation. The FloatAnimation will be named FloatAnimation1
8) Create a new OnItemClick handler for ListBox1, and add the following code:
FloatAnimation1.StartFromCurrent := True;
FloatAnimation1.StopValue := 0 - ((LeftLayout.Width) / 1);
FloatAnimation1.Start;
9) Create a new button, and place it on the toolbar at the top of the left window
10) Create a handler for the new button, and add the following code:
FloatAnimation1.StartFromCurrent := True;
FloatAnimation1.StopValue := 0;
FloatAnimation1.Start;
11) Double Click on the ListBox to open the Items Designer, and click the AddItem button three times to add three TListBoxItems
12) Run the app. Click on one of the three items in the ListBox. The ListBox animates to the left, out of view. Click on the button we added to get it back. Click on the other items, and eventually, you will have all three items selected, even though MultiSelect is turned off for the ListBox1.
13) Stop the app. Change the OnItemClick handler code by changing the "1" to a "2", so the ListBox will only move half of the way to the left. Run the app again. Now, when you click on the ListBox, only one item will be selected, and the previously-selected item will be deselected (as it should be for a single-selection list box).
Again, if I run this on iPad, iPad simulator, or an Android tablet, the ListBox works properly: when an item is clicked in the ListBox, the previously-selected item is deselected.
I can't be the first person to find this, since this sort of animation is so common in apps. Why is the ListBox misbehaving, and why is it different in Windows32 if I animate it only part way off the screen, and why is it different in Windows32 than on the iPad or Android tablet?
i have the same problem, Win32 App with XE5 Update2, Listbox moving out left, then coming back but with remainders of the blue selection underlay.
What works (very dirty i know) for me, is starting a Timer right after starting the Animation. Timer Interval is 100ms
Code in Timer
if lb_liste.selected is TListBoxItem then
lb_liste.selected.isselected:= false;
//lb_liste is my Listbox, a problem could be that then no more item is selected, but that was fine for me.
I had this part in the OnProcess Event of the TFloatAnimation before, but strangely this caused an AV whenever i talked to a database over in another form before sliding back to my listbox.
For me this is clearly a bug in FMX, lets wait for XE6,7,8
I have kept an TImage component at the Top-right corner of a bitbutton.While loading of Form some part of image is Hidden by Button as like in image .How to avoid this.? and also tell me how to find corner of a Button such that i can place my image correctly to show notification correctly in case of Dynamically loaded buttons.
Yours Rakesh.
A TImage cannot be brought in front of a TBitButton since a BitButton is a windowed control (TWinControl). Instead of a TBitBtn or a TButton, you can use a control which does not descend from TWinControl, like a TSpeedButton.
The top-right corner of a button is at (Button.Left + Button.Width, Button.Top).
A TBitButton owns a window handle and only controls with an own window handle can be placed in front of it. You could place your bitmap on a TPanel (TPanel inherits from TWinControl and has a window handle), and this panel you can bring in front of any other control. Set the BorderStyle of the panel to bsNone, so it only works as a container and is not visible.
P.S. If your bitmap is as simple as the one in your example, you could directly write onto the panel and set the colors accordingly.
I add a toolbar with some standard Delphi components to my application. Unfortunately, the stupid arrow is first glyph (does anyone even know what it is for?)
I would like to destroy it totally, or, at least, set itcs icon to blank, so that it blends in with the toolbar.
How can I do this?
I need some code which can be executed twice without causing an exception. Thanks
TToolButton gets its image from combining its ImageIndex property with the enclosing toolbar's Images property, which refers to a TImageList. To make a toolbar button have no image, assign ImageIndex := -1.
To remove the glyph from a TSpeedButton at design time, select the button, and then select the Glyph property in the Object Inspector. Press Del to clear the property. To do the same at run time, assign Button.Glyph := nil.
If you have a pre-made toolbar, such as TMediaPlayer or TDBNavigator, then you can't customize the buttons. They always show the arrow glyphs that are hard-coded in the control. You can choose to hide or show certain buttons, though. If you placed the control just to get a row of buttons and have no intention of using them to play media or navigate a database, then don't use that control. Just place a TPanel and put standalone buttons on it.