TPopup Arrow Position - delphi

I have a delphi project that creates a TPopup when I put my mouse over a field in a StringGrid (Field is edited in a Memo so I wanted to have a fast way to read it).
The problem is: when I place the mouse over it the little "arrow" pointing to my StringGrid is not aligned with my mouse, my mouse is pointing to a corner of the Popup.
Is there a property that changes it's position? Or a way to allign it with the mouse pointer?
I've Already used these placements (and many others):
Balao.Placement := FMX.Controls.TPlacement.MouseCenter;
Balao.Placement := FMX.Controls.TPlacement.Mouse;

Just noticed that the little "arrow" comes from TCalloutPanel. Changed it to a TPanel and it got a lot better. But as most of my users use transparent styles I'm gonna have to use a TRectangle otherwise the text is impossible to read

Related

X,Y coordinates of text cursor position

How to find out X,Y screen coordinates of a text cursor in a control whatever is focused at current time? It may be TEdit, TMemo or any other control with text cursor.
I need it in order to display a window with a choice of alternative characters user can enter. This window should pop up on a special key combination, with its top left corner near to the caret in currently active editor. Because I did'nt want to make individual processing for each editing control, I do it application wide in Application.OnMessage handler.
GetCaretPos can do the trick.
It works like
if Windows.GetCaretPos(cp) and Windows.ClientToScreen(GetFocus(), cp) then begin
//.......
end;

Creating a forms editor in Delphi

My goal is to create a simple forms editor like the one that we find on Delphi IDE.
Right now the user can select and add the components making it parent of a TPanel that is the holder of the form. For simplicity, please consider also TPanel as the visual components added to the form.
I have 2 missing parts I want to find out ideas/code to help complete:
1 - how to move the created visual component? The same effect that in IDE for moving the visual component, for example Tpanel, around, chaning its top and left position
2 - how to draw that hooks for the component with focus on the form editor
3 - how to resize using the hooks
I only want the part related to handle the visual part. I am not generating DFM or anything like that.
Simply put your moving code needs to do this:
When the mouse goes down, check if the mouse position is over a control that can be dragged. If so, then set a variable named FDragControl to refer to that control. This code lives in an OnMouseDown event handler.
When the mouse moves, if FDragControl is not nil, move the control. This code lives in an OnMouseMove event handler.
When the mouse goes up, set FDragControl to nil.
That's pretty much all there is to it. The main nuance is that you must also remember the X, Y values of the mouse when the drag commenced. So in your OnMouseDown handler you write:
FStartMousePos := Point(X, Y);
FStartDragControlPos := Point(FDragControl.Left, FDragControl.Top);
And then in the OnMouseMove your position code reads:
FDragControl.Left := FStartDragControlPos.X + (X-FStartX);
FDragControl.Top := FStartDragControlPos.Y + (Y-FStartY);
You will also need to capture the mouse when you start dragging.
The resizing code is similar. Again, you need to decide in the OnMouseDown that you are resizing rather than dragging, but the code still involves handling mouse down, move and up events.
As for painting, you need to force a repaint whenever one of your event handlers changes a property that will influence the visual appearance of your form. You can use the value of FDragControl to decide whether or not to use special drawing of your control and indicate that it is being dragged. And likewise for resizing.
I've not coded up a full working implementation since your question is high level and conceptual. The implementation is down to you.
// I have made this an answer as I have just read your latest update which really should have been made as an edit to your original question but, anyway.
You can download the Cindy Components Pack and use the cyResizer Component which will do pretty much everything you need and is very customisable as well.
You can download it from here: http://sourceforge.net/projects/tcycomponents/
Searching more for an answer I could find these articles:
How to Move and Resize Controls at Run Time
http://delphi.about.com/library/weekly/aa102505a.htm
How to Add Size Handles to Controls being Resized at Run-Time
http://delphi.about.com/library/weekly/aa110105a.htm
Pretty much with all the information to complete this task with source code example.
These articles show how to implement and use a TMover class. I have done it and work correctly.
I have also downloaded the TcyComponents Pack and used the TcyResizer. It is a full featured form editor with pretty much everything that is required for a Delphi like forms editor. I recommend. It comes with source code and works fine with XE2 version.

Add shortcut to a TForm or Panel.Transparent?

To thwart the nit-pickers, let me start with, I searched here with this and could not find an answer, and yes, also I did scroll through the "Similar questions."...
Adding shortcuts to a TForm
I want to drag and drop some shortcuts from the Desktop to a TForm in my application. I am using Anders Melander's brilliant Drag Drop Suite (DDS).
I tried putting a TImage on the form but the DDS does not drop to an Image so I added a TPanel with a TImage on it. I could then drop on the panel and assign the image to the TImage.Picture. Problem was the Panel has no Transparent Property so the shortcut on the form looks clunky with the visible Panel behind it.
I need to be able to drop to the TImage or make the underlying TPanel transparent.
Can anyone help with code-snippets for either of those options, or better yet, a method of dropping a Shortcut directly on to my Form.
Thanks
Coincidentally I needed to make a TWinControl (the base for every visible control with a window handle, including TPanel) transparent. I found numerous results and applied them to this answer.
It's been a while since I implemented drag and drop, but I assume you call some API and pass it the handle of the panel? That answers the question why you can't use TImage. TImage is a graphic control, a control without a handle, that relies on its parent for recieving messages and drawing itself.
It should be possible to use the form, though, since that has a handle too.
If the TImage is directly on the TForm, then let the TForm handle the drop, no TPanel needed. OLE Drag&Drop operations (which Ander's components implement) provide coordinates where dragging and dropping occurs. The TForm should be able to detect when a drag is over the area occupied by the TImage and what type of data is being dragged, and only allow dropping of supported types within that area, extracting the dropped data and updating the TImageas needed, and denying anything else that does not match that criteria.

How to Detect that the Mouse is unmoved and button still pressed?

In Delphi, I've added a Scrollbar component (oriented vertical) to the right side of my form.
I've added a Scrollbar OnChange event so I can change the view of the form and the position of the scrollbar thumb when the user clicks on the UpArrow or DownArrow button with his mouse, and this works fine.
But the OnChange event only seems to get triggered when the mouse button is initially pressed on the arrow.
I notice all scrollbar controls repeat the command and continue scrolling while the mouse remains pressed on the arrow, and I'd like to implement this behavior.
So how can I easily detect if the user has not moved the mouse and continues to press the mouse button while the mouse remains over the arrow?
Conclusion. Somehow something in the scrollbar in my project got corrupted. After I deleted the ScrollBar, and added it again, the problem vanished.
This is one of those tricky ones that took me a lot of time to solve. Thanks for your help. I'm closing this question.
Use the OnScroll event.
The following code adds 'xxx' to a memo as long as the mouse is held down on the scrollbar arrow button. Tested with Delphi 6.
procedure TForm1.ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
begin
Memo1.Lines.Add( 'xxx' );
end;
The usual way to handle auto-repeating is to enable a TTimer and check in the OnTimer() event handler whether the action needs to be performed again, and to deactivate the timer if not. If you need sample code, I seem to remember that the SynEdit control used a similar technique for autoscrolling in drag and drop operations.
If a component does not encapsulate the behaviour you are looking for and you can't easily simulate the behaviour with the methods available you should really subclass the closest component that does most of what you need and add the behaviours that are missing.
I know that some extra work is involved but it really is the better way to go. Now with Delphi, I seem to recall that subclassed components needed a bit of extra work as well to be able to be used from the IDE for form design, maybe this has changed since version 7.

How to check if form is maximized?

I'm having a problem with a component I use.Its aligned to bottom ,and ,when form is maximized,the control is placed at the correct position,but when I attempt to minimize the form,the control stays at the position where it is.
I tried using a timer that always sets the align to bottom,but I'm sure a timer is the worst solution to my issue.
Please suggest a way to set the align to Bottom when the form is restored from maximize.(maximize->restore only).
My current idea is to check if form is maximized at FormResize event,but that won't work,because I need to do it when its restored,not maximized.
You can check if a form is maximised by using
Self.WindowState = wsMaximized
Other states are
wsNormal
wsMinimized
wsMaximized
Depending on what you are doing, you could also place the control on a panel and align the panel to the bottom of the form, if you turn the borders off and use the parent colour, you cant see the panel, that way it will stay at the bottom of the form without additional code.

Resources