RichEdit VCL and URLs. Workarounds for OnPaint Issues - delphi

My issue is with the thing Delphi progies scare to death - Rich Edit in Windows (XP and pre-XP versions).
Situation:
I have added EM_AUTOURLDETECTION in OnCreate of form. Target -> RichEdit1. Then, I have form, that is "collapsed" after showing form. RichEdit Control is sattic, visible and enabled, but it is "hidden" because form window is collapsed.
I can expand and collapse form, using Button1 and changing forms Constraints and Size properties.
After first time I expand form, the URL inside RichEdit1 control is highlighted. But, after second, third, fourth, etc... times I collapse and expand form, the RichEdit1 Control does not highlight URL anymore.
I have tried EM_SETTEXTMODE messages, also WM_UPDATEUISTATE, also basic WM_TEXT message -> no luck. It sems like this merssage really works ( enables detection ) while sending keyboard strokes ( virtual keycodes ), but not when text has been modified.
Also - I am thinking to rewrite code to make RichEdit Control dynamic. Would this fix the problem?
Maybe solution is to override OnPaint / OnDraw method to avoid highlight ( formatting ) losing when collapsing or expanding form?
Weird is that my Embarcadero Documentation says this function must work in any moment text has been modified. Why it does not work?
Any help appreciated. I am making this Community Wiki because this is common problem and togewther we cam find solution, right? :)
Also - follow-ups and related Question:
Override OnPaint
How to autodetect urls in RichEdit 2.0?
http://www.vbforums.com/archive/index.php/t-59959.html

I am not sure but is the window of the richedit recreated when geing from hide to show? If this is the case you might create your own derived TRichEdit class, override the function that creates the WIndows Handle (TWinControl.CreateHandle) and add EM_AUTOURLDETECTION there.

Related

Make FireMonkey TListBox in XE5 transparent

I have done some FireMonkey stuff in XE2, in this case I'm having troubles with a customized TListBox.
In XE2 I built this customized TListBox by removing it's background and surrounding rectangle (basically I only need the 'grouping of child items' functionality provided by TListBox. This was simple, drop a TListBox, hit 'edit custom style', select the background rectangle, edit the fill and the stroke and you're golden.
Now we're moving to XE5 and I cannot reproduce the same behavior. Using the style book editor I can see the background (which is now TStyleObject and not TRectangle), but I cannot make the changes I could make before. I see tutorials on how to add stuff to a TListBox, but not on how to take default behavior away.
Can someone explain how to achieve this specific behavior, or point me towards a good tutorial?
Try changing the StyleLookup property of the list box to transparentlistboxstyle

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.

How do I write a TDBCtrlGrid VCL Style custom class?

There are lots of questions here about XE2 VCL Styles and custom colors for Buttons, Panels, edits, etc, and VCL Styles. As much as I wish the existing questions covered it, they don't... So DB Control Grids appear to be Yet Another Special Case.
In the DB Control Grid VCL sources, it registers a style hook thusly: TCustomStyleEngine.RegisterStyleHook( TDBCtrlGrid, TScrollingStyleHook);
However, that's not what you would descend from if you want to write your own DB Control Grid VCL style hook. If you do, you get the whole control painted like a very large scrollbar.
So how do you custom-theme a DB Control grid? When you disable the themes completely, it seems to still not allow the active row to be custom painted. So I think that one must have to write a custom subclass and override the Paint method, plus write a VCL style hook class, for this purpose.
It appears that one should probably mostly just customizing using the regular owner draw events OnPaintPanel, and that adding that event, if you didn't, fixes the biggest VCL Styles glitch that I see for TDBCtrlGrid, which is that it doesn't ever use the SelectedColor and just paints everything in flat gray or whatever else is the base color. If anyone can confirm that, or tell me otherwise, it would be appreciated.

Cause 'hint' to refire on listview as I move over items

Sure I've seen this done before but off-hand I can't find any examples.
I've got a TListView, set in 'report' viewstyle. It has about half a dozen subitems, and one thing we'd like to do is have the 'hint' (tooltip) on the listview dynamically show another field of data. That is, each time you move the mouse over any given row, the 'hint' would show some text relevant to that particular row.
I'm partway there - I can do this using the OnInfoTip method, but unfortunately once a tip has appeared, Windows seems to decide that I don't need to see a hint for the listview again until I move the mouse away from the listview and then back 'over' it again. Simply moving the mouse down to the next row, all-the-time keeping the mouse over the control, doesn't persuade the program to display the new hint.
Just to be clear - I've got OnInfoTip working so that the program does display the right hint relevant to the item I first moved the mouse over. Changing the hint text isn't the issue. The problem is that moving the mouse to another item in the listview doesn't cause the software to show a new hint. (Hope that makes sense).
Is there some proper way of getting this behaviour to work, or am I going to end up doing something icky with mouseovers and then manually drawing a hintbox (etc)?
check the following link:
Display Custom Hints for TListView Sub Items
Edit:
I just checked it now on delphi7 it's showing the hint for every row dynamically after moving the mouse on the listview.
Offtopic: This is simple in Virtual Treeview component, it is build-in feature.
i was using the OnInfoTip event (i didn't need hints for the subitems). the hint was "flashing" (show/hide/show/hide/show/hide/show/hide). found the listview's ShowHint was false. set it to True and it worked as it should.

Delphi control that could mimic "Add-ons|Extension list" of Firefox?

My aim is to update the look of the GUI in my app. Currently my GUI contains a lot of listboxes which are used to edit some objects in an old fashioned way, that is, user double-clicks an item and a dialog is shown to modify the corresponding object.
I think a good modern approach is how Firefox displays the extensions installed (a snapshot below).
My question is about how to build such a GUI in Delphi(win32) easily? Are there any components you use mimicing such behaviour or will I just need to code this from stratch using panels? (IMO a very cumbersome job I'd like to avoid - the selection logic, resizings, etc...)
You can do something similar (not exactly) with standard components; TDBCtrlGrid, TSpeedButton,...
alt text http://img8.imageshack.us/img8/9585/imagen29ox3.png
If you're using Delphi 2007 or Delphi 2009, you might be able to do something similar using TCategoryButtons (from the 'Additional' component palette page). Drop it on a form and right click to display the popup menu, and then click "Categories Editor...". Add a category with the resulting dialog, set it's caption, and optionally set up Items it contains. Not exactly the same, but it might do what you need.
You could also use a dialog with a TTreeView (if you have categories of objects) or TListView to emulate the Delphi 2007 Projects->Options dialog. Clicking an item in the TreeView or ListView displays the proper page of a TPageControl to configure the object.
I mostly agree with Lars, but I would use a frame for each item instead of a panel. That would separate into its own file, and you would get easy designtime support for it.
Using a TFrame for each list item and put them all Aligned Top on a TScrollBox might work. Also see TDBCtrlGrid which does something like that in combination with datasets.
It can be done with existing Delphi controls.
For instance in the TCustomListBox control you can create your own OnDrawItem event to draw your own list item. You also need to create your own OnMeasureItem to change the item height.
In some cases it is very limited, so if you want more freedom you will need to do it from scratch.

Resources