How to change the size of activex control automatically? - activex

I wrote an activex control for showing images in richedit.What i want is the control's size changes as the image in it changes, but the control's size seems to be fixed, i've no idea how to get it.Is there way to reach that?

Change the size of your ActiveX control's window with SetWindowPos then call IOleInPlaceSite::OnPosRectChange on your site object.
[EDITED] Apparently, you could perform the above upon EN_REQUESTRESIZE notification from RichEdit. EN_OBJECTPOSITIONS also looks relevant. Try both and share the result with us.

Related

Delphi, Firemonkey - How to draw on component canvas outside of paint

I am writing my first component for Firemonkey. It is very dynamic control and to keep refresh times minimal, when a property changes, I only want to modify the effected attributes rather than repaint the entire control.
The first issue I found was that unless you are in the Paint loop, you need to call Canvas.SetMatrix(AbsoluteMatrix) first otherwise canvas functions are referenced to the parents coordinates. I don't quite understand this.
The second issued is that when use this control on OSX, unless I call the inherited paint procedure (which I override) nothing changes on the canvas gets displayed. This works fine in Win32
Component is based off of TControl
You might not like this, but you're not supposed to paint outside of a paint event. So don't do it. Windows is a bit more forgiving if you break that rule, but you shouldn't do it on Windows either. For example, if your window is (partly) hidden, no updates are needed and the OS will skip the paint event. So instead of trying to work against the OS it is better to work with it. And usually there is a better alternative.
You can keep an internal "cache" bitmap and update that as needed. Then when the paint event comes, you can draw this entire bitmap. If possible, update this cached bitmap in the paint event if it needs changing.
If you want to temporarily highlight items, you can have a transparent window on top and paint on that window. Let the OS window manager do the heavy work for you.

Show TEdit in FireMonkey has an error in it with red border

I'm working on a mobile application where the user needs to login.
The server is returning me if the e-mail is invalid, or subdomain or password and I want to focus the TEdit that has the error. Focus is easy but I would also like to mark the edit as invalid like many web applications do.
What is the best way to do this is a consistent way so it will look correct on both Android as iOS. Is something like this built-in? I'm using Delphi 10.1
Loki's suggestion is a possible solution.
A solution which takes advantage of FMX features would be to use a TGlowEffect for the red frame around the TEdit and then use a TPopup to create the hint.
the style it's just a nightmare in 99% of the case, so i strongly suggest to not touch it. i will instead put a Trectangle as the background of the Tedit, put the Tedit as Transparent (you already have this style ready in the stylelookup in the object inspector), and then simply set the stroke.color of the trectangle.
i m working also right now on a 100% native Tedit on ios/android/windows i guess i will finish this code in around 1 week.

Scrolling like Google Chrome with a click of the mouse wheel button

In Google Chrome when you click the mouse wheel button you get this cursor:
And then you are able to scroll to all possible directions, when you move around with your mouse...
IE also has this, but only moves up and down:
Is there any component for Delphi that can do this? (for a TScrollBox for example)
TMemo, for example, can do that for you, provided you set its ScrollBars property to something else than ssNone. It will even adjust according to which scroll bars are enabled. Problem with TScrollBar component is that on its own it doesn't have any focusable parts and won't receive OnMouseWheel(/Up/Down) events, but its included windowed controls might. You could write a workaround for that on main form events, though. Check solutions at http://www.delphipages.com/forum/showthread.php?t=197309
EDIT: OnMouseWheel(/Up/Down) should be OnMouse(/Up/Down), thanks to #Sertac Akyuz for pointing this out ;)
Seems like this feature is available in RAD studio 2009 (but not in D7).
You need to use Imouse (imouse.pas unit) and the control must have ControlStyle of csPannable.
quote:
Imouse (imouse.pas unit) is a standard implementation of scrolling
with middle button (called also "mouse panning"). It's also used in
RAD Studio. Imouse functionality relays on standard window scrollbars
and sends WM_HSCROLL/WM_VSCROLL to the window to make it scroll. It
works on every window, that have a scrollbar (e.g. TListView,
TTreeView, even TForm/TFrame if AutoScroll is True and at least one
scrollbar is visible).
Oh, I've forgotten one thing. Control must have csPannable in
ControlStyle, but RichView hasn't by default. So, after adding Code:
RichViewEdit1.ControlStyle := RichViewEdit1.ControlStyle +
[csPannable];
I didn't test it though.
All that is left for me is to look into the source code (When I can get my hands on copy of D2009) and maybe impliment this with D7...

Windows appearing off edge of screen (Delphi)

Windows in my application are popping up off the edge of the screen, and this of course is a problem because some of the windows are modal and can't be dismissed (you don't even know they are there).
I'm using the TurboPower Orpheus component which remembers the location and size of each form, then restores it when the form is shown again. It saves the size and placement in an INI file.
What can I do to prevent windows from ever showing off the side of the screen?
It's common for this sort of thing to happen if you use multiple monitors and then disconnect one, such as when undocking a laptop. Or if you dock a laptop to a screen with a higher resolution. Or use remote desktop, etc..
The remedy is to override the "remember my position" behavior with a sanity check, to see if the left+width exceeds the width of the screen (Screen.Monitors array, actually - thanks guys), and vice-versa for the top+height.
Ideally, you "bump" by subtracting the difference, so you're butting up against the edge that the window wanted to straddle.
Also, see if there are updates to Orpheus that fix this. If not, you can get the source, make the correction (optional), and contribute it back to the project. It's OSS, as I recall.
You may want to give a look at their DefaultMonitor property and read the code from TCustomForm.SetWindowToMonitor to see how to deal with positioning relatively to Screen.Monitors.
Use DefaultMonitor to associate a form with a particular monitor in a multi-monitor application. The following table lists the possible values:
Value Meaning
dmDesktop No attempt is made to position the form on a specific monitor.
dmPrimary The form is positioned on the first monitor listed in the global screen object's Monitors property.
dmMainForm The form appears on the same monitor as the application's main form.
dmActiveForm The form appears on the same monitor as the currently active form.
Note: DefaultMonitor has no effect if the application does not have a main form.
To recall the previous position of a form, without having it suddenly in an area which is no longer available (due to a plugged off screen or changed resolution), you just call
TForm.MakeFullyVisible;
That's it. See the documentation.

Change the color of the applications title bar

With Delphi 7 trying to change the color of the title bar of the software from the window theme. I have seen code which allows you to change ALL the title bars of all programs, but I am just wanting to change my program.
Anyone seen/done anything like this? Don't mind paying for a component if needed.
I believe Windows sends the WM_NCPAINT message to an application when it should paint the window frame including the title bar. The default behaviour is to fall back to the default Windows handler which draws the default frame. You could replace this, or re-paint the title-bar section right after.
This looks like a good example: http://delphi.about.com/od/adptips2006/qt/draw_captionbar.htm
The answer by Stijn is not fully complete, as the caption and border of the window will also be redrawn when it is (de-)activated. So in addition to WM_NCPAINT you will also need to handle WM_NCACTIVATE. Unfortunately this can not simply be replaced, as there is other code in the default message handler (apart from drawing code) that needs to be executed. But calling the default handler will in turn lead to the default caption and border being drawn first, which you would then need to draw over with your intended colour, resulting in flicker.
One way to work around this is to adjust the drawing region that the default message handler is called with. See "Drawing titlebar on XP with themes" for an example using Windows API calls that should easily translate to Delphi. Note that this deals only with the text in the caption bar, but the principle applies.
You might take a look at a skinning library. ExpressSkin by DevExpress is a good one.

Resources