Delphi - TCustomControl - can it show dotted rectangle when got focus? - delphi

I'm coding an tExCustomControl, which in turn, I use to derive other custom controls. Assuming I have a tExButton inherited from tExCustomcontrol, I wonder how can I make the base class tExCustomControl show the dotted rectangle, when issuing a SetFocus to the derived class tExButton.

In the overridden Paint method for the control, call DrawFocusRect if the control has the focus.

Related

TGraphicControl transparency on a TCustomControl

I created a control based on TGraphicControl that is transparent and mostly empty space. It actually implements a simple symbol in line art.
i.e. TLFMagicControl = class(TGraphicControl)
In the constructor which I have:
ControlStyle := ControlStyle + [csOpaque];
My "TLFMagicControl" is then placed on my own panel that is a TCustomControl.
i.e. TLFGridPanel = class(TCustomControl)
The transparency of the TLFMagicControl works perfectly interacting with each other but not with the parent panel they are on (TLFGridPanel).
The TLFGridPanel spends most of its time just black so its not an issue but I want to user to be able to turn on/off grid lines on the panel. When I override the paint handler TLFGridPanel and draw my grid the controls placed on top are not transparent and block the grid lines underneath.
Is there a way around this for a TCustomControl or have I chosen the wrong base for my panel?
csOpaque tells the VCL that you draw the control entirely by yourself, which supresses the automatic background drawing (or erasing). Remove that control style in order to let WM_ERASEBKGND do its work.

Delphi 7, How can a child react to the parent form Moving?

I'm writing a TFrame descendant that can host any sort of controls at runtime.
Among its features, under specific conditions, it should show a sort of visual dimmed "mask".
I achieved this effect overlaying a separate TCustomForm descendant class with AlphaBlend,
and for this to work the form must have no parent.
Thus, I need some extra code to keep this window anchored to the Client area of the frame, whether it's been resized or moved.
Not a big deal for resizing: I can override TMyFrame's Resize method.
But what about MOVING?
Let's say the frame is client-aligned to the main form: its Left and Top values don't change if I move the main window, so no WM_MOVE message is sent to the frame.
And I need somethig to be incapsulated INSIDE the TMyFrame unit, in order to keep it reusable.
Is there any other message I can handle in such a situation?
Thank you
Hook the parent form's WindowProc property, or subclass the parent form's window using SetWindowSubclass(), to intercept WM_WINDOWPOSCHANING and WM_WINDOWPOSCHANGED messages.

Creating custom Hint window

I'm trying to find a way to use my 2nd form as a hint window for a component (for example a TLabel) in my 1st form.
At the moment, I'm exploring the use of THintWindow and HintWindowClass, but it is not possible to directly assign a TForm to HintWindowClass. Some examples I've seen so far use a TBitmap which is then drawn on the THintWindow.Canvas, which is not bad, but I'd still like to use some kind of integrated automatic mechanism.
Another solution that crossed my mind is to manually implement this functionality using OnMouseEnter, OnMouseMove and OnMouseLeave events of the said Tlabel.
If there actually is a way to "assign" a TForm to HintWindowClass, I'd like to ask if anyone can provide a code snippet illustrating this. Thanks.
THintWindow is a descendant of TCustomControl. TForm is not a descendant of either of those classes, so you cannot assign any TForm class to HintWindowClass. Hint windows need to descend from THintWindow. Anything you can put on a form you can also put on a THintWindow. You'll just have to instantiate it manually and assign its Parent property to make it appear.
The closest you can probably get to "visually" designing a hint window is to design a frame. Make your THintWindow descendant create an instance of the frame, and then override ActivateHint (and ActivateHintData, if you need the data) to forward the hint text and desired size to your frame.

how is it possible to clear what was painted before?

I'm using Delphi and I'm building my own label component with class TControl.
Before I paint the text according to the properties (such as caption, font, etc.) I want to clear paint rect like there is nothing at the place of component. I mean I want to make it like a glass so that the other components behind it will be displayed; and then paint the text. What should I do to paint other components that are placed behind my label to it?
To do that, you need to do nothing. :-)
When you make a transparent label-like component, you best use the TGraphicControl base class. This is actually little more than a canvas to paint on. Whenever the content should be changed, you call the Invalidate method to repaint your control. This will call the Paint method that you can override. With every repaint, your control will be clear and transparent, except for the parts where you draw stuff in your Paint method.
Unless you override and disable the background painting, then you dont need to do anything. It depends on what base-class you go for. Although you can simply use (in the Paint() method):
Canvas.Brush.Style:=bsSolid;
Canvas.Brush.Color:=self.Color; //If you have a public color property
Canvas.FillRect(ClientRect);
You should also read up on TControlCanvas. Here is a website that deals with this topic more in depth: http://www.delphidabbler.com/tips/75

How to make control invisible but responsive to mouse events?

I want to create a control (derived from TCustomControl) that is invisible but reacts to normal events (I want to use it to show a hint when moving the mouse over a custom element). I thought overriding the paint method and leaving it empty would do the job but unfortunately a rectangle is drawn where the component is.
How can I make the control completely invisible?
You can inherit from TGraphicControl instead of from TCustomControl, and leave the paint handler empty. Nothing will be drawn.
If you need a windowed control, then you should make sure that it has no border and uses the parent background. See this question for info on how to do that. You may need to override CreateParams() as well, to remove the border style bits.
If the control is not visible then process click messages in the parent, do a simple test for those being in the control's rectangle and use PostMessage to forward the message to the control. Such code may be more readable than empty paint handlers.
Bri

Resources